Example usage for org.bouncycastle.cert.ocsp SingleResp getNextUpdate

List of usage examples for org.bouncycastle.cert.ocsp SingleResp getNextUpdate

Introduction

In this page you can find the example usage for org.bouncycastle.cert.ocsp SingleResp getNextUpdate.

Prototype

public Date getNextUpdate() 

Source Link

Document

return the NextUpdate value - note: this is an optional field so may be returned as null.

Usage

From source file:be.fedict.trust.ocsp.OcspTrustLinker.java

License:Open Source License

@Override
public TrustLinkerResult hasTrustLink(X509Certificate childCertificate, X509Certificate certificate,
        Date validationDate, RevocationData revocationData, AlgorithmPolicy algorithmPolicy)
        throws TrustLinkerResultException, Exception {
    URI ocspUri = getOcspUri(childCertificate);
    if (null == ocspUri) {
        return TrustLinkerResult.UNDECIDED;
    }//from   ww w  .j ava2  s.co m
    LOG.debug("OCSP URI: " + ocspUri);

    OCSPResp ocspResp = this.ocspRepository.findOcspResponse(ocspUri, childCertificate, certificate,
            validationDate);
    if (null == ocspResp) {
        LOG.debug("OCSP response not found");
        return TrustLinkerResult.UNDECIDED;
    }

    int ocspRespStatus = ocspResp.getStatus();
    if (OCSPResponseStatus.SUCCESSFUL != ocspRespStatus) {
        LOG.debug("OCSP response status: " + ocspRespStatus);
        return TrustLinkerResult.UNDECIDED;
    }

    Object responseObject = ocspResp.getResponseObject();
    BasicOCSPResp basicOCSPResp = (BasicOCSPResp) responseObject;

    X509CertificateHolder[] responseCertificates = basicOCSPResp.getCerts();
    for (X509CertificateHolder responseCertificate : responseCertificates) {
        LOG.debug("OCSP response cert: " + responseCertificate.getSubject());
        LOG.debug("OCSP response cert issuer: " + responseCertificate.getIssuer());
    }

    algorithmPolicy.checkSignatureAlgorithm(basicOCSPResp.getSignatureAlgOID().getId(), validationDate);

    if (0 == responseCertificates.length) {
        /*
         * This means that the OCSP response has been signed by the issuing
         * CA itself.
         */
        ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(certificate.getPublicKey());
        boolean verificationResult = basicOCSPResp.isSignatureValid(contentVerifierProvider);
        if (false == verificationResult) {
            LOG.debug("OCSP response signature invalid");
            return TrustLinkerResult.UNDECIDED;
        }
    } else {
        /*
         * We're dealing with a dedicated authorized OCSP Responder
         * certificate, or of course with a CA that issues the OCSP
         * Responses itself.
         */

        X509CertificateHolder ocspResponderCertificate = responseCertificates[0];
        ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(ocspResponderCertificate);

        boolean verificationResult = basicOCSPResp.isSignatureValid(contentVerifierProvider);
        if (false == verificationResult) {
            LOG.debug("OCSP Responser response signature invalid");
            return TrustLinkerResult.UNDECIDED;
        }
        if (false == Arrays.equals(certificate.getEncoded(), ocspResponderCertificate.getEncoded())) {
            // check certificate signature algorithm
            algorithmPolicy.checkSignatureAlgorithm(
                    ocspResponderCertificate.getSignatureAlgorithm().getAlgorithm().getId(), validationDate);

            X509Certificate issuingCaCertificate;
            if (responseCertificates.length < 2) {
                // so the OCSP certificate chain only contains a single
                // entry
                LOG.debug("OCSP responder complete certificate chain missing");
                /*
                 * Here we assume that the OCSP Responder is directly signed
                 * by the CA.
                 */
                issuingCaCertificate = certificate;
            } else {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                issuingCaCertificate = (X509Certificate) certificateFactory
                        .generateCertificate(new ByteArrayInputStream(responseCertificates[1].getEncoded()));
                /*
                 * Is next check really required?
                 */
                if (false == certificate.equals(issuingCaCertificate)) {
                    LOG.debug("OCSP responder certificate not issued by CA");
                    return TrustLinkerResult.UNDECIDED;
                }
            }
            // check certificate signature
            algorithmPolicy.checkSignatureAlgorithm(issuingCaCertificate.getSigAlgOID(), validationDate);

            PublicKeyTrustLinker publicKeyTrustLinker = new PublicKeyTrustLinker();
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate x509OcspResponderCertificate = (X509Certificate) certificateFactory
                    .generateCertificate(new ByteArrayInputStream(ocspResponderCertificate.getEncoded()));
            LOG.debug("OCSP Responder public key fingerprint: "
                    + DigestUtils.sha1Hex(x509OcspResponderCertificate.getPublicKey().getEncoded()));
            publicKeyTrustLinker.hasTrustLink(x509OcspResponderCertificate, issuingCaCertificate,
                    validationDate, revocationData, algorithmPolicy);
            if (null == x509OcspResponderCertificate
                    .getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId())) {
                LOG.debug("OCSP Responder certificate should have id-pkix-ocsp-nocheck");
                /*
                 * TODO: perform CRL validation on the OCSP Responder
                 * certificate. On the other hand, do we really want to
                 * check the checker?
                 */
                return TrustLinkerResult.UNDECIDED;
            }
            List<String> extendedKeyUsage = x509OcspResponderCertificate.getExtendedKeyUsage();
            if (null == extendedKeyUsage) {
                LOG.debug("OCSP Responder certificate has no extended key usage extension");
                return TrustLinkerResult.UNDECIDED;
            }
            if (false == extendedKeyUsage.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) {
                LOG.debug("OCSP Responder certificate should have a OCSPSigning extended key usage");
                return TrustLinkerResult.UNDECIDED;
            }
        } else {
            LOG.debug("OCSP Responder certificate equals the CA certificate");
            // and the CA certificate is already trusted at this point
        }
    }

    DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder()
            .setProvider(BouncyCastleProvider.PROVIDER_NAME).build();
    CertificateID certificateId = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1),
            new JcaX509CertificateHolder(certificate), childCertificate.getSerialNumber());

    SingleResp[] singleResps = basicOCSPResp.getResponses();
    for (SingleResp singleResp : singleResps) {
        CertificateID responseCertificateId = singleResp.getCertID();
        if (false == certificateId.equals(responseCertificateId)) {
            continue;
        }
        DateTime thisUpdate = new DateTime(singleResp.getThisUpdate());
        DateTime nextUpdate;
        if (null != singleResp.getNextUpdate()) {
            nextUpdate = new DateTime(singleResp.getNextUpdate());
        } else {
            LOG.debug("no OCSP nextUpdate");
            nextUpdate = thisUpdate;
        }
        LOG.debug("OCSP thisUpdate: " + thisUpdate);
        LOG.debug("(OCSP) nextUpdate: " + nextUpdate);
        DateTime beginValidity = thisUpdate.minus(this.freshnessInterval);
        DateTime endValidity = nextUpdate.plus(this.freshnessInterval);
        DateTime validationDateTime = new DateTime(validationDate);
        if (validationDateTime.isBefore(beginValidity)) {
            LOG.warn("OCSP response not yet valid");
            continue;
        }
        if (validationDateTime.isAfter(endValidity)) {
            LOG.warn("OCSP response expired");
            continue;
        }
        if (null == singleResp.getCertStatus()) {
            LOG.debug("OCSP OK for: " + childCertificate.getSubjectX500Principal());
            addRevocationData(revocationData, ocspResp, ocspUri);
            return TrustLinkerResult.TRUSTED;
        } else {
            LOG.debug("OCSP certificate status: " + singleResp.getCertStatus().getClass().getName());
            if (singleResp.getCertStatus() instanceof RevokedStatus) {
                LOG.debug("OCSP status revoked");
            }
            addRevocationData(revocationData, ocspResp, ocspUri);
            throw new TrustLinkerResultException(TrustLinkerResultReason.INVALID_REVOCATION_STATUS,
                    "certificate revoked by OCSP");
        }
    }

    LOG.debug("no matching OCSP response entry");
    return TrustLinkerResult.UNDECIDED;
}

