use of org.xipki.scep.transaction.MessageType in project xipki by xipki.
the class ScepResponder method servicePkiOperation0.
private PkiMessage servicePkiOperation0(DecodedPkiMessage req, AuditEvent event) throws MessageDecodingException, CaException {
TransactionId tid = req.getTransactionId();
PkiMessage rep = new PkiMessage(tid, MessageType.CertRep, Nonce.randomNonce());
rep.setPkiStatus(PkiStatus.SUCCESS);
rep.setRecipientNonce(req.getSenderNonce());
if (req.getFailureMessage() != null) {
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
}
Boolean bo = req.isSignatureValid();
if (bo != null && !bo.booleanValue()) {
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badMessageCheck);
}
bo = req.isDecryptionSuccessful();
if (bo != null && !bo.booleanValue()) {
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
}
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) {
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badTime);
}
}
// 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);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
}
// end if
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;
}
} else if (hashAlgo == ScepHashAlgo.MD5) {
if (control.isUseInsecureAlg()) {
supported = true;
}
}
if (!supported) {
LOG.warn("tid={}: unsupported digest algorithm {}", tid, oid);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
}
// end if
// 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);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
}
} else if (AES_ENC_ALGS.contains(encOid)) {
if (!caCaps.containsCapability(CaCapability.AES)) {
LOG.warn("tid={}: encryption with AES algorithm {} is not permitted", tid, encOid);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
}
} else if (CMSAlgorithm.DES_CBC.equals(encOid)) {
if (!control.isUseInsecureAlg()) {
LOG.warn("tid={}: encryption with DES algorithm {} is not permitted", tid, encOid);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
}
} else {
LOG.warn("tid={}: encryption with algorithm {} is not permitted", tid, encOid);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badAlg);
}
if (rep.getPkiStatus() == PkiStatus.FAILURE) {
return rep;
}
MessageType messageType = req.getMessageType();
switch(messageType) {
case PKCSReq:
boolean selfSigned = req.getSignatureCert().getIssuerX500Principal().equals(req.getSignatureCert().getIssuerX500Principal());
CertificationRequest csr = CertificationRequest.getInstance(req.getMessageData());
if (selfSigned) {
X500Name name = X500Name.getInstance(req.getSignatureCert().getSubjectX500Principal().getEncoded());
if (!name.equals(csr.getCertificationRequestInfo().getSubject())) {
LOG.warn("tid={}: self-signed cert.subject != CSR.subject", tid);
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
}
}
String challengePwd = getChallengePassword(csr.getCertificationRequestInfo());
if (challengePwd == null || !control.getSecret().equals(challengePwd)) {
LOG.warn("challengePassword is not trusted");
return buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
}
Certificate cert;
try {
cert = caEmulator.generateCert(csr);
} catch (Exception ex) {
throw new CaException("system failure: " + ex.getMessage(), ex);
}
if (cert != null && control.isPendingCert()) {
rep.setPkiStatus(PkiStatus.PENDING);
} else if (cert != null) {
ContentInfo messageData = createSignedData(cert);
rep.setMessageData(messageData);
} else {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
}
break;
case CertPoll:
IssuerAndSubject is = IssuerAndSubject.getInstance(req.getMessageData());
cert = caEmulator.pollCert(is.getIssuer(), is.getSubject());
if (cert != null) {
rep.setMessageData(createSignedData(cert));
} else {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
}
break;
case GetCert:
IssuerAndSerialNumber isn = IssuerAndSerialNumber.getInstance(req.getMessageData());
cert = caEmulator.getCert(isn.getName(), isn.getSerialNumber().getValue());
if (cert != null) {
rep.setMessageData(createSignedData(cert));
} else {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
}
break;
case RenewalReq:
if (!caCaps.containsCapability(CaCapability.Renewal)) {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
} else {
csr = CertificationRequest.getInstance(req.getMessageData());
try {
cert = caEmulator.generateCert(csr);
} catch (Exception ex) {
throw new CaException("system failure: " + ex.getMessage(), ex);
}
if (cert != null) {
rep.setMessageData(createSignedData(cert));
} else {
rep.setPkiStatus(PkiStatus.FAILURE);
rep.setFailInfo(FailInfo.badCertId);
}
}
break;
case UpdateReq:
if (!caCaps.containsCapability(CaCapability.Update)) {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
} else {
csr = CertificationRequest.getInstance(req.getMessageData());
try {
cert = caEmulator.generateCert(csr);
} catch (Exception ex) {
throw new CaException("system failure: " + ex.getMessage(), ex);
}
if (cert != null) {
rep.setMessageData(createSignedData(cert));
} else {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
}
}
break;
case GetCRL:
isn = IssuerAndSerialNumber.getInstance(req.getMessageData());
CertificateList crl;
try {
crl = caEmulator.getCrl(isn.getName(), isn.getSerialNumber().getValue());
} catch (Exception ex) {
throw new CaException("system failure: " + ex.getMessage(), ex);
}
if (crl != null) {
rep.setMessageData(createSignedData(crl));
} else {
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badCertId);
}
break;
default:
buildPkiMessage(rep, PkiStatus.FAILURE, FailInfo.badRequest);
}
return rep;
}
use of org.xipki.scep.transaction.MessageType 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 org.xipki.scep.transaction.MessageType in project xipki by xipki.
the class DecodedPkiMessage method decode.
@SuppressWarnings("unchecked")
public static DecodedPkiMessage decode(CMSSignedData pkiMessage, EnvelopedDataDecryptor recipient, CollectionStore<X509CertificateHolder> certStore) throws MessageDecodingException {
ScepUtil.requireNonNull("pkiMessage", pkiMessage);
ScepUtil.requireNonNull("recipient", recipient);
SignerInformationStore signerStore = pkiMessage.getSignerInfos();
Collection<SignerInformation> signerInfos = signerStore.getSigners();
if (signerInfos.size() != 1) {
throw new MessageDecodingException("number of signerInfos is not 1, but " + signerInfos.size());
}
SignerInformation signerInfo = signerInfos.iterator().next();
SignerId sid = signerInfo.getSID();
Collection<?> signedDataCerts = null;
if (certStore != null) {
signedDataCerts = certStore.getMatches(sid);
}
if (signedDataCerts == null || signedDataCerts.isEmpty()) {
signedDataCerts = pkiMessage.getCertificates().getMatches(signerInfo.getSID());
}
if (signedDataCerts == null || signedDataCerts.size() != 1) {
throw new MessageDecodingException("could not find embedded certificate to verify the signature");
}
AttributeTable signedAttrs = signerInfo.getSignedAttributes();
if (signedAttrs == null) {
throw new MessageDecodingException("missing SCEP attributes");
}
Date signingTime = null;
// signingTime
ASN1Encodable attrValue = ScepUtil.getFirstAttrValue(signedAttrs, CMSAttributes.signingTime);
if (attrValue != null) {
signingTime = Time.getInstance(attrValue).getDate();
}
// transactionId
String str = getPrintableStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_TRANSACTION_ID);
if (str == null || str.isEmpty()) {
throw new MessageDecodingException("missing required SCEP attribute transactionId");
}
TransactionId transactionId = new TransactionId(str);
// messageType
Integer intValue = getIntegerPrintStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_MESSAGE_TYPE);
if (intValue == null) {
throw new MessageDecodingException("tid " + transactionId.getId() + ": missing required SCEP attribute messageType");
}
MessageType messageType;
try {
messageType = MessageType.forValue(intValue);
} catch (IllegalArgumentException ex) {
throw new MessageDecodingException("tid " + transactionId.getId() + ": invalid messageType '" + intValue + "'");
}
// senderNonce
Nonce senderNonce = getNonceAttrValue(signedAttrs, ScepObjectIdentifiers.ID_SENDER_NONCE);
if (senderNonce == null) {
throw new MessageDecodingException("tid " + transactionId.getId() + ": missing required SCEP attribute senderNonce");
}
DecodedPkiMessage ret = new DecodedPkiMessage(transactionId, messageType, senderNonce);
if (signingTime != null) {
ret.setSigningTime(signingTime);
}
Nonce recipientNonce = null;
try {
recipientNonce = getNonceAttrValue(signedAttrs, ScepObjectIdentifiers.ID_RECIPIENT_NONCE);
} catch (MessageDecodingException ex) {
ret.setFailureMessage("could not parse recipientNonce: " + ex.getMessage());
}
if (recipientNonce != null) {
ret.setRecipientNonce(recipientNonce);
}
PkiStatus pkiStatus = null;
FailInfo failInfo = null;
if (MessageType.CertRep == messageType) {
// pkiStatus
try {
intValue = getIntegerPrintStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_PKI_STATUS);
} catch (MessageDecodingException ex) {
ret.setFailureMessage("could not parse pkiStatus: " + ex.getMessage());
return ret;
}
if (intValue == null) {
ret.setFailureMessage("missing required SCEP attribute pkiStatus");
return ret;
}
try {
pkiStatus = PkiStatus.forValue(intValue);
} catch (IllegalArgumentException ex) {
ret.setFailureMessage("invalid pkiStatus '" + intValue + "'");
return ret;
}
ret.setPkiStatus(pkiStatus);
// failureInfo
if (pkiStatus == PkiStatus.FAILURE) {
try {
intValue = getIntegerPrintStringAttrValue(signedAttrs, ScepObjectIdentifiers.ID_FAILINFO);
} catch (MessageDecodingException ex) {
ret.setFailureMessage("could not parse failInfo: " + ex.getMessage());
return ret;
}
if (intValue == null) {
ret.setFailureMessage("missing required SCEP attribute failInfo");
return ret;
}
try {
failInfo = FailInfo.forValue(intValue);
} catch (IllegalArgumentException ex) {
ret.setFailureMessage("invalid failInfo '" + intValue + "'");
return ret;
}
ret.setFailInfo(failInfo);
}
// end if(pkiStatus == PkiStatus.FAILURE)
}
// end if (MessageType.CertRep == messageType)
// other signedAttributes
Attribute[] attrs = signedAttrs.toASN1Structure().getAttributes();
for (Attribute attr : attrs) {
ASN1ObjectIdentifier type = attr.getAttrType();
if (!SCEP_ATTR_TYPES.contains(type)) {
ret.addSignendAttribute(type, attr.getAttrValues().getObjectAt(0));
}
}
// unsignedAttributes
AttributeTable unsignedAttrs = signerInfo.getUnsignedAttributes();
attrs = (unsignedAttrs == null) ? null : unsignedAttrs.toASN1Structure().getAttributes();
if (attrs != null) {
for (Attribute attr : attrs) {
ASN1ObjectIdentifier type = attr.getAttrType();
ret.addUnsignendAttribute(type, attr.getAttrValues().getObjectAt(0));
}
}
ASN1ObjectIdentifier digestAlgOid = signerInfo.getDigestAlgorithmID().getAlgorithm();
ret.setDigestAlgorithm(digestAlgOid);
String sigAlgOid = signerInfo.getEncryptionAlgOID();
if (!PKCSObjectIdentifiers.rsaEncryption.getId().equals(sigAlgOid)) {
ASN1ObjectIdentifier tmpDigestAlgOid;
try {
tmpDigestAlgOid = ScepUtil.extractDigesetAlgorithmIdentifier(signerInfo.getEncryptionAlgOID(), signerInfo.getEncryptionAlgParams());
} catch (Exception ex) {
final String msg = "could not extract digest algorithm from signerInfo.signatureAlgorithm: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
return ret;
}
if (!digestAlgOid.equals(tmpDigestAlgOid)) {
ret.setFailureMessage("digestAlgorithm and encryptionAlgorithm do not use the same digestAlgorithm");
return ret;
}
// end if
}
// end if
X509CertificateHolder tmpSignerCert = (X509CertificateHolder) signedDataCerts.iterator().next();
X509Certificate signerCert;
try {
signerCert = ScepUtil.toX509Cert(tmpSignerCert.toASN1Structure());
} catch (CertificateException ex) {
final String msg = "could not construct X509Certificate: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
return ret;
}
ret.setSignatureCert(signerCert);
// validate the signature
SignerInformationVerifier verifier;
try {
verifier = new JcaSimpleSignerInfoVerifierBuilder().build(tmpSignerCert);
} catch (OperatorCreationException | CertificateException ex) {
final String msg = "could not build signature verifier: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
return ret;
}
boolean signatureValid;
try {
signatureValid = signerInfo.verify(verifier);
} catch (CMSException ex) {
final String msg = "could not verify the signature: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
return ret;
}
ret.setSignatureValid(signatureValid);
if (!signatureValid) {
return ret;
}
if (MessageType.CertRep == messageType && (pkiStatus == PkiStatus.FAILURE | pkiStatus == PkiStatus.PENDING)) {
return ret;
}
// MessageData
CMSTypedData signedContent = pkiMessage.getSignedContent();
ASN1ObjectIdentifier signedContentType = signedContent.getContentType();
if (!CMSObjectIdentifiers.envelopedData.equals(signedContentType)) {
// fall back: some SCEP client, such as JSCEP use id-data
if (!CMSObjectIdentifiers.data.equals(signedContentType)) {
ret.setFailureMessage("either id-envelopedData or id-data is excepted, but not '" + signedContentType.getId());
return ret;
}
}
CMSEnvelopedData envData;
try {
envData = new CMSEnvelopedData((byte[]) signedContent.getContent());
} catch (CMSException ex) {
final String msg = "could not create the CMSEnvelopedData: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
return ret;
}
ret.setContentEncryptionAlgorithm(envData.getContentEncryptionAlgorithm().getAlgorithm());
byte[] encodedMessageData;
try {
encodedMessageData = recipient.decrypt(envData);
} catch (MessageDecodingException ex) {
final String msg = "could not create the CMSEnvelopedData: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
ret.setDecryptionSuccessful(false);
return ret;
}
ret.setDecryptionSuccessful(true);
try {
if (MessageType.PKCSReq == messageType || MessageType.RenewalReq == messageType || MessageType.UpdateReq == messageType) {
CertificationRequest messageData = CertificationRequest.getInstance(encodedMessageData);
ret.setMessageData(messageData);
} else if (MessageType.CertPoll == messageType) {
IssuerAndSubject messageData = IssuerAndSubject.getInstance(encodedMessageData);
ret.setMessageData(messageData);
} else if (MessageType.GetCert == messageType || MessageType.GetCRL == messageType) {
IssuerAndSerialNumber messageData = IssuerAndSerialNumber.getInstance(encodedMessageData);
ret.setMessageData(messageData);
ret.setMessageData(messageData);
} else if (MessageType.CertRep == messageType) {
ContentInfo ci = ContentInfo.getInstance(encodedMessageData);
ret.setMessageData(ci);
} else {
throw new RuntimeException("should not reach here, unknown messageType " + messageType);
}
} catch (Exception ex) {
final String msg = "could not parse the messageData: " + ex.getMessage();
LOG.error(msg);
LOG.debug(msg, ex);
ret.setFailureMessage(msg);
return ret;
}
return ret;
}
Aggregations