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

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

Introduction

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

Prototype

private OCSPReq(ASN1InputStream aIn) throws IOException 

Source Link

Usage

From source file:Controllers.OCSPController.java

License:Apache License

/**
 * Method to do OCSP response to client.
 *
 * @param requestBytes//from  w ww.  j  av a  2 s .co m
 * @param mode
 *
 * @return
 *
 * @throws NotImplementedException
 */
private byte[] processOcspRequest(byte[] requestBytes, OCSP_PROCESS_MODE mode) throws NotImplementedException {
    try {
        // get request info
        OCSPReq ocspRequest = new OCSPReq(requestBytes);
        X509CertificateHolder[] requestCerts = ocspRequest.getCerts();
        Req[] requestList = ocspRequest.getRequestList();
        // setup response
        BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder(
                new RespID(x509CertificateHolder.getSubject()));
        LOG.info("OCSP request version: " + ocspRequest.getVersionNumber() + ", Requester name: "
                + ocspRequest.getRequestorName() + ", is signed: " + ocspRequest.isSigned()
                + ", has extensions: " + ocspRequest.hasExtensions() + ", number of additional certificates: "
                + requestCerts.length + ", number of certificate ids to verify: " + requestList.length);
        int ocspResult = OCSPRespBuilder.SUCCESSFUL;
        switch (mode) {
        case AUTO:
            LOG.error("Auto OCSP server is not implemented in this version.");
            throw new NotImplementedException();
        case GOOD:
            LOG.warn("Mocked mode, server will always return Good ocsp response");
            for (Req req : requestList) {
                CertificateID certId = req.getCertID();
                String serialNumber = "0x" + certId.getSerialNumber().toString(16);
                LOG.debug(String.format("Processing request for cert serial number:[%s]", serialNumber));
                CertificateStatus certificateStatus = CertificateStatus.GOOD;
                Calendar thisUpdate = new GregorianCalendar();
                Date now = thisUpdate.getTime();
                thisUpdate.add(Calendar.DAY_OF_MONTH, 7);
                Date nexUpdate = thisUpdate.getTime();
                responseBuilder.addResponse(certId, certificateStatus, now, nexUpdate, null);
            }
            break;
        case REVOKED:
            LOG.warn("Mocked mode, server will always return REVOKED ocsp response");
            for (Req req : requestList) {
                CertificateID certId = req.getCertID();
                String serialNumber = "0x" + certId.getSerialNumber().toString(16);
                LOG.debug(String.format("Processing request for cert serial number:[%s]", serialNumber));
                Calendar cal = new GregorianCalendar();
                cal.add(Calendar.DAY_OF_MONTH, -7);//Set revoked 7 days ago.
                CertificateStatus certificateStatus = new RevokedStatus(cal.getTime(), 16);
                Calendar thisUpdate = new GregorianCalendar();
                Date now = thisUpdate.getTime();
                thisUpdate.add(Calendar.DAY_OF_MONTH, 7);
                Date nexUpdate = thisUpdate.getTime();
                responseBuilder.addResponse(certId, certificateStatus, now, nexUpdate, null);
            }
            break;
        case UNKNOWN:
            LOG.warn("Mocked mode, server will always return Known ocsp response");
            for (Req req : requestList) {
                CertificateID certId = req.getCertID();
                String serialNumber = "0x" + certId.getSerialNumber().toString(16);
                LOG.debug(String.format("Processing request for cert serial number:[%s]", serialNumber));
                CertificateStatus certificateStatus = new UnknownStatus();
                Calendar thisUpdate = new GregorianCalendar();
                Date now = thisUpdate.getTime();
                thisUpdate.add(Calendar.DAY_OF_MONTH, 7);
                Date nexUpdate = thisUpdate.getTime();
                responseBuilder.addResponse(certId, certificateStatus, now, nexUpdate, null);
            }
            break;
        }
        // process nonce
        Extension extNonce = ocspRequest.getExtension(new ASN1ObjectIdentifier("1.3.6.1.5.5.7.48.1.2"));
        if (extNonce != null) {
            LOG.debug("Nonce is present in the request");
            responseBuilder.setResponseExtensions(new Extensions(extNonce));
        } else {
            LOG.info("Nonce is not present in the request");
            if (bRequireNonce) {
                LOG.info("Nonce is required, fail the request");
                ocspResult = OCSPRespBuilder.UNAUTHORIZED;
            }
        }
        X509CertificateHolder[] chain = { x509CertificateHolder };
        ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);
        BasicOCSPResp ocspResponse = responseBuilder.build(signer, chain, Calendar.getInstance().getTime());
        OCSPRespBuilder ocspResponseBuilder = new OCSPRespBuilder();
        byte[] encoded = ocspResponseBuilder.build(ocspResult, ocspResponse).getEncoded();
        LOG.info("Sending OCSP response to client, size: " + encoded.length);
        return encoded;

    } catch (Exception e) {
        LOG.error("Exception during processing OCSP request: " + e.getMessage());
        e.printStackTrace();
    }
    return null;
}

