/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* CrlRevocationChecker is a <code>PKIXCertPathChecker</code> that checks
* revocation status information on a PKIX certificate using CRLs obtained
* from one or more <code>CertStores</code>. This is based on section 6.3
* of RFC 3280 (http://www.ietf.org/rfc/rfc3280.txt).
*
* @since 1.4
* @author Seth Proctor
* @author Steve Hanna
*/
private boolean mCRLSignFlag;
private static final boolean [] mCrlSignUsage =
{ false, false, false, false, false, false, true };
private static final boolean[] ALL_REASONS =
{true, true, true, true, true, true, true, true, true};
private boolean mOnlyEECert = false;
// Maximum clock skew in milliseconds (15 minutes) allowed when checking
// validity of CRLs
/**
* Creates a <code>CrlRevocationChecker</code>.
*
* @param anchor anchor selected to validate the target certificate
* @param params <code>PKIXParameters</code> to be used for
* finding certificates and CRLs, etc.
*/
throws CertPathValidatorException
{
}
/**
* Creates a <code>CrlRevocationChecker</code>, allowing
* extra certificates to be supplied beyond those contained
* in the <code>PKIXParameters</code>.
*
* @param anchor anchor selected to validate the target certificate
* @param params <code>PKIXParameters</code> to be used for
* finding certificates and CRLs, etc.
* @param certs a <code>Collection</code> of certificates
* that may be useful, beyond those available
* through <code>params</code> (<code>null</code>
* if none)
*/
{
}
throws CertPathValidatorException {
try {
new CollectionCertStoreParameters(certs)));
} catch (Exception e) {
// should never occur but not necessarily fatal, so log it,
// ignore and continue
"error creating Collection CertStore: " + e);
}
}
}
init(false);
}
/**
* Initializes the internal state of the checker from parameters
* specified in the constructor
*/
{
if (!forward) {
} else {
}
} else {
mPrevPubKey = null;
}
mCRLSignFlag = true;
} else {
throw new CertPathValidatorException("forward checking "
+ "not supported");
}
}
public boolean isForwardCheckingSupported() {
return false;
}
return null;
}
/**
* Performs the revocation status check on the certificate using
* its internal state.
*
* @param cert the Certificate
* @param unresolvedCritExts a Collection of the unresolved critical
* extensions
* @exception CertPathValidatorException Exception thrown if
* certificate does not verify
*/
throws CertPathValidatorException
{
// Make new public key if parameters are missing
if (cKey instanceof DSAPublicKey &&
// cKey needs to inherit DSA parameters from prev key
}
mPrevPubKey = cKey;
}
/**
* Performs the revocation status check on the certificate using
* the provided state variables, as well as the constant internal
* data.
*
* @param currCert the Certificate
* @param prevKey the previous PublicKey in the chain
* @param signFlag a boolean as returned from the last call, or true
* if this is the first cert in the chain
* @return a boolean specifying if the cert is allowed to vouch for the
* validity of a CRL for the next iteration
* @exception CertPathValidatorException Exception thrown if
* certificate does not verify.
*/
boolean signFlag) throws CertPathValidatorException
{
return certCanSignCrl(currCert);
}
/**
* Checks that a cert can be used to verify a CRL.
*
* @param currCert an X509Certificate to check
* @return a boolean specifying if the cert is allowed to vouch for the
* validity of a CRL
*/
// if the cert doesn't include the key usage ext, or
// the key usage ext asserts cRLSigning, return true,
// otherwise return false.
return kbools[6];
}
return false;
}
/**
* Internal method to start the verification of a cert
*/
throws CertPathValidatorException
{
}
/**
* Internal method to start the verification of a cert
* @param stackedCerts a <code>Set</code> of <code>X509Certificate</code>s>
* whose revocation status depends on the
* non-revoked status of this cert. To avoid
* circular dependencies, we assume they're
* revoked while checking the revocation
* status of this cert.
* @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
*/
}
}
return;
}
// reject circular dependencies - RFC 3280 is not explicit on how
// to handle this, so we feel it is safest to reject them until
// the issue is resolved in the PKIX WG.
" circular dependency");
}
throw new CertPathValidatorException
}
// init the state for this run
boolean[] reasonsMask = new boolean[9];
try {
}
}
// all CRLs returned by the DP Fetcher have also been verified
} catch (Exception e) {
+ "unexpected exception: " + e.getMessage());
}
throw new CertPathValidatorException(e);
}
}
if (!mPossibleCRLs.isEmpty()) {
// Now that we have a list of possible CRLs, see which ones can
// be approved
}
}
// make sure that we have at least one CRL that _could_ cover
// the certificate in question and all reasons are covered
if (mApprovedCRLs.isEmpty() ||
if (allowSeparateKey) {
return;
} else {
throw new CertPathValidatorException
}
}
// See if the cert is in the set of approved crls.
"starting the final sweep...");
}
if (e != null) {
try {
} catch (CRLException ce) {
throw new CertPathValidatorException(ce);
}
}
/*
* Abort CRL validation and throw exception if there are any
* unrecognized critical CRL entry extensions (see section
* 5.3 of RFC 3280).
*/
/* remove any that we will process */
if (!unresCritExts.isEmpty()) {
+ "critical extension(s) in revoked CRL entry: "
+ unresCritExts);
}
throw new CertPathValidatorException
}
}
if (reasonCode == null) {
}
Throwable t = new CertificateRevokedException
throw new CertPathValidatorException(t.getMessage(), t,
}
}
}
/**
* We have a cert whose revocation status couldn't be verified by
* a CRL issued by the cert that issued the CRL. See if we can
* find a valid CRL issued by a separate key that can verify the
* revocation status of this certificate.
* <p>
* Note that this does not provide support for indirect CRLs,
* only CRLs signed with a different key (but the same issuer
* name) as the certificate being checked.
*
* @param currCert the <code>X509Certificate</code> to be checked
* @param prevKey the <code>PublicKey</code> that failed
* @param signFlag <code>true</code> if that key was trusted to sign CRLs
* @param stackedCerts a <code>Set</code> of <code>X509Certificate</code>s>
* whose revocation status depends on the
* non-revoked status of this cert. To avoid
* circular dependencies, we assume they're
* revoked while checking the revocation
* status of this cert.
* @throws CertPathValidatorException if the cert's revocation status
* cannot be verified successfully with another key
*/
throws CertPathValidatorException {
"CrlRevocationChecker.verifyWithSeparateSigningKey()" +
}
// reject circular dependencies - RFC 3280 is not explicit on how
// to handle this, so we feel it is safest to reject them until
// the issue is resolved in the PKIX WG.
"CrlRevocationChecker.verifyWithSeparateSigningKey()" +
" circular dependency");
}
throw new CertPathValidatorException
}
// If prevKey wasn't trusted, maybe we just didn't have the right
// path to it. Don't rule that key out.
if (!signFlag) {
}
// Try to find another key that might be able to sign
// CRLs vouching for this cert.
}
/**
* Tries to find a CertPath that establishes a key that can be
* used to verify the revocation status of a given certificate.
* Ignores keys that have previously been tried. Throws a
* CertPathValidatorException if no such key could be found.
*
* @param currCert the <code>X509Certificate</code> to be checked
* @param prevKey the <code>PublicKey</code> of the certificate whose key
* cannot be used to vouch for the CRL and should be ignored
* @param stackedCerts a <code>Set</code> of <code>X509Certificate</code>s>
* whose revocation status depends on the
* establishment of this path.
* @throws CertPathValidatorException on failure
*/
throws CertPathValidatorException {
" starting work");
}
}
if (mParams instanceof PKIXBuilderParameters) {
// Policy qualifiers must be rejected, since we don't have
// any way to convey them back to the application.
try {
} catch (InvalidAlgorithmParameterException iape) {
}
} else {
// It's unfortunate that there's no easy way to make a
// PKIXBuilderParameters object from a PKIXParameters
// object. This might miss some things if parameters
// are added in the future or the validatorParams object
// is a custom class derived from PKIXValidatorParameters.
try {
} catch (InvalidAlgorithmParameterException iape) {
}
// Policy qualifiers must be rejected, since we don't have
// any way to convey them back to the application.
// That's the default, so no need to write code.
}
// Skip revocation during this build to detect circular
// references. But check revocation afterwards, using the
// key (or any other that works).
builderParams.setRevocationEnabled(false);
// check for AuthorityInformationAccess extension
try {
} catch (CertificateException ce) {
// ignore but log it
"error decoding cert: " + ce);
}
}
if (currCertImpl != null) {
}
}
}
}
}
}
}
try {
} catch (NoSuchAlgorithmException nsae) {
throw new CertPathValidatorException(nsae);
}
while (true) {
try {
" about to try build ...");
}
" about to check revocation ...");
}
// Now check revocation of all certs in path, assuming that
// the stackedCerts are revoked.
if (stackedCerts == null) {
}
}
boolean signFlag = true;
try {
}
}
} catch (CertPathValidatorException cpve) {
// ignore it and try to get another key
continue;
}
}
// Now check revocation on the current cert using that key.
// If it doesn't check out, try to find a different key.
// And if we can't find a key, then return false.
try {
// If that passed, the cert is OK!
return;
} catch (CertPathValidatorException cpve) {
// If it is revoked, rethrow exception
throw cpve;
}
// Otherwise, ignore the exception and
// try to get another key.
}
} catch (InvalidAlgorithmParameterException iape) {
throw new CertPathValidatorException(iape);
} catch (CertPathBuilderException cpbe) {
throw new CertPathValidatorException
}
}
}
/*
* This inner class extends the X509CertSelector to add an additional
* check to make sure the subject public key isn't on a particular list.
* This class is used by buildToNewKey() to make sure the builder doesn't
* end up with a CertPath to a public key that has already been rejected.
*/
/**
* Creates a new <code>RejectKeySelector</code>.
*
* @param badPublicKeys a <code>Set</code> of
* <code>PublicKey</code>s that
* should be rejected (or <code>null</code>
* if no such check should be done)
*/
this.badKeySet = badPublicKeys;
}
/**
* Decides whether a <code>Certificate</code> should be selected.
*
* @param cert the <code>Certificate</code> to be checked
* @return <code>true</code> if the <code>Certificate</code> should be
* selected, <code>false</code> otherwise
*/
return(false);
return false;
}
return true;
}
/**
* Return a printable representation of the <code>CertSelector</code>.
*
* @return a <code>String</code> describing the contents of the
* <code>CertSelector</code>
*/
}
}
/**
* Internal method that verifies a set of possible_crls,
* and sees if each is approved, based on the cert.
*
* @param crls a set of possible CRLs to test for acceptability
* @param cert the certificate whose revocation status is being checked
* @param signFlag <code>true</code> if prevKey was trusted to sign CRLs
* @param prevKey the public key of the issuer of cert
* @param reasonsMask the reason code mask
* @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s>
* @return a collection of approved crls (or an empty collection)
*/
boolean[] reasonsMask,
try {
"Checking CRLDPs for "
}
// assume a DP with reasons and CRLIssuer fields omitted
// and a DP name of the cert issuer.
// TODO add issuerAltName too
} else {
}
}
}
}
return results;
} catch (Exception e) {
e.printStackTrace();
}
return Collections.emptySet();
}
}
}