下面列出了java.security.cert.X509CRL#isRevoked() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Check if given certificate is revoked looking on it's CRL (if exist).
* @param cert which is validated
* @return true if certificate is revoked, false if it isn't or CRL cannot be accessed (because it might not exist).
*/
public boolean checkRevocation(X509Certificate cert) {
boolean revoked = false;
try {
SparkTrustManager man = new SparkTrustManager();
Collection<X509CRL> crls = man.loadCRL(new X509Certificate[] { cert });
CertificateFactory cf = CertificateFactory.getInstance("X.509");
for (X509CRL crl : crls) {
if (crl.isRevoked(cert)) {
revoked = true;
break;
}
}
} catch (CRLException | CertificateException | IOException | InvalidAlgorithmParameterException
| NoSuchAlgorithmException | CertStoreException e) {
Log.warning("Cannot check validity", e);
}
return revoked;
}
public boolean isRevoked ( final X509Certificate cert )
{
for ( final X509CRL crl : this.crls )
{
if ( crl.isRevoked ( cert ) )
{
return true;
}
}
return false;
}
/**
* Check that {@code cert} is signed by the {@code ca} and not revoked.
*
* <p>Support for certificate chains has not been implemented.
*
* @throws GeneralSecurityException for unsupported protocols, certs not signed by the TMCH,
* parsing errors, encoding errors, if the CRL is expired, or if the CRL is older than the
* one currently in memory.
*/
public static void verifyCertificate(
X509Certificate rootCert, X509CRL crl, @Tainted X509Certificate cert, Date now)
throws GeneralSecurityException {
cert.checkValidity(checkNotNull(now, "now"));
cert.verify(rootCert.getPublicKey());
if (crl.isRevoked(cert)) {
X509CRLEntry entry = crl.getRevokedCertificate(cert);
throw new CertificateRevokedException(
checkNotNull(entry.getRevocationDate(), "revocationDate"),
Optional.ofNullable(entry.getRevocationReason()).orElse(CRLReason.UNSPECIFIED),
firstNonNull(entry.getCertificateIssuer(), crl.getIssuerX500Principal()),
ImmutableMap.of());
}
}
/**
* Check the signature on CRL and check if 1st certificate from the chain ((The actual certificate from the client)) is valid and not available on CRL.
*
* @param certs The 1st certificate is the actual certificate of the user. The other certificates represents the certificate chain
* @param crl Given CRL
* @throws GeneralSecurityException if some error in validation happens. Typically certificate not valid, or CRL signature not valid
*/
public static void check(X509Certificate[] certs, X509CRL crl, KeycloakSession session) throws GeneralSecurityException {
if (certs.length < 2) {
throw new GeneralSecurityException("Not possible to verify signature on CRL. X509 certificate doesn't have CA chain available on it");
}
X500Principal crlIssuerPrincipal = crl.getIssuerX500Principal();
X509Certificate crlSignatureCertificate = null;
// Try to find the certificate in the CA chain, which was used to sign the CRL
for (int i=1 ; i<certs.length ; i++) {
X509Certificate currentCACert = certs[i];
if (crlIssuerPrincipal.equals(currentCACert.getSubjectX500Principal())) {
crlSignatureCertificate = currentCACert;
log.tracef("Found certificate used to sign CRL in the CA chain of the certificate. CRL issuer: %s", crlIssuerPrincipal);
break;
}
}
// Try to find the CRL issuer certificate in the truststore
if (crlSignatureCertificate == null) {
log.tracef("Not found CRL issuer '%s' in the CA chain of the certificate. Fallback to lookup CRL issuer in the truststore", crlIssuerPrincipal);
crlSignatureCertificate = findCRLSignatureCertificateInTruststore(session, certs, crlIssuerPrincipal);
}
// Verify signature on CRL
// TODO: It will be nice to cache CRLs and also verify their signatures just once at the time when CRL is loaded, rather than in every request
crl.verify(crlSignatureCertificate.getPublicKey());
// Finally check if
if (crl.isRevoked(certs[0])) {
String message = String.format("Certificate has been revoked, certificate's subject: %s", certs[0].getSubjectDN().getName());
log.debug(message);
throw new GeneralSecurityException(message);
}
}
/**
* Validate certificate path
*
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws InvalidAlgorithmParameterException
* @throws CertPathValidatorException
* @throws CertPathBuilderException
* @throws CertificateException
*/
private void validatePath(X509Certificate[] chain)
throws NoSuchAlgorithmException, KeyStoreException, InvalidAlgorithmParameterException,
CertPathValidatorException, CertPathBuilderException, CertificateException {
// PKIX algorithm is defined in rfc3280
CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX");
CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("PKIX");
X509CertSelector certSelector = new X509CertSelector();
// set last certificate (often root CA) from chain for CertSelector so trust store must contain it
certSelector.setCertificate(chain[chain.length - 1]);
// checks against time validity aren't done here as are already done in checkDateValidity (X509Certificate[]
// chain)
certSelector.setCertificateValid(null);
// create parameters using trustStore as source of Trust Anchors and using X509CertSelector
PKIXBuilderParameters parameters = new PKIXBuilderParameters(allStore, certSelector);
// will use PKIXRevocationChecker (or nothing if revocation mechanisms are
// disabled) instead of the default revocation checker
parameters.setRevocationEnabled(false);
// if revoked certificates aren't accepted, but no revocation checks then only
// certificates from blacklist will be rejected
if (acceptRevoked == false) {
// OCSP checking is done according to Java PKI Programmer's Guide, PKIXRevocationChecker was added in Java 8:
// https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html#PKIXRevocationChecker
PKIXRevocationChecker checker = (PKIXRevocationChecker) certPathBuilder.getRevocationChecker();
EnumSet<PKIXRevocationChecker.Option> checkerOptions = EnumSet.noneOf(PKIXRevocationChecker.Option.class);
// if soft fail isn't enabled then OCSP or CRL must pass validation, in case
// when any of them cannot be validated verification will fail, if soft fail
// is enabled then in case of network issues revocation checking is omitted
if (allowSoftFail) {
checkerOptions.add(PKIXRevocationChecker.Option.SOFT_FAIL);
}
// check OCSP, CRL serve as backup
if (checkOCSP && checkCRL) {
checker.setOptions(checkerOptions);
parameters.addCertPathChecker(checker);
} else if (!checkOCSP && checkCRL) {
// check only CRL, if CRL fail then there is no fallback to OCSP
checkerOptions.add(PKIXRevocationChecker.Option.PREFER_CRLS);
checkerOptions.add(PKIXRevocationChecker.Option.NO_FALLBACK);
checker.setOptions(checkerOptions);
parameters.addCertPathChecker(checker);
}
}
try {
CertPathBuilderResult pathResult = certPathBuilder.build(parameters);
CertPath certPath = pathResult.getCertPath();
PKIXCertPathValidatorResult validationResult = (PKIXCertPathValidatorResult) certPathValidator
.validate(certPath, parameters);
X509Certificate trustedCert = validationResult.getTrustAnchor().getTrustedCert();
if (trustedCert == null) {
throw new CertificateException("certificate path failed: Trusted CA is NULL");
}
// check if all certificates in path have Basic Constraints, only certificate that isn't required to have
// this extension is last certificate: root CA
for (int i = 0; i < chain.length - 1; i++) {
checkBasicConstraints(chain[i]);
}
} catch (CertificateRevokedException e) {
Log.warning("Certificate was revoked", e);
for (X509Certificate cert : chain) {
for (X509CRL crl : crlCollection) {
if (crl.isRevoked(cert)) {
try {
addToBlackList(cert);
} catch (IOException | HeadlessException | InvalidNameException e1) {
Log.error("Couldn't move to the blacklist", e1);
}
break;
}
}
}
throw new CertificateException("Certificate was revoked");
}
}