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}