173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/* 2258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak * Copyright (c) 2000, 2015, 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.AccessController; 3073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.GeneralSecurityException; 3173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.*; 3273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.*; 3373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 3473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.action.GetBooleanAction; 3573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.provider.certpath.PKIX.BuilderParams; 3673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.Debug; 3773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralNames; 3873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralNameInterface; 3973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralSubtrees; 4073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.NameConstraintsExtension; 4173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.SubjectAlternativeNameExtension; 4273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.X500Name; 4373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.X509CertImpl; 4473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 4573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/** 4673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Abstract class representing a builder, which is able to retrieve 4773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * matching certificates and is able to verify a particular certificate. 4873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 4973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @since 1.4 5073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author Sean Mullan 5173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author Yassir Elley 5273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 5373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 5473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootpublic abstract class Builder { 5573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 5673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final Debug debug = Debug.getInstance("certpath"); 5773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private Set<String> matchingPolicies; 5873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root final BuilderParams buildParams; 5973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root final X509CertSelector targetCertConstraints; 6073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 6273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Flag indicating whether support for the caIssuers field of the 6373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Authority Information Access extension shall be enabled. Currently 6473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * disabled by default for compatibility reasons. 6573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 6673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root final static boolean USE_AIA = AccessController.doPrivileged 6773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (new GetBooleanAction("com.sun.security.enableAIAcaIssuers")); 6873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 7073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Initialize the builder with the input parameters. 7173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 7273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param params the parameter set used to build a certification path 7373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 7473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Builder(BuilderParams buildParams) { 7573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root this.buildParams = buildParams; 7673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root this.targetCertConstraints = 7773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (X509CertSelector)buildParams.targetCertConstraints(); 7873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 7973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 8073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 8173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Retrieves certificates from the list of certStores using the buildParams 8273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * and the currentState as a filter 8373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 8473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param currentState the current State 8573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param certStores list of CertStores 8673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 8773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root abstract Collection<X509Certificate> getMatchingCerts 8873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (State currentState, List<CertStore> certStores) 8973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws CertStoreException, CertificateException, IOException; 9073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 9173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 9273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Verifies the cert against the currentState, using the certPathList 9373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * generated thus far to help with loop detection 9473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 9573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate to be verified 9673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param currentState the current state against which the cert is verified 9773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param certPathList the certPathList generated thus far 9873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 9973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root abstract void verifyCert(X509Certificate cert, State currentState, 10073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root List<X509Certificate> certPathList) 10173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws GeneralSecurityException; 10273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 10473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Verifies whether the input certificate completes the path. 10585bdb5220c5c264d1746134a90f6e11f15745787Przemyslaw Szczepaniak * When building in the forward direction, a trust anchor will 10685bdb5220c5c264d1746134a90f6e11f15745787Przemyslaw Szczepaniak * complete the path. 10773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 10873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate to test 10973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return a boolean value indicating whether the cert completes the path. 11073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 11173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root abstract boolean isPathCompleted(X509Certificate cert); 11273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 11373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 11473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Adds the certificate to the certPathList 11573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 11673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate to be added 11773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param certPathList the certification path list 11873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 11973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root abstract void addCertToPath(X509Certificate cert, 12073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root LinkedList<X509Certificate> certPathList); 12173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 12273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 12373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Removes final certificate from the certPathList 12473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 12573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param certPathList the certification path list 12673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 12773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root abstract void removeFinalCertFromPath 12873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (LinkedList<X509Certificate> certPathList); 12973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 13073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 13173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * get distance of one GeneralName from another 13273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 13373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param base GeneralName at base of subtree 13473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param test GeneralName to be tested against base 13573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param incomparable the value to return if the names are 13673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * incomparable 13773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return distance of test name from base, where 0 13873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * means exact match, 1 means test is an immediate 13973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * child of base, 2 means test is a grandchild, etc. 14073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * -1 means test is a parent of base, -2 means test 14173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * is a grandparent, etc. 14273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 14373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static int distance(GeneralNameInterface base, 14473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralNameInterface test, int incomparable) 14573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 14673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root switch (base.constrains(test)) { 14773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_DIFF_TYPE: 14873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 14973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.distance(): Names are different types"); 15073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 15173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 15273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_SAME_TYPE: 15373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 15473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.distance(): Names are same type but " + 15573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root "in different subtrees"); 15673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 15773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 15873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_MATCH: 15973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return 0; 16073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_WIDENS: 16173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root break; 16273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_NARROWS: 16373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root break; 16473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root default: // should never occur 16573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 16673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 16773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 16873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* names are in same subtree */ 16973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return test.subtreeDepth() - base.subtreeDepth(); 17073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 17173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 17273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 17373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * get hop distance of one GeneralName from another in links where 17473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * the names need not have an ancestor/descendant relationship. 17573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * For example, the hop distance from ou=D,ou=C,o=B,c=US to 17673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * ou=F,ou=E,ou=C,o=B,c=US is 3: D->C, C->E, E->F. The hop distance 17773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * from ou=C,o=B,c=US to ou=D,ou=C,o=B,c=US is -1: C->D 17873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 17973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param base GeneralName 18073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param test GeneralName to be tested against base 18173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param incomparable the value to return if the names are 18273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * incomparable 18373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return distance of test name from base measured in hops in the 18473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * namespace hierarchy, where 0 means exact match. Result 18573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * is positive if path is some number of up hops followed by 18673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * some number of down hops; result is negative if path is 18773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * some number of down hops. 18873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 18973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static int hops(GeneralNameInterface base, GeneralNameInterface test, 19073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int incomparable) 19173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 19273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int baseRtest = base.constrains(test); 19373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root switch (baseRtest) { 19473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_DIFF_TYPE: 19573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 19673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.hops(): Names are different types"); 19773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 19873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 19973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_SAME_TYPE: 20073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* base and test are in different subtrees */ 20173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root break; 20273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_MATCH: 20373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* base matches test */ 20473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return 0; 20573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_WIDENS: 20673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* base is ancestor of test */ 20773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (test.subtreeDepth()-base.subtreeDepth()); 20873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root case GeneralNameInterface.NAME_NARROWS: 20973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* base is descendant of test */ 21073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (test.subtreeDepth()-base.subtreeDepth()); 21173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root default: // should never occur 21273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 21373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 21573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* names are in different subtrees */ 21673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (base.getType() != GeneralNameInterface.NAME_DIRECTORY) { 21773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 21873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.hops(): hopDistance not implemented " + 21973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root "for this name type"); 22073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 22173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 22273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 22373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X500Name baseName = (X500Name)base; 22473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X500Name testName = (X500Name)test; 22573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X500Name commonName = baseName.commonAncestor(testName); 22673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (commonName == null) { 22773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 22873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.hops(): Names are in different " + 22973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root "namespaces"); 23073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 23173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return incomparable; 23273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else { 23373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int commonDistance = commonName.subtreeDepth(); 23473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int baseDistance = baseName.subtreeDepth(); 23573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int testDistance = testName.subtreeDepth(); 23673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (baseDistance + testDistance - (2 * commonDistance)); 23773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 23873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 23973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 24073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 24173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Determine how close a given certificate gets you toward 24273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * a given target. 24373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 24473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param constraints Current NameConstraints; if null, 24573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * then caller must verify NameConstraints 24673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * independently, realizing that this certificate 24773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * may not actually lead to the target at all. 24873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert Candidate certificate for chain 24973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param target GeneralNameInterface name of target 25073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return distance from this certificate to target: 25173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <ul> 25273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <li>-1 means certificate could be CA for target, but 25373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * there are no NameConstraints limiting how close 25473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <li> 0 means certificate subject or subjectAltName 25573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * matches target 25673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <li> 1 means certificate is permitted to be CA for 25773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * target. 25873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <li> 2 means certificate is permitted to be CA for 25973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * parent of target. 26073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <li>>0 in general, means certificate is permitted 26173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * to be a CA for this distance higher in the naming 26273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * hierarchy than the target, plus 1. 26373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * </ul> 26473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <p>Note that the subject and/or subjectAltName of the 26573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * candidate cert does not have to be an ancestor of the 26673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * target in order to be a CA that can issue a certificate to 26773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * the target. In these cases, the target distance is calculated 26873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * by inspecting the NameConstraints extension in the candidate 26973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * certificate. For example, suppose the target is an X.500 DN with 27073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * a value of "CN=mullan,OU=ireland,O=sun,C=us" and the 27173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * NameConstraints extension in the candidate certificate 27273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * includes a permitted component of "O=sun,C=us", which implies 27373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * that the candidate certificate is allowed to issue certs in 27473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * the "O=sun,C=us" namespace. The target distance is 3 27573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * ((distance of permitted NC from target) + 1). 27673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * The (+1) is added to distinguish the result from the case 27773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * which returns (0). 27873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws IOException if certificate does not get closer 27973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 28073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static int targetDistance(NameConstraintsExtension constraints, 28173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate cert, GeneralNameInterface target) 28273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws IOException 28373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 28473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* ensure that certificate satisfies existing name constraints */ 28573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (constraints != null && !constraints.verify(cert)) { 28673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new IOException("certificate does not satisfy existing name " 28773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root + "constraints"); 28873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 28973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 29073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CertImpl certImpl; 29173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 29273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certImpl = X509CertImpl.toImpl(cert); 29373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertificateException e) { 29473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new IOException("Invalid certificate", e); 29573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 29673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* see if certificate subject matches target */ 29773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X500Name subject = X500Name.asX500Name(certImpl.getSubjectX500Principal()); 29873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (subject.equals(target)) { 29973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* match! */ 30073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return 0; 30173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 30273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 30373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root SubjectAlternativeNameExtension altNameExt = 30473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certImpl.getSubjectAlternativeNameExtension(); 30573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (altNameExt != null) { 30673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralNames altNames = altNameExt.get( 30773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root SubjectAlternativeNameExtension.SUBJECT_NAME); 30873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* see if any alternative name matches target */ 30973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (altNames != null) { 31073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (int j = 0, n = altNames.size(); j < n; j++) { 31173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralNameInterface altName = altNames.get(j).getName(); 31273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (altName.equals(target)) { 31373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return 0; 31473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 31973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 32073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* no exact match; see if certificate can get us to target */ 32173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 32273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* first, get NameConstraints out of certificate */ 32373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root NameConstraintsExtension ncExt = certImpl.getNameConstraintsExtension(); 32473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (ncExt == null) { 32573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return -1; 32673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 32773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 32873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* merge certificate's NameConstraints with current NameConstraints */ 32973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (constraints != null) { 33073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root constraints.merge(ncExt); 33173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else { 33273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Make sure we do a clone here, because we're probably 33373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // going to modify this object later and we don't want to 33473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // be sharing it with a Certificate object! 33573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root constraints = (NameConstraintsExtension) ncExt.clone(); 33673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 33873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 33973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.targetDistance() merged constraints: " 34073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root + String.valueOf(constraints)); 34173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 34273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* reduce permitted by excluded */ 34373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralSubtrees permitted = 34473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root constraints.get(NameConstraintsExtension.PERMITTED_SUBTREES); 34573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralSubtrees excluded = 34673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root constraints.get(NameConstraintsExtension.EXCLUDED_SUBTREES); 34773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (permitted != null) { 34873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root permitted.reduce(excluded); 34973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 35073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 35173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.targetDistance() reduced constraints: " 35273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root + permitted); 35373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 35473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* see if new merged constraints allow target */ 35573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!constraints.verify(target)) { 35673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new IOException("New certificate not allowed to sign " 35773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root + "certificate for target"); 35873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 35973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* find distance to target, if any, in permitted */ 36073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (permitted == null) { 36173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* certificate is unconstrained; could sign for anything */ 36273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return -1; 36373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 36473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (int i = 0, n = permitted.size(); i < n; i++) { 36573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralNameInterface perName = permitted.get(i).getName().getName(); 36673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int distance = distance(perName, target, -1); 36773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (distance >= 0) { 36873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (distance + 1); 36973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 37073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 37173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /* no matching type in permitted; cert holder could certify target */ 37273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return -1; 37373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 37473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 37573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 37673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This method can be used as an optimization to filter out 37773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * certificates that do not have policies which are valid. 37873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * It returns the set of policies (String OIDs) that should exist in 37973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * the certificate policies extension of the certificate that is 38073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * needed by the builder. The logic applied is as follows: 38173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * <p> 38273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1) If some initial policies have been set *and* policy mappings are 38373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * inhibited, then acceptable certificates are those that include 38473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * the ANY_POLICY OID or with policies that intersect with the 38573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * initial policies. 38673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2) If no initial policies have been set *or* policy mappings are 38773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * not inhibited then we don't have much to work with. All we know is 38873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * that a certificate must have *some* policy because if it didn't 38973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * have any policy then the policy tree would become null (and validation 39073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * would fail). 39173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 39273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return the Set of policies any of which must exist in a 39373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * cert's certificate policies extension in order for a cert to be selected. 39473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 39573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Set<String> getMatchingPolicies() { 39673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (matchingPolicies != null) { 39773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Set<String> initialPolicies = buildParams.initialPolicies(); 39873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if ((!initialPolicies.isEmpty()) && 39973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (!initialPolicies.contains(PolicyChecker.ANY_POLICY)) && 40073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (buildParams.policyMappingInhibited())) 40173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 40273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root matchingPolicies = new HashSet<>(initialPolicies); 40373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root matchingPolicies.add(PolicyChecker.ANY_POLICY); 40473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } else { 40573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // we just return an empty set to make sure that there is 40673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // at least a certificate policies extension in the cert 40773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root matchingPolicies = Collections.<String>emptySet(); 40873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 40973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return matchingPolicies; 41173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 41273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 41373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 41473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Search the specified CertStores and add all certificates matching 41573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * selector to resultCerts. Self-signed certs are not useful here 41673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * and therefore ignored. 41773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 41873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * If the targetCert criterion of the selector is set, only that cert 41973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * is examined and the CertStores are not searched. 42073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 42173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * If checkAll is true, all CertStores are searched for matching certs. 42273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * If false, the method returns as soon as the first CertStore returns 42373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * a matching cert(s). 42473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 42573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns true iff resultCerts changed (a cert was added to the collection) 42673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 42773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root boolean addMatchingCerts(X509CertSelector selector, 42873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Collection<CertStore> certStores, 42973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Collection<X509Certificate> resultCerts, 43073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root boolean checkAll) 43173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 43273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate targetCert = selector.getCertificate(); 43373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (targetCert != null) { 43473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // no need to search CertStores 43573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (selector.match(targetCert) && !X509CertImpl.isSelfSigned 43673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root (targetCert, buildParams.sigProvider())) { 43773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 438258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak debug.println("Builder.addMatchingCerts: " + 439258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak "adding target cert" + 440258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak "\n SN: " + Debug.toHexString( 441258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak targetCert.getSerialNumber()) + 442258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak "\n Subject: " + targetCert.getSubjectX500Principal() + 443258f65b9ea497337055478068b1c4a3503fb6768Przemyslaw Szczepaniak "\n Issuer: " + targetCert.getIssuerX500Principal()); 44473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 44573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return resultCerts.add(targetCert); 44673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 44773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return false; 44873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 44973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root boolean add = false; 45073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (CertStore store : certStores) { 45173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 45273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Collection<? extends Certificate> certs = 45373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root store.getCertificates(selector); 45473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (Certificate cert : certs) { 45573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!X509CertImpl.isSelfSigned 45673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ((X509Certificate)cert, buildParams.sigProvider())) { 45773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (resultCerts.add((X509Certificate)cert)) { 45873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root add = true; 45973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 46073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 46173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 46273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (!checkAll && add) { 46373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return true; 46473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 46573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertStoreException cse) { 46673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // if getCertificates throws a CertStoreException, we ignore 46773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // it and move on to the next CertStore 46873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 46973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Builder.addMatchingCerts, non-fatal " + 47073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root "exception retrieving certs: " + cse); 47173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root cse.printStackTrace(); 47273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return add; 47673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 47773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root} 478