Example usage for org.bouncycastle.cert.ocsp OCSPReq getCriticalExtensionOIDs

List of usage examples for org.bouncycastle.cert.ocsp OCSPReq getCriticalExtensionOIDs

Introduction

In this page you can find the example usage for org.bouncycastle.cert.ocsp OCSPReq getCriticalExtensionOIDs.

Prototype

public Set getCriticalExtensionOIDs() 

Source Link

Usage

From source file:org.xipki.ocsp.server.impl.OcspServer.java

License:Open Source License

public OcspRespWithCacheInfo answer(final Responder responder, final OCSPReq request,
        final AuditEvent auditEvent, final boolean viaGet) {
    ResponderOption responderOption = responder.getResponderOption();
    RequestOption requestOption = responder.getRequestOption();
    ResponseOption responseOption = responder.getResponseOption();
    ResponderSigner signer = responder.getSigner();
    AuditOption auditOption = responder.getAuditOption();
    CertprofileOption certprofileOption = responder.getCertprofileOption();

    int version = request.getVersionNumber();
    if (requestOption.isVersionAllowed(version) == false) {
        String message = "invalid request version " + version;
        LOG.warn(message);//  ww w.  j  av a 2 s.com
        if (auditEvent != null) {
            fillAuditEvent(auditEvent, AuditLevel.INFO, AuditStatus.FAILED, message);
        }
        return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest);
    }

    try {
        OcspRespWithCacheInfo resp = checkSignature(request, requestOption, auditEvent);
        if (resp != null) {
            return resp;
        }

        boolean couldCacheInfo = viaGet;

        List<Extension> responseExtensions = new ArrayList<>(2);

        Req[] requestList = request.getRequestList();
        int n = requestList.length;

        Set<ASN1ObjectIdentifier> criticalExtensionOIDs = new HashSet<>();
        Set<?> tmp = request.getCriticalExtensionOIDs();
        if (tmp != null) {
            for (Object oid : tmp) {
                criticalExtensionOIDs.add((ASN1ObjectIdentifier) oid);
            }
        }

        RespID respID = new RespID(signer.getResponderId());
        BasicOCSPRespBuilder basicOcspBuilder = new BasicOCSPRespBuilder(respID);
        ASN1ObjectIdentifier extensionType = OCSPObjectIdentifiers.id_pkix_ocsp_nonce;
        criticalExtensionOIDs.remove(extensionType);
        Extension nonceExtn = request.getExtension(extensionType);
        if (nonceExtn != null) {
            byte[] nonce = nonceExtn.getExtnValue().getOctets();
            int len = nonce.length;
            int min = requestOption.getNonceMinLen();
            int max = requestOption.getNonceMaxLen();

            if (len < min || len > max) {
                LOG.warn("length of nonce {} not within [{},{}]", new Object[] { len, min, max });
                if (auditEvent != null) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("length of nonce ").append(len);
                    sb.append(" not within [").append(min).append(", ").append(max);
                    fillAuditEvent(auditEvent, AuditLevel.INFO, AuditStatus.FAILED, sb.toString());
                }
                return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest);
            }

            couldCacheInfo = false;
            responseExtensions.add(nonceExtn);
        } else if (requestOption.isNonceRequired()) {
            String message = "nonce required, but is not present in the request";
            LOG.warn(message);
            if (auditEvent != null) {
                fillAuditEvent(auditEvent, AuditLevel.INFO, AuditStatus.FAILED, message);
            }
            return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest);
        }

        boolean includeExtendedRevokeExtension = false;

        long cacheThisUpdate = 0;
        long cacheNextUpdate = Long.MAX_VALUE;
        for (int i = 0; i < n; i++) {
            AuditChildEvent childAuditEvent = null;
            if (auditEvent != null) {
                childAuditEvent = new AuditChildEvent();
                auditEvent.addChildAuditEvent(childAuditEvent);
            }

            Req req = requestList[i];
            CertificateID certID = req.getCertID();
            String certIdHashAlgo = certID.getHashAlgOID().getId();
            HashAlgoType reqHashAlgo = HashAlgoType.getHashAlgoType(certIdHashAlgo);
            if (reqHashAlgo == null) {
                LOG.warn("unknown CertID.hashAlgorithm {}", certIdHashAlgo);
                if (childAuditEvent != null) {
                    fillAuditEvent(childAuditEvent, AuditLevel.INFO, AuditStatus.FAILED,
                            "unknown CertID.hashAlgorithm " + certIdHashAlgo);
                }
                return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest);
            } else if (requestOption.allows(reqHashAlgo) == false) {
                LOG.warn("CertID.hashAlgorithm {} not allowed", certIdHashAlgo);
                if (childAuditEvent != null) {
                    fillAuditEvent(childAuditEvent, AuditLevel.INFO, AuditStatus.FAILED,
                            "CertID.hashAlgorithm " + certIdHashAlgo + " not allowed");
                }
                return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest);
            }

            CertStatusInfo certStatusInfo = null;
            CertStatusStore answeredStore = null;
            boolean exceptionOccurs = false;

            for (CertStatusStore store : responder.getStores()) {
                try {
                    certStatusInfo = store.getCertStatus(reqHashAlgo, certID.getIssuerNameHash(),
                            certID.getIssuerKeyHash(), certID.getSerialNumber(),
                            responseOption.isIncludeCerthash(), responseOption.getCertHashAlgo(),
                            certprofileOption);
                    if (certStatusInfo.getCertStatus() != CertStatus.ISSUER_UNKNOWN) {
                        answeredStore = store;
                        break;
                    }
                } catch (CertStatusStoreException e) {
                    exceptionOccurs = true;
                    final String message = "getCertStatus() of CertStatusStore " + store.getName();
                    if (LOG.isErrorEnabled()) {
                        LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(),
                                e.getMessage());
                    }
                    LOG.debug(message, e);
                }
            }

            if (certStatusInfo == null) {
                if (childAuditEvent != null) {
                    fillAuditEvent(childAuditEvent, AuditLevel.ERROR, AuditStatus.FAILED,
                            "no CertStatusStore can answer the request");
                }
                if (exceptionOccurs) {
                    return createUnsuccessfullOCSPResp(OcspResponseStatus.tryLater);
                } else {
                    certStatusInfo = CertStatusInfo.getIssuerUnknownCertStatusInfo(new Date(), null);
                }
            } else if (answeredStore != null) {
                if (responderOption.isInheritCaRevocation()) {
                    CertRevocationInfo caRevInfo = answeredStore.getCARevocationInfo(reqHashAlgo,
                            certID.getIssuerNameHash(), certID.getIssuerKeyHash());
                    if (caRevInfo != null) {
                        CertStatus certStatus = certStatusInfo.getCertStatus();
                        boolean replaced = false;
                        if (certStatus == CertStatus.GOOD || certStatus == CertStatus.UNKNOWN) {
                            replaced = true;
                        } else if (certStatus == CertStatus.REVOKED) {
                            if (certStatusInfo.getRevocationInfo().getRevocationTime()
                                    .after(caRevInfo.getRevocationTime())) {
                                replaced = true;
                            }
                        }

                        if (replaced) {
                            CertRevocationInfo newRevInfo;
                            if (caRevInfo.getReason() == CRLReason.CA_COMPROMISE) {
                                newRevInfo = caRevInfo;
                            } else {
                                newRevInfo = new CertRevocationInfo(CRLReason.CA_COMPROMISE,
                                        caRevInfo.getRevocationTime(), caRevInfo.getInvalidityTime());
                            }
                            certStatusInfo = CertStatusInfo.getRevokedCertStatusInfo(newRevInfo,
                                    certStatusInfo.getCertHashAlgo(), certStatusInfo.getCertHash(),
                                    certStatusInfo.getThisUpdate(), certStatusInfo.getNextUpdate(),
                                    certStatusInfo.getCertprofile());
                        }
                    }
                }
            }

            if (childAuditEvent != null) {
                String certprofile = certStatusInfo.getCertprofile();
                String auditCertType;
                if (certprofile != null) {
                    auditCertType = auditOption.getCertprofileMapping().get(certprofile);
                    if (auditCertType == null) {
                        auditCertType = certprofile;
                    }
                } else {
                    auditCertType = "UNKNOWN";
                }

                childAuditEvent.addEventData(new AuditEventData("certType", auditCertType));
            }

            // certStatusInfo could not be null in any case, since at least one store is configured
            Date thisUpdate = certStatusInfo.getThisUpdate();
            if (thisUpdate == null) {
                thisUpdate = new Date();
            }
            Date nextUpdate = certStatusInfo.getNextUpdate();

            List<Extension> extensions = new LinkedList<>();
            boolean unknownAsRevoked = false;
            CertificateStatus bcCertStatus = null;
            switch (certStatusInfo.getCertStatus()) {
            case GOOD:
                bcCertStatus = null;
                break;

            case ISSUER_UNKNOWN:
                couldCacheInfo = false;
                bcCertStatus = new UnknownStatus();
                break;

            case UNKNOWN:
            case IGNORE:
                couldCacheInfo = false;
                if (responderOption.getMode() == OCSPMode.RFC2560) {
                    bcCertStatus = new UnknownStatus();
                } else// (ocspMode == OCSPMode.RFC6960)
                {
                    unknownAsRevoked = true;
                    includeExtendedRevokeExtension = true;
                    bcCertStatus = new RevokedStatus(new Date(0L), CRLReason.CERTIFICATE_HOLD.getCode());
                }
                break;
            case REVOKED:
                CertRevocationInfo revInfo = certStatusInfo.getRevocationInfo();
                ASN1GeneralizedTime revTime = new ASN1GeneralizedTime(revInfo.getRevocationTime());
                org.bouncycastle.asn1.x509.CRLReason _reason = null;
                if (responseOption.isIncludeRevReason()) {
                    _reason = org.bouncycastle.asn1.x509.CRLReason.lookup(revInfo.getReason().getCode());
                }
                RevokedInfo _revInfo = new RevokedInfo(revTime, _reason);
                bcCertStatus = new RevokedStatus(_revInfo);

                Date invalidityDate = revInfo.getInvalidityTime();
                if (responseOption.isIncludeInvalidityDate() && invalidityDate != null
                        && invalidityDate.equals(revTime) == false) {
                    Extension extension = new Extension(Extension.invalidityDate, false,
                            new ASN1GeneralizedTime(invalidityDate).getEncoded());
                    extensions.add(extension);
                }
                break;
            }

            byte[] certHash = certStatusInfo.getCertHash();
            if (certHash != null) {
                ASN1ObjectIdentifier hashAlgoOid = new ASN1ObjectIdentifier(
                        certStatusInfo.getCertHashAlgo().getOid());
                AlgorithmIdentifier aId = new AlgorithmIdentifier(hashAlgoOid, DERNull.INSTANCE);
                CertHash bcCertHash = new CertHash(aId, certHash);

                byte[] encodedCertHash;
                try {
                    encodedCertHash = bcCertHash.getEncoded();
                } catch (IOException e) {
                    final String message = "answer() bcCertHash.getEncoded";
                    if (LOG.isErrorEnabled()) {
                        LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(),
                                e.getMessage());
                    }
                    LOG.debug(message, e);
                    if (childAuditEvent != null) {
                        fillAuditEvent(childAuditEvent, AuditLevel.ERROR, AuditStatus.FAILED,
                                "CertHash.getEncoded() with IOException");
                    }
                    return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError);
                }

                Extension extension = new Extension(ISISMTTObjectIdentifiers.id_isismtt_at_certHash, false,
                        encodedCertHash);

                extensions.add(extension);
            }

            if (certStatusInfo.getArchiveCutOff() != null) {
                Extension extension = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_archive_cutoff, false,
                        new ASN1GeneralizedTime(certStatusInfo.getArchiveCutOff()).getEncoded());
                extensions.add(extension);
            }

            String certStatusText;
            if (bcCertStatus instanceof UnknownStatus) {
                certStatusText = "unknown";
            } else if (bcCertStatus instanceof RevokedStatus) {
                certStatusText = unknownAsRevoked ? "unknown_as_revoked" : "revoked";
            } else if (bcCertStatus == null) {
                certStatusText = "good";
            } else {
                certStatusText = "should-not-happen";
            }

            if (childAuditEvent != null) {
                childAuditEvent.setLevel(AuditLevel.INFO);
                childAuditEvent.setStatus(AuditStatus.SUCCESSFUL);
                childAuditEvent.addEventData(new AuditEventData("certStatus", certStatusText));
            }

            if (LOG.isDebugEnabled()) {
                StringBuilder sb = new StringBuilder();
                sb.append("certHashAlgo: ").append(certID.getHashAlgOID().getId()).append(", ");

                String hexCertHash = null;
                if (certHash != null) {
                    hexCertHash = Hex.toHexString(certHash).toUpperCase();
                }

                sb.append("issuerKeyHash: ").append(Hex.toHexString(certID.getIssuerKeyHash()).toUpperCase())
                        .append(", ");
                sb.append("issuerNameHash: ").append(Hex.toHexString(certID.getIssuerNameHash()).toUpperCase())
                        .append(", ");
                sb.append("serialNumber: ").append(certID.getSerialNumber()).append(", ");
                sb.append("certStatus: ").append(certStatusText).append(", ");
                sb.append("thisUpdate: ").append(thisUpdate).append(", ");
                sb.append("nextUpdate: ").append(nextUpdate).append(", ");
                sb.append("certHash: ").append(hexCertHash);
                LOG.debug(sb.toString());
            }

            basicOcspBuilder.addResponse(certID, bcCertStatus, thisUpdate, nextUpdate,
                    CollectionUtil.isEmpty(extensions) ? null
                            : new Extensions(extensions.toArray(new Extension[0])));
            cacheThisUpdate = Math.max(cacheThisUpdate, thisUpdate.getTime());
            if (nextUpdate != null) {
                cacheNextUpdate = Math.min(cacheNextUpdate, nextUpdate.getTime());
            }
        }

        if (includeExtendedRevokeExtension) {
            responseExtensions.add(new Extension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke, true,
                    DERNull.INSTANCE.getEncoded()));
        }

        if (CollectionUtil.isNotEmpty(responseExtensions)) {
            basicOcspBuilder
                    .setResponseExtensions(new Extensions(responseExtensions.toArray(new Extension[0])));
        }

        ConcurrentContentSigner concurrentSigner = null;
        if (responderOption.getMode() != OCSPMode.RFC2560) {
            extensionType = ObjectIdentifiers.id_pkix_ocsp_prefSigAlgs;
            criticalExtensionOIDs.remove(extensionType);
            Extension ext = request.getExtension(extensionType);
            if (ext != null) {
                ASN1Sequence preferredSigAlgs = ASN1Sequence.getInstance(ext.getParsedValue());
                concurrentSigner = signer.getSignerForPreferredSigAlgs(preferredSigAlgs);
            }
        }

        if (CollectionUtil.isNotEmpty(criticalExtensionOIDs)) {
            return createUnsuccessfullOCSPResp(OcspResponseStatus.malformedRequest);
        }

        if (concurrentSigner == null) {
            concurrentSigner = signer.getFirstSigner();
        }

        ContentSigner singleSigner;
        try {
            singleSigner = concurrentSigner.borrowContentSigner();
        } catch (NoIdleSignerException e) {
            return createUnsuccessfullOCSPResp(OcspResponseStatus.tryLater);
        }

        X509CertificateHolder[] certsInResp;
        EmbedCertsMode certsMode = responseOption.getEmbedCertsMode();
        if (certsMode == null || certsMode == EmbedCertsMode.SIGNER) {
            certsInResp = new X509CertificateHolder[] { signer.getBcCertificate() };
        } else if (certsMode == EmbedCertsMode.SIGNER_AND_CA) {
            certsInResp = signer.getBcCertificateChain();
        } else {
            // NONE
            certsInResp = null;
        }

        BasicOCSPResp basicOcspResp;
        try {
            basicOcspResp = basicOcspBuilder.build(singleSigner, certsInResp, new Date());
        } catch (OCSPException e) {
            final String message = "answer() basicOcspBuilder.build";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
            }
            LOG.debug(message, e);
            if (auditEvent != null) {
                fillAuditEvent(auditEvent, AuditLevel.ERROR, AuditStatus.FAILED,
                        "BasicOCSPRespBuilder.build() with OCSPException");
            }
            return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError);
        } finally {
            concurrentSigner.returnContentSigner(singleSigner);
        }

        OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder();
        try {
            OCSPResp ocspResp = ocspRespBuilder.build(OcspResponseStatus.successfull.getStatus(),
                    basicOcspResp);

            if (couldCacheInfo) {
                ResponseCacheInfo cacheInfo = new ResponseCacheInfo(cacheThisUpdate);
                if (cacheNextUpdate != Long.MAX_VALUE) {
                    cacheInfo.setNextUpdate(cacheNextUpdate);
                }
                return new OcspRespWithCacheInfo(ocspResp, cacheInfo);
            } else {
                return new OcspRespWithCacheInfo(ocspResp, null);
            }
        } catch (OCSPException e) {
            final String message = "answer() ocspRespBuilder.build";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
            }
            LOG.debug(message, e);
            if (auditEvent != null) {
                fillAuditEvent(auditEvent, AuditLevel.ERROR, AuditStatus.FAILED,
                        "OCSPRespBuilder.build() with OCSPException");
            }
            return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError);
        }

    } catch (Throwable t) {
        final String message = "Throwable";
        if (LOG.isErrorEnabled()) {
            LOG.error(LogUtil.buildExceptionLogFormat(message), t.getClass().getName(), t.getMessage());
        }
        LOG.debug(message, t);

        if (auditEvent != null) {
            fillAuditEvent(auditEvent, AuditLevel.ERROR, AuditStatus.FAILED, "internal error");
        }

        return createUnsuccessfullOCSPResp(OcspResponseStatus.internalError);
    }
}

