use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project mucommander by mucommander.
the class AbstractPkcsValidator method parseSignerData.
/**
* SignedData ::= SEQUENCE {
* 0, version CMSVersion,
* 1, digestAlgorithms DigestAlgorithmIdentifiers,
* 2, encapContentInfo EncapsulatedContentInfo,
* 3, certificateChain [0] IMPLICIT CertificateSet OPTIONAL,
* 4, crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
* 5, signerInfos SignerInfos }
* <p/>
* DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
* SignerInfos ::= SET OF SignerInfo
*/
protected void parseSignerData(ASN1Sequence signedData, byte[] cmsData) throws SignatureIntegrityException {
// digest algorithms ID, not currently using them but useful for debug.
if (logger.isLoggable(Level.FINER)) {
// should always be 1.
int cmsVersion = ((ASN1Integer) signedData.getObjectAt(0)).getValue().intValue();
logger.finest("CMS version: " + cmsVersion);
Enumeration<ASN1Sequence> enumeration = ((ASN1Set) signedData.getObjectAt(1)).getObjects();
while (enumeration.hasMoreElements()) {
String objectId = ((ASN1ObjectIdentifier) enumeration.nextElement().getObjectAt(0)).getId();
try {
String digestAlgorithmName = AlgorithmIdentifier.getDigestAlgorithmName(objectId);
MessageDigest tmp = AlgorithmIdentifier.getDigestInstance(objectId, null);
logger.finest("DigestAlgorithmIdentifiers: " + digestAlgorithmName + " " + objectId);
logger.finest(tmp.toString());
} catch (Throwable ex) {
logger.log(Level.WARNING, "Error finding iod: " + objectId, ex);
}
}
}
/**
* EncapsulatedContentInfo ::= SEQUENCE {
* eContentType ContentType,
* eContent [0] EXPLICIT OCTET STRING OPTIONAL }
*
* ContentType ::= OBJECT IDENTIFIER
*/
encapsulatedContentInfoData = null;
ASN1Sequence encapsulatedContentInfo = (ASN1Sequence) signedData.getObjectAt(2);
// grab just the first definitions, as we are looking for encapuslated data for PKCS7.sha1.
if (encapsulatedContentInfo.size() >= 2) {
// should still be iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 ...
ASN1ObjectIdentifier eObjectIdentifier = (ASN1ObjectIdentifier) encapsulatedContentInfo.getObjectAt(0);
String eObjectIdentifierId = eObjectIdentifier.getId();
if (logger.isLoggable(Level.FINER)) {
logger.finest("EncapsulatedContentInfo: " + eObjectIdentifierId + " " + Pkcs7Validator.getObjectIdName(eObjectIdentifierId));
}
// should be octets encode as pkcs#7
ASN1OctetString eContent = (ASN1OctetString) ((ASN1TaggedObject) encapsulatedContentInfo.getObjectAt(1)).getObject();
// shows up in pkcs7.sha1 only
encapsulatedContentInfoData = eContent.getOctets();
if (logger.isLoggable(Level.FINER)) {
logger.finest("EncapsulatedContentInfo Data " + eContent.toString());
}
} else if (encapsulatedContentInfo.size() == 1) {
if (logger.isLoggable(Level.FINER)) {
ASN1ObjectIdentifier eObjectIdentifier = (ASN1ObjectIdentifier) encapsulatedContentInfo.getObjectAt(0);
String eObjectIdentifierId = eObjectIdentifier.getId();
logger.finest("EncapsulatedContentInfo size is 1: " + eObjectIdentifierId + " " + Pkcs7Validator.getObjectIdName(eObjectIdentifierId));
}
}
// grab the signer info.
ASN1Sequence signerInfo = parseCertificateData(cmsData, signedData);
// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
digestAlgorithmIdentifier = ((ASN1ObjectIdentifier) ((ASN1Sequence) signerInfo.getObjectAt(2)).getObjectAt(0)).getId();
// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
// signedAttrs is optional so we look for the occurrence
//
// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute
//
// Attribute ::= SEQUENCE {
// attrType OBJECT IDENTIFIER,
// attrValues SET OF AttributeValue }
//
// AttributeValue ::= ANY
// SignatureValue ::= OCTET STRING
int nextEntry = 3;
messageDigest = null;
ASN1TaggedObject signedAttributes;
signedAttributesSequence = null;
if (signerInfo.getObjectAt(nextEntry) instanceof ASN1TaggedObject) {
signedAttributes = (ASN1TaggedObject) signerInfo.getObjectAt(nextEntry);
signedAttributesSequence = ASN1Set.getInstance(signedAttributes, false);
for (int i = 0, max = signedAttributesSequence.size(); i < max; ++i) {
// attribute type/value pair.
ASN1Sequence attributePair = (ASN1Sequence) signedAttributesSequence.getObjectAt(i);
// mainly just looking for the message digest.
if (((ASN1ObjectIdentifier) attributePair.getObjectAt(0)).getId().equals(PKCSObjectIdentifiers.pkcs_9_at_messageDigest.getId())) {
ASN1Set set = (ASN1Set) attributePair.getObjectAt(1);
messageDigest = ((ASN1OctetString) set.getObjectAt(0)).getOctets();
}
// try and pull out the signing time.
// currently not using this time.
// if (((ASN1ObjectIdentifier) attributePair.getObjectAt(0)).getId().equals(
// PKCSObjectIdentifiers.pkcs_9_at_signingTime.getId())) {
// ASN1Set set = (ASN1Set) attributePair.getObjectAt(1);
// ASN1UTCTime signerTime = ((ASN1UTCTime) set.getObjectAt(0));
// try {
// // see if the signer time matches the certificate validity times.
// System.out.println(" SignatureSigner Time " + signerTime.getDate());
// } catch (ParseException e) {
// e.printStackTrace();
// }
// }
// more attributes to come.
}
if (messageDigest == null) {
throw new SignatureIntegrityException("Message Digest can nut be null");
}
++nextEntry;
}
// signatureAlgorithm SignatureAlgorithmIdentifier,
signatureAlgorithmIdentifier = ((ASN1ObjectIdentifier) ((ASN1Sequence) signerInfo.getObjectAt(nextEntry)).getObjectAt(0)).getId();
nextEntry++;
// signature SignatureValue
signatureValue = ((ASN1OctetString) signerInfo.getObjectAt(nextEntry)).getOctets();
nextEntry++;
// once again optional so we check to see if the entry is available.
if (nextEntry < signerInfo.size() && signerInfo.getObjectAt(nextEntry) instanceof ASN1TaggedObject) {
ASN1TaggedObject unsignedAttributes = (ASN1TaggedObject) signerInfo.getObjectAt(nextEntry);
ASN1Set unsignedAttributeSequence = ASN1Set.getInstance(unsignedAttributes, false);
AttributeTable attributeTable = new AttributeTable(unsignedAttributeSequence);
Attribute timeStamp = attributeTable.get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken);
if (timeStamp != null && timeStamp.getAttrValues().size() > 0) {
ASN1Set attributeValues = timeStamp.getAttrValues();
ASN1Sequence tokenSequence = ASN1Sequence.getInstance(attributeValues.getObjectAt(0));
ContentInfo contentInfo = ContentInfo.getInstance(tokenSequence);
// if we can parse it we call it good, so cert has a embedded time but we don't do any validation on it
try {
new TimeStampToken(contentInfo);
isEmbeddedTimeStamp = true;
} catch (Throwable e1) {
throw new SignatureIntegrityException("Valid TimeStamp could now be created");
}
}
}
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project nhin-d by DirectProject.
the class SplitProviderDirectSignedDataGenerator method generate.
/**
* {@inheritDoc}
*/
@Override
public CMSSignedData generate(String signedContentType, CMSProcessable content, boolean encapsulate, String sigProvider, boolean addDefaultAttributes) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException {
final ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
final ASN1EncodableVector signerInfos = new ASN1EncodableVector();
// clear the current preserved digest state
_digests.clear();
//
// add the SignerInfo objects
//
DERObjectIdentifier contentTypeOID;
boolean isCounterSignature;
if (signedContentType != null) {
contentTypeOID = new DERObjectIdentifier(signedContentType);
isCounterSignature = false;
} else {
contentTypeOID = CMSObjectIdentifiers.data;
isCounterSignature = true;
}
for (DirectTargetedSignerInf signer : privateSigners) {
AlgorithmIdentifier digAlgId;
try {
digAlgId = new AlgorithmIdentifier(new DERObjectIdentifier(signer.digestOID), new DERNull());
digestAlgs.add(digAlgId);
try {
signerInfos.add(signer.toSignerInfo(contentTypeOID, content, rand, sigProvider, digestProvider, addDefaultAttributes, isCounterSignature));
} catch (ClassCastException e) {
// try again with the digest provider... the key may need to use a different provider than the sig provider
signerInfos.add(signer.toSignerInfo(contentTypeOID, content, rand, digestProvider, digestProvider, addDefaultAttributes, isCounterSignature));
}
} catch (IOException e) {
throw new CMSException("encoding error.", e);
} catch (InvalidKeyException e) {
throw new CMSException("key inappropriate for signature.", e);
} catch (SignatureException e) {
throw new CMSException("error creating signature.", e);
} catch (CertificateEncodingException e) {
throw new CMSException("error creating sid.", e);
}
}
ASN1Set certificates = null;
if (_certs.size() != 0) {
certificates = createBerSetFromList(_certs);
}
ASN1Set certrevlist = null;
if (_crls.size() != 0) {
certrevlist = createBerSetFromList(_crls);
}
ContentInfo encInfo;
if (encapsulate) {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try {
content.write(bOut);
} catch (IOException e) {
throw new CMSException("encapsulation error.", e);
}
ASN1OctetString octs = new BERConstructedOctetString(bOut.toByteArray());
encInfo = new ContentInfo(contentTypeOID, octs);
} else {
encInfo = new ContentInfo(contentTypeOID, null);
}
SignedData sd = new SignedData(new DERSet(digestAlgs), encInfo, certificates, certrevlist, new DERSet(signerInfos));
ContentInfo contentInfo = new ContentInfo(PKCSObjectIdentifiers.signedData, sd);
return new CMSSignedData(content, contentInfo);
}
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) throws ServletException, IOException {
AuditServiceRegister auditServiceRegister = ServletHelper.getAuditServiceRegister();
if (auditServiceRegister == null) {
LOG.error("ServletHelper.auditServiceRegister not configured");
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
ResponderManager responderManager = ServletHelper.getResponderManager();
if (responderManager == null) {
LOG.error("ServletHelper.responderManager not configured");
sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
String path = StringUtil.getRelativeRequestUri(req.getServletPath(), req.getRequestURI());
String scepName = 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) {
scepName = tokens[0];
certProfileName = tokens[1].toLowerCase();
}
}
// end if
}
if (scepName == null || certProfileName == null) {
sendError(resp, HttpServletResponse.SC_NOT_FOUND);
return;
}
AuditService auditService = auditServiceRegister.getAuditService();
AuditEvent event = new AuditEvent(new Date());
event.setApplicationName("SCEP");
event.setName(CaAuditConstants.NAME_PERF);
event.addEventData(CaAuditConstants.NAME_SCEP_name, scepName + "/" + certProfileName);
event.addEventData(CaAuditConstants.NAME_reqType, 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 {
Scep responder = responderManager.getScep(scepName);
if (responder == null || !responder.isOnService() || !responder.supportsCertProfile(certProfileName)) {
auditMessage = "unknown SCEP '" + scepName + "/" + certProfileName + "'";
LOG.warn(auditMessage);
auditStatus = AuditStatus.FAILED;
sendError(resp, HttpServletResponse.SC_NOT_FOUND);
return;
}
String operation = req.getParameter("operation");
event.addEventData(CaAuditConstants.NAME_SCEP_operation, operation);
if ("PKIOperation".equalsIgnoreCase(operation)) {
CMSSignedData reqMessage;
// parse the request
try {
byte[] content;
if (viaPost) {
content = IoUtil.read(req.getInputStream());
} else {
String b64 = req.getParameter("message");
content = Base64.decode(b64);
}
reqMessage = new CMSSignedData(content);
} 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;
}
byte[] bodyBytes = ci.getEncoded();
sendOKResponse(resp, CT_RESPONSE, bodyBytes);
} else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] caCapsBytes = responder.getCaCaps().getBytes();
sendOKResponse(resp, ScepConstants.CT_TEXT_PLAIN, caCapsBytes);
} else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] respBytes = responder.getCaCertResp().getBytes();
sendOKResponse(resp, ScepConstants.CT_X509_CA_RA_CERT, respBytes);
} 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;
}
} 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);
}
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo 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;
}
use of com.github.zhenwei.pkix.util.asn1.cms.ContentInfo in project xipki by xipki.
the class HttpScepServlet method service.
@Override
public FullHttpResponse service(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
HttpVersion version = request.protocolVersion();
HttpMethod method = request.method();
boolean viaPost;
if (method == HttpMethod.POST) {
viaPost = true;
} else if (method == HttpMethod.GET) {
viaPost = false;
} else {
return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
}
String scepName = null;
String certProfileName = null;
if (servletUri.getPath().length() > 1) {
String scepPath = servletUri.getPath();
if (scepPath.endsWith(CGI_PROGRAM)) {
// skip also the first char (which is always '/')
String path = scepPath.substring(1, scepPath.length() - CGI_PROGRAM_LEN);
String[] tokens = path.split("/");
if (tokens.length == 2) {
scepName = tokens[0];
certProfileName = tokens[1].toLowerCase();
}
}
// end if
}
if (scepName == null || certProfileName == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
AuditService auditService = auditServiceRegister.getAuditService();
AuditEvent event = new AuditEvent(new Date());
event.setApplicationName("SCEP");
event.setName(CaAuditConstants.NAME_PERF);
event.addEventData(CaAuditConstants.NAME_SCEP_name, scepName + "/" + certProfileName);
event.addEventData(CaAuditConstants.NAME_reqType, 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 {
if (responderManager == null) {
auditMessage = "responderManager in servlet not configured";
LOG.error(auditMessage);
auditLevel = AuditLevel.ERROR;
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
Scep responder = responderManager.getScep(scepName);
if (responder == null || !responder.isOnService() || !responder.supportsCertProfile(certProfileName)) {
auditMessage = "unknown SCEP '" + scepName + "/" + certProfileName + "'";
LOG.warn(auditMessage);
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
String operation = servletUri.getParameter("operation");
event.addEventData(CaAuditConstants.NAME_SCEP_operation, operation);
if ("PKIOperation".equalsIgnoreCase(operation)) {
CMSSignedData reqMessage;
// parse the request
try {
byte[] content;
if (viaPost) {
content = readContent(request);
} else {
String b64 = servletUri.getParameter("message");
content = Base64.decode(b64);
}
reqMessage = new CMSSignedData(content);
} catch (Exception ex) {
final String msg = "invalid request";
LogUtil.error(LOG, ex, msg);
auditMessage = msg;
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
}
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;
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
} catch (OperationException ex) {
ErrorCode code = ex.getErrorCode();
HttpResponseStatus httpCode;
switch(code) {
case ALREADY_ISSUED:
case CERT_REVOKED:
case CERT_UNREVOKED:
httpCode = HttpResponseStatus.FORBIDDEN;
break;
case BAD_CERT_TEMPLATE:
case BAD_REQUEST:
case BAD_POP:
case INVALID_EXTENSION:
case UNKNOWN_CERT:
case UNKNOWN_CERT_PROFILE:
httpCode = HttpResponseStatus.BAD_REQUEST;
break;
case NOT_PERMITTED:
httpCode = HttpResponseStatus.UNAUTHORIZED;
break;
case SYSTEM_UNAVAILABLE:
httpCode = HttpResponseStatus.SERVICE_UNAVAILABLE;
break;
case CRL_FAILURE:
case DATABASE_FAILURE:
case SYSTEM_FAILURE:
httpCode = HttpResponseStatus.INTERNAL_SERVER_ERROR;
break;
default:
httpCode = HttpResponseStatus.INTERNAL_SERVER_ERROR;
break;
}
auditMessage = ex.getMessage();
LogUtil.error(LOG, ex, auditMessage);
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, httpCode);
}
byte[] bodyBytes = ci.getEncoded();
return createOKResponse(version, CT_RESPONSE, bodyBytes);
} else if (Operation.GetCACaps.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] caCapsBytes = responder.getCaCaps().getBytes();
return createOKResponse(version, ScepConstants.CT_TEXT_PLAIN, caCapsBytes);
} else if (Operation.GetCACert.getCode().equalsIgnoreCase(operation)) {
// CA-Ident is ignored
byte[] respBytes = responder.getCaCertResp().getBytes();
return createOKResponse(version, ScepConstants.CT_X509_CA_RA_CERT, respBytes);
} else if (Operation.GetNextCACert.getCode().equalsIgnoreCase(operation)) {
auditMessage = "SCEP operation '" + operation + "' is not permitted";
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.FORBIDDEN);
} else {
auditMessage = "unknown SCEP operation '" + operation + "'";
auditStatus = AuditStatus.FAILED;
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
}
} 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";
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
} finally {
audit(auditService, event, auditLevel, auditStatus, auditMessage);
}
}
Aggregations