src/java.base/share/classes/sun/security/x509/X509CertImpl.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 47478 438e0c9f2f17
child 53018 8bf9268df0e2
--- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Fri May 11 14:55:56 2018 -0700
+++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Fri May 11 15:53:12 2018 -0700
@@ -34,6 +34,7 @@
 import java.io.OutputStream;
 import java.math.BigInteger;
 import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
 import java.security.cert.*;
 import java.security.cert.Certificate;
 import java.util.*;
@@ -41,7 +42,6 @@
 
 import javax.security.auth.x500.X500Principal;
 
-import sun.security.util.HexDumpEncoder;
 import java.util.Base64;
 import sun.security.util.*;
 import sun.security.provider.X509Factory;
@@ -388,7 +388,6 @@
     public void verify(PublicKey key)
     throws CertificateException, NoSuchAlgorithmException,
         InvalidKeyException, NoSuchProviderException, SignatureException {
-
         verify(key, "");
     }
 
@@ -435,8 +434,19 @@
         } else {
             sigVerf = Signature.getInstance(algId.getName(), sigProvider);
         }
+
         sigVerf.initVerify(key);
 
+        // set parameters after Signature.initSign/initVerify call,
+        // so the deferred provider selection happens when key is set
+        try {
+            SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
+        } catch (ProviderException e) {
+            throw new CertificateException(e.getMessage(), e.getCause());
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new CertificateException(e);
+        }
+
         byte[] rawCert = info.getEncodedInfo();
         sigVerf.update(rawCert, 0, rawCert.length);
 
@@ -480,8 +490,19 @@
         } else {
             sigVerf = Signature.getInstance(algId.getName(), sigProvider);
         }
+
         sigVerf.initVerify(key);
 
+        // set parameters after Signature.initSign/initVerify call,
+        // so the deferred provider selection happens when key is set
+        try {
+            SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
+        } catch (ProviderException e) {
+            throw new CertificateException(e.getMessage(), e.getCause());
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new CertificateException(e);
+        }
+
         byte[] rawCert = info.getEncodedInfo();
         sigVerf.update(rawCert, 0, rawCert.length);
 
@@ -537,6 +558,42 @@
     throws CertificateException, NoSuchAlgorithmException,
         InvalidKeyException, NoSuchProviderException, SignatureException {
         try {
+            sign(key, null, algorithm, provider);
+        } catch (InvalidAlgorithmParameterException e) {
+            // should not happen; re-throw just in case
+            throw new SignatureException(e);
+        }
+    }
+
+    /**
+     * Creates an X.509 certificate, and signs it using the given key
+     * (associating a signature algorithm and an X.500 name), signature
+     * parameters, and security provider. If the given provider name
+     * is null or empty, the implementation look up will be based on
+     * provider configurations.
+     * This operation is used to implement the certificate generation
+     * functionality of a certificate authority.
+     *
+     * @param key the private key used for signing
+     * @param signingParams the parameters used for signing
+     * @param algorithm the name of the signature algorithm used
+     * @param provider the name of the provider, may be null
+     *
+     * @exception NoSuchAlgorithmException on unsupported signature
+     *            algorithms
+     * @exception InvalidKeyException on incorrect key
+     * @exception InvalidAlgorithmParameterException on invalid signature
+     *            parameters
+     * @exception NoSuchProviderException on incorrect provider
+     * @exception SignatureException on signature errors
+     * @exception CertificateException on encoding errors
+     */
+    public void sign(PrivateKey key, AlgorithmParameterSpec signingParams,
+            String algorithm, String provider)
+            throws CertificateException, NoSuchAlgorithmException,
+            InvalidKeyException, InvalidAlgorithmParameterException,
+            NoSuchProviderException, SignatureException {
+        try {
             if (readOnly)
                 throw new CertificateEncodingException(
                               "cannot over-write existing certificate");
@@ -548,9 +605,22 @@
 
             sigEngine.initSign(key);
 
-                                // in case the name is reset
-            algId = AlgorithmId.get(sigEngine.getAlgorithm());
+            // set parameters after Signature.initSign/initVerify call, so
+            // the deferred provider selection happens when the key is set
+            try {
+                sigEngine.setParameter(signingParams);
+            } catch (UnsupportedOperationException e) {
+                // for backward compatibility, only re-throw when
+                // parameters is not null
+                if (signingParams != null) throw e;
+            }
 
+            // in case the name is reset
+            if (signingParams != null) {
+                algId = AlgorithmId.get(sigEngine.getParameters());
+            } else {
+                algId = AlgorithmId.get(algorithm);
+            }
             DerOutputStream out = new DerOutputStream();
             DerOutputStream tmp = new DerOutputStream();