From source file:net.maritimecloud.identityregistry.controllers.CertificateController.java

License:Apache License

protected byte[] handleOCSP(byte[] input, String certAlias) throws IOException {
    OCSPReq ocspreq = new OCSPReq(input);
    /* TODO: verify signature - needed?
    if (ocspreq.isSigned()) {//from   w  w  w.ja va2  s.co m
    }*/
    BasicOCSPRespBuilder respBuilder = Revocation.initOCSPRespBuilder(ocspreq,
            certUtil.getKeystoreHandler().getMCCertificate(certAlias).getPublicKey());
    Req[] requests = ocspreq.getRequestList();
    for (Req req : requests) {
        BigInteger sn = req.getCertID().getSerialNumber();
        Certificate cert = this.certificateService.getCertificateBySerialNumber(sn);

        if (cert == null) {
            respBuilder.addResponse(req.getCertID(), new UnknownStatus());

            // Check if the certificate is even signed by this CA
        } else if (!certAlias.equals(cert.getCertificateAuthority())) {
            respBuilder.addResponse(req.getCertID(), new UnknownStatus());

            // Check if certificate has been revoked
        } else if (cert.isRevoked()) {
            respBuilder.addResponse(req.getCertID(), new RevokedStatus(cert.getRevokedAt(),
                    Revocation.getCRLReasonFromString(cert.getRevokeReason())));

        } else {
            // Certificate is valid
            respBuilder.addResponse(req.getCertID(), CertificateStatus.GOOD);
        }
    }
    OCSPResp response = Revocation.generateOCSPResponse(respBuilder,
            certUtil.getKeystoreHandler().getSigningCertEntry(certAlias));
    return response.getEncoded();
}

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

License:Open Source License

/**
 * This method takes byte array and translates it onto a OCSPReq class.
 * /*w w w.j a v  a 2 s .c  o m*/
 * @param request the byte array in question.
 * @param remoteAddress The remote address of the HttpRequest associated with this array.
 * @param transactionLogger A transaction logger.
 * @return
 * @throws MalformedRequestException
 * @throws SignRequestException thrown if an unsigned request was processed when system configuration requires that all requests be signed.
 * @throws CertificateException
 * @throws NoSuchAlgorithmException
 * @throws SignRequestSignatureException
 */
