Example usage for org.bouncycastle.asn1.x509 CRLReason CRLReason

List of usage examples for org.bouncycastle.asn1.x509 CRLReason CRLReason

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.x509 CRLReason CRLReason.

Prototype

private CRLReason(int reason) 

Source Link

Usage

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

License:Open Source License

@Override
public RevocationToken check(final CertificateToken toCheckToken) {

    String crlUri = null;/* ww w .j av  a2 s.co  m*/
    try {

        if (crlSource == null) {

            toCheckToken.extraInfo().infoCRLSourceIsNull();
            return null;
        }
        final X509Certificate toCheckCert = toCheckToken.getCertificate();
        final X509Certificate issuerCert = toCheckToken.getIssuerToken().getCertificate();
        final X509CRL x509crl = crlSource.findCrl(toCheckCert, issuerCert);
        if (crlSource instanceof OnlineCRLSource) {

            crlUri = ((OnlineCRLSource) crlSource).getCrlUri(toCheckCert);
        }
        if (x509crl == null) {

            if (LOG.isLoggable(Level.INFO)) {
                LOG.info("No CRL found for " + toCheckToken.getDSSIdAsString());
            }
            if (crlSource instanceof OnlineCRLSource) {

                toCheckToken.extraInfo().infoNoCRLInfoFound(crlUri);
            }
            return null;
        }
        final CRLToken crlToken = new CRLToken(x509crl);
        if (crlSource instanceof OnlineCRLSource) {

            crlToken.setSourceURI(crlUri);
        }
        if (!isCRLTokenValid(crlToken, toCheckToken.getIssuerToken())) {

            LOG.warning("The CRL is not valid !");
            toCheckToken.extraInfo().infoCRLIsNotValid();
            return null;
        }
        final X509CRLEntry crlEntry = x509crl.getRevokedCertificate(toCheckCert.getSerialNumber());
        if (null == crlEntry) {

            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("CRL OK for: " + toCheckToken.getDSSIdAsString());
            }
            /*
             * If there is no entry in the CRL, the certificate is more likely to be valid
             */
            crlToken.setStatus(true);
        } else {

            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("CRL reports certificate: " + toCheckToken.getDSSIdAsString() + " as revoked since "
                        + crlEntry.getRevocationDate());
            }
            crlToken.setStatus(false);
            crlToken.setRevocationDate(crlEntry.getRevocationDate());
            final byte[] extensionBytes = crlEntry.getExtensionValue(X509Extension.reasonCode.getId());
            ASN1InputStream dIn = null;
            try {

                dIn = new ASN1InputStream(extensionBytes);
                CRLReason reason = new CRLReason(DEREnumerated.getInstance(dIn.readObject()));
                crlToken.setReason(reason.toString());
            } catch (IllegalArgumentException e) {
                // In the test case XAdESTest003 testTRevoked() there is an error in the revocation reason.
                LOG.warning("Error when revocation reason decoding from CRL: " + e.toString());
                crlToken.setReason(new CRLReason(7).toString()); // unknown
            } finally {

                DSSUtils.closeQuietly(dIn);
            }
        }
        toCheckToken.setRevocationToken(crlToken);
        return crlToken;
    } catch (final Exception e) {

        LOG.log(Level.SEVERE, "Exception when accessing CRL for " + toCheckToken.getDSSIdAsString(), e);
        toCheckToken.extraInfo().infoCRLException(crlUri, e);
        return null;
    }
}

From source file:org.candlepin.util.X509CRLStreamWriter.java

License:Open Source License

