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.*;
025
026
027/**
028 * Critical ({@code crit}) header parameters deferral policy.
029 *
030 * @see CriticalHeaderParamsAware
031 *
032 * @author Vladimir Dzhuvinov
033 * @version 2020-04-17
034 */
035public class CriticalHeaderParamsDeferral {
036
037
038        /**
039         * The names of the deferred critical headers.
040         */
041        private Set<String> deferredParams = Collections.emptySet();
042
043
044        /**
045         * Returns the names of the critical ({@code crit}) header parameters
046         * that are understood and processed.
047         *
048         * @return Empty immutable set.
049         */
050        public Set<String> getProcessedCriticalHeaderParams() {
051
052                return Collections.singleton(HeaderParameterNames.BASE64_URL_ENCODE_PAYLOAD);
053        }
054
055
056        /**
057         * Returns the names of the critical ({@code crit}) header parameters
058         * that are deferred to the application for processing.
059         *
060         * @return The names of the critical header parameters that are
061         *         deferred to the application for processing, as an
062         *         unmodifiable set, empty set if none.
063         */
064        public Set<String> getDeferredCriticalHeaderParams() {
065
066                return Collections.unmodifiableSet(deferredParams);
067        }
068
069
070        /**
071         * Sets the names of the critical ({@code crit}) header parameters
072         * that are deferred to the application for processing.
073         *
074         * @param defCritHeaders The names of the critical header parameters
075         *                       that are deferred to the application for
076         *                       processing, empty set or {@code null} if none.
077         */
078        public void setDeferredCriticalHeaderParams(final Set<String> defCritHeaders) {
079
080                if (defCritHeaders == null) {
081                        this.deferredParams = Collections.emptySet();
082                } else {
083                        this.deferredParams = defCritHeaders;
084                }
085        }
086
087
088        /**
089         * Returns {@code true} if the specified header passes the critical
090         * parameters check.
091         *
092         * @param header The JWS or JWE header to check. Must not be
093         *               {@code null}.
094         *
095         * @return {@code true} if the header passes, {@code false} if the
096         *         header contains one or more critical header parameters which
097         *         are not marked for deferral to the application.
098         */
099        public boolean headerPasses(final Header header) {
100
101                if (header.getCriticalParams() == null) {
102                        return true; // ok
103                }
104                
105                for (String critParam: header.getCriticalParams()) {
106                        if (getProcessedCriticalHeaderParams().contains(critParam)) {
107                                continue;
108                        }
109                        if (getDeferredCriticalHeaderParams().contains(critParam)) {
110                                continue;
111                        }
112                        return false;
113                }
114                return true;
115        }
116
117
118        /**
119         * Throws a JOSE exception if the specified JWE header doesn't pass the
120         * critical header parameters check.
121         *
122         * @param header The JWE header to check. Must not be {@code null}.
123         *
124         * @throws JOSEException If the JWE header doesn't pass the check.
125         */
126        public void ensureHeaderPasses(final JWEHeader header)
127                throws JOSEException {
128
129                if (! headerPasses(header)) {
130                        throw new JOSEException("Unsupported critical header parameter(s)");
131                }
132        }
133}