private OCSPReq translateRequestFromByteArray(byte[] request, String remoteAddress,
        TransactionLogger transactionLogger) throws MalformedRequestException, SignRequestException,
        SignRequestSignatureException, CertificateException, NoSuchAlgorithmException {
    final OCSPReq ocspRequest;
    try {
        ocspRequest = new OCSPReq(request);
    } catch (IOException e) {
        throw new MalformedRequestException("Could not form OCSP request", e);
    }
    if (ocspRequest.getRequestorName() == null) {
        if (log.isDebugEnabled()) {
            log.debug("Requestor name is null");
        }
    } else {
        if (log.isDebugEnabled()) {
            log.debug("Requestor name is: " + ocspRequest.getRequestorName().toString());
        }
        if (transactionLogger.isEnabled()) {
            transactionLogger.paramPut(TransactionLogger.REQ_NAME, ocspRequest.getRequestorName().toString());
        }
    }

    /**
     * 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 (log.isDebugEnabled()) {
        log.debug("Incoming OCSP request is signed : " + ocspRequest.isSigned());
    }
    if (ocspRequest.isSigned()) {
        final X509Certificate signercert = checkRequestSignature(remoteAddress, ocspRequest);
        final String signercertIssuerName = CertTools.getIssuerDN(signercert);
        final BigInteger signercertSerNo = CertTools.getSerialNumber(signercert);
        final String signercertSubjectName = CertTools.getSubjectDN(signercert);
        if (transactionLogger.isEnabled()) {
            transactionLogger.paramPut(TransactionLogger.SIGN_ISSUER_NAME_DN, signercertIssuerName);
            transactionLogger.paramPut(TransactionLogger.SIGN_SERIAL_NO,
                    signercert.getSerialNumber().toByteArray());
            transactionLogger.paramPut(TransactionLogger.SIGN_SUBJECT_NAME, signercertSubjectName);
            transactionLogger.paramPut(PatternLogger.REPLY_TIME, TransactionLogger.REPLY_TIME);
        }
        // Check if we have configured request verification using the old property file way..
        boolean enforceRequestSigning = OcspConfiguration.getEnforceRequestSigning();
        // Next, check if there is an OcspKeyBinding where signing is required and configured for this request
        // In the case where multiple requests are bundled together they all must be trusting the signer
        for (final Req req : ocspRequest.getRequestList()) {
            OcspSigningCacheEntry ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getEntry(req.getCertID());
            if (ocspSigningCacheEntry == null) {
                if (log.isTraceEnabled()) {
                    log.trace("Using default responder to check signature.");
                }
                ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getDefaultEntry();
            }
            if (ocspSigningCacheEntry != null
                    && ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate()) {
                if (log.isTraceEnabled()) {
                    log.trace("ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate: "
                            + ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate());
                }
                final OcspKeyBinding ocspKeyBinding = ocspSigningCacheEntry.getOcspKeyBinding();
                if (log.isTraceEnabled()) {
                    log.trace("OcspKeyBinding " + ocspKeyBinding.getId() + ", RequireTrustedSignature: "
                            + ocspKeyBinding.getRequireTrustedSignature());
                }
                if (ocspKeyBinding.getRequireTrustedSignature()) {
                    enforceRequestSigning = true;
                    boolean isTrusted = false;
                    final List<InternalKeyBindingTrustEntry> trustedCertificateReferences = ocspKeyBinding
                            .getTrustedCertificateReferences();
                    if (trustedCertificateReferences.isEmpty()) {
                        // We trust ANY cert from a known CA
                        isTrusted = true;
                    } else {
                        for (final InternalKeyBindingTrustEntry trustEntry : trustedCertificateReferences) {
                            final int trustedCaId = trustEntry.getCaId();
                            final BigInteger trustedSerialNumber = trustEntry.fetchCertificateSerialNumber();
                            if (log.isTraceEnabled()) {
                                log.trace("Processing trustedCaId=" + trustedCaId + " trustedSerialNumber="
                                        + trustedSerialNumber + " signercertIssuerName.hashCode()="
                                        + signercertIssuerName.hashCode() + " signercertSerNo="
                                        + signercertSerNo);
                            }
                            if (trustedCaId == signercertIssuerName.hashCode()) {
                                if (trustedSerialNumber == null) {
                                    // We trust any certificate from this CA
                                    isTrusted = true;
                                    if (log.isTraceEnabled()) {
                                        log.trace(
                                                "Trusting request signature since ANY certificate from issuer "
                                                        + trustedCaId + " is trusted.");
                                    }
                                    break;
                                } else if (signercertSerNo.equals(trustedSerialNumber)) {
                                    // We trust this particular certificate from this CA
                                    isTrusted = true;
                                    if (log.isTraceEnabled()) {
                                        log.trace(
                                                "Trusting request signature since certificate with serialnumber "
                                                        + trustedSerialNumber + " from issuer " + trustedCaId
                                                        + " is trusted.");
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    if (!isTrusted) {
                        final String infoMsg = intres.getLocalizedMessage("ocsp.infosigner.notallowed",
                                signercertSubjectName, signercertIssuerName, signercertSerNo.toString(16));
                        log.info(infoMsg);
                        throw new SignRequestSignatureException(infoMsg);
                    }
                }
            }
        }
        if (enforceRequestSigning) {
            // If it verifies OK, check if it is revoked
            final CertificateStatus status = certificateStoreSession.getStatus(signercertIssuerName,
                    signercertSerNo);
            /*
             * 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);
                log.info(infoMsg);
                throw new SignRequestSignatureException(infoMsg);
            }
        }
    } else {
        if (OcspConfiguration.getEnforceRequestSigning()) {
            // Signature required
            throw new SignRequestException("Signature required");
        }
        // Next, check if there is an OcspKeyBinding where signing is required and configured for this request
        // In the case where multiple requests are bundled together they all must be trusting the signer
        for (final Req req : ocspRequest.getRequestList()) {
            OcspSigningCacheEntry ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getEntry(req.getCertID());
            if (ocspSigningCacheEntry == null) {
                ocspSigningCacheEntry = OcspSigningCache.INSTANCE.getDefaultEntry();
            }
            if (ocspSigningCacheEntry != null
                    && ocspSigningCacheEntry.isUsingSeparateOcspSigningCertificate()) {
                final OcspKeyBinding ocspKeyBinding = ocspSigningCacheEntry.getOcspKeyBinding();
                if (ocspKeyBinding.getRequireTrustedSignature()) {
                    throw new SignRequestException("Signature required");
                }
            }
        }
    }
    return ocspRequest;
}

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

License:Common Public License

public OCSPReq getBCOCSPReq() {
    if (asn1bcReq == null)
        return null;
    return new OCSPReq(asn1bcReq);
}

From source file:org.keycloak.testsuite.forms.x509.OcspHandler.java

License:Open Source License

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if (exchange.isInIoThread()) {
        exchange.dispatch(this);
        return;/*  w w w  . j  av a  2  s.  c  o m*/
    }

    final byte[] buffy = new byte[16384];
    try (InputStream requestStream = exchange.getInputStream()) {
        requestStream.read(buffy);
    }

    final OCSPReq request = new OCSPReq(buffy);
    final Req[] requested = request.getRequestList();

    final Extension nonce = request.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);

    final DigestCalculator sha1Calculator = new JcaDigestCalculatorProviderBuilder().build()
            .get(AlgorithmIdentifier.getInstance(RespID.HASH_SHA1));

    final BasicOCSPRespBuilder responseBuilder = new BasicOCSPRespBuilder(subjectPublicKeyInfo, sha1Calculator);

    if (nonce != null) {
        responseBuilder.setResponseExtensions(new Extensions(nonce));
    }

    for (final Req req : requested) {
        final CertificateID certId = req.getCertID();

        final BigInteger certificateSerialNumber = certId.getSerialNumber();
        responseBuilder.addResponse(certId, REVOKED_CERTIFICATES_STATUS.get(certificateSerialNumber));
    }

    final ContentSigner contentSigner = new BcRSAContentSignerBuilder(
            new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption),
            new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256)).build(privateKey);

    final OCSPResp response = new OCSPRespBuilder().build(OCSPResp.SUCCESSFUL,
            responseBuilder.build(contentSigner, chain, new Date()));

    final byte[] responseBytes = response.getEncoded();

    final HeaderMap responseHeaders = exchange.getResponseHeaders();
    responseHeaders.put(Headers.CONTENT_TYPE, "application/ocsp-response");

    final Sender responseSender = exchange.getResponseSender();
    responseSender.send(ByteBuffer.wrap(responseBytes));

    exchange.endExchange();
}

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