From source file:org.xipki.pki.ocsp.server.impl.OcspServer.java

License:Open Source License

public OcspRespWithCacheInfo answer(final Responder responder, final OCSPReq request, final boolean viaGet,
        final AuditEvent event) {
    ParamUtil.requireNonNull("responder", responder);
    ParamUtil.requireNonNull("request", request);

    RequestOption reqOpt = responder.getRequestOption();
    ResponderSigner signer = responder.getSigner();
    ResponseOption repOpt = responder.getResponseOption();

    String msgId = null;//w  w w .  jav a  2s . co m
    if (event != null) {
        msgId = RandomUtil.nextHexLong();
        event.addEventData(OcspAuditConstants.NAME_mid, msgId);
    }

    int version = request.getVersionNumber();
    if (!reqOpt.isVersionAllowed(version)) {
        String message = "invalid request version " + version;
        LOG.warn(message);
        fillAuditEvent(event, AuditLevel.INFO, AuditStatus.FAILED, message);
        return createUnsuccessfulOcspResp(OcspResponseStatus.malformedRequest);
    }

    try {
        OcspRespWithCacheInfo resp = checkSignature(request, reqOpt, event);
        if (resp != null) {
            return resp;
        }

        OcspRespControl repControl = new OcspRespControl();
        repControl.couldCacheInfo = viaGet;

        List<Extension> responseExtensions = new ArrayList<>(2);

        Req[] requestList = request.getRequestList();
        // CHECKSTYLE:SKIP
        int requestsSize = requestList.length;

        Set<ASN1ObjectIdentifier> criticalExtensionOids = new HashSet<>();
        Set<?> tmp = request.getCriticalExtensionOIDs();
        if (tmp != null) {
            for (Object oid : tmp) {
                criticalExtensionOids.add((ASN1ObjectIdentifier) oid);
            }
        }

        RespID respId = signer.getResponder(repOpt.isResponderIdByName());
        BasicOCSPRespBuilder basicOcspBuilder = new BasicOCSPRespBuilder(respId);
        ASN1ObjectIdentifier extensionType = OCSPObjectIdentifiers.id_pkix_ocsp_nonce;
        criticalExtensionOids.remove(extensionType);
        Extension nonceExtn = request.getExtension(extensionType);
        if (nonceExtn != null) {
            byte[] nonce = nonceExtn.getExtnValue().getOctets();
            int len = nonce.length;
            int min = reqOpt.getNonceMinLen();
            int max = reqOpt.getNonceMaxLen();

            if (len < min || len > max) {
                LOG.warn("length of nonce {} not within [{},{}]", len, min, max);
                StringBuilder sb = new StringBuilder(50);
                sb.append("length of nonce ").append(len);
                sb.append(" not within [").append(min).append(", ").append(max).append("]");
                fillAuditEvent(event, AuditLevel.INFO, AuditStatus.FAILED, sb.toString());
                return createUnsuccessfulOcspResp(OcspResponseStatus.malformedRequest);
            }

            repControl.couldCacheInfo = false;
            responseExtensions.add(nonceExtn);
        } else if (reqOpt.isNonceRequired()) {
            String message = "nonce required, but is not present in the request";
            LOG.warn(message);
            fillAuditEvent(event, AuditLevel.INFO, AuditStatus.FAILED, message);
            return createUnsuccessfulOcspResp(OcspResponseStatus.malformedRequest);
        }

        for (int i = 0; i < requestsSize; i++) {
            AuditEvent singleEvent = null;
            if (event != null) {
                singleEvent = new AuditEvent(new Date());
                singleEvent.setApplicationName(OcspAuditConstants.APPNAME);
                singleEvent.setName(OcspAuditConstants.NAME_PERF);
                singleEvent.addEventData(OcspAuditConstants.NAME_mid, msgId);
            }

            OcspRespWithCacheInfo ocspResp = null;
            try {
                ocspResp = processCertReq(requestList[i], basicOcspBuilder, responder, reqOpt, repOpt,
                        repControl, singleEvent);
            } finally {
                if (singleEvent != null) {
                    singleEvent.finish();
                    auditServiceRegister.getAuditService().doLogEvent(singleEvent);
                }
            }

            if (ocspResp != null) {
                return ocspResp;
            }
        }

        if (repControl.includeExtendedRevokeExtension) {
            responseExtensions.add(new Extension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke, true,
                    Arrays.copyOf(DERNullBytes, DERNullBytes.length)));
        }

        if (CollectionUtil.isNonEmpty(responseExtensions)) {
            basicOcspBuilder
                    .setResponseExtensions(new Extensions(responseExtensions.toArray(new Extension[0])));
        }

        ConcurrentContentSigner concurrentSigner = null;
        if (responder.getResponderOption().getMode() != OcspMode.RFC2560) {
            extensionType = ObjectIdentifiers.id_pkix_ocsp_prefSigAlgs;
            criticalExtensionOids.remove(extensionType);
            Extension ext = request.getExtension(extensionType);
            if (ext != null) {
                ASN1Sequence preferredSigAlgs = ASN1Sequence.getInstance(ext.getParsedValue());
                concurrentSigner = signer.getSignerForPreferredSigAlgs(preferredSigAlgs);
            }
        }

        if (CollectionUtil.isNonEmpty(criticalExtensionOids)) {
            return createUnsuccessfulOcspResp(OcspResponseStatus.malformedRequest);
        }

        if (concurrentSigner == null) {
            concurrentSigner = signer.getFirstSigner();
        }

        X509CertificateHolder[] certsInResp;
        EmbedCertsMode certsMode = repOpt.getEmbedCertsMode();
        if (certsMode == null || certsMode == EmbedCertsMode.SIGNER) {
            certsInResp = new X509CertificateHolder[] { signer.getBcCertificate() };
        } else if (certsMode == EmbedCertsMode.SIGNER_AND_CA) {
            certsInResp = signer.getBcCertificateChain();
        } else {
            // NONE
            certsInResp = null;
        }

        BasicOCSPResp basicOcspResp;
        try {
            basicOcspResp = concurrentSigner.build(basicOcspBuilder, certsInResp, new Date());
        } catch (NoIdleSignerException ex) {
            return createUnsuccessfulOcspResp(OcspResponseStatus.tryLater);
        } catch (OCSPException ex) {
            LogUtil.error(LOG, ex, "answer() basicOcspBuilder.build");
            fillAuditEvent(event, AuditLevel.ERROR, AuditStatus.FAILED,
                    "BasicOCSPRespBuilder.build() with OCSPException");
            return createUnsuccessfulOcspResp(OcspResponseStatus.internalError);
        }

        OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder();
        try {
            OCSPResp ocspResp = ocspRespBuilder.build(OcspResponseStatus.successful.getStatus(), basicOcspResp);

            if (repControl.couldCacheInfo) {
                ResponseCacheInfo cacheInfo = new ResponseCacheInfo(repControl.cacheThisUpdate);
                if (repControl.cacheNextUpdate != Long.MAX_VALUE) {
                    cacheInfo.setNextUpdate(repControl.cacheNextUpdate);
                }
                return new OcspRespWithCacheInfo(ocspResp, cacheInfo);
            } else {
                return new OcspRespWithCacheInfo(ocspResp, null);
            }
        } catch (OCSPException ex) {
            LogUtil.error(LOG, ex, "answer() ocspRespBuilder.build");
            fillAuditEvent(event, AuditLevel.ERROR, AuditStatus.FAILED,
                    "OCSPRespBuilder.build() with OCSPException");
            return createUnsuccessfulOcspResp(OcspResponseStatus.internalError);
        }
    } catch (Throwable th) {
        LogUtil.error(LOG, th);
        fillAuditEvent(event, AuditLevel.ERROR, AuditStatus.FAILED, "internal error");
        return createUnsuccessfulOcspResp(OcspResponseStatus.internalError);
    }
}