changeset 51373:514035618c1d

8201290: keytool importcert fails with CertificateParsingException if unknown certificate algorithms should be imported Reviewed-by: mullan, xuelei
author weijun
date Fri, 10 Aug 2018 17:07:44 +0800
parents 4737d92d752f
children 7be0084191ed
files src/java.base/share/classes/sun/security/tools/keytool/Main.java
diffstat 1 files changed, 45 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Aug 10 13:07:21 2018 +0800
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Aug 10 17:07:44 2018 +0800
@@ -34,6 +34,7 @@
 import java.security.KeyStoreException;
 import java.security.MessageDigest;
 import java.security.Key;
+import java.security.NoSuchProviderException;
 import java.security.PublicKey;
 import java.security.PrivateKey;
 import java.security.Signature;
@@ -159,7 +160,6 @@
     private boolean srcprotectedPath = false;
     private boolean cacerts = false;
     private boolean nowarn = false;
-    private CertificateFactory cf = null;
     private KeyStore caks = null; // "cacerts" keystore
     private char[] srcstorePass = null;
     private String srcstoretype = null;
@@ -240,7 +240,9 @@
             PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
             PROVIDERPATH, V, PROTECTED),
         PRINTCERT("Prints.the.content.of.a.certificate",
-            RFC, FILEIN, SSLSERVER, JARFILE, V),
+            RFC, FILEIN, SSLSERVER, JARFILE,
+            PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
+            PROVIDERPATH, V),
         PRINTCERTREQ("Prints.the.content.of.a.certificate.request",
             FILEIN, V),
         PRINTCRL("Prints.the.content.of.a.CRL.file",
@@ -1067,12 +1069,6 @@
             }
         }
 
-        // Create a certificate factory
-        if (command == PRINTCERT || command == IMPORTCERT
-                || command == IDENTITYDB || command == PRINTCRL) {
-            cf = CertificateFactory.getInstance("X509");
-        }
-
         // -trustcacerts can only be specified on -importcert.
         // Reset it so that warnings on CA cert will remain for
         // -printcert, etc.
@@ -2596,7 +2592,7 @@
     {
         Collection<? extends Certificate> c = null;
         try {
-            c = cf.generateCertificates(in);
+            c = generateCertificates(in);
         } catch (CertificateException ce) {
             throw new Exception(rb.getString("Failed.to.parse.input"), ce);
         }
@@ -2628,6 +2624,44 @@
         }
     }
 
+    private Collection<? extends Certificate> generateCertificates(InputStream in)
+            throws CertificateException, IOException {
+        byte[] data = in.readAllBytes();
+        try {
+            return CertificateFactory.getInstance("X.509")
+                    .generateCertificates(new ByteArrayInputStream(data));
+        } catch (CertificateException e) {
+            if (providerName != null) {
+                try {
+                    return CertificateFactory.getInstance("X.509", providerName)
+                            .generateCertificates(new ByteArrayInputStream(data));
+                } catch (Exception e2) {
+                    e.addSuppressed(e2);
+                }
+            }
+            throw e;
+        }
+    }
+
+    private Certificate generateCertificate(InputStream in)
+            throws CertificateException, IOException {
+        byte[] data = in.readAllBytes();
+        try {
+            return CertificateFactory.getInstance("X.509")
+                    .generateCertificate(new ByteArrayInputStream(data));
+        } catch (CertificateException e) {
+            if (providerName != null) {
+                try {
+                    return CertificateFactory.getInstance("X.509", providerName)
+                            .generateCertificate(new ByteArrayInputStream(data));
+                } catch (Exception e2) {
+                    e.addSuppressed(e2);
+                }
+            }
+            throw e;
+        }
+    }
+
     private static String oneInMany(String label, int i, int num) {
         if (num == 1) {
             return label;
@@ -2922,7 +2956,7 @@
         }
 
         // Read the certificates in the reply
-        Collection<? extends Certificate> c = cf.generateCertificates(in);
+        Collection<? extends Certificate> c = generateCertificates(in);
         if (c.isEmpty()) {
             throw new Exception(rb.getString("Reply.has.no.certificates"));
         }
@@ -2969,7 +3003,7 @@
         // Read the certificate
         X509Certificate cert = null;
         try {
-            cert = (X509Certificate)cf.generateCertificate(in);
+            cert = (X509Certificate)generateCertificate(in);
         } catch (ClassCastException | CertificateException ce) {
             throw new Exception(rb.getString("Input.not.an.X.509.certificate"));
         }