use of org.xipki.ca.server.impl.CertTemplateData in project xipki by xipki.
the class X509CaCmpResponderImpl method processP10cr.
// method processCertReqMessages
/**
* handle the PKI body with the choice {@code p10cr}<br/>
* Since it is not possible to add attribute to the PKCS#10 request (CSR), the certificate
* profile must be specified in the attribute regInfo-utf8Pairs (1.3.6.1.5.5.7.5.2.1) within
* PKIHeader.generalInfo
*/
private PKIBody processP10cr(PKIMessage request, CmpRequestorInfo requestor, ASN1OctetString tid, PKIHeader reqHeader, CertificationRequest p10cr, CmpControl cmpControl, String msgId, AuditEvent event) {
// verify the POP first
CertResponse certResp;
ASN1Integer certReqId = new ASN1Integer(-1);
boolean certGenerated = false;
X509Ca ca = getCa();
if (!securityFactory.verifyPopo(p10cr, getCmpControl().getPopoAlgoValidator())) {
LOG.warn("could not validate POP for the pkcs#10 requst");
certResp = buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "invalid POP");
} else {
CertificationRequestInfo certTemp = p10cr.getCertificationRequestInfo();
Extensions extensions = CaUtil.getExtensions(certTemp);
X500Name subject = certTemp.getSubject();
SubjectPublicKeyInfo publicKeyInfo = certTemp.getSubjectPublicKeyInfo();
CmpUtf8Pairs keyvalues = CmpUtil.extract(reqHeader.getGeneralInfo());
String certprofileName = null;
Date notBefore = null;
Date notAfter = null;
if (keyvalues != null) {
certprofileName = keyvalues.value(CmpUtf8Pairs.KEY_CERTPROFILE);
String str = keyvalues.value(CmpUtf8Pairs.KEY_NOTBEFORE);
if (str != null) {
notBefore = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
}
str = keyvalues.value(CmpUtf8Pairs.KEY_NOTAFTER);
if (str != null) {
notAfter = DateUtil.parseUtcTimeyyyyMMddhhmmss(str);
}
}
if (certprofileName == null) {
certResp = buildErrorCertResponse(certReqId, PKIFailureInfo.badCertTemplate, "badCertTemplate", null);
} else {
certprofileName = certprofileName.toLowerCase();
if (!requestor.isCertProfilePermitted(certprofileName)) {
String msg = "certprofile " + certprofileName + " is not allowed";
certResp = buildErrorCertResponse(certReqId, PKIFailureInfo.notAuthorized, msg);
} else {
CertTemplateData certTemplateData = new CertTemplateData(subject, publicKeyInfo, notBefore, notAfter, extensions, certprofileName);
certResp = generateCertificates(Arrays.asList(certTemplateData), Arrays.asList(certReqId), requestor, tid, false, request, cmpControl, msgId, event).get(0);
certGenerated = true;
}
}
}
CMPCertificate[] caPubs = null;
if (certGenerated && cmpControl.isSendCaCert()) {
caPubs = new CMPCertificate[] { ca.getCaInfo().getCertInCmpFormat() };
}
CertRepMessage repMessage = new CertRepMessage(caPubs, new CertResponse[] { certResp });
return new PKIBody(PKIBody.TYPE_CERT_REP, repMessage);
}
use of org.xipki.ca.server.impl.CertTemplateData in project xipki by xipki.
the class X509CaCmpResponderImpl method processCertReqMessages.
private CertRepMessage processCertReqMessages(PKIMessage request, CmpRequestorInfo requestor, ASN1OctetString tid, PKIHeader reqHeader, CertReqMessages kur, boolean keyUpdate, CmpControl cmpControl, String msgId, AuditEvent event) {
CmpRequestorInfo tmpRequestor = (CmpRequestorInfo) requestor;
CertReqMsg[] certReqMsgs = kur.toCertReqMsgArray();
final int n = certReqMsgs.length;
Map<Integer, CertTemplateData> certTemplateDatas = new HashMap<>(n * 10 / 6);
Map<Integer, CertResponse> certResponses = new HashMap<>(n * 10 / 6);
Map<Integer, ASN1Integer> certReqIds = new HashMap<>(n * 10 / 6);
// pre-process requests
for (int i = 0; i < n; i++) {
if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != i) {
// last certReqMsg cannot be used to enroll certificate
break;
}
CertReqMsg reqMsg = certReqMsgs[i];
CertificateRequestMessage req = new CertificateRequestMessage(reqMsg);
ASN1Integer certReqId = reqMsg.getCertReq().getCertReqId();
certReqIds.put(i, certReqId);
if (!req.hasProofOfPossession()) {
certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "no POP", null));
continue;
}
if (!verifyPopo(req, tmpRequestor.isRa())) {
LOG.warn("could not validate POP for request {}", certReqId.getValue());
certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badPOP, "invalid POP", null));
continue;
}
CmpUtf8Pairs keyvalues = CmpUtil.extract(reqMsg.getRegInfo());
String certprofileName = (keyvalues == null) ? null : keyvalues.value(CmpUtf8Pairs.KEY_CERTPROFILE);
if (certprofileName == null) {
String msg = "no certificate profile";
certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.badCertTemplate, msg));
continue;
}
certprofileName = certprofileName.toLowerCase();
if (!tmpRequestor.isCertProfilePermitted(certprofileName)) {
String msg = "certprofile " + certprofileName + " is not allowed";
certResponses.put(i, buildErrorCertResponse(certReqId, PKIFailureInfo.notAuthorized, msg));
continue;
}
CertTemplate certTemp = req.getCertTemplate();
OptionalValidity validity = certTemp.getValidity();
Date notBefore = null;
Date notAfter = null;
if (validity != null) {
Time time = validity.getNotBefore();
if (time != null) {
notBefore = time.getDate();
}
time = validity.getNotAfter();
if (time != null) {
notAfter = time.getDate();
}
}
CertTemplateData certTempData = new CertTemplateData(certTemp.getSubject(), certTemp.getPublicKey(), notBefore, notAfter, certTemp.getExtensions(), certprofileName);
certTemplateDatas.put(i, certTempData);
}
if (certResponses.size() == n) {
// all error
CertResponse[] certResps = new CertResponse[n];
for (int i = 0; i < n; i++) {
certResps[i] = certResponses.get(i);
}
return new CertRepMessage(null, certResps);
}
if (cmpControl.isGroupEnroll() && certTemplateDatas.size() != n) {
// at least one certRequest cannot be used to enroll certificate
int lastFailureIndex = certTemplateDatas.size();
BigInteger failCertReqId = certReqIds.get(lastFailureIndex).getPositiveValue();
CertResponse failCertResp = certResponses.get(lastFailureIndex);
PKIStatus failStatus = PKIStatus.getInstance(new ASN1Integer(failCertResp.getStatus().getStatus()));
PKIFailureInfo failureInfo = new PKIFailureInfo(failCertResp.getStatus().getFailInfo());
CertResponse[] certResps = new CertResponse[n];
for (int i = 0; i < n; i++) {
if (i == lastFailureIndex) {
certResps[i] = failCertResp;
continue;
}
ASN1Integer certReqId = certReqIds.get(i);
String msg = "error in certReq " + failCertReqId;
PKIStatusInfo tmpStatus = generateRejectionStatus(failStatus, failureInfo.intValue(), msg);
certResps[i] = new CertResponse(certReqId, tmpStatus);
}
return new CertRepMessage(null, certResps);
}
final int k = certTemplateDatas.size();
List<CertTemplateData> certTemplateList = new ArrayList<>(k);
List<ASN1Integer> certReqIdList = new ArrayList<>(k);
Map<Integer, Integer> reqIndexToCertIndexMap = new HashMap<>(k * 10 / 6);
for (int i = 0; i < n; i++) {
if (!certTemplateDatas.containsKey(i)) {
continue;
}
certTemplateList.add(certTemplateDatas.get(i));
certReqIdList.add(certReqIds.get(i));
reqIndexToCertIndexMap.put(i, certTemplateList.size() - 1);
}
List<CertResponse> generateCertResponses = generateCertificates(certTemplateList, certReqIdList, tmpRequestor, tid, keyUpdate, request, cmpControl, msgId, event);
boolean anyCertEnrolled = false;
CertResponse[] certResps = new CertResponse[n];
for (int i = 0; i < n; i++) {
if (certResponses.containsKey(i)) {
certResps[i] = certResponses.get(i);
} else {
int respIndex = reqIndexToCertIndexMap.get(i);
certResps[i] = generateCertResponses.get(respIndex);
if (!anyCertEnrolled && certResps[i].getCertifiedKeyPair() != null) {
anyCertEnrolled = true;
}
}
}
CMPCertificate[] caPubs = null;
if (anyCertEnrolled && cmpControl.isSendCaCert()) {
caPubs = new CMPCertificate[] { getCa().getCaInfo().getCertInCmpFormat() };
}
return new CertRepMessage(caPubs, certResps);
}
use of org.xipki.ca.server.impl.CertTemplateData in project xipki by xipki.
the class X509CaCmpResponderImpl method generateCertificates.
// method processP10cr
private List<CertResponse> generateCertificates(List<CertTemplateData> certTemplates, List<ASN1Integer> certReqIds, CmpRequestorInfo requestor, ASN1OctetString tid, boolean keyUpdate, PKIMessage request, CmpControl cmpControl, String msgId, AuditEvent event) {
X509Ca ca = getCa();
final int n = certTemplates.size();
List<CertResponse> ret = new ArrayList<>(n);
if (cmpControl.isGroupEnroll()) {
try {
List<X509CertificateInfo> certInfos;
if (keyUpdate) {
certInfos = ca.regenerateCertificates(certTemplates, requestor, RequestType.CMP, tid.getOctets(), msgId);
} else {
certInfos = ca.generateCertificates(certTemplates, requestor, RequestType.CMP, tid.getOctets(), msgId);
}
// save the request
Long reqDbId = null;
if (ca.getCaInfo().isSaveRequest()) {
try {
byte[] encodedRequest = request.getEncoded();
reqDbId = ca.addRequest(encodedRequest);
} catch (Exception ex) {
LOG.warn("could not save request");
}
}
for (int i = 0; i < n; i++) {
X509CertificateInfo certInfo = certInfos.get(i);
ret.add(postProcessCertInfo(certReqIds.get(i), certInfo, tid, cmpControl));
if (reqDbId != null) {
ca.addRequestCert(reqDbId, certInfo.getCert().getCertId());
}
}
} catch (OperationException ex) {
for (int i = 0; i < n; i++) {
ret.add(postProcessException(certReqIds.get(i), ex));
}
}
} else {
Long reqDbId = null;
boolean savingRequestFailed = false;
for (int i = 0; i < n; i++) {
CertTemplateData certTemplate = certTemplates.get(i);
ASN1Integer certReqId = certReqIds.get(i);
X509CertificateInfo certInfo;
try {
if (keyUpdate) {
certInfo = ca.regenerateCertificate(certTemplate, requestor, RequestType.CMP, tid.getOctets(), msgId);
} else {
certInfo = ca.generateCertificate(certTemplate, requestor, RequestType.CMP, tid.getOctets(), msgId);
}
if (ca.getCaInfo().isSaveRequest()) {
if (reqDbId == null && !savingRequestFailed) {
try {
byte[] encodedRequest = request.getEncoded();
reqDbId = ca.addRequest(encodedRequest);
} catch (Exception ex) {
savingRequestFailed = true;
LOG.warn("could not save request");
}
}
if (reqDbId != null) {
ca.addRequestCert(reqDbId, certInfo.getCert().getCertId());
}
}
ret.add(postProcessCertInfo(certReqId, certInfo, tid, cmpControl));
} catch (OperationException ex) {
ret.add(postProcessException(certReqId, ex));
}
}
}
return ret;
}
use of org.xipki.ca.server.impl.CertTemplateData in project xipki by xipki.
the class RestImpl method service.
public RestResponse service(String path, AuditEvent event, byte[] request, HttpRequestMetadataRetriever httpRetriever) {
event.setApplicationName(CaAuditConstants.APPNAME);
event.setName(CaAuditConstants.NAME_PERF);
event.addEventData(CaAuditConstants.NAME_reqType, RequestType.REST.name());
String msgId = RandomUtil.nextHexLong();
event.addEventData(CaAuditConstants.NAME_mid, msgId);
AuditLevel auditLevel = AuditLevel.INFO;
AuditStatus auditStatus = AuditStatus.SUCCESSFUL;
String auditMessage = null;
try {
if (responderManager == null) {
String message = "responderManager in servlet not configured";
LOG.error(message);
throw new HttpRespAuditException(HttpResponseStatus.INTERNAL_SERVER_ERROR, null, message, AuditLevel.ERROR, AuditStatus.FAILED);
}
String caName = null;
String command = null;
X509Ca ca = null;
if (path.length() > 1) {
// the first char is always '/'
String coreUri = path;
int sepIndex = coreUri.indexOf('/', 1);
if (sepIndex == -1 || sepIndex == coreUri.length() - 1) {
String message = "invalid path " + path;
LOG.error(message);
throw new HttpRespAuditException(HttpResponseStatus.NOT_FOUND, null, message, AuditLevel.ERROR, AuditStatus.FAILED);
}
// skip also the first char ('/')
String caAlias = coreUri.substring(1, sepIndex);
command = coreUri.substring(sepIndex + 1);
caName = responderManager.getCaNameForAlias(caAlias);
if (caName == null) {
caName = caAlias.toLowerCase();
}
ca = ((X509CaCmpResponderImpl) responderManager.getX509CaResponder(caName)).getCa();
}
if (caName == null || ca == null || ca.getCaInfo().getStatus() != CaStatus.ACTIVE) {
String message;
if (caName == null) {
message = "no CA is specified";
} else if (ca == null) {
message = "unknown CA '" + caName + "'";
} else {
message = "CA '" + caName + "' is out of service";
}
LOG.warn(message);
throw new HttpRespAuditException(HttpResponseStatus.NOT_FOUND, null, message, AuditLevel.INFO, AuditStatus.FAILED);
}
event.addEventData(CaAuditConstants.NAME_ca, ca.getCaIdent().getName());
event.addEventType(command);
RequestorInfo requestor;
// Retrieve the user:password
String hdrValue = httpRetriever.getHeader("Authorization");
if (hdrValue != null && hdrValue.startsWith("Basic ")) {
String user = null;
byte[] password = null;
if (hdrValue.length() > 6) {
String b64 = hdrValue.substring(6);
byte[] userPwd = Base64.decodeFast(b64);
int idx = -1;
for (int i = 0; i < userPwd.length; i++) {
if (userPwd[i] == ':') {
idx = i;
break;
}
}
if (idx != -1 && idx < userPwd.length - 1) {
user = new String(Arrays.copyOfRange(userPwd, 0, idx));
password = Arrays.copyOfRange(userPwd, idx + 1, userPwd.length);
}
}
if (user == null) {
throw new HttpRespAuditException(HttpResponseStatus.UNAUTHORIZED, "invalid Authorization information", AuditLevel.INFO, AuditStatus.FAILED);
}
NameId userIdent = ca.authenticateUser(user, password);
if (userIdent == null) {
throw new HttpRespAuditException(HttpResponseStatus.UNAUTHORIZED, "could not authenticate user", AuditLevel.INFO, AuditStatus.FAILED);
}
requestor = ca.getByUserRequestor(userIdent);
} else {
X509Certificate clientCert = httpRetriever.getTlsClientCert();
if (clientCert == null) {
throw new HttpRespAuditException(HttpResponseStatus.UNAUTHORIZED, null, "no client certificate", AuditLevel.INFO, AuditStatus.FAILED);
}
requestor = ca.getRequestor(clientCert);
}
if (requestor == null) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "no requestor specified");
}
event.addEventData(CaAuditConstants.NAME_requestor, requestor.getIdent().getName());
String respCt = null;
byte[] respBytes = null;
if (RestAPIConstants.CMD_cacert.equalsIgnoreCase(command)) {
respCt = RestAPIConstants.CT_pkix_cert;
respBytes = ca.getCaInfo().getCert().getEncodedCert();
} else if (RestAPIConstants.CMD_enroll_cert.equalsIgnoreCase(command)) {
String profile = httpRetriever.getParameter(RestAPIConstants.PARAM_profile);
if (StringUtil.isBlank(profile)) {
throw new HttpRespAuditException(HttpResponseStatus.BAD_REQUEST, null, "required parameter " + RestAPIConstants.PARAM_profile + " not specified", AuditLevel.INFO, AuditStatus.FAILED);
}
profile = profile.toLowerCase();
try {
requestor.assertPermitted(PermissionConstants.ENROLL_CERT);
} catch (InsuffientPermissionException ex) {
throw new OperationException(ErrorCode.NOT_PERMITTED, ex.getMessage());
}
if (!requestor.isCertProfilePermitted(profile)) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "certProfile " + profile + " is not allowed");
}
String ct = httpRetriever.getHeader("Content-Type");
if (!RestAPIConstants.CT_pkcs10.equalsIgnoreCase(ct)) {
String message = "unsupported media type " + ct;
throw new HttpRespAuditException(HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE, message, AuditLevel.INFO, AuditStatus.FAILED);
}
String strNotBefore = httpRetriever.getParameter(RestAPIConstants.PARAM_not_before);
Date notBefore = (strNotBefore == null) ? null : DateUtil.parseUtcTimeyyyyMMddhhmmss(strNotBefore);
String strNotAfter = httpRetriever.getParameter(RestAPIConstants.PARAM_not_after);
Date notAfter = (strNotAfter == null) ? null : DateUtil.parseUtcTimeyyyyMMddhhmmss(strNotAfter);
byte[] encodedCsr = request;
CertificationRequest csr = CertificationRequest.getInstance(encodedCsr);
ca.checkCsr(csr);
CertificationRequestInfo certTemp = csr.getCertificationRequestInfo();
X500Name subject = certTemp.getSubject();
SubjectPublicKeyInfo publicKeyInfo = certTemp.getSubjectPublicKeyInfo();
Extensions extensions = CaUtil.getExtensions(certTemp);
CertTemplateData certTemplate = new CertTemplateData(subject, publicKeyInfo, notBefore, notAfter, extensions, profile);
X509CertificateInfo certInfo = ca.generateCertificate(certTemplate, requestor, RequestType.REST, null, msgId);
if (ca.getCaInfo().isSaveRequest()) {
long dbId = ca.addRequest(encodedCsr);
ca.addRequestCert(dbId, certInfo.getCert().getCertId());
}
X509Cert cert = certInfo.getCert();
if (cert == null) {
String message = "could not generate certificate";
LOG.warn(message);
throw new HttpRespAuditException(HttpResponseStatus.INTERNAL_SERVER_ERROR, null, message, AuditLevel.INFO, AuditStatus.FAILED);
}
respCt = RestAPIConstants.CT_pkix_cert;
respBytes = cert.getEncodedCert();
} else if (RestAPIConstants.CMD_revoke_cert.equalsIgnoreCase(command) || RestAPIConstants.CMD_delete_cert.equalsIgnoreCase(command)) {
int permission;
if (RestAPIConstants.CMD_revoke_cert.equalsIgnoreCase(command)) {
permission = PermissionConstants.REVOKE_CERT;
} else {
permission = PermissionConstants.REMOVE_CERT;
}
try {
requestor.assertPermitted(permission);
} catch (InsuffientPermissionException ex) {
throw new OperationException(ErrorCode.NOT_PERMITTED, ex.getMessage());
}
String strCaSha1 = httpRetriever.getParameter(RestAPIConstants.PARAM_ca_sha1);
if (StringUtil.isBlank(strCaSha1)) {
throw new HttpRespAuditException(HttpResponseStatus.BAD_REQUEST, null, "required parameter " + RestAPIConstants.PARAM_ca_sha1 + " not specified", AuditLevel.INFO, AuditStatus.FAILED);
}
String strSerialNumber = httpRetriever.getParameter(RestAPIConstants.PARAM_serial_number);
if (StringUtil.isBlank(strSerialNumber)) {
throw new HttpRespAuditException(HttpResponseStatus.BAD_REQUEST, null, "required parameter " + RestAPIConstants.PARAM_serial_number + " not specified", AuditLevel.INFO, AuditStatus.FAILED);
}
if (!strCaSha1.equalsIgnoreCase(ca.getHexSha1OfCert())) {
throw new HttpRespAuditException(HttpResponseStatus.BAD_REQUEST, null, "unknown " + RestAPIConstants.PARAM_ca_sha1, AuditLevel.INFO, AuditStatus.FAILED);
}
BigInteger serialNumber = toBigInt(strSerialNumber);
if (RestAPIConstants.CMD_revoke_cert.equalsIgnoreCase(command)) {
String strReason = httpRetriever.getParameter(RestAPIConstants.PARAM_reason);
CrlReason reason = (strReason == null) ? CrlReason.UNSPECIFIED : CrlReason.forNameOrText(strReason);
if (reason == CrlReason.REMOVE_FROM_CRL) {
ca.unrevokeCertificate(serialNumber, msgId);
} else {
Date invalidityTime = null;
String strInvalidityTime = httpRetriever.getParameter(RestAPIConstants.PARAM_invalidity_time);
if (StringUtil.isNotBlank(strInvalidityTime)) {
invalidityTime = DateUtil.parseUtcTimeyyyyMMddhhmmss(strInvalidityTime);
}
ca.revokeCertificate(serialNumber, reason, invalidityTime, msgId);
}
} else if (RestAPIConstants.CMD_delete_cert.equalsIgnoreCase(command)) {
ca.removeCertificate(serialNumber, msgId);
}
} else if (RestAPIConstants.CMD_crl.equalsIgnoreCase(command)) {
try {
requestor.assertPermitted(PermissionConstants.GET_CRL);
} catch (InsuffientPermissionException ex) {
throw new OperationException(ErrorCode.NOT_PERMITTED, ex.getMessage());
}
String strCrlNumber = httpRetriever.getParameter(RestAPIConstants.PARAM_crl_number);
BigInteger crlNumber = null;
if (StringUtil.isNotBlank(strCrlNumber)) {
try {
crlNumber = toBigInt(strCrlNumber);
} catch (NumberFormatException ex) {
String message = "invalid crlNumber '" + strCrlNumber + "'";
LOG.warn(message);
throw new HttpRespAuditException(HttpResponseStatus.BAD_REQUEST, null, message, AuditLevel.INFO, AuditStatus.FAILED);
}
}
X509CRL crl = ca.getCrl(crlNumber);
if (crl == null) {
String message = "could not get CRL";
LOG.warn(message);
throw new HttpRespAuditException(HttpResponseStatus.INTERNAL_SERVER_ERROR, null, message, AuditLevel.INFO, AuditStatus.FAILED);
}
respCt = RestAPIConstants.CT_pkix_crl;
respBytes = crl.getEncoded();
} else if (RestAPIConstants.CMD_new_crl.equalsIgnoreCase(command)) {
try {
requestor.assertPermitted(PermissionConstants.GEN_CRL);
} catch (InsuffientPermissionException ex) {
throw new OperationException(ErrorCode.NOT_PERMITTED, ex.getMessage());
}
X509CRL crl = ca.generateCrlOnDemand(msgId);
if (crl == null) {
String message = "could not generate CRL";
LOG.warn(message);
throw new HttpRespAuditException(HttpResponseStatus.INTERNAL_SERVER_ERROR, null, message, AuditLevel.INFO, AuditStatus.FAILED);
}
respCt = RestAPIConstants.CT_pkix_crl;
respBytes = crl.getEncoded();
} else {
String message = "invalid command '" + command + "'";
LOG.error(message);
throw new HttpRespAuditException(HttpResponseStatus.NOT_FOUND, message, AuditLevel.INFO, AuditStatus.FAILED);
}
Map<String, String> headers = new HashMap<>();
headers.put(RestAPIConstants.HEADER_PKISTATUS, RestAPIConstants.PKISTATUS_accepted);
return new RestResponse(HttpResponseStatus.OK, respCt, headers, respBytes);
} catch (OperationException ex) {
ErrorCode code = ex.getErrorCode();
if (LOG.isWarnEnabled()) {
String msg = StringUtil.concat("generate certificate, OperationException: code=", code.name(), ", message=", ex.getErrorMessage());
LOG.warn(msg);
LOG.debug(msg, ex);
}
int sc;
String failureInfo;
switch(code) {
case ALREADY_ISSUED:
sc = HttpResponseStatus.BAD_REQUEST;
failureInfo = RestAPIConstants.FAILINFO_badRequest;
break;
case BAD_CERT_TEMPLATE:
sc = HttpResponseStatus.BAD_REQUEST;
failureInfo = RestAPIConstants.FAILINFO_badCertTemplate;
break;
case BAD_REQUEST:
sc = HttpResponseStatus.BAD_REQUEST;
failureInfo = RestAPIConstants.FAILINFO_badRequest;
break;
case CERT_REVOKED:
sc = HttpResponseStatus.CONFLICT;
failureInfo = RestAPIConstants.FAILINFO_certRevoked;
break;
case CRL_FAILURE:
sc = HttpResponseStatus.INTERNAL_SERVER_ERROR;
failureInfo = RestAPIConstants.FAILINFO_systemFailure;
break;
case DATABASE_FAILURE:
sc = HttpResponseStatus.INTERNAL_SERVER_ERROR;
failureInfo = RestAPIConstants.FAILINFO_systemFailure;
break;
case NOT_PERMITTED:
sc = HttpResponseStatus.UNAUTHORIZED;
failureInfo = RestAPIConstants.FAILINFO_notAuthorized;
break;
case INVALID_EXTENSION:
sc = HttpResponseStatus.BAD_REQUEST;
failureInfo = RestAPIConstants.FAILINFO_badRequest;
break;
case SYSTEM_FAILURE:
sc = HttpResponseStatus.INTERNAL_SERVER_ERROR;
failureInfo = RestAPIConstants.FAILINFO_systemFailure;
break;
case SYSTEM_UNAVAILABLE:
sc = HttpResponseStatus.SERVICE_UNAVAILABLE;
failureInfo = RestAPIConstants.FAILINFO_systemUnavail;
break;
case UNKNOWN_CERT:
sc = HttpResponseStatus.BAD_REQUEST;
failureInfo = RestAPIConstants.FAILINFO_badCertId;
break;
case UNKNOWN_CERT_PROFILE:
sc = HttpResponseStatus.BAD_REQUEST;
failureInfo = RestAPIConstants.FAILINFO_badCertTemplate;
break;
default:
sc = HttpResponseStatus.INTERNAL_SERVER_ERROR;
failureInfo = RestAPIConstants.FAILINFO_systemFailure;
break;
}
// end switch (code)
event.setStatus(AuditStatus.FAILED);
event.addEventData(CaAuditConstants.NAME_message, code.name());
switch(code) {
case DATABASE_FAILURE:
case SYSTEM_FAILURE:
auditMessage = code.name();
break;
default:
auditMessage = code.name() + ": " + ex.getErrorMessage();
break;
}
// end switch code
Map<String, String> headers = new HashMap<>();
headers.put(RestAPIConstants.HEADER_PKISTATUS, RestAPIConstants.PKISTATUS_rejection);
if (StringUtil.isNotBlank(failureInfo)) {
headers.put(RestAPIConstants.HEADER_failInfo, failureInfo);
}
return new RestResponse(sc, null, headers, null);
} catch (HttpRespAuditException ex) {
auditStatus = ex.getAuditStatus();
auditLevel = ex.getAuditLevel();
auditMessage = ex.getAuditMessage();
return new RestResponse(ex.getHttpStatus(), null, null, null);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
auditLevel = AuditLevel.ERROR;
auditStatus = AuditStatus.FAILED;
auditMessage = "internal error";
return new RestResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR, null, null, null);
} finally {
event.setStatus(auditStatus);
event.setLevel(auditLevel);
if (auditMessage != null) {
event.addEventData(CaAuditConstants.NAME_message, auditMessage);
}
}
}
use of org.xipki.ca.server.impl.CertTemplateData in project xipki by xipki.
the class ScepImpl method servicePkiOperation0.
// method servicePkiOperation
private PkiMessage servicePkiOperation0(CMSSignedData requestContent, DecodedPkiMessage req, String certProfileName, String msgId, AuditEvent event) throws MessageDecodingException, OperationException {
ParamUtil.requireNonNull("requestContent", requestContent);
ParamUtil.requireNonNull("req", req);
String tid = req.getTransactionId().getId();
// verify and decrypt the request
audit(event, CaAuditConstants.NAME_tid, tid);
if (req.getFailureMessage() != null) {
audit(event, CaAuditConstants.NAME_SCEP_failureMessage, req.getFailureMessage());
}
Boolean bo = req.isSignatureValid();
if (bo != null && !bo.booleanValue()) {
audit(event, CaAuditConstants.NAME_SCEP_signature, "invalid");
}
bo = req.isDecryptionSuccessful();
if (bo != null && !bo.booleanValue()) {
audit(event, CaAuditConstants.NAME_SCEP_decryption, "failed");
}
PkiMessage rep = new PkiMessage(req.getTransactionId(), MessageType.CertRep, Nonce.randomNonce());
rep.setRecipientNonce(req.getSenderNonce());
if (req.getFailureMessage() != null) {
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badRequest);
return rep;
}
bo = req.isSignatureValid();
if (bo != null && !bo.booleanValue()) {
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badMessageCheck);
return rep;
}
bo = req.isDecryptionSuccessful();
if (bo != null && !bo.booleanValue()) {
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badRequest);
return rep;
}
Date signingTime = req.getSigningTime();
if (maxSigningTimeBiasInMs > 0) {
boolean isTimeBad = false;
if (signingTime == null) {
isTimeBad = true;
} else {
long now = System.currentTimeMillis();
long diff = now - signingTime.getTime();
if (diff < 0) {
diff = -1 * diff;
}
isTimeBad = diff > maxSigningTimeBiasInMs;
}
if (isTimeBad) {
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badTime);
return rep;
}
}
// end if
// check the digest algorithm
String oid = req.getDigestAlgorithm().getId();
ScepHashAlgo hashAlgo = ScepHashAlgo.forNameOrOid(oid);
if (hashAlgo == null) {
LOG.warn("tid={}: unknown digest algorithm {}", tid, oid);
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badAlg);
return rep;
}
boolean supported = false;
if (hashAlgo == ScepHashAlgo.SHA1) {
if (caCaps.containsCapability(CaCapability.SHA1)) {
supported = true;
}
} else if (hashAlgo == ScepHashAlgo.SHA256) {
if (caCaps.containsCapability(CaCapability.SHA256)) {
supported = true;
}
} else if (hashAlgo == ScepHashAlgo.SHA512) {
if (caCaps.containsCapability(CaCapability.SHA512)) {
supported = true;
}
}
if (!supported) {
LOG.warn("tid={}: unsupported digest algorithm {}", tid, oid);
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badAlg);
return rep;
}
// check the content encryption algorithm
ASN1ObjectIdentifier encOid = req.getContentEncryptionAlgorithm();
if (CMSAlgorithm.DES_EDE3_CBC.equals(encOid)) {
if (!caCaps.containsCapability(CaCapability.DES3)) {
LOG.warn("tid={}: encryption with DES3 algorithm is not permitted", tid, encOid);
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badAlg);
return rep;
}
} else if (AES_ENC_ALGOS.contains(encOid)) {
if (!caCaps.containsCapability(CaCapability.AES)) {
LOG.warn("tid={}: encryption with AES algorithm {} is not permitted", tid, encOid);
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badAlg);
return rep;
}
} else {
LOG.warn("tid={}: encryption with algorithm {} is not permitted", tid, encOid);
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badAlg);
return rep;
}
X509Ca ca;
try {
ca = caManager.getX509Ca(caIdent);
} catch (CaMgmtException ex) {
LogUtil.error(LOG, ex, tid + "=" + tid + ",could not get X509CA");
throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex);
}
X500Name caX500Name = ca.getCaInfo().getCert().getSubjectAsX500Name();
try {
SignedData signedData;
MessageType mt = req.getMessageType();
audit(event, CaAuditConstants.NAME_SCEP_messageType, mt.toString());
switch(mt) {
case PKCSReq:
case RenewalReq:
case UpdateReq:
CertificationRequest csr = CertificationRequest.getInstance(req.getMessageData());
X500Name reqSubject = csr.getCertificationRequestInfo().getSubject();
if (LOG.isInfoEnabled()) {
LOG.info("tid={}, subject={}", tid, X509Util.getRfc4519Name(reqSubject));
}
try {
ca.checkCsr(csr);
} catch (OperationException ex) {
LogUtil.warn(LOG, ex, "tid=" + tid + " POPO verification failed");
throw FailInfoException.BAD_MESSAGE_CHECK;
}
CertificationRequestInfo csrReqInfo = csr.getCertificationRequestInfo();
X509Certificate reqSignatureCert = req.getSignatureCert();
X500Principal reqSigCertSubject = reqSignatureCert.getSubjectX500Principal();
boolean selfSigned = reqSigCertSubject.equals(reqSignatureCert.getIssuerX500Principal());
if (selfSigned) {
X500Name tmp = X500Name.getInstance(reqSigCertSubject.getEncoded());
if (!tmp.equals(csrReqInfo.getSubject())) {
LOG.warn("tid={}, self-signed identityCert.subject != csr.subject");
throw FailInfoException.BAD_REQUEST;
}
}
if (X509Util.getCommonName(csrReqInfo.getSubject()) == null) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "tid=" + tid + ": no CommonName in requested subject");
}
NameId userIdent = null;
String challengePwd = CaUtil.getChallengePassword(csrReqInfo);
if (challengePwd != null) {
String[] strs = challengePwd.split(":");
if (strs == null || strs.length != 2) {
LOG.warn("tid={}: challengePassword does not have the format <user>:<password>", tid);
throw FailInfoException.BAD_REQUEST;
}
String user = strs[0];
String password = strs[1];
userIdent = ca.authenticateUser(user, password.getBytes());
if (userIdent == null) {
LOG.warn("tid={}: could not authenticate user {}", tid, user);
throw FailInfoException.BAD_REQUEST;
}
}
if (selfSigned) {
if (MessageType.PKCSReq != mt) {
LOG.warn("tid={}: self-signed certificate is not permitted for" + " messageType {}", tid, mt);
throw FailInfoException.BAD_REQUEST;
}
if (userIdent == null) {
LOG.warn("tid={}: could not extract user & password from challengePassword" + ", which are required for self-signed signature certificate", tid);
throw FailInfoException.BAD_REQUEST;
}
} else {
// certificate is known by the CA
if (userIdent == null) {
// up to draft-nourse-scep-23 the client sends all messages to enroll
// certificate via MessageType PKCSReq
KnowCertResult knowCertRes = ca.knowsCertificate(reqSignatureCert);
if (!knowCertRes.isKnown()) {
LOG.warn("tid={}: signature certificate is not trusted by the CA", tid);
throw FailInfoException.BAD_REQUEST;
}
Integer userId = knowCertRes.getUserId();
if (userId == null) {
LOG.warn("tid={}: could not extract user from the signature cert", tid);
throw FailInfoException.BAD_REQUEST;
}
userIdent = ca.getUserIdent(userId);
}
// end if
}
// end if
ByUserRequestorInfo requestor = ca.getByUserRequestor(userIdent);
checkUserPermission(requestor, certProfileName);
byte[] tidBytes = getTransactionIdBytes(tid);
Extensions extensions = CaUtil.getExtensions(csrReqInfo);
CertTemplateData certTemplateData = new CertTemplateData(csrReqInfo.getSubject(), csrReqInfo.getSubjectPublicKeyInfo(), (Date) null, (Date) null, extensions, certProfileName);
X509CertificateInfo cert = ca.generateCertificate(certTemplateData, requestor, RequestType.SCEP, tidBytes, msgId);
/* Don't save SCEP message, since it contains password in plaintext
if (ca.getCaInfo().isSaveRequest() && cert.getCert().getCertId() != null) {
byte[] encodedRequest;
try {
encodedRequest = requestContent.getEncoded();
} catch (IOException ex) {
LOG.warn("could not encode request");
encodedRequest = null;
}
if (encodedRequest != null) {
long reqId = ca.addRequest(encodedRequest);
ca.addRequestCert(reqId, cert.getCert().getCertId());
}
}*/
signedData = buildSignedData(cert.getCert().getCert());
break;
case CertPoll:
IssuerAndSubject is = IssuerAndSubject.getInstance(req.getMessageData());
audit(event, CaAuditConstants.NAME_issuer, X509Util.getRfc4519Name(is.getIssuer()));
audit(event, CaAuditConstants.NAME_subject, X509Util.getRfc4519Name(is.getSubject()));
ensureIssuedByThisCa(caX500Name, is.getIssuer());
signedData = pollCert(ca, is.getSubject(), req.getTransactionId());
break;
case GetCert:
IssuerAndSerialNumber isn = IssuerAndSerialNumber.getInstance(req.getMessageData());
BigInteger serial = isn.getSerialNumber().getPositiveValue();
audit(event, CaAuditConstants.NAME_issuer, X509Util.getRfc4519Name(isn.getName()));
audit(event, CaAuditConstants.NAME_serial, LogUtil.formatCsn(serial));
ensureIssuedByThisCa(caX500Name, isn.getName());
signedData = getCert(ca, isn.getSerialNumber().getPositiveValue());
break;
case GetCRL:
isn = IssuerAndSerialNumber.getInstance(req.getMessageData());
serial = isn.getSerialNumber().getPositiveValue();
audit(event, CaAuditConstants.NAME_issuer, X509Util.getRfc4519Name(isn.getName()));
audit(event, CaAuditConstants.NAME_serial, LogUtil.formatCsn(serial));
ensureIssuedByThisCa(caX500Name, isn.getName());
signedData = getCrl(ca, serial);
break;
default:
LOG.error("unknown SCEP messageType '{}'", req.getMessageType());
throw FailInfoException.BAD_REQUEST;
}
// end switch<
ContentInfo ci = new ContentInfo(CMSObjectIdentifiers.signedData, signedData);
rep.setMessageData(ci);
rep.setPkiStatus(PkiStatus.SUCCESS);
} catch (FailInfoException ex) {
LogUtil.error(LOG, ex);
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(ex.getFailInfo());
}
return rep;
}
Aggregations