From source file:ee.ria.xroad.common.ocsp.OcspVerifier.java

License:Open Source License

private void verifyValidityAt(Date atDate, SingleResp singleResp) {
    // 5. The time at which the status being indicated is known
    // to be correct (thisUpdate) is sufficiently recent.
    if (isExpired(singleResp, atDate)) {
        throw new CodedException(X_INCORRECT_VALIDATION_INFO, "OCSP response is too old (thisUpdate: %s)",
                singleResp.getThisUpdate());
    }//from  ww  w . ja v  a2  s.c  om

    if (options.isVerifyNextUpdate()) {
        // 6. When available, the time at or before which newer information will
        // be available about the status of the certificate (nextUpdate) is
        // greater than the current time.
        log.debug("Verify OCSP nextUpdate, atDate: {} nextUpdate: {}", atDate, singleResp.getNextUpdate());
        if (singleResp.getNextUpdate() != null && singleResp.getNextUpdate().before(atDate)) {
            SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
            throw new CodedException(X_INCORRECT_VALIDATION_INFO,
                    String.format("OCSP nextUpdate is too old, atDate: %s nextUpdate: %s", fmt.format(atDate),
                            fmt.format(singleResp.getNextUpdate())));
        }
    } else {
        log.debug("OCSP nextUpdate verification is turned off");
    }
}

From source file:eu.europa.ec.markt.dss.validation102853.OCSPCertificateVerifier.java

License:Open Source License

@Override
public RevocationToken check(final CertificateToken toCheckToken) {

    if (ocspSource == null) {

        LOG.warn("OCSPSource null");
        toCheckToken.extraInfo().infoOCSPSourceIsNull();
        return null;
    }/*from ww w . jav  a2  s  .c om*/
    try {

        final X509Certificate issuerCert = toCheckToken.getIssuerToken().getCertificate();
        final X509Certificate toCheckCert = toCheckToken.getCertificate();
        final BasicOCSPResp basicOCSPResp = ocspSource.getOCSPResponse(toCheckCert, issuerCert);
        if (basicOCSPResp == null) {

            String uri = "";
            if (ocspSource instanceof OnlineOCSPSource) {

                uri = ((OnlineOCSPSource) ocspSource).getAccessLocation(toCheckCert);
                toCheckToken.extraInfo().infoNoOCSPResponse(uri);
            }

            if (LOG.isInfoEnabled()) {
                LOG.info("OCSP response not found for " + toCheckToken.getDSSIdAsString() + " [" + uri + "]");
            }
            return null;
        }
        final BigInteger serialNumber = toCheckCert.getSerialNumber();
        final X509CertificateHolder x509CertificateHolder = new X509CertificateHolder(
                DSSUtils.getEncoded(issuerCert));
        final DigestCalculator digestCalculator = DSSUtils.getSHA1DigestCalculator();
        final CertificateID certificateId = new CertificateID(digestCalculator, x509CertificateHolder,
                serialNumber);
        final SingleResp[] singleResps = basicOCSPResp.getResponses();
        for (final SingleResp singleResp : singleResps) {
            if (!DSSRevocationUtils.matches(certificateId, singleResp)) {

                continue;
            }
            if (LOG.isDebugEnabled()) {

                LOG.debug("OCSP thisUpdate: " + singleResp.getThisUpdate());
                LOG.debug("OCSP nextUpdate: " + singleResp.getNextUpdate());
            }
            final OCSPToken ocspToken = new OCSPToken(basicOCSPResp, validationCertPool);
            if (ocspSource instanceof OnlineOCSPSource) {

                ocspToken.setSourceURI(((OnlineOCSPSource) ocspSource).getAccessLocation(toCheckCert));
            }

            ocspToken.setIssuingTime(basicOCSPResp.getProducedAt());
            toCheckToken.setRevocationToken(ocspToken);
            final Object certStatus = singleResp.getCertStatus();
            if (certStatus == null) {

                if (LOG.isInfoEnabled()) {
                    LOG.info("OCSP OK for: " + toCheckToken.getDSSIdAsString());
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("CertificateToken:\n{}", toCheckToken.toString());
                    }
                }
                ocspToken.setStatus(true);
            } else {

                if (LOG.isInfoEnabled()) {
                    LOG.info("OCSP certificate status: " + certStatus.getClass().getName());
                }
                if (certStatus instanceof RevokedStatus) {

                    if (LOG.isInfoEnabled()) {
                        LOG.info("OCSP status revoked");
                    }
                    final RevokedStatus revokedStatus = (RevokedStatus) certStatus;
                    ocspToken.setStatus(false);
                    ocspToken.setRevocationDate(revokedStatus.getRevocationTime());
                    final int reasonId = revokedStatus.getRevocationReason();
                    final CRLReason crlReason = CRLReason.lookup(reasonId);
                    ocspToken.setReason(crlReason.toString());
                } else if (certStatus instanceof UnknownStatus) {

                    if (LOG.isInfoEnabled()) {
                        LOG.info("OCSP status unknown");
                    }
                    ocspToken.setReason("OCSP status: unknown");
                }
            }
            return ocspToken;
        }
    } catch (DSSException e) {

        LOG.error("OCSP DSS Exception: " + e.getMessage(), e);
        toCheckToken.extraInfo().infoOCSPException(e);
        return null;
    } catch (OCSPException e) {

        LOG.error("OCSP Exception: " + e.getMessage());
        toCheckToken.extraInfo().infoOCSPException(e);
        throw new DSSException(e);
    } catch (IOException e) {
        throw new DSSException(e);
    }
    if (LOG.isInfoEnabled()) {
        LOG.debug("No matching OCSP response entry");
    }
    toCheckToken.extraInfo().infoNoOCSPResponse(null);
    return null;
}

