Example usage for org.bouncycastle.cert.ocsp OCSPResp toASN1Structure

List of usage examples for org.bouncycastle.cert.ocsp OCSPResp toASN1Structure

Introduction

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

Prototype

public OCSPResponse toASN1Structure() 

Source Link

Usage

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  va  2  s . c om*/
    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
}