4756N/A * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * This class is able to build certification paths in either the forward 0N/A * or reverse directions. 0N/A * <p> If successful, it returns a certification path which has succesfully 0N/A * satisfied all the constraints and requirements specified in the 0N/A * PKIXBuilderParameters object and has been validated according to the PKIX 0N/A * path validation algorithm defined in RFC 3280. 0N/A * <p> This implementation uses a depth-first search approach to finding 0N/A * certification paths. If it comes to a point in which it cannot find 0N/A * any more certificates leading to the target OR the path length is too long 0N/A * it backtracks to previous paths until the target has been found or 0N/A * all possible paths have been exhausted. 0N/A * <p> This implementation is not thread-safe. 0N/A * @author Sean Mullan 0N/A * @author Yassir Elley 0N/A * private objects shared by methods 0N/A * Create an instance of <code>SunCertPathBuilder</code>. 0N/A * @throws CertPathBuilderException if an error occurs 1652N/A (
"com.sun.security.onlyCheckRevocationOfEECert"));
0N/A * Attempts to build a certification path using the Sun build 0N/A * algorithm from a trusted anchor(s) to a target subject, which must both 0N/A * be specified in the input parameter set. By default, this method will 0N/A * attempt to build in the forward direction. In order to build in the 0N/A * reverse direction, the caller needs to pass in an instance of 0N/A * SunCertPathBuilderParameters with the buildForward flag set to false. 0N/A * <p>The certification path that is constructed is validated 0N/A * according to the PKIX specification. 0N/A * @param params the parameter set for building a path. Must be an instance 0N/A * of <code>PKIXBuilderParameters</code>. 0N/A * @return a certification path builder result. 0N/A * @exception CertPathBuilderException Exception thrown if builder is 0N/A * unable to build a complete certification path from the trusted anchor(s) 0N/A * to the target subject. 0N/A * @throws InvalidAlgorithmParameterException if the given parameters are 0N/A * inappropriate for this certification path builder. 0N/A "parameter type, must be an instance of PKIXBuilderParameters");
0N/A /* Check mandatory parameters */ 0N/A // Make sure that none of the trust anchors include name constraints 0N/A (
"name constraints in trust anchor not supported");
0N/A +
"targetCertConstraints parameter must be an " 0N/A +
"X509CertSelector");
0N/A // reorder CertStores so that local CertStores are tried first 0N/A (
"Could not determine unique target subject");
0N/A +
"certification path to requested target",
0N/A // Init shared variables and build certification path 0N/A +
"certification path to requested target", e,
0N/A // construct SunCertPathBuilderResult 0N/A // we must return a certpath which has the target 0N/A // as the first cert in the certpath - i.e. reverse 0N/A +
"certification path to requested target", e,
0N/A * Private build reverse method. 0N/A /* Initialize adjacency list */ 0N/A * Perform a search using each trust anchor, until a valid 0N/A /* check if anchor satisfies target constraints */ 0N/A /* Initialize current state */ 0N/A // init the crl checker 0N/A // continue on error if more anchors to try 0N/A // break out of loop if search is successful 0N/A +
"depthFirstSearchReverse()");
0N/A * Private build forward method. 0N/A /* Initialize current state */ 0N/A /* Initialize adjacency list */ 0N/A // init the crl checker 0N/A * This method performs a depth first search for a certification 0N/A * path while building forward which meets the requirements set in 0N/A * the parameters object. 0N/A * It uses an adjacency list to store all certificates which were 0N/A * tried (i.e. at one time added to the path - they may not end up in 0N/A * the final path if backtracking occurs). This information can 0N/A * be used later to debug or demo the build. 0N/A * See "Data Structure and Algorithms, by Aho, Hopcroft, and Ullman" 0N/A * for an explanation of the DFS algorithm. 0N/A * @param dN the distinguished name being currently searched for certs 0N/A * @param currentState the current PKIX validation state 0N/A //XXX This method should probably catch & handle exceptions 0N/A * Find all the certificates issued to dN which 0N/A * satisfy the PKIX certification path constraints. 0N/A * For each cert in the collection, verify anything 0N/A * that hasn't been checked yet (signature, revocation, etc) 0N/A * and check for loops. Call depthFirstSearchForward() 0N/A * recursively for each good cert. 0N/A * Restore state to currentState each time through the loop. 0N/A * This is important because some of the user-defined 0N/A * checkers modify the state, which MUST be restored if 0N/A * the cert eventually fails to lead to the target and 0N/A * the next matching cert is tried. 0N/A +
": validation failed: " +
gse);
0N/A * Certificate is good. 0N/A * If cert completes the path, 0N/A * process userCheckers that don't support forward checking 0N/A * and process policies over whole path 0N/A * and backtrack appropriately if there is a failure 0N/A * else if cert does not complete the path, 0N/A * add it to the path 0N/A +
": commencing final verification");
0N/A * if the trust anchor selected is specified as a trusted 0N/A * public key rather than a trusted cert, then verify this 0N/A * cert (which is signed by the trusted public key), but 0N/A * don't add it yet to the certPathList 2999N/A // add the algorithm checker 2999N/A "SunCertPathBuilder.depthFirstSearchForward " +
2999N/A "using buildParams public key: " +
2999N/A // add the crl revocation checker 2999N/A // Why we don't need BasicChecker and CrlRevocationChecker 2999N/A // if nextState.keyParamsNeeded() is false? 2999N/A // AlgorithmChecker may not be 2999N/A // able to set the trust anchor until now. 0N/A (
"SunCertPathBuilder.depthFirstSearchForward(): " +
0N/A "final verification failed: " +
cpve);
0N/A * Remove extensions from user checkers that support 0N/A * forward checking. After this step, we will have 0N/A * removed all extensions that all user checkers 0N/A * are capable of processing. 585N/A (
"unrecognized critical extension(s)",
null,
0N/A +
": final verification succeeded - path completed!");
0N/A * if the user specified a trusted public key rather than 0N/A * trusted certs, then add this cert (which is signed by 0N/A * the trusted public key) to the certPathList 0N/A // Save the trust anchor 0N/A * Extract and save the final target public key 0N/A /* Update the PKIX state */ 0N/A * Append an entry for cert in adjacency list and 0N/A * set index for current vertex. 0N/A /* recursively search for matching certs at next dN */ 0N/A * If path has been completed, return ASAP! 0N/A * If we get here, it means we have searched all possible 0N/A * certs issued by the dN w/o finding any matching certs. 0N/A * This means we have to backtrack to the previous cert in 0N/A * the path and try some other paths. 0N/A +
": backtracking");
0N/A * This method performs a depth first search for a certification 0N/A * path while building reverse which meets the requirements set in 0N/A * the parameters object. 0N/A * It uses an adjacency list to store all certificates which were 0N/A * tried (i.e. at one time added to the path - they may not end up in 0N/A * the final path if backtracking occurs). This information can 0N/A * be used later to debug or demo the build. 0N/A * See "Data Structure and Algorithms, by Aho, Hopcroft, and Ullman" 0N/A * for an explanation of the DFS algorithm. 0N/A * @param dN the distinguished name being currently searched for certs 0N/A * @param currentState the current PKIX validation state 0N/A * Find all the certificates issued by dN which 0N/A * satisfy the PKIX certification path constraints. 0N/A * For each cert in the collection, verify anything 0N/A * that hasn't been checked yet (signature, revocation, etc) 0N/A * and check for loops. Call depthFirstSearchReverse() 0N/A * recursively for each good cert. 0N/A * Restore state to currentState each time through the loop. 0N/A * This is important because some of the user-defined 0N/A * checkers modify the state, which MUST be restored if 0N/A * the cert eventually fails to lead to the target and 0N/A * the next matching cert is tried. 0N/A +
": validation failed: " +
gse);
0N/A * Certificate is good, add it to the path (if it isn't a 0N/A * self-signed cert) and update state 0N/A // save trust anchor 0N/A * Check if path is completed, return ASAP if so. 0N/A +
": path completed!");
0N/A * Extract and save the final target public key 0N/A /* Update the PKIX state */ 0N/A * Append an entry for cert in adjacency list and 0N/A * set index for current vertex. 0N/A /* recursively search for matching certs at next dN */ 0N/A * If path has been completed, return ASAP! 0N/A * If we get here, it means we have searched all possible 0N/A * certs issued by the dN w/o finding any matching certs. This 0N/A * means we have to backtrack to the previous cert in the path 0N/A * and try some other paths. 0N/A +
": backtracking");
0N/A +
"certs in this adjacency list checked");
0N/A * Adds a collection of matching certificates to the 0N/A * Returns true if trust anchor certificate matches specified 0N/A * certificate constraints. 0N/A * Comparator that orders CertStores so that local CertStores come before 0N/A * remote CertStores. 0N/A * Returns the target subject DN from the first X509Certificate that 0N/A * is fetched that matches the specified X509CertSelector. 0N/A // ignore but log it 0N/A "non-fatal exception retrieving certs: " + e);