From 85a5b97ea9f4f3bfa17b17bab2b3fb44471eb3f1 Mon Sep 17 00:00:00 2001 From: wang_yi03 <18228455379@163.com> Date: Mon, 18 Dec 2023 13:53:33 +0800 Subject: [PATCH] =?UTF-8?q?CVE-2023-22081=20=E5=AE=89=E5=85=A8=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=9Aopenjdk-lts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- debian/.changelog.swp | Bin 0 -> 12288 bytes .../security/cert/CertPathHelperImpl.java | 11 +- .../java/security/cert/X509CertSelector.java | 560 +++++++++--------- .../provider/certpath/CertPathHelper.java | 15 +- .../provider/certpath/ForwardState.java | 76 +-- .../provider/certpath/SunCertPathBuilder.java | 318 ++++++---- 6 files changed, 476 insertions(+), 504 deletions(-) create mode 100644 debian/.changelog.swp diff --git a/debian/.changelog.swp b/debian/.changelog.swp new file mode 100644 index 0000000000000000000000000000000000000000..aa3cb620aa94dd6a3e98563914769c9fbb68ccb8 GIT binary patch literal 12288 zcmeI&!A{gb7zglyD^Uz4o;3Ny3yAH`%u4AlLRjKOBauYmzI3K*X}4`?dsq(a1NZ_Y zyaK#}F91hw`Y?W7mw+)F_huyjN&lJMZD;!Rm-H~%IgtDBcBth_!R?U{->!%Dt9c^M zW`yuPxf$G_jME#c!XDJ&3w# zBlyxydp5~>6X(MT2tZ&;fvOB0|G{2UtI@0eV(~dWUf7#*FfM}t1Rwwb2tWV=5P$## z?t?&?&xj#E$n5xG=EglQ|3~enAAdy$0SG_<0uX=z1Rwwb2tWV=5P-mcD9|-RoIVud z2dDo3|7QJvH7~>^=Yn(2NjNcQjpK2iah`JOao_8)Xb^w^1Rwwb2tWV=5P$##AOL}X zBtVWsMHTWka(eTt---uGlxBq+q?<%LS^A1pi$2+$wA7lEZ0i;uv?6`U+hmDe(smUk zhQjQK>iz1Y@vabe_O8>CQm%BBx8gfltd?oOH!P3sI#owKn+Ai8zBN(R=jo=YM|-#R o$X0t*xAp70^>mD(Vo;Q}@8m%dBvENy6NTX)MakQu^yH#`0_?Vh7ytkO literal 0 HcmV?d00001 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 bd6545a73..3da6cb3dd 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); } 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 70c77258a..c2db3c5fa 100644 --- a/src/java.base/share/classes/java/security/cert/X509CertSelector.java +++ b/src/java.base/share/classes/java/security/cert/X509CertSelector.java @@ -80,19 +80,15 @@ import sun.security.x509.*; * @see CertSelector * @see X509Certificate * - * @since 1.4 - * @author Steve Hanna + * @since 1.4 + * @author Steve Hanna */ 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(); - } + private static final ObjectIdentifier ANY_EXTENDED_KEY_USAGE = ObjectIdentifier + .newInternal(new int[] { 2, 5, 29, 37, 0 }); private BigInteger serialNumber; private X500Principal issuer; @@ -130,10 +126,10 @@ public class X509CertSelector implements CertSelector { private static final String[] EXTENSION_OIDS = new String[NUM_OF_EXTENSIONS]; static { - EXTENSION_OIDS[PRIVATE_KEY_USAGE_ID] = "2.5.29.16"; - EXTENSION_OIDS[SUBJECT_ALT_NAME_ID] = "2.5.29.17"; - EXTENSION_OIDS[NAME_CONSTRAINTS_ID] = "2.5.29.30"; - EXTENSION_OIDS[CERT_POLICIES_ID] = "2.5.29.32"; + EXTENSION_OIDS[PRIVATE_KEY_USAGE_ID] = "2.5.29.16"; + EXTENSION_OIDS[SUBJECT_ALT_NAME_ID] = "2.5.29.17"; + EXTENSION_OIDS[NAME_CONSTRAINTS_ID] = "2.5.29.30"; + EXTENSION_OIDS[CERT_POLICIES_ID] = "2.5.29.32"; EXTENSION_OIDS[EXTENDED_KEY_USAGE_ID] = "2.5.29.37"; }; @@ -162,13 +158,14 @@ public class X509CertSelector implements CertSelector { * {@code X509Certificate} passed to the {@code match} method. * If {@code null}, then this check is not applied. * - *

This method is particularly useful when it is necessary to + *

+ * This method is particularly useful when it is necessary to * match a single certificate. Although other criteria can be specified * in conjunction with the certificateEquals criterion, it is usually not * practical or necessary. * * @param cert the {@code X509Certificate} to match (or - * {@code null}) + * {@code null}) * @see #getCertificate */ public void setCertificate(X509Certificate cert) { @@ -182,7 +179,7 @@ public class X509CertSelector implements CertSelector { * serial number will do. * * @param serial the certificate serial number to match - * (or {@code null}) + * (or {@code null}) * @see #getSerialNumber */ public void setSerialNumber(BigInteger serial) { @@ -196,7 +193,7 @@ public class X509CertSelector implements CertSelector { * distinguished name will do. * * @param issuer a distinguished name as X500Principal - * (or {@code null}) + * (or {@code null}) * @since 1.5 */ public void setIssuer(X500Principal issuer) { @@ -241,6 +238,7 @@ public class X509CertSelector implements CertSelector { * If {@code issuerDN} is not {@code null}, it should contain a * single DER encoded distinguished name, as defined in X.501. The ASN.1 * notation for this structure is as follows. + * *

{@code
      * Name ::= CHOICE {
      *   RDNSequence }
@@ -288,7 +286,7 @@ public class X509CertSelector implements CertSelector {
      * distinguished name will do.
      *
      * @param subject a distinguished name as X500Principal
-     *                  (or {@code null})
+     *                (or {@code null})
      * @since 1.5
      */
     public void setSubject(X500Principal subject) {
@@ -410,13 +408,13 @@ public class X509CertSelector implements CertSelector {
      * }
*

* Authority key identifiers are not parsed by the - * {@code X509CertSelector}. Instead, the values are + * {@code X509CertSelector}. Instead, the values are * compared using a byte-by-byte comparison. *

* When the {@code keyIdentifier} field of * {@code AuthorityKeyIdentifier} is populated, the value is * usually taken from the {@code SubjectKeyIdentifier} extension - * in the issuer's certificate. Note, however, that the result of + * in the issuer's certificate. Note, however, that the result of * {@code X509Certificate.getExtensionValue()} on the issuer's certificate may NOT be used * directly as the input to {@code setAuthorityKeyIdentifier}. @@ -435,7 +433,7 @@ public class X509CertSelector implements CertSelector { * subsequent modifications. * * @param authorityKeyID the authority key identifier - * (or {@code null}) + * (or {@code null}) * @see #getAuthorityKeyIdentifier */ public void setAuthorityKeyIdentifier(byte[] authorityKeyID) { @@ -462,7 +460,7 @@ public class X509CertSelector implements CertSelector { if (certValid == null) { certificateValid = null; } else { - certificateValid = (Date)certValid.clone(); + certificateValid = (Date) certValid.clone(); } } @@ -483,7 +481,7 @@ public class X509CertSelector implements CertSelector { if (privateKeyValid == null) { this.privateKeyValid = null; } else { - this.privateKeyValid = (Date)privateKeyValid.clone(); + this.privateKeyValid = (Date) privateKeyValid.clone(); } } @@ -497,8 +495,9 @@ public class X509CertSelector implements CertSelector { * for (or {@code null}). An OID is represented by a * set of nonnegative integers separated by periods. * @throws IOException if the OID is invalid, such as - * the first component being not 0, 1 or 2 or the second component - * being greater than 39. + * the first component being not 0, 1 or 2 or the second + * component + * being greater than 39. * * @see #getSubjectPublicKeyAlgID */ @@ -539,6 +538,7 @@ public class X509CertSelector implements CertSelector { * If {@code key} is not {@code null}, it should contain a * single DER encoded SubjectPublicKeyInfo structure, as defined in X.509. * The ASN.1 notation for this structure is as follows. + * *

{@code
      * SubjectPublicKeyInfo  ::=  SEQUENCE  {
      *   algorithm            AlgorithmIdentifier,
@@ -558,7 +558,7 @@ public class X509CertSelector implements CertSelector {
      * @param key a byte array containing the subject public key in ASN.1 DER
      *            form (or {@code null})
      * @throws IOException if an encoding error occurs (incorrect form for
-     * subject public key)
+     *                     subject public key)
      * @see #getSubjectPublicKey
      */
     public void setSubjectPublicKey(byte[] key) throws IOException {
@@ -582,7 +582,8 @@ public class X509CertSelector implements CertSelector {
      *
      * @param keyUsage a boolean array in the same format as the boolean
      *                 array returned by
-     * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}.
+     *                 {@link X509Certificate#getKeyUsage()
+     *                 X509Certificate.getKeyUsage()}.
      *                 Or {@code null}.
      * @see #getKeyUsage
      */
@@ -606,11 +607,13 @@ public class X509CertSelector implements CertSelector {
      * subsequent modifications.
      *
      * @param keyPurposeSet a {@code Set} of key purpose OIDs in string
-     * format (or {@code null}). Each OID is represented by a set of
-     * nonnegative integers separated by periods.
+     *                      format (or {@code null}). Each OID is represented by a
+     *                      set of
+     *                      nonnegative integers separated by periods.
      * @throws IOException if the OID is invalid, such as
-     * the first component being not 0, 1 or 2 or the second component
-     * being greater than 39.
+     *                     the first component being not 0, 1 or 2 or the second
+     *                     component
+     *                     being greater than 39.
      * @see #getExtendedKeyUsage
      */
     public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException {
@@ -618,8 +621,7 @@ public class X509CertSelector implements CertSelector {
             this.keyPurposeSet = null;
             keyPurposeOIDSet = null;
         } else {
-            this.keyPurposeSet =
-                Collections.unmodifiableSet(new HashSet<>(keyPurposeSet));
+            this.keyPurposeSet = Collections.unmodifiableSet(new HashSet<>(keyPurposeSet));
             keyPurposeOIDSet = new HashSet<>();
             for (String s : this.keyPurposeSet) {
                 keyPurposeOIDSet.add(new ObjectIdentifier(s));
@@ -637,10 +639,11 @@ public class X509CertSelector implements CertSelector {
      * {@code X509Certificate} must contain at least one of the
      * specified subject alternative names.
      *
-     * 

The matchAllNames flag is {@code true} by default. + *

+ * The matchAllNames flag is {@code true} by default. * * @param matchAllNames if {@code true}, the flag is enabled; - * if {@code false}, the flag is disabled. + * if {@code false}, the flag is disabled. * @see #getMatchAllSubjectAltNames */ public void setMatchAllSubjectAltNames(boolean matchAllNames) { @@ -774,6 +777,7 @@ public class X509CertSelector implements CertSelector { * the encoded value of the name, and should not include the tag associated * with the name in the GeneralName structure. The ASN.1 definition of this * structure appears below. + * *

{@code
      *  GeneralName ::= CHOICE {
      *       otherName                       [0]     OtherName,
@@ -850,11 +854,11 @@ public class X509CertSelector implements CertSelector {
             if (nameList.size() != 2) {
                 throw new IOException("name list size not 2");
             }
-            Object o =  nameList.get(0);
+            Object o = nameList.get(0);
             if (!(o instanceof Integer)) {
                 throw new IOException("expected an Integer");
             }
-            int nameType = ((Integer)o).intValue();
+            int nameType = ((Integer) o).intValue();
             o = nameList.get(1);
             genNames.add(makeGeneralNameInterface(nameType, o));
         }
@@ -882,10 +886,10 @@ public class X509CertSelector implements CertSelector {
     /**
      * Make a {@code GeneralNameInterface} out of a name type (0-8) and an
      * Object that may be a byte array holding the ASN.1 DER encoded
-     * name or a String form of the name.  Except for X.509
+     * name or a String form of the name. Except for X.509
      * Distinguished Names, the String form of the name must not be the
      * result from calling toString on an existing GeneralNameInterface
-     * implementing class.  The output of toString is not compatible
+     * implementing class. The output of toString is not compatible
      * with the String constructors for names other than Distinguished
      * Names.
      *
@@ -899,95 +903,93 @@ public class X509CertSelector implements CertSelector {
         GeneralNameInterface result;
         if (debug != null) {
             debug.println("X509CertSelector.makeGeneralNameInterface("
-                + type + ")...");
+                    + type + ")...");
         }
 
         if (name instanceof String) {
             if (debug != null) {
                 debug.println("X509CertSelector.makeGeneralNameInterface() "
-                    + "name is String: " + name);
+                        + "name is String: " + name);
             }
             switch (type) {
-            case NAME_RFC822:
-                result = new RFC822Name((String)name);
-                break;
-            case NAME_DNS:
-                result = new DNSName((String)name);
-                break;
-            case NAME_DIRECTORY:
-                result = new X500Name((String)name);
-                break;
-            case NAME_URI:
-                result = new URIName((String)name);
-                break;
-            case NAME_IP:
-                result = new IPAddressName((String)name);
-                break;
-            case NAME_OID:
-                result = new OIDName((String)name);
-                break;
-            default:
-                throw new IOException("unable to parse String names of type "
-                                      + type);
+                case NAME_RFC822:
+                    result = new RFC822Name((String) name);
+                    break;
+                case NAME_DNS:
+                    result = new DNSName((String) name);
+                    break;
+                case NAME_DIRECTORY:
+                    result = new X500Name((String) name);
+                    break;
+                case NAME_URI:
+                    result = new URIName((String) name);
+                    break;
+                case NAME_IP:
+                    result = new IPAddressName((String) name);
+                    break;
+                case NAME_OID:
+                    result = new OIDName((String) name);
+                    break;
+                default:
+                    throw new IOException("unable to parse String names of type "
+                            + type);
             }
             if (debug != null) {
                 debug.println("X509CertSelector.makeGeneralNameInterface() "
-                    + "result: " + result.toString());
+                        + "result: " + result.toString());
             }
         } else if (name instanceof byte[]) {
             DerValue val = new DerValue((byte[]) name);
             if (debug != null) {
-                debug.println
-                    ("X509CertSelector.makeGeneralNameInterface() is byte[]");
+                debug.println("X509CertSelector.makeGeneralNameInterface() is byte[]");
             }
 
             switch (type) {
-            case NAME_ANY:
-                result = new OtherName(val);
-                break;
-            case NAME_RFC822:
-                result = new RFC822Name(val);
-                break;
-            case NAME_DNS:
-                result = new DNSName(val);
-                break;
-            case NAME_X400:
-                result = new X400Address(val);
-                break;
-            case NAME_DIRECTORY:
-                result = new X500Name(val);
-                break;
-            case NAME_EDI:
-                result = new EDIPartyName(val);
-                break;
-            case NAME_URI:
-                result = new URIName(val);
-                break;
-            case NAME_IP:
-                result = new IPAddressName(val);
-                break;
-            case NAME_OID:
-                result = new OIDName(val);
-                break;
-            default:
-                throw new IOException("unable to parse byte array names of "
-                    + "type " + type);
+                case NAME_ANY:
+                    result = new OtherName(val);
+                    break;
+                case NAME_RFC822:
+                    result = new RFC822Name(val);
+                    break;
+                case NAME_DNS:
+                    result = new DNSName(val);
+                    break;
+                case NAME_X400:
+                    result = new X400Address(val);
+                    break;
+                case NAME_DIRECTORY:
+                    result = new X500Name(val);
+                    break;
+                case NAME_EDI:
+                    result = new EDIPartyName(val);
+                    break;
+                case NAME_URI:
+                    result = new URIName(val);
+                    break;
+                case NAME_IP:
+                    result = new IPAddressName(val);
+                    break;
+                case NAME_OID:
+                    result = new OIDName(val);
+                    break;
+                default:
+                    throw new IOException("unable to parse byte array names of "
+                            + "type " + type);
             }
             if (debug != null) {
                 debug.println("X509CertSelector.makeGeneralNameInterface() result: "
-                    + result.toString());
+                        + result.toString());
             }
         } else {
             if (debug != null) {
                 debug.println("X509CertSelector.makeGeneralName() input name "
-                    + "not String or byte array");
+                        + "not String or byte array");
             }
             throw new IOException("name not String or byte array");
         }
         return result;
     }
 
-
     /**
      * Sets the name constraints criterion. The {@code X509Certificate}
      * must have subject and subject alternative names that
@@ -1083,10 +1085,11 @@ public class X509CertSelector implements CertSelector {
      * @param certPolicySet a {@code Set} of certificate policy OIDs in
      *                      string format (or {@code null}). Each OID is
      *                      represented by a set of nonnegative integers
-     *                    separated by periods.
+     *                      separated by periods.
      * @throws IOException if a parsing error occurs on the OID such as
-     * the first component is not 0, 1 or 2 or the second component is
-     * greater than 39.
+     *                     the first component is not 0, 1 or 2 or the second
+     *                     component is
+     *                     greater than 39.
      * @see #getPolicy
      */
     public void setPolicy(Set certPolicySet) throws IOException {
@@ -1095,8 +1098,7 @@ public class X509CertSelector implements CertSelector {
             policy = null;
         } else {
             // Snapshot set and parse it
-            Set tempSet = Collections.unmodifiableSet
-                                        (new HashSet<>(certPolicySet));
+            Set tempSet = Collections.unmodifiableSet(new HashSet<>(certPolicySet));
             /* Convert to Vector of ObjectIdentifiers */
             Iterator i = tempSet.iterator();
             Vector polIdVector = new Vector<>();
@@ -1106,7 +1108,7 @@ public class X509CertSelector implements CertSelector {
                     throw new IOException("non String in certPolicySet");
                 }
                 polIdVector.add(new CertificatePolicyId(new ObjectIdentifier(
-                  (String)o)));
+                        (String) o)));
             }
             // If everything went OK, make the changes
             policySet = tempSet;
@@ -1177,14 +1179,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
@@ -1193,7 +1187,7 @@ public class X509CertSelector implements CertSelector {
      * This method allows the caller to add a name to the set of names which
      * the {@code X509Certificates}'s name constraints must permit.
      * The specified name is added to any previous value for the
-     * pathToNames criterion.  If the name is a duplicate, it may be ignored.
+     * pathToNames criterion. If the name is a duplicate, it may be ignored.
      * 

* The name is provided in string format. RFC 822, DNS, and URI names * use the well-established string formats for those types (subject to @@ -1247,7 +1241,7 @@ public class X509CertSelector implements CertSelector { * @param name a byte array containing the name in ASN.1 DER encoded form * @throws IOException if a parsing error occurs */ - public void addPathToName(int type, byte [] name) throws IOException { + public void addPathToName(int type, byte[] name) throws IOException { // clone because byte arrays are modifiable addPathToNameInternal(type, name.clone()); } @@ -1297,7 +1291,7 @@ public class X509CertSelector implements CertSelector { * serial number will do. * * @return the certificate serial number to match - * (or {@code null}) + * (or {@code null}) * @see #setSerialNumber */ public BigInteger getSerialNumber() { @@ -1360,7 +1354,7 @@ public class X509CertSelector implements CertSelector { * @throws IOException if an encoding error occurs */ public byte[] getIssuerAsBytes() throws IOException { - return (issuer == null ? null: issuer.getEncoded()); + return (issuer == null ? null : issuer.getEncoded()); } /** @@ -1455,7 +1449,7 @@ public class X509CertSelector implements CertSelector { */ public byte[] getAuthorityKeyIdentifier() { if (authorityKeyID == null) { - return null; + return null; } return authorityKeyID.clone(); } @@ -1476,7 +1470,7 @@ public class X509CertSelector implements CertSelector { if (certificateValid == null) { return null; } - return (Date)certificateValid.clone(); + return (Date) certificateValid.clone(); } /** @@ -1495,7 +1489,7 @@ public class X509CertSelector implements CertSelector { if (privateKeyValid == null) { return null; } - return (Date)privateKeyValid.clone(); + return (Date) privateKeyValid.clone(); } /** @@ -1537,9 +1531,9 @@ public class X509CertSelector implements CertSelector { * subsequent modifications. * * @return a boolean array in the same format as the boolean - * array returned by - * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. - * Or {@code null}. + * array returned by + * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. + * Or {@code null}. * @see #setKeyUsage */ public boolean[] getKeyUsage() { @@ -1558,7 +1552,7 @@ public class X509CertSelector implements CertSelector { * implicitly allows all key purposes. * * @return an immutable {@code Set} of key purpose OIDs in string - * format (or {@code null}) + * format (or {@code null}) * @see #setExtendedKeyUsage */ public Set getExtendedKeyUsage() { @@ -1577,8 +1571,8 @@ public class X509CertSelector implements CertSelector { * specified subject alternative names. * * @return {@code true} if the flag is enabled; - * {@code false} if the flag is disabled. The flag is - * {@code true} by default. + * {@code false} if the flag is disabled. The flag is + * {@code true} by default. * @see #setMatchAllSubjectAltNames */ public boolean getMatchAllSubjectAltNames() { @@ -1600,7 +1594,7 @@ public class X509CertSelector implements CertSelector { * {@code Integer} (the name type, 0-8) and whose second * entry is a {@code String} or a byte array (the name, in * string or ASN.1 DER encoded form, respectively). - * There can be multiple names of the same type. Note that the + * There can be multiple names of the same type. Note that the * {@code Collection} returned may contain duplicate names (same name * and name type). *

@@ -1650,7 +1644,7 @@ public class X509CertSelector implements CertSelector { return cloneAndCheckNames(names); } catch (IOException e) { throw new RuntimeException("cloneNames encountered IOException: " + - e.getMessage()); + e.getMessage()); } } @@ -1672,15 +1666,14 @@ public class X509CertSelector implements CertSelector { private static Set> cloneAndCheckNames(Collection> names) throws IOException { // Copy the Lists and Collection Set> namesCopy = new HashSet<>(); - for (List o : names) - { + for (List o : names) { namesCopy.add(new ArrayList<>(o)); } // Check the contents of the Lists and clone any byte arrays for (List list : namesCopy) { @SuppressWarnings("unchecked") // See javadoc for parameter "names". - List nameList = (List)list; + List nameList = (List) list; if (nameList.size() != 2) { throw new IOException("name list size not 2"); } @@ -1688,16 +1681,16 @@ public class X509CertSelector implements CertSelector { if (!(o instanceof Integer)) { throw new IOException("expected an Integer"); } - int nameType = ((Integer)o).intValue(); + int nameType = ((Integer) o).intValue(); if ((nameType < 0) || (nameType > 8)) { throw new IOException("name type not 0-8"); } Object nameObject = nameList.get(1); if (!(nameObject instanceof byte[]) && - !(nameObject instanceof String)) { + !(nameObject instanceof String)) { if (debug != null) { debug.println("X509CertSelector.cloneAndCheckNames() " - + "name not byte array"); + + "name not byte array"); } throw new IOException("name not byte array or String"); } @@ -1826,48 +1819,48 @@ public class X509CertSelector implements CertSelector { sb.append(" Subject: " + getSubjectAsString() + "\n"); } sb.append(" matchAllSubjectAltNames flag: " - + String.valueOf(matchAllSubjectAltNames) + "\n"); + + String.valueOf(matchAllSubjectAltNames) + "\n"); if (subjectAlternativeNames != null) { sb.append(" SubjectAlternativeNames:\n"); Iterator> i = subjectAlternativeNames.iterator(); while (i.hasNext()) { List list = i.next(); sb.append(" type " + list.get(0) + - ", name " + list.get(1) + "\n"); + ", name " + list.get(1) + "\n"); } } if (subjectKeyID != null) { HexDumpEncoder enc = new HexDumpEncoder(); sb.append(" Subject Key Identifier: " + - enc.encodeBuffer(subjectKeyID) + "\n"); + enc.encodeBuffer(subjectKeyID) + "\n"); } if (authorityKeyID != null) { HexDumpEncoder enc = new HexDumpEncoder(); sb.append(" Authority Key Identifier: " + - enc.encodeBuffer(authorityKeyID) + "\n"); + enc.encodeBuffer(authorityKeyID) + "\n"); } if (certificateValid != null) { sb.append(" Certificate Valid: " + - certificateValid.toString() + "\n"); + certificateValid.toString() + "\n"); } if (privateKeyValid != null) { sb.append(" Private Key Valid: " + - privateKeyValid.toString() + "\n"); + privateKeyValid.toString() + "\n"); } if (subjectPublicKeyAlgID != null) { sb.append(" Subject Public Key AlgID: " + - subjectPublicKeyAlgID.toString() + "\n"); + subjectPublicKeyAlgID.toString() + "\n"); } if (subjectPublicKey != null) { sb.append(" Subject Public Key: " + - subjectPublicKey.toString() + "\n"); + subjectPublicKey.toString() + "\n"); } if (keyUsage != null) { sb.append(" Key Usage: " + keyUsageToString(keyUsage) + "\n"); } if (keyPurposeSet != null) { sb.append(" Extended Key Usage: " + - keyPurposeSet.toString() + "\n"); + keyPurposeSet.toString() + "\n"); } if (policy != null) { sb.append(" Policy: " + policy.toString() + "\n"); @@ -1918,7 +1911,8 @@ public class X509CertSelector implements CertSelector { if (k[8]) { s += " Decipher_Only\n"; } - } catch (ArrayIndexOutOfBoundsException ex) {} + } catch (ArrayIndexOutOfBoundsException ex) { + } s += "]\n"; @@ -1930,37 +1924,38 @@ public class X509CertSelector implements CertSelector { * Throw an {@code IOException} if the extension byte value is * malformed. * - * @param cert a {@code X509Certificate} + * @param cert a {@code X509Certificate} * @param extId an {@code integer} which specifies the extension index. - * Currently, the supported extensions are as follows: - * index 0 - PrivateKeyUsageExtension - * index 1 - SubjectAlternativeNameExtension - * index 2 - NameConstraintsExtension - * index 3 - CertificatePoliciesExtension - * index 4 - ExtendedKeyUsageExtension + * Currently, the supported extensions are as follows: + * index 0 - PrivateKeyUsageExtension + * index 1 - SubjectAlternativeNameExtension + * index 2 - NameConstraintsExtension + * index 3 - CertificatePoliciesExtension + * index 4 - ExtendedKeyUsageExtension * @return an {@code Extension} object whose real type is as specified - * by the extension oid. + * by the extension oid. * @throws IOException if cannot construct the {@code Extension} - * object with the extension encoding retrieved from the passed in - * {@code X509Certificate}. + * object with the extension encoding retrieved from the + * passed in + * {@code X509Certificate}. */ private static Extension getExtensionObject(X509Certificate cert, int extId) throws IOException { if (cert instanceof X509CertImpl) { - X509CertImpl impl = (X509CertImpl)cert; + X509CertImpl impl = (X509CertImpl) cert; switch (extId) { - case PRIVATE_KEY_USAGE_ID: - return impl.getPrivateKeyUsageExtension(); - case SUBJECT_ALT_NAME_ID: - return impl.getSubjectAlternativeNameExtension(); - case NAME_CONSTRAINTS_ID: - return impl.getNameConstraintsExtension(); - case CERT_POLICIES_ID: - return impl.getCertificatePoliciesExtension(); - case EXTENDED_KEY_USAGE_ID: - return impl.getExtendedKeyUsageExtension(); - default: - return null; + case PRIVATE_KEY_USAGE_ID: + return impl.getPrivateKeyUsageExtension(); + case SUBJECT_ALT_NAME_ID: + return impl.getSubjectAlternativeNameExtension(); + case NAME_CONSTRAINTS_ID: + return impl.getNameConstraintsExtension(); + case CERT_POLICIES_ID: + return impl.getCertificatePoliciesExtension(); + case EXTENDED_KEY_USAGE_ID: + return impl.getExtendedKeyUsageExtension(); + default: + return null; } } byte[] rawExtVal = cert.getExtensionValue(EXTENSION_OIDS[extId]); @@ -1970,22 +1965,22 @@ public class X509CertSelector implements CertSelector { DerInputStream in = new DerInputStream(rawExtVal); byte[] encoded = in.getOctetString(); switch (extId) { - case PRIVATE_KEY_USAGE_ID: - try { - return new PrivateKeyUsageExtension(FALSE, encoded); - } catch (CertificateException ex) { - throw new IOException(ex.getMessage()); - } - case SUBJECT_ALT_NAME_ID: - return new SubjectAlternativeNameExtension(FALSE, encoded); - case NAME_CONSTRAINTS_ID: - return new NameConstraintsExtension(FALSE, encoded); - case CERT_POLICIES_ID: - return new CertificatePoliciesExtension(FALSE, encoded); - case EXTENDED_KEY_USAGE_ID: - return new ExtendedKeyUsageExtension(FALSE, encoded); - default: - return null; + case PRIVATE_KEY_USAGE_ID: + try { + return new PrivateKeyUsageExtension(FALSE, encoded); + } catch (CertificateException ex) { + throw new IOException(ex.getMessage()); + } + case SUBJECT_ALT_NAME_ID: + return new SubjectAlternativeNameExtension(FALSE, encoded); + case NAME_CONSTRAINTS_ID: + return new NameConstraintsExtension(FALSE, encoded); + case CERT_POLICIES_ID: + return new CertificatePoliciesExtension(FALSE, encoded); + case EXTENDED_KEY_USAGE_ID: + return new ExtendedKeyUsageExtension(FALSE, encoded); + default: + return null; } } @@ -2000,13 +1995,13 @@ public class X509CertSelector implements CertSelector { if (!(cert instanceof X509Certificate)) { return false; } - X509Certificate xcert = (X509Certificate)cert; + X509Certificate xcert = (X509Certificate) cert; if (debug != null) { debug.println("X509CertSelector.match(SN: " - + (xcert.getSerialNumber()).toString(16) + "\n Issuer: " - + xcert.getIssuerDN() + "\n Subject: " + xcert.getSubjectDN() - + ")"); + + (xcert.getSerialNumber()).toString(16) + "\n Issuer: " + + xcert.getIssuerDN() + "\n Subject: " + xcert.getSubjectDN() + + ")"); } /* match on X509Certificate */ @@ -2014,7 +2009,7 @@ public class X509CertSelector implements CertSelector { if (!x509Cert.equals(xcert)) { if (debug != null) { debug.println("X509CertSelector.match: " - + "certs don't match"); + + "certs don't match"); } return false; } @@ -2025,7 +2020,7 @@ public class X509CertSelector implements CertSelector { if (!serialNumber.equals(xcert.getSerialNumber())) { if (debug != null) { debug.println("X509CertSelector.match: " - + "serial numbers don't match"); + + "serial numbers don't match"); } return false; } @@ -2036,7 +2031,7 @@ public class X509CertSelector implements CertSelector { if (!issuer.equals(xcert.getIssuerX500Principal())) { if (debug != null) { debug.println("X509CertSelector.match: " - + "issuer DNs don't match"); + + "issuer DNs don't match"); } return false; } @@ -2047,7 +2042,7 @@ public class X509CertSelector implements CertSelector { if (!subject.equals(xcert.getSubjectX500Principal())) { if (debug != null) { debug.println("X509CertSelector.match: " - + "subject DNs don't match"); + + "subject DNs don't match"); } return false; } @@ -2060,7 +2055,7 @@ public class X509CertSelector implements CertSelector { } catch (CertificateException e) { if (debug != null) { debug.println("X509CertSelector.match: " - + "certificate not within validity period"); + + "certificate not within validity period"); } return false; } @@ -2072,23 +2067,23 @@ public class X509CertSelector implements CertSelector { if (!Arrays.equals(subjectPublicKeyBytes, certKey)) { if (debug != null) { debug.println("X509CertSelector.match: " - + "subject public keys don't match"); + + "subject public keys don't match"); } return false; } } boolean result = matchBasicConstraints(xcert) - && matchKeyUsage(xcert) - && matchExtendedKeyUsage(xcert) - && matchSubjectKeyID(xcert) - && matchAuthorityKeyID(xcert) - && matchPrivateKeyValid(xcert) - && matchSubjectPublicKeyAlgID(xcert) - && matchPolicy(xcert) - && matchSubjectAlternativeNames(xcert) - && matchPathToNames(xcert) - && matchNameConstraints(xcert); + && matchKeyUsage(xcert) + && matchExtendedKeyUsage(xcert) + && matchSubjectKeyID(xcert) + && matchAuthorityKeyID(xcert) + && matchPrivateKeyValid(xcert) + && matchSubjectPublicKeyAlgID(xcert) + && matchPolicy(xcert) + && matchSubjectAlternativeNames(xcert) + && matchPathToNames(xcert) + && matchNameConstraints(xcert); if (result && (debug != null)) { debug.println("X509CertSelector.match returning: true"); @@ -2106,7 +2101,7 @@ public class X509CertSelector implements CertSelector { if (extVal == null) { if (debug != null) { debug.println("X509CertSelector.match: " - + "no subject key ID extension"); + + "no subject key ID extension"); } return false; } @@ -2116,17 +2111,17 @@ public class X509CertSelector implements CertSelector { !Arrays.equals(subjectKeyID, certSubjectKeyID)) { if (debug != null) { debug.println("X509CertSelector.match: subject key IDs " + - "don't match\nX509CertSelector.match: subjectKeyID: " + - Arrays.toString(subjectKeyID) + - "\nX509CertSelector.match: certSubjectKeyID: " + - Arrays.toString(certSubjectKeyID)); + "don't match\nX509CertSelector.match: subjectKeyID: " + + Arrays.toString(subjectKeyID) + + "\nX509CertSelector.match: certSubjectKeyID: " + + Arrays.toString(certSubjectKeyID)); } return false; } } catch (IOException ex) { if (debug != null) { debug.println("X509CertSelector.match: " - + "exception in subject key ID check"); + + "exception in subject key ID check"); } return false; } @@ -2143,7 +2138,7 @@ public class X509CertSelector implements CertSelector { if (extVal == null) { if (debug != null) { debug.println("X509CertSelector.match: " - + "no authority key ID extension"); + + "no authority key ID extension"); } return false; } @@ -2153,14 +2148,14 @@ public class X509CertSelector implements CertSelector { !Arrays.equals(authorityKeyID, certAuthKeyID)) { if (debug != null) { debug.println("X509CertSelector.match: " - + "authority key IDs don't match"); + + "authority key IDs don't match"); } return false; } } catch (IOException ex) { if (debug != null) { debug.println("X509CertSelector.match: " - + "exception in authority key ID check"); + + "exception in authority key ID check"); } return false; } @@ -2174,8 +2169,7 @@ public class X509CertSelector implements CertSelector { } PrivateKeyUsageExtension ext = null; try { - ext = (PrivateKeyUsageExtension) - getExtensionObject(xcert, PRIVATE_KEY_USAGE_ID); + ext = (PrivateKeyUsageExtension) getExtensionObject(xcert, PRIVATE_KEY_USAGE_ID); if (ext != null) { ext.valid(privateKeyValid); } @@ -2189,9 +2183,9 @@ public class X509CertSelector implements CertSelector { // not able to retrieve notAfter value } debug.println("X509CertSelector.match: private key usage not " - + "within validity date; ext.NOT_After: " - + time + "; X509CertSelector: " - + this.toString()); + + "within validity date; ext.NOT_After: " + + time + "; X509CertSelector: " + + this.toString()); e1.printStackTrace(); } return false; @@ -2205,17 +2199,17 @@ public class X509CertSelector implements CertSelector { // not able to retrieve notBefore value } debug.println("X509CertSelector.match: private key usage not " - + "within validity date; ext.NOT_BEFORE: " - + time + "; X509CertSelector: " - + this.toString()); + + "within validity date; ext.NOT_BEFORE: " + + time + "; X509CertSelector: " + + this.toString()); e2.printStackTrace(); } return false; } catch (IOException e4) { if (debug != null) { debug.println("X509CertSelector.match: IOException in " - + "private key usage check; X509CertSelector: " - + this.toString()); + + "private key usage check; X509CertSelector: " + + this.toString()); e4.printStackTrace(); } return false; @@ -2238,20 +2232,20 @@ public class X509CertSelector implements CertSelector { AlgorithmId algID = AlgorithmId.parse(val.data.getDerValue()); if (debug != null) { debug.println("X509CertSelector.match: subjectPublicKeyAlgID = " - + subjectPublicKeyAlgID + ", xcert subjectPublicKeyAlgID = " - + algID.getOID()); + + subjectPublicKeyAlgID + ", xcert subjectPublicKeyAlgID = " + + algID.getOID()); } if (!subjectPublicKeyAlgID.equals(algID.getOID())) { if (debug != null) { debug.println("X509CertSelector.match: " - + "subject public key alg IDs don't match"); + + "subject public key alg IDs don't match"); } return false; } } catch (IOException e5) { if (debug != null) { debug.println("X509CertSelector.match: IOException in subject " - + "public key algorithm OID check"); + + "public key algorithm OID check"); } return false; } @@ -2267,10 +2261,10 @@ public class X509CertSelector implements CertSelector { if (certKeyUsage != null) { for (int keyBit = 0; keyBit < keyUsage.length; keyBit++) { if (keyUsage[keyBit] && - ((keyBit >= certKeyUsage.length) || !certKeyUsage[keyBit])) { + ((keyBit >= certKeyUsage.length) || !certKeyUsage[keyBit])) { if (debug != null) { debug.println("X509CertSelector.match: " - + "key usage bits don't match"); + + "key usage bits don't match"); } return false; } @@ -2285,17 +2279,15 @@ public class X509CertSelector implements CertSelector { return true; } try { - ExtendedKeyUsageExtension ext = - (ExtendedKeyUsageExtension)getExtensionObject(xcert, - EXTENDED_KEY_USAGE_ID); + ExtendedKeyUsageExtension ext = (ExtendedKeyUsageExtension) getExtensionObject(xcert, + EXTENDED_KEY_USAGE_ID); if (ext != null) { - Vector certKeyPurposeVector = - ext.get(ExtendedKeyUsageExtension.USAGES); + Vector certKeyPurposeVector = ext.get(ExtendedKeyUsageExtension.USAGES); if (!certKeyPurposeVector.contains(ANY_EXTENDED_KEY_USAGE) && !certKeyPurposeVector.containsAll(keyPurposeOIDSet)) { if (debug != null) { debug.println("X509CertSelector.match: cert failed " - + "extendedKeyUsage criterion"); + + "extendedKeyUsage criterion"); } return false; } @@ -2303,7 +2295,7 @@ public class X509CertSelector implements CertSelector { } catch (IOException ex) { if (debug != null) { debug.println("X509CertSelector.match: " - + "IOException in extended key usage check"); + + "IOException in extended key usage check"); } return false; } @@ -2316,32 +2308,28 @@ public class X509CertSelector implements CertSelector { return true; } try { - SubjectAlternativeNameExtension sanExt = - (SubjectAlternativeNameExtension) getExtensionObject(xcert, - SUBJECT_ALT_NAME_ID); + SubjectAlternativeNameExtension sanExt = (SubjectAlternativeNameExtension) getExtensionObject(xcert, + SUBJECT_ALT_NAME_ID); if (sanExt == null) { if (debug != null) { - debug.println("X509CertSelector.match: " - + "no subject alternative name extension"); + debug.println("X509CertSelector.match: " + + "no subject alternative name extension"); } return false; } - GeneralNames certNames = - sanExt.get(SubjectAlternativeNameExtension.SUBJECT_NAME); - Iterator i = - subjectAlternativeGeneralNames.iterator(); + GeneralNames certNames = sanExt.get(SubjectAlternativeNameExtension.SUBJECT_NAME); + Iterator i = subjectAlternativeGeneralNames.iterator(); while (i.hasNext()) { GeneralNameInterface matchName = i.next(); boolean found = false; - for (Iterator t = certNames.iterator(); - t.hasNext() && !found; ) { + for (Iterator t = certNames.iterator(); t.hasNext() && !found;) { GeneralNameInterface certName = (t.next()).getName(); found = certName.equals(matchName); } if (!found && (matchAllSubjectAltNames || !i.hasNext())) { if (debug != null) { - debug.println("X509CertSelector.match: subject alternative " - + "name " + matchName + " not found"); + debug.println("X509CertSelector.match: subject alternative " + + "name " + matchName + " not found"); } return false; } else if (found && !matchAllSubjectAltNames) { @@ -2351,7 +2339,7 @@ public class X509CertSelector implements CertSelector { } catch (IOException ex) { if (debug != null) debug.println("X509CertSelector.match: IOException in subject " - + "alternative name check"); + + "alternative name check"); return false; } return true; @@ -2366,14 +2354,14 @@ public class X509CertSelector implements CertSelector { if (!nc.verify(xcert)) { if (debug != null) { debug.println("X509CertSelector.match: " - + "name constraints not satisfied"); + + "name constraints not satisfied"); } return false; } } catch (IOException e) { if (debug != null) { debug.println("X509CertSelector.match: " - + "IOException in name constraints check"); + + "IOException in name constraints check"); } return false; } @@ -2386,12 +2374,12 @@ public class X509CertSelector implements CertSelector { return true; } try { - CertificatePoliciesExtension ext = (CertificatePoliciesExtension) - getExtensionObject(xcert, CERT_POLICIES_ID); + CertificatePoliciesExtension ext = (CertificatePoliciesExtension) getExtensionObject(xcert, + CERT_POLICIES_ID); if (ext == null) { if (debug != null) { - debug.println("X509CertSelector.match: " - + "no certificate policy extension"); + debug.println("X509CertSelector.match: " + + "no certificate policy extension"); } return false; } @@ -2415,7 +2403,7 @@ public class X509CertSelector implements CertSelector { if (policyIDs.isEmpty()) { if (debug != null) { debug.println("X509CertSelector.match: " - + "cert failed policyAny criterion"); + + "cert failed policyAny criterion"); } return false; } @@ -2429,7 +2417,7 @@ public class X509CertSelector implements CertSelector { if (!foundOne) { if (debug != null) { debug.println("X509CertSelector.match: " - + "cert failed policyAny criterion"); + + "cert failed policyAny criterion"); } return false; } @@ -2438,7 +2426,7 @@ public class X509CertSelector implements CertSelector { } catch (IOException ex) { if (debug != null) { debug.println("X509CertSelector.match: " - + "IOException in certificate policy ID check"); + + "IOException in certificate policy ID check"); } return false; } @@ -2451,24 +2439,20 @@ public class X509CertSelector implements CertSelector { return true; } try { - NameConstraintsExtension ext = (NameConstraintsExtension) - getExtensionObject(xcert, NAME_CONSTRAINTS_ID); + NameConstraintsExtension ext = (NameConstraintsExtension) getExtensionObject(xcert, NAME_CONSTRAINTS_ID); if (ext == null) { return true; } if ((debug != null) && Debug.isOn("certpath")) { debug.println("X509CertSelector.match pathToNames:\n"); - Iterator i = - pathToGeneralNames.iterator(); + Iterator i = pathToGeneralNames.iterator(); while (i.hasNext()) { debug.println(" " + i.next() + "\n"); } } - GeneralSubtrees permitted = - ext.get(NameConstraintsExtension.PERMITTED_SUBTREES); - GeneralSubtrees excluded = - ext.get(NameConstraintsExtension.EXCLUDED_SUBTREES); + GeneralSubtrees permitted = ext.get(NameConstraintsExtension.PERMITTED_SUBTREES); + GeneralSubtrees excluded = ext.get(NameConstraintsExtension.EXCLUDED_SUBTREES); if (excluded != null) { if (matchExcluded(excluded) == false) { return false; @@ -2482,7 +2466,7 @@ public class X509CertSelector implements CertSelector { } catch (IOException ex) { if (debug != null) { debug.println("X509CertSelector.match: " - + "IOException in name constraints check"); + + "IOException in name constraints check"); } return false; } @@ -2495,7 +2479,7 @@ public class X509CertSelector implements CertSelector { * to all pathToNames. If any pathToName is within any of the * subtrees listed in excluded, return false. */ - for (Iterator t = excluded.iterator(); t.hasNext(); ) { + for (Iterator t = excluded.iterator(); t.hasNext();) { GeneralSubtree tree = t.next(); GeneralNameInterface excludedName = tree.getName().getName(); Iterator i = pathToGeneralNames.iterator(); @@ -2503,16 +2487,16 @@ public class X509CertSelector implements CertSelector { GeneralNameInterface pathToName = i.next(); if (excludedName.getType() == pathToName.getType()) { switch (pathToName.constrains(excludedName)) { - case GeneralNameInterface.NAME_WIDENS: - case GeneralNameInterface.NAME_MATCH: - if (debug != null) { - debug.println("X509CertSelector.match: name constraints " - + "inhibit path to specified name"); - debug.println("X509CertSelector.match: excluded name: " + - pathToName); - } - return false; - default: + case GeneralNameInterface.NAME_WIDENS: + case GeneralNameInterface.NAME_MATCH: + if (debug != null) { + debug.println("X509CertSelector.match: name constraints " + + "inhibit path to specified name"); + debug.println("X509CertSelector.match: excluded name: " + + pathToName); + } + return false; + default: } } } @@ -2541,17 +2525,17 @@ public class X509CertSelector implements CertSelector { nameTypeFound = true; names = names + " " + permittedName; switch (pathToName.constrains(permittedName)) { - case GeneralNameInterface.NAME_WIDENS: - case GeneralNameInterface.NAME_MATCH: - permittedNameFound = true; - break; - default: + case GeneralNameInterface.NAME_WIDENS: + case GeneralNameInterface.NAME_MATCH: + permittedNameFound = true; + break; + default: } } } if (!permittedNameFound && nameTypeFound) { if (debug != null) - debug.println("X509CertSelector.match: " + + debug.println("X509CertSelector.match: " + "name constraints inhibit path to specified name; " + "permitted names of type " + pathToName.getType() + ": " + names); @@ -2591,8 +2575,8 @@ public class X509CertSelector implements CertSelector { @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly private static Set cloneSet(Set set) { if (set instanceof HashSet) { - Object clone = ((HashSet)set).clone(); - return (Set)clone; + Object clone = ((HashSet) set).clone(); + return (Set) clone; } else { return new HashSet(set); } @@ -2605,13 +2589,11 @@ public class X509CertSelector implements CertSelector { */ public Object clone() { try { - X509CertSelector copy = (X509CertSelector)super.clone(); + X509CertSelector copy = (X509CertSelector) super.clone(); // Must clone these because addPathToName et al. modify them if (subjectAlternativeNames != null) { - copy.subjectAlternativeNames = - cloneSet(subjectAlternativeNames); - copy.subjectAlternativeGeneralNames = - cloneSet(subjectAlternativeGeneralNames); + copy.subjectAlternativeNames = cloneSet(subjectAlternativeNames); + copy.subjectAlternativeGeneralNames = cloneSet(subjectAlternativeGeneralNames); } if (pathToGeneralNames != null) { copy.pathToNames = cloneSet(pathToNames); 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 7c0200742..2ed067d30 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,13 +26,10 @@ 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; +import java.security.cert.X509CRLSelector; /** * Helper class that allows access to JDK specific known-public methods 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/ForwardState.java b/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java index 2dc9e208e..2db43ad87 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,25 +31,20 @@ 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; /** * A specification of a forward PKIX validation state * which is initialized by each build and updated each time a * certificate is added to the current path. - * @since 1.4 - * @author Yassir Elley + * + * @since 1.4 + * @author Yassir Elley */ class ForwardState implements State { @@ -61,9 +56,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,14 +65,14 @@ class ForwardState implements State { /* Flag indicating if state is initial (path is just starting) */ private boolean init = true; - /* the untrusted certificates checker */ UntrustedChecker untrustedChecker; /* The list of user-defined checkers that support forward checking */ ArrayList forwardCheckers; - /* Flag indicating if key needing to inherit key parameters has been + /* + * Flag indicating if key needing to inherit key parameters has been * encountered. */ boolean keyParamsNeededFlag = false; @@ -101,7 +93,7 @@ class ForwardState implements State { * key parameters has been encountered. * * @return boolean true if key needing to inherit parameters has been - * encountered; false otherwise. + * encountered; false otherwise. */ @Override public boolean keyParamsNeeded() { @@ -118,10 +110,7 @@ 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 keyParamsNeeded: ").append(String.valueOf(keyParamsNeededFlag)); sb.append("]\n"); return sb.toString(); } @@ -132,9 +121,7 @@ class ForwardState implements State { * @param certPathCheckers the list of user-defined PKIXCertPathCheckers */ public void initState(List certPathCheckers) - throws CertPathValidatorException - { - subjectNamesTraversed = new HashSet(); + throws CertPathValidatorException { traversedCACerts = 0; /* @@ -159,7 +146,7 @@ class ForwardState implements State { */ @Override public void updateState(X509Certificate cert) - throws CertificateException, IOException, CertPathValidatorException { + throws CertificateException, IOException, CertPathValidatorException { if (cert == null) return; @@ -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 @@ -233,24 +190,15 @@ class ForwardState implements State { ForwardState clonedState = (ForwardState) super.clone(); /* clone checkers, if cloneable */ - clonedState.forwardCheckers = (ArrayList) - forwardCheckers.clone(); - ListIterator li = - clonedState.forwardCheckers.listIterator(); + clonedState.forwardCheckers = (ArrayList) forwardCheckers.clone(); + ListIterator li = clonedState.forwardCheckers.listIterator(); while (li.hasNext()) { PKIXCertPathChecker checker = li.next(); if (checker instanceof Cloneable) { - li.set((PKIXCertPathChecker)checker.clone()); + li.set((PKIXCertPathChecker) checker.clone()); } } - /* - * 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 5f825ff44..46fcaa32a 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, 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 @@ -33,6 +33,7 @@ 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,27 +43,32 @@ 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; /** * This class builds certification paths in the forward direction. * - *

If successful, it returns a certification path which has successfully + *

+ * If successful, it returns a certification path which has successfully * satisfied all the constraints and requirements specified in the * PKIXBuilderParameters object and has been validated according to the PKIX * path validation algorithm defined in RFC 5280. * - *

This implementation uses a depth-first search approach to finding + *

+ * This implementation uses a depth-first search approach to finding * certification paths. If it comes to a point in which it cannot find * any more certificates leading to the target OR the path length is too long * it backtracks to previous paths until the target has been found or * all possible paths have been exhausted. * - *

This implementation is not thread-safe. + *

+ * This implementation is not thread-safe. * - * @since 1.4 - * @author Sean Mullan - * @author Yassir Elley + * @since 1.4 + * @author Sean Mullan + * @author Yassir Elley */ public final class SunCertPathBuilder extends CertPathBuilderSpi { @@ -102,21 +108,24 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { * be specified in the input parameter set. This method will * attempt to build in the forward direction: from the target to the CA. * - *

The certification path that is constructed is validated + *

+ * The certification path that is constructed is validated * according to the PKIX specification. * * @param params the parameter set for building a path. Must be an instance - * of PKIXBuilderParameters. + * of PKIXBuilderParameters. * @return a certification path builder result. * @exception CertPathBuilderException Exception thrown if builder is - * unable to build a complete certification path from the trusted anchor(s) - * to the target subject. + * unable to build a complete certification + * path from the trusted anchor(s) + * to the target subject. * @throws InvalidAlgorithmParameterException if the given parameters are - * inappropriate for this certification path builder. + * inappropriate for this + * certification path builder. */ @Override public CertPathBuilderResult engineBuild(CertPathParameters params) - throws CertPathBuilderException, InvalidAlgorithmParameterException { + throws CertPathBuilderException, InvalidAlgorithmParameterException { if (debug != null) { debug.println("SunCertPathBuilder.engineBuild(" + params + ")"); @@ -130,26 +139,28 @@ 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; " + - "try building again searching all certstores"); + 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 " + throw new SunCertPathBuilderException("unable to find valid " + "certification path to requested target", new AdjacencyList(adjList)); - } } return result; } private PKIXCertPathBuilderResult buildCertPath(boolean searchAllCertStores, - List> adjList) - throws CertPathBuilderException - { + List> adjList) + throws CertPathBuilderException { // Init shared variables and build certification path pathCompleted = false; trustAnchor = null; @@ -161,12 +172,12 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { } catch (GeneralSecurityException | IOException e) { if (debug != null) { debug.println("SunCertPathBuilder.engineBuild() exception in " - + "build"); + + "build"); e.printStackTrace(); } throw new SunCertPathBuilderException("unable to find valid " - + "certification path to requested target", e, - new AdjacencyList(adjList)); + + "certification path to requested target", e, + new AdjacencyList(adjList)); } // construct SunCertPathBuilderResult @@ -174,7 +185,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { if (pathCompleted) { if (debug != null) debug.println("SunCertPathBuilder.engineBuild() " - + "pathCompleted"); + + "pathCompleted"); // we must return a certpath which has the target // as the first cert in the certpath - i.e. reverse @@ -182,19 +193,19 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { Collections.reverse(certPathList); return new SunCertPathBuilderResult( - cf.generateCertPath(certPathList), trustAnchor, - policyTreeResult, finalPublicKey, - new AdjacencyList(adjList)); + cf.generateCertPath(certPathList), trustAnchor, + policyTreeResult, finalPublicKey, + new AdjacencyList(adjList)); } } catch (CertificateException e) { if (debug != null) { debug.println("SunCertPathBuilder.engineBuild() exception " - + "in wrap-up"); + + "in wrap-up"); e.printStackTrace(); } throw new SunCertPathBuilderException("unable to find valid " - + "certification path to requested target", e, - new AdjacencyList(adjList)); + + "certification path to requested target", e, + new AdjacencyList(adjList)); } return null; @@ -204,10 +215,9 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { * Private build forward method. */ private void buildForward(List> adjacencyList, - LinkedList certPathList, - boolean searchAllCertStores) - throws GeneralSecurityException, IOException - { + LinkedList certPathList, + boolean searchAllCertStores) + throws GeneralSecurityException, IOException { if (debug != null) { debug.println("SunCertPathBuilder.buildForward()..."); } @@ -223,9 +233,9 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { currentState.untrustedChecker = new UntrustedChecker(); depthFirstSearchForward(buildParams.targetSubject(), currentState, - new ForwardBuilder(buildParams, - searchAllCertStores), - adjacencyList, certPathList); + new ForwardBuilder(buildParams, + searchAllCertStores), + adjacencyList, certPathList); } /* @@ -241,41 +251,39 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { * for an explanation of the DFS algorithm. * * @param dN the distinguished name being currently searched for certs + * * @param currentState the current PKIX validation state */ private void depthFirstSearchForward(X500Principal dN, - ForwardState currentState, - ForwardBuilder builder, - List> adjList, - LinkedList cpList) - throws GeneralSecurityException, IOException - { + ForwardState currentState, + ForwardBuilder builder, + List> adjList, + LinkedList cpList) + throws GeneralSecurityException, IOException { if (debug != null) { debug.println("SunCertPathBuilder.depthFirstSearchForward(" + dN - + ", " + currentState.toString() + ")"); + + ", " + currentState.toString() + ")"); } /* * Find all the certificates issued to dN which * satisfy the PKIX certification path constraints. */ - Collection certs = - builder.getMatchingCerts(currentState, buildParams.certStores()); - List vertices = addVertices(certs, adjList); + Collection certs = builder.getMatchingCerts(currentState, buildParams.certStores()); + List vertices = addVertices(certs, adjList, cpList); if (debug != null) { debug.println("SunCertPathBuilder.depthFirstSearchForward(): " - + "certs.size=" + vertices.size()); + + "certs.size=" + vertices.size()); } /* * 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: - for (Vertex vertex : vertices) { + vertices: for (Vertex vertex : vertices) { /** * Restore state to currentState each time through the loop. * This is important because some of the user-defined @@ -291,7 +299,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { } catch (GeneralSecurityException gse) { if (debug != null) { debug.println("SunCertPathBuilder.depthFirstSearchForward()" - + ": validation failed: " + gse); + + ": validation failed: " + gse); gse.printStackTrace(); } vertex.setThrowable(gse); @@ -301,17 +309,17 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { /* * Certificate is good. * If cert completes the path, - * process userCheckers that don't support forward checking - * and process policies over whole path - * and backtrack appropriately if there is a failure + * process userCheckers that don't support forward checking + * and process policies over whole path + * and backtrack appropriately if there is a failure * else if cert does not complete the path, - * add it to the path + * add it to the path */ if (builder.isPathCompleted(cert)) { if (debug != null) debug.println("SunCertPathBuilder.depthFirstSearchForward()" - + ": commencing final verification"); + + ": commencing final verification"); List appendedCerts = new ArrayList<>(cpList); @@ -321,51 +329,45 @@ 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); - Set initExpPolSet = - Collections.singleton(PolicyChecker.ANY_POLICY); + // 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); PolicyNodeImpl rootNode = new PolicyNodeImpl(null, - PolicyChecker.ANY_POLICY, null, false, initExpPolSet, false); - - List checkers = new ArrayList<>(); - PolicyChecker policyChecker - = new PolicyChecker(buildParams.initialPolicies(), - appendedCerts.size(), - buildParams.explicitPolicyRequired(), - buildParams.policyMappingInhibited(), - buildParams.anyPolicyInhibited(), - buildParams.policyQualifiersRejected(), - rootNode); + PolicyChecker.ANY_POLICY, null, false, initExpPolSet, false); + + PolicyChecker policyChecker = new PolicyChecker(buildParams.initialPolicies(), + appendedCerts.size(), + buildParams.explicitPolicyRequired(), + buildParams.policyMappingInhibited(), + buildParams.anyPolicyInhibited(), + 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.timestamp(), buildParams.variant())); buildParams.setCertPath(cf.generateCertPath(appendedCerts)); @@ -375,13 +377,13 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { if (ckr instanceof PKIXRevocationChecker) { if (revCheckerAdded) { throw new CertPathValidatorException( - "Only one PKIXRevocationChecker can be specified"); + "Only one PKIXRevocationChecker can be specified"); } revCheckerAdded = true; // if it's our own, initialize it if (ckr instanceof RevocationChecker) { - ((RevocationChecker)ckr).init(builder.trustAnchor, - buildParams); + ((RevocationChecker) ckr).init(builder.trustAnchor, + buildParams); } } } @@ -389,7 +391,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { // a PKIXRevocationChecker has not already been added if (buildParams.revocationEnabled() && !revCheckerAdded) { checkers.add(new RevocationChecker(builder.trustAnchor, - buildParams)); + buildParams)); } checkers.addAll(ckrs); @@ -401,9 +403,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { X509Certificate currCert = appendedCerts.get(i); if (debug != null) debug.println("current subject = " - + currCert.getSubjectX500Principal()); - Set unresCritExts = - currCert.getCriticalExtensionOIDs(); + + currCert.getSubjectX500Principal()); + Set unresCritExts = currCert.getCriticalExtensionOIDs(); if (unresCritExts == null) { unresCritExts = Collections.emptySet(); } @@ -417,8 +418,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { // AlgorithmChecker may not be // able to set the trust anchor until now. if (currChecker instanceof AlgorithmChecker) { - ((AlgorithmChecker)currChecker). - trySetTrustAnchor(builder.trustAnchor); + ((AlgorithmChecker) currChecker).trySetTrustAnchor(builder.trustAnchor); } } @@ -426,9 +426,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { currChecker.check(currCert, unresCritExts); } catch (CertPathValidatorException cpve) { if (debug != null) - debug.println - ("SunCertPathBuilder.depthFirstSearchForward(): " + - "final verification failed: " + cpve); + debug.println("SunCertPathBuilder.depthFirstSearchForward(): " + + "final verification failed: " + cpve); // If the target cert itself is revoked, we // cannot trust it. We can bail out here. if (buildParams.targetCertConstraints().match(currCert) @@ -447,12 +446,9 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { * removed all extensions that all user checkers * are capable of processing. */ - for (PKIXCertPathChecker checker : - buildParams.certPathCheckers()) - { + for (PKIXCertPathChecker checker : buildParams.certPathCheckers()) { if (checker.isForwardCheckingSupported()) { - Set suppExts = - checker.getSupportedExtensions(); + Set suppExts = checker.getSupportedExtensions(); if (suppExts != null) { unresCritExts.removeAll(suppExts); } @@ -467,20 +463,19 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { unresCritExts.remove(PolicyConstraints_Id.toString()); unresCritExts.remove(InhibitAnyPolicy_Id.toString()); unresCritExts.remove( - SubjectAlternativeName_Id.toString()); + SubjectAlternativeName_Id.toString()); unresCritExts.remove(KeyUsage_Id.toString()); unresCritExts.remove(ExtendedKeyUsage_Id.toString()); if (!unresCritExts.isEmpty()) { - throw new CertPathValidatorException - ("unrecognized critical extension(s)", null, - null, -1, PKIXReason.UNRECOGNIZED_CRIT_EXT); + throw new CertPathValidatorException("unrecognized critical extension(s)", null, + null, -1, PKIXReason.UNRECOGNIZED_CRIT_EXT); } } } if (debug != null) debug.println("SunCertPathBuilder.depthFirstSearchForward()" - + ": final verification succeeded - path completed!"); + + ": final verification succeeded - path completed!"); pathCompleted = true; /* @@ -511,6 +506,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); } @@ -526,7 +529,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { /* recursively search for matching certs at next dN */ depthFirstSearchForward(cert.getIssuerX500Principal(), nextState, - builder, adjList, cpList); + builder, adjList, cpList); /* * If path has been completed, return ASAP! @@ -542,7 +545,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { */ if (debug != null) debug.println("SunCertPathBuilder.depthFirstSearchForward()" - + ": backtracking"); + + ": backtracking"); builder.removeFinalCertFromPath(cpList); } } @@ -553,29 +556,86 @@ 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. */ private static boolean anchorIsTarget(TrustAnchor anchor, - CertSelector sel) - { + CertSelector sel) { X509Certificate anchorCert = anchor.getTrustedCert(); if (anchorCert != null) { return sel.match(anchorCert); } return false; } -} +} \ No newline at end of file -- Gitee