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);
}
}
Aggregations