From 6d91a3eb7bd1e1403cfb67f7eb8ce06d7e08e7a7 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Tue, 21 Sep 2021 13:45:47 +0000 Subject: [PATCH] 8269039: Disable SHA-1 Signed JARs Reviewed-by: weijun --- src/java.base/share/classes/module-info.java | 3 +- .../provider/certpath/AlgorithmChecker.java | 16 +- .../CertPathConstraintsParameters.java | 6 +- .../sun/security/provider/certpath/PKIX.java | 26 +- .../certpath/PKIXCertPathValidator.java | 6 +- .../provider/certpath/SunCertPathBuilder.java | 4 +- .../util/DisabledAlgorithmConstraints.java | 9 +- .../util/JarConstraintsParameters.java | 32 ++- .../share/conf/security/java.security | 7 +- .../sun/security/tools/jarsigner/Main.java | 223 +++++++++++------- .../java/security/Security/signedfirst/Dyn.sh | 94 -------- .../Security/signedfirst/DynStatic.java | 96 ++++++++ .../security/Security/signedfirst/Static.sh | 96 -------- .../signedfirst/com/sun/exp/provider/EXP.java | 34 +++ .../signedfirst/com/sun/exp/provider/SHA.java | 33 +++ .../security/Security/signedfirst/exp.jar | Bin 5772 -> 0 bytes .../Security/signedfirst/keystore.jks | Bin 1215 -> 0 bytes test/jdk/java/util/jar/JarFile/Signed.jar | Bin 2966 -> 3466 bytes test/jdk/java/util/jar/JarFile/test.jar | Bin 2324 -> 2843 bytes .../java/util/jar/JarInputStream/signed.jar | Bin 2298 -> 2774 bytes .../tools/jarsigner/CheckSignerCertChain.java | 4 +- .../sun/security/tools/jarsigner/DiffEnd.java | 4 +- .../sun/security/tools/jarsigner/OldSig.java | 7 +- .../sun/security/tools/jarsigner/OldSig.props | 2 + .../security/tools/jarsigner/Test4431684.java | 9 +- .../tools/jarsigner/TimestampCheck.java | 92 +++++--- .../jdk/test/lib/security/SecurityUtils.java | 11 +- 27 files changed, 457 insertions(+), 357 deletions(-) delete mode 100644 test/jdk/java/security/Security/signedfirst/Dyn.sh create mode 100644 test/jdk/java/security/Security/signedfirst/DynStatic.java delete mode 100644 test/jdk/java/security/Security/signedfirst/Static.sh create mode 100644 test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/EXP.java create mode 100644 test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/SHA.java delete mode 100644 test/jdk/java/security/Security/signedfirst/exp.jar delete mode 100644 test/jdk/java/security/Security/signedfirst/keystore.jks create mode 100644 test/jdk/sun/security/tools/jarsigner/OldSig.props diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 9d4a794de1a..19e8bcfd255 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -318,7 +318,8 @@ module java.base { jdk.crypto.ec, jdk.security.auth; exports sun.security.provider.certpath to - java.naming; + java.naming, + jdk.jartool; exports sun.security.rsa to jdk.crypto.cryptoki; exports sun.security.timestamp to diff --git a/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java b/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java index 56f26d69280..3ed82afaab8 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 @@ -131,7 +131,7 @@ public final class AlgorithmChecker extends PKIXCertPathChecker { * certificate * @param constraints the algorithm constraints (or null) * @param date the date specified by the PKIXParameters date, or the - * JAR timestamp if jar files are being validated and the + * timestamp if JAR files are being validated and the * JAR is timestamped. May be null if no timestamp or * PKIXParameter date is set. * @param variant the Validator variant of the operation. A null value @@ -160,17 +160,19 @@ public final class AlgorithmChecker extends PKIXCertPathChecker { /** * Create a new {@code AlgorithmChecker} with the given {@code TrustAnchor}, - * {@code PKIXParameter} date, and {@code varient} + * {@code PKIXParameter} date, and {@code variant}. * * @param anchor the trust anchor selected to validate the target * certificate - * @param pkixdate Date the constraints are checked against. The value is - * either the PKIXParameters date or null for the current date. + * @param date the date specified by the PKIXParameters date, or the + * timestamp if JAR files are being validated and the + * JAR is timestamped. May be null if no timestamp or + * PKIXParameter date is set. * @param variant the Validator variant of the operation. A null value * passed will set it to Validator.GENERIC. */ - public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) { - this(anchor, certPathDefaultConstraints, pkixdate, variant); + public AlgorithmChecker(TrustAnchor anchor, Date date, String variant) { + this(anchor, certPathDefaultConstraints, date, variant); } @Override diff --git a/src/java.base/share/classes/sun/security/provider/certpath/CertPathConstraintsParameters.java b/src/java.base/share/classes/sun/security/provider/certpath/CertPathConstraintsParameters.java index 597c1f7935c..dacbd12737a 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/CertPathConstraintsParameters.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/CertPathConstraintsParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -39,7 +39,7 @@ import sun.security.validator.Validator; * constraints specified in the jdk.certpath.disabledAlgorithms security * property. */ -class CertPathConstraintsParameters implements ConstraintsParameters { +public class CertPathConstraintsParameters implements ConstraintsParameters { // The public key of the certificate private final Key key; // The certificate's trust anchor which will be checked against the @@ -103,7 +103,7 @@ class CertPathConstraintsParameters implements ConstraintsParameters { @Override public String toString() { StringBuilder sb = new StringBuilder("[\n"); - sb.append("\n Variant: ").append(variant); + sb.append(" Variant: ").append(variant); if (anchor != null) { sb.append("\n Anchor: ").append(anchor); } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java b/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java index 32f2034394f..1362fccc3ba 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java @@ -88,6 +88,7 @@ class PKIX { private Set anchors; private List certs; private Timestamp timestamp; + private Date timestampDate; private String variant = Validator.VAR_GENERIC; ValidatorParams(CertPath cp, PKIXParameters params) @@ -154,10 +155,20 @@ class PKIX { stores = params.getCertStores(); return stores; } + // The date() param is used when enforcing the validity period + // of certificates and when checking the time period of revocation data. + // The main difference between the date() and timestamp() method is + // that the date() method only uses the timestamp (if specified) + // for certificates in a code signer's chain. Date date() { if (!gotDate) { - // use timestamp if checking signed code that is - // timestamped, otherwise use date parameter + // Use timestamp if checking signed code that is + // timestamped, otherwise use date parameter. + // Note that TSA server certificates do not use the + // timestamp, which means that an expired TSA certificate + // is considered a validation failure. This policy means + // that signed and timestamped code is valid until the TSA + // certificate expires (assuming all other checks are valid). if (timestamp != null && variant.equals(Validator.VAR_CODE_SIGNING)) { date = timestamp.getTimestamp(); @@ -209,6 +220,17 @@ class PKIX { String variant() { return variant; } + // The timestamp() param is passed as the date param when creating an + // AlgorithmChecker. An AlgorithmChecker always uses the timestamp + // if specified in order to enforce the denyAfter constraint. + Date timestamp() { + // return timestamp date if set, otherwise use date parameter + if (timestampDate == null) { + timestampDate = (timestamp != null) + ? timestamp.getTimestamp() : date(); + } + return timestampDate; + } } static class BuilderParams extends ValidatorParams { diff --git a/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java b/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java index fdacbf716df..de3923bb3bc 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -176,8 +176,8 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi { List certPathCheckers = new ArrayList<>(); // add standard checkers that we will be using certPathCheckers.add(untrustedChecker); - certPathCheckers.add(new AlgorithmChecker(anchor, null, params.date(), - params.variant())); + certPathCheckers.add(new AlgorithmChecker(anchor, null, + params.timestamp(), params.variant())); certPathCheckers.add(new KeyChecker(certPathLen, params.targetCertConstraints())); certPathCheckers.add(new ConstraintsChecker(certPathLen)); diff --git a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java index 5f825ff44bf..c1c03d86b7e 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -344,7 +344,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { // add the algorithm checker checkers.add(new AlgorithmChecker(builder.trustAnchor, - buildParams.date(), buildParams.variant())); + buildParams.timestamp(), buildParams.variant())); BasicChecker basicChecker = null; if (nextState.keyParamsNeeded()) { diff --git a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java index 46064d0e9cc..c56f9b60b75 100644 --- a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java +++ b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java @@ -39,7 +39,6 @@ import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.NamedParameterSpec; import java.security.spec.PSSParameterSpec; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -688,8 +687,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { */ private static class DenyAfterConstraint extends Constraint { private Date denyAfterDate; - private static final SimpleDateFormat dateFormat = - new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy"); DenyAfterConstraint(String algo, int year, int month, int day) { Calendar c; @@ -723,7 +720,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { denyAfterDate = c.getTime(); if (debug != null) { debug.println("DenyAfterConstraint date set to: " + - dateFormat.format(denyAfterDate)); + denyAfterDate); } } @@ -754,8 +751,8 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { throw new CertPathValidatorException( "denyAfter constraint check failed: " + algorithm + " used with Constraint date: " + - dateFormat.format(denyAfterDate) + "; params date: " + - dateFormat.format(currentDate) + cp.extendedExceptionMsg(), + denyAfterDate + "; params date: " + + currentDate + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } diff --git a/src/java.base/share/classes/sun/security/util/JarConstraintsParameters.java b/src/java.base/share/classes/sun/security/util/JarConstraintsParameters.java index 81fe0eaa835..9cf2bf9ffb3 100644 --- a/src/java.base/share/classes/sun/security/util/JarConstraintsParameters.java +++ b/src/java.base/share/classes/sun/security/util/JarConstraintsParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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,9 +50,9 @@ public class JarConstraintsParameters implements ConstraintsParameters { private boolean anchorIsJdkCASet; // The timestamp of the signed JAR file, if timestamped private Date timestamp; - // The keys of the signers + // The keys of the signers and TSA private final Set keys; - // The certs in the signers' chains that are issued by the trust anchor + // The certs in the signers and TSA chain that are issued by the trust anchor private final Set certsIssuedByAnchor; // The extended exception message private String message; @@ -73,7 +73,7 @@ public class JarConstraintsParameters implements ConstraintsParameters { // used for checking if the signer's certificate chains back to a // JDK root CA for (CodeSigner signer : signers) { - init(signer.getSignerCertPath()); + addToCertsAndKeys(signer.getSignerCertPath()); Timestamp timestamp = signer.getTimestamp(); if (timestamp == null) { // this means one of the signers doesn't have a timestamp @@ -82,7 +82,7 @@ public class JarConstraintsParameters implements ConstraintsParameters { skipTimestamp = true; } else { // add the key and last cert of TSA too - init(timestamp.getSignerCertPath()); + addToCertsAndKeys(timestamp.getSignerCertPath()); if (!skipTimestamp) { Date timestampDate = timestamp.getTimestamp(); if (latestTimestamp == null) { @@ -98,11 +98,27 @@ public class JarConstraintsParameters implements ConstraintsParameters { this.timestamp = latestTimestamp; } - // extract last certificate and key from chain - private void init(CertPath cp) { + public JarConstraintsParameters(List chain, Timestamp timestamp) { + this.keys = new HashSet<>(); + this.certsIssuedByAnchor = new HashSet<>(); + addToCertsAndKeys(chain); + if (timestamp != null) { + addToCertsAndKeys(timestamp.getSignerCertPath()); + this.timestamp = timestamp.getTimestamp(); + } else { + this.timestamp = null; + } + } + + // extract last certificate and signer's public key from chain + private void addToCertsAndKeys(CertPath cp) { @SuppressWarnings("unchecked") List chain = (List)cp.getCertificates(); + addToCertsAndKeys(chain); + } + + private void addToCertsAndKeys(List chain) { if (!chain.isEmpty()) { this.certsIssuedByAnchor.add(chain.get(chain.size() - 1)); this.keys.add(chain.get(0).getPublicKey()); @@ -168,7 +184,7 @@ public class JarConstraintsParameters implements ConstraintsParameters { @Override public String toString() { StringBuilder sb = new StringBuilder("[\n"); - sb.append("\n Variant: ").append(getVariant()); + sb.append(" Variant: ").append(getVariant()); sb.append("\n Certs Issued by Anchor:"); for (X509Certificate cert : certsIssuedByAnchor) { sb.append("\n Cert Issuer: ") diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 6d91e3f8e4e..63be286686d 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -558,7 +558,7 @@ sun.security.krb5.maxReferrals=5 # can be included in the disabledAlgorithms properties. These properties are # to help manage common actions easier across multiple disabledAlgorithm # properties. -# There is one defined security property: jdk.disabled.NamedCurves +# There is one defined security property: jdk.disabled.namedCurves # See the property for more specific details. # # @@ -634,7 +634,8 @@ sun.security.krb5.maxReferrals=5 # # jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \ - RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224 + RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, \ + SHA1 usage SignedJAR & denyAfter 2019-01-01 # # Legacy algorithms for certification path (CertPath) processing and @@ -698,7 +699,7 @@ jdk.security.legacyAlgorithms=SHA1, \ # See "jdk.certpath.disabledAlgorithms" for syntax descriptions. # jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \ - DSA keySize < 1024 + DSA keySize < 1024, SHA1 denyAfter 2019-01-01 # # Algorithm restrictions for Secure Socket Layer/Transport Layer Security diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index fcf3691cffd..139243a61ad 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -56,6 +56,7 @@ import jdk.security.jarsigner.JarSigner; import jdk.security.jarsigner.JarSignerException; import sun.security.pkcs.PKCS7; import sun.security.pkcs.SignerInfo; +import sun.security.provider.certpath.CertPathConstraintsParameters; import sun.security.timestamp.TimestampToken; import sun.security.tools.KeyStoreUtil; import sun.security.validator.Validator; @@ -972,7 +973,8 @@ public class Main { String history; try { SignerInfo si = p7.getSignerInfos()[0]; - X509Certificate signer = si.getCertificate(p7); + ArrayList chain = si.getCertificateChain(p7); + X509Certificate signer = chain.get(0); String digestAlg = digestMap.get(s); String sigAlg = SignerInfo.makeSigAlg( si.getDigestAlgorithmId(), @@ -996,26 +998,31 @@ public class Main { TimeZone.getTimeZone("UTC"), Locale.getDefault(Locale.Category.FORMAT)); c.setTime(tsTokenInfo.getDate()); + JarConstraintsParameters jcp = + new JarConstraintsParameters(chain, si.getTimestamp()); history = String.format( rb.getString("history.with.ts"), signer.getSubjectX500Principal(), - verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false), - verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false), - verifyWithWeak(key), + verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false, jcp), + verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false, jcp), + verifyWithWeak(key, jcp), c, tsSigner.getSubjectX500Principal(), - verifyWithWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET, true), - verifyWithWeak(tsSigAlg, SIG_PRIMITIVE_SET, true), - verifyWithWeak(tsKey)); + verifyWithWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET, true, jcp), + verifyWithWeak(tsSigAlg, SIG_PRIMITIVE_SET, true, jcp), + verifyWithWeak(tsKey, jcp)); } else { + JarConstraintsParameters jcp = + new JarConstraintsParameters(chain, null); history = String.format( rb.getString("history.without.ts"), signer.getSubjectX500Principal(), - verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false), - verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false), - verifyWithWeak(key)); + verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false, jcp), + verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false, jcp), + verifyWithWeak(key, jcp)); } } catch (Exception e) { + e.printStackTrace(); // The only usage of sigNameMap, remember the name // of the block file if it's invalid. history = String.format( @@ -1339,56 +1346,67 @@ public class Main { } } - private String verifyWithWeak(String alg, Set primitiveSet, boolean tsa) { - if (JAR_DISABLED_CHECK.permits(primitiveSet, alg, null)) { - if (LEGACY_CHECK.permits(primitiveSet, alg, null)) { - return alg; - } else { - if (primitiveSet == SIG_PRIMITIVE_SET) { - legacyAlg |= 2; - legacySigAlg = alg; - } else { - if (tsa) { - legacyAlg |= 4; - legacyTsaDigestAlg = alg; - } else { - legacyAlg |= 1; - legacyDigestAlg = alg; - } - } - return String.format(rb.getString("with.weak"), alg); - } - } else { + private String verifyWithWeak(String alg, Set primitiveSet, + boolean tsa, JarConstraintsParameters jcp) { + + try { + JAR_DISABLED_CHECK.permits(alg, jcp); + } catch (CertPathValidatorException e) { disabledAlgFound = true; return String.format(rb.getString("with.disabled"), alg); } - } - - private String verifyWithWeak(PublicKey key) { - int kLen = KeyUtil.getKeySize(key); - if (JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (kLen >= 0) { - return String.format(rb.getString("key.bit"), kLen); - } else { - return rb.getString("unknown.size"); - } + try { + LEGACY_CHECK.permits(alg, jcp); + return alg; + } catch (CertPathValidatorException e) { + if (primitiveSet == SIG_PRIMITIVE_SET) { + legacyAlg |= 2; + legacySigAlg = alg; } else { - weakPublicKey = key; - legacyAlg |= 8; - return String.format(rb.getString("key.bit.weak"), kLen); + if (tsa) { + legacyAlg |= 4; + legacyTsaDigestAlg = alg; + } else { + legacyAlg |= 1; + legacyDigestAlg = alg; + } } - } else { - disabledAlgFound = true; - return String.format(rb.getString("key.bit.disabled"), kLen); + return String.format(rb.getString("with.weak"), alg); } } - private void checkWeakSign(String alg, Set primitiveSet, boolean tsa) { - if (JAR_DISABLED_CHECK.permits(primitiveSet, alg, null)) { - if (!LEGACY_CHECK.permits(primitiveSet, alg, null)) { + private String verifyWithWeak(PublicKey key, JarConstraintsParameters jcp) { + int kLen = KeyUtil.getKeySize(key); + try { + JAR_DISABLED_CHECK.permits(key.getAlgorithm(), jcp); + } catch (CertPathValidatorException e) { + disabledAlgFound = true; + return String.format(rb.getString("key.bit.disabled"), kLen); + } + try { + LEGACY_CHECK.permits(key.getAlgorithm(), jcp); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen); + } else { + return rb.getString("unknown.size"); + } + } catch (CertPathValidatorException e) { + weakPublicKey = key; + legacyAlg |= 8; + return String.format(rb.getString("key.bit.weak"), kLen); + } + } + + private void checkWeakSign(String alg, Set primitiveSet, + boolean tsa, JarConstraintsParameters jcp) { + + try { + JAR_DISABLED_CHECK.permits(alg, jcp); + try { + LEGACY_CHECK.permits(alg, jcp); + } catch (CertPathValidatorException e) { if (primitiveSet == SIG_PRIMITIVE_SET) { - legacyAlg |= 2; + legacyAlg |= 2; } else { if (tsa) { legacyAlg |= 4; @@ -1397,7 +1415,7 @@ public class Main { } } } - } else { + } catch (CertPathValidatorException e) { if (primitiveSet == SIG_PRIMITIVE_SET) { disabledAlg |= 2; } else { @@ -1410,43 +1428,50 @@ public class Main { } } - private void checkWeakSign(PrivateKey key) { - if (JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (!LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { + private void checkWeakSign(PrivateKey key, JarConstraintsParameters jcp) { + try { + JAR_DISABLED_CHECK.permits(key.getAlgorithm(), jcp); + try { + LEGACY_CHECK.permits(key.getAlgorithm(), jcp); + } catch (CertPathValidatorException e) { legacyAlg |= 8; } - } else { + } catch (CertPathValidatorException e) { disabledAlg |= 8; } } - private static String checkWeakKey(PublicKey key) { + private static String checkWeakKey(PublicKey key, CertPathConstraintsParameters cpcp) { int kLen = KeyUtil.getKeySize(key); - if (CERTPATH_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (kLen >= 0) { - return String.format(rb.getString("key.bit"), kLen); - } else { - return rb.getString("unknown.size"); - } + try { + CERTPATH_DISABLED_CHECK.permits(key.getAlgorithm(), cpcp); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.disabled"), kLen); + } + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen); } else { - return String.format(rb.getString("key.bit.weak"), kLen); + return rb.getString("unknown.size"); } - } else { - return String.format(rb.getString("key.bit.disabled"), kLen); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.weak"), kLen); } } - private static String checkWeakAlg(String alg) { - if (CERTPATH_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { - if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { - return alg; - } else { - return String.format(rb.getString("with.weak"), alg); - } - } else { + private static String checkWeakAlg(String alg, CertPathConstraintsParameters cpcp) { + try { + CERTPATH_DISABLED_CHECK.permits(alg, cpcp); + } catch (CertPathValidatorException e) { return String.format(rb.getString("with.disabled"), alg); } + try { + LEGACY_CHECK.permits(alg, cpcp); + return alg; + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.weak"), alg); + } } private static MessageFormat validityTimeForm = null; @@ -1471,7 +1496,7 @@ public class Main { * @param checkUsage true to check code signer keyUsage */ String printCert(boolean isTsCert, String tab, Certificate c, - Date timestamp, boolean checkUsage) throws Exception { + Date timestamp, boolean checkUsage, CertPathConstraintsParameters cpcp) throws Exception { StringBuilder certStr = new StringBuilder(); String space = rb.getString("SPACE"); @@ -1504,16 +1529,16 @@ public class Main { .append("Signature algorithm: ") .append(sigalg) .append(rb.getString("COMMA")) - .append(checkWeakKey(key)); + .append(checkWeakKey(key, cpcp)); certStr.append("\n").append(tab).append("["); certStr.append(rb.getString("trusted.certificate")); } else { certStr.append("\n").append(tab) .append("Signature algorithm: ") - .append(checkWeakAlg(sigalg)) + .append(checkWeakAlg(sigalg, cpcp)) .append(rb.getString("COMMA")) - .append(checkWeakKey(key)); + .append(checkWeakKey(key, cpcp)); certStr.append("\n").append(tab).append("["); @@ -1694,19 +1719,21 @@ public class Main { if (digestalg == null) { digestalg = JarSigner.Builder.getDefaultDigestAlgorithm(); } - checkWeakSign(digestalg, DIGEST_PRIMITIVE_SET, false); + JarConstraintsParameters jcp = + new JarConstraintsParameters(Arrays.asList(certChain), null); + checkWeakSign(digestalg, DIGEST_PRIMITIVE_SET, false, jcp); if (tSADigestAlg == null) { tSADigestAlg = JarSigner.Builder.getDefaultDigestAlgorithm(); } - checkWeakSign(tSADigestAlg, DIGEST_PRIMITIVE_SET, true); + checkWeakSign(tSADigestAlg, DIGEST_PRIMITIVE_SET, true, jcp); if (sigalg == null) { sigalg = JarSigner.Builder.getDefaultSignatureAlgorithm(privateKey); } - checkWeakSign(sigalg, SIG_PRIMITIVE_SET, false); + checkWeakSign(sigalg, SIG_PRIMITIVE_SET, false, jcp); - checkWeakSign(privateKey); + checkWeakSign(privateKey, jcp); boolean aliasUsed = false; X509Certificate tsaCert = null; @@ -1804,8 +1831,10 @@ public class Main { if (tsaUrl != null) { System.out.println(rb.getString("TSA.location.") + tsaUrl); } else if (tsaCert != null) { + CertPathConstraintsParameters cpcp = + new CertPathConstraintsParameters(tsaCert, Validator.VAR_TSA_SERVER, null, null); System.out.println(rb.getString("TSA.certificate.") + - printCert(true, "", tsaCert, null, false)); + printCert(true, "", tsaCert, null, false, cpcp)); } } builder.tsa(tsaURI); @@ -2015,8 +2044,13 @@ public class Main { boolean first = true; StringBuilder sb = new StringBuilder(); sb.append(tab1).append(rb.getString("...Signer")).append('\n'); + @SuppressWarnings("unchecked") + List chain = (List)certs; + TrustAnchor anchor = findTrustAnchor(chain); for (Certificate c : certs) { - sb.append(printCert(false, tab2, c, timestamp, first)); + CertPathConstraintsParameters cpcp = + new CertPathConstraintsParameters((X509Certificate)c, Validator.VAR_CODE_SIGNING, anchor, timestamp); + sb.append(printCert(false, tab2, c, timestamp, first, cpcp)); sb.append('\n'); first = false; } @@ -2029,9 +2063,15 @@ public class Main { .append(e.getLocalizedMessage()).append("]\n"); } if (ts != null) { + List tscerts = ts.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List tschain = (List)tscerts; + anchor = findTrustAnchor(chain); sb.append(tab1).append(rb.getString("...TSA")).append('\n'); - for (Certificate c : ts.getSignerCertPath().getCertificates()) { - sb.append(printCert(true, tab2, c, null, false)); + for (Certificate c : tschain) { + CertPathConstraintsParameters cpcp = + new CertPathConstraintsParameters((X509Certificate)c, Validator.VAR_TSA_SERVER, anchor, timestamp); + sb.append(printCert(true, tab2, c, null, false, cpcp)); sb.append('\n'); } try { @@ -2052,6 +2092,15 @@ public class Main { return sb.toString(); } + private TrustAnchor findTrustAnchor(List chain) { + X509Certificate last = chain.get(chain.size() - 1); + Optional trusted = + trustedCerts.stream() + .filter(c -> c.getSubjectX500Principal().equals(last.getIssuerX500Principal())) + .findFirst(); + return trusted.isPresent() ? new TrustAnchor(trusted.get(), null) : null; + } + void loadKeyStore(String keyStoreName, boolean prompt) { if (!nullStream && keyStoreName == null) { diff --git a/test/jdk/java/security/Security/signedfirst/Dyn.sh b/test/jdk/java/security/Security/signedfirst/Dyn.sh deleted file mode 100644 index ad1211c2fbf..00000000000 --- a/test/jdk/java/security/Security/signedfirst/Dyn.sh +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright (c) 2002, 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 4504355 -# @summary problems if signed crypto provider is the most preferred provider -# -# @run shell Dyn.sh - -# set a few environment variables so that the shell-script can run stand-alone -# in the source directory -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi - -if [ "${TESTCLASSES}" = "" ] ; then - TESTCLASSES="." -fi - -if [ "${TESTJAVA}" = "" ] ; then - echo "TESTJAVA not set. Test cannot execute." - echo "FAILED!!!" - exit 1 -fi - -if [ "${COMPILEJAVA}" = "" ]; then - COMPILEJAVA="${TESTJAVA}" -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Linux ) - PATHSEP=":" - FILESEP="/" - ;; - Darwin ) - PATHSEP=":" - FILESEP="/" - ;; - AIX ) - PATHSEP=":" - FILESEP="/" - ;; - CYGWIN* ) - PATHSEP=";" - FILESEP="/" - ;; - Windows* ) - PATHSEP=";" - FILESEP="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -# remove old class files -cd ${TESTCLASSES}${FILESEP} -rm DynSignedProvFirst.class - -# compile the test program -${COMPILEJAVA}${FILESEP}bin${FILESEP}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -classpath ${TESTSRC}${FILESEP}exp.jar \ - -d ${TESTCLASSES}${FILESEP} \ - ${TESTSRC}${FILESEP}DynSignedProvFirst.java - -# run the test -${TESTJAVA}${FILESEP}bin${FILESEP}java ${TESTVMOPTS} \ - -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ - DynSignedProvFirst - -exit $? diff --git a/test/jdk/java/security/Security/signedfirst/DynStatic.java b/test/jdk/java/security/Security/signedfirst/DynStatic.java new file mode 100644 index 00000000000..5256564064b --- /dev/null +++ b/test/jdk/java/security/Security/signedfirst/DynStatic.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 4504355 4744260 + * @summary problems if signed crypto provider is the most preferred provider + * @modules java.base/sun.security.tools.keytool + * jdk.jartool/sun.security.tools.jarsigner + * @library /test/lib + * @run main/othervm DynStatic + */ + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.JarUtils; + +public class DynStatic { + + private static final String TEST_SRC = + Paths.get(System.getProperty("test.src")).toString(); + private static final Path TEST_CLASSES = + Paths.get(System.getProperty("test.classes")); + + private static final Path EXP_SRC_DIR = Paths.get(TEST_SRC, "com"); + private static final Path EXP_DEST_DIR = Paths.get("build"); + private static final Path DYN_SRC = + Paths.get(TEST_SRC, "DynSignedProvFirst.java"); + private static final Path STATIC_SRC = + Paths.get(TEST_SRC, "StaticSignedProvFirst.java"); + + private static final String STATIC_PROPS = + Paths.get(TEST_SRC, "Static.props").toString(); + + public static void main(String[] args) throws Exception { + + // Compile the provider + CompilerUtils.compile(EXP_SRC_DIR, EXP_DEST_DIR); + + // Create a jar file containing the provider + JarUtils.createJarFile(Path.of("exp.jar"), EXP_DEST_DIR, "com"); + + // Create a keystore + sun.security.tools.keytool.Main.main( + ("-genkeypair -dname CN=Signer -keystore exp.ks -storepass " + + "changeit -keypass changeit -keyalg rsa").split(" ")); + + // Sign jar + sun.security.tools.jarsigner.Main.main( + "-storepass changeit -keystore exp.ks exp.jar mykey" + .split(" ")); + + // Compile the DynSignedProvFirst test program + CompilerUtils.compile(DYN_SRC, TEST_CLASSES, "-classpath", "exp.jar"); + + // Run the DynSignedProvFirst test program + ProcessTools.executeTestJvm("-classpath", + TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", + "DynSignedProvFirst") + .shouldContain("test passed"); + + // Compile the StaticSignedProvFirst test program + CompilerUtils.compile(STATIC_SRC, TEST_CLASSES, "-classpath", "exp.jar"); + + // Run the StaticSignedProvFirst test program + ProcessTools.executeTestJvm("-classpath", + TEST_CLASSES.toString() + File.pathSeparator + "exp.jar", + "-Djava.security.properties=file:" + STATIC_PROPS, + "StaticSignedProvFirst") + .shouldContain("test passed"); + } +} diff --git a/test/jdk/java/security/Security/signedfirst/Static.sh b/test/jdk/java/security/Security/signedfirst/Static.sh deleted file mode 100644 index 940e10a1c5a..00000000000 --- a/test/jdk/java/security/Security/signedfirst/Static.sh +++ /dev/null @@ -1,96 +0,0 @@ -# -# Copyright (c) 2002, 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 4504355 4744260 -# @summary problems if signed crypto provider is the most preferred provider -# -# @run shell Static.sh - -# set a few environment variables so that the shell-script can run stand-alone -# in the source directory -if [ "${TESTSRC}" = "" ] ; then - TESTSRC="." -fi - -if [ "${TESTCLASSES}" = "" ] ; then - TESTCLASSES="." -fi - -if [ "${TESTJAVA}" = "" ] ; then - echo "TESTJAVA not set. Test cannot execute." - echo "FAILED!!!" - exit 1 -fi - -if [ "${COMPILEJAVA}" = "" ]; then - COMPILEJAVA="${TESTJAVA}" -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Linux ) - PATHSEP=":" - FILESEP="/" - ;; - Darwin ) - PATHSEP=":" - FILESEP="/" - ;; - AIX ) - PATHSEP=":" - FILESEP="/" - ;; - CYGWIN* ) - PATHSEP=";" - FILESEP="/" - ;; - Windows* ) - PATHSEP=";" - FILESEP="\\" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -# remove old class files -cd ${TESTCLASSES}${FILESEP} -rm StaticSignedProvFirst.class - -# compile the test program -${COMPILEJAVA}${FILESEP}bin${FILESEP}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \ - -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ - -d ${TESTCLASSES}${FILESEP} \ - ${TESTSRC}${FILESEP}StaticSignedProvFirst.java - -# run the test -cd ${TESTSRC}${FILESEP} -${TESTJAVA}${FILESEP}bin${FILESEP}java ${TESTVMOPTS} \ - -classpath "${TESTCLASSES}${PATHSEP}${TESTSRC}${FILESEP}exp.jar" \ - -Djava.security.properties=file:${TESTSRC}${FILESEP}Static.props \ - StaticSignedProvFirst - -exit $? diff --git a/test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/EXP.java b/test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/EXP.java new file mode 100644 index 00000000000..ef916e6e100 --- /dev/null +++ b/test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/EXP.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.exp.provider; + +import java.security.Provider; + +public class EXP extends Provider { + + public EXP() { + super("EXP", 0.0d, "Test provider"); + put("MessageDigest.SHA1", "com.sun.exp.provider.SHA"); + } +} diff --git a/test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/SHA.java b/test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/SHA.java new file mode 100644 index 00000000000..7f6c4128ac0 --- /dev/null +++ b/test/jdk/java/security/Security/signedfirst/com/sun/exp/provider/SHA.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.exp.provider; + +import java.security.MessageDigestSpi; + +public class SHA extends MessageDigestSpi { + protected void engineReset() {} + protected void engineUpdate(byte input) {} + protected void engineUpdate(byte[] input, int offset, int len) {} + protected byte[] engineDigest() { return null; } +} diff --git a/test/jdk/java/security/Security/signedfirst/exp.jar b/test/jdk/java/security/Security/signedfirst/exp.jar deleted file mode 100644 index 7411a0a18a8ea9de8c439939bec290b53233279c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5772 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 RpQ6yy_oUpll{uEh5&%JE2XX)a diff --git a/test/jdk/java/util/jar/JarFile/Signed.jar b/test/jdk/java/util/jar/JarFile/Signed.jar index c20f60c73e6592a3234983ed6b000a5b0dda73f8..2122b30883d5db96b43c6acd56f4f14f91bb293d 100644 GIT binary patch delta 2119 zcmZ8ic|6ox8y}{b#t?bOB`HFdO7>)%Tcd_DSC+A4%hk+SCX6LpgWpwm6k2GQQDiHM zTy&?#OiUts#JwR~mdqeKL&)}y_tRVMea`3koaa2x`JQv0^T+o~lSz;hx50pSNP%E5 z7%1Nkj!hOn2oRbvqE}Dup$u^bfi!|*0*-j#d7CCaA9^pZTq~W}gt3zpMN@;FFb&BL5_n?Wp!exD!EZzw9J^^_cTA?70Mo9^)-=O4fl;Dlp zU#R=hnMJbsrVr__T*gv;c9!gtmRy3fWcPl4?yP4AjLPlDInYP^WM0i1KY zAX=sw94@9(mP3yd{#hdvttjG$e(#YQZf{nXYJIXT2u6D}kY5+m8SdrNR4<}whZCdq zv^#eI>#|to9-9CDCyAlttjhJbVnUL&BN@5TZxtDjdecTT$)O8oNc$>L=SK5!t;@7u zXb#tvY?H!zs6<2IVGsihQJ6efMWDleb>;#%k;wogP*{#l4c5 zUO6bS^~IA7Y6?n1Aka;L|MQEft3vXC9TuhMbFsy9xSh!NS$+4m;obA>_+y;{zZ;+Y zSJJ?5^jms4E!T8X?@{8DQ>%WH%Sj4CAsD#=FG3*@6T)7q=BldVap50^!}`zQpuX1% zaa<^oag1v)h{uT&JP}^-T?SmpeK0prgb|@aQ`rmOGaJk5tDf9|6hs0SH2bw7&D9#3 zdEEuj;7=9iaZqU}%^a!i3a!KD-#?cmo^Pg6g_~=34pHcUNZ0=~XZ1X9`9bPj?NtcTGlrms#*Le!lfBiL8GwFwG1&v3Fy(#d!qT*L zrJO`Tp?0ad&qurHd0<5*H4{>c7H0?_j*!-OrzT{Tb8ULydNXPvkI(mRER3T$|Y?k-Y@{d_wcs`TSN{XaN zPc&zjmIraa0=>KHS7Ta3jeVE+r4r>GE6NjVjJukzmV?|#>rKIP?iBzC>n9iWg(qLoFcV$^2>qXP9xgEG&abb7ubyF432O-{-KHO9iN%i>_U6q4uHlQ0$D)SR`yI(gqRrybsWz|c z*E1F1&L+mkqnh2=#3ceoi&7#_o+u8I2K@W->mve|P8Teq=i3`lNW^c zev__Y!KY5g1tprrG$H-ZE^p*K9ITw>l;-`CSYEWTqH!PTPbvelUp-`pcRgU$ow`RT zm(~Cd(+2tpQR~@%QFuqb$QtO(f%Ra=wU5h2*rnOn@@4FpZf%BdP72F^$!Lyi=x#p= zReVEikZ81wgT|@8HpTBFWG5ya)3Mi1I;D3-(dAsHg}S$n{YBe0i4CKwHr7$wcqa9^B)mnfA##b`HrQ;>4m`tJ;koQgRQgax zc}AUlrM|i0!ZF3#2{JP5nPT8c4>`ozDj!H*6oz&BaCVIn&=HBe zCFf4UyFfm_u<9?JxOrXoDQ9tpzt@%A<5VIs9kIC9_cHFz=tyFybzpi_%ZUoNr){Id zJcJ0}%MdflGCHqwl$hSt+A%kLyL6Mjl6QSGZK{iH6&x1hyOs&bx3g6n55b!(w}x#VH#j)|Xe!(CGnSrc0nwG(DERAv494iG31vYoQx z1&T*Cgcu0H7$k@|STM!Fa)ow()57mcLe+-r0^gF`xo=BEe%PuY{I{goV1$IFKtJSl z`!gheKn0Pj@W0Ul8r=pr25mid3nJL~KNA57`uT41JGbFCnzp+9|J77E(F3log1S8+ z;`3bu=i HZLR(b2M4AN delta 1499 zcmeB@o+i#0;LXe;!oUH9Y}wX^6Zur?W6wBpHyKDYJly@D{>DbWE;l(Ls~1yDF7XtX z{EZ4uv&@`5>A&6U7hhYSpLO^!OEXtcP4s4D6KQ^&9Ebm0G=$5di^ytJ-+^OQL?Z~HH8NxZUhP5-SAvEjTLUyn^Lk$?Xw z^xjF^$M3REocQ2a_c}ZMj`)6NkZ&)ZzM%;6>31n&eHYaDzt(r4FL2G!}?r^yFIJo+- z`TG2CsNfgwPG*^H7cfg!qxM`=tK* z4V#UE+-8H-#cqLV8yn|XtZ(dWTsm>*!if_%E=&~Z;7*z4xbsVqoABc@g=>wh49XLf z&tJK5;=^{k9f8|IJd9uLyDqcW+<#uZ@Ey67&-Yp%ZkSVhc$>pkpX(9qOAp+ixNWcC z{%`Vscb%?(aQo%Wg_hT)*Gi}OezISxnsa`h zIXquJdZW*j`A^F~Z$It+l+So(8;5(RugR~lUzKyq9+j^BK7Yy#)#q_v5^TkUtPUy z{zJPv+ur!TY@GP8cK14$U-sH5;u$$N9%+WH_;bkJ*{9-nrQhOt!l&hKb%d6-U-^<{ z6S2q7uln<*OP!V7uXomK&Qh!WGdJYuilo}KlgDednbb?xW$gQJ@akpFHqX16g}hf6 zuF~wWyY~NFb(W#|HUk4wvn%!Ib{wl;^ZRFGa*^7bO?%vb=< zsf(_c@`ubRvp;k9+s=P4O>1vYu6QS>|W1npk4#)tyWaSe2Uhb>jStnmZ-`i+9&= z{nT_?E0Dn z_xA)&{=e^o%F|`-ZN1gJQss=sU5oDl`!84tvGI=O;J z#to_r**;LNM1Z%9usrJLrtcE!?WzaNrUBlJOd<@Bf*9(z4(rn^fAe#V%gq>di diff --git a/test/jdk/java/util/jar/JarFile/test.jar b/test/jdk/java/util/jar/JarFile/test.jar index 1e3523346ab150eefac16e36e55d979d3f9bbd5a..6afd0d140c75044f803d1909ad42b0671ed3da64 100644 GIT binary patch delta 2040 zcmaJ?c{JN;7Y-_7Z>v??F#TF#$k>;n)>;OWGExjAnlt&~zjHMUlWGWKR-_eIZ~sp%izea}7beeZehJ@>tTJWtlyLQx@GYpzr0KoAH7 z^q)9hM8=RfVULF&IG zSku>#OfcgEe>KAVf;Z7yjF*3;%Sibmr@2;n_5s9HOix@f`dpKk$Hy#p`GmCSk+cz= zlqFie^mc~ZA95qO1kD@Qu;}yF%Sbt>7Pi-Ms)9d0NXQ!Si?2l*<)#x4`($jbc_3?< zNtQ_<5GbAP{~nl~_{UDOBe>ZO<8Ljmn=6~zTbn5%%)?XRHnA!o{MzOHcxlZFk-XW< z8^8C32yi%QtKWK5Uhn%Og+gs{N6!s+(+Jv8B^Mh0>!ryD@Xe6YgJuot<#GZ{ah_(9 zVlm4eU~$JAA(OF%b~i^5rv=|%fmA=i1WNdyG3sO9r0Oc1r>gqZfMs9<%!-cIFtn^X zoxb=uyeeQUxaR(WGwb1`pS?Z7t4RUR0MsSK;_unvqEnKrWL#kOa>L(*B~D3+vi6y) zn61p;&cXq5SAJVQ_>E40XX~%JawbcU1I}#|c8zFAliRTQ8Eu(_*Wv3qHUlkH4cc`W z!pFHrK}FTx%y?I+^`}`0Dvh_dzdd9xiU(q$0?yfCuSJjJ|1Iv!mx}|G>=4H4{+=&A z=0=fQ{(FN1{ew?R6E(-!o|%|2oIdk&ZmN3O%UIRy{J6x7?2ex$%hEB%BINsQuQnDD zS?2VGnnR&N_=xejThrfpfdgWzyy##gS(C0c>+L1v<00b9C#Xf|F5sev@RB2Cb7Up> z#MbXMPj>!!$V~#G+?1wOxT&2mrSb_9IQ0Efb39lSoMR4#g7LmTd|g{sc26hEnzR8= zvFaBB?-E)PGl(4WgFU0&{r&5ni7sz~Uzb~t$sRSQFKl27n0(^=m5RhpN2Paa^Q~KJ zp$ik(E!r*F=(jQTRu-$Y=N4D>?Ubx&?tM~d)$zu~Ho)&N7SlTcP99g01RuLt~ zspTeyxIa&-Bf1z~()Y=2nhq93OgB2ZZN||L8-Macw9S?!?I&eTT%8g})>eL$C=%XyR56d3RK3i|AFaJKdwfb-e zR-lhUHvy&X4_YGL6gT%?%lBy&1z-v}Gt)kI4@!sQ<`w@E*HYc!Qio`(Xp2YM<=OtQ zb-|9}^6E;L5vTNDMO1wM#HbPYVi&SMEh}3<@ca7$VP_sg@qFM=e>M#bJl}=P!|+xx zz8+km_7Op6#V2}nvN)c|=#SXT#jg2=;x(mRWE-35vuB=Ybc}TO&pzw}PA|s9X2bp5 z;MceFKS%>M2U9Ign}NF;Xg6RO+-}$~LUPMLi$oPnQfN{9hEGG9QLLP(2k-IPLyAqN zCCU$xH3MtSs)Zf49pVKopt6;A=;z$>UcT2Ltuyl&j3m7lLMB z_iR(eU`V9q!XTz4R8iO1+h%cN0;hKbk2&8^z`(em^1Qb2)9ph?sZfKLDJAW>mEK7- z@>mZ!w}JY~U_hQ3P&?k0TtbmF1nyu1JCVg)YZRXeO+z(@RGM>hvy$_26pi&u{wFG% zRGbInPJuun+$X85<`-VXCjlTVo|1y{K#pV1Pl=PL2bs#Szmx2XEWusPDaQk`47Owy zu)(G5uC~@3oaaEFh43H6Ax!b80e`FGNj5zeo6kmNhhIw1mn~0z;Fxhg8y9*SVM<;>9$2icH8&d%0&%mC8e0Nh I^B%wc2V$*$IRF3v delta 1518 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 delta 1481 zcmca6`b&^6z?+#xgn-U(ctDkqx*F$ z>q`Z8h5&DN4xxm$C5;RW3@t#6?ncS_U{7~HH%}i|y*iUGGPmIA%A2g6H10XPr^vV2`b9CbbY-1Oo8bP0Ae&Pe)q_}I#;&n|wepF4fx z+)PK|&(Y0l&!+qI^t9b!o0GHVR?Qiopfx;fcQ{;o99(l8Tz%Mleb{G2yy07K%Ivk7 zdFlDc4F=3tmo;xSYTvYh)3}xGu!YPapL2a}PHapHe7g;n7iT(V1$w5%?NjV$6!+-y zo^kWy$(sQ;90ZO$7JJ5}q3d0;{7G%KDyUn(YjqVuzq zg!Bw4riG0=H+qW9$WF}Qd3x!*qHoXb#t3#Xjvj|To8V;S!}otZaJw0#cy__>xZ*GO zY%2fx7F16-TP@ypxab@2ZKkV6vB|PinCjhceRKPBtNzPtz2^Mo>Fv*A^0(woFg^Ky z%Crsjw$*6|E~$QgzCU55Sb)`&{nbyu*5B^;{J(*(zAopeQDEJ)`)BX#$xpRDlOm-g zqiS~XMfA((rMEh-Z@pI^lr(Kl^~L6o7Lzp&e`#r`3ru}yJX`H;PSlrOt-qaH&V*06 zyw5)7LRIdzw|g&FhaI2smg9b;W$NE|@nP#{)wTUDxV@>~d?~wI+xNG-gkJt%Ga+`t z#>DRB5eq+Y%kvsOeEZz8x5`haIzu_^s%+5Z)gKc+T3Nn5d)iC=neMvh|CVOV`tq?n zNOW=6*O{vF-`8@?xv+E5&wqzkEdP8{t#tWO(~$O6%M5-+{I`C;^5~r#hYno1ArN?c zdw$o9DbJ7IiukAUtbU?xeVw$$IoTh3K70L%3Ag^6H}y_a?0=mi6+PL%sa0h!Up2qY zd|vjaPGWma@3+m}&yHI!FK^d353>CB;P19OHPRUlohrXJdc*NLg^MVV8UT^XpHZw+s&BE->OajmX z4PJ~)UdCxu4;4hth$8Te2VxusV$94J>=xk7$RxsmC?`RVfVlybVG&>zBQ_I&*%xR8 zFWd~UYh$>iq+bC&0k`nqDUgp~Hcg($rJ$of(protocols)); } - private static void removeFromDisabledAlgs(String prop, List algs) { + /** + * Removes constraints that contain the specified constraint from the + * specified security property. For example, List.of("SHA1") will remove + * any constraint containing "SHA1". + */ + public static void removeFromDisabledAlgs(String prop, + List constraints) { String value = Security.getProperty(prop); value = Arrays.stream(value.split(",")) .map(s -> s.trim()) - .filter(s -> !algs.contains(s)) + .filter(s -> constraints.stream() + .allMatch(constraint -> !s.contains(constraint))) .collect(Collectors.joining(",")); Security.setProperty(prop, value); }