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