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}