8237995: Enhance certificate processing

Fri, 11 Sep 2020 18:58:51 +0300

author
yan
date
Fri, 11 Sep 2020 18:58:51 +0300
changeset 14212
eca1dcb470d8
parent 14211
ccf97104b8ea
child 14213
cb50526a9629

8237995: Enhance certificate processing
Reviewed-by: mbalao, andrew

src/share/classes/sun/security/util/UntrustedCertificates.java file | annotate | diff | comparison | revisions
src/share/lib/security/BlacklistedCertsConverter.java file | annotate | diff | comparison | revisions
src/share/lib/security/blacklisted.certs file | annotate | diff | comparison | revisions
test/lib/security/CheckBlacklistedCerts.java file | annotate | diff | comparison | revisions
     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, "

mercurial