use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project xipki by xipki.
the class ScepServlet method service.
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
boolean post;
String method = req.getMethod();
if ("GET".equals(method)) {
post = false;
} else if ("POST".equals(method)) {
post = true;
} else {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
AuditEvent event = new AuditEvent();
event.setName(AuditEvent.NAME_PERF);
event.putEventData(AuditEvent.NAME_servletPath, req.getServletPath());
AuditLevel auditLevel = AuditLevel.INFO;
String auditMessage = null;
try {
CaCaps caCaps = responder.getCaCaps();
if (post && !caCaps.supportsPost()) {
auditMessage = "HTTP POST is not supported";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
String operation = req.getParameter("operation");
event.putEventData(AuditEvent.NAME_operation, operation);
if ("PKIOperation".equalsIgnoreCase(operation)) {
CMSSignedData reqMessage;
// parse the request
try {
byte[] content = post ? IoUtil.read(req.getInputStream()) : Base64.decode(req.getParameter("message"));
reqMessage = new CMSSignedData(content);
} catch (Exception ex) {
auditMessage = "invalid request";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
ContentInfo ci;
try {
ci = responder.servicePkiOperation(reqMessage, event);
} catch (MessageDecodingException ex) {
auditMessage = "could not decrypt and/or verify the request";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
} catch (CaException ex) {
ex.printStackTrace();
auditMessage = "system internal error";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
byte[] respBytes = ci.getEncoded();
sendToResponse(resp, CT_RESPONSE, respBytes);
} else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] caCapsBytes = responder.getCaCaps().getBytes();
sendToResponse(resp, ScepConstants.CT_TEXT_PLAIN, caCapsBytes);
} else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] respBytes;
String ct;
if (responder.getRaEmulator() == null) {
ct = ScepConstants.CT_X509_CA_CERT;
respBytes = responder.getCaEmulator().getCaCertBytes();
} else {
ct = ScepConstants.CT_X509_CA_RA_CERT;
CMSSignedDataGenerator cmsSignedDataGen = new CMSSignedDataGenerator();
try {
cmsSignedDataGen.addCertificate(responder.getCaEmulator().getCaCert().toBcCert());
ct = ScepConstants.CT_X509_CA_RA_CERT;
cmsSignedDataGen.addCertificate(responder.getRaEmulator().getRaCert().toBcCert());
CMSSignedData degenerateSignedData = cmsSignedDataGen.generate(new CMSAbsentContent());
respBytes = degenerateSignedData.getEncoded();
} catch (CMSException ex) {
ex.printStackTrace();
auditMessage = "system internal error";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
}
sendToResponse(resp, ct, respBytes);
} else if (Operation.GetNextCACert.getCode().equalsIgnoreCase(operation)) {
if (responder.getNextCaAndRa() == null) {
auditMessage = "SCEP operation '" + operation + "' is not permitted";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
try {
NextCaMessage nextCaMsg = new NextCaMessage();
nextCaMsg.setCaCert(responder.getNextCaAndRa().getCaCert());
if (responder.getNextCaAndRa().getRaCert() != null) {
X509Cert raCert = responder.getNextCaAndRa().getRaCert();
nextCaMsg.setRaCerts(Collections.singletonList(raCert));
}
ContentInfo signedData = responder.encode(nextCaMsg);
byte[] respBytes = signedData.getEncoded();
sendToResponse(resp, ScepConstants.CT_X509_NEXT_CA_CERT, respBytes);
} catch (Exception ex) {
ex.printStackTrace();
auditMessage = "system internal error";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
} else {
auditMessage = "unknown SCEP operation '" + operation + "'";
auditLevel = AuditLevel.ERROR;
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
// end if ("PKIOperation".equalsIgnoreCase(operation))
} catch (EOFException ex) {
LOG.warn("connection reset by peer", ex);
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (Throwable th) {
LOG.error("Throwable thrown, this should not happen!", th);
auditLevel = AuditLevel.ERROR;
auditMessage = "internal error";
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
if (event.getLevel() != AuditLevel.ERROR) {
event.setLevel(auditLevel);
}
if (auditMessage != null) {
event.putEventData("error", auditMessage);
}
event.log(LOG);
}
// end try
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project xipki by xipki.
the class Client method retrieveCaCertStore.
private static AuthorityCertStore retrieveCaCertStore(ScepHttpResponse resp, CaCertValidator caValidator) throws ScepClientException {
String ct = resp.getContentType();
X509Cert caCert = null;
List<X509Cert> raCerts = new LinkedList<>();
if (ScepConstants.CT_X509_CA_CERT.equalsIgnoreCase(ct)) {
try {
caCert = X509Util.parseCert(resp.getContentBytes());
} catch (CertificateEncodingException ex) {
throw new ScepClientException("error parsing certificate: " + ex.getMessage(), ex);
}
} else if (ScepConstants.CT_X509_CA_RA_CERT.equalsIgnoreCase(ct)) {
ContentInfo contentInfo = ContentInfo.getInstance(resp.getContentBytes());
SignedData signedData;
try {
signedData = SignedData.getInstance(contentInfo.getContent());
} catch (IllegalArgumentException ex) {
throw new ScepClientException("invalid SignedData message: " + ex.getMessage(), ex);
}
List<X509Cert> certs;
try {
certs = ScepUtil.getCertsFromSignedData(signedData);
} catch (CertificateException ex) {
throw new ScepClientException(ex.getMessage(), ex);
}
final int n = certs.size();
if (n < 2) {
throw new ScepClientException("at least 2 certificates are expected, but only " + n + " is available");
}
for (X509Cert cert : certs) {
if (cert.getBasicConstraints() > -1) {
if (caCert != null) {
throw new ScepClientException("multiple CA certificates is returned, but exactly 1 is expected");
}
caCert = cert;
} else {
raCerts.add(cert);
}
}
if (caCert == null) {
throw new ScepClientException("no CA certificate is returned");
}
} else {
throw new ScepClientException("invalid Content-Type '" + ct + "'");
}
if (!caValidator.isTrusted(caCert)) {
throw new ScepClientException("CA certificate '" + caCert.getSubjectRfc4519Text() + "' is not trusted");
}
if (raCerts.isEmpty()) {
return AuthorityCertStore.getInstance(caCert);
}
AuthorityCertStore cs = AuthorityCertStore.getInstance(caCert, raCerts.toArray(new X509Cert[0]));
X509Cert raEncCert = cs.getEncryptionCert();
X509Cert raSignCert = cs.getSignatureCert();
try {
if (!X509Util.issues(caCert, raEncCert)) {
throw new ScepClientException("RA certificate '" + raEncCert.getSubjectRfc4519Text() + " is not issued by the CA");
}
if (raSignCert != raEncCert && X509Util.issues(caCert, raSignCert)) {
throw new ScepClientException("RA certificate '" + raSignCert.getSubjectRfc4519Text() + " is not issued by the CA");
}
} catch (CertificateException ex) {
throw new ScepClientException("invalid certificate: " + ex.getMessage(), ex);
}
return cs;
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project xipki by xipki.
the class Client method scepGetCert.
// method scepGetCrl
public List<X509Cert> scepGetCert(PrivateKey identityKey, X509Cert identityCert, X500Name issuer, BigInteger serialNumber) throws ScepClientException {
Args.notNull(identityKey, "identityKey");
Args.notNull(identityCert, "identityCert");
Args.notNull(issuer, "issuer");
Args.notNull(serialNumber, "serialNumber");
initIfNotInited();
PkiMessage request = new PkiMessage(TransactionId.randomTransactionId(), MessageType.GetCert);
IssuerAndSerialNumber isn = new IssuerAndSerialNumber(issuer, serialNumber);
request.setMessageData(isn);
ContentInfo envRequest = encryptThenSign(request, identityKey, identityCert);
ScepHttpResponse httpResp = httpSend(Operation.PKIOperation, envRequest);
CMSSignedData cmsSignedData = parsePkiMessage(httpResp.getContentBytes());
DecodedPkiMessage response = decode(cmsSignedData, identityKey, identityCert);
if (response.getPkiStatus() != PkiStatus.SUCCESS) {
throw new ScepClientException("server returned " + response.getPkiStatus());
}
ContentInfo messageData = ContentInfo.getInstance(response.getMessageData());
try {
return ScepUtil.getCertsFromSignedData(SignedData.getInstance(messageData.getContent()));
} catch (CertificateException ex) {
throw new ScepClientException(ex.getMessage(), ex);
}
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project xipki by xipki.
the class Client method scepCertPoll.
// method scepCertPoll
public EnrolmentResponse scepCertPoll(PrivateKey identityKey, X509Cert identityCert, TransactionId transactionId, X500Name issuer, X500Name subject) throws ScepClientException {
Args.notNull(identityKey, "identityKey");
Args.notNull(identityCert, "identityCert");
Args.notNull(issuer, "issuer");
Args.notNull(transactionId, "transactionId");
initIfNotInited();
PkiMessage pkiMessage = new PkiMessage(transactionId, MessageType.CertPoll);
IssuerAndSubject is = new IssuerAndSubject(issuer, subject);
pkiMessage.setMessageData(is);
ContentInfo envRequest = encryptThenSign(pkiMessage, identityKey, identityCert);
ScepHttpResponse httpResp = httpSend(Operation.PKIOperation, envRequest);
CMSSignedData cmsSignedData = parsePkiMessage(httpResp.getContentBytes());
DecodedPkiMessage response = decode(cmsSignedData, identityKey, identityCert);
assertSameNonce(pkiMessage, response);
return new EnrolmentResponse(response);
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo 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