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 2020-10-30 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, SecureRandom expensive and not needed for verification (iss #385) 128 verifier.getJCAContext().setProvider(jcaContext.getProvider()); 129 130 return verifier; 131 } 132}