001package com.nimbusds.jose.crypto; 002 003 004import java.security.InvalidKeyException; 005import java.security.Signature; 006import java.security.SignatureException; 007import java.security.interfaces.RSAPublicKey; 008import java.util.Set; 009 010import net.jcip.annotations.ThreadSafe; 011 012import com.nimbusds.jose.*; 013import com.nimbusds.jose.jwk.RSAKey; 014import com.nimbusds.jose.util.Base64URL; 015 016 017/** 018 * RSA Signature-Scheme-with-Appendix (RSASSA) verifier of 019 * {@link com.nimbusds.jose.JWSObject JWS objects}. Expects a public RSA key. 020 * 021 * <p>See RFC 7518, sections 022 * <a href="https://tools.ietf.org/html/rfc7518#section-3.3">3.3</a> and 023 * <a href="https://tools.ietf.org/html/rfc7518#section-3.5">3.5</a> for more 024 * information. 025 * 026 * <p>This class is thread-safe. 027 * 028 * <p>Supports the following algorithms: 029 * 030 * <ul> 031 * <li>{@link com.nimbusds.jose.JWSAlgorithm#RS256} 032 * <li>{@link com.nimbusds.jose.JWSAlgorithm#RS384} 033 * <li>{@link com.nimbusds.jose.JWSAlgorithm#RS512} 034 * <li>{@link com.nimbusds.jose.JWSAlgorithm#PS256} 035 * <li>{@link com.nimbusds.jose.JWSAlgorithm#PS384} 036 * <li>{@link com.nimbusds.jose.JWSAlgorithm#PS512} 037 * </ul> 038 * 039 * @author Vladimir Dzhuvinov 040 * @version 2015-06-02 041 */ 042@ThreadSafe 043public class RSASSAVerifier extends RSASSAProvider implements JWSVerifier, CriticalHeaderParamsAware { 044 045 046 /** 047 * The critical header policy. 048 */ 049 private final CriticalHeaderParamsDeferral critPolicy = new CriticalHeaderParamsDeferral(); 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 this(publicKey, null); 066 } 067 068 069 /** 070 * Creates a new RSA Signature-Scheme-with-Appendix (RSASSA) verifier. 071 * 072 * @param rsaJWK The RSA JSON Web Key (JWK). Must not be {@code null}. 073 * 074 * @throws JOSEException If the RSA JWK extraction failed. 075 */ 076 public RSASSAVerifier(final RSAKey rsaJWK) 077 throws JOSEException { 078 079 this(rsaJWK.toRSAPublicKey(), null); 080 } 081 082 083 /** 084 * Creates a new RSA Signature-Scheme-with-Appendix (RSASSA) verifier. 085 * 086 * @param publicKey The public RSA key. Must not be {@code null}. 087 * @param defCritHeaders The names of the critical header parameters 088 * that are deferred to the application for 089 * processing, empty set or {@code null} if none. 090 */ 091 public RSASSAVerifier(final RSAPublicKey publicKey, 092 final Set<String> defCritHeaders) { 093 094 if (publicKey == null) { 095 throw new IllegalArgumentException("The public RSA key must not be null"); 096 } 097 098 this.publicKey = publicKey; 099 100 critPolicy.setDeferredCriticalHeaderParams(defCritHeaders); 101 } 102 103 104 /** 105 * Gets the public RSA key. 106 * 107 * @return The public RSA key. 108 */ 109 public RSAPublicKey getPublicKey() { 110 111 return publicKey; 112 } 113 114 115 @Override 116 public Set<String> getProcessedCriticalHeaderParams() { 117 118 return critPolicy.getProcessedCriticalHeaderParams(); 119 } 120 121 122 @Override 123 public Set<String> getDeferredCriticalHeaderParams() { 124 125 return critPolicy.getProcessedCriticalHeaderParams(); 126 } 127 128 129 @Override 130 public boolean verify(final JWSHeader header, 131 final byte[] signedContent, 132 final Base64URL signature) 133 throws JOSEException { 134 135 if (! critPolicy.headerPasses(header)) { 136 return false; 137 } 138 139 final Signature verifier = RSASSA.getSignerAndVerifier(header.getAlgorithm(), getJCAContext().getProvider()); 140 141 try { 142 verifier.initVerify(publicKey); 143 144 } catch (InvalidKeyException e) { 145 throw new JOSEException("Invalid public RSA key: " + e.getMessage(), e); 146 } 147 148 try { 149 verifier.update(signedContent); 150 return verifier.verify(signature.decode()); 151 152 } catch (SignatureException e) { 153 return false; 154 } 155 } 156}