Fri, 11 Sep 2020 18:58:51 +0300
8237995: Enhance certificate processing
Reviewed-by: mbalao, andrew
1.1 --- a/src/share/classes/sun/security/util/UntrustedCertificates.java Mon Jun 22 14:30:37 2020 +0100 1.2 +++ b/src/share/classes/sun/security/util/UntrustedCertificates.java Fri Sep 11 18:58:51 2020 +0300 1.3 @@ -31,7 +31,7 @@ 1.4 import java.security.PrivilegedAction; 1.5 import java.security.cert.X509Certificate; 1.6 import java.security.cert.CertificateException; 1.7 -import java.util.*; 1.8 +import java.util.Properties; 1.9 import sun.security.x509.X509CertImpl; 1.10 1.11 /** 1.12 @@ -58,10 +58,6 @@ 1.13 "lib/security/blacklisted.certs"); 1.14 try (FileInputStream fin = new FileInputStream(f)) { 1.15 props.load(fin); 1.16 - // It's said that the fingerprint could contain colons 1.17 - for (Map.Entry<Object,Object> e: props.entrySet()) { 1.18 - e.setValue(stripColons(e.getValue())); 1.19 - } 1.20 } catch (IOException fnfe) { 1.21 if (debug != null) { 1.22 debug.println("Error parsing blacklisted.certs"); 1.23 @@ -73,21 +69,6 @@ 1.24 algorithm = props.getProperty(ALGORITHM_KEY); 1.25 } 1.26 1.27 - private static String stripColons(Object input) { 1.28 - String s = (String)input; 1.29 - char[] letters = s.toCharArray(); 1.30 - int pos = 0; 1.31 - for (int i = 0; i < letters.length; i++) { 1.32 - if (letters[i] != ':') { 1.33 - if (i != pos) { 1.34 - letters[pos] = letters[i]; 1.35 - } 1.36 - pos++; 1.37 - } 1.38 - } 1.39 - if (pos == letters.length) return s; 1.40 - else return new String(letters, 0, pos); 1.41 - } 1.42 /** 1.43 * Checks if a certificate is untrusted. 1.44 *
2.1 --- a/src/share/lib/security/BlacklistedCertsConverter.java Mon Jun 22 14:30:37 2020 +0100 2.2 +++ b/src/share/lib/security/BlacklistedCertsConverter.java Fri Sep 11 18:58:51 2020 +0300 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -23,13 +23,26 @@ 2.11 * questions. 2.12 */ 2.13 2.14 +import java.io.IOException; 2.15 +import java.math.BigInteger; 2.16 import java.security.MessageDigest; 2.17 +import java.security.PublicKey; 2.18 import java.security.NoSuchAlgorithmException; 2.19 import java.security.cert.Certificate; 2.20 import java.security.cert.CertificateEncodingException; 2.21 import java.security.cert.CertificateFactory; 2.22 import java.security.cert.X509Certificate; 2.23 +import java.security.interfaces.ECPublicKey; 2.24 +import java.util.ArrayList; 2.25 +import java.util.Arrays; 2.26 import java.util.Collection; 2.27 +import java.util.List; 2.28 +import java.util.Set; 2.29 +import java.util.TreeSet; 2.30 + 2.31 +import sun.security.util.DerInputStream; 2.32 +import sun.security.util.DerOutputStream; 2.33 +import sun.security.util.DerValue; 2.34 2.35 /** 2.36 * This is the tool to convert blacklisted.certs.pem to blacklisted.certs. 2.37 @@ -50,9 +63,14 @@ 2.38 Collection<? extends Certificate> certs 2.39 = cf.generateCertificates(System.in); 2.40 System.out.println("Algorithm=" + mdAlg); 2.41 + Set<String> fingerprints = new TreeSet<>(); 2.42 for (Certificate cert: certs) { 2.43 - System.out.println( 2.44 - getCertificateFingerPrint(mdAlg, (X509Certificate)cert)); 2.45 + fingerprints.addAll( 2.46 + getCertificateFingerPrints(mdAlg, (X509Certificate)cert)); 2.47 + } 2.48 + 2.49 + for (String s: fingerprints) { 2.50 + System.out.println(s); 2.51 } 2.52 } 2.53 2.54 @@ -69,23 +87,90 @@ 2.55 } 2.56 2.57 /** 2.58 - * Gets the requested finger print of the certificate. 2.59 + * Gets the requested fingerprints of the certificate. 2.60 */ 2.61 - private static String getCertificateFingerPrint(String mdAlg, 2.62 - X509Certificate cert) { 2.63 - String fingerPrint = ""; 2.64 - try { 2.65 - byte[] encCertInfo = cert.getEncoded(); 2.66 + private static List<String> getCertificateFingerPrints( 2.67 + String mdAlg, X509Certificate cert) throws Exception { 2.68 + List<String> fingerprints = new ArrayList<>(); 2.69 + for (byte[] encoding : altEncodings(cert)) { 2.70 MessageDigest md = MessageDigest.getInstance(mdAlg); 2.71 - byte[] digest = md.digest(encCertInfo); 2.72 + byte[] digest = md.digest(encoding); 2.73 StringBuffer buf = new StringBuffer(); 2.74 for (int i = 0; i < digest.length; i++) { 2.75 byte2hex(digest[i], buf); 2.76 } 2.77 - fingerPrint = buf.toString(); 2.78 - } catch (NoSuchAlgorithmException | CertificateEncodingException e) { 2.79 - // ignored 2.80 + fingerprints.add(buf.toString()); 2.81 } 2.82 - return fingerPrint; 2.83 + return fingerprints; 2.84 + } 2.85 + 2.86 + private static List<byte[]> altEncodings(X509Certificate c) 2.87 + throws Exception { 2.88 + List<byte[]> result = new ArrayList<>(); 2.89 + 2.90 + DerValue d = new DerValue(c.getEncoded()); 2.91 + DerValue[] seq = new DerValue[3]; 2.92 + // tbsCertificate 2.93 + seq[0] = d.data.getDerValue(); 2.94 + // signatureAlgorithm 2.95 + seq[1] = d.data.getDerValue(); 2.96 + // signature 2.97 + seq[2] = d.data.getDerValue(); 2.98 + 2.99 + List<DerValue> algIds = Arrays.asList(seq[1], altAlgId(seq[1])); 2.100 + 2.101 + List<DerValue> sigs; 2.102 + PublicKey p = c.getPublicKey(); 2.103 + if (p instanceof ECPublicKey) { 2.104 + ECPublicKey ep = (ECPublicKey) p; 2.105 + BigInteger mod = ep.getParams().getOrder(); 2.106 + sigs = Arrays.asList(seq[2], altSig(mod, seq[2])); 2.107 + } else { 2.108 + sigs = Arrays.asList(seq[2]); 2.109 + } 2.110 + 2.111 + for (DerValue algId : algIds) { 2.112 + for (DerValue sig : sigs) { 2.113 + DerOutputStream tmp = new DerOutputStream(); 2.114 + tmp.putDerValue(seq[0]); 2.115 + tmp.putDerValue(algId); 2.116 + tmp.putDerValue(sig); 2.117 + DerOutputStream tmp2 = new DerOutputStream(); 2.118 + tmp2.write(DerValue.tag_Sequence, tmp); 2.119 + result.add(tmp2.toByteArray()); 2.120 + } 2.121 + } 2.122 + return result; 2.123 + } 2.124 + 2.125 + private static DerValue altSig(BigInteger mod, DerValue sig) 2.126 + throws IOException { 2.127 + byte[] sigBits = sig.getBitString(); 2.128 + DerInputStream in = 2.129 + new DerInputStream(sigBits, 0, sigBits.length, false); 2.130 + DerValue[] values = in.getSequence(2); 2.131 + BigInteger r = values[0].getBigInteger(); 2.132 + BigInteger s = values[1].getBigInteger(); 2.133 + BigInteger s2 = s.negate().mod(mod); 2.134 + DerOutputStream out = new DerOutputStream(); 2.135 + out.putInteger(r); 2.136 + out.putInteger(s2); 2.137 + DerOutputStream tmp = new DerOutputStream(); 2.138 + tmp.putBitString(new DerValue(DerValue.tag_Sequence, 2.139 + out.toByteArray()).toByteArray()); 2.140 + return new DerValue(tmp.toByteArray()); 2.141 + } 2.142 + 2.143 + private static DerValue altAlgId(DerValue algId) throws IOException { 2.144 + DerInputStream in = algId.toDerInputStream(); 2.145 + DerOutputStream bytes = new DerOutputStream(); 2.146 + bytes.putOID(in.getOID()); 2.147 + // encode parameters as NULL if not present or omit if NULL 2.148 + if (in.available() == 0) { 2.149 + bytes.putNull(); 2.150 + } 2.151 + DerOutputStream tmp = new DerOutputStream(); 2.152 + tmp.write(DerValue.tag_Sequence, bytes); 2.153 + return new DerValue(tmp.toByteArray()); 2.154 } 2.155 }
3.1 --- a/src/share/lib/security/blacklisted.certs Mon Jun 22 14:30:37 2020 +0100 3.2 +++ b/src/share/lib/security/blacklisted.certs Fri Sep 11 18:58:51 2020 +0300 3.3 @@ -1,20 +1,39 @@ 3.4 -Algorithm=SHA-256 3.5 -76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645 3.6 -4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE 3.7 -D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F 3.8 -14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD 3.9 -D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967 3.10 -5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B 3.11 -9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC 3.12 -FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B 3.13 -A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083 3.14 -4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176 3.15 -8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF 3.16 -B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD 3.17 -3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66 3.18 -31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133 3.19 -450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2 3.20 -FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD 3.21 -DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE 3.22 -F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7 3.23 -EC30C9C3065A06BB07DC5B1C6B497F370C1CA65C0F30C08E042BA6BCECC78F2C 3.24 +Algorithm=SHA-256 3.25 +03DB9E5E79FE6117177F81C11595AF598CB176AF766290DBCEB2C318B32E39A2 3.26 +08C396C006A21055D00826A5781A5CCFCE2C8D053AB3C197637A4A7A5BB9A650 3.27 +14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD 3.28 +1C5E6985ACC09221DBD1A4B7BBC6D3A8C3F8540D19F20763A9537FDD42B4FFE7 3.29 +1F6BF8A3F2399AF7FD04516C2719C566CBAD51F412738F66D0457E1E6BDE6F2D 3.30 +2A464E4113141352C7962FBD1706ED4B88533EF24D7BBA6CCC5D797FD202F1C4 3.31 +31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133 3.32 +3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66 3.33 +3E11CF90719F6FB44D94EAC9A156B89BEBE7B8598F28EC58913F2BFCAF91D0C0 3.34 +423279423B9FC8CB06F1BB7C3B247522B948D5F18939F378ECC901126DE40BFB 3.35 +450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2 3.36 +4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE 3.37 +4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176 3.38 +535D04DFCE027C70BD5F8A9E0AD4F218E9AFDCF5BBCF9B6DE0D81E148E2E3172 3.39 +568FAF38D9F155F624838E2181B1CEB4D8459305EE652B0F810C97C3611BFE19 3.40 +585CFE6B7436CBD4E732763A2137D7F49599BA9B1790E688FCEC799C58EB84A6 3.41 +5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B 3.42 +71CB00749B9130FB2707A2664BFF958D0FCC8E161D9674C7450BA0FC2BEAF9D3 3.43 +76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645 3.44 +8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF 3.45 +9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC 3.46 +9FADCE80D62A959F9930D748488C1E22E821F4E1E4A43584B848C2FC11E04D77 3.47 +A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083 3.48 +A90132CEA1D4F7185E4F688EFFD16F6AC14DFD78356A807599A5DABBEEF3333E 3.49 +B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD 3.50 +C0D1F42B9F4BF7ACC045B7BB5D4805E10737F67B6310CE505248D543D0D5FE07 3.51 +D0156949F1381943442C6974E9B5B49EF441BB799EF20477B90A89C3F33620CE 3.52 +D151962D954970501C60079258EBCFA38502E0A9F03CD640322B08C0A3117FE5 3.53 +D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F 3.54 +D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967 3.55 +D6CEAE5D9E047FAF7D797858D229AC991AD44316D1E2A37A21926D763153593A 3.56 +DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE 3.57 +E0E740E4B0F8B3548181FF75B5372FAF4C70B99EC995D694ED0FB91B03FF8D21 3.58 +EC30C9C3065A06BB07DC5B1C6B497F370C1CA65C0F30C08E042BA6BCECC78F2C 3.59 +F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7 3.60 +FBB12938ABD86C125796EDF4162D291028890A7D6C0C1CCA75FD4B95EBFA7A1A 3.61 +FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD 3.62 +FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B
4.1 --- a/test/lib/security/CheckBlacklistedCerts.java Mon Jun 22 14:30:37 2020 +0100 4.2 +++ b/test/lib/security/CheckBlacklistedCerts.java Fri Sep 11 18:58:51 2020 +0300 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -23,7 +23,7 @@ 4.11 4.12 /* 4.13 * @test 4.14 - * @bug 8011402 4.15 + * @bug 8011402 8237995 4.16 * @summary Move blacklisting certificate logic from hard code to data 4.17 */ 4.18 4.19 @@ -115,7 +115,8 @@ 4.20 System.out.println("There are " + acount + " algorithms"); 4.21 failed = true; 4.22 } 4.23 - if (ccount != blacklisted.size() 4.24 + // There are two unique fingerprints for each RSA certificate 4.25 + if (ccount != blacklisted.size() * 2 4.26 && !blacklisted.isEmpty()) { 4.27 System.out.println("Wrong blacklisted.certs size: " 4.28 + ccount + " fingerprints, "