From source file:io.netty.example.ocsp.OcspServerExample.java

License:Apache License

public static void main(String[] args) throws Exception {
    // We assume there's a private key.
    PrivateKey privateKey = null;

    // Step 1: Load the certificate chain for netty.io. We'll need the certificate
    // and the issuer's certificate and we don't need any of the intermediate certs.
    // The array is assumed to be a certain order to keep things simple.
    X509Certificate[] keyCertChain = parseCertificates(OcspServerExample.class, "netty_io_chain.pem");

    X509Certificate certificate = keyCertChain[0];
    X509Certificate issuer = keyCertChain[keyCertChain.length - 1];

    // Step 2: We need the URL of the CA's OCSP responder server. It's somewhere encoded
    // into the certificate! Notice that it's a HTTP URL.
    URI uri = OcspUtils.ocspUri(certificate);
    System.out.println("OCSP Responder URI: " + uri);

    if (uri == null) {
        throw new IllegalStateException("The CA/certificate doesn't have an OCSP responder");
    }//from ww w .  j  a v a 2  s.c  o  m

    // Step 3: Construct the OCSP request
    OCSPReq request = new OcspRequestBuilder().certificate(certificate).issuer(issuer).build();

    // Step 4: Do the request to the CA's OCSP responder
    OCSPResp response = OcspUtils.request(uri, request, 5L, TimeUnit.SECONDS);
    if (response.getStatus() != OCSPResponseStatus.SUCCESSFUL) {
        throw new IllegalStateException("response-status=" + response.getStatus());
    }

    // Step 5: Is my certificate any good or has the CA revoked it?
    BasicOCSPResp basicResponse = (BasicOCSPResp) response.getResponseObject();
    SingleResp first = basicResponse.getResponses()[0];

    CertificateStatus status = first.getCertStatus();
    System.out.println("Status: " + (status == CertificateStatus.GOOD ? "Good" : status));
    System.out.println("This Update: " + first.getThisUpdate());
    System.out.println("Next Update: " + first.getNextUpdate());

    if (status != null) {
        throw new IllegalStateException("certificate-status=" + status);
    }

    BigInteger certSerial = certificate.getSerialNumber();
    BigInteger ocspSerial = first.getCertID().getSerialNumber();
    if (!certSerial.equals(ocspSerial)) {
        throw new IllegalStateException("Bad Serials=" + certSerial + " vs. " + ocspSerial);
    }

    // Step 6: Cache the OCSP response and use it as long as it's not
    // expired. The exact semantics are beyond the scope of this example.

    if (!OpenSsl.isAvailable()) {
        throw new IllegalStateException("OpenSSL is not available!");
    }

    if (!OpenSsl.isOcspSupported()) {
        throw new IllegalStateException("OCSP is not supported!");
    }

    if (privateKey == null) {
        throw new IllegalStateException(
                "Because we don't have a PrivateKey we can't continue past this point.");
    }

    ReferenceCountedOpenSslContext context = (ReferenceCountedOpenSslContext) SslContextBuilder
            .forServer(privateKey, keyCertChain).sslProvider(SslProvider.OPENSSL).enableOcsp(true).build();

    try {
        ServerBootstrap bootstrap = new ServerBootstrap().childHandler(newServerHandler(context, response));

        // so on and so forth...
    } finally {
        context.release();
    }
}

From source file:org.ejbca.core.protocol.ocsp.ProtocolOcspHttpStandaloneTest.java

License:Open Source License

/**
 * Tests the ocsp.revoked.untilNextUpdate configuration.
 * /*from   www .ja v  a 2 s  .  com*/
 * The test sets ocsp.untilNextUpdate and ocsp.revoked.untilNextUpdate to different values and then verified that the response's next update value matches 
 * the setting of ocsp.revoked.untilNextUpdate and not ocsp.untilNextUpdate
 * 
 * @throws Exception
 *             error
 */
