com.tencent.kona.sun.security.provider.certpath.ForwardBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kona-pkix Show documentation
Show all versions of kona-pkix Show documentation
A Java security provider for supporting ShangMi algorithms in public key infrastructure
/*
* Copyright (c) 2000, 2024, 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 com.tencent.kona.sun.security.provider.certpath;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXReason;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import com.tencent.kona.sun.security.provider.certpath.PKIX.BuilderParams;
import com.tencent.kona.sun.security.util.ObjectIdentifier;
import com.tencent.kona.sun.security.util.Debug;
import com.tencent.kona.sun.security.x509.AccessDescription;
import com.tencent.kona.sun.security.x509.AuthorityInfoAccessExtension;
import com.tencent.kona.sun.security.x509.AuthorityKeyIdentifierExtension;
import com.tencent.kona.sun.security.x509.AVA;
import com.tencent.kona.sun.security.x509.PKIXExtensions;
import com.tencent.kona.sun.security.x509.RDN;
import com.tencent.kona.sun.security.x509.X500Name;
import com.tencent.kona.sun.security.x509.X509CertImpl;
/**
* This class represents a forward builder, which is able to retrieve
* matching certificates from CertStores and verify a particular certificate
* against a ForwardState.
*
* @since 1.4
* @author Yassir Elley
* @author Sean Mullan
*/
public class ForwardBuilder extends Builder {
private static final Debug debug = Debug.getInstance("certpath");
private final Set trustedCerts;
private final Set trustedSubjectDNs;
private final Set trustAnchors;
private X509CertSelector eeSelector;
private AdaptableX509CertSelector caSelector;
private X509CertSelector caTargetSelector;
TrustAnchor trustAnchor;
private final boolean searchAllCertStores;
/**
* Initialize the builder with the input parameters.
*
* @param buildParams the parameter set used to build a certification path
*/
ForwardBuilder(BuilderParams buildParams, boolean searchAllCertStores) {
super(buildParams);
// populate sets of trusted certificates and subject DNs
trustAnchors = buildParams.trustAnchors();
trustedCerts = new HashSet(trustAnchors.size());
trustedSubjectDNs = new HashSet(trustAnchors.size());
for (TrustAnchor anchor : trustAnchors) {
X509Certificate trustedCert = anchor.getTrustedCert();
if (trustedCert != null) {
trustedCerts.add(trustedCert);
trustedSubjectDNs.add(trustedCert.getSubjectX500Principal());
} else {
trustedSubjectDNs.add(anchor.getCA());
}
}
this.searchAllCertStores = searchAllCertStores;
}
/**
* 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 ForwardState
* @param certStores list of CertStores
*/
@Override
Collection getMatchingCerts(State currentState,
List certStores)
throws IOException
{
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCerts()...");
}
ForwardState currState = (ForwardState) currentState;
/*
* We store certs in a Set because we don't want duplicates.
* As each cert is added, it is sorted based on the PKIXCertComparator
* algorithm.
*/
Comparator comparator =
new PKIXCertComparator(trustedSubjectDNs, currState.cert);
Set certs = new TreeSet<>(comparator);
/*
* Only look for EE certs if search has just started.
*/
if (currState.isInitial()) {
getMatchingEECerts(currState, certStores, certs);
}
getMatchingCACerts(currState, certStores, certs);
return certs;
}
/*
* Retrieves all end-entity certificates which satisfy constraints
* and requirements specified in the parameters and PKIX state.
*/
private void getMatchingEECerts(ForwardState currentState,
List certStores,
Collection eeCerts)
throws IOException
{
if (debug != null) {
debug.println("ForwardBuilder.getMatchingEECerts()...");
}
/*
* Compose a certificate matching rule to filter out
* certs which don't satisfy constraints
*
* First, retrieve clone of current target cert constraints,
* and then add more selection criteria based on current validation
* state. Since selector never changes, cache local copy & reuse.
*/
if (eeSelector == null) {
eeSelector = (X509CertSelector) targetCertConstraints.clone();
/*
* Match on certificate validity date
*/
eeSelector.setCertificateValid(buildParams.date());
/*
* Policy processing optimizations
*/
if (buildParams.explicitPolicyRequired()) {
eeSelector.setPolicy(getMatchingPolicies());
}
/*
* Require EE certs
*/
eeSelector.setBasicConstraints(-2);
}
/* Retrieve matching EE certs from CertStores */
addMatchingCerts(eeSelector, certStores, eeCerts, searchAllCertStores);
}
/**
* Retrieves all CA certificates which satisfy constraints
* and requirements specified in the parameters and PKIX state.
*/
private void getMatchingCACerts(ForwardState currentState,
List certStores,
Collection caCerts)
throws IOException
{
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts()...");
}
int initialSize = caCerts.size();
/*
* Compose a CertSelector to filter out
* certs which do not satisfy requirements.
*/
X509CertSelector sel;
if (currentState.isInitial()) {
if (targetCertConstraints.getBasicConstraints() == -2) {
// no need to continue: this means we never can match a CA cert
return;
}
/* This means a CA is the target, so match on same stuff as
* getMatchingEECerts
*/
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts(): " +
"the target is a CA");
}
if (caTargetSelector == null) {
caTargetSelector =
(X509CertSelector) targetCertConstraints.clone();
/*
* Since we don't check the validity period of trusted
* certificates, please don't set the certificate valid
* criterion unless the trusted certificate matching is
* completed.
*/
/*
* Policy processing optimizations
*/
if (buildParams.explicitPolicyRequired())
caTargetSelector.setPolicy(getMatchingPolicies());
}
sel = caTargetSelector;
} else {
if (caSelector == null) {
caSelector = new AdaptableX509CertSelector();
/*
* Since we don't check the validity period of trusted
* certificates, please don't set the certificate valid
* criterion unless the trusted certificate matching is
* completed.
*/
/*
* Policy processing optimizations
*/
if (buildParams.explicitPolicyRequired())
caSelector.setPolicy(getMatchingPolicies());
}
/*
* Match on subject (issuer of previous cert)
*/
caSelector.setSubject(currentState.issuerDN);
/*
* check the validity period
*/
caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
currentState.cert.getNotAfter());
sel = caSelector;
}
/*
* For compatibility, conservatively, we don't check the path
* length constraint of trusted anchors. Please don't set the
* basic constraints criterion unless the trusted certificate
* matching is completed.
*/
sel.setBasicConstraints(-1);
for (X509Certificate trustedCert : trustedCerts) {
if (sel.match(trustedCert)) {
if (debug != null) {
debug.println("ForwardBuilder.getMatchingCACerts: " +
"found matching trust anchor." +
"\n SN: " +
Debug.toString(trustedCert.getSerialNumber()) +
"\n Subject: " +
trustedCert.getSubjectX500Principal() +
"\n Issuer: " +
trustedCert.getIssuerX500Principal());
}
caCerts.add(trustedCert);
}
}
/*
* The trusted certificate matching is completed. We need to match
* on certificate validity date.
*/
sel.setCertificateValid(buildParams.date());
/*
* Require CA certs with a pathLenConstraint that allows
* at least as many CA certs that have already been traversed
*/
sel.setBasicConstraints(currentState.traversedCACerts);
/*
* If we have already traversed as many CA certs as the maxPathLength
* will allow us to, then we don't bother looking through these
* certificate pairs. If maxPathLength has a value of -1, this
* means it is unconstrained, so we always look through the
* certificate pairs.
*/
if (currentState.isInitial() ||
(buildParams.maxPathLength() == -1) ||
(buildParams.maxPathLength() > currentState.traversedCACerts))
{
if (addMatchingCerts(sel, certStores,
caCerts, searchAllCertStores)
&& !searchAllCertStores) {
return;
}
}
if (!currentState.isInitial() && USE_AIA) {
// check for AuthorityInformationAccess extension
AuthorityInfoAccessExtension aiaExt =
currentState.cert.getAuthorityInfoAccessExtension();
if (aiaExt != null) {
getCerts(aiaExt, caCerts);
}
}
if (debug != null) {
int numCerts = caCerts.size() - initialSize;
debug.println("ForwardBuilder.getMatchingCACerts: found " +
numCerts + " CA certs");
}
}
// Thread-local gate to prevent recursive provider lookups
private static ThreadLocal
© 2015 - 2024 Weber Informatics LLC | Privacy Policy