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 * </ul> 030 * 031 * <p>Accepts all {@link com.nimbusds.jose.JWSHeader#getReservedParameterNames 032 * reserved JWS header parameters}. Modify the {@link #getJWSHeaderFilter 033 * header filter} properties to restrict the acceptable JWS algorithms and 034 * header parameters, or to allow custom JWS header parameters. 035 * 036 * @author Vladimir Dzhuvinov 037 * @version $version$ (2013-03-27) 038 */ 039@ThreadSafe 040public class RSASSAVerifier extends RSASSAProvider implements JWSVerifier { 041 042 043 /** 044 * The JWS header filter. 045 */ 046 private final DefaultJWSHeaderFilter headerFilter; 047 048 049 /** 050 * The public RSA key. 051 */ 052 private final RSAPublicKey publicKey; 053 054 055 /** 056 * Creates a new RSA Signature-Scheme-with-Appendix (RSASSA) verifier. 057 * 058 * @param publicKey The public RSA key. Must not be {@code null}. 059 */ 060 public RSASSAVerifier(final RSAPublicKey publicKey) { 061 062 if (publicKey == null) { 063 064 throw new IllegalArgumentException("The public RSA key must not be null"); 065 } 066 067 this.publicKey = publicKey; 068 069 headerFilter = new DefaultJWSHeaderFilter(supportedAlgorithms()); 070 } 071 072 073 /** 074 * Gets the public RSA key. 075 * 076 * @return The public RSA key. 077 */ 078 public RSAPublicKey getPublicKey() { 079 080 return publicKey; 081 } 082 083 084 @Override 085 public JWSHeaderFilter getJWSHeaderFilter() { 086 087 return headerFilter; 088 } 089 090 091 @Override 092 public boolean verify(final ReadOnlyJWSHeader header, 093 final byte[] signedContent, 094 final Base64URL signature) 095 throws JOSEException { 096 097 Signature verifier = getRSASignerAndVerifier(header.getAlgorithm()); 098 099 try { 100 verifier.initVerify(publicKey); 101 verifier.update(signedContent); 102 return verifier.verify(signature.decode()); 103 104 } catch (InvalidKeyException e) { 105 106 throw new JOSEException("Invalid public RSA key: " + e.getMessage(), e); 107 108 } catch (SignatureException e) { 109 110 throw new JOSEException("RSA signature exception: " + e.getMessage(), e); 111 } 112 } 113}