@Test
public void testRevokedNextUpdate() throws Exception {
    ocspResponseGeneratorTestSession.reloadOcspSigningCache();
    final X509Certificate ocspTestCert = getRevokedTestCert();

    final String oldConfigurationValue1 = configurationSession.getConfigurationValue(
            "ocsp." + CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER + ".untilNextUpdate");
    final String oldConfigurationValue2 = configurationSession.getConfigurationValue(
            "ocsp." + CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER + ".revoked.untilNextUpdate");
    configurationSession.setConfigurationValue(
            "ocsp." + CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER + ".untilNextUpdate", "7");
    configurationSession.setConfigurationValue(
            "ocsp." + CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER + ".revoked.untilNextUpdate",
            "5");
    // Make sure that we run the test with a CA where this is no OcspKeyBinding
    OcspTestUtils.setInternalKeyBindingStatus(authenticationToken, internalKeyBindingId,
            InternalKeyBindingStatus.DISABLED);
    ocspResponseGeneratorTestSession.reloadOcspSigningCache();
    try {

        // And an OCSP request
        OCSPReqBuilder gen = new OCSPReqBuilder();
        gen.addRequest(new JcaCertificateID(SHA1DigestCalculator.buildSha1Instance(), getCaCert(ocspTestCert),
                ocspTestCert.getSerialNumber()));
        OCSPReq req = gen.build();

        // Send the request and receive a singleResponse
        SingleResp[] singleResps = helper.sendOCSPPost(req.getEncoded(), null, 0, 200);
        assertEquals("No of SingResps should be 1.", 1, singleResps.length);
        SingleResp singleResp = singleResps[0];

        CertificateID certId = singleResp.getCertID();
        assertEquals("Serno in response does not match serno in request.", certId.getSerialNumber(),
                ocspTestCert.getSerialNumber());
        Object status = singleResp.getCertStatus();
        assertTrue("Status (" + status + ") is not RevokedStatus", status instanceof RevokedStatus);
        RevokedStatus rev = (RevokedStatus) status;
        assertTrue("Status does not have reason", rev.hasRevocationReason());

        Date thisUpdate = singleResp.getThisUpdate();
        Date nextUpdate = singleResp.getNextUpdate();
        assertNotNull("thisUpdate was not set.", thisUpdate);
        assertNotNull(
                "nextUpdate was not set. (This test requires ocsp.revoked.untilNextUpdate to be configured.)",
                nextUpdate);

        long diff = nextUpdate.getTime() - thisUpdate.getTime();
        assertEquals("The nextUpdate value was not taken from ocsp.revoked.untilNextUpdate", 5000L, diff);

    } finally {
        configurationSession.setConfigurationValue(
                "ocsp." + CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER + ".untilNextUpdate",
                oldConfigurationValue1);
        configurationSession.setConfigurationValue(
                "ocsp." + CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER + ".revoked.untilNextUpdate",
                oldConfigurationValue2);
        OcspTestUtils.setInternalKeyBindingStatus(authenticationToken, internalKeyBindingId,
                InternalKeyBindingStatus.ACTIVE);
    }

}

From source file:org.jruby.ext.openssl.OCSPBasicResponse.java

License:Common Public License

@JRubyMethod(name = "sign", rest = true)
public IRubyObject sign(final ThreadContext context, IRubyObject[] args) {
    Ruby runtime = context.getRuntime();

    int flag = 0;
    IRubyObject additionalCerts = context.nil;
    IRubyObject flags = context.nil;//from   w  w  w  . j  ava 2 s .c  o  m
    IRubyObject digest = context.nil;
    Digest digestInstance = new Digest(runtime, _Digest(runtime));
    List<X509CertificateHolder> addlCerts = new ArrayList<X509CertificateHolder>();

    switch (Arity.checkArgumentCount(runtime, args, 2, 5)) {
    case 3:
        additionalCerts = args[2];
        break;
    case 4:
        additionalCerts = args[2];
        flags = args[3];
        break;
    case 5:
        additionalCerts = args[2];
        flags = args[3];
        digest = args[4];
        break;
    default:
        break;
    }

    if (digest.isNil())
        digest = digestInstance.initialize(context,
                new IRubyObject[] { RubyString.newString(runtime, "SHA1") });
    if (!flags.isNil())
        flag = RubyFixnum.fix2int(flags);
    if (additionalCerts.isNil())
        flag |= RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCERTS));

    X509Cert signer = (X509Cert) args[0];
    PKey signerKey = (PKey) args[1];

    String keyAlg = signerKey.getAlgorithm();
    String digAlg = ((Digest) digest).getShortAlgorithm();

    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(digAlg + "with" + keyAlg);
    signerBuilder.setProvider("BC");
    ContentSigner contentSigner = null;
    try {
        contentSigner = signerBuilder.build(signerKey.getPrivateKey());
    } catch (OperatorCreationException e) {
        throw newOCSPError(runtime, e);
    }

    BasicOCSPRespBuilder respBuilder = null;
    try {
        if ((flag & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_RESPID_KEY))) != 0) {
            JcaDigestCalculatorProviderBuilder dcpb = new JcaDigestCalculatorProviderBuilder();
            dcpb.setProvider("BC");
            DigestCalculatorProvider dcp = dcpb.build();
            DigestCalculator calculator = dcp.get(contentSigner.getAlgorithmIdentifier());
            respBuilder = new BasicOCSPRespBuilder(
                    SubjectPublicKeyInfo.getInstance(signerKey.getPublicKey().getEncoded()), calculator);
        } else {
            respBuilder = new BasicOCSPRespBuilder(new RespID(signer.getSubject().getX500Name()));
        }
    } catch (Exception e) {
        throw newOCSPError(runtime, e);
    }

    X509CertificateHolder[] chain = null;
    try {
        if ((flag & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOCERTS))) == 0) {
            addlCerts.add(new X509CertificateHolder(signer.getAuxCert().getEncoded()));
            if (!additionalCerts.isNil()) {
                Iterator<java.security.cert.Certificate> rubyAddlCerts = ((RubyArray) additionalCerts)
                        .iterator();
                while (rubyAddlCerts.hasNext()) {
                    java.security.cert.Certificate cert = rubyAddlCerts.next();
                    addlCerts.add(new X509CertificateHolder(cert.getEncoded()));
                }
            }

            chain = addlCerts.toArray(new X509CertificateHolder[addlCerts.size()]);
        }
    } catch (Exception e) {
        throw newOCSPError(runtime, e);
    }

    Date producedAt = null;
    if ((flag & RubyFixnum.fix2int((RubyFixnum) _OCSP(runtime).getConstant(OCSP_NOTIME))) == 0) {
        producedAt = new Date();
    }

    for (OCSPSingleResponse resp : singleResponses) {
        SingleResp singleResp = new SingleResp(resp.getBCSingleResp());
        respBuilder.addResponse(singleResp.getCertID(), singleResp.getCertStatus(), singleResp.getThisUpdate(),
                singleResp.getNextUpdate(), resp.getBCSingleResp().getSingleExtensions());
    }

    try {
        Extension[] respExtAry = new Extension[extensions.size()];
        Extensions respExtensions = new Extensions(extensions.toArray(respExtAry));
        BasicOCSPResp bcBasicOCSPResp = respBuilder.setResponseExtensions(respExtensions).build(contentSigner,
                chain, producedAt);
        asn1BCBasicOCSPResp = BasicOCSPResponse.getInstance(bcBasicOCSPResp.getEncoded());
    } catch (Exception e) {
        throw newOCSPError(runtime, e);
    }
    return this;
}

