001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
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.factories;
019
020
021import java.security.Key;
022import java.security.interfaces.ECPublicKey;
023import java.security.interfaces.RSAPublicKey;
024import java.util.Collections;
025import java.util.LinkedHashSet;
026import java.util.Set;
027import javax.crypto.SecretKey;
028
029import com.nimbusds.jose.*;
030import com.nimbusds.jose.crypto.ECDSAVerifier;
031import com.nimbusds.jose.crypto.MACVerifier;
032import com.nimbusds.jose.crypto.RSASSAVerifier;
033import com.nimbusds.jose.jca.JCAContext;
034import com.nimbusds.jose.proc.JWSVerifierFactory;
035import net.jcip.annotations.ThreadSafe;
036
037
038/**
039 * Default JSON Web Signature (JWS) verifier factory.
040 *
041 * <p>Supports all standard JWS algorithms implemented in the
042 * {@link com.nimbusds.jose.crypto} package.
043 *
044 * @author Vladimir Dzhuvinov
045 * @version 2015-11-16
046 */
047@ThreadSafe
048public class DefaultJWSVerifierFactory implements JWSVerifierFactory {
049
050
051        /**
052         * The supported JWS algorithms.
053         */
054        public static final Set<JWSAlgorithm> SUPPORTED_ALGORITHMS;
055
056
057        static {
058                Set<JWSAlgorithm> algs = new LinkedHashSet<>();
059                algs.addAll(MACVerifier.SUPPORTED_ALGORITHMS);
060                algs.addAll(RSASSAVerifier.SUPPORTED_ALGORITHMS);
061                algs.addAll(ECDSAVerifier.SUPPORTED_ALGORITHMS);
062                SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs);
063        }
064
065
066        /**
067         * The JCA context.
068         */
069        private final JCAContext jcaContext = new JCAContext();
070
071
072        @Override
073        public Set<JWSAlgorithm> supportedJWSAlgorithms() {
074
075                return SUPPORTED_ALGORITHMS;
076        }
077
078
079        @Override
080        public JCAContext getJCAContext() {
081
082                return jcaContext;
083        }
084
085
086        @Override
087        public JWSVerifier createJWSVerifier(final JWSHeader header, final Key key)
088                throws JOSEException {
089
090                JWSVerifier verifier;
091
092                if (MACVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) {
093
094                        if (!(key instanceof SecretKey)) {
095                                throw new KeyTypeException(SecretKey.class);
096                        }
097
098                        SecretKey macKey = (SecretKey)key;
099
100                        verifier = new MACVerifier(macKey);
101
102                } else if (RSASSAVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) {
103
104                        if (!(key instanceof RSAPublicKey)) {
105                                throw new KeyTypeException(RSAPublicKey.class);
106                        }
107
108                        RSAPublicKey rsaPublicKey = (RSAPublicKey)key;
109
110                        verifier = new RSASSAVerifier(rsaPublicKey);
111
112                } else if (ECDSAVerifier.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm())) {
113
114                        if (!(key instanceof ECPublicKey)) {
115                                throw new KeyTypeException(ECPublicKey.class);
116                        }
117
118                        ECPublicKey ecPublicKey = (ECPublicKey)key;
119
120                        verifier = new ECDSAVerifier(ecPublicKey);
121
122                } else {
123
124                        throw new JOSEException("Unsupported JWS algorithm: " + header.getAlgorithm());
125                }
126
127                // Apply JCA context
128                verifier.getJCAContext().setSecureRandom(jcaContext.getSecureRandom());
129                verifier.getJCAContext().setProvider(jcaContext.getProvider());
130
131                return verifier;
132        }
133}