Search in sources :

Example 1 with ScepResponder

use of org.xipki.ca.server.ScepResponder in project xipki by xipki.

the class HttpScepServlet method service0.

private void service0(HttpServletRequest req, HttpServletResponse resp, boolean viaPost) {
    String path = (String) req.getAttribute(HttpConstants.ATTR_XIPKI_PATH);
    String caAlias = null;
    String certprofileName = null;
    if (path.length() > 1) {
        String scepPath = path;
        if (scepPath.endsWith(CGI_PROGRAM)) {
            // skip also the first char (which is always '/')
            String tpath = scepPath.substring(1, scepPath.length() - CGI_PROGRAM_LEN);
            String[] tokens = tpath.split("/");
            if (tokens.length == 2) {
                caAlias = tokens[0];
                certprofileName = tokens[1].toLowerCase();
            }
        }
    // end if
    }
    if (caAlias == null || certprofileName == null) {
        sendError(resp, HttpServletResponse.SC_NOT_FOUND);
        return;
    }
    AuditService auditService = Audits.getAuditService();
    AuditEvent event = new AuditEvent(new Date());
    event.setApplicationName("SCEP");
    event.setName(CaAuditConstants.NAME_perf);
    event.addEventData(CaAuditConstants.Scep.NAME_name, caAlias + "/" + certprofileName);
    event.addEventData(CaAuditConstants.NAME_req_type, RequestType.SCEP.name());
    String msgId = RandomUtil.nextHexLong();
    event.addEventData(CaAuditConstants.NAME_mid, msgId);
    AuditLevel auditLevel = AuditLevel.INFO;
    AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
    String auditMessage = null;
    try {
        String caName = responderManager.getCaNameForAlias(caAlias);
        if (caName == null) {
            caName = caAlias.toLowerCase();
        }
        ScepResponder responder = responderManager.getScepResponder(caName);
        if (responder == null || !responder.isOnService()) {
            auditMessage = "unknown SCEP '" + caAlias + "/" + certprofileName + "'";
            LOG.warn(auditMessage);
            auditStatus = AuditStatus.FAILED;
            sendError(resp, HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        String operation = req.getParameter("operation");
        event.addEventData(CaAuditConstants.Scep.NAME_operation, operation);
        byte[] requestBytes;
        byte[] respBody;
        String contentType;
        if ("PKIOperation".equalsIgnoreCase(operation)) {
            CMSSignedData reqMessage;
            // parse the request
            try {
                if (viaPost) {
                    requestBytes = IoUtil.read(req.getInputStream());
                } else {
                    String b64 = req.getParameter("message");
                    requestBytes = Base64.decode(b64);
                }
                reqMessage = new CMSSignedData(requestBytes);
            } catch (Exception ex) {
                final String msg = "invalid request";
                LogUtil.error(LOG, ex, msg);
                auditMessage = msg;
                auditStatus = AuditStatus.FAILED;
                sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
                return;
            }
            ContentInfo ci;
            try {
                ci = responder.servicePkiOperation(reqMessage, certprofileName, msgId, event);
            } catch (MessageDecodingException ex) {
                final String msg = "could not decrypt and/or verify the request";
                LogUtil.error(LOG, ex, msg);
                auditMessage = msg;
                auditStatus = AuditStatus.FAILED;
                sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
                return;
            } catch (OperationException ex) {
                ErrorCode code = ex.getErrorCode();
                int httpCode;
                switch(code) {
                    case ALREADY_ISSUED:
                    case CERT_REVOKED:
                    case CERT_UNREVOKED:
                        httpCode = HttpServletResponse.SC_FORBIDDEN;
                        break;
                    case BAD_CERT_TEMPLATE:
                    case BAD_REQUEST:
                    case BAD_POP:
                    case INVALID_EXTENSION:
                    case UNKNOWN_CERT:
                    case UNKNOWN_CERT_PROFILE:
                        httpCode = HttpServletResponse.SC_BAD_REQUEST;
                        break;
                    case NOT_PERMITTED:
                        httpCode = HttpServletResponse.SC_UNAUTHORIZED;
                        break;
                    case SYSTEM_UNAVAILABLE:
                        httpCode = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
                        break;
                    case CRL_FAILURE:
                    case DATABASE_FAILURE:
                    case SYSTEM_FAILURE:
                        httpCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                        break;
                    default:
                        httpCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                        break;
                }
                auditMessage = ex.getMessage();
                LogUtil.error(LOG, ex, auditMessage);
                auditStatus = AuditStatus.FAILED;
                sendError(resp, httpCode);
                return;
            }
            respBody = ci.getEncoded();
            contentType = CT_RESPONSE;
        } else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
            // CA-Ident is ignored
            requestBytes = null;
            contentType = ScepConstants.CT_TEXT_PLAIN;
            respBody = responder.getCaCaps().getBytes();
        } else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
            // CA-Ident is ignored
            requestBytes = null;
            contentType = ScepConstants.CT_X509_CA_RA_CERT;
            respBody = responder.getCaCertResp().getBytes();
        } else if (Operation.GetNextCACert.getCode().equalsIgnoreCase(operation)) {
            auditMessage = "SCEP operation '" + operation + "' is not permitted";
            auditStatus = AuditStatus.FAILED;
            sendError(resp, HttpServletResponse.SC_FORBIDDEN);
            return;
        } else {
            auditMessage = "unknown SCEP operation '" + operation + "'";
            auditStatus = AuditStatus.FAILED;
            sendError(resp, HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        if (logReqResp && LOG.isDebugEnabled()) {
            if (viaPost) {
                LOG.debug("HTTP POST CA SCEP path: {}\nRequest:\n{}\nResponse:\n{}", req.getRequestURI(), LogUtil.base64Encode(requestBytes), LogUtil.base64Encode(respBody));
            } else {
                LOG.debug("HTTP GET CA SCEP path: {}\nResponse:\n{}", req.getRequestURI(), LogUtil.base64Encode(respBody));
            }
        }
        sendOKResponse(resp, contentType, respBody);
    } catch (Throwable th) {
        if (th instanceof EOFException) {
            final String msg = "connection reset by peer";
            if (LOG.isWarnEnabled()) {
                LogUtil.warn(LOG, th, msg);
            }
            LOG.debug(msg, th);
        } else {
            LOG.error("Throwable thrown, this should not happen!", th);
        }
        auditLevel = AuditLevel.ERROR;
        auditStatus = AuditStatus.FAILED;
        auditMessage = "internal error";
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    } finally {
        audit(auditService, event, auditLevel, auditStatus, auditMessage);
    }
}
Also used : ScepResponder(org.xipki.ca.server.ScepResponder) CMSSignedData(org.bouncycastle.cms.CMSSignedData) Date(java.util.Date) ServletException(javax.servlet.ServletException) MessageDecodingException(org.xipki.scep.message.MessageDecodingException) IOException(java.io.IOException) EOFException(java.io.EOFException) OperationException(org.xipki.ca.api.OperationException) MessageDecodingException(org.xipki.scep.message.MessageDecodingException) ContentInfo(org.bouncycastle.asn1.cms.ContentInfo) EOFException(java.io.EOFException) ErrorCode(org.xipki.ca.api.OperationException.ErrorCode) OperationException(org.xipki.ca.api.OperationException)

Aggregations

EOFException (java.io.EOFException)1 IOException (java.io.IOException)1 Date (java.util.Date)1 ServletException (javax.servlet.ServletException)1 ContentInfo (org.bouncycastle.asn1.cms.ContentInfo)1 CMSSignedData (org.bouncycastle.cms.CMSSignedData)1 OperationException (org.xipki.ca.api.OperationException)1 ErrorCode (org.xipki.ca.api.OperationException.ErrorCode)1 ScepResponder (org.xipki.ca.server.ScepResponder)1 MessageDecodingException (org.xipki.scep.message.MessageDecodingException)1