From source file:org.keycloak.common.util.OCSPUtils.java

License:Apache License

private static void verifyResponse(BasicOCSPResp basicOcspResponse, X509Certificate issuerCertificate,
        X509Certificate responderCertificate, byte[] requestNonce, Date date)
        throws NoSuchProviderException, NoSuchAlgorithmException, CertificateNotYetValidException,
        CertificateExpiredException, CertPathValidatorException {

    List<X509CertificateHolder> certs = new ArrayList<>(Arrays.asList(basicOcspResponse.getCerts()));
    X509Certificate signingCert = null;

    try {/*  ww w. j a v a 2s  .  co m*/
        certs.add(new JcaX509CertificateHolder(issuerCertificate));
        if (responderCertificate != null) {
            certs.add(new JcaX509CertificateHolder(responderCertificate));
        }
    } catch (CertificateEncodingException e) {
        e.printStackTrace();
    }
    if (certs.size() > 0) {

        X500Name responderName = basicOcspResponse.getResponderId().toASN1Primitive().getName();
        byte[] responderKey = basicOcspResponse.getResponderId().toASN1Primitive().getKeyHash();

        if (responderName != null) {
            logger.log(Level.INFO, "Responder Name: {0}", responderName.toString());
            for (X509CertificateHolder certHolder : certs) {
                try {
                    X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC")
                            .getCertificate(certHolder);
                    X500Name respName = new X500Name(tempCert.getSubjectX500Principal().getName());
                    if (responderName.equals(respName)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO,
                                "Found a certificate whose principal \"{0}\" matches the responder name \"{1}\"",
                                new Object[] { tempCert.getSubjectDN().getName(), responderName.toString() });
                        break;
                    }
                } catch (CertificateException e) {
                    logger.log(Level.FINE, e.getMessage());
                }
            }
        } else if (responderKey != null) {
            SubjectKeyIdentifier responderSubjectKey = new SubjectKeyIdentifier(responderKey);
            logger.log(Level.INFO, "Responder Key: {0}", Arrays.toString(responderKey));
            for (X509CertificateHolder certHolder : certs) {
                try {
                    X509Certificate tempCert = new JcaX509CertificateConverter().setProvider("BC")
                            .getCertificate(certHolder);

                    SubjectKeyIdentifier subjectKeyIdentifier = null;
                    if (certHolder.getExtensions() != null) {
                        subjectKeyIdentifier = SubjectKeyIdentifier.fromExtensions(certHolder.getExtensions());
                    }

                    if (subjectKeyIdentifier != null) {
                        logger.log(Level.INFO, "Certificate: {0}\nSubject Key Id: {1}",
                                new Object[] { tempCert.getSubjectDN().getName(),
                                        Arrays.toString(subjectKeyIdentifier.getKeyIdentifier()) });
                    }

                    if (subjectKeyIdentifier != null && responderSubjectKey.equals(subjectKeyIdentifier)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO,
                                "Found a signer certificate \"{0}\" with the subject key extension value matching the responder key",
                                signingCert.getSubjectDN().getName());

                        break;
                    }

                    subjectKeyIdentifier = new JcaX509ExtensionUtils()
                            .createSubjectKeyIdentifier(tempCert.getPublicKey());
                    if (responderSubjectKey.equals(subjectKeyIdentifier)) {
                        signingCert = tempCert;
                        logger.log(Level.INFO,
                                "Found a certificate \"{0}\" with the subject key matching the OCSP responder key",
                                signingCert.getSubjectDN().getName());
                        break;
                    }

                } catch (CertificateException e) {
                    logger.log(Level.FINE, e.getMessage());
                }
            }
        }
    }
    if (signingCert != null) {
        if (signingCert.equals(issuerCertificate)) {
            logger.log(Level.INFO, "OCSP response is signed by the target''s Issuing CA");
        } else if (responderCertificate != null && signingCert.equals(responderCertificate)) {
            // https://www.ietf.org/rfc/rfc2560.txt
            // 2.6  OCSP Signature Authority Delegation
            // - The responder certificate is issued to the responder by CA
            logger.log(Level.INFO, "OCSP response is signed by an authorized responder certificate");
        } else {
            // 4.2.2.2  Authorized Responders
            // 3. Includes a value of id-ad-ocspSigning in an ExtendedKeyUsage
            // extension and is issued by the CA that issued the certificate in
            // question."
            if (!signingCert.getIssuerX500Principal().equals(issuerCertificate.getSubjectX500Principal())) {
                logger.log(Level.INFO, "Signer certificate''s Issuer: {0}\nIssuer certificate''s Subject: {1}",
                        new Object[] { signingCert.getIssuerX500Principal().getName(),
                                issuerCertificate.getSubjectX500Principal().getName() });
                throw new CertPathValidatorException(
                        "Responder\'s certificate is not authorized to sign OCSP responses");
            }
            try {
                List<String> purposes = signingCert.getExtendedKeyUsage();
                if (purposes != null && !purposes.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) {
                    logger.log(Level.INFO, "OCSPSigning extended usage is not set");
                    throw new CertPathValidatorException(
                            "Responder\'s certificate not valid for signing OCSP responses");
                }
            } catch (CertificateParsingException e) {
                logger.log(Level.FINE, "Failed to get certificate''s extended key usage extension\n{0}",
                        e.getMessage());
            }
            if (date == null) {
                signingCert.checkValidity();
            } else {
                signingCert.checkValidity(date);
            }
            try {
                Extension noOCSPCheck = new JcaX509CertificateHolder(signingCert)
                        .getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck);
                // TODO If the extension is present, the OCSP client can trust the
                // responder's certificate for the lifetime of the certificate.
                logger.log(Level.INFO, "OCSP no-check extension is {0} present",
                        noOCSPCheck == null ? "not" : "");
            } catch (CertificateEncodingException e) {
                logger.log(Level.FINE, "Certificate encoding exception: {0}", e.getMessage());
            }

            try {
                signingCert.verify(issuerCertificate.getPublicKey());
                logger.log(Level.INFO, "OCSP response is signed by an Authorized Responder");

            } catch (GeneralSecurityException ex) {
                signingCert = null;
            }
        }
    }
    if (signingCert == null) {
        throw new CertPathValidatorException("Unable to verify OCSP Response\'s signature");
    } else {
        if (!verifySignature(basicOcspResponse, signingCert)) {
            throw new CertPathValidatorException("Error verifying OCSP Response\'s signature");
        } else {
            Extension responseNonce = basicOcspResponse.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
            if (responseNonce != null && requestNonce != null
                    && !Arrays.equals(requestNonce, responseNonce.getExtnValue().getOctets())) {
                throw new CertPathValidatorException("Nonces do not match.");
            } else {
                // See Sun's OCSP implementation.
                // https://www.ietf.org/rfc/rfc2560.txt, if nextUpdate is not set,
                // the responder is indicating that newer update is avilable all the time
                long current = date == null ? System.currentTimeMillis() : date.getTime();
                Date stop = new Date(current + (long) TIME_SKEW);
                Date start = new Date(current - (long) TIME_SKEW);

                Iterator<SingleResp> iter = Arrays.asList(basicOcspResponse.getResponses()).iterator();
                SingleResp singleRes = null;
                do {
                    if (!iter.hasNext()) {
                        return;
                    }
                    singleRes = iter.next();
                } while (!stop.before(singleRes.getThisUpdate())
                        && !start.after(singleRes.getNextUpdate() != null ? singleRes.getNextUpdate()
                                : singleRes.getThisUpdate()));

                throw new CertPathValidatorException(
                        "Response is unreliable: its validity interval is out-of-date");
            }
        }
    }
}

