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.ReadOnlyJWSHeader;
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 * </ul>
029 * 
030 * @author Vladimir Dzhuvinov
031 * @version $version$ (2013-05-04)
032 */
033@ThreadSafe
034public class RSASSASigner extends RSASSAProvider implements JWSSigner {
035
036
037        /**
038         * The private RSA key.
039         */
040        private final RSAPrivateKey privateKey;
041
042
043        /**
044         * Creates a new RSA Signature-Scheme-with-Appendix (RSASSA) signer.
045         *
046         * @param privateKey The private RSA key. Must not be {@code null}.
047         */
048        public RSASSASigner(final RSAPrivateKey privateKey) {
049
050                if (privateKey == null) {
051
052                        throw new IllegalArgumentException("The private RSA key must not be null");
053                }
054
055                this.privateKey = privateKey;
056        }
057
058
059        /**
060         * Gets the private RSA key.
061         *
062         * @return The private RSA key.
063         */
064        public RSAPrivateKey getPrivateKey() {
065
066                return privateKey;
067        }
068
069
070        @Override
071        public Base64URL sign(final ReadOnlyJWSHeader header, final byte[] signingInput)
072                throws JOSEException {
073
074                Signature signer = getRSASignerAndVerifier(header.getAlgorithm());
075
076                try {
077                        signer.initSign(privateKey);
078                        signer.update(signingInput);
079                        return Base64URL.encode(signer.sign());
080
081                } catch (InvalidKeyException e) {
082
083                        throw new JOSEException("Invalid private RSA key: " + e.getMessage(), e);
084
085                } catch (SignatureException e) {
086
087                        throw new JOSEException("RSA signature exception: " + e.getMessage(), e);
088                }
089        }
090}