--- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Mon May 21 17:17:24 2018 -0400
+++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java Mon May 21 23:40:52 2018 +0000
@@ -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();