/**
 * Create an entry to be added to the CRL.
 *
 * @param serial//from w w  w  .j  ava  2s .  c o m
 * @param date
 * @param reason
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public void add(BigInteger serial, Date date, int reason) {
    if (locked) {
        throw new IllegalStateException("Cannot add to a locked stream.");
    }

    ASN1EncodableVector v = new ASN1EncodableVector();

    v.add(new DERInteger(serial));
    v.add(new Time(date));

    CRLReason crlReason = new CRLReason(reason);
    Vector extOids = new Vector();
    Vector extValues = new Vector();
    extOids.addElement(X509Extension.reasonCode);
    extValues.addElement(new X509Extension(false, new DEROctetString(crlReason.getDEREncoded())));
    v.add(new X509Extensions(extOids, extValues));

    newEntries.add(new DERSequence(v));
}

From source file:org.cesecore.certificates.ocsp.CanLogCache.java

License:Open Source License

public byte[] getOcspResponse(AuthenticationToken authenticationToken, byte[] request,
        X509Certificate[] requestCertificates, String remoteAddress, String remoteHost)
        throws AuthorizationDeniedException, MalformedRequestException {
    initiateIfNecessary();/*w  w w .j  av  a2 s  . c  o m*/

    // Validate byte array.
    if (request.length > MAX_REQUEST_SIZE) {
        final String msg = intres.getLocalizedMessage("request.toolarge", MAX_REQUEST_SIZE, request.length);
        throw new MalformedRequestException(msg);
    }

    byte[] respBytes = null;

    final Date startTime = new Date();

    OCSPResp ocspResponse = null;

    int localTransactionId = TransactionCounter.INSTANCE.getTransactionNumber();
    // Create the transaction logger for this transaction.
    TransactionLogger transactionLogger = new TransactionLogger(localTransactionId,
            GuidHolder.INSTANCE.getGlobalUid(), remoteAddress);
    // Create the audit logger for this transaction.
    AuditLogger auditLogger = new AuditLogger("", localTransactionId, GuidHolder.INSTANCE.getGlobalUid(),
            remoteAddress);

    // Start logging process time after we have received the request
    transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
    auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
    auditLogger.paramPut(AuditLogger.OCSPREQUEST, new String(Hex.encode(request)));

    OCSPReq req;

    OCSPRespGenerator responseGenerator = new OCSPRespGenerator();

    try {
        try {
            req = translateRequestFromByteArray(request, remoteAddress, transactionLogger);

            // Get the certificate status requests that are inside this OCSP req
            Req[] ocspRequests = req.getRequestList();

            if (ocspRequests.length <= 0) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errornoreqentities");
                log.info(infoMsg);
                throw new MalformedRequestException(infoMsg);
            }
            int maxRequests = 100;
            if (ocspRequests.length > maxRequests) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errortoomanyreqentities", maxRequests);
                log.info(infoMsg);
                throw new MalformedRequestException(infoMsg);
            }

            if (log.isDebugEnabled()) {
                log.debug("The OCSP request contains " + ocspRequests.length + " simpleRequests.");
            }

            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);

            CryptoTokenAndChain signerTokenAndChain = null;

            long maxAge = OcspConfiguration.getMaxAge(CertificateProfileConstants.CERTPROFILE_NO_PROFILE);
            long nextUpdate = OcspConfiguration
                    .getUntilNextUpdate(CertificateProfileConstants.CERTPROFILE_NO_PROFILE);

            // Add standard response extensions
            Hashtable<DERObjectIdentifier, X509Extension> responseExtensions = getStandardResponseExtensions(
                    req);

            // Look for extension OIDs
            final Collection<String> extensionOids = OcspConfiguration.getExtensionOids();

            // Look over the status requests
            List<OCSPResponseItem> responseList = new ArrayList<OCSPResponseItem>();
            for (Req ocspRequest : ocspRequests) {
                CertificateID certId = ocspRequest.getCertID();

                transactionLogger.paramPut(TransactionLogger.SERIAL_NOHEX,
                        certId.getSerialNumber().toByteArray());
                // TODO:find text version of this or find out if it should be something else
                transactionLogger.paramPut(TransactionLogger.DIGEST_ALGOR, certId.getHashAlgOID());
                transactionLogger.paramPut(TransactionLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());
                transactionLogger.paramPut(TransactionLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(AuditLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(AuditLogger.SERIAL_NOHEX, certId.getSerialNumber().toByteArray());
                auditLogger.paramPut(AuditLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());

                byte[] hashbytes = certId.getIssuerNameHash();
                String hash = null;
                if (hashbytes != null) {
                    hash = new String(Hex.encode(hashbytes));
                }
                String infoMsg = intres.getLocalizedMessage("ocsp.inforeceivedrequest",
                        certId.getSerialNumber().toString(16), hash, remoteAddress);
                log.info(infoMsg);

                // Locate the CA which gave out the certificate
                signerTokenAndChain = getTokenAndChainCache().get(certId);
                /*
                 * if the certId was issued by an unknown CA 
                 * 
                 * The algorithm here: 
                 * We will sign the response with the CA that issued the last certificate(certId) in the request. If the issuing CA is not available on 
                 * this server, we sign the response with the default responderId (from params in web.xml). We have to look up the ca-certificate for 
                 * each certId in the request though, as we will check for revocation on the ca-cert as well when checking for revocation on the certId.
                 */

                if (signerTokenAndChain != null) {
                    transactionLogger.paramPut(TransactionLogger.ISSUER_NAME_DN,
                            signerTokenAndChain.getCaCertificate().getSubjectDN().getName());
                } else {
                    // We could not find certificate for this request so get certificate for default responder
                    signerTokenAndChain = getTokenAndChainCache().getForDefaultResponder();
                    if (signerTokenAndChain != null) {
                        String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacertusedefault",
                                new String(Hex.encode(certId.getIssuerNameHash())));
                        log.info(errMsg);
                        // If we can not find the CA, answer UnknowStatus
                        responseList.add(new OCSPResponseItem(certId, new UnknownStatus(), nextUpdate));
                        transactionLogger.paramPut(TransactionLogger.CERT_STATUS,
                                OCSPResponseItem.OCSP_UNKNOWN);
                        transactionLogger.writeln();
                        continue;
                    } else {
                        String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacert",
                                new String(Hex.encode(certId.getIssuerNameHash())),
                                OcspConfiguration.getDefaultResponderId());
                        log.error(errMsg);
                        continue;
                    }
                }

                /*
                 * Implement logic according to chapter 2.7 in RFC2560
                 * 
                 * 2.7 CA Key Compromise If an OCSP responder knows that a particular CA's private key has been compromised, it MAY return the revoked
                 * state for all certificates issued by that CA.
                 */
                final org.bouncycastle.ocsp.CertificateStatus certStatus;
                transactionLogger.paramPut(TransactionLogger.CERT_STATUS, OCSPResponseItem.OCSP_GOOD); // it seems to be correct

                // Check if the cacert (or the default responderid) is revoked
                final CertificateStatus signerIssuerCertStatus = certificateStoreSession.getStatus(
                        CertTools.getSubjectDN(signerTokenAndChain.getCaCertificate()),
                        CertTools.getSerialNumber(signerTokenAndChain.getCaCertificate()));

                String subjectDn = signerTokenAndChain.getCaCertificate().getSubjectDN().getName();
                if (!signerIssuerCertStatus.equals(CertificateStatus.REVOKED)) {

                    // Check if cert is revoked
                    final CertificateStatus status = certificateStoreSession.getStatus(subjectDn,
                            certId.getSerialNumber());

                    /* If we have different maxAge and untilNextUpdate for different certificate profiles, we have to fetch these
                     values now that we have fetched the certificate status, that includes certificate profile.*/
                    nextUpdate = OcspConfiguration.getUntilNextUpdate(status.certificateProfileId);
                    maxAge = OcspConfiguration.getMaxAge(status.certificateProfileId);
                    if (log.isDebugEnabled()) {
                        log.debug("Set nextUpdate=" + nextUpdate + ", and maxAge=" + maxAge
                                + " for certificateProfileId=" + status.certificateProfileId);
                    }

                    final String sStatus;
                    if (status.equals(CertificateStatus.NOT_AVAILABLE)) {
                        // No revocation info available for this cert, handle it
                        if (log.isDebugEnabled()) {
                            log.debug("Unable to find revocation information for certificate with serial '"
                                    + certId.getSerialNumber().toString(16) + "'" + " from issuer '" + subjectDn
                                    + "'");
                        }
                        /* 
                         * If we do not treat non existing certificates as good
                         * OR
                         * we don't actually handle requests for the CA issuing the certificate asked about
                         * then we return unknown 
                         * */
                        if ((!OcspConfiguration.getNonExistingIsGood())
                                || (getTokenAndChainCache().get(certId) == null)) {
                            sStatus = "unknown";
                            certStatus = new UnknownStatus();

                        } else {
                            sStatus = "good";
                            certStatus = null; // null means "good" in OCSP

                        }
                    } else if (status.equals(CertificateStatus.REVOKED)) {
                        // Revocation info available for this cert, handle it
                        sStatus = "revoked";
                        certStatus = new RevokedStatus(
                                new RevokedInfo(new DERGeneralizedTime(status.revocationDate),
                                        new CRLReason(status.revocationReason)));
                    } else {
                        sStatus = "good";
                        certStatus = null;

                    }
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", sStatus,
                            certId.getSerialNumber().toString(16), subjectDn);
                    log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));

                } else {
                    certStatus = new RevokedStatus(
                            new RevokedInfo(new DERGeneralizedTime(signerIssuerCertStatus.revocationDate),
                                    new CRLReason(signerIssuerCertStatus.revocationReason)));
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", "revoked",
                            certId.getSerialNumber().toString(16), subjectDn);
                    log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));

                }
                for (String oidstr : extensionOids) {
                    DERObjectIdentifier oid = new DERObjectIdentifier(oidstr);
                    X509Extensions reqexts = req.getRequestExtensions();
                    if (reqexts != null) {
                        X509Extension ext = reqexts.getExtension(oid);
                        if (null != ext) {
                            // We found an extension, call the extension class
                            if (log.isDebugEnabled()) {
                                log.debug("Found OCSP extension oid: " + oidstr);
                            }
                            OCSPExtension extObj = OcspExtensionsCache.INSTANCE.getExtensions().get(oidstr);
                            if (extObj != null) {
                                // Find the certificate from the certId
                                X509Certificate cert = null;
                                cert = (X509Certificate) certificateStoreSession
                                        .findCertificateByIssuerAndSerno(subjectDn, certId.getSerialNumber());
                                if (cert != null) {
                                    // Call the OCSP extension
                                    Map<DERObjectIdentifier, X509Extension> retext = extObj.process(
                                            requestCertificates, remoteAddress, remoteHost, cert, certStatus);
                                    if (retext != null) {
                                        // Add the returned X509Extensions to the responseExtension we will add to the basic OCSP response
                                        responseExtensions.putAll(retext);
                                    } else {
                                        String errMsg = intres.getLocalizedMessage("ocsp.errorprocessextension",
                                                extObj.getClass().getName(),
                                                Integer.valueOf(extObj.getLastErrorCode()));
                                        log.error(errMsg);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (signerTokenAndChain != null) {
                // Add responseExtensions
                X509Extensions exts = new X509Extensions(responseExtensions);
                // generate the signed response object

                final X509Certificate[] signerChain = signerTokenAndChain.getChain();
                final PrivateKey privateKey = signerTokenAndChain.getPrivateKey();
                final String privateKeyProvider = signerTokenAndChain.getSignProviderName();
                BasicOCSPResp basicresp = signOcspResponse(req, responseList, exts, signerChain, privateKey,
                        privateKeyProvider);
                ocspResponse = responseGenerator.generate(OCSPRespGenerator.SUCCESSFUL, basicresp);
                auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
                transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            } else {
                // Only unknown CAs in requests and no default responder's cert
                String errMsg = intres.getLocalizedMessage("ocsp.errornocacreateresp");
                log.error(errMsg);
                throw new OcspFailureException(errMsg);
            }
        } catch (MalformedRequestException e) {
            transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            log.info(errMsg);
            if (log.isDebugEnabled()) {
                log.debug(errMsg, e);
            }
            ocspResponse = responseGenerator.generate(OCSPRespGenerator.MALFORMED_REQUEST, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
            transactionLogger.writeln();
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
        } catch (SignRequestException e) {
            transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            log.info(errMsg); // No need to log the full exception here
            ocspResponse = responseGenerator.generate(OCSPRespGenerator.SIG_REQUIRED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
            transactionLogger.writeln();
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
        } catch (SignRequestSignatureException e) {
            transactionLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            auditLogger.paramPut(PatternLogger.PROCESS_TIME, PatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            log.info(errMsg); // No need to log the full exception here
            ocspResponse = responseGenerator.generate(OCSPRespGenerator.UNAUTHORIZED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(TransactionLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
            transactionLogger.writeln();
            auditLogger.paramPut(AuditLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
        } catch (NoSuchAlgorithmException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (CertificateException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (ExtendedCAServiceNotActiveException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (IllegalExtendedCAServiceRequestException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (ExtendedCAServiceRequestException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (CADoesntExistsException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (IllegalCryptoTokenException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        } catch (CryptoTokenOfflineException e) {
            ocspResponse = processDefaultError(responseGenerator, transactionLogger, auditLogger, e);
        }

        try {
            respBytes = ocspResponse.getEncoded();
            auditLogger.paramPut(AuditLogger.OCSPRESPONSE, new String(Hex.encode(respBytes)));
            auditLogger.writeln();
            auditLogger.flush();
            transactionLogger.flush();
            if (OcspConfiguration.getLogSafer()) {
                // See if the Errorhandler has found any problems
                if (hasErrorHandlerFailedSince(startTime)) {
                    log.info("ProbableErrorhandler reported error, cannot answer request");
                    ocspResponse = responseGenerator.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on
                                                                                                       // error.
                    respBytes = ocspResponse.getEncoded();
                }
                // See if the Appender has reported any problems
                if (!CanLogCache.INSTANCE.canLog()) {
                    log.info("SaferDailyRollingFileAppender reported error, cannot answer request");
                    ocspResponse = responseGenerator.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on
                                                                                                       // error.
                    respBytes = ocspResponse.getEncoded();
                }
            }
        } catch (IOException e) {
            log.error("", e);
            transactionLogger.flush();
            auditLogger.flush();
        }
    } catch (OCSPException e) {
        throw new OcspFailureException("OCSP response generation failed", e);
    }

    return respBytes;

}

From source file:org.ejbca.ui.web.protocol.OCSPServletBase.java

License:Open Source License

/** Performs service of the actual OCSP request, which is contained in reqBytes. 
 *  // w w  w .  j av a  2s  . co  m
 *  @param reqBytes the binary OCSP request bytes. This parameter must already have been checked for max or min size. 
 */
public void serviceOCSP(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    if (m_log.isTraceEnabled()) {
        m_log.trace(">service()");
    }
    final int localTransactionID;
    synchronized (this) {
        this.mTransactionID += 1;
        localTransactionID = this.mTransactionID;
    }
    final IPatternLogger transactionLogger;
    final IPatternLogger auditLogger;
    final Date startTime = new Date();
    if (this.mDoTransactionLog) {
        transactionLogger = this.transactionLogger.getPatternLogger();
    } else {
        transactionLogger = new DummyPatternLogger(); // Ignores everything
    }
    if (this.mDoAuditLog) {
        auditLogger = this.auditLogger.getPatternLogger();
    } else {
        auditLogger = new DummyPatternLogger(); // Ignores everything
    }
    final String remoteAddress = request.getRemoteAddr();
    auditLogger.paramPut(IAuditLogger.OCSPREQUEST, ""); // No request bytes yet
    auditLogger.paramPut(IPatternLogger.LOG_ID, new Integer(localTransactionID));
    auditLogger.paramPut(IPatternLogger.SESSION_ID, this.m_SessionID);
    auditLogger.paramPut(IOCSPLogger.CLIENT_IP, remoteAddress);
    transactionLogger.paramPut(IPatternLogger.LOG_ID, new Integer(localTransactionID));
    transactionLogger.paramPut(IPatternLogger.SESSION_ID, this.m_SessionID);
    transactionLogger.paramPut(IOCSPLogger.CLIENT_IP, remoteAddress);

    try {
        // Read configuration values affecting the response, these can be dynamically updated from properties files in file system
        // Read default values here for each request since may take a millisecond to read the value
        // These values can be changed depending on if there are different configurations for different certificate profiles
        // In that case it is updated once we have read the certificate status of the certificate searched for.
        long maxAge = OcspConfiguration.getMaxAge(SecConst.CERTPROFILE_NO_PROFILE);
        long nextUpdate = OcspConfiguration.getUntilNextUpdate(SecConst.CERTPROFILE_NO_PROFILE);

        OCSPResp ocspresp = null;
        OCSPRespGenerator res = new OCSPRespGenerator();
        X509Certificate cacert = null; // CA-certificate used to sign response
        try {
            byte[] reqBytes = checkAndGetRequestBytes(request);
            // Start logging process time after we have received the request
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IAuditLogger.OCSPREQUEST, new String(Hex.encode(reqBytes)));
            OCSPReq req = null;
            try {
                req = new OCSPReq(reqBytes);
            } catch (Exception e) {
                // When not being able to parse the request, we want to send a MalformedRequest back
                throw new MalformedRequestException(e);
            }
            if (req.getRequestorName() == null) {
                m_log.debug("Requestorname is null");
            } else {
                if (m_log.isDebugEnabled()) {
                    m_log.debug("Requestorname is: " + req.getRequestorName().toString());
                }
                transactionLogger.paramPut(ITransactionLogger.REQ_NAME, req.getRequestorName().toString());
            }
            // Make sure our signature keys are updated
            loadPrivateKeys(this.data.m_adm, null);

            /**
             * check the signature if contained in request.
             * if the request does not contain a signature
             * and the servlet is configured in the way 
             * the a signature is required we send back
             * 'sigRequired' response.
             */
            if (m_log.isDebugEnabled()) {
                m_log.debug("Incoming OCSP request is signed : " + req.isSigned());
            }
            if (req.isSigned()) {
                X509Certificate signercert = OCSPUtil.checkRequestSignature(request.getRemoteAddr(), req,
                        this.data.m_caCertCache);
                String signercertIssuerName = CertTools.getIssuerDN(signercert);
                BigInteger signercertSerNo = CertTools.getSerialNumber(signercert);
                String signercertSubjectName = CertTools.getSubjectDN(signercert);
                transactionLogger.paramPut(ITransactionLogger.SIGN_ISSUER_NAME_DN, signercertIssuerName);
                transactionLogger.paramPut(ITransactionLogger.SIGN_SERIAL_NO,
                        signercert.getSerialNumber().toByteArray());
                transactionLogger.paramPut(ITransactionLogger.SIGN_SUBJECT_NAME, signercertSubjectName);
                transactionLogger.paramPut(IPatternLogger.REPLY_TIME, ITransactionLogger.REPLY_TIME);
                if (OcspConfiguration.getEnforceRequestSigning()) {
                    // If it verifies OK, check if it is revoked
                    final CertificateStatus status = this.data.certificateStoreSession.getStatus(
                            CertTools.getIssuerDN(signercert), CertTools.getSerialNumber(signercert));
                    // If rci == null it means the certificate does not exist in database, we then treat it as ok,
                    // because it may be so that only revoked certificates is in the (external) OCSP database.
                    if (status.equals(CertificateStatus.REVOKED)) {
                        String serno = signercertSerNo.toString(16);
                        String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.revoked",
                                signercertSubjectName, signercertIssuerName, serno);
                        m_log.info(infoMsg);
                        throw new SignRequestSignatureException(infoMsg);
                    }

                    if (m_reqRestrictSignatures) {
                        loadTrustDir();
                        if (m_reqRestrictMethod == OcspConfiguration.RESTRICTONSIGNER) {
                            if (!OCSPUtil.checkCertInList(signercert, mTrustedReqSigSigners)) {
                                String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.notallowed",
                                        signercertSubjectName, signercertIssuerName,
                                        signercertSerNo.toString(16));
                                m_log.info(infoMsg);
                                throw new SignRequestSignatureException(infoMsg);
                            }
                        } else if (m_reqRestrictMethod == OcspConfiguration.RESTRICTONISSUER) {
                            X509Certificate signerca = this.data.m_caCertCache
                                    .findLatestBySubjectDN(HashID.getFromDN(signercertIssuerName));
                            if ((signerca == null)
                                    || (!OCSPUtil.checkCertInList(signerca, mTrustedReqSigIssuers))) {
                                String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.notallowed",
                                        signercertSubjectName, signercertIssuerName,
                                        signercertSerNo.toString(16));
                                m_log.info(infoMsg);
                                throw new SignRequestSignatureException(infoMsg);
                            }
                        } else {
                            throw new Exception("m_reqRestrictMethod=" + m_reqRestrictMethod); // there must be an internal error. We do not want to send a response, just to be safe.
                        }
                    }
                }
            } else {
                if (OcspConfiguration.getEnforceRequestSigning()) {
                    // Signature required
                    throw new SignRequestException("Signature required");
                }
            }

            // Get the certificate status requests that are inside this OCSP req
            Req[] requests = req.getRequestList();
            transactionLogger.paramPut(ITransactionLogger.NUM_CERT_ID, requests.length);
            if (requests.length <= 0) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errornoreqentities");
                m_log.info(infoMsg);
                {
                    // All this just so we can create an error response
                    cacert = this.data.m_caCertCache
                            .findLatestBySubjectDN(HashID.getFromDN(this.data.m_defaultResponderId));
                }
                throw new MalformedRequestException(infoMsg);
            }
            int maxRequests = 100;
            if (requests.length > maxRequests) {
                String infoMsg = intres.getLocalizedMessage("ocsp.errortoomanyreqentities", maxRequests);
                m_log.info(infoMsg);
                {
                    // All this just so we can create an error response
                    cacert = this.data.m_caCertCache
                            .findLatestBySubjectDN(HashID.getFromDN(this.data.m_defaultResponderId));
                }
                throw new MalformedRequestException(infoMsg);
            }

            if (m_log.isDebugEnabled()) {
                m_log.debug("The OCSP request contains " + requests.length + " simpleRequests.");
            }

            // Add standard response extensions
            Hashtable responseExtensions = OCSPUtil.getStandardResponseExtensions(req);
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            // Look over the status requests
            ArrayList responseList = new ArrayList();
            for (int i = 0; i < requests.length; i++) {
                CertificateID certId = requests[i].getCertID();
                // now some Logging
                transactionLogger.paramPut(ITransactionLogger.SERIAL_NOHEX,
                        certId.getSerialNumber().toByteArray());
                transactionLogger.paramPut(ITransactionLogger.DIGEST_ALGOR, certId.getHashAlgOID()); //todo, find text version of this or find out if it should be something else               
                transactionLogger.paramPut(ITransactionLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());
                transactionLogger.paramPut(ITransactionLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(IAuditLogger.ISSUER_KEY, certId.getIssuerKeyHash());
                auditLogger.paramPut(IAuditLogger.SERIAL_NOHEX, certId.getSerialNumber().toByteArray());
                auditLogger.paramPut(IAuditLogger.ISSUER_NAME_HASH, certId.getIssuerNameHash());
                byte[] hashbytes = certId.getIssuerNameHash();
                String hash = null;
                if (hashbytes != null) {
                    hash = new String(Hex.encode(hashbytes));
                }
                String infoMsg = intres.getLocalizedMessage("ocsp.inforeceivedrequest",
                        certId.getSerialNumber().toString(16), hash, request.getRemoteAddr());
                m_log.info(infoMsg);
                boolean unknownCA = false;
                // if the certId was issued by an unknown CA
                // The algorithm here:
                // We will sign the response with the CA that issued the first 
                // certificate(certId) in the request. If the issuing CA is not available
                // on this server, we sign the response with the default responderId (from params in web.xml).
                // We have to look up the ca-certificate for each certId in the request though, as we will check
                // for revocation on the ca-cert as well when checking for revocation on the certId. 
                cacert = this.data.m_caCertCache.findByOcspHash(certId); // Get the issuer of certId
                if (cacert == null) {
                    // We could not find certificate for this request so get certificate for default responder
                    cacert = this.data.m_caCertCache
                            .findLatestBySubjectDN(HashID.getFromDN(this.data.m_defaultResponderId));
                    unknownCA = true;
                }
                if (cacert == null) {
                    String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacert",
                            new String(Hex.encode(certId.getIssuerNameHash())), this.data.m_defaultResponderId);
                    m_log.error(errMsg);
                    continue;
                }
                if (unknownCA == true) {
                    String errMsg = intres.getLocalizedMessage("ocsp.errorfindcacertusedefault",
                            new String(Hex.encode(certId.getIssuerNameHash())));
                    m_log.info(errMsg);
                    // If we can not find the CA, answer UnknowStatus
                    responseList.add(new OCSPResponseItem(certId, new UnknownStatus(), nextUpdate));
                    transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_UNKNOWN);
                    transactionLogger.writeln();
                    continue;
                } else {
                    transactionLogger.paramPut(ITransactionLogger.ISSUER_NAME_DN,
                            cacert.getSubjectDN().getName());
                }
                /*
                 * Implement logic according to
                 * chapter 2.7 in RFC2560
                 * 
                 * 2.7  CA Key Compromise
                 *   If an OCSP responder knows that a particular CA's private key has
                 *   been compromised, it MAY return the revoked state for all
                 *   certificates issued by that CA.
                 */
                final org.bouncycastle.ocsp.CertificateStatus certStatus;
                transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_GOOD); // it seems to be correct
                // Check if the cacert (or the default responderid) is revoked
                final CertificateStatus cacertStatus = this.data.certificateStoreSession
                        .getStatus(CertTools.getIssuerDN(cacert), CertTools.getSerialNumber(cacert));
                if (!cacertStatus.equals(CertificateStatus.REVOKED)) {
                    // Check if cert is revoked
                    final CertificateStatus status = this.data.certificateStoreSession
                            .getStatus(cacert.getSubjectDN().getName(), certId.getSerialNumber());
                    // If we have different maxAge and untilNextUpdate for different certificate profiles, we have to fetch these
                    // values now that we have fetched the certificate status, that includes certificate profile.
                    nextUpdate = OcspConfiguration.getUntilNextUpdate(status.certificateProfileId);
                    maxAge = OcspConfiguration.getMaxAge(status.certificateProfileId);
                    if (m_log.isDebugEnabled()) {
                        m_log.debug("Set nextUpdate=" + nextUpdate + ", and maxAge=" + maxAge
                                + " for certificateProfileId=" + status.certificateProfileId);
                    }

                    final String sStatus;
                    if (status.equals(CertificateStatus.NOT_AVAILABLE)) {
                        // No revocation info available for this cert, handle it
                        if (m_log.isDebugEnabled()) {
                            m_log.debug("Unable to find revocation information for certificate with serial '"
                                    + certId.getSerialNumber().toString(16) + "'" + " from issuer '"
                                    + cacert.getSubjectDN().getName() + "'");
                        }
                        // If we do not treat non existing certificates as good 
                        // OR
                        // we don't actually handle requests for the CA issuing the certificate asked about
                        // then we return unknown
                        if (!nonExistingIsGood(request.getRequestURL())
                                || this.data.m_caCertCache.findByOcspHash(certId) == null) {
                            sStatus = "unknown";
                            certStatus = new UnknownStatus();
                            transactionLogger.paramPut(ITransactionLogger.CERT_STATUS,
                                    OCSPUnidResponse.OCSP_UNKNOWN);
                        } else {
                            sStatus = "good";
                            certStatus = null; // null means "good" in OCSP
                            transactionLogger.paramPut(ITransactionLogger.CERT_STATUS,
                                    OCSPUnidResponse.OCSP_GOOD);
                        }
                    } else if (status.equals(CertificateStatus.REVOKED)) {
                        // Revocation info available for this cert, handle it
                        sStatus = "revoked";
                        certStatus = new RevokedStatus(
                                new RevokedInfo(new DERGeneralizedTime(status.revocationDate),
                                        new CRLReason(status.revocationReason)));
                        transactionLogger.paramPut(ITransactionLogger.CERT_STATUS,
                                OCSPUnidResponse.OCSP_REVOKED); //1 = revoked
                    } else {
                        sStatus = "good";
                        certStatus = null;
                        transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_GOOD);
                    }
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", sStatus,
                            certId.getSerialNumber().toString(16), cacert.getSubjectDN().getName());
                    m_log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));
                    transactionLogger.writeln();
                } else {
                    certStatus = new RevokedStatus(
                            new RevokedInfo(new DERGeneralizedTime(cacertStatus.revocationDate),
                                    new CRLReason(cacertStatus.revocationReason)));
                    infoMsg = intres.getLocalizedMessage("ocsp.infoaddedstatusinfo", "revoked",
                            certId.getSerialNumber().toString(16), cacert.getSubjectDN().getName());
                    m_log.info(infoMsg);
                    responseList.add(new OCSPResponseItem(certId, certStatus, nextUpdate));
                    transactionLogger.paramPut(ITransactionLogger.CERT_STATUS, OCSPUnidResponse.OCSP_REVOKED);
                    transactionLogger.writeln();
                }
                // Look for extension OIDs
                Iterator iter = m_extensionOids.iterator();
                while (iter.hasNext()) {
                    String oidstr = (String) iter.next();
                    DERObjectIdentifier oid = new DERObjectIdentifier(oidstr);
                    X509Extensions reqexts = req.getRequestExtensions();
                    if (reqexts != null) {
                        X509Extension ext = reqexts.getExtension(oid);
                        if (null != ext) {
                            // We found an extension, call the extenstion class
                            if (m_log.isDebugEnabled()) {
                                m_log.debug("Found OCSP extension oid: " + oidstr);
                            }
                            IOCSPExtension extObj = (IOCSPExtension) m_extensionMap.get(oidstr);
                            if (extObj != null) {
                                // Find the certificate from the certId
                                X509Certificate cert = null;
                                cert = (X509Certificate) this.data.certificateStoreSession
                                        .findCertificateByIssuerAndSerno(this.data.m_adm,
                                                cacert.getSubjectDN().getName(), certId.getSerialNumber());
                                if (cert != null) {
                                    // Call the OCSP extension
                                    Hashtable retext = extObj.process(request, cert, certStatus);
                                    if (retext != null) {
                                        // Add the returned X509Extensions to the responseExtension we will add to the basic OCSP response
                                        responseExtensions.putAll(retext);
                                    } else {
                                        String errMsg = intres.getLocalizedMessage("ocsp.errorprocessextension",
                                                extObj.getClass().getName(),
                                                new Integer(extObj.getLastErrorCode()));
                                        m_log.error(errMsg);
                                    }
                                }
                            }
                        }
                    }
                }
            } // end of huge for loop
            if (cacert != null) {
                // Add responseExtensions
                X509Extensions exts = new X509Extensions(responseExtensions);
                // generate the signed response object
                BasicOCSPResp basicresp = signOCSPResponse(req, responseList, exts, cacert);
                ocspresp = res.generate(OCSPRespGenerator.SUCCESSFUL, basicresp);
                auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
                transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.SUCCESSFUL);
            } else {
                // Only unknown CAs in requests and no default reponders cert 
                String errMsg = intres.getLocalizedMessage("ocsp.errornocacreateresp");
                m_log.error(errMsg);
                throw new ServletException(errMsg);
            }
        } catch (MalformedRequestException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg);
            if (m_log.isDebugEnabled()) {
                m_log.debug(errMsg, e);
            }
            ocspresp = res.generate(OCSPRespGenerator.MALFORMED_REQUEST, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.MALFORMED_REQUEST);
        } catch (SignRequestException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg); // No need to log the full exception here
            ocspresp = res.generate(OCSPRespGenerator.SIG_REQUIRED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.SIG_REQUIRED);
        } catch (SignRequestSignatureException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg); // No need to log the full exception here
            ocspresp = res.generate(OCSPRespGenerator.UNAUTHORIZED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
        } catch (InvalidKeyException e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.info(errMsg, e);
            ocspresp = res.generate(OCSPRespGenerator.UNAUTHORIZED, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.UNAUTHORIZED);
        } catch (Throwable e) {
            transactionLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            auditLogger.paramPut(IPatternLogger.PROCESS_TIME, IPatternLogger.PROCESS_TIME);
            String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
            m_log.error(errMsg, e);
            ocspresp = res.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on error.
            transactionLogger.paramPut(ITransactionLogger.STATUS, OCSPRespGenerator.INTERNAL_ERROR);
            transactionLogger.writeln();
            auditLogger.paramPut(IAuditLogger.STATUS, OCSPRespGenerator.INTERNAL_ERROR);
        }
        byte[] respBytes = ocspresp.getEncoded();
        auditLogger.paramPut(IAuditLogger.OCSPRESPONSE, new String(Hex.encode(respBytes)));
        auditLogger.writeln();
        auditLogger.flush();
        transactionLogger.flush();
        if (mDoSaferLogging) {
            // See if the Errorhandler has found any problems
            if (hasErrorHandlerFailedSince(startTime)) {
                m_log.info("ProbableErrorhandler reported error, cannot answer request");
                ocspresp = res.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on error.
                respBytes = ocspresp.getEncoded();
            }
            // See if the Appender has reported any problems
            if (!canlog) {
                m_log.info("SaferDailyRollingFileAppender reported error, cannot answer request");
                ocspresp = res.generate(OCSPRespGenerator.INTERNAL_ERROR, null); // RFC 2560: responseBytes are not set on error.
                respBytes = ocspresp.getEncoded();
            }
        }
        response.setContentType("application/ocsp-response");
        //response.setHeader("Content-transfer-encoding", "binary");
        response.setContentLength(respBytes.length);
        addRfc5019CacheHeaders(request, response, ocspresp, maxAge);
        response.getOutputStream().write(respBytes);
        response.getOutputStream().flush();
    } catch (OCSPException e) {
        String errMsg = intres.getLocalizedMessage("ocsp.errorprocessreq", e.getMessage());
        m_log.error(errMsg, e);
        throw new ServletException(e);
    } catch (Exception e) {
        m_log.error("", e);
        transactionLogger.flush();
        auditLogger.flush();
    }
    if (m_log.isTraceEnabled()) {
        m_log.trace("<service()");
    }
}