License:Open Source License

private void processRequest(final HttpServletRequest request, final HttpServletResponse response,
        final ResponderAndRelativeUri r, final boolean getMethod) throws ServletException, IOException {
    Responder responder = r.getResponder();
    AuditEvent auditEvent = null;//from w w w . j a  v a2  s . c o  m

    AuditLevel auditLevel = AuditLevel.INFO;
    AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
    String auditMessage = null;

    long start = 0;

    AuditLoggingService auditLoggingService = auditServiceRegister == null ? null
            : auditServiceRegister.getAuditLoggingService();

    if (auditLoggingService != null && responder.getAuditOption() != null) {
        start = System.currentTimeMillis();
        auditEvent = new AuditEvent(new Date());
        auditEvent.setApplicationName("OCSP");
        auditEvent.setName("PERF");
    }

    try {
        if (server == null) {
            String message = "responder in servlet not configured";
            LOG.error(message);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.setContentLength(0);

            auditLevel = AuditLevel.ERROR;
            auditStatus = AuditStatus.FAILED;
            auditMessage = message;
            return;
        }

        InputStream requestStream;
        if (getMethod) {
            String relativeUri = r.getRelativeUri();

            // RFC2560 A.1.1 specifies that request longer than 255 bytes SHOULD be sent by POST,
            // we support GET for longer requests anyway.
            if (relativeUri.length() > responder.getRequestOption().getMaxRequestSize()) {
                response.setContentLength(0);
                response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);

                auditStatus = AuditStatus.FAILED;
                auditMessage = "request too large";
                return;
            }

            requestStream = new ByteArrayInputStream(Base64.decode(relativeUri));
        } else {
            // accept only "application/ocsp-request" as content type
            if (CT_REQUEST.equalsIgnoreCase(request.getContentType()) == false) {
                response.setContentLength(0);
                response.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);

                auditStatus = AuditStatus.FAILED;
                auditMessage = "unsupporte media type " + request.getContentType();
                return;
            }

            // request too long
            if (request.getContentLength() > responder.getRequestOption().getMaxRequestSize()) {
                response.setContentLength(0);
                response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);

                auditStatus = AuditStatus.FAILED;
                auditMessage = "request too large";
                return;
            } // if(CT_REQUEST)

            requestStream = request.getInputStream();
        } // end if(getMethod)

        OCSPRequest ocspRequest;
        try {
            ASN1StreamParser parser = new ASN1StreamParser(requestStream);
            ocspRequest = OCSPRequest.getInstance(parser.readObject());
        } catch (Exception e) {
            response.setContentLength(0);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

            auditStatus = AuditStatus.FAILED;
            auditMessage = "bad request";

            final String message = "could not parse the request (OCSPRequest)";
            if (LOG.isErrorEnabled()) {
                LOG.error(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
            }
            LOG.debug(message, e);

            return;
        }

        OCSPReq ocspReq = new OCSPReq(ocspRequest);

        response.setContentType(Rfc2560Servlet.CT_RESPONSE);

        OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, ocspReq, auditEvent, getMethod);
        if (ocspRespWithCacheInfo == null) {
            auditMessage = "processRequest returned null, this should not happen";
            LOG.error(auditMessage);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.setContentLength(0);

            auditLevel = AuditLevel.ERROR;
            auditStatus = AuditStatus.FAILED;
        } else {
            OCSPResp resp = ocspRespWithCacheInfo.getResponse();
            byte[] encodedOcspResp = resp.getEncoded();
            response.setStatus(HttpServletResponse.SC_OK);
            response.setContentLength(encodedOcspResp.length);

            ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
            if (getMethod && cacheInfo != null) {
                long now = System.currentTimeMillis();
                // RFC 5019 6.2: Date: The date and time at which the OCSP server generated the HTTP response.
                response.setDateHeader("Date", now);
                // RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder last modified the response.
                response.setDateHeader("Last-Modified", cacheInfo.getThisUpdate());
                // RFC 5019 6.2: Expires: This date and time will be the same as the nextUpdate time-stamp in the OCSP
                // response itself.
                // This is overridden by max-age on HTTP/1.1 compatible components
                if (cacheInfo.getNextUpdate() != null) {
                    response.setDateHeader("Expires", cacheInfo.getNextUpdate());
                }
                // RFC 5019 6.2: This profile RECOMMENDS that the ETag value be the ASCII HEX representation of the
                // SHA1 hash of the OCSPResponse structure.
                response.setHeader("ETag", "\"" + SecurityUtil.sha1sum(encodedOcspResp).toLowerCase() + "\"");

                // Max age must be in seconds in the cache-control header
                long maxAge;
                if (responder.getResponseOption().getCacheMaxAge() != null) {
                    maxAge = responder.getResponseOption().getCacheMaxAge().longValue();
                } else {
                    maxAge = OcspServer.defaultCacheMaxAge;
                }

                if (cacheInfo.getNextUpdate() != null) {
                    maxAge = Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
                }

                response.setHeader("Cache-Control",
                        "max-age=" + maxAge + ",public,no-transform,must-revalidate");
            } // end if(getMethod && cacheInfo != null)
            response.getOutputStream().write(encodedOcspResp);
        } // end if (ocspRespWithCacheInfo)
    } catch (EOFException e) {
        final String message = "Connection reset by peer";
        if (LOG.isErrorEnabled()) {
            LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage());
        }
        LOG.debug(message, e);

        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);
    } catch (Throwable t) {
        final String message = "Throwable thrown, this should not happen!";
        LOG.error(message, t);

        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);

        auditLevel = AuditLevel.ERROR;
        auditStatus = AuditStatus.FAILED;
        auditMessage = "internal error";
    } finally {
        try {
            response.flushBuffer();
        } finally {
            if (auditEvent != null) {
                if (auditLevel != null) {
                    auditEvent.setLevel(auditLevel);
                }

                if (auditStatus != null) {
                    auditEvent.setStatus(auditStatus);
                }

                if (auditMessage != null) {
                    auditEvent.addEventData(new AuditEventData("message", auditMessage));
                }

                auditEvent.setDuration(System.currentTimeMillis() - start);

                if (auditEvent.containsChildAuditEvents() == false) {
                    auditLoggingService.logEvent(auditEvent);
                } else {
                    List<AuditEvent> expandedAuditEvents = auditEvent.expandAuditEvents();
                    for (AuditEvent event : expandedAuditEvents) {
                        auditLoggingService.logEvent(event);
                    }
                }
            } // end if(auditEvent != null)
        } // end inner try
    } // end external try
}

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

