diff --git a/debian/changelog b/debian/changelog index 8aba95f3709ecb788a9fa2e5f9cd5be6fdbb697e..5f73d9a000f322b7784f866cf79c4d6ec64a84a4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openjdk-lts (11.0.16+8-ok3) yangtze; urgency=medium + + * CVE-2023-22081 fixd. + + -- KT Mon, 4 Dec 2025 22:34:28 +0800 + openjdk-lts (11.0.16+8-ok2) yangtze; urgency=medium * Add system-pcsclite.diff. diff --git a/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java b/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java index bd6545a7357532f5c8f953560d786d3ce5abdf99..b1e0b52422b0bc494305143f0fccc9f0808c4c70 100644 --- a/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java +++ b/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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,12 +25,10 @@ package java.security.cert; -import java.util.*; +import java.util.Date; import sun.security.provider.certpath.CertPathHelper; -import sun.security.x509.GeneralNameInterface; - /** * Helper class that allows the Sun CertPath provider to access * implementation dependent APIs in CertPath framework. @@ -55,11 +53,6 @@ class CertPathHelperImpl extends CertPathHelper { } } - protected void implSetPathToNames(X509CertSelector sel, - Set names) { - sel.setPathToNamesInternal(names); - } - protected void implSetDateAndTime(X509CRLSelector sel, Date date, long skew) { sel.setDateAndTime(date, skew); } @@ -67,4 +60,4 @@ class CertPathHelperImpl extends CertPathHelper { protected boolean implIsJdkCA(TrustAnchor anchor) { return anchor.isJdkCA(); } -} +} \ No newline at end of file diff --git a/src/java.base/share/classes/java/security/cert/X509CertSelector.java b/src/java.base/share/classes/java/security/cert/X509CertSelector.java index 70c77258ad0f4ccdee114af8bd5879640e070bde..10189efe5ec8cbaa19df9b85169294ba1bb744f0 100644 --- a/src/java.base/share/classes/java/security/cert/X509CertSelector.java +++ b/src/java.base/share/classes/java/security/cert/X509CertSelector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, 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 @@ -31,11 +31,7 @@ import java.security.PublicKey; import java.util.*; import javax.security.auth.x500.X500Principal; -import sun.security.util.HexDumpEncoder; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; import sun.security.x509.*; /** @@ -88,11 +84,7 @@ public class X509CertSelector implements CertSelector { private static final Debug debug = Debug.getInstance("certpath"); private static final ObjectIdentifier ANY_EXTENDED_KEY_USAGE = - ObjectIdentifier.newInternal(new int[] {2, 5, 29, 37, 0}); - - static { - CertPathHelperImpl.initialize(); - } + ObjectIdentifier.of(KnownOIDs.anyExtendedKeyUsage); private BigInteger serialNumber; private X500Principal issuer; @@ -506,7 +498,7 @@ public class X509CertSelector implements CertSelector { if (oid == null) { subjectPublicKeyAlgID = null; } else { - subjectPublicKeyAlgID = new ObjectIdentifier(oid); + subjectPublicKeyAlgID = ObjectIdentifier.of(oid); } } @@ -622,7 +614,7 @@ public class X509CertSelector implements CertSelector { Collections.unmodifiableSet(new HashSet<>(keyPurposeSet)); keyPurposeOIDSet = new HashSet<>(); for (String s : this.keyPurposeSet) { - keyPurposeOIDSet.add(new ObjectIdentifier(s)); + keyPurposeOIDSet.add(ObjectIdentifier.of(s)); } } } @@ -1105,8 +1097,8 @@ public class X509CertSelector implements CertSelector { if (!(o instanceof String)) { throw new IOException("non String in certPolicySet"); } - polIdVector.add(new CertificatePolicyId(new ObjectIdentifier( - (String)o))); + polIdVector.add(new CertificatePolicyId + (ObjectIdentifier.of((String)o))); } // If everything went OK, make the changes policySet = tempSet; @@ -1177,14 +1169,6 @@ public class X509CertSelector implements CertSelector { } } - // called from CertPathHelper - void setPathToNamesInternal(Set names) { - // set names to non-null dummy value - // this breaks getPathToNames() - pathToNames = Collections.>emptySet(); - pathToGeneralNames = names; - } - /** * Adds a name to the pathToNames criterion. The {@code X509Certificate} * must not include name constraints that would prohibit building a @@ -2623,4 +2607,4 @@ public class X509CertSelector implements CertSelector { throw new InternalError(e.toString(), e); } } -} +} \ No newline at end of file diff --git a/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java b/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java index 7c02007422d9f8fd6bb21a209857f0771f33aab7..79e433f7035c0a80de2d3a3a9ef72787f6f4f603 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2023, 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,14 +26,11 @@ package sun.security.provider.certpath; import java.util.Date; -import java.util.Set; import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.security.cert.X509CRLSelector; -import sun.security.x509.GeneralNameInterface; - /** * Helper class that allows access to JDK specific known-public methods in the * java.security.cert package. It relies on a subclass in the @@ -55,18 +52,10 @@ public abstract class CertPathHelper { // empty } - protected abstract void implSetPathToNames(X509CertSelector sel, - Set names); - protected abstract void implSetDateAndTime(X509CRLSelector sel, Date date, long skew); protected abstract boolean implIsJdkCA(TrustAnchor anchor); - static void setPathToNames(X509CertSelector sel, - Set names) { - instance.implSetPathToNames(sel, names); - } - public static void setDateAndTime(X509CRLSelector sel, Date date, long skew) { instance.implSetDateAndTime(sel, date, skew); } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java index 56ecabfc4f350f910c4d1f8910edbc29198e1deb..903d43b6d7e18c2c9756a8ae56ebe10bb4394780 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -257,14 +257,6 @@ class ForwardBuilder extends Builder { */ caSelector.setSubject(currentState.issuerDN); - /* - * Match on subjectNamesTraversed (both DNs and AltNames) - * (checks that current cert's name constraints permit it - * to certify all the DNs and AltNames that have been traversed) - */ - CertPathHelper.setPathToNames - (caSelector, currentState.subjectNamesTraversed); - /* * check the validity period */ diff --git a/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java index 2dc9e208e924f212b4b9d6a26fbac752e599967d..c6480760bcd36531bf12c1765c01dba3af1ba802 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java @@ -31,17 +31,11 @@ import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXCertPathChecker; import java.security.cert.X509Certificate; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.ListIterator; import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; -import sun.security.x509.SubjectAlternativeNameExtension; -import sun.security.x509.GeneralNames; -import sun.security.x509.GeneralName; -import sun.security.x509.GeneralNameInterface; -import sun.security.x509.X500Name; import sun.security.x509.X509CertImpl; /** @@ -61,9 +55,6 @@ class ForwardState implements State { /* The last cert in the path */ X509CertImpl cert; - /* The set of subjectDNs and subjectAltNames of all certs in the path */ - HashSet subjectNamesTraversed; - /* * The number of intermediate CA certs which have been traversed so * far in the path @@ -73,7 +64,6 @@ class ForwardState implements State { /* Flag indicating if state is initial (path is just starting) */ private boolean init = true; - /* the untrusted certificates checker */ UntrustedChecker untrustedChecker; @@ -120,8 +110,6 @@ class ForwardState implements State { sb.append("\n init: ").append(String.valueOf(init)); sb.append("\n keyParamsNeeded: ").append (String.valueOf(keyParamsNeededFlag)); - sb.append("\n subjectNamesTraversed: \n").append - (subjectNamesTraversed); sb.append("]\n"); return sb.toString(); } @@ -134,7 +122,6 @@ class ForwardState implements State { public void initState(List certPathCheckers) throws CertPathValidatorException { - subjectNamesTraversed = new HashSet(); traversedCACerts = 0; /* @@ -188,32 +175,6 @@ class ForwardState implements State { } } - /* update subjectNamesTraversed only if this is the EE cert or if - this cert is not self-issued */ - if (init || !X509CertImpl.isSelfIssued(cert)){ - X500Principal subjName = cert.getSubjectX500Principal(); - subjectNamesTraversed.add(X500Name.asX500Name(subjName)); - - try { - SubjectAlternativeNameExtension subjAltNameExt - = icert.getSubjectAlternativeNameExtension(); - if (subjAltNameExt != null) { - GeneralNames gNames = subjAltNameExt.get( - SubjectAlternativeNameExtension.SUBJECT_NAME); - for (GeneralName gName : gNames.names()) { - subjectNamesTraversed.add(gName.getName()); - } - } - } catch (IOException e) { - if (debug != null) { - debug.println("ForwardState.updateState() unexpected " - + "exception"); - e.printStackTrace(); - } - throw new CertPathValidatorException(e); - } - } - init = false; } @@ -221,10 +182,6 @@ class ForwardState implements State { * Clone current state. The state is cloned as each cert is * added to the path. This is necessary if backtracking occurs, * and a prior state needs to be restored. - * - * Note that this is a SMART clone. Not all fields are fully copied, - * because some of them will - * not have their contents modified by subsequent calls to updateState. */ @Override @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly @@ -244,13 +201,6 @@ class ForwardState implements State { } } - /* - * Shallow copy traversed names. There is no need to - * deep copy contents, since the elements of the Set - * are never modified by subsequent calls to updateState(). - */ - clonedState.subjectNamesTraversed - = (HashSet)subjectNamesTraversed.clone(); return clonedState; } catch (CloneNotSupportedException e) { throw new InternalError(e.toString(), e); 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 5f825ff44bf79993314a985c8519cceed085fc47..6a12f4622e4ce562238b0f5e38f07fb83468d784 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 @@ -31,8 +31,8 @@ import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.cert.*; import java.security.cert.CertPathValidatorException.BasicReason; -import java.security.cert.PKIXReason; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -42,6 +42,8 @@ import javax.security.auth.x500.X500Principal; import sun.security.provider.certpath.PKIX.BuilderParams; import static sun.security.x509.PKIXExtensions.*; +import sun.security.x509.SubjectAlternativeNameExtension; +import sun.security.x509.X509CertImpl; import sun.security.util.Debug; /** @@ -261,7 +263,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { */ Collection certs = builder.getMatchingCerts(currentState, buildParams.certStores()); - List vertices = addVertices(certs, adjList); + List vertices = addVertices(certs, adjList, cpList); if (debug != null) { debug.println("SunCertPathBuilder.depthFirstSearchForward(): " + "certs.size=" + vertices.size()); @@ -321,9 +323,25 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { * cert (which is signed by the trusted public key), but * don't add it yet to the cpList */ + PublicKey rootKey = cert.getPublicKey(); if (builder.trustAnchor.getTrustedCert() == null) { appendedCerts.add(0, cert); + rootKey = builder.trustAnchor.getCAPublicKey(); + if (debug != null) + debug.println( + "SunCertPathBuilder.depthFirstSearchForward " + + "using buildParams public key: " + + rootKey.toString()); } + TrustAnchor anchor = new TrustAnchor + (cert.getSubjectX500Principal(), rootKey, null); + // add the basic checker + List checkers = new ArrayList<>(); + BasicChecker basicChecker = new BasicChecker(anchor, + buildParams.date(), + buildParams.sigProvider(), + true); + checkers.add(basicChecker); Set initExpPolSet = Collections.singleton(PolicyChecker.ANY_POLICY); @@ -331,7 +349,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { PolicyNodeImpl rootNode = new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null, false, initExpPolSet, false); - List checkers = new ArrayList<>(); PolicyChecker policyChecker = new PolicyChecker(buildParams.initialPolicies(), appendedCerts.size(), @@ -341,32 +358,14 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { buildParams.policyQualifiersRejected(), rootNode); checkers.add(policyChecker); + + // add the constraints checker + checkers.add(new ConstraintsChecker(appendedCerts.size())); // add the algorithm checker checkers.add(new AlgorithmChecker(builder.trustAnchor, buildParams.date(), buildParams.variant())); - BasicChecker basicChecker = null; - if (nextState.keyParamsNeeded()) { - PublicKey rootKey = cert.getPublicKey(); - if (builder.trustAnchor.getTrustedCert() == null) { - rootKey = builder.trustAnchor.getCAPublicKey(); - if (debug != null) - debug.println( - "SunCertPathBuilder.depthFirstSearchForward " + - "using buildParams public key: " + - rootKey.toString()); - } - TrustAnchor anchor = new TrustAnchor - (cert.getSubjectX500Principal(), rootKey, null); - - // add the basic checker - basicChecker = new BasicChecker(anchor, buildParams.date(), - buildParams.sigProvider(), - true); - checkers.add(basicChecker); - } - buildParams.setCertPath(cf.generateCertPath(appendedCerts)); boolean revCheckerAdded = false; @@ -553,18 +552,79 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { * adjacency list. */ private static List addVertices(Collection certs, - List> adjList) + List> adjList, + List cpList) { List l = adjList.get(adjList.size() - 1); for (X509Certificate cert : certs) { - Vertex v = new Vertex(cert); - l.add(v); + boolean repeated = false; + for (X509Certificate cpListCert : cpList) { + /* + * Ignore if we encounter the same certificate or a + * certificate with the same public key, subject DN, and + * subjectAltNames as a cert that is already in path. + */ + if (repeated(cpListCert, cert)) { + if (debug != null) { + debug.println("cert with repeated subject, " + + "public key, and subjectAltNames detected"); + } + repeated = true; + break; + } + } + if (!repeated) { + l.add(new Vertex(cert)); + } } return l; } + /** + * Return true if two certificates are equal or have the same subject, + * public key, and subject alternative names. + */ + private static boolean repeated( + X509Certificate currCert, X509Certificate nextCert) { + if (currCert.equals(nextCert)) { + return true; + } + return (currCert.getSubjectX500Principal().equals( + nextCert.getSubjectX500Principal()) && + currCert.getPublicKey().equals(nextCert.getPublicKey()) && + altNamesEqual(currCert, nextCert)); + } + + /** + * Return true if two certificates have the same subject alternative names. + */ + private static boolean altNamesEqual( + X509Certificate currCert, X509Certificate nextCert) { + X509CertImpl curr, next; + try { + curr = X509CertImpl.toImpl(currCert); + next = X509CertImpl.toImpl(nextCert); + } catch (CertificateException ce) { + return false; + } + + SubjectAlternativeNameExtension currAltNameExt = + curr.getSubjectAlternativeNameExtension(); + SubjectAlternativeNameExtension nextAltNameExt = + next.getSubjectAlternativeNameExtension(); + if (currAltNameExt != null) { + if (nextAltNameExt == null) { + return false; + } + return Arrays.equals(currAltNameExt.getExtensionValue(), + nextAltNameExt.getExtensionValue()); + } else { + return (nextAltNameExt == null); + } + } + /** * Returns true if trust anchor certificate matches specified * certificate constraints.