From 7459aba3fba90021c7f1cbdf3d305aece2797b80 Mon Sep 17 00:00:00 2001 From: alvdavi Date: Sun, 12 Jan 2020 06:59:35 +0000 Subject: [PATCH] 8230318: Better trust store usage Reviewed-by: andrew --- .../sun/security/validator/PKIXValidator.java | 59 +++++++++++++++++-- .../tools/jarsigner/TsacertOptionTest.java | 1 + .../sun/security/tools/jarsigner/Warning.java | 2 +- .../tools/jarsigner/concise_jarsigner.sh | 4 +- test/sun/security/tools/jarsigner/ec.sh | 2 +- .../security/tools/jarsigner/onlymanifest.sh | 2 +- .../warnings/BadExtendedKeyUsageTest.java | 4 +- .../jarsigner/warnings/BadKeyUsageTest.java | 4 +- .../warnings/BadNetscapeCertTypeTest.java | 4 +- .../warnings/ChainNotValidatedTest.java | 4 +- .../warnings/HasExpiredCertTest.java | 4 +- .../warnings/HasExpiringCertTest.java | 4 +- .../warnings/HasUnsignedEntryTest.java | 4 +- .../warnings/MultipleWarningsTest.java | 4 +- .../jarsigner/warnings/NoTimestampTest.java | 4 +- .../warnings/NotSignedByAliasTest.java | 4 +- .../warnings/NotYetValidCertTest.java | 4 +- .../validator/EndEntityExtensionCheck.java | 3 +- 18 files changed, 85 insertions(+), 32 deletions(-) diff --git a/src/share/classes/sun/security/validator/PKIXValidator.java b/src/share/classes/sun/security/validator/PKIXValidator.java index f46017dd8..d6d973c39 100644 --- a/src/share/classes/sun/security/validator/PKIXValidator.java +++ b/src/share/classes/sun/security/validator/PKIXValidator.java @@ -32,6 +32,7 @@ import java.security.cert.*; import javax.security.auth.x500.X500Principal; import sun.security.action.GetBooleanAction; +import sun.security.action.GetPropertyAction; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.provider.certpath.PKIXExtendedParameters; @@ -64,6 +65,18 @@ public final class PKIXValidator extends Validator { // enable use of the validator if possible private final static boolean TRY_VALIDATOR = true; + /** + * System property that if set (or set to "true"), allows trust anchor + * certificates to be used if they do not have the proper CA extensions. + * Set to false if prop is not set, or set to any other value. + */ + private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor(); + private static boolean allowNonCaAnchor() { + String prop = GetPropertyAction + .privilegedGetProperty("jdk.security.allowNonCaAnchor"); + return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true")); + } + private final Set trustedCerts; private final PKIXBuilderParameters parameterTemplate; private int certPathLength = -1; @@ -322,15 +335,18 @@ public final class PKIXValidator extends Validator { private static X509Certificate[] toArray(CertPath path, TrustAnchor anchor) throws CertificateException { - List list = - path.getCertificates(); - X509Certificate[] chain = new X509Certificate[list.size() + 1]; - list.toArray(chain); X509Certificate trustedCert = anchor.getTrustedCert(); if (trustedCert == null) { throw new ValidatorException ("TrustAnchor must be specified as certificate"); } + + verifyTrustAnchor(trustedCert); + + List list = + path.getCertificates(); + X509Certificate[] chain = new X509Certificate[list.size() + 1]; + list.toArray(chain); chain[chain.length - 1] = trustedCert; return chain; } @@ -365,6 +381,41 @@ public final class PKIXValidator extends Validator { } } + /** + * Verify that a trust anchor certificate is a CA certificate. + */ + private static void verifyTrustAnchor(X509Certificate trustedCert) + throws ValidatorException { + + // skip check if jdk.security.allowNonCAAnchor system property is set + if (ALLOW_NON_CA_ANCHOR) { + return; + } + + // allow v1 trust anchor certificates + if (trustedCert.getVersion() < 3) { + return; + } + + // check that the BasicConstraints cA field is not set to false + if (trustedCert.getBasicConstraints() == -1) { + throw new ValidatorException + ("TrustAnchor with subject \"" + + trustedCert.getSubjectX500Principal() + + "\" is not a CA certificate"); + } + + // check that the KeyUsage extension, if included, asserts the + // keyCertSign bit + boolean[] keyUsageBits = trustedCert.getKeyUsage(); + if (keyUsageBits != null && !keyUsageBits[5]) { + throw new ValidatorException + ("TrustAnchor with subject \"" + + trustedCert.getSubjectX500Principal() + + "\" does not have keyCertSign bit set in KeyUsage extension"); + } + } + private X509Certificate[] doBuild(X509Certificate[] chain, Collection otherCerts, PKIXBuilderParameters params) throws CertificateException { diff --git a/test/sun/security/tools/jarsigner/TsacertOptionTest.java b/test/sun/security/tools/jarsigner/TsacertOptionTest.java index 96116e1ef..0bf70d35d 100644 --- a/test/sun/security/tools/jarsigner/TsacertOptionTest.java +++ b/test/sun/security/tools/jarsigner/TsacertOptionTest.java @@ -87,6 +87,7 @@ public class TsacertOptionTest { "-storepass", PASSWORD, "-keypass", PASSWORD, "-dname", "CN=CA", + "-ext", "bc:c", "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0); ProcessTools.executeCommand(KEYTOOL, "-genkey", diff --git a/test/sun/security/tools/jarsigner/Warning.java b/test/sun/security/tools/jarsigner/Warning.java index 095d20534..adb783348 100644 --- a/test/sun/security/tools/jarsigner/Warning.java +++ b/test/sun/security/tools/jarsigner/Warning.java @@ -42,7 +42,7 @@ public class Warning { Files.deleteIfExists(Paths.get("ks")); - newCert("ca", "-validity 365000"); + newCert("ca", "-validity 365000", "-ext bc:c"); recreateJar(); diff --git a/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/test/sun/security/tools/jarsigner/concise_jarsigner.sh index e299eb05a..b2affb490 100644 --- a/test/sun/security/tools/jarsigner/concise_jarsigner.sh +++ b/test/sun/security/tools/jarsigner/concise_jarsigner.sh @@ -224,8 +224,8 @@ $JARSIGNER -verify a.jar # ========================================================== $KT -genkeypair -alias ee -dname CN=ee -$KT -genkeypair -alias caone -dname CN=caone -$KT -genkeypair -alias catwo -dname CN=catwo +$KT -genkeypair -alias caone -dname CN=caone -ext bc:c +$KT -genkeypair -alias catwo -dname CN=catwo -ext bc:c $KT -certreq -alias ee | $KT -gencert -alias catwo -rfc > ee.cert $KT -certreq -alias catwo | $KT -gencert -alias caone -sigalg MD5withRSA -rfc > catwo.cert diff --git a/test/sun/security/tools/jarsigner/ec.sh b/test/sun/security/tools/jarsigner/ec.sh index 442e85463..2893dca63 100644 --- a/test/sun/security/tools/jarsigner/ec.sh +++ b/test/sun/security/tools/jarsigner/ec.sh @@ -53,7 +53,7 @@ rm $KS $JFILE echo A > A $JAR cvf $JFILE A -$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 || exit 11 +$KT -alias ca -dname CN=ca -keyalg ec -genkey -validity 300 -ext bc:c || exit 11 $KT -alias a -dname CN=a -keyalg ec -genkey || exit 11 $KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 111 diff --git a/test/sun/security/tools/jarsigner/onlymanifest.sh b/test/sun/security/tools/jarsigner/onlymanifest.sh index bbc90a1b3..cc42e8f32 100644 --- a/test/sun/security/tools/jarsigner/onlymanifest.sh +++ b/test/sun/security/tools/jarsigner/onlymanifest.sh @@ -57,7 +57,7 @@ rm $KS $JFILE 2> /dev/null echo "Key: Value" > manifest $JAR cvfm $JFILE manifest -$KT -alias ca -dname CN=ca -genkey -validity 300 || exit 1 +$KT -alias ca -dname CN=ca -genkey -validity 300 -ext bc:c || exit 1 $KT -alias a -dname CN=a -genkey -validity 300 || exit 2 $KT -alias a -certreq | $KT -gencert -alias ca -validity 300 | $KT -import -alias a || exit 3 $JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 4 diff --git a/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java b/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java index 1a49c15d1..bb0f4484f 100644 --- a/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java +++ b/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -53,7 +53,7 @@ public class BadExtendedKeyUsageTest extends Test { // create a certificate whose signer certificate's // ExtendedKeyUsage extension doesn't allow code signing // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff --git a/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java b/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java index fb0fac9fd..46cd5648f 100644 --- a/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java +++ b/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -53,7 +53,7 @@ public class BadKeyUsageTest extends Test { // create a certificate whose signer certificate's KeyUsage extension // doesn't allow code signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff --git a/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java b/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java index 443331dde..0d1a063a2 100644 --- a/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java +++ b/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -54,7 +54,7 @@ public class BadNetscapeCertTypeTest extends Test { // create a certificate whose signer certificate's // NetscapeCertType extension doesn't allow code signing // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff --git a/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java b/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java index b9d0ae59e..6055546f2 100644 --- a/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java +++ b/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -54,7 +54,7 @@ public class ChainNotValidatedTest extends Test { // Root CA is not checked at all. If the intermediate CA has // BasicConstraints extension set to true, it will be valid. // Otherwise, chain validation will fail. - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(CA2_KEY_ALIAS); issueCert(CA2_KEY_ALIAS, "-ext", diff --git a/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java b/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java index f457776fb..1a8ee1708 100644 --- a/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java +++ b/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -52,7 +52,7 @@ public class HasExpiredCertTest extends Test { JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff --git a/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java b/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java index 8a71c6678..c414f48dc 100644 --- a/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java +++ b/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -52,7 +52,7 @@ public class HasExpiringCertTest extends Test { JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create key pair for jar signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff --git a/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java b/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java index 078ff8962..1aafc58ed 100644 --- a/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java +++ b/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -51,7 +51,7 @@ public class HasUnsignedEntryTest extends Test { JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create key pair for signing - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( KEY_ALIAS, diff --git a/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java b/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java index 862e8cae7..0831dc59f 100644 --- a/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java +++ b/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -54,7 +54,7 @@ public class MultipleWarningsTest extends Test { // create a jar file that contains one class file JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); // create first expired certificate // whose ExtendedKeyUsage extension does not allow code signing diff --git a/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java b/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java index 8429fe26b..447baab0e 100644 --- a/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java +++ b/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -57,7 +57,7 @@ public class NoTimestampTest extends Test { * 24 * 60 * 60 * 1000L); // create key pair - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert(KEY_ALIAS, "-validity", Integer.toString(VALIDITY)); diff --git a/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java b/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java index 9fb92625f..db415f941 100644 --- a/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java +++ b/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -49,7 +49,7 @@ public class NotSignedByAliasTest extends Test { Utils.createFiles(FIRST_FILE); JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); // create first key pair for signing createAlias(FIRST_KEY_ALIAS); diff --git a/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java b/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java index 4d19c9adc..a9aa77dc8 100644 --- a/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java +++ b/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -50,7 +50,7 @@ public class NotYetValidCertTest extends Test { JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE); // create certificate that will be valid only tomorrow - createAlias(CA_KEY_ALIAS); + createAlias(CA_KEY_ALIAS, "-ext", "bc:c"); createAlias(KEY_ALIAS); issueCert( diff --git a/test/sun/security/validator/EndEntityExtensionCheck.java b/test/sun/security/validator/EndEntityExtensionCheck.java index 3cff8fcb5..72db27764 100644 --- a/test/sun/security/validator/EndEntityExtensionCheck.java +++ b/test/sun/security/validator/EndEntityExtensionCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, 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 @@ -26,6 +26,7 @@ * @bug 8076117 * @summary EndEntityChecker should not process custom extensions * after PKIX validation + * @run main/othervm -Djdk.security.allowNonCaAnchor EndEntityExtensionCheck */ import java.io.ByteArrayInputStream; -- GitLab