License:Open Source License

private void processRequest(final HttpServletRequest request, final HttpServletResponse response,
        final ResponderAndRelativeUri respAndUri, final boolean getMethod)
        throws ServletException, IOException {
    Responder responder = respAndUri.getResponder();
    AuditEvent event = null;//from   w w  w  .j  a v  a 2s  . c  o m
    AuditLevel auditLevel = AuditLevel.INFO;
    AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
    String auditMessage = null;

    AuditService auditService = (auditServiceRegister == null) ? null : auditServiceRegister.getAuditService();

    if (responder.getAuditOption() != null) {
        event = new AuditEvent(new Date());
        event.setApplicationName(OcspAuditConstants.APPNAME);
        event.setName(OcspAuditConstants.NAME_PERF);
    }

    try {
        if (server == null) {
            String message = "responder in servlet not configured";
            LOG.error(message);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.setContentLength(0);

            auditLevel = AuditLevel.ERROR;
            auditStatus = AuditStatus.FAILED;
            auditMessage = message;
            return;
        }

        InputStream requestStream;
        if (getMethod) {
            String relativeUri = respAndUri.getRelativeUri();

            // RFC2560 A.1.1 specifies that request longer than 255 bytes SHOULD be sent by
            // POST, we support GET for longer requests anyway.
            if (relativeUri.length() > responder.getRequestOption().getMaxRequestSize()) {
                response.setContentLength(0);
                response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);

                auditStatus = AuditStatus.FAILED;
                auditMessage = "request too large";
                return;
            }

            requestStream = new ByteArrayInputStream(Base64.decode(relativeUri));
        } else {
            // accept only "application/ocsp-request" as content type
            if (!CT_REQUEST.equalsIgnoreCase(request.getContentType())) {
                response.setContentLength(0);
                response.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);

                auditStatus = AuditStatus.FAILED;
                auditMessage = "unsupported media type " + request.getContentType();
                return;
            }

            // request too long
            if (request.getContentLength() > responder.getRequestOption().getMaxRequestSize()) {
                response.setContentLength(0);
                response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);

                auditStatus = AuditStatus.FAILED;
                auditMessage = "request too large";
                return;
            } // if (CT_REQUEST)

            requestStream = request.getInputStream();
        } // end if (getMethod)

        OCSPRequest ocspRequest;
        try {
            ASN1StreamParser parser = new ASN1StreamParser(requestStream);
            ocspRequest = OCSPRequest.getInstance(parser.readObject());
        } catch (Exception ex) {
            response.setContentLength(0);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

            auditStatus = AuditStatus.FAILED;
            auditMessage = "bad request";

            LogUtil.error(LOG, ex, "could not parse the request (OCSPRequest)");
            return;
        }

        OCSPReq ocspReq = new OCSPReq(ocspRequest);

        response.setContentType(HttpOcspServlet.CT_RESPONSE);

        OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, ocspReq, getMethod, event);
        if (ocspRespWithCacheInfo == null) {
            auditMessage = "processRequest returned null, this should not happen";
            LOG.error(auditMessage);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.setContentLength(0);

            auditLevel = AuditLevel.ERROR;
            auditStatus = AuditStatus.FAILED;
        } else {
            OCSPResp resp = ocspRespWithCacheInfo.getResponse();
            byte[] encodedOcspResp = null;
            response.setStatus(HttpServletResponse.SC_OK);

            ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
            if (getMethod && cacheInfo != null) {
                encodedOcspResp = resp.getEncoded();
                long now = System.currentTimeMillis();
                // RFC 5019 6.2: Date: The date and time at which the OCSP server generated
                // the HTTP response.
                response.setDateHeader("Date", now);
                // RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder
                // last modified the response.
                response.setDateHeader("Last-Modified", cacheInfo.getThisUpdate());
                // RFC 5019 6.2: Expires: This date and time will be the same as the
                // nextUpdate time-stamp in the OCSP
                // response itself.
                // This is overridden by max-age on HTTP/1.1 compatible components
                if (cacheInfo.getNextUpdate() != null) {
                    response.setDateHeader("Expires", cacheInfo.getNextUpdate());
                }
                // RFC 5019 6.2: This profile RECOMMENDS that the ETag value be the ASCII
                // HEX representation of the SHA1 hash of the OCSPResponse structure.
                response.setHeader("ETag", new StringBuilder(42).append('\\')
                        .append(HashAlgoType.SHA1.hexHash(encodedOcspResp)).append('\\').toString());

                // Max age must be in seconds in the cache-control header
                long maxAge;
                if (responder.getResponseOption().getCacheMaxAge() != null) {
                    maxAge = responder.getResponseOption().getCacheMaxAge().longValue();
                } else {
                    maxAge = OcspServer.DFLT_CACHE_MAX_AGE;
                }

                if (cacheInfo.getNextUpdate() != null) {
                    maxAge = Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
                }

                response.setHeader("Cache-Control", new StringBuilder(55).append("max-age=").append(maxAge)
                        .append(",public,no-transform,must-revalidate").toString());
            } // end if (getMethod && cacheInfo != null)

            if (encodedOcspResp != null) {
                response.getOutputStream().write(encodedOcspResp);
            } else {
                ASN1OutputStream asn1Out = new ASN1OutputStream(response.getOutputStream());
                asn1Out.writeObject(resp.toASN1Structure());
                asn1Out.flush();
            }
        } // end if (ocspRespWithCacheInfo)
    } catch (EOFException ex) {
        LogUtil.warn(LOG, ex, "Connection reset by peer");
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);
    } catch (Throwable th) {
        final String message = "Throwable thrown, this should not happen!";
        LogUtil.error(LOG, th, message);

        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        response.setContentLength(0);

        auditLevel = AuditLevel.ERROR;
        auditStatus = AuditStatus.FAILED;
        auditMessage = "internal error";
    } finally {
        try {
            response.flushBuffer();
        } catch (IOException ex) {
            final String message = "error while calling responsse.flushBuffer";
            LogUtil.error(LOG, ex, message);
            auditLevel = AuditLevel.ERROR;
            auditStatus = AuditStatus.FAILED;
            auditMessage = "internal error";
        } finally {
            if (event != null) {
                if (auditLevel != null) {
                    event.setLevel(auditLevel);
                }

                if (auditStatus != null) {
                    event.setStatus(auditStatus);
                }

                if (auditMessage != null) {
                    event.addEventData(OcspAuditConstants.NAME_message, auditMessage);
                }

                event.finish();
                auditService.logEvent(event);
            }
        } // end internal try
    } // end external try
}