From source file:org.signserver.module.xades.validator.AbstractCustomCertPathChecker.java

License:Open Source License

/**
 * Parses received response bytes to form basic ocsp response object and verifies ocsp response  
 * If returns , ocsp response is successfully verified, otherwise throws exception detailing problem
 * /*from ww w  .j ava  2  s . c o  m*/
 * @param x509Cert - certificate originally passed to validator for validation
 * @param ocspresp - ocsp response received from ocsp responder
 * @throws OCSPException 
 * @throws NoSuchProviderException 
 * @throws IOException 
 * @throws CertStoreException 
 * @throws NoSuchAlgorithmException 
 * @throws SignServerException 
 * @throws CertificateParsingException 
 * @throws CryptoTokenOfflineException 
 * @throws IllegalRequestException 
 */
protected void parseAndVerifyOCSPResponse(X509Certificate x509Cert, OCSPResp ocspresp, X509Certificate cACert)
        throws NoSuchProviderException, OCSPException, NoSuchAlgorithmException, CertStoreException,
        IOException, SignServerException, CertificateParsingException, IllegalRequestException,
        CryptoTokenOfflineException, OperatorCreationException, CertificateEncodingException {

    if (ocspresp.getStatus() != OCSPRespStatus.SUCCESSFUL) {
        throw new SignServerException(
                "Unexpected ocsp response status. Response Status Received : " + ocspresp.getStatus());
    }

    // we currently support only basic ocsp response 
    BasicOCSPResp basicOCSPResponse = (BasicOCSPResp) ocspresp.getResponseObject();

    if (basicOCSPResponse == null) {
        throw new SignServerException(
                "Could not construct BasicOCSPResp object from response. Only BasicOCSPResponse as defined in RFC 2560 is supported.");
    }

    //OCSP response might be signed by CA issuing the certificate or  
    //the Authorized OCSP responder certificate containing the id-kp-OCSPSigning extended key usage extension

    X509Certificate ocspRespSignerCertificate = null;

    //first check if CA issuing certificate signed the response
    //since it is expected to be the most common case
    if (basicOCSPResponse.isSignatureValid(
            new JcaContentVerifierProviderBuilder().setProvider("BC").build(cACert.getPublicKey()))) {
        ocspRespSignerCertificate = cACert;
    }
    //if CA did not sign the ocsp response, look for authorized ocsp responses from properties or from certificate chain received with response

    if (ocspRespSignerCertificate == null) {
        //look for existence of Authorized OCSP responder inside the cert chain in ocsp response
        ocspRespSignerCertificate = getAuthorizedOCSPRespondersCertificateFromOCSPResponse(basicOCSPResponse);

        //could not find the certificate signing the OCSP response in the ocsp response
        if (ocspRespSignerCertificate == null) {
            throw new SignServerException(
                    "Certificate signing the ocsp response is not found in ocsp response's certificate chain received and is not signed by CA issuing certificate");
        }
    }

    LOG.debug("OCSP response signed by :  " + CertTools.getSubjectDN(ocspRespSignerCertificate));
    // validating ocsp signers certificate
    // Check if responders certificate has id-pkix-ocsp-nocheck extension, in which case we do not validateUsingCRL (perform revocation check on ) ocsp certs for lifetime of certificate
    // using CRL RFC 2560 sect 4.2.2.2.1
    // TODO : RFC States the extension value should be NULL, so maybe bare existence of the extension is not sufficient ??
    if (ocspRespSignerCertificate
            .getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId()) != null) {
        //check if lifetime of certificate is ok
        try {
            ocspRespSignerCertificate.checkValidity();
        } catch (CertificateExpiredException e) {
            throw new SignServerException(
                    "Certificate signing the ocsp response has expired. OCSP Responder Certificate Subject DN : "
                            + CertTools.getSubjectDN(ocspRespSignerCertificate));
        } catch (CertificateNotYetValidException e) {
            throw new SignServerException(
                    "Certificate signing the ocsp response is not yet valid. OCSP Responder Certificate Subject DN : "
                            + CertTools.getSubjectDN(ocspRespSignerCertificate));
        }
    } else if (ocspRespSignerCertificate.equals(cACert)) {
        LOG.debug("Not performing revocation check on issuer certificate");
    } else {
        // TODO: Could try to use CRL if available
        throw new SignServerException("Revokation check of OCSP certificate not yet supported");
    }

    //get the response we requested for 
    for (SingleResp singleResponse : basicOCSPResponse.getResponses()) {
        if (singleResponse.getCertID().getSerialNumber().equals(x509Cert.getSerialNumber())) {
            //found our response
            //check if response is OK, and if not throw OCSPStatusNotGoodException
            if (singleResponse.getCertStatus() != null) {
                throw new OCSPStatusNotGoodException(
                        "Responce for queried certificate is not good. Certificate status returned : "
                                + singleResponse.getCertStatus(),
                        singleResponse.getCertStatus());
            }
            //check the dates ThisUpdate and NextUpdate RFC 2560 sect : 4.2.2.1
            if (singleResponse.getNextUpdate() != null
                    && (new Date()).compareTo(singleResponse.getNextUpdate()) >= 0) {
                throw new SignServerException(
                        "Unreliable response received. Response reported a nextupdate as : "
                                + singleResponse.getNextUpdate().toString()
                                + " which is earlier than current date.");
            }
            if (singleResponse.getThisUpdate() != null
                    && (new Date()).compareTo(singleResponse.getThisUpdate()) <= 0) {
                throw new SignServerException(
                        "Unreliable response received. Response reported a thisupdate as : "
                                + singleResponse.getThisUpdate().toString()
                                + " which is earlier than current date.");
            }

            break;
        }
    }

}

