From bedf59aebbe9a9bc06199314903bce9578c73913 Mon Sep 17 00:00:00 2001 From: xzf1234 Date: Wed, 26 Apr 2023 16:18:44 +0800 Subject: [PATCH] fix CVE-2023-21967 --- fix-CVE-2023-21967.patch | 454 +++++++++++++++++++++++++++++++++++++++ openjdk-1.8.0.spec | 7 +- 2 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 fix-CVE-2023-21967.patch diff --git a/fix-CVE-2023-21967.patch b/fix-CVE-2023-21967.patch new file mode 100644 index 0000000..e039317 --- /dev/null +++ b/fix-CVE-2023-21967.patch @@ -0,0 +1,454 @@ +From 16644f9440ead5ea4f3a116514cd8bf470b359ff Mon Sep 17 00:00:00 2001 +From: yjing +Date: Wed, 26 Apr 2023 15:29:01 +0800 +Subject: [PATCH] fix CVE-2023-21967 + +--- + .../provider/certpath/AdjacencyList.java | 11 ++- + .../security/provider/certpath/Builder.java | 16 ++-- + .../provider/certpath/ForwardBuilder.java | 81 ++++++++++++------- + .../provider/certpath/ForwardState.java | 34 ++------ + .../sun/security/provider/certpath/State.java | 10 +-- + .../provider/certpath/SunCertPathBuilder.java | 70 +++++++++------- + 6 files changed, 115 insertions(+), 107 deletions(-) + +diff --git a/jdk/src/share/classes/sun/security/provider/certpath/AdjacencyList.java b/jdk/src/share/classes/sun/security/provider/certpath/AdjacencyList.java +index f26919b..a29582b 100644 +--- a/jdk/src/share/classes/sun/security/provider/certpath/AdjacencyList.java ++++ b/jdk/src/share/classes/sun/security/provider/certpath/AdjacencyList.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2013, 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 +@@ -87,7 +87,7 @@ public class AdjacencyList { + // the actual set of steps the AdjacencyList represents + private ArrayList mStepList; + +- // the original list, just for the toString method ++ // the original list, just for the toString method, just for the toString method + private List> mOrigList; + + /** +@@ -114,6 +114,13 @@ public class AdjacencyList { + return Collections.unmodifiableList(mStepList).iterator(); + } + ++ /** ++ * Returns the number of attempted paths (useful for debugging). ++ */ ++ public int numAttemptedPaths() { ++ return mOrigList.size(); ++ } ++ + /** + * Recursive, private method which actually builds the step list from + * the given adjacency list. Follow is the parent BuildStep +diff --git a/jdk/src/share/classes/sun/security/provider/certpath/Builder.java b/jdk/src/share/classes/sun/security/provider/certpath/Builder.java +index e6b5fc0..b4d7e06 100644 +--- a/jdk/src/share/classes/sun/security/provider/certpath/Builder.java ++++ b/jdk/src/share/classes/sun/security/provider/certpath/Builder.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 +@@ -412,8 +412,7 @@ public abstract class Builder { + + /** + * Search the specified CertStores and add all certificates matching +- * selector to resultCerts. Self-signed certs are not useful here +- * and therefore ignored. ++ * selector to resultCerts. + * + * If the targetCert criterion of the selector is set, only that cert + * is examined and the CertStores are not searched. +@@ -432,8 +431,7 @@ public abstract class Builder { + X509Certificate targetCert = selector.getCertificate(); + if (targetCert != null) { + // no need to search CertStores +- if (selector.match(targetCert) && !X509CertImpl.isSelfSigned +- (targetCert, buildParams.sigProvider())) { ++ if (selector.match(targetCert)) { + if (debug != null) { + debug.println("Builder.addMatchingCerts: " + + "adding target cert" + +@@ -452,12 +450,8 @@ public abstract class Builder { + Collection certs = + store.getCertificates(selector); + for (Certificate cert : certs) { +- if (!X509CertImpl.isSelfSigned +- ((X509Certificate)cert, buildParams.sigProvider())) { +- if (resultCerts.add((X509Certificate)cert)) { +- add = true; +- } +- } ++ if (resultCerts.add((X509Certificate)cert)) { ++ add = true; + } + if (!checkAll && add) { + return true; +diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +index 56ecabf..35cba12 100644 +--- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java ++++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2016, 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 +@@ -48,6 +48,7 @@ import sun.security.x509.AccessDescription; + import sun.security.x509.AuthorityInfoAccessExtension; + import sun.security.x509.AuthorityKeyIdentifierExtension; + import static sun.security.x509.PKIXExtensions.*; ++import sun.security.x509.SubjectAlternativeNameExtension; + import sun.security.x509.X500Name; + import sun.security.x509.X509CertImpl; + +@@ -294,9 +295,7 @@ class ForwardBuilder extends Builder { + "\n Issuer: " + + trustedCert.getIssuerX500Principal()); + } +- if (caCerts.add(trustedCert) && !searchAllCertStores) { +- return; +- } ++ caCerts.add(trustedCert); + } + } + +@@ -675,8 +674,7 @@ class ForwardBuilder extends Builder { + * only be executed in a reverse direction are deferred until the + * complete path has been built. + * +- * Trust anchor certs are not validated, but are used to verify the +- * signature and revocation status of the previous cert. ++ * Trust anchor certs are not validated. + * + * If the last certificate is being verified (the one whose subject + * matches the target subject, then steps in 6.1.4 of the PKIX +@@ -707,17 +705,15 @@ class ForwardBuilder extends Builder { + currState.untrustedChecker.check(cert, Collections.emptySet()); + + /* +- * check for looping - abort a loop if we encounter the same +- * certificate twice ++ * Abort 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 (certPathList != null) { +- for (X509Certificate cpListCert : certPathList) { +- if (cert.equals(cpListCert)) { +- if (debug != null) { +- debug.println("loop detected!!"); +- } +- throw new CertPathValidatorException("loop detected"); +- } ++ for (X509Certificate cpListCert : certPathList) { ++ if (repeated(cpListCert, cert)) { ++ throw new CertPathValidatorException( ++ "cert with repeated subject, public key, and " + ++ "subjectAltNames detected"); + } + } + +@@ -796,21 +792,48 @@ class ForwardBuilder extends Builder { + */ + KeyChecker.verifyCAKeyUsage(cert); + } ++ } + +- /* +- * the following checks are performed even when the cert +- * is a trusted cert, since we are only extracting the +- * subjectDN, and publicKey from the cert +- * in order to verify a previous cert +- */ ++ /** ++ * 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)); ++ } + +- /* +- * Check signature only if no key requiring key parameters has been +- * encountered. +- */ +- if (!currState.keyParamsNeeded()) { +- (currState.cert).verify(cert.getPublicKey(), +- buildParams.sigProvider()); ++ /** ++ * 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); + } + } + +diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ForwardState.java b/jdk/src/share/classes/sun/security/provider/certpath/ForwardState.java +index 2dc9e20..c96ed61 100644 +--- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardState.java ++++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardState.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2012, 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 +@@ -80,10 +80,8 @@ class ForwardState implements State { + /* The list of user-defined checkers that support forward checking */ + ArrayList forwardCheckers; + +- /* Flag indicating if key needing to inherit key parameters has been +- * encountered. +- */ +- boolean keyParamsNeededFlag = false; ++ /* Flag indicating if last cert in path is self-issued */ ++ boolean selfIssued; + + /** + * Returns a boolean flag indicating if the state is initial +@@ -96,18 +94,6 @@ class ForwardState implements State { + return init; + } + +- /** +- * Return boolean flag indicating whether a public key that needs to inherit +- * key parameters has been encountered. +- * +- * @return boolean true if key needing to inherit parameters has been +- * encountered; false otherwise. +- */ +- @Override +- public boolean keyParamsNeeded() { +- return keyParamsNeededFlag; +- } +- + /** + * Display state for debugging purposes + */ +@@ -118,10 +104,10 @@ class ForwardState implements State { + sb.append("\n issuerDN of last cert: ").append(issuerDN); + sb.append("\n traversedCACerts: ").append(traversedCACerts); + 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 selfIssued: ").append ++ (String.valueOf(selfIssued)); + sb.append("]\n"); + return sb.toString(); + } +@@ -166,18 +152,14 @@ class ForwardState implements State { + + X509CertImpl icert = X509CertImpl.toImpl(cert); + +- /* see if certificate key has null parameters */ +- if (PKIX.isDSAPublicKeyWithoutParams(icert.getPublicKey())) { +- keyParamsNeededFlag = true; +- } +- + /* update certificate */ + this.cert = icert; + + /* update issuer DN */ + issuerDN = cert.getIssuerX500Principal(); + +- if (!X509CertImpl.isSelfIssued(cert)) { ++ selfIssued = X509CertImpl.isSelfIssued(cert); ++ if (!selfIssued) { + + /* + * update traversedCACerts only if this is a non-self-issued +@@ -190,7 +172,7 @@ 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)){ ++ if (init || !selfIssued) { + X500Principal subjName = cert.getSubjectX500Principal(); + subjectNamesTraversed.add(X500Name.asX500Name(subjName)); + +diff --git a/jdk/src/share/classes/sun/security/provider/certpath/State.java b/jdk/src/share/classes/sun/security/provider/certpath/State.java +index 93a153f..3292d65 100644 +--- a/jdk/src/share/classes/sun/security/provider/certpath/State.java ++++ b/jdk/src/share/classes/sun/security/provider/certpath/State.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2001, 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 +@@ -62,12 +62,4 @@ interface State extends Cloneable { + * @return boolean flag indicating if the state is initial (just starting) + */ + public boolean isInitial(); +- +- /** +- * Returns a boolean flag indicating if a key lacking necessary key +- * algorithm parameters has been encountered. +- * +- * @return boolean flag indicating if key lacking parameters encountered. +- */ +- public boolean keyParamsNeeded(); + } +diff --git a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +index c1c03d8..fd4eb95 100644 +--- a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java ++++ b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2000, 2021, 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 +@@ -42,6 +42,7 @@ import javax.security.auth.x500.X500Principal; + + import sun.security.provider.certpath.PKIX.BuilderParams; + import static sun.security.x509.PKIXExtensions.*; ++import sun.security.x509.X509CertImpl; + import sun.security.util.Debug; + + /** +@@ -130,18 +131,21 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { + List> adjList = new ArrayList<>(); + PKIXCertPathBuilderResult result = buildCertPath(false, adjList); + if (result == null) { +- if (debug != null) { +- debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " + ++ if (buildParams.certStores().size() > 1 || Builder.USE_AIA) { ++ if (debug != null) { ++ debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " + + "try building again searching all certstores"); ++ } ++ // try again ++ adjList.clear(); ++ result = buildCertPath(true, adjList); ++ if (result != null) { ++ return result; ++ } + } +- // try again +- adjList.clear(); +- result = buildCertPath(true, adjList); +- if (result == null) { +- throw new SunCertPathBuilderException("unable to find valid " +- + "certification path to requested target", +- new AdjacencyList(adjList)); +- } ++ throw new SunCertPathBuilderException("unable to find valid " ++ + "certification path to requested target", ++ new AdjacencyList(adjList)); + } + return result; + } +@@ -270,8 +274,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { + /* + * For each cert in the collection, verify anything + * that hasn't been checked yet (signature, revocation, etc) +- * and check for loops. Call depthFirstSearchForward() +- * recursively for each good cert. ++ * and check for certs with repeated public key and subject. ++ * Call depthFirstSearchForward() recursively for each good cert. + */ + + vertices: +@@ -346,26 +350,24 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { + checkers.add(new AlgorithmChecker(builder.trustAnchor, + buildParams.timestamp(), 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); ++ 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(), ++ // add the basic checker ++ BasicChecker basicChecker = new BasicChecker(anchor, ++ buildParams.date(), + buildParams.sigProvider(), + true); +- checkers.add(basicChecker); +- } ++ checkers.add(basicChecker); + + buildParams.setCertPath(cf.generateCertPath(appendedCerts)); + +@@ -511,6 +513,14 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { + policyTreeResult = policyChecker.getPolicyTree(); + return; + } else { ++ // If successive certs are self-issued, don't continue search ++ // on this branch. ++ if (currentState.selfIssued && X509CertImpl.isSelfIssued(cert)) { ++ if (debug != null) { ++ debug.println("Successive certs are self-issued"); ++ } ++ return; ++ } + builder.addCertToPath(cert, cpList); + } + +-- +2.33.1.windows.1 + diff --git a/openjdk-1.8.0.spec b/openjdk-1.8.0.spec index f836f3c..d0fcc1b 100644 --- a/openjdk-1.8.0.spec +++ b/openjdk-1.8.0.spec @@ -916,7 +916,7 @@ Provides: java-%{javaver}-%{origin}-accessibility%{?1} = %{epoch}:%{version}-%{r Name: java-%{javaver}-%{origin} Version: %{javaver}.%{updatever}.%{buildver} -Release: 3 +Release: 4 # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons # and this change was brought into RHEL-4. java-1.5.0-ibm packages # also included the epoch in their virtual provides. This created a @@ -1184,6 +1184,7 @@ Patch298: Add-CMS-s-trim-test-cases-and-fix-failure.patch Patch299: Disable-cds-on-x86-32.patch Patch300: Disable-no-compressedOop-cds-on-x86-32.patch Patch301: fix-SUSE-x86_32-build-failure.patch +Patch302: fix-CVE-2023-21967.patch ############################################# # @@ -1706,6 +1707,7 @@ pushd %{top_level_dir_name} %patch299 -p1 %patch300 -p1 %patch301 -p1 +%patch302 -p1 popd # System library fixes @@ -2330,6 +2332,9 @@ cjc.mainProgram(arg) %endif %changelog +* Wed Apr 26 2023 yangjing - 1:1.8.0.362.b09-4 +- fix CVE-2023-21967. + * Thu Mar 09 2023 herengui - 1:1.8.0.362.b09-3 - fix the issue of %%pretrans reporting error. -- Gitee