src/java.base/share/classes/sun/security/ssl/RSASignature.java
changeset 50768 68fa3d4026ea
parent 50204 3195a713e24d
child 53734 cb1642ccc732
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 
       
    27 package sun.security.ssl;
    26 package sun.security.ssl;
    28 
    27 
    29 import java.security.*;
    28 import java.security.*;
    30 import java.security.spec.AlgorithmParameterSpec;
    29 import java.security.spec.AlgorithmParameterSpec;
    31 
    30 
    44  * implementation allows the hashes to be explicitly set, which is required
    43  * implementation allows the hashes to be explicitly set, which is required
    45  * for RSA client authentication. It can be obtained via the
    44  * for RSA client authentication. It can be obtained via the
    46  * getInternalInstance() method.
    45  * getInternalInstance() method.
    47  *
    46  *
    48  * This class is not thread safe.
    47  * This class is not thread safe.
    49  *
       
    50  */
    48  */
    51 public final class RSASignature extends SignatureSpi {
    49 public final class RSASignature extends SignatureSpi {
    52 
       
    53     private final Signature rawRsa;
    50     private final Signature rawRsa;
    54     private MessageDigest md5, sha;
    51     private final MessageDigest mdMD5;
    55 
    52     private final MessageDigest mdSHA;
    56     // flag indicating if the MessageDigests are in reset state
       
    57     private boolean isReset;
       
    58 
    53 
    59     public RSASignature() throws NoSuchAlgorithmException {
    54     public RSASignature() throws NoSuchAlgorithmException {
    60         super();
    55         super();
    61         rawRsa = JsseJce.getSignature(JsseJce.SIGNATURE_RAWRSA);
    56         rawRsa = JsseJce.getSignature(JsseJce.SIGNATURE_RAWRSA);
    62         isReset = true;
    57         this.mdMD5 = JsseJce.getMessageDigest("MD5");
       
    58         this.mdSHA = JsseJce.getMessageDigest("SHA");
    63     }
    59     }
    64 
    60 
    65     /**
    61     /**
    66      * Get an implementation for the RSA signature. Follows the standard
    62      * Get an implementation for the RSA signature.
    67      * JCA getInstance() model, so it return the implementation from the
    63      *
    68      * provider with the highest precedence, which may be this class.
    64      * Follows the standard JCA getInstance() model, so it return the
       
    65      * implementation from the  provider with the highest precedence,
       
    66      * which may be this class.
    69      */
    67      */
    70     static Signature getInstance() throws NoSuchAlgorithmException {
    68     static Signature getInstance() throws NoSuchAlgorithmException {
    71         return JsseJce.getSignature(JsseJce.SIGNATURE_SSLRSA);
    69         return JsseJce.getSignature(JsseJce.SIGNATURE_SSLRSA);
    72     }
    70     }
    73 
    71 
    74     /**
       
    75      * Get an internal implementation for the RSA signature. Used for RSA
       
    76      * client authentication, which needs the ability to set the digests
       
    77      * to externally provided values via the setHashes() method.
       
    78      */
       
    79     static Signature getInternalInstance()
       
    80             throws NoSuchAlgorithmException, NoSuchProviderException {
       
    81         return Signature.getInstance(JsseJce.SIGNATURE_SSLRSA, "SunJSSE");
       
    82     }
       
    83 
       
    84     /**
       
    85      * Set the MD5 and SHA hashes to the provided objects.
       
    86      */
       
    87     @SuppressWarnings("deprecation")
       
    88     static void setHashes(Signature sig, MessageDigest md5, MessageDigest sha) {
       
    89         sig.setParameter("hashes", new MessageDigest[] {md5, sha});
       
    90     }
       
    91 
       
    92     /**
       
    93      * Reset the MessageDigests unless they are already reset.
       
    94      */
       
    95     private void reset() {
       
    96         if (isReset == false) {
       
    97             md5.reset();
       
    98             sha.reset();
       
    99             isReset = true;
       
   100         }
       
   101     }
       
   102 
       
   103     private static void checkNull(Key key) throws InvalidKeyException {
       
   104         if (key == null) {
       
   105             throw new InvalidKeyException("Key must not be null");
       
   106         }
       
   107     }
       
   108 
       
   109     @Override
    72     @Override
   110     protected void engineInitVerify(PublicKey publicKey)
    73     protected void engineInitVerify(PublicKey publicKey)
   111             throws InvalidKeyException {
    74             throws InvalidKeyException {
   112         checkNull(publicKey);
    75         if (publicKey == null) {
   113         reset();
    76             throw new InvalidKeyException("Public key must not be null");
       
    77         }
       
    78         mdMD5.reset();
       
    79         mdSHA.reset();
   114         rawRsa.initVerify(publicKey);
    80         rawRsa.initVerify(publicKey);
   115     }
    81     }
   116 
    82 
   117     @Override
    83     @Override
   118     protected void engineInitSign(PrivateKey privateKey)
    84     protected void engineInitSign(PrivateKey privateKey)
   121     }
    87     }
   122 
    88 
   123     @Override
    89     @Override
   124     protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
    90     protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
   125             throws InvalidKeyException {
    91             throws InvalidKeyException {
   126         checkNull(privateKey);
    92         if (privateKey == null) {
   127         reset();
    93             throw new InvalidKeyException("Private key must not be null");
       
    94         }
       
    95         mdMD5.reset();
       
    96         mdSHA.reset();
   128         rawRsa.initSign(privateKey, random);
    97         rawRsa.initSign(privateKey, random);
   129     }
       
   130 
       
   131     // lazily initialize the MessageDigests
       
   132     private void initDigests() {
       
   133         if (md5 == null) {
       
   134             md5 = JsseJce.getMD5();
       
   135             sha = JsseJce.getSHA();
       
   136         }
       
   137     }
    98     }
   138 
    99 
   139     @Override
   100     @Override
   140     protected void engineUpdate(byte b) {
   101     protected void engineUpdate(byte b) {
   141         initDigests();
   102         mdMD5.update(b);
   142         isReset = false;
   103         mdSHA.update(b);
   143         md5.update(b);
       
   144         sha.update(b);
       
   145     }
   104     }
   146 
   105 
   147     @Override
   106     @Override
   148     protected void engineUpdate(byte[] b, int off, int len) {
   107     protected void engineUpdate(byte[] b, int off, int len) {
   149         initDigests();
   108         mdMD5.update(b, off, len);
   150         isReset = false;
   109         mdSHA.update(b, off, len);
   151         md5.update(b, off, len);
       
   152         sha.update(b, off, len);
       
   153     }
   110     }
   154 
   111 
   155     private byte[] getDigest() throws SignatureException {
   112     private byte[] getDigest() throws SignatureException {
   156         try {
   113         try {
   157             initDigests();
       
   158             byte[] data = new byte[36];
   114             byte[] data = new byte[36];
   159             md5.digest(data, 0, 16);
   115             mdMD5.digest(data, 0, 16);
   160             sha.digest(data, 16, 20);
   116             mdSHA.digest(data, 16, 20);
   161             isReset = true;
       
   162             return data;
   117             return data;
   163         } catch (DigestException e) {
   118         } catch (DigestException e) {
   164             // should never occur
   119             // should never occur
   165             throw new SignatureException(e);
   120             throw new SignatureException(e);
   166         }
   121         }
   184         return rawRsa.verify(sigBytes, offset, length);
   139         return rawRsa.verify(sigBytes, offset, length);
   185     }
   140     }
   186 
   141 
   187     @Override
   142     @Override
   188     @SuppressWarnings("deprecation")
   143     @SuppressWarnings("deprecation")
   189     protected void engineSetParameter(String param, Object value)
   144     protected void engineSetParameter(String param,
   190             throws InvalidParameterException {
   145             Object value) throws InvalidParameterException {
   191         if (param.equals("hashes") == false) {
   146         throw new InvalidParameterException("Parameters not supported");
   192             throw new InvalidParameterException
       
   193                 ("Parameter not supported: " + param);
       
   194         }
       
   195         if (value instanceof MessageDigest[] == false) {
       
   196             throw new InvalidParameterException
       
   197                 ("value must be MessageDigest[]");
       
   198         }
       
   199         MessageDigest[] digests = (MessageDigest[])value;
       
   200         md5 = digests[0];
       
   201         sha = digests[1];
       
   202     }
   147     }
   203 
   148 
   204     @Override
   149     @Override
   205     protected void engineSetParameter(AlgorithmParameterSpec params)
   150     protected void engineSetParameter(AlgorithmParameterSpec params)
   206             throws InvalidAlgorithmParameterException {
   151             throws InvalidAlgorithmParameterException {
   209         }
   154         }
   210     }
   155     }
   211 
   156 
   212     @Override
   157     @Override
   213     @SuppressWarnings("deprecation")
   158     @SuppressWarnings("deprecation")
   214     protected Object engineGetParameter(String param)
   159     protected Object engineGetParameter(
   215             throws InvalidParameterException {
   160             String param) throws InvalidParameterException {
   216         throw new InvalidParameterException("Parameters not supported");
   161         throw new InvalidParameterException("Parameters not supported");
   217     }
   162     }
   218 
   163 
   219     @Override
   164     @Override
   220     protected AlgorithmParameters engineGetParameters() {
   165     protected AlgorithmParameters engineGetParameters() {