173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/* 273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is free software; you can redistribute it and/or modify it 673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * under the terms of the GNU General Public License version 2 only, as 773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * published by the Free Software Foundation. Oracle designates this 873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * particular file as subject to the "Classpath" exception as provided 973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * by Oracle in the LICENSE file that accompanied this code. 1073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is distributed in the hope that it will be useful, but WITHOUT 1273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * version 2 for more details (a copy is included in the LICENSE file that 1573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * accompanied this code). 1673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * You should have received a copy of the GNU General Public License version 1873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2 along with this work; if not, write to the Free Software Foundation, 1973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * or visit www.oracle.com if you need additional information or have any 2373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * questions. 2473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 2573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 2673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootpackage sun.security.provider.certpath; 2773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 2873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.IOException; 2973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertificateException; 3073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertPathValidatorException; 3173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.PKIXCertPathChecker; 3273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509Certificate; 3373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.ArrayList; 3473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.HashSet; 3573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.List; 3673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.ListIterator; 3773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport javax.security.auth.x500.X500Principal; 3873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 3973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.Debug; 4073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.SubjectAlternativeNameExtension; 4173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralNames; 4273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralName; 4373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralNameInterface; 4473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.X500Name; 4573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.X509CertImpl; 4673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 4773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/** 4873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * A specification of a forward PKIX validation state 4973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * which is initialized by each build and updated each time a 5073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * certificate is added to the current path. 5173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @since 1.4 5273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author Yassir Elley 5373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 5473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootclass ForwardState implements State { 5573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 5673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final Debug debug = Debug.getInstance("certpath"); 5773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 5873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* The issuer DN of the last cert in the path */ 5973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X500Principal issuerDN; 6073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* The last cert in the path */ 6273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CertImpl cert; 6373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* The set of subjectDNs and subjectAltNames of all certs in the path */ 6573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root HashSet<GeneralNameInterface> subjectNamesTraversed; 6673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* 6873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * The number of intermediate CA certs which have been traversed so 6973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * far in the path 7073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 7173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int traversedCACerts; 7273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 7373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* Flag indicating if state is initial (path is just starting) */ 7473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private boolean init = true; 7573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 7673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 7773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* the untrusted certificates checker */ 784087011821a84f2a4e2b827f304bb00481d3d139Tobias Thierer // Android-removed: Android doesn't use this mechanism for checking untrusted certificates. 794087011821a84f2a4e2b827f304bb00481d3d139Tobias Thierer // UntrustedChecker untrustedChecker; 8073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 8173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* The list of user-defined checkers that support forward checking */ 8273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ArrayList<PKIXCertPathChecker> forwardCheckers; 8373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 8473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* Flag indicating if key needing to inherit key parameters has been 8573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * encountered. 8673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 8773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root boolean keyParamsNeededFlag = false; 8873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 8973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 9073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns a boolean flag indicating if the state is initial 9173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * (just starting) 9273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 9373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return boolean flag indicating if the state is initial (just starting) 9473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 9573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 9673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public boolean isInitial() { 9773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return init; 9873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 9973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 10173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Return boolean flag indicating whether a public key that needs to inherit 10273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * key parameters has been encountered. 10373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 10473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return boolean true if key needing to inherit parameters has been 10573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * encountered; false otherwise. 10673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 10773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 10873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public boolean keyParamsNeeded() { 10973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return keyParamsNeededFlag; 11073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 11173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 11273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 11373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Display state for debugging purposes 11473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 11573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 11673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public String toString() { 11773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root StringBuilder sb = new StringBuilder(); 11873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("State ["); 11973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("\n issuerDN of last cert: ").append(issuerDN); 12073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("\n traversedCACerts: ").append(traversedCACerts); 12173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("\n init: ").append(String.valueOf(init)); 12273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("\n keyParamsNeeded: ").append 12373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (String.valueOf(keyParamsNeededFlag)); 12473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("\n subjectNamesTraversed: \n").append 12573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (subjectNamesTraversed); 12673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root sb.append("]\n"); 12773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return sb.toString(); 12873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 12973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 13073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 13173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Initialize the state. 13273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 13373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param certPathCheckers the list of user-defined PKIXCertPathCheckers 13473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 13573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public void initState(List<PKIXCertPathChecker> certPathCheckers) 13673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws CertPathValidatorException 13773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 13873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root subjectNamesTraversed = new HashSet<GeneralNameInterface>(); 13973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root traversedCACerts = 0; 14073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 14173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* 14273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Populate forwardCheckers with every user-defined checker 14373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * that supports forward checking and initialize the forwardCheckers 14473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 14573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root forwardCheckers = new ArrayList<PKIXCertPathChecker>(); 14673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (PKIXCertPathChecker checker : certPathCheckers) { 14773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (checker.isForwardCheckingSupported()) { 14873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root checker.init(true); 14973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root forwardCheckers.add(checker); 15073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 15173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 15273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 15373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root init = true; 15473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 15573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 15673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 15773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Update the state with the next certificate added to the path. 15873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 15973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate which is used to update the state 16073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 16173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 16273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public void updateState(X509Certificate cert) 16373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws CertificateException, IOException, CertPathValidatorException { 16473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 16573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (cert == null) 16673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return; 16773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 16873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CertImpl icert = X509CertImpl.toImpl(cert); 16973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 17073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* see if certificate key has null parameters */ 17173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (PKIX.isDSAPublicKeyWithoutParams(icert.getPublicKey())) { 17273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root keyParamsNeededFlag = true; 17373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 17473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 17573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* update certificate */ 17673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root this.cert = icert; 17773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 17873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* update issuer DN */ 17973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root issuerDN = cert.getIssuerX500Principal(); 18073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 18173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!X509CertImpl.isSelfIssued(cert)) { 18273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 18373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* 18473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * update traversedCACerts only if this is a non-self-issued 18573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * intermediate CA cert 18673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 18773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!init && cert.getBasicConstraints() != -1) { 18873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root traversedCACerts++; 18973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 19073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 19173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 19273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* update subjectNamesTraversed only if this is the EE cert or if 19373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root this cert is not self-issued */ 19473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (init || !X509CertImpl.isSelfIssued(cert)){ 19573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X500Principal subjName = cert.getSubjectX500Principal(); 19673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root subjectNamesTraversed.add(X500Name.asX500Name(subjName)); 19773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 19873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 19973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root SubjectAlternativeNameExtension subjAltNameExt 20073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root = icert.getSubjectAlternativeNameExtension(); 20173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (subjAltNameExt != null) { 20273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralNames gNames = subjAltNameExt.get( 20373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root SubjectAlternativeNameExtension.SUBJECT_NAME); 20473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (GeneralName gName : gNames.names()) { 20573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root subjectNamesTraversed.add(gName.getName()); 20673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 20773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 20873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException e) { 20973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 21073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("ForwardState.updateState() unexpected " 21173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root + "exception"); 21273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root e.printStackTrace(); 21373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException(e); 21573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 21873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root init = false; 21973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 22073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 22173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* 22273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Clone current state. The state is cloned as each cert is 22373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * added to the path. This is necessary if backtracking occurs, 22473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * and a prior state needs to be restored. 22573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 22673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Note that this is a SMART clone. Not all fields are fully copied, 22773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * because some of them will 22873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * not have their contents modified by subsequent calls to updateState. 22973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 23073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @Override 23173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly 23273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public Object clone() { 23373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 23473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ForwardState clonedState = (ForwardState) super.clone(); 23573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 23673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* clone checkers, if cloneable */ 23773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root clonedState.forwardCheckers = (ArrayList<PKIXCertPathChecker>) 23873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root forwardCheckers.clone(); 23973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ListIterator<PKIXCertPathChecker> li = 24073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root clonedState.forwardCheckers.listIterator(); 24173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root while (li.hasNext()) { 24273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root PKIXCertPathChecker checker = li.next(); 24373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (checker instanceof Cloneable) { 24473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root li.set((PKIXCertPathChecker)checker.clone()); 24573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 24673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 24773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 24873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* 24973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Shallow copy traversed names. There is no need to 25073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * deep copy contents, since the elements of the Set 25173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * are never modified by subsequent calls to updateState(). 25273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 25373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root clonedState.subjectNamesTraversed 25473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root = (HashSet<GeneralNameInterface>)subjectNamesTraversed.clone(); 25573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return clonedState; 25673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CloneNotSupportedException e) { 25773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new InternalError(e.toString(), e); 25873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 25973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 26073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root} 261