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.proc;
019
020
021import java.util.Arrays;
022import java.util.Collections;
023import java.util.HashSet;
024import java.util.Set;
025
026import net.jcip.annotations.Immutable;
027
028import com.nimbusds.jose.JOSEObjectType;
029
030
031/**
032 * Default JOSE header "typ" (type) parameter verifier.
033 *
034 * <p>Example JWS header with a "typ" (type) parameter set to "at+jwt":
035 *
036 * <pre>
037 * {
038 *   "alg" : "ES256",
039 *   "typ" : "at+jwt",
040 *   "kid" : "123"
041 * }
042 * </pre>
043 *
044 * <p>To create a verifier which allows the "typ" to be omitted or set to
045 * "JWT":
046 *
047 * <pre>
048 * JOSEObjectVerifier verifier = new DefaultJOSEObjectTypeVerifier(JOSEObjectType.JWT, null);
049 * </pre>
050 *
051 * <p>To create a verifier which allows a "typ" of "at+jwt":
052 *
053 * <pre>
054 * JOSEObjectVerifier verifier = new DefaultJOSEObjectTypeVerifier(new JOSEObjectType("at+jwt")));
055 * </pre>
056 *
057 * @author Vladimir Dzhuvinov
058 * @version 2019-10-15
059 * @since 8.0
060 */
061@Immutable
062public class DefaultJOSEObjectTypeVerifier <C extends SecurityContext> implements JOSEObjectTypeVerifier<C> {
063        
064        
065        /**
066         * The allowed types.
067         */
068        private final Set<JOSEObjectType> allowedTypes;
069        
070        
071        /**
072         * The standard header "typ" (type) parameter verifier for JWS, JWE and
073         * plain (unsecured) JOSE objects (other than JWT). See RFC 7515,
074         * section 4.1.9 and RFC 7516, section 4.1.11.
075         */
076        public static final DefaultJOSEObjectTypeVerifier JOSE = new DefaultJOSEObjectTypeVerifier(JOSEObjectType.JOSE, null);
077        
078        /**
079         * The standard header "typ" (type) parameter verifier for signed,
080         * encrypted and plain (unsecured) JWTs. See RFC 7519, section 5.1.
081         */
082        public static final DefaultJOSEObjectTypeVerifier JWT = new DefaultJOSEObjectTypeVerifier(JOSEObjectType.JWT, null);
083        
084        
085        /**
086         * Creates a new JOSE object type verifier which allows the type to be
087         * omitted or {@code null}.
088         */
089        public DefaultJOSEObjectTypeVerifier() {
090                
091                this.allowedTypes = Collections.singleton(null);
092        }
093        
094        
095        /**
096         * Creates a new JOSE object type verifier allowing the specified
097         * types.
098         *
099         * @param allowedTypes The allowed types, if a {@code null} is included
100         *                     the type parameter may be omitted or
101         *                     {@code null}. The set must not be {@code null}
102         *                     or empty.
103         */
104        public DefaultJOSEObjectTypeVerifier(final Set<JOSEObjectType> allowedTypes) {
105                if (allowedTypes == null || allowedTypes.isEmpty()) {
106                        throw new IllegalArgumentException("The allowed types must not be null or empty");
107                }
108                this.allowedTypes = allowedTypes;
109        }
110        
111        
112        /**
113         * Creates a new JOSE object type verifier allowing the specified
114         * types.
115         *
116         * @param allowedTypes The allowed types, if a {@code null} is included
117         *                     the type parameter may be omitted or
118         *                     {@code null}. The array must not be {@code null}
119         *                     or empty.
120         */
121        public DefaultJOSEObjectTypeVerifier(final JOSEObjectType ... allowedTypes) {
122                if (allowedTypes == null || allowedTypes.length == 0) {
123                        throw new IllegalArgumentException("The allowed types must not be null or empty");
124                }
125                this.allowedTypes = new HashSet<>(Arrays.asList(allowedTypes));
126        }
127        
128        
129        /**
130         * Returns the allowed JOSE object types.
131         *
132         * @return The allowed JOSE object types, if a {@code null} is included
133         *         the type parameter may be omitted or {@code null}.
134         */
135        public Set<JOSEObjectType> getAllowedTypes() {
136                return allowedTypes;
137        }
138        
139        
140        @Override
141        public void verify(final JOSEObjectType type, final C context)
142                throws BadJOSEException {
143        
144                if (type == null && ! allowedTypes.contains(null)) {
145                        throw new BadJOSEException("Required JOSE header typ (type) parameter is missing");
146                }
147                
148                if (! allowedTypes.contains(type)) {
149                        throw new BadJOSEException("JOSE header typ (type) " + type + " not allowed");
150                }
151        }
152}