use of org.bouncycastle.asn1.ocsp.Request in project xipki by xipki.
the class IdentifiedX509Certprofile method validate.
public void validate() throws CertprofileException {
StringBuilder msg = new StringBuilder();
Map<ASN1ObjectIdentifier, ExtensionControl> controls = getExtensionControls();
// make sure that non-request extensions are not permitted in requests
Set<ASN1ObjectIdentifier> set = new HashSet<>();
for (ASN1ObjectIdentifier type : NONE_REQUEST_EXTENSION_TYPES) {
ExtensionControl control = controls.get(type);
if (control != null && control.isRequest()) {
set.add(type);
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("extensions ").append(toString(set)).append(" must not be contained in request, ");
}
X509CertLevel level = getCertLevel();
boolean ca = (level == X509CertLevel.RootCA) || (level == X509CertLevel.SubCA);
// make sure that CA-only extensions are not permitted in EE certificate
set.clear();
if (!ca) {
set.clear();
for (ASN1ObjectIdentifier type : CA_ONLY_EXTENSION_TYPES) {
if (controls.containsKey(type)) {
set.add(type);
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("EE profile contains CA-only extensions ").append(toString(set)).append(", ");
}
}
// make sure that critical only extensions are not marked as non-critical.
set.clear();
for (ASN1ObjectIdentifier type : controls.keySet()) {
ExtensionControl control = controls.get(type);
if (CRITICAL_ONLY_EXTENSION_TYPES.contains(type)) {
if (!control.isCritical()) {
set.add(type);
}
}
if (ca && CA_CRITICAL_ONLY_EXTENSION_TYPES.contains(type)) {
if (!control.isCritical()) {
set.add(type);
}
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("critical only extensions are marked as non-critical ");
msg.append(toString(set)).append(", ");
}
// make sure that non-critical only extensions are not marked as critical.
set.clear();
for (ASN1ObjectIdentifier type : controls.keySet()) {
ExtensionControl control = controls.get(type);
if (NONCRITICAL_ONLY_EXTENSION_TYPES.contains(type)) {
if (control.isCritical()) {
set.add(type);
}
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("non-critical extensions are marked as critical ").append(toString(set)).append(", ");
}
// make sure that required extensions are present
set.clear();
Set<ASN1ObjectIdentifier> requiredTypes = ca ? REQUIRED_CA_EXTENSION_TYPES : REQUIRED_EE_EXTENSION_TYPES;
for (ASN1ObjectIdentifier type : requiredTypes) {
ExtensionControl extCtrl = controls.get(type);
if (extCtrl == null || !extCtrl.isRequired()) {
set.add(type);
}
}
if (level == X509CertLevel.SubCA) {
ASN1ObjectIdentifier type = Extension.authorityKeyIdentifier;
ExtensionControl extCtrl = controls.get(type);
if (extCtrl == null || !extCtrl.isRequired()) {
set.add(type);
}
}
if (!set.isEmpty()) {
msg.append("required extensions are not marked as required ").append(toString(set)).append(", ");
}
// KeyUsage
Set<KeyUsageControl> usages = getKeyUsage();
if (ca) {
// make sure the CA certificate contains usage keyCertSign
if (!containsKeyusage(usages, KeyUsage.keyCertSign)) {
msg.append("CA profile does not contain keyUsage ").append(KeyUsage.keyCertSign).append(", ");
}
} else {
// make sure the EE certificate does not contain CA-only usages
KeyUsage[] caOnlyUsages = { KeyUsage.keyCertSign, KeyUsage.cRLSign };
Set<KeyUsage> setUsages = new HashSet<>();
for (KeyUsage caOnlyUsage : caOnlyUsages) {
if (containsKeyusage(usages, caOnlyUsage)) {
setUsages.add(caOnlyUsage);
}
}
if (CollectionUtil.isNonEmpty(set)) {
msg.append("EE profile contains CA-only keyUsage ").append(setUsages).append(", ");
}
}
final int len = msg.length();
if (len > 2) {
msg.delete(len - 2, len);
throw new CertprofileException(msg.toString());
}
}
use of org.bouncycastle.asn1.ocsp.Request 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.bouncycastle.asn1.ocsp.Request in project xipki by xipki.
the class CertStoreQueryExecutor method addRequest.
long addRequest(byte[] request) throws DataAccessException {
ParamUtil.requireNonNull("request", request);
long id = idGenerator.nextId();
long currentTimeSeconds = System.currentTimeMillis() / 1000;
String b64Request = Base64.encodeToString(request);
final String sql = SQLs.SQL_ADD_REQUEST;
PreparedStatement ps = borrowPreparedStatement(sql);
try {
ps.setLong(1, id);
ps.setLong(2, currentTimeSeconds);
ps.setString(3, b64Request);
ps.executeUpdate();
} catch (SQLException ex) {
throw datasource.translate(sql, ex);
} finally {
releaseDbResources(ps, null);
}
return id;
}
use of org.bouncycastle.asn1.ocsp.Request in project xipki by xipki.
the class CmpCaClient method cmpCaCerts.
private Certificate[] cmpCaCerts() throws Exception {
ProtectedPKIMessageBuilder builder = new ProtectedPKIMessageBuilder(PKIHeader.CMP_2000, requestorSubject, responderSubject);
builder.setMessageTime(new Date());
builder.setTransactionID(randomTransactionId());
builder.setSenderNonce(randomSenderNonce());
InfoTypeAndValue itv = new InfoTypeAndValue(id_xipki_cmp);
PKIBody body = new PKIBody(PKIBody.TYPE_GEN_MSG, new GenMsgContent(itv));
builder.setBody(body);
ProtectedPKIMessage request = builder.build(requestorSigner);
PKIMessage response = transmit(request);
ASN1Encodable asn1Value = extractGeneralRepContent(response, id_xipki_cmp.getId());
ASN1Sequence seq = ASN1Sequence.getInstance(asn1Value);
final int size = seq.size();
Certificate[] caCerts = new Certificate[size];
for (int i = 0; i < size; i++) {
caCerts[i] = CMPCertificate.getInstance(seq.getObjectAt(i)).getX509v3PKCert();
}
return caCerts;
}
use of org.bouncycastle.asn1.ocsp.Request in project xipki by xipki.
the class CmpCaClient method requestCertViaCrmf.
public X509Certificate requestCertViaCrmf(String certProfile, PrivateKey privateKey, SubjectPublicKeyInfo publicKeyInfo, String subject) throws Exception {
CertTemplateBuilder certTemplateBuilder = new CertTemplateBuilder();
certTemplateBuilder.setSubject(new X500Name(subject));
certTemplateBuilder.setPublicKey(publicKeyInfo);
CertRequest certReq = new CertRequest(1, certTemplateBuilder.build(), null);
ProofOfPossessionSigningKeyBuilder popoBuilder = new ProofOfPossessionSigningKeyBuilder(certReq);
ContentSigner popoSigner = buildSigner(privateKey);
POPOSigningKey popoSk = popoBuilder.build(popoSigner);
ProofOfPossession popo = new ProofOfPossession(popoSk);
AttributeTypeAndValue certprofileInfo = new AttributeTypeAndValue(CMPObjectIdentifiers.regInfo_utf8Pairs, new DERUTF8String("CERT-PROFILE?" + certProfile + "%"));
AttributeTypeAndValue[] atvs = { certprofileInfo };
CertReqMsg certReqMsg = new CertReqMsg(certReq, popo, atvs);
PKIBody body = new PKIBody(PKIBody.TYPE_CERT_REQ, new CertReqMessages(certReqMsg));
ProtectedPKIMessageBuilder builder = new ProtectedPKIMessageBuilder(PKIHeader.CMP_2000, requestorSubject, responderSubject);
builder.setMessageTime(new Date());
builder.setTransactionID(randomTransactionId());
builder.setSenderNonce(randomSenderNonce());
builder.addGeneralInfo(new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm, DERNull.INSTANCE));
builder.setBody(body);
ProtectedPKIMessage request = builder.build(requestorSigner);
PKIMessage response = transmit(request);
return parseEnrollCertResult(response);
}
Aggregations