7194452: Remove "Reverse" PKIX CertPathBuilder implementation
Reviewed-by: mullan
This commit is contained in:
parent
7cbdcf978d
commit
454ec2e69d
@ -102,8 +102,8 @@ public abstract class Builder {
|
||||
|
||||
/**
|
||||
* Verifies whether the input certificate completes the path.
|
||||
* When building forward, a trust anchor will complete the path.
|
||||
* When building reverse, the target certificate will complete the path.
|
||||
* When building in the forward direction, a trust anchor will
|
||||
* complete the path.
|
||||
*
|
||||
* @param cert the certificate to test
|
||||
* @return a boolean value indicating whether the cert completes the path.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, 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,7 +25,6 @@
|
||||
package sun.security.provider.certpath;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.*;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
@ -194,7 +193,6 @@ class PKIX {
|
||||
|
||||
static class BuilderParams extends ValidatorParams {
|
||||
private PKIXBuilderParameters params;
|
||||
private boolean buildForward = true;
|
||||
private List<CertStore> stores;
|
||||
private X500Principal targetSubject;
|
||||
|
||||
@ -213,10 +211,6 @@ class PKIX {
|
||||
+ "targetCertConstraints parameter must be an "
|
||||
+ "X509CertSelector");
|
||||
}
|
||||
if (params instanceof SunCertPathBuilderParameters) {
|
||||
buildForward =
|
||||
((SunCertPathBuilderParameters)params).getBuildForward();
|
||||
}
|
||||
this.params = params;
|
||||
this.targetSubject = getTargetSubject(
|
||||
certStores(), (X509CertSelector)targetCertConstraints());
|
||||
@ -230,7 +224,6 @@ class PKIX {
|
||||
return stores;
|
||||
}
|
||||
int maxPathLength() { return params.getMaxPathLength(); }
|
||||
boolean buildForward() { return buildForward; }
|
||||
PKIXBuilderParameters params() { return params; }
|
||||
X500Principal targetSubject() { return targetSubject; }
|
||||
|
||||
|
@ -1,551 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.provider.certpath;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.PKIXBuilderParameters;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.X509CertSelector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.provider.certpath.PKIX.BuilderParams;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.x509.Extension;
|
||||
import static sun.security.x509.PKIXExtensions.*;
|
||||
import sun.security.x509.X500Name;
|
||||
import sun.security.x509.X509CertImpl;
|
||||
import sun.security.x509.PolicyMappingsExtension;
|
||||
|
||||
/**
|
||||
* This class represents a reverse builder, which is able to retrieve
|
||||
* matching certificates from CertStores and verify a particular certificate
|
||||
* against a ReverseState.
|
||||
*
|
||||
* @since 1.4
|
||||
* @author Sean Mullan
|
||||
* @author Yassir Elley
|
||||
*/
|
||||
|
||||
class ReverseBuilder extends Builder {
|
||||
|
||||
private Debug debug = Debug.getInstance("certpath");
|
||||
|
||||
private final Set<String> initPolicies;
|
||||
|
||||
/**
|
||||
* Initialize the builder with the input parameters.
|
||||
*
|
||||
* @param params the parameter set used to build a certification path
|
||||
*/
|
||||
ReverseBuilder(BuilderParams buildParams) {
|
||||
super(buildParams);
|
||||
|
||||
Set<String> initialPolicies = buildParams.initialPolicies();
|
||||
initPolicies = new HashSet<String>();
|
||||
if (initialPolicies.isEmpty()) {
|
||||
// if no initialPolicies are specified by user, set
|
||||
// initPolicies to be anyPolicy by default
|
||||
initPolicies.add(PolicyChecker.ANY_POLICY);
|
||||
} else {
|
||||
initPolicies.addAll(initialPolicies);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all certs from the specified CertStores that satisfy the
|
||||
* requirements specified in the parameters and the current
|
||||
* PKIX state (name constraints, policy constraints, etc).
|
||||
*
|
||||
* @param currentState the current state.
|
||||
* Must be an instance of <code>ReverseState</code>
|
||||
* @param certStores list of CertStores
|
||||
*/
|
||||
@Override
|
||||
Collection<X509Certificate> getMatchingCerts
|
||||
(State currState, List<CertStore> certStores)
|
||||
throws CertStoreException, CertificateException, IOException
|
||||
{
|
||||
ReverseState currentState = (ReverseState) currState;
|
||||
|
||||
if (debug != null)
|
||||
debug.println("In ReverseBuilder.getMatchingCerts.");
|
||||
|
||||
/*
|
||||
* The last certificate could be an EE or a CA certificate
|
||||
* (we may be building a partial certification path or
|
||||
* establishing trust in a CA).
|
||||
*
|
||||
* Try the EE certs before the CA certs. It will be more
|
||||
* common to build a path to an end entity.
|
||||
*/
|
||||
Collection<X509Certificate> certs =
|
||||
getMatchingEECerts(currentState, certStores);
|
||||
certs.addAll(getMatchingCACerts(currentState, certStores));
|
||||
|
||||
return certs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves all end-entity certificates which satisfy constraints
|
||||
* and requirements specified in the parameters and PKIX state.
|
||||
*/
|
||||
private Collection<X509Certificate> getMatchingEECerts
|
||||
(ReverseState currentState, List<CertStore> certStores)
|
||||
throws CertStoreException, CertificateException, IOException {
|
||||
|
||||
/*
|
||||
* Compose a CertSelector to filter out
|
||||
* certs which do not satisfy requirements.
|
||||
*
|
||||
* First, retrieve clone of current target cert constraints, and
|
||||
* then add more selection criteria based on current validation state.
|
||||
*/
|
||||
X509CertSelector sel = (X509CertSelector) targetCertConstraints.clone();
|
||||
|
||||
/*
|
||||
* Match on issuer (subject of previous cert)
|
||||
*/
|
||||
sel.setIssuer(currentState.subjectDN);
|
||||
|
||||
/*
|
||||
* Match on certificate validity date.
|
||||
*/
|
||||
sel.setCertificateValid(buildParams.date());
|
||||
|
||||
/*
|
||||
* Policy processing optimizations
|
||||
*/
|
||||
if (currentState.explicitPolicy == 0)
|
||||
sel.setPolicy(getMatchingPolicies());
|
||||
|
||||
/*
|
||||
* If previous cert has a subject key identifier extension,
|
||||
* use it to match on authority key identifier extension.
|
||||
*/
|
||||
/*if (currentState.subjKeyId != null) {
|
||||
AuthorityKeyIdentifierExtension authKeyId = new AuthorityKeyIdentifierExtension(
|
||||
(KeyIdentifier) currentState.subjKeyId.get(SubjectKeyIdentifierExtension.KEY_ID),
|
||||
null, null);
|
||||
sel.setAuthorityKeyIdentifier(authKeyId.getExtensionValue());
|
||||
}*/
|
||||
|
||||
/*
|
||||
* Require EE certs
|
||||
*/
|
||||
sel.setBasicConstraints(-2);
|
||||
|
||||
/* Retrieve matching certs from CertStores */
|
||||
HashSet<X509Certificate> eeCerts = new HashSet<>();
|
||||
addMatchingCerts(sel, certStores, eeCerts, true);
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("ReverseBuilder.getMatchingEECerts got "
|
||||
+ eeCerts.size() + " certs.");
|
||||
}
|
||||
return eeCerts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves all CA certificates which satisfy constraints
|
||||
* and requirements specified in the parameters and PKIX state.
|
||||
*/
|
||||
private Collection<X509Certificate> getMatchingCACerts
|
||||
(ReverseState currentState, List<CertStore> certStores)
|
||||
throws CertificateException, CertStoreException, IOException {
|
||||
|
||||
/*
|
||||
* Compose a CertSelector to filter out
|
||||
* certs which do not satisfy requirements.
|
||||
*/
|
||||
X509CertSelector sel = new X509CertSelector();
|
||||
|
||||
/*
|
||||
* Match on issuer (subject of previous cert)
|
||||
*/
|
||||
sel.setIssuer(currentState.subjectDN);
|
||||
|
||||
/*
|
||||
* Match on certificate validity date.
|
||||
*/
|
||||
sel.setCertificateValid(buildParams.date());
|
||||
|
||||
/*
|
||||
* Match on target subject name (checks that current cert's
|
||||
* name constraints permit it to certify target).
|
||||
* (4 is the integer type for DIRECTORY name).
|
||||
*/
|
||||
byte[] subject = targetCertConstraints.getSubjectAsBytes();
|
||||
if (subject != null) {
|
||||
sel.addPathToName(4, subject);
|
||||
} else {
|
||||
X509Certificate cert = targetCertConstraints.getCertificate();
|
||||
if (cert != null) {
|
||||
sel.addPathToName(4,
|
||||
cert.getSubjectX500Principal().getEncoded());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Policy processing optimizations
|
||||
*/
|
||||
if (currentState.explicitPolicy == 0)
|
||||
sel.setPolicy(getMatchingPolicies());
|
||||
|
||||
/*
|
||||
* If previous cert has a subject key identifier extension,
|
||||
* use it to match on authority key identifier extension.
|
||||
*/
|
||||
/*if (currentState.subjKeyId != null) {
|
||||
AuthorityKeyIdentifierExtension authKeyId = new AuthorityKeyIdentifierExtension(
|
||||
(KeyIdentifier) currentState.subjKeyId.get(SubjectKeyIdentifierExtension.KEY_ID),
|
||||
null, null);
|
||||
sel.setAuthorityKeyIdentifier(authKeyId.getExtensionValue());
|
||||
}*/
|
||||
|
||||
/*
|
||||
* Require CA certs
|
||||
*/
|
||||
sel.setBasicConstraints(0);
|
||||
|
||||
/* Retrieve matching certs from CertStores */
|
||||
ArrayList<X509Certificate> reverseCerts = new ArrayList<>();
|
||||
addMatchingCerts(sel, certStores, reverseCerts, true);
|
||||
|
||||
/* Sort remaining certs using name constraints */
|
||||
Collections.sort(reverseCerts, new PKIXCertComparator());
|
||||
|
||||
if (debug != null)
|
||||
debug.println("ReverseBuilder.getMatchingCACerts got " +
|
||||
reverseCerts.size() + " certs.");
|
||||
return reverseCerts;
|
||||
}
|
||||
|
||||
/*
|
||||
* This inner class compares 2 PKIX certificates according to which
|
||||
* should be tried first when building a path to the target. For
|
||||
* now, the algorithm is to look at name constraints in each cert and those
|
||||
* which constrain the path closer to the target should be
|
||||
* ranked higher. Later, we may want to consider other components,
|
||||
* such as key identifiers.
|
||||
*/
|
||||
class PKIXCertComparator implements Comparator<X509Certificate> {
|
||||
|
||||
private Debug debug = Debug.getInstance("certpath");
|
||||
|
||||
@Override
|
||||
public int compare(X509Certificate cert1, X509Certificate cert2) {
|
||||
|
||||
/*
|
||||
* if either cert certifies the target, always
|
||||
* put at head of list.
|
||||
*/
|
||||
X500Principal targetSubject = buildParams.targetSubject();
|
||||
if (cert1.getSubjectX500Principal().equals(targetSubject)) {
|
||||
return -1;
|
||||
}
|
||||
if (cert2.getSubjectX500Principal().equals(targetSubject)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int targetDist1;
|
||||
int targetDist2;
|
||||
try {
|
||||
X500Name targetSubjectName = X500Name.asX500Name(targetSubject);
|
||||
targetDist1 = Builder.targetDistance(
|
||||
null, cert1, targetSubjectName);
|
||||
targetDist2 = Builder.targetDistance(
|
||||
null, cert2, targetSubjectName);
|
||||
} catch (IOException e) {
|
||||
if (debug != null) {
|
||||
debug.println("IOException in call to Builder.targetDistance");
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new ClassCastException
|
||||
("Invalid target subject distinguished name");
|
||||
}
|
||||
|
||||
if (targetDist1 == targetDist2)
|
||||
return 0;
|
||||
|
||||
if (targetDist1 == -1)
|
||||
return 1;
|
||||
|
||||
if (targetDist1 < targetDist2)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a matching certificate.
|
||||
*
|
||||
* This method executes any of the validation steps in the PKIX path validation
|
||||
* algorithm which were not satisfied via filtering out non-compliant
|
||||
* certificates with certificate matching rules.
|
||||
*
|
||||
* If the last certificate is being verified (the one whose subject
|
||||
* matches the target subject, then the steps in Section 6.1.4 of the
|
||||
* Certification Path Validation algorithm are NOT executed,
|
||||
* regardless of whether or not the last cert is an end-entity
|
||||
* cert or not. This allows callers to certify CA certs as
|
||||
* well as EE certs.
|
||||
*
|
||||
* @param cert the certificate to be verified
|
||||
* @param currentState the current state against which the cert is verified
|
||||
* @param certPathList the certPathList generated thus far
|
||||
*/
|
||||
@Override
|
||||
void verifyCert(X509Certificate cert, State currState,
|
||||
List<X509Certificate> certPathList)
|
||||
throws GeneralSecurityException
|
||||
{
|
||||
if (debug != null) {
|
||||
debug.println("ReverseBuilder.verifyCert(SN: "
|
||||
+ Debug.toHexString(cert.getSerialNumber())
|
||||
+ "\n Subject: " + cert.getSubjectX500Principal() + ")");
|
||||
}
|
||||
|
||||
ReverseState currentState = (ReverseState) currState;
|
||||
|
||||
/* we don't perform any validation of the trusted cert */
|
||||
if (currentState.isInitial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't bother to verify untrusted certificate more.
|
||||
currentState.untrustedChecker.check(cert,
|
||||
Collections.<String>emptySet());
|
||||
|
||||
/*
|
||||
* check for looping - abort a loop if
|
||||
* ((we encounter the same certificate twice) AND
|
||||
* ((policyMappingInhibited = true) OR (no policy mapping
|
||||
* extensions can be found between the occurrences of the same
|
||||
* certificate)))
|
||||
* in order to facilitate the check to see if there are
|
||||
* any policy mapping extensions found between the occurrences
|
||||
* of the same certificate, we reverse the certpathlist first
|
||||
*/
|
||||
if ((certPathList != null) && (!certPathList.isEmpty())) {
|
||||
List<X509Certificate> reverseCertList = new ArrayList<>();
|
||||
for (X509Certificate c : certPathList) {
|
||||
reverseCertList.add(0, c);
|
||||
}
|
||||
|
||||
boolean policyMappingFound = false;
|
||||
for (X509Certificate cpListCert : reverseCertList) {
|
||||
X509CertImpl cpListCertImpl = X509CertImpl.toImpl(cpListCert);
|
||||
PolicyMappingsExtension policyMappingsExt =
|
||||
cpListCertImpl.getPolicyMappingsExtension();
|
||||
if (policyMappingsExt != null) {
|
||||
policyMappingFound = true;
|
||||
}
|
||||
if (debug != null)
|
||||
debug.println("policyMappingFound = " + policyMappingFound);
|
||||
if (cert.equals(cpListCert)) {
|
||||
if ((buildParams.policyMappingInhibited()) ||
|
||||
(!policyMappingFound)){
|
||||
if (debug != null)
|
||||
debug.println("loop detected!!");
|
||||
throw new CertPathValidatorException("loop detected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if target cert */
|
||||
boolean finalCert = cert.getSubjectX500Principal().equals(buildParams.targetSubject());
|
||||
|
||||
/* check if CA cert */
|
||||
boolean caCert = (cert.getBasicConstraints() != -1 ? true : false);
|
||||
|
||||
/* if there are more certs to follow, verify certain constraints */
|
||||
if (!finalCert) {
|
||||
|
||||
/* check if CA cert */
|
||||
if (!caCert)
|
||||
throw new CertPathValidatorException("cert is NOT a CA cert");
|
||||
|
||||
/* If the certificate was not self-issued, verify that
|
||||
* remainingCerts is greater than zero
|
||||
*/
|
||||
if ((currentState.remainingCACerts <= 0) && !X509CertImpl.isSelfIssued(cert)) {
|
||||
throw new CertPathValidatorException
|
||||
("pathLenConstraint violated, path too long", null,
|
||||
null, -1, PKIXReason.PATH_TOO_LONG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check keyUsage extension (only if CA cert and not final cert)
|
||||
*/
|
||||
KeyChecker.verifyCAKeyUsage(cert);
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If final cert, check that it satisfies specified target
|
||||
* constraints
|
||||
*/
|
||||
if (targetCertConstraints.match(cert) == false) {
|
||||
throw new CertPathValidatorException("target certificate " +
|
||||
"constraints check failed");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check revocation.
|
||||
*/
|
||||
if (buildParams.revocationEnabled() && currentState.revChecker != null) {
|
||||
currentState.revChecker.check(cert, Collections.<String>emptySet());
|
||||
}
|
||||
|
||||
/* Check name constraints if this is not a self-issued cert */
|
||||
if (finalCert || !X509CertImpl.isSelfIssued(cert)){
|
||||
if (currentState.nc != null) {
|
||||
try {
|
||||
if (!currentState.nc.verify(cert)){
|
||||
throw new CertPathValidatorException
|
||||
("name constraints check failed", null, null, -1,
|
||||
PKIXReason.INVALID_NAME);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new CertPathValidatorException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check policy
|
||||
*/
|
||||
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
|
||||
currentState.rootNode = PolicyChecker.processPolicies
|
||||
(currentState.certIndex, initPolicies,
|
||||
currentState.explicitPolicy, currentState.policyMapping,
|
||||
currentState.inhibitAnyPolicy,
|
||||
buildParams.policyQualifiersRejected(), currentState.rootNode,
|
||||
certImpl, finalCert);
|
||||
|
||||
/*
|
||||
* Check CRITICAL private extensions
|
||||
*/
|
||||
Set<String> unresolvedCritExts = cert.getCriticalExtensionOIDs();
|
||||
if (unresolvedCritExts == null) {
|
||||
unresolvedCritExts = Collections.<String>emptySet();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the signature algorithm is not disabled.
|
||||
*/
|
||||
currentState.algorithmChecker.check(cert, unresolvedCritExts);
|
||||
|
||||
for (PKIXCertPathChecker checker : currentState.userCheckers) {
|
||||
checker.check(cert, unresolvedCritExts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look at the remaining extensions and remove any ones we have
|
||||
* already checked. If there are any left, throw an exception!
|
||||
*/
|
||||
if (!unresolvedCritExts.isEmpty()) {
|
||||
unresolvedCritExts.remove(BasicConstraints_Id.toString());
|
||||
unresolvedCritExts.remove(NameConstraints_Id.toString());
|
||||
unresolvedCritExts.remove(CertificatePolicies_Id.toString());
|
||||
unresolvedCritExts.remove(PolicyMappings_Id.toString());
|
||||
unresolvedCritExts.remove(PolicyConstraints_Id.toString());
|
||||
unresolvedCritExts.remove(InhibitAnyPolicy_Id.toString());
|
||||
unresolvedCritExts.remove(SubjectAlternativeName_Id.toString());
|
||||
unresolvedCritExts.remove(KeyUsage_Id.toString());
|
||||
unresolvedCritExts.remove(ExtendedKeyUsage_Id.toString());
|
||||
|
||||
if (!unresolvedCritExts.isEmpty())
|
||||
throw new CertPathValidatorException
|
||||
("Unrecognized critical extension(s)", null, null, -1,
|
||||
PKIXReason.UNRECOGNIZED_CRIT_EXT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check signature.
|
||||
*/
|
||||
if (buildParams.sigProvider() != null) {
|
||||
cert.verify(currentState.pubKey, buildParams.sigProvider());
|
||||
} else {
|
||||
cert.verify(currentState.pubKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the input certificate completes the path.
|
||||
* This checks whether the cert is the target certificate.
|
||||
*
|
||||
* @param cert the certificate to test
|
||||
* @return a boolean value indicating whether the cert completes the path.
|
||||
*/
|
||||
@Override
|
||||
boolean isPathCompleted(X509Certificate cert) {
|
||||
return cert.getSubjectX500Principal().equals(buildParams.targetSubject());
|
||||
}
|
||||
|
||||
/** Adds the certificate to the certPathList
|
||||
*
|
||||
* @param cert the certificate to be added
|
||||
* @param certPathList the certification path list
|
||||
*/
|
||||
@Override
|
||||
void addCertToPath(X509Certificate cert,
|
||||
LinkedList<X509Certificate> certPathList) {
|
||||
certPathList.addLast(cert);
|
||||
}
|
||||
|
||||
/** Removes final certificate from the certPathList
|
||||
*
|
||||
* @param certPathList the certification path list
|
||||
*/
|
||||
@Override
|
||||
void removeFinalCertFromPath(LinkedList<X509Certificate> certPathList) {
|
||||
certPathList.removeLast();
|
||||
}
|
||||
}
|
@ -1,406 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.provider.certpath;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXRevocationChecker;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.provider.certpath.PKIX.BuilderParams;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.x509.NameConstraintsExtension;
|
||||
import sun.security.x509.SubjectKeyIdentifierExtension;
|
||||
import sun.security.x509.X509CertImpl;
|
||||
|
||||
/**
|
||||
* A specification of a reverse 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 Sean Mullan
|
||||
* @author Yassir Elley
|
||||
*/
|
||||
|
||||
class ReverseState implements State {
|
||||
|
||||
private static final Debug debug = Debug.getInstance("certpath");
|
||||
|
||||
/* The subject DN of the last cert in the path */
|
||||
X500Principal subjectDN;
|
||||
|
||||
/* The subject public key of the last cert */
|
||||
PublicKey pubKey;
|
||||
|
||||
/* The subject key identifier extension (if any) of the last cert */
|
||||
SubjectKeyIdentifierExtension subjKeyId;
|
||||
|
||||
/* The PKIX constrained/excluded subtrees state variable */
|
||||
NameConstraintsExtension nc;
|
||||
|
||||
/* The PKIX explicit policy, policy mapping, and inhibit_any-policy
|
||||
state variables */
|
||||
int explicitPolicy;
|
||||
int policyMapping;
|
||||
int inhibitAnyPolicy;
|
||||
int certIndex;
|
||||
PolicyNodeImpl rootNode;
|
||||
|
||||
/* The number of remaining CA certs which may follow in the path.
|
||||
* -1: previous cert was an EE cert
|
||||
* 0: only EE certs may follow.
|
||||
* >0 and <Integer.MAX_VALUE:no more than this number of CA certs may follow
|
||||
* Integer.MAX_VALUE: unlimited
|
||||
*/
|
||||
int remainingCACerts;
|
||||
|
||||
/* The list of user-defined checkers retrieved from the PKIXParameters
|
||||
* instance */
|
||||
ArrayList<PKIXCertPathChecker> userCheckers;
|
||||
|
||||
/* Flag indicating if state is initial (path is just starting) */
|
||||
private boolean init = true;
|
||||
|
||||
/* the checker used for revocation status */
|
||||
RevocationChecker revChecker;
|
||||
|
||||
/* the algorithm checker */
|
||||
AlgorithmChecker algorithmChecker;
|
||||
|
||||
/* the untrusted certificates checker */
|
||||
UntrustedChecker untrustedChecker;
|
||||
|
||||
/* the trust anchor used to validate the path */
|
||||
TrustAnchor trustAnchor;
|
||||
|
||||
/* Flag indicating if current cert can vouch for the CRL for
|
||||
* the next cert
|
||||
*/
|
||||
boolean crlSign = true;
|
||||
|
||||
/**
|
||||
* Returns a boolean flag indicating if the state is initial
|
||||
* (just starting)
|
||||
*
|
||||
* @return boolean flag indicating if the state is initial (just starting)
|
||||
*/
|
||||
@Override
|
||||
public boolean isInitial() {
|
||||
return init;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display state for debugging purposes
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("State [");
|
||||
sb.append("\n subjectDN of last cert: ").append(subjectDN);
|
||||
sb.append("\n subjectKeyIdentifier: ").append
|
||||
(String.valueOf(subjKeyId));
|
||||
sb.append("\n nameConstraints: ").append(String.valueOf(nc));
|
||||
sb.append("\n certIndex: ").append(certIndex);
|
||||
sb.append("\n explicitPolicy: ").append(explicitPolicy);
|
||||
sb.append("\n policyMapping: ").append(policyMapping);
|
||||
sb.append("\n inhibitAnyPolicy: ").append(inhibitAnyPolicy);
|
||||
sb.append("\n rootNode: ").append(rootNode);
|
||||
sb.append("\n remainingCACerts: ").append(remainingCACerts);
|
||||
sb.append("\n crlSign: ").append(crlSign);
|
||||
sb.append("\n init: ").append(init);
|
||||
sb.append("\n]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the state.
|
||||
*
|
||||
* @param buildParams builder parameters
|
||||
*/
|
||||
public void initState(BuilderParams buildParams)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
/*
|
||||
* Initialize number of remainingCACerts.
|
||||
* Note that -1 maxPathLen implies unlimited.
|
||||
* 0 implies only an EE cert is acceptable.
|
||||
*/
|
||||
int maxPathLen = buildParams.maxPathLength();
|
||||
remainingCACerts = (maxPathLen == -1) ? Integer.MAX_VALUE
|
||||
: maxPathLen;
|
||||
|
||||
/* Initialize explicit policy state variable */
|
||||
if (buildParams.explicitPolicyRequired()) {
|
||||
explicitPolicy = 0;
|
||||
} else {
|
||||
// unconstrained if maxPathLen is -1,
|
||||
// otherwise, we want to initialize this to the value of the
|
||||
// longest possible path + 1 (i.e. maxpathlen + finalcert + 1)
|
||||
explicitPolicy = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2;
|
||||
}
|
||||
|
||||
/* Initialize policy mapping state variable */
|
||||
if (buildParams.policyMappingInhibited()) {
|
||||
policyMapping = 0;
|
||||
} else {
|
||||
policyMapping = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2;
|
||||
}
|
||||
|
||||
/* Initialize inhibit any policy state variable */
|
||||
if (buildParams.anyPolicyInhibited()) {
|
||||
inhibitAnyPolicy = 0;
|
||||
} else {
|
||||
inhibitAnyPolicy = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2;
|
||||
}
|
||||
|
||||
/* Initialize certIndex */
|
||||
certIndex = 1;
|
||||
|
||||
/* Initialize policy tree */
|
||||
Set<String> initExpPolSet = new HashSet<>(1);
|
||||
initExpPolSet.add(PolicyChecker.ANY_POLICY);
|
||||
|
||||
rootNode = new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null,
|
||||
false, initExpPolSet, false);
|
||||
|
||||
/*
|
||||
* Initialize each user-defined checker
|
||||
* Shallow copy the checkers
|
||||
*/
|
||||
userCheckers = new ArrayList<>(buildParams.certPathCheckers());
|
||||
/* initialize each checker (just in case) */
|
||||
for (PKIXCertPathChecker checker : userCheckers) {
|
||||
checker.init(false);
|
||||
}
|
||||
|
||||
/* Start by trusting the cert to sign CRLs */
|
||||
crlSign = true;
|
||||
|
||||
init = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state with the specified trust anchor.
|
||||
*
|
||||
* @param anchor the most-trusted CA
|
||||
* @param buildParams builder parameters
|
||||
*/
|
||||
public void updateState(TrustAnchor anchor, BuilderParams buildParams)
|
||||
throws CertificateException, IOException, CertPathValidatorException
|
||||
{
|
||||
trustAnchor = anchor;
|
||||
X509Certificate trustedCert = anchor.getTrustedCert();
|
||||
if (trustedCert != null) {
|
||||
updateState(trustedCert);
|
||||
} else {
|
||||
X500Principal caName = anchor.getCA();
|
||||
updateState(anchor.getCAPublicKey(), caName);
|
||||
}
|
||||
|
||||
// The user specified AlgorithmChecker and RevocationChecker may not be
|
||||
// able to set the trust anchor until now.
|
||||
boolean revCheckerAdded = false;
|
||||
for (PKIXCertPathChecker checker : userCheckers) {
|
||||
if (checker instanceof AlgorithmChecker) {
|
||||
((AlgorithmChecker)checker).trySetTrustAnchor(anchor);
|
||||
} else if (checker instanceof PKIXRevocationChecker) {
|
||||
if (revCheckerAdded) {
|
||||
throw new CertPathValidatorException(
|
||||
"Only one PKIXRevocationChecker can be specified");
|
||||
}
|
||||
// if it's our own, initialize it
|
||||
if (checker instanceof RevocationChecker) {
|
||||
((RevocationChecker)checker).init(anchor, buildParams);
|
||||
}
|
||||
((PKIXRevocationChecker)checker).init(false);
|
||||
revCheckerAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// only create a RevocationChecker if revocation is enabled and
|
||||
// a PKIXRevocationChecker has not already been added
|
||||
if (buildParams.revocationEnabled() && !revCheckerAdded) {
|
||||
revChecker = new RevocationChecker(anchor, buildParams);
|
||||
revChecker.init(false);
|
||||
}
|
||||
|
||||
init = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state. This method is used when the most-trusted CA is
|
||||
* a trusted public-key and caName, instead of a trusted cert.
|
||||
*
|
||||
* @param pubKey the public key of the trusted CA
|
||||
* @param subjectDN the subject distinguished name of the trusted CA
|
||||
*/
|
||||
private void updateState(PublicKey pubKey, X500Principal subjectDN) {
|
||||
|
||||
/* update subject DN */
|
||||
this.subjectDN = subjectDN;
|
||||
|
||||
/* update subject public key */
|
||||
this.pubKey = pubKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state with the next certificate added to the path.
|
||||
*
|
||||
* @param cert the certificate which is used to update the state
|
||||
*/
|
||||
public void updateState(X509Certificate cert)
|
||||
throws CertificateException, IOException, CertPathValidatorException {
|
||||
|
||||
if (cert == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* update subject DN */
|
||||
subjectDN = cert.getSubjectX500Principal();
|
||||
|
||||
/* check for key needing to inherit alg parameters */
|
||||
X509CertImpl icert = X509CertImpl.toImpl(cert);
|
||||
PublicKey newKey = cert.getPublicKey();
|
||||
if (PKIX.isDSAPublicKeyWithoutParams(newKey)) {
|
||||
newKey = BasicChecker.makeInheritedParamsKey(newKey, pubKey);
|
||||
}
|
||||
|
||||
/* update subject public key */
|
||||
pubKey = newKey;
|
||||
|
||||
/*
|
||||
* if this is a trusted cert (init == true), then we
|
||||
* don't update any of the remaining fields
|
||||
*/
|
||||
if (init) {
|
||||
init = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* update subject key identifier */
|
||||
subjKeyId = icert.getSubjectKeyIdentifierExtension();
|
||||
|
||||
/* update crlSign */
|
||||
crlSign = RevocationChecker.certCanSignCrl(cert);
|
||||
|
||||
/* update current name constraints */
|
||||
if (nc != null) {
|
||||
nc.merge(icert.getNameConstraintsExtension());
|
||||
} else {
|
||||
nc = icert.getNameConstraintsExtension();
|
||||
if (nc != null) {
|
||||
// Make sure we do a clone here, because we're probably
|
||||
// going to modify this object later and we don't want to
|
||||
// be sharing it with a Certificate object!
|
||||
nc = (NameConstraintsExtension) nc.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/* update policy state variables */
|
||||
explicitPolicy =
|
||||
PolicyChecker.mergeExplicitPolicy(explicitPolicy, icert, false);
|
||||
policyMapping =
|
||||
PolicyChecker.mergePolicyMapping(policyMapping, icert);
|
||||
inhibitAnyPolicy =
|
||||
PolicyChecker.mergeInhibitAnyPolicy(inhibitAnyPolicy, icert);
|
||||
certIndex++;
|
||||
|
||||
/*
|
||||
* Update remaining CA certs
|
||||
*/
|
||||
remainingCACerts =
|
||||
ConstraintsChecker.mergeBasicConstraints(cert, remainingCACerts);
|
||||
|
||||
init = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean flag indicating if a key lacking necessary key
|
||||
* algorithm parameters has been encountered.
|
||||
*
|
||||
* @return boolean flag indicating if key lacking parameters encountered.
|
||||
*/
|
||||
@Override
|
||||
public boolean keyParamsNeeded() {
|
||||
/* when building in reverse, we immediately get parameters needed
|
||||
* or else throw an exception
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (e.g., subjKeyId) will
|
||||
* not have their contents modified by subsequent calls to updateState.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly
|
||||
public Object clone() {
|
||||
try {
|
||||
ReverseState clonedState = (ReverseState) super.clone();
|
||||
|
||||
/* clone checkers, if cloneable */
|
||||
clonedState.userCheckers =
|
||||
(ArrayList<PKIXCertPathChecker>)userCheckers.clone();
|
||||
ListIterator<PKIXCertPathChecker> li =
|
||||
clonedState.userCheckers.listIterator();
|
||||
while (li.hasNext()) {
|
||||
PKIXCertPathChecker checker = li.next();
|
||||
if (checker instanceof Cloneable) {
|
||||
li.set((PKIXCertPathChecker)checker.clone());
|
||||
}
|
||||
}
|
||||
|
||||
/* make copy of name constraints */
|
||||
if (nc != null) {
|
||||
clonedState.nc = (NameConstraintsExtension) nc.clone();
|
||||
}
|
||||
|
||||
/* make copy of policy tree */
|
||||
if (rootNode != null) {
|
||||
clonedState.rootNode = rootNode.copyTree();
|
||||
}
|
||||
|
||||
return clonedState;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new InternalError(e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -35,8 +35,6 @@ import java.security.cert.PKIXReason;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
@ -47,8 +45,7 @@ import static sun.security.x509.PKIXExtensions.*;
|
||||
import sun.security.util.Debug;
|
||||
|
||||
/**
|
||||
* This class is able to build certification paths in either the forward
|
||||
* or reverse directions.
|
||||
* This class builds certification paths in the forward direction.
|
||||
*
|
||||
* <p> If successful, it returns a certification path which has successfully
|
||||
* satisfied all the constraints and requirements specified in the
|
||||
@ -102,10 +99,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
||||
/**
|
||||
* Attempts to build a certification path using the Sun build
|
||||
* algorithm from a trusted anchor(s) to a target subject, which must both
|
||||
* be specified in the input parameter set. By default, this method will
|
||||
* attempt to build in the forward direction. In order to build in the
|
||||
* reverse direction, the caller needs to pass in an instance of
|
||||
* SunCertPathBuilderParameters with the buildForward flag set to false.
|
||||
* be specified in the input parameter set. This method will
|
||||
* attempt to build in the forward direction: from the target to the CA.
|
||||
*
|
||||
* <p>The certification path that is constructed is validated
|
||||
* according to the PKIX specification.
|
||||
@ -162,11 +157,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
||||
policyTreeResult = null;
|
||||
LinkedList<X509Certificate> certPathList = new LinkedList<>();
|
||||
try {
|
||||
if (buildParams.buildForward()) {
|
||||
buildForward(adjList, certPathList, searchAllCertStores);
|
||||
} else {
|
||||
buildReverse(adjList, certPathList);
|
||||
}
|
||||
buildForward(adjList, certPathList, searchAllCertStores);
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
if (debug != null) {
|
||||
debug.println("SunCertPathBuilder.engineBuild() exception in "
|
||||
@ -209,81 +200,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Private build reverse method.
|
||||
*/
|
||||
private void buildReverse(List<List<Vertex>> adjacencyList,
|
||||
LinkedList<X509Certificate> certPathList)
|
||||
throws GeneralSecurityException, IOException
|
||||
{
|
||||
if (debug != null) {
|
||||
debug.println("SunCertPathBuilder.buildReverse()...");
|
||||
debug.println("SunCertPathBuilder.buildReverse() InitialPolicies: "
|
||||
+ buildParams.initialPolicies());
|
||||
}
|
||||
|
||||
ReverseState currentState = new ReverseState();
|
||||
/* Initialize adjacency list */
|
||||
adjacencyList.clear();
|
||||
adjacencyList.add(new LinkedList<Vertex>());
|
||||
|
||||
/*
|
||||
* Perform a search using each trust anchor, until a valid
|
||||
* path is found
|
||||
*/
|
||||
Iterator<TrustAnchor> iter = buildParams.trustAnchors().iterator();
|
||||
while (iter.hasNext()) {
|
||||
TrustAnchor anchor = iter.next();
|
||||
|
||||
/* check if anchor satisfies target constraints */
|
||||
if (anchorIsTarget(anchor, buildParams.targetCertConstraints())) {
|
||||
this.trustAnchor = anchor;
|
||||
this.pathCompleted = true;
|
||||
this.finalPublicKey = anchor.getTrustedCert().getPublicKey();
|
||||
break;
|
||||
}
|
||||
|
||||
// skip anchor if it contains a DSA key with no DSA params
|
||||
X509Certificate trustedCert = anchor.getTrustedCert();
|
||||
PublicKey pubKey = trustedCert != null ? trustedCert.getPublicKey()
|
||||
: anchor.getCAPublicKey();
|
||||
|
||||
if (PKIX.isDSAPublicKeyWithoutParams(pubKey)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Initialize current state */
|
||||
currentState.initState(buildParams);
|
||||
currentState.updateState(anchor, buildParams);
|
||||
|
||||
currentState.algorithmChecker = new AlgorithmChecker(anchor);
|
||||
currentState.untrustedChecker = new UntrustedChecker();
|
||||
try {
|
||||
depthFirstSearchReverse(null, currentState,
|
||||
new ReverseBuilder(buildParams),
|
||||
adjacencyList, certPathList);
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
// continue on error if more anchors to try
|
||||
if (iter.hasNext())
|
||||
continue;
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
|
||||
// break out of loop if search is successful
|
||||
if (pathCompleted) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("SunCertPathBuilder.buildReverse() returned from "
|
||||
+ "depthFirstSearchReverse()");
|
||||
debug.println("SunCertPathBuilder.buildReverse() "
|
||||
+ "certPathList.size: " + certPathList.size());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Private build forward method.
|
||||
*/
|
||||
@ -631,147 +547,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This method performs a depth first search for a certification
|
||||
* path while building reverse which meets the requirements set in
|
||||
* the parameters object.
|
||||
* It uses an adjacency list to store all certificates which were
|
||||
* tried (i.e. at one time added to the path - they may not end up in
|
||||
* the final path if backtracking occurs). This information can
|
||||
* be used later to debug or demo the build.
|
||||
*
|
||||
* See "Data Structure and Algorithms, by Aho, Hopcroft, and Ullman"
|
||||
* 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 depthFirstSearchReverse(X500Principal dN,
|
||||
ReverseState currentState,
|
||||
ReverseBuilder builder,
|
||||
List<List<Vertex>> adjList,
|
||||
LinkedList<X509Certificate> cpList)
|
||||
throws GeneralSecurityException, IOException
|
||||
{
|
||||
if (debug != null)
|
||||
debug.println("SunCertPathBuilder.depthFirstSearchReverse(" + dN
|
||||
+ ", " + currentState.toString() + ")");
|
||||
|
||||
/*
|
||||
* Find all the certificates issued by dN which
|
||||
* satisfy the PKIX certification path constraints.
|
||||
*/
|
||||
Collection<X509Certificate> certs =
|
||||
builder.getMatchingCerts(currentState, buildParams.certStores());
|
||||
List<Vertex> vertices = addVertices(certs, adjList);
|
||||
if (debug != null)
|
||||
debug.println("SunCertPathBuilder.depthFirstSearchReverse(): "
|
||||
+ "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 depthFirstSearchReverse()
|
||||
* recursively for each good cert.
|
||||
*/
|
||||
for (Vertex vertex : vertices) {
|
||||
/**
|
||||
* Restore state to currentState each time through the loop.
|
||||
* This is important because some of the user-defined
|
||||
* checkers modify the state, which MUST be restored if
|
||||
* the cert eventually fails to lead to the target and
|
||||
* the next matching cert is tried.
|
||||
*/
|
||||
ReverseState nextState = (ReverseState) currentState.clone();
|
||||
X509Certificate cert = vertex.getCertificate();
|
||||
try {
|
||||
builder.verifyCert(cert, nextState, cpList);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (debug != null)
|
||||
debug.println("SunCertPathBuilder.depthFirstSearchReverse()"
|
||||
+ ": validation failed: " + gse);
|
||||
vertex.setThrowable(gse);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Certificate is good, add it to the path (if it isn't a
|
||||
* self-signed cert) and update state
|
||||
*/
|
||||
if (!currentState.isInitial())
|
||||
builder.addCertToPath(cert, cpList);
|
||||
// save trust anchor
|
||||
this.trustAnchor = currentState.trustAnchor;
|
||||
|
||||
/*
|
||||
* Check if path is completed, return ASAP if so.
|
||||
*/
|
||||
if (builder.isPathCompleted(cert)) {
|
||||
if (debug != null)
|
||||
debug.println("SunCertPathBuilder.depthFirstSearchReverse()"
|
||||
+ ": path completed!");
|
||||
pathCompleted = true;
|
||||
|
||||
PolicyNodeImpl rootNode = nextState.rootNode;
|
||||
|
||||
if (rootNode == null)
|
||||
policyTreeResult = null;
|
||||
else {
|
||||
policyTreeResult = rootNode.copyTree();
|
||||
((PolicyNodeImpl)policyTreeResult).setImmutable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract and save the final target public key
|
||||
*/
|
||||
finalPublicKey = cert.getPublicKey();
|
||||
if (PKIX.isDSAPublicKeyWithoutParams(finalPublicKey)) {
|
||||
finalPublicKey =
|
||||
BasicChecker.makeInheritedParamsKey
|
||||
(finalPublicKey, currentState.pubKey);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the PKIX state */
|
||||
nextState.updateState(cert);
|
||||
|
||||
/*
|
||||
* Append an entry for cert in adjacency list and
|
||||
* set index for current vertex.
|
||||
*/
|
||||
adjList.add(new LinkedList<Vertex>());
|
||||
vertex.setIndex(adjList.size() - 1);
|
||||
|
||||
/* recursively search for matching certs at next dN */
|
||||
depthFirstSearchReverse(cert.getSubjectX500Principal(), nextState,
|
||||
builder, adjList, cpList);
|
||||
|
||||
/*
|
||||
* If path has been completed, return ASAP!
|
||||
*/
|
||||
if (pathCompleted) {
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* If we get here, it means we have searched all possible
|
||||
* certs issued by the dN w/o finding any matching certs. This
|
||||
* means we have to backtrack to the previous cert in the path
|
||||
* and try some other paths.
|
||||
*/
|
||||
if (debug != null)
|
||||
debug.println("SunCertPathBuilder.depthFirstSearchReverse()"
|
||||
+ ": backtracking");
|
||||
if (!currentState.isInitial())
|
||||
builder.removeFinalCertFromPath(cpList);
|
||||
}
|
||||
}
|
||||
if (debug != null)
|
||||
debug.println("SunCertPathBuilder.depthFirstSearchReverse() all "
|
||||
+ "certs in this adjacency list checked");
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a collection of matching certificates to the
|
||||
* adjacency list.
|
||||
|
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.provider.certpath;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.cert.*;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class specifies the set of parameters used as input for the Sun
|
||||
* certification path build algorithm. It is identical to PKIXBuilderParameters
|
||||
* with the addition of a <code>buildForward</code> parameter which allows
|
||||
* the caller to specify whether or not the path should be constructed in
|
||||
* the forward direction.
|
||||
*
|
||||
* The default for the <code>buildForward</code> parameter is
|
||||
* true, which means that the build algorithm should construct paths
|
||||
* from the target subject back to the trusted anchor.
|
||||
*
|
||||
* @since 1.4
|
||||
* @author Sean Mullan
|
||||
* @author Yassir Elley
|
||||
*/
|
||||
public class SunCertPathBuilderParameters extends PKIXBuilderParameters {
|
||||
|
||||
private boolean buildForward = true;
|
||||
|
||||
/**
|
||||
* Creates an instance of <code>SunCertPathBuilderParameters</code> with the
|
||||
* specified parameter values.
|
||||
*
|
||||
* @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
|
||||
* @param targetConstraints a <code>CertSelector</code> specifying the
|
||||
* constraints on the target certificate
|
||||
* @throws InvalidAlgorithmParameterException if the specified
|
||||
* <code>Set</code> is empty <code>(trustAnchors.isEmpty() == true)</code>
|
||||
* @throws NullPointerException if the specified <code>Set</code> is
|
||||
* <code>null</code>
|
||||
* @throws ClassCastException if any of the elements in the <code>Set</code>
|
||||
* are not of type <code>java.security.cert.TrustAnchor</code>
|
||||
*/
|
||||
public SunCertPathBuilderParameters(Set<TrustAnchor> trustAnchors,
|
||||
CertSelector targetConstraints) throws InvalidAlgorithmParameterException
|
||||
{
|
||||
super(trustAnchors, targetConstraints);
|
||||
setBuildForward(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of <code>SunCertPathBuilderParameters</code> that
|
||||
* uses the specified <code>KeyStore</code> to populate the set
|
||||
* of most-trusted CA certificates.
|
||||
*
|
||||
* @param keystore A keystore from which the set of most-trusted
|
||||
* CA certificates will be populated.
|
||||
* @param targetConstraints a <code>CertSelector</code> specifying the
|
||||
* constraints on the target certificate
|
||||
* @throws KeyStoreException if the keystore has not been initialized.
|
||||
* @throws InvalidAlgorithmParameterException if the keystore does
|
||||
* not contain at least one trusted certificate entry
|
||||
* @throws NullPointerException if the keystore is <code>null</code>
|
||||
*/
|
||||
public SunCertPathBuilderParameters(KeyStore keystore,
|
||||
CertSelector targetConstraints)
|
||||
throws KeyStoreException, InvalidAlgorithmParameterException
|
||||
{
|
||||
super(keystore, targetConstraints);
|
||||
setBuildForward(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the buildForward flag.
|
||||
*
|
||||
* @return the value of the buildForward flag
|
||||
*/
|
||||
public boolean getBuildForward() {
|
||||
return this.buildForward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the buildForward flag. If true, paths
|
||||
* are built from the target subject to the trusted anchor.
|
||||
* If false, paths are built from the trusted anchor to the
|
||||
* target subject. The default value if not specified is true.
|
||||
*
|
||||
* @param buildForward the value of the buildForward flag
|
||||
*/
|
||||
public void setBuildForward(boolean buildForward) {
|
||||
this.buildForward = buildForward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted string describing the parameters.
|
||||
*
|
||||
* @return a formatted string describing the parameters.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[\n");
|
||||
sb.append(super.toString());
|
||||
sb.append(" Build Forward Flag: " + String.valueOf(buildForward) + "\n");
|
||||
sb.append("]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6511784
|
||||
* @summary Make sure that building a path to a CRL issuer works in the
|
||||
* reverse direction
|
||||
* @library ../../../../../java/security/testlibrary
|
||||
* @build CertUtils
|
||||
* @run main BuildPath
|
||||
*/
|
||||
import java.security.cert.*;
|
||||
import java.util.Collections;
|
||||
import sun.security.provider.certpath.SunCertPathBuilderParameters;
|
||||
|
||||
public class BuildPath {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
TrustAnchor anchor =
|
||||
new TrustAnchor(CertUtils.getCertFromFile("mgrM2mgrM"), null);
|
||||
X509Certificate target = CertUtils.getCertFromFile("mgrM2leadMA");
|
||||
X509CertSelector xcs = new X509CertSelector();
|
||||
xcs.setSubject("CN=leadMA,CN=mgrM,OU=prjM,OU=divE,OU=Comp,O=sun,C=us");
|
||||
xcs.setCertificate(target);
|
||||
SunCertPathBuilderParameters params =
|
||||
new SunCertPathBuilderParameters(Collections.singleton(anchor),xcs);
|
||||
params.setBuildForward(false);
|
||||
CertStore cs = CertUtils.createStore(new String[]
|
||||
{"mgrM2prjM", "prjM2mgrM", "prjM2divE", "mgrM2leadMA" });
|
||||
params.addCertStore(cs);
|
||||
CertStore cs2 = CertUtils.createCRLStore
|
||||
(new String[] {"mgrMcrl", "prjMcrl"});
|
||||
params.addCertStore(cs2);
|
||||
PKIXCertPathBuilderResult res = CertUtils.build(params);
|
||||
}
|
||||
}
|
@ -1,356 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
//
|
||||
// Security properties, once set, cannot revert to unset. To avoid
|
||||
// conflicts with tests running in the same VM isolate this test by
|
||||
// running it in otherVM mode.
|
||||
//
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7167988
|
||||
* @summary PKIX CertPathBuilder in reverse mode doesn't work if more than
|
||||
* one trust anchor is specified
|
||||
* @run main/othervm ReverseBuild
|
||||
*/
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.security.cert.*;
|
||||
import java.security.Security;
|
||||
|
||||
import sun.security.provider.certpath.SunCertPathBuilderParameters;
|
||||
|
||||
public class ReverseBuild {
|
||||
// Certificate information:
|
||||
// Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
|
||||
// Validity
|
||||
// Not Before: Dec 8 02:43:36 2008 GMT
|
||||
// Not After : Aug 25 02:43:36 2028 GMT
|
||||
// Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org
|
||||
// X509v3 Subject Key Identifier:
|
||||
// FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
|
||||
// DirName:/C=US/ST=Some-State/L=Some-City/O=Some-Org
|
||||
// serial:00
|
||||
static String NoiceTrusedCertStr =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICrDCCAhWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
|
||||
"MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
|
||||
"EwhTb21lLU9yZzAeFw0wODEyMDgwMjQzMzZaFw0yODA4MjUwMjQzMzZaMEkxCzAJ\n" +
|
||||
"BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
|
||||
"dHkxETAPBgNVBAoTCFNvbWUtT3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n" +
|
||||
"gQDLxDggB76Ip5OwoUNRLdeOha9U3a2ieyNbz5kTU5lFfe5tui2/461uPZ8a+QOX\n" +
|
||||
"4BdVrhEmV94BKY4FPyH35zboLjfXSKxT1mAOx1Bt9sWF94umxZE1cjyU7vEX8HHj\n" +
|
||||
"7BvOyk5AQrBt7moO1uWtPA/JuoJPePiJl4kqlRJM2Akq6QIDAQABo4GjMIGgMB0G\n" +
|
||||
"A1UdDgQWBBT6uVG/TOfZhpgz+efLHvEzSfeoFDBxBgNVHSMEajBogBT6uVG/TOfZ\n" +
|
||||
"hpgz+efLHvEzSfeoFKFNpEswSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUt\n" +
|
||||
"U3RhdGUxEjAQBgNVBAcTCVNvbWUtQ2l0eTERMA8GA1UEChMIU29tZS1PcmeCAQAw\n" +
|
||||
"DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBcIm534U123Hz+rtyYO5uA\n" +
|
||||
"ofd81G6FnTfEAV8Kw9fGyyEbQZclBv34A9JsFKeMvU4OFIaixD7nLZ/NZ+IWbhmZ\n" +
|
||||
"LovmJXyCkOufea73pNiZ+f/4/ScZaIlM/PRycQSqbFNd4j9Wott+08qxHPLpsf3P\n" +
|
||||
"6Mvf0r1PNTY2hwTJLJmKtg==\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
|
||||
// Certificate information:
|
||||
// Issuer: C=US, O=Java, OU=SunJSSE Test Serivce
|
||||
// Validity
|
||||
// Not Before: Aug 19 01:52:19 2011 GMT
|
||||
// Not After : Jul 29 01:52:19 2032 GMT
|
||||
// Subject: C=US, O=Java, OU=SunJSSE Test Serivce
|
||||
|
||||
// X509v3 Subject Key Identifier:
|
||||
// B9:7C:D5:D9:DF:A7:4C:03:AE:FD:0E:27:5B:31:95:6C:C7:F3:75:E1
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:B9:7C:D5:D9:DF:A7:4C:03:AE:FD:0E:27:5B:31:95:6C:C7:F3:75:E1
|
||||
// DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
|
||||
// serial:00
|
||||
static String NoiceTrusedCertStr_2nd =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
|
||||
"MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
|
||||
"MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
|
||||
"A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
|
||||
"KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
|
||||
"ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
|
||||
"iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
|
||||
"vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
|
||||
"MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
|
||||
"EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
|
||||
"Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
|
||||
"BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
|
||||
"pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
|
||||
"XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
|
||||
|
||||
// Certificate information:
|
||||
// Issuer: C=US, O=Java, OU=SunJSSE Test Serivce
|
||||
// Validity
|
||||
// Not Before: May 5 02:40:50 2012 GMT
|
||||
// Not After : Apr 15 02:40:50 2033 GMT
|
||||
// Subject: C=US, O=Java, OU=SunJSSE Test Serivce
|
||||
// X509v3 Subject Key Identifier:
|
||||
// DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B
|
||||
// DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
|
||||
// serial:00
|
||||
static String trustedCertStr =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" +
|
||||
"MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
|
||||
"MTIwNTA1MDI0MDUwWhcNMzMwNDE1MDI0MDUwWjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
|
||||
"A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
|
||||
"KoZIhvcNAQEBBQADgY0AMIGJAoGBANtiq0AIJK+iVRwFrqcD7fYXTCbMYC5Qz/k6\n" +
|
||||
"AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwvzuURbc9+paOBWeHbN+Sc\n" +
|
||||
"x3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStFhSHXATjtdbskNOAYGLTV\n" +
|
||||
"x8uEy9GbAgMBAAGjgaUwgaIwHQYDVR0OBBYEFN1OjSoRwIMD8Kzror/58n3IaR+b\n" +
|
||||
"MGMGA1UdIwRcMFqAFN1OjSoRwIMD8Kzror/58n3IaR+boT+kPTA7MQswCQYDVQQG\n" +
|
||||
"EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
|
||||
"Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" +
|
||||
"BQADgYEAjjkJesQrkbr36N40egybaIxw7RcqT6iy5fkAGS1JYlBDk8uSCK1o6bCH\n" +
|
||||
"ls5EpYcGeEoabSS73WRdkO1lgeyWDduO4ef8cCCSpmpT6/YdZG0QS1PtcREeVig+\n" +
|
||||
"Zr25jNemS4ADHX0aaXP4kiV/G80cR7nX5t5XCUm4bYdbwM07NgI=\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
static String trustedPrivateKey = // Private key in the format of PKCS#8
|
||||
"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANtiq0AIJK+iVRwF\n" +
|
||||
"rqcD7fYXTCbMYC5Qz/k6AXBy7/1rI8wDhEJLE3m/+NSqiJwZcmdq2dNh/1fJFrwv\n" +
|
||||
"zuURbc9+paOBWeHbN+Scx3huw91oPZme385VpoK3G13rSE114S/rF4DM9mz4EStF\n" +
|
||||
"hSHXATjtdbskNOAYGLTVx8uEy9GbAgMBAAECgYEA2VjHkIiA0ABjkX+PqKeb+VLb\n" +
|
||||
"fxS7tSca5C8zfdRhLxAWRui0/3ihst0eCJNrBDuxvAOACovsDWyLuaUjtI2v2ysz\n" +
|
||||
"vz6SPyGy82PhQOFzyKQuQ814N6EpothpiZzF0yFchfKIGhUsdY89UrGs9nM7m6NT\n" +
|
||||
"rztYvgIu4avg2VPR2AECQQD+pFAqipR2BplQRIuuRSZfHRxvoEyDjT1xnHJsC6WP\n" +
|
||||
"I5hCLghL91MhQGWbP4EJMKYQOTRVukWlcp2Kycpf+P5hAkEA3I43gmVUAPEdyZdY\n" +
|
||||
"fatW7OaLlbbYJb6qEtpCZ1Rwe/BIvm6H6E3qSi/lpz7Ia7WDulpbF6BawHH3pRFq\n" +
|
||||
"CUY5ewJBAP3pUDqrRpBN0jB0uSeDslhjSciQ+dqvSpZv3rSYBHUvlBJhnkpJiy37\n" +
|
||||
"7ZUZhIxqYxyIPgRBolLwb+FFh7OdL+ECQCtldDic9WVmC+VheRDpCKZ+SlK/8lGi\n" +
|
||||
"7VXeShiIvcU1JysJFoa35fSI7hf1O3wt7+hX5PqGG7Un94EsJwACKEcCQQC1TWt6\n" +
|
||||
"ArKH6tRxKjOxFtqfs8fgEVYUaOr3j1jF4KBUuX2mtQtddZe3VfJ2wPsuKMMxmhkB\n" +
|
||||
"e7xWWZnJsErt2e+E";
|
||||
|
||||
// Certificate information:
|
||||
// Issuer: C=US, O=Java, OU=SunJSSE Test Serivce
|
||||
// Validity
|
||||
// Not Before: May 5 02:40:53 2012 GMT
|
||||
// Not After : Jan 21 02:40:53 2032 GMT
|
||||
// Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:DD:4E:8D:2A:11:C0:83:03:F0:AC:EB:A2:BF:F9:F2:7D:C8:69:1F:9B
|
||||
// DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
|
||||
// serial:00
|
||||
static String caSignerStr =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICqDCCAhGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
|
||||
"MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
|
||||
"MTIwNTA1MDI0MDUzWhcNMzIwMTIxMDI0MDUzWjBOMQswCQYDVQQGEwJVUzENMAsG\n" +
|
||||
"A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAPBgNV\n" +
|
||||
"BAMTCGNhc2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+x8+o7oM0\n" +
|
||||
"ct/LZmZLXBL4CQ8jrULD5P7NtEW0hg/zxBFZfBHf+44Oo2eMPYZj+7xaREOH5BmV\n" +
|
||||
"KRYlzRtONAaC5Ng4Mrm5UKNPcMIIUjUOvm7vWM4oSTMSfoEcSX+vp99uUAkw3w7Z\n" +
|
||||
"+frYDm1M4At/j0b+lLij71GFN2L8drpgPQIDAQABo4GoMIGlMB0GA1UdDgQWBBQT\n" +
|
||||
"B+ARB9vrMyOHMdDbfhZWvhGQCjBjBgNVHSMEXDBagBTdTo0qEcCDA/Cs66K/+fJ9\n" +
|
||||
"yGkfm6E/pD0wOzELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsT\n" +
|
||||
"FFN1bkpTU0UgVGVzdCBTZXJpdmNlggEAMBIGA1UdEwEB/wQIMAYBAf8CAQEwCwYD\n" +
|
||||
"VR0PBAQDAgEGMA0GCSqGSIb3DQEBBAUAA4GBAI+LXA/UCPkTANablUkt80JNPWsl\n" +
|
||||
"pS4XLNgPxWaN0bkRDs5oI4ooWAz1rwpeJ/nfetOvWlpmrVjSeovBFja5Hl+dUHTf\n" +
|
||||
"VfuyzkxXbhuNiJIpo1mVBpNsjwu9YRxuwX6UA2LTUQpgvtVJEE012x3zRvxBCbu2\n" +
|
||||
"Y/v1R5fZ4c+hXDfC\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
static String caSignerPrivateKey = // Private key in the format of PKCS#8
|
||||
"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL7Hz6jugzRy38tm\n" +
|
||||
"ZktcEvgJDyOtQsPk/s20RbSGD/PEEVl8Ed/7jg6jZ4w9hmP7vFpEQ4fkGZUpFiXN\n" +
|
||||
"G040BoLk2DgyublQo09wwghSNQ6+bu9YzihJMxJ+gRxJf6+n325QCTDfDtn5+tgO\n" +
|
||||
"bUzgC3+PRv6UuKPvUYU3Yvx2umA9AgMBAAECgYBYvu30cW8LONyt62Zua9hPFTe7\n" +
|
||||
"qt9B7QYyfkdmoG5PQMepTrOp84SzfoOukvgvDm0huFuJnSvhXQl2cCDhkgXskvFj\n" +
|
||||
"Hh7KBCFViVXokGdq5YoS0/KYMyQV0TZfJUvILBl51uc4/siQ2tClC/N4sa+1JhgW\n" +
|
||||
"a6dFGfRjiUKSSlmMwQJBAPWpIz3Q/c+DYMvoQr5OD8EaYwYIevlTdXb97RnJJh2b\n" +
|
||||
"UnhB9jrqesJiHYVzPmP0ukyPOXOwlp2T5Am4Kw0LFOkCQQDGz150NoHOp28Mvyc4\n" +
|
||||
"CTqz/zYzUhy2eCJESl196uyP4N65Y01VYQ3JDww4DlsXiU17tVSbgA9TCcfTYOzy\n" +
|
||||
"vyw1AkARUky+1hafZCcWGZljK8PmnMKwsTZikCTvL/Zg5BMA8Wu+OQBwpQnk3OAy\n" +
|
||||
"Aa87gw0DyvGFG8Vy9POWT9sRP1/JAkBqP0hrMvYMSs6+MSn0eHo2151PsAJIQcuO\n" +
|
||||
"U2/Da1khSzu8N6WMi2GiobgV/RYRbf9KrY2ZzMZjykZQYOxAjopBAkEAghCu38cN\n" +
|
||||
"aOsW6ueo24uzsWI1FTdE+qWNVEi3RSP120xXBCyhaBjIq4WVSlJK9K2aBaJpit3j\n" +
|
||||
"iQ5tl6zrLlxQhg==";
|
||||
|
||||
// Certificate information:
|
||||
// Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=casigner
|
||||
// Validity
|
||||
// Not Before: May 5 02:40:57 2012 GMT
|
||||
// Not After : Jan 21 02:40:57 2032 GMT
|
||||
// Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:13:07:E0:11:07:DB:EB:33:23:87:31:D0:DB:7E:16:56:BE:11:90:0A
|
||||
// DirName:/C=US/O=Java/OU=SunJSSE Test Serivce
|
||||
// serial:02
|
||||
static String certIssuerStr =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICvjCCAiegAwIBAgIBAzANBgkqhkiG9w0BAQQFADBOMQswCQYDVQQGEwJVUzEN\n" +
|
||||
"MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxETAP\n" +
|
||||
"BgNVBAMTCGNhc2lnbmVyMB4XDTEyMDUwNTAyNDA1N1oXDTMyMDEyMTAyNDA1N1ow\n" +
|
||||
"UDELMAkGA1UEBhMCVVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0Ug\n" +
|
||||
"VGVzdCBTZXJpdmNlMRMwEQYDVQQDEwpjZXJ0aXNzdWVyMIGfMA0GCSqGSIb3DQEB\n" +
|
||||
"AQUAA4GNADCBiQKBgQCyz55zinU6kNL/LeiTNiBI0QWYmDG0YTotuC4D75liBNqs\n" +
|
||||
"7Mmladsh2mTtQUAwmuGaGzaZV25a+cUax0DXZoyBwdbTI09u1bUYsZcaUUKbPoCC\n" +
|
||||
"HH26e4jLFL4olW13Sv4ZAd57tIYevMw+Fp5f4fLPFGegCJTFlv2Qjpmic/cuvQID\n" +
|
||||
"AQABo4GpMIGmMB0GA1UdDgQWBBQ5DsYzsVC8cwcx5dgE97uXVc+byDBjBgNVHSME\n" +
|
||||
"XDBagBQTB+ARB9vrMyOHMdDbfhZWvhGQCqE/pD0wOzELMAkGA1UEBhMCVVMxDTAL\n" +
|
||||
"BgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlggECMBMG\n" +
|
||||
"A1UdEwEB/wQJMAcBAf8CAgQAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQQFAAOB\n" +
|
||||
"gQCQTagenCdClT98C+oTJGJrw/dUBD9K3tE6ZJKPMc/2bUia8G5ei1C0eXj4mWG2\n" +
|
||||
"lu9umR6C90/A6qB050QB2h50qtqxSrkpu+ym1yypauZpg7U3nUY9wZWJNI1vqrQZ\n" +
|
||||
"pqUMRcXY3iQIVKx+Qj+4/Za1wwFQzpEoGmqRW31V1SdMEw==\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
static String certIssuerPrivateKey = // Private key in the format of PKCS#8
|
||||
"MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBALLPnnOKdTqQ0v8t\n" +
|
||||
"6JM2IEjRBZiYMbRhOi24LgPvmWIE2qzsyaVp2yHaZO1BQDCa4ZobNplXblr5xRrH\n" +
|
||||
"QNdmjIHB1tMjT27VtRixlxpRQps+gIIcfbp7iMsUviiVbXdK/hkB3nu0hh68zD4W\n" +
|
||||
"nl/h8s8UZ6AIlMWW/ZCOmaJz9y69AgMBAAECgYEAjtew2tgm4gxDojqIauF4VPM1\n" +
|
||||
"pzsdqd1p3pAdomNLgrQiBLZ8N7oiph6TNb1EjA+OXc+ThFgF/oM9ZDD8qZZwcvjN\n" +
|
||||
"qDZlpTkFs2TaGcyEZfUaMB45NHVs6Nn+pSkagSNwwy3xeyAct7sQEzGNTDlEwVv5\n" +
|
||||
"7V9LQutQtBd6xT48KzkCQQDpNRfv2OFNG/6GtzJoO68oJhpnpl2MsYNi4ntRkre/\n" +
|
||||
"6uXpiCYaDskcrPMRwOOs0m7mxG+Ev+uKnLnSoEMm1GCbAkEAxEmDtiD0Psb8Z9BL\n" +
|
||||
"ZRb83Jqho3xe2MCAh3xUfz9b/Mhae9dZ44o4OCgQZuwvW1mczF0NtpgZl93BmYa2\n" +
|
||||
"hTwHhwJBAKHrEj6ep/fA6x0gD2idoATRR94VfbiU+7NpqtO9ecVP0+gsdr/66hn1\n" +
|
||||
"3yLBeZLh3MxvMTrLgkAQh1i9m0JXjOcCQQClLXAHHegrw+u3uNMZeKTFR+Lp3sk6\n" +
|
||||
"AZSnbvr0Me9I45kxSeG81x3ENALJecvIRbrrRws5MvmmkNhQR8rkh8WVAkEAk6b+\n" +
|
||||
"aVtmBgUaTS5+FFlHGHJY9HFrfT1a1C/dwyMuqlmbC3YsBmZaMOlKli5TXNybLff8\n" +
|
||||
"5KMeGEpXMzgC7AscGA==";
|
||||
|
||||
// Certificate information:
|
||||
// Issuer: C=US, O=Java, OU=SunJSSE Test Serivce, CN=certissuer
|
||||
// Validity
|
||||
// Not Before: May 5 02:41:01 2012 GMT
|
||||
// Not After : Jan 21 02:41:01 2032 GMT
|
||||
// Subject: C=US, O=Java, OU=SunJSSE Test Serivce, CN=localhost
|
||||
// X509v3 Subject Key Identifier:
|
||||
// AD:C0:2C:4C:E4:C2:2E:A1:BB:5D:92:BE:66:E0:4E:E0:0D:2F:11:EF
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:39:0E:C6:33:B1:50:BC:73:07:31:E5:D8:04:F7:BB:97:55:CF:9B:C8
|
||||
static String targetCertStr =
|
||||
"-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICjTCCAfagAwIBAgIBBDANBgkqhkiG9w0BAQQFADBQMQswCQYDVQQGEwJVUzEN\n" +
|
||||
"MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEzAR\n" +
|
||||
"BgNVBAMTCmNlcnRpc3N1ZXIwHhcNMTIwNTA1MDI0MTAxWhcNMzIwMTIxMDI0MTAx\n" +
|
||||
"WjBPMQswCQYDVQQGEwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNT\n" +
|
||||
"RSBUZXN0IFNlcml2Y2UxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0B\n" +
|
||||
"AQEFAAOBjQAwgYkCgYEAvwaUd7wmBSKqycEstYLWD26vkU08DM39EtaT8wL9HnQ0\n" +
|
||||
"fgPblwBFI4zdLa2cuYXRZcFUb04N8nrkcpR0D6kkE+AlFAoRWrrZF80B7JTbtEK4\n" +
|
||||
"1PIeurihXvUT+4MpzGLOojIihMfvM4ufelblD56SInso4WFHm7t4qCln88J1gjkC\n" +
|
||||
"AwEAAaN4MHYwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBStwCxM5MIuobtdkr5m4E7g\n" +
|
||||
"DS8R7zAfBgNVHSMEGDAWgBQ5DsYzsVC8cwcx5dgE97uXVc+byDAnBgNVHSUEIDAe\n" +
|
||||
"BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GB\n" +
|
||||
"AGfwcfdvEG/nSCiAn2MGbYHp34mgF3OA1SJLWUW0LvWJhwm2cn4AXlSoyvbwrkaB\n" +
|
||||
"IDDCwhJvvc0vUyL2kTx7sqVaFTq3mDs+ktlB/FfH0Pb+i8FE+g+7T42Iw/j0qxHL\n" +
|
||||
"YmgbrjBQf5WYN1AvBE/rrPt9aOtS3UsqtVGW574b0shW\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
static String targetPrivateKey = // Private key in the format of PKCS#8
|
||||
"MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAL8GlHe8JgUiqsnB\n" +
|
||||
"LLWC1g9ur5FNPAzN/RLWk/MC/R50NH4D25cARSOM3S2tnLmF0WXBVG9ODfJ65HKU\n" +
|
||||
"dA+pJBPgJRQKEVq62RfNAeyU27RCuNTyHrq4oV71E/uDKcxizqIyIoTH7zOLn3pW\n" +
|
||||
"5Q+ekiJ7KOFhR5u7eKgpZ/PCdYI5AgMBAAECf3CscOYvFD3zNMnMJ5LomVqA7w3F\n" +
|
||||
"gKYM2jlCWAH+wU41PMEXhW6Lujw92jgXL1o+lERwxFzirVdZJWZwKgUSvzP1G0h3\n" +
|
||||
"fkucq1/UWnToK+8NSXNM/yS8hXbBgSEoJo5f7LKcIi1Ev6doBVofMxs+njzyWKbM\n" +
|
||||
"Nb7rOLHadghoon0CQQDgQzbzzSN8Dc1YmmylhI5v+0sQRHH0DL7D24k4Weh4vInG\n" +
|
||||
"EAbt4x8M7ZKEo8/dv0s4hbmNmAnJl93/RRxIyEqLAkEA2g87DiswSQam2pZ8GlrO\n" +
|
||||
"+w4Qg9mH8uxx8ou2rl0XlHzH1XiTNbkjfY0EZoL7L31BHFk9n11Fb2P85g6ws+Hy\n" +
|
||||
"ywJAM/xgyLNM/nzUlS128geAXUULaYH0SHaL4isJ7B4rXZGW/mrIsGxtzjlkNYsj\n" +
|
||||
"rGujrD6TfNc5rZmexIXowJZtcQJBAIww+pCzZ4mrgx5JXWQ8OZHiiu+ZrPOa2+9J\n" +
|
||||
"r5sOMpi+WGN/73S8oHqZbNjTINZ5OqEVJq8MchWZPQBTNXuQql0CQHEjUzzkCQa3\n" +
|
||||
"j6JTa2KAdqyvLOx0XF9zcc1gA069uNQI2gPUHS8V215z57f/gMGnDNhVfLs/vMKz\n" +
|
||||
"sFkVZ3zg7As=";
|
||||
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
// MD5 is used in this test case, don't disable MD5 algorithm.
|
||||
Security.setProperty(
|
||||
"jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
|
||||
|
||||
// generate certificate from cert string
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
// create a set of trust anchors
|
||||
LinkedHashSet<TrustAnchor> trustAnchors = new LinkedHashSet<>();
|
||||
|
||||
ByteArrayInputStream is =
|
||||
new ByteArrayInputStream(NoiceTrusedCertStr.getBytes());
|
||||
Certificate trustedCert = cf.generateCertificate(is);
|
||||
is.close();
|
||||
TrustAnchor anchor =
|
||||
new TrustAnchor((X509Certificate)trustedCert, null);
|
||||
trustAnchors.add(anchor);
|
||||
|
||||
is = new ByteArrayInputStream(trustedCertStr.getBytes());
|
||||
trustedCert = cf.generateCertificate(is);
|
||||
is.close();
|
||||
anchor = new TrustAnchor((X509Certificate)trustedCert, null);
|
||||
trustAnchors.add(anchor);
|
||||
|
||||
is = new ByteArrayInputStream(NoiceTrusedCertStr_2nd.getBytes());
|
||||
trustedCert = cf.generateCertificate(is);
|
||||
is.close();
|
||||
anchor = new TrustAnchor((X509Certificate)trustedCert, null);
|
||||
trustAnchors.add(anchor);
|
||||
|
||||
// create a list of certificates
|
||||
List<Certificate> chainList = new ArrayList<>();
|
||||
|
||||
is = new ByteArrayInputStream(targetCertStr.getBytes());
|
||||
Certificate cert = cf.generateCertificate(is);
|
||||
is.close();
|
||||
chainList.add(cert);
|
||||
|
||||
is = new ByteArrayInputStream(certIssuerStr.getBytes());
|
||||
cert = cf.generateCertificate(is);
|
||||
is.close();
|
||||
chainList.add(cert);
|
||||
|
||||
is = new ByteArrayInputStream(caSignerStr.getBytes());
|
||||
cert = cf.generateCertificate(is);
|
||||
is.close();
|
||||
chainList.add(cert);
|
||||
|
||||
// create a certificate selector
|
||||
X509CertSelector xcs = new X509CertSelector();
|
||||
X509Certificate eeCert = (X509Certificate)chainList.get(0);
|
||||
xcs.setSubject(eeCert.getSubjectX500Principal());
|
||||
|
||||
// reverse build
|
||||
SunCertPathBuilderParameters params =
|
||||
new SunCertPathBuilderParameters(trustAnchors, xcs);
|
||||
params.setBuildForward(false);
|
||||
params.setRevocationEnabled(false);
|
||||
|
||||
CollectionCertStoreParameters ccsp =
|
||||
new CollectionCertStoreParameters(chainList);
|
||||
params.addCertStore(CertStore.getInstance("Collection", ccsp));
|
||||
|
||||
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
|
||||
CertPathBuilderResult res = cpb.build(params);
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user