changeset 9990:2cde484ef248

8237995: Enhance certificate processing Reviewed-by: bae, dcherepanov
author yan
date Fri, 11 Sep 2020 18:58:51 +0300
parents 06c643a674d2
children 0cff9d23573a
files src/share/classes/sun/security/util/UntrustedCertificates.java src/share/lib/security/BlacklistedCertsConverter.java src/share/lib/security/blacklisted.certs test/lib/security/CheckBlacklistedCerts.java
diffstat 4 files changed, 143 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/util/UntrustedCertificates.java	Wed May 20 08:07:25 2020 -0400
+++ b/src/share/classes/sun/security/util/UntrustedCertificates.java	Fri Sep 11 18:58:51 2020 +0300
@@ -31,7 +31,7 @@
 import java.security.PrivilegedAction;
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
-import java.util.*;
+import java.util.Properties;
 import sun.security.x509.X509CertImpl;
 
 /**
@@ -58,10 +58,6 @@
                         "lib/security/blacklisted.certs");
                 try (FileInputStream fin = new FileInputStream(f)) {
                     props.load(fin);
-                    // It's said that the fingerprint could contain colons
-                    for (Map.Entry<Object,Object> e: props.entrySet()) {
-                        e.setValue(stripColons(e.getValue()));
-                    }
                 } catch (IOException fnfe) {
                     if (debug != null) {
                         debug.println("Error parsing blacklisted.certs");
@@ -73,21 +69,6 @@
         algorithm = props.getProperty(ALGORITHM_KEY);
     }
 
-    private static String stripColons(Object input) {
-        String s = (String)input;
-        char[] letters = s.toCharArray();
-        int pos = 0;
-        for (int i = 0; i < letters.length; i++) {
-            if (letters[i] != ':') {
-                if (i != pos) {
-                    letters[pos] = letters[i];
-                }
-                pos++;
-            }
-        }
-        if (pos == letters.length) return s;
-        else return new String(letters, 0, pos);
-    }
     /**
      * Checks if a certificate is untrusted.
      *
--- a/src/share/lib/security/BlacklistedCertsConverter.java	Wed May 20 08:07:25 2020 -0400
+++ b/src/share/lib/security/BlacklistedCertsConverter.java	Fri Sep 11 18:58:51 2020 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,13 +21,26 @@
  * questions.
  */
 
+import java.io.IOException;
+import java.math.BigInteger;
 import java.security.MessageDigest;
+import java.security.PublicKey;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import sun.security.util.DerInputStream;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
 
 /**
  * This is the tool to convert blacklisted.certs.pem to blacklisted.certs.
@@ -48,9 +61,14 @@
         Collection<? extends Certificate> certs
                 = cf.generateCertificates(System.in);
         System.out.println("Algorithm=" + mdAlg);
+        Set<String> fingerprints = new TreeSet<>();
         for (Certificate cert: certs) {
-            System.out.println(
-                    getCertificateFingerPrint(mdAlg, (X509Certificate)cert));
+            fingerprints.addAll(
+                    getCertificateFingerPrints(mdAlg, (X509Certificate)cert));
+        }
+
+        for (String s: fingerprints) {
+            System.out.println(s);
         }
     }
 
@@ -67,23 +85,90 @@
     }
 
     /**
-     * Gets the requested finger print of the certificate.
+     * Gets the requested fingerprints of the certificate.
      */
-    private static String getCertificateFingerPrint(String mdAlg,
-                                                    X509Certificate cert) {
-        String fingerPrint = "";
-        try {
-            byte[] encCertInfo = cert.getEncoded();
+    private static List<String> getCertificateFingerPrints(
+            String mdAlg, X509Certificate cert) throws Exception {
+        List<String> fingerprints = new ArrayList<>();
+        for (byte[] encoding : altEncodings(cert)) {
             MessageDigest md = MessageDigest.getInstance(mdAlg);
-            byte[] digest = md.digest(encCertInfo);
+            byte[] digest = md.digest(encoding);
             StringBuffer buf = new StringBuffer();
             for (int i = 0; i < digest.length; i++) {
                 byte2hex(digest[i], buf);
             }
-            fingerPrint = buf.toString();
-        } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
-            // ignored
+            fingerprints.add(buf.toString());
+        }
+        return fingerprints;
+    }
+
+    private static List<byte[]> altEncodings(X509Certificate c)
+            throws Exception {
+        List<byte[]> result = new ArrayList<>();
+
+        DerValue d = new DerValue(c.getEncoded());
+        DerValue[] seq = new DerValue[3];
+        // tbsCertificate
+        seq[0] = d.data.getDerValue();
+        // signatureAlgorithm
+        seq[1] = d.data.getDerValue();
+        // signature
+        seq[2] = d.data.getDerValue();
+
+        List<DerValue> algIds = Arrays.asList(seq[1], altAlgId(seq[1]));
+
+        List<DerValue> sigs;
+        PublicKey p = c.getPublicKey();
+        if (p instanceof ECPublicKey) {
+            ECPublicKey ep = (ECPublicKey) p;
+            BigInteger mod = ep.getParams().getOrder();
+            sigs = Arrays.asList(seq[2], altSig(mod, seq[2]));
+        } else {
+            sigs = Arrays.asList(seq[2]);
         }
-        return fingerPrint;
+
+        for (DerValue algId : algIds) {
+            for (DerValue sig : sigs) {
+                DerOutputStream tmp = new DerOutputStream();
+                tmp.putDerValue(seq[0]);
+                tmp.putDerValue(algId);
+                tmp.putDerValue(sig);
+                DerOutputStream tmp2 = new DerOutputStream();
+                tmp2.write(DerValue.tag_Sequence, tmp);
+                result.add(tmp2.toByteArray());
+            }
+        }
+        return result;
+    }
+
+    private static DerValue altSig(BigInteger mod, DerValue sig)
+            throws IOException {
+        byte[] sigBits = sig.getBitString();
+        DerInputStream in =
+            new DerInputStream(sigBits, 0, sigBits.length, false);
+        DerValue[] values = in.getSequence(2);
+        BigInteger r = values[0].getBigInteger();
+        BigInteger s = values[1].getBigInteger();
+        BigInteger s2 = s.negate().mod(mod);
+        DerOutputStream out = new DerOutputStream();
+        out.putInteger(r);
+        out.putInteger(s2);
+        DerOutputStream tmp = new DerOutputStream();
+        tmp.putBitString(new DerValue(DerValue.tag_Sequence,
+                out.toByteArray()).toByteArray());
+        return new DerValue(tmp.toByteArray());
+    }
+
+    private static DerValue altAlgId(DerValue algId) throws IOException {
+        DerInputStream in = algId.toDerInputStream();
+        DerOutputStream bytes = new DerOutputStream();
+        bytes.putOID(in.getOID());
+        // encode parameters as NULL if not present or omit if NULL
+        if (in.available() == 0) {
+            bytes.putNull();
+        }
+        DerOutputStream tmp = new DerOutputStream();
+        tmp.write(DerValue.tag_Sequence, bytes);
+        return new DerValue(tmp.toByteArray());
     }
 }
