001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.crypto.impl;
019
020
021import java.util.Collections;
022import java.util.Set;
023
024import com.nimbusds.jose.CriticalHeaderParamsAware;
025import com.nimbusds.jose.Header;
026import com.nimbusds.jose.JOSEException;
027import com.nimbusds.jose.JWEHeader;
028
029
030/**
031 * Critical ({@code crit}) header parameters deferral policy.
032 *
033 * @see CriticalHeaderParamsAware
034 *
035 * @author Vladimir Dzhuvinov
036 * @version 2020-04-17
037 */
038public class CriticalHeaderParamsDeferral {
039
040
041        /**
042         * The names of the deferred critical headers.
043         */
044        private Set<String> deferredParams = Collections.emptySet();
045
046
047        /**
048         * Returns the names of the critical ({@code crit}) header parameters
049         * that are understood and processed.
050         *
051         * @return Empty immutable set.
052         */
053        public Set<String> getProcessedCriticalHeaderParams() {
054
055                return Collections.singleton("b64");
056        }
057
058
059        /**
060         * Returns the names of the critical ({@code crit}) header parameters
061         * that are deferred to the application for processing.
062         *
063         * @return The names of the critical header parameters that are
064         *         deferred to the application for processing, as an
065         *         unmodifiable set, empty set if none.
066         */
067        public Set<String> getDeferredCriticalHeaderParams() {
068
069                return Collections.unmodifiableSet(deferredParams);
070        }
071
072
073        /**
074         * Sets the names of the critical ({@code crit}) header parameters
075         * that are deferred to the application for processing.
076         *
077         * @param defCritHeaders The names of the critical header parameters
078         *                       that are deferred to the application for
079         *                       processing, empty set or {@code null} if none.
080         */
081        public void setDeferredCriticalHeaderParams(final Set<String> defCritHeaders) {
082
083                if (defCritHeaders == null) {
084                        this.deferredParams = Collections.emptySet();
085                } else {
086                        this.deferredParams = defCritHeaders;
087                }
088        }
089
090
091        /**
092         * Returns {@code true} if the specified header passes the critical
093         * parameters check.
094         *
095         * @param header The JWS or JWE header to check. Must not be
096         *               {@code null}.
097         *
098         * @return {@code true} if the header passes, {@code false} if the
099         *         header contains one or more critical header parameters which
100         *         are not marked for deferral to the application.
101         */
102        public boolean headerPasses(final Header header) {
103
104                if (header.getCriticalParams() == null) {
105                        return true; // ok
106                }
107                
108                for (String critParam: header.getCriticalParams()) {
109                        if (getProcessedCriticalHeaderParams().contains(critParam)) {
110                                continue;
111                        }
112                        if (getDeferredCriticalHeaderParams().contains(critParam)) {
113                                continue;
114                        }
115                        return false;
116                }
117                return true;
118        }
119
120
121        /**
122         * Throws a JOSE exception if the specified JWE header doesn't pass the
123         * critical header parameters check.
124         *
125         * @param header The JWE header to check. Must not be {@code null}.
126         *
127         * @throws JOSEException If the JWE header doesn't pass the check.
128         */
129        public void ensureHeaderPasses(final JWEHeader header)
130                throws JOSEException {
131
132                if (! headerPasses(header)) {
133                        throw new JOSEException("Unsupported critical header parameter(s)");
134                }
135        }
136}