From source file:org.signserver.validationservice.server.OCSPPathChecker.java

License:Open Source License

/**
 * Parses received response bytes to form basic ocsp response object and verifies ocsp response  
 * If returns , ocsp response is successfully verified, otherwise throws exception detailing problem
 * // ww  w  . j a  va  2  s  . c o  m
 * @param x509Cert - certificate originally passed to validator for validation
 * @param derocspresponse - der formatted ocsp response received from ocsp responder
 * @throws OCSPException 
 * @throws NoSuchProviderException 
 * @throws IOException 
 * @throws CertStoreException 
 * @throws NoSuchAlgorithmException 
 * @throws NoSuchAlgorithmException 
 * @throws SignServerException 
 * @throws CertificateParsingException 
 * @throws CryptoTokenOfflineException 
 * @throws IllegalRequestException 
 */
protected void parseAndVerifyOCSPResponse(X509Certificate x509Cert, byte[] derocspresponse)
        throws NoSuchProviderException, OCSPException, NoSuchAlgorithmException, CertStoreException,
        IOException, SignServerException, CertificateParsingException, IllegalRequestException,
        CryptoTokenOfflineException, OperatorCreationException, CertificateEncodingException {
    //parse received ocsp response
    OCSPResp ocspresp = new OCSPResp(derocspresponse);
    if (ocspresp.getStatus() != OCSPRespStatus.SUCCESSFUL) {
        throw new SignServerException(
                "Unexpected ocsp response status. Response Status Received : " + ocspresp.getStatus());
    }

    // we currently support only basic ocsp response 
    BasicOCSPResp basicOCSPResponse = (BasicOCSPResp) ocspresp.getResponseObject();

    if (basicOCSPResponse == null) {
        throw new SignServerException(
                "Could not construct BasicOCSPResp object from response. Only BasicOCSPResponse as defined in RFC 2560 is supported.");
    }

    //OCSP response might be signed by CA issuing the certificate or  
    //the Authorized OCSP responder certificate containing the id-kp-OCSPSigning extended key usage extension

    X509Certificate ocspRespSignerCertificate = null;

    //first check if CA issuing certificate signed the response
    //since it is expected to be the most common case
    if (basicOCSPResponse.isSignatureValid(
            new JcaContentVerifierProviderBuilder().setProvider("BC").build(cACert.getPublicKey()))) {
        ocspRespSignerCertificate = cACert;
    }
    //if CA did not sign the ocsp response, look for authorized ocsp responses from properties or from certificate chain received with response
    if (ocspRespSignerCertificate == null) {
        log.debug("OCSP Response is not signed by issuing CA. Looking for authorized responders");
        if (basicOCSPResponse.getCerts() == null) {
            log.debug(
                    "OCSP Response does not contain certificate chain, trying to verify response using one of configured authorized ocsp responders");

            //certificate chain is not present in response received 
            //try to verify using one of the configured AuthorizedOCSPResponderCerts
            ocspRespSignerCertificate = getAuthorizedOCSPRespondersCertificateFromProperties(basicOCSPResponse);

            if (ocspRespSignerCertificate == null) {
                throw new SignServerException(
                        "OCSP Response does not contain certificate chain, and response is not signed by any of the configured Authorized OCSP Responders or CA issuing certificate.");
            }
        } else {
            //look for existence of Authorized OCSP responder inside the cert chain in ocsp response
            ocspRespSignerCertificate = getAuthorizedOCSPRespondersCertificateFromOCSPResponse(
                    basicOCSPResponse);

            //could not find the certificate signing the OCSP response in the ocsp response
            if (ocspRespSignerCertificate == null) {
                throw new SignServerException(
                        "Certificate signing the ocsp response is not found in ocsp response's certificate chain received and is not signed by CA issuing certificate");
            }
        }
    }

    log.debug("OCSP response signed by :  " + CertTools.getSubjectDN(ocspRespSignerCertificate));
    // validating ocsp signers certificate
    // Check if responders certificate has id-pkix-ocsp-nocheck extension, in which case we do not validate (perform revocation check on ) ocsp certs for lifetime of certificate
    // using CRL RFC 2560 sect 4.2.2.2.1
    // TODO : RFC States the extension value should be NULL, so maybe bare existence of the extension is not sufficient ??
    if (ocspRespSignerCertificate
            .getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId()) != null) {
        //check if lifetime of certificate is ok
        try {
            ocspRespSignerCertificate.checkValidity();
        } catch (CertificateExpiredException e) {
            throw new SignServerException(
                    "Certificate signing the ocsp response has expired. OCSP Responder Certificate Subject DN : "
                            + CertTools.getSubjectDN(ocspRespSignerCertificate));
        } catch (CertificateNotYetValidException e) {
            throw new SignServerException(
                    "Certificate signing the ocsp response is not yet valid. OCSP Responder Certificate Subject DN : "
                            + CertTools.getSubjectDN(ocspRespSignerCertificate));
        }
    } else {
        // check if CDP exists in ocsp signers certificate
        // TODO : ?? add property for issuer whether to accept the OCSP response if the CDPs are not available (or use preconfigured CRLs) on signing certificate CRL RFC 2560 sect 4.2.2.2.1
        if (CertTools.getCrlDistributionPoint(ocspRespSignerCertificate) == null) {
            throw new SignServerException(
                    "CRL Distribution Point extension missing in ocsp signer's certificate.");
        }

        //verify certificate using CRL Validator
        //TODO : refactor Validators to follow factory pattern (discuss)
        CRLValidator crlValidator = new CRLValidator();
        Validation valresult = crlValidator.validate(ocspRespSignerCertificate, this.props);
        if (valresult.getStatus() != Validation.Status.VALID) {
            throw new SignServerException(
                    "Validation of ocsp signer's certificate failed. Status message received : "
                            + valresult.getStatusMessage());
        }
    }

    //get the response we requested for 
    for (SingleResp singleResponse : basicOCSPResponse.getResponses()) {
        if (singleResponse.getCertID().getSerialNumber().equals(x509Cert.getSerialNumber())) {
            //found our response
            //check if response is OK, and if not throw OCSPStatusNotGoodException
            if (singleResponse.getCertStatus() != null) {
                throw new OCSPStatusNotGoodException(
                        "Responce for queried certificate is not good. Certificate status returned : "
                                + singleResponse.getCertStatus(),
                        singleResponse.getCertStatus());
            }
            //check the dates ThisUpdate and NextUpdate RFC 2560 sect : 4.2.2.1
            if (singleResponse.getNextUpdate() != null
                    && (new Date()).compareTo(singleResponse.getNextUpdate()) >= 0) {
                throw new SignServerException(
                        "Unreliable response received. Response reported a nextupdate as : "
                                + singleResponse.getNextUpdate().toString()
                                + " which is earlier than current date.");
            }
            if (singleResponse.getThisUpdate() != null
                    && (new Date()).compareTo(singleResponse.getThisUpdate()) <= 0) {
                throw new SignServerException(
                        "Unreliable response received. Response reported a thisupdate as : "
                                + singleResponse.getThisUpdate().toString()
                                + " which is earlier than current date.");
            }

            break;
        }
    }

}