--- a/src/share/lib/security/blacklisted.certs	Wed May 20 08:07:25 2020 -0400
+++ b/src/share/lib/security/blacklisted.certs	Fri Sep 11 18:58:51 2020 +0300
@@ -1,20 +1,39 @@
-Algorithm=SHA-256
-76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645
-4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE
-D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F
-14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD
-D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967
-5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B
-9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC
-FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B
-A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083
-4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176
-8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF
-B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD
-3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66
-31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133
-450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2
-FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD
-DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE
-F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7
-EC30C9C3065A06BB07DC5B1C6B497F370C1CA65C0F30C08E042BA6BCECC78F2C
+Algorithm=SHA-256
+03DB9E5E79FE6117177F81C11595AF598CB176AF766290DBCEB2C318B32E39A2
+08C396C006A21055D00826A5781A5CCFCE2C8D053AB3C197637A4A7A5BB9A650
+14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD
+1C5E6985ACC09221DBD1A4B7BBC6D3A8C3F8540D19F20763A9537FDD42B4FFE7
+1F6BF8A3F2399AF7FD04516C2719C566CBAD51F412738F66D0457E1E6BDE6F2D
+2A464E4113141352C7962FBD1706ED4B88533EF24D7BBA6CCC5D797FD202F1C4
+31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133
+3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66
+3E11CF90719F6FB44D94EAC9A156B89BEBE7B8598F28EC58913F2BFCAF91D0C0
+423279423B9FC8CB06F1BB7C3B247522B948D5F18939F378ECC901126DE40BFB
+450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2
+4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE
+4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176
+535D04DFCE027C70BD5F8A9E0AD4F218E9AFDCF5BBCF9B6DE0D81E148E2E3172
+568FAF38D9F155F624838E2181B1CEB4D8459305EE652B0F810C97C3611BFE19
+585CFE6B7436CBD4E732763A2137D7F49599BA9B1790E688FCEC799C58EB84A6
+5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B
+71CB00749B9130FB2707A2664BFF958D0FCC8E161D9674C7450BA0FC2BEAF9D3
+76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645
+8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF
+9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC
+9FADCE80D62A959F9930D748488C1E22E821F4E1E4A43584B848C2FC11E04D77
+A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083
+A90132CEA1D4F7185E4F688EFFD16F6AC14DFD78356A807599A5DABBEEF3333E
+B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD
+C0D1F42B9F4BF7ACC045B7BB5D4805E10737F67B6310CE505248D543D0D5FE07
+D0156949F1381943442C6974E9B5B49EF441BB799EF20477B90A89C3F33620CE
+D151962D954970501C60079258EBCFA38502E0A9F03CD640322B08C0A3117FE5
+D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F
+D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967
+D6CEAE5D9E047FAF7D797858D229AC991AD44316D1E2A37A21926D763153593A
+DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE
+E0E740E4B0F8B3548181FF75B5372FAF4C70B99EC995D694ED0FB91B03FF8D21
+EC30C9C3065A06BB07DC5B1C6B497F370C1CA65C0F30C08E042BA6BCECC78F2C
+F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7
+FBB12938ABD86C125796EDF4162D291028890A7D6C0C1CCA75FD4B95EBFA7A1A
+FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD
+FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B
--- a/test/lib/security/CheckBlacklistedCerts.java	Wed May 20 08:07:25 2020 -0400
+++ b/test/lib/security/CheckBlacklistedCerts.java	Fri Sep 11 18:58:51 2020 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8011402
+ * @bug 8011402 8237995
  * @summary Move blacklisting certificate logic from hard code to data
  */
 
@@ -115,7 +115,8 @@
                 System.out.println("There are " + acount + " algorithms");
                 failed = true;
             }
-            if (ccount != blacklisted.size()
+            // There are two unique fingerprints for each RSA certificate
+            if (ccount != blacklisted.size() * 2
                     && !blacklisted.isEmpty()) {
                 System.out.println("Wrong blacklisted.certs size: "
                         + ccount + " fingerprints, "