OpenJDK / jdk-updates / jdk11u
changeset 53504:adc949b07eeb
8237995: Enhance certificate processing
Reviewed-by: weijun, rhalade, ahgross, erikj, mbalao, andrew
author | mullan |
---|---|
date | Wed, 06 May 2020 07:25:59 -0400 |
parents | e8b4096c7091 |
children | 52fbbaed4d22 |
files | make/CompileToolsJdk.gmk make/ToolsJdk.gmk make/data/blacklistedcertsconverter/blacklisted.certs.pem make/jdk/src/classes/build/tools/blacklistedcertsconverter/BlacklistedCertsConverter.java src/java.base/share/classes/sun/security/util/UntrustedCertificates.java test/jdk/sun/security/lib/CheckBlacklistedCerts.java |
diffstat | 6 files changed, 106 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/make/CompileToolsJdk.gmk Mon Jun 22 14:30:37 2020 +0100 +++ b/make/CompileToolsJdk.gmk Wed May 06 07:25:59 2020 -0400 @@ -55,6 +55,7 @@ ADD_JAVAC_FLAGS := \ --add-exports java.desktop/sun.awt=ALL-UNNAMED \ --add-exports java.base/sun.text=ALL-UNNAMED \ + --add-exports java.base/sun.security.util=ALL-UNNAMED \ , \ ))
--- a/make/ToolsJdk.gmk Mon Jun 22 14:30:37 2020 +0100 +++ b/make/ToolsJdk.gmk Wed May 06 07:25:59 2020 -0400 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -74,6 +74,7 @@ build.tools.tzdb.TzdbZoneRulesCompiler TOOL_BLACKLISTED_CERTS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ + --add-exports java.base/sun.security.util=ALL-UNNAMED \ build.tools.blacklistedcertsconverter.BlacklistedCertsConverter TOOL_MAKEJAVASECURITY = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
--- a/make/data/blacklistedcertsconverter/blacklisted.certs.pem Mon Jun 22 14:30:37 2020 +0100 +++ b/make/data/blacklistedcertsconverter/blacklisted.certs.pem Wed May 06 07:25:59 2020 -0400 @@ -1,8 +1,7 @@ #! java BlacklistedCertsConverter SHA-256 -# The line above must be the first line of the blacklisted.certs.pem -# file inside src/share/lib/security/. It will be ignored if added in -# src/closed/share/lib/security/blacklisted.certs.pem. +# The line above must be the first line of this file. Do not +# remove it. // Subject: CN=Digisign Server ID (Enrich), // OU=457608-K,
--- a/make/jdk/src/classes/build/tools/blacklistedcertsconverter/BlacklistedCertsConverter.java Mon Jun 22 14:30:37 2020 +0100 +++ b/make/jdk/src/classes/build/tools/blacklistedcertsconverter/BlacklistedCertsConverter.java Wed May 06 07:25:59 2020 -0400 @@ -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 @@ -25,14 +25,24 @@ package build.tools.blacklistedcertsconverter; +import java.io.IOException; +import java.math.BigInteger; import java.security.MessageDigest; +import java.security.PublicKey; import java.security.cert.Certificate; 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; /** * Converts blacklisted.certs.pem from System.in to blacklisted.certs in @@ -75,8 +85,8 @@ // Output sorted so that it's easy to locate an entry. Set<String> fingerprints = new TreeSet<>(); for (Certificate cert: certs) { - fingerprints.add( - getCertificateFingerPrint(mdAlg, (X509Certificate)cert)); + fingerprints.addAll( + getCertificateFingerPrints(mdAlg, (X509Certificate)cert)); } for (String s: fingerprints) { @@ -97,17 +107,90 @@ } /** - * Gets the requested finger print of the certificate. + * Computes the possible fingerprints of the certificate. */ - private static String getCertificateFingerPrint( + private static List<String> getCertificateFingerPrints( String mdAlg, X509Certificate cert) throws Exception { - byte[] encCertInfo = cert.getEncoded(); - MessageDigest md = MessageDigest.getInstance(mdAlg); - byte[] digest = md.digest(encCertInfo); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < digest.length; i++) { - byte2hex(digest[i], buf); + List<String> fingerprints = new ArrayList<>(); + for (byte[] encoding : altEncodings(cert)) { + MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] digest = md.digest(encoding); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < digest.length; i++) { + byte2hex(digest[i], buf); + } + 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 buf.toString(); + + 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/java.base/share/classes/sun/security/util/UntrustedCertificates.java Mon Jun 22 14:30:37 2020 +0100 +++ b/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java Wed May 06 07:25:59 2020 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -29,7 +29,7 @@ import java.security.PrivilegedAction; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; -import java.util.*; +import java.util.Properties; import jdk.internal.util.StaticProperty; 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/test/jdk/sun/security/lib/CheckBlacklistedCerts.java Mon Jun 22 14:30:37 2020 +0100 +++ b/test/jdk/sun/security/lib/CheckBlacklistedCerts.java Wed May 06 07:25:59 2020 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, 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 8211969 + * @bug 8011402 8211969 8237995 * @summary Move blacklisting certificate logic from hard code to data * @modules java.base/sun.security.util */ @@ -99,7 +99,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, "