001package com.nimbusds.jose.crypto; 002 003 004import java.security.InvalidKeyException; 005import java.security.Signature; 006import java.security.SignatureException; 007import java.security.interfaces.RSAPublicKey; 008 009import net.jcip.annotations.ThreadSafe; 010 011import com.nimbusds.jose.DefaultJWSHeaderFilter; 012import com.nimbusds.jose.JOSEException; 013import com.nimbusds.jose.JWSHeaderFilter; 014import com.nimbusds.jose.JWSVerifier; 015import com.nimbusds.jose.ReadOnlyJWSHeader; 016import com.nimbusds.jose.util.Base64URL; 017 018 019/** 020 * RSA Signature-Scheme-with-Appendix (RSASSA) verifier of 021 * {@link com.nimbusds.jose.JWSObject JWS objects}. This class is thread-safe. 022 * 023 * <p>Supports the following JSON Web Algorithms (JWAs): 024 * 025 * <ul> 026 * <li>{@link com.nimbusds.jose.JWSAlgorithm#RS256} 027 * <li>{@link com.nimbusds.jose.JWSAlgorithm#RS384} 028 * <li>{@link com.nimbusds.jose.JWSAlgorithm#RS512} 029 * <li>{@link com.nimbusds.jose.JWSAlgorithm#PS256} 030 * <li>{@link com.nimbusds.jose.JWSAlgorithm#PS384} 031 * <li>{@link com.nimbusds.jose.JWSAlgorithm#PS512} 032 * </ul> 033 * 034 * <p>Accepts all {@link com.nimbusds.jose.JWSHeader#getRegisteredParameterNames 035 * registered JWS header parameters}. Modify the {@link #getJWSHeaderFilter 036 * header filter} properties to restrict the acceptable JWS algorithms and 037 * header parameters, or to allow custom JWS header parameters. 038 * 039 * @author Vladimir Dzhuvinov 040 * @version $version$ (2013-10-07) 041 */ 042@ThreadSafe 043public class RSASSAVerifier extends RSASSAProvider implements JWSVerifier { 044 045 046 /** 047 * The JWS header filter. 048 */ 049 private final DefaultJWSHeaderFilter headerFilter; 050 051 052 /** 053 * The public RSA key. 054 */ 055 private final RSAPublicKey publicKey; 056 057 058 /** 059 * Creates a new RSA Signature-Scheme-with-Appendix (RSASSA) verifier. 060 * 061 * @param publicKey The public RSA key. Must not be {@code null}. 062 */ 063 public RSASSAVerifier(final RSAPublicKey publicKey) { 064 065 if (publicKey == null) { 066 067 throw new IllegalArgumentException("The public RSA key must not be null"); 068 } 069 070 this.publicKey = publicKey; 071 072 headerFilter = new DefaultJWSHeaderFilter(supportedAlgorithms()); 073 } 074 075 076 /** 077 * Gets the public RSA key. 078 * 079 * @return The public RSA key. 080 */ 081 public RSAPublicKey getPublicKey() { 082 083 return publicKey; 084 } 085 086 087 @Override 088 public JWSHeaderFilter getJWSHeaderFilter() { 089 090 return headerFilter; 091 } 092 093 094 @Override 095 public boolean verify(final ReadOnlyJWSHeader header, 096 final byte[] signedContent, 097 final Base64URL signature) 098 throws JOSEException { 099 100 Signature verifier = getRSASignerAndVerifier(header.getAlgorithm()); 101 102 try { 103 verifier.initVerify(publicKey); 104 verifier.update(signedContent); 105 return verifier.verify(signature.decode()); 106 107 } catch (InvalidKeyException e) { 108 109 throw new JOSEException("Invalid public RSA key: " + e.getMessage(), e); 110 111 } catch (SignatureException e) { 112 113 throw new JOSEException("RSA signature exception: " + e.getMessage(), e); 114 } 115 } 116}