From source file:org.xdi.oxauth.cert.validation.OCSPCertificateVerifier.java

License:MIT License

@Override
public ValidationStatus validate(X509Certificate certificate, List<X509Certificate> issuers,
        Date validationDate) {/*from   w  ww .j av a2 s  .  c o m*/
    X509Certificate issuer = issuers.get(0);
    ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate,
            ValidatorSourceType.OCSP, CertificateValidity.UNKNOWN);

    try {
        Principal subjectX500Principal = certificate.getSubjectX500Principal();

        String ocspUrl = getOCSPUrl(certificate);
        if (ocspUrl == null) {
            log.error("OCSP URL for '" + subjectX500Principal + "' is empty");
            return status;
        }

        log.debug("OCSP URL for '" + subjectX500Principal + "' is '" + ocspUrl + "'");

        DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build()
                .get(CertificateID.HASH_SHA1);
        CertificateID certificateId = new CertificateID(digestCalculator,
                new JcaX509CertificateHolder(certificate), certificate.getSerialNumber());

        // Generate OCSP request
        OCSPReq ocspReq = generateOCSPRequest(certificateId);

        // Get OCSP response from server
        OCSPResp ocspResp = requestOCSPResponse(ocspUrl, ocspReq);
        if (ocspResp.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
            log.error("OCSP response is invalid!");
            status.setValidity(CertificateValidity.INVALID);
            return status;
        }

        boolean foundResponse = false;
        BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResp.getResponseObject();
        SingleResp[] singleResps = basicOCSPResp.getResponses();
        for (SingleResp singleResp : singleResps) {
            CertificateID responseCertificateId = singleResp.getCertID();
            if (!certificateId.equals(responseCertificateId)) {
                continue;
            }

            foundResponse = true;

            log.debug("OCSP validationDate: " + validationDate);
            log.debug("OCSP thisUpdate: " + singleResp.getThisUpdate());
            log.debug("OCSP nextUpdate: " + singleResp.getNextUpdate());

            status.setRevocationObjectIssuingTime(basicOCSPResp.getProducedAt());

            Object certStatus = singleResp.getCertStatus();
            if (certStatus == CertificateStatus.GOOD) {
                log.debug("OCSP status is valid for '" + certificate.getSubjectX500Principal() + "'");
                status.setValidity(CertificateValidity.VALID);
            } else {
                if (singleResp.getCertStatus() instanceof RevokedStatus) {
                    log.warn("OCSP status is revoked for: " + subjectX500Principal);
                    if (validationDate
                            .before(((RevokedStatus) singleResp.getCertStatus()).getRevocationTime())) {
                        log.warn("OCSP revocation time after the validation date, the certificate '"
                                + subjectX500Principal + "' was valid at " + validationDate);
                        status.setValidity(CertificateValidity.VALID);
                    } else {
                        Date revocationDate = ((RevokedStatus) singleResp.getCertStatus()).getRevocationTime();
                        log.info("OCSP for certificate '" + subjectX500Principal + "' is revoked since "
                                + revocationDate);
                        status.setRevocationDate(revocationDate);
                        status.setRevocationObjectIssuingTime(singleResp.getThisUpdate());
                        status.setValidity(CertificateValidity.REVOKED);
                    }
                }
            }
        }

        if (!foundResponse) {
            log.error("There is no matching OCSP response entries");
        }
    } catch (Exception ex) {
        log.error("OCSP exception: ", ex);
    }

    return status;
}