001package com.nimbusds.jose.crypto;
002
003
004import java.security.InvalidKeyException;
005import java.security.Signature;
006import java.security.SignatureException;
007import java.security.interfaces.RSAPrivateKey;
008
009import net.jcip.annotations.ThreadSafe;
010
011import com.nimbusds.jose.JOSEException;
012import com.nimbusds.jose.JWSSigner;
013import com.nimbusds.jose.JWSHeader;
014import com.nimbusds.jose.util.Base64URL;
015
016
017
018/**
019 * RSA Signature-Scheme-with-Appendix (RSASSA) signer of 
020 * {@link com.nimbusds.jose.JWSObject JWS objects}. This class is thread-safe.
021 *
022 * <p>Supports the following JSON Web Algorithms (JWAs):
023 *
024 * <ul>
025 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#RS256}
026 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#RS384}
027 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#RS512}
028 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#PS256}
029 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#PS384}
030 *     <li>{@link com.nimbusds.jose.JWSAlgorithm#PS512}
031 * </ul>
032 * 
033 * @author Vladimir Dzhuvinov
034 * @version $version$ (2013-05-04)
035 */
036@ThreadSafe
037public class RSASSASigner extends RSASSAProvider implements JWSSigner {
038
039
040        /**
041         * The private RSA key.
042         */
043        private final RSAPrivateKey privateKey;
044
045
046        /**
047         * Creates a new RSA Signature-Scheme-with-Appendix (RSASSA) signer.
048         *
049         * @param privateKey The private RSA key. Must not be {@code null}.
050         */
051        public RSASSASigner(final RSAPrivateKey privateKey) {
052
053                if (privateKey == null) {
054
055                        throw new IllegalArgumentException("The private RSA key must not be null");
056                }
057
058                this.privateKey = privateKey;
059        }
060
061
062        /**
063         * Gets the private RSA key.
064         *
065         * @return The private RSA key.
066         */
067        public RSAPrivateKey getPrivateKey() {
068
069                return privateKey;
070        }
071
072
073        @Override
074        public Base64URL sign(final JWSHeader header, final byte[] signingInput)
075                throws JOSEException {
076
077                Signature signer = getRSASignerAndVerifier(header.getAlgorithm(), provider);
078
079                try {
080                        signer.initSign(privateKey);
081                        signer.update(signingInput);
082                        return Base64URL.encode(signer.sign());
083
084                } catch (InvalidKeyException e) {
085
086                        throw new JOSEException("Invalid private RSA key: " + e.getMessage(), e);
087
088                } catch (SignatureException e) {
089
090                        throw new JOSEException("RSA signature exception: " + e.getMessage(), e);
091                }
092        }
093}