use of org.openecard.bouncycastle.asn1.x500.X500Name in project xipki by xipki.
the class X509SelfSignedCertBuilder method generateCertificate.
// method generateSelfSigned
private static X509Certificate generateCertificate(ConcurrentContentSigner signer, IdentifiedX509Certprofile certprofile, CertificationRequest csr, BigInteger serialNumber, SubjectPublicKeyInfo publicKeyInfo, List<String> caCertUris, List<String> ocspUris, List<String> crlUris, List<String> deltaCrlUris, ConfPairs extraControl) throws OperationException {
SubjectPublicKeyInfo tmpPublicKeyInfo;
try {
tmpPublicKeyInfo = X509Util.toRfc3279Style(publicKeyInfo);
} catch (InvalidKeySpecException ex) {
LOG.warn("SecurityUtil.toRfc3279Style", ex);
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
try {
certprofile.checkPublicKey(tmpPublicKeyInfo);
} catch (BadCertTemplateException ex) {
LOG.warn("certprofile.checkPublicKey", ex);
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
X500Name requestedSubject = csr.getCertificationRequestInfo().getSubject();
SubjectInfo subjectInfo;
// subject
try {
subjectInfo = certprofile.getSubject(requestedSubject);
} catch (CertprofileException ex) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "exception in cert profile " + certprofile.getIdent());
} catch (BadCertTemplateException ex) {
LOG.warn("certprofile.getSubject", ex);
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
Date notBefore = certprofile.getNotBefore(null);
if (notBefore == null) {
notBefore = new Date();
}
CertValidity validity = certprofile.getValidity();
if (validity == null) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "no validity specified in the profile " + certprofile.getIdent());
}
Date notAfter = validity.add(notBefore);
X500Name grantedSubject = subjectInfo.getGrantedSubject();
X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(grantedSubject, serialNumber, notBefore, notAfter, grantedSubject, tmpPublicKeyInfo);
PublicCaInfo publicCaInfo = new PublicCaInfo(grantedSubject, serialNumber, null, null, caCertUris, ocspUris, crlUris, deltaCrlUris, extraControl);
Extensions extensions = null;
ASN1Set attrs = csr.getCertificationRequestInfo().getAttributes();
for (int i = 0; i < attrs.size(); i++) {
Attribute attr = Attribute.getInstance(attrs.getObjectAt(i));
if (PKCSObjectIdentifiers.pkcs_9_at_extensionRequest.equals(attr.getAttrType())) {
extensions = Extensions.getInstance(attr.getAttributeValues()[0]);
}
}
try {
addExtensions(certBuilder, certprofile, requestedSubject, grantedSubject, extensions, tmpPublicKeyInfo, publicCaInfo, notBefore, notAfter);
ConcurrentBagEntrySigner signer0 = signer.borrowSigner();
X509CertificateHolder certHolder;
try {
certHolder = certBuilder.build(signer0.value());
} finally {
signer.requiteSigner(signer0);
}
Certificate bcCert = certHolder.toASN1Structure();
return X509Util.parseCert(bcCert.getEncoded());
} catch (BadCertTemplateException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
} catch (NoIdleSignerException | CertificateException | IOException | CertprofileException ex) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex);
}
}
use of org.openecard.bouncycastle.asn1.x500.X500Name 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.openecard.bouncycastle.asn1.x500.X500Name in project xipki by xipki.
the class CaManagerQueryExecutor method canonicalizName.
static String canonicalizName(X500Principal prin) {
ParamUtil.requireNonNull("prin", prin);
X500Name x500Name = X500Name.getInstance(prin.getEncoded());
return X509Util.canonicalizName(x500Name);
}
use of org.openecard.bouncycastle.asn1.x500.X500Name in project xipki by xipki.
the class X509Ca method createGrantedCertTemplate.
private GrantedCertTemplate createGrantedCertTemplate(CertTemplateData certTemplate, RequestorInfo requestor, boolean keyUpdate) throws OperationException {
ParamUtil.requireNonNull("certTemplate", certTemplate);
if (caInfo.getRevocationInfo() != null) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is revoked");
}
IdentifiedX509Certprofile certprofile = getX509Certprofile(certTemplate.getCertprofileName());
if (certprofile == null) {
throw new OperationException(ErrorCode.UNKNOWN_CERT_PROFILE, "unknown cert profile " + certTemplate.getCertprofileName());
}
ConcurrentContentSigner signer = caInfo.getSigner(certprofile.getSignatureAlgorithms());
if (signer == null) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "CA does not support any signature algorithm restricted by the cert profile");
}
final NameId certprofileIdent = certprofile.getIdent();
if (certprofile.getVersion() != X509CertVersion.v3) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "unknown cert version " + certprofile.getVersion());
}
if (certprofile.isOnlyForRa()) {
if (requestor == null || !requestor.isRa()) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "profile " + certprofileIdent + " not applied to non-RA");
}
}
X500Name requestedSubject = removeEmptyRdns(certTemplate.getSubject());
if (!certprofile.isSerialNumberInReqPermitted()) {
RDN[] rdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_SN);
if (rdns != null && rdns.length > 0) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "subjectDN SerialNumber in request is not permitted");
}
}
Date now = new Date();
Date reqNotBefore;
if (certTemplate.getNotBefore() != null && certTemplate.getNotBefore().after(now)) {
reqNotBefore = certTemplate.getNotBefore();
} else {
reqNotBefore = now;
}
Date grantedNotBefore = certprofile.getNotBefore(reqNotBefore);
// notBefore in the past is not permitted
if (grantedNotBefore.before(now)) {
grantedNotBefore = now;
}
if (certprofile.hasMidnightNotBefore()) {
grantedNotBefore = setToMidnight(grantedNotBefore, certprofile.getTimezone());
}
if (grantedNotBefore.before(caInfo.getNotBefore())) {
grantedNotBefore = caInfo.getNotBefore();
if (certprofile.hasMidnightNotBefore()) {
grantedNotBefore = setToMidnight(grantedNotBefore, certprofile.getTimezone());
}
}
long time = caInfo.getNoNewCertificateAfter();
if (grantedNotBefore.getTime() > time) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is not permitted to issue certifate after " + new Date(time));
}
SubjectPublicKeyInfo grantedPublicKeyInfo;
try {
grantedPublicKeyInfo = X509Util.toRfc3279Style(certTemplate.getPublicKeyInfo());
} catch (InvalidKeySpecException ex) {
LogUtil.warn(LOG, ex, "invalid SubjectPublicKeyInfo");
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid SubjectPublicKeyInfo");
}
// public key
try {
grantedPublicKeyInfo = certprofile.checkPublicKey(grantedPublicKeyInfo);
} catch (BadCertTemplateException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
// CHECK weak public key, like RSA key (ROCA)
if (grantedPublicKeyInfo.getAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) {
try {
ASN1Sequence seq = ASN1Sequence.getInstance(grantedPublicKeyInfo.getPublicKeyData().getOctets());
if (seq.size() != 2) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid format of RSA public key");
}
BigInteger modulus = ASN1Integer.getInstance(seq.getObjectAt(0)).getPositiveValue();
if (RSABrokenKey.isAffected(modulus)) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "RSA public key is too weak");
}
} catch (IllegalArgumentException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid format of RSA public key");
}
}
Date gsmckFirstNotBefore = null;
if (certprofile.getspecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
gsmckFirstNotBefore = grantedNotBefore;
RDN[] cnRdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_CN);
if (cnRdns != null && cnRdns.length > 0) {
String requestedCn = X509Util.rdnValueToString(cnRdns[0].getFirst().getValue());
Long gsmckFirstNotBeforeInSecond = certstore.getNotBeforeOfFirstCertStartsWithCommonName(requestedCn, certprofileIdent);
if (gsmckFirstNotBeforeInSecond != null) {
gsmckFirstNotBefore = new Date(gsmckFirstNotBeforeInSecond * MS_PER_SECOND);
}
// append the commonName with '-' + yyyyMMdd
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMdd");
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
String yyyyMMdd = dateF.format(gsmckFirstNotBefore);
String suffix = "-" + yyyyMMdd;
// append the -yyyyMMdd to the commonName
RDN[] rdns = requestedSubject.getRDNs();
for (int i = 0; i < rdns.length; i++) {
if (ObjectIdentifiers.DN_CN.equals(rdns[i].getFirst().getType())) {
rdns[i] = new RDN(ObjectIdentifiers.DN_CN, new DERUTF8String(requestedCn + suffix));
}
}
requestedSubject = new X500Name(rdns);
}
// end if
}
// end if
// subject
SubjectInfo subjectInfo;
try {
subjectInfo = certprofile.getSubject(requestedSubject);
} catch (CertprofileException ex) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "exception in cert profile " + certprofileIdent);
} catch (BadCertTemplateException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
X500Name grantedSubject = subjectInfo.getGrantedSubject();
// make sure that empty subject is not permitted
ASN1ObjectIdentifier[] attrTypes = grantedSubject.getAttributeTypes();
if (attrTypes == null || attrTypes.length == 0) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "empty subject is not permitted");
}
// make sure that the grantedSubject does not equal the CA's subject
if (X509Util.canonicalizName(grantedSubject).equals(caInfo.getPublicCaInfo().getC14nSubject())) {
throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate with the same subject as CA is not allowed");
}
boolean duplicateKeyPermitted = caInfo.isDuplicateKeyPermitted();
if (duplicateKeyPermitted && !certprofile.isDuplicateKeyPermitted()) {
duplicateKeyPermitted = false;
}
byte[] subjectPublicKeyData = grantedPublicKeyInfo.getPublicKeyData().getBytes();
long fpPublicKey = FpIdCalculator.hash(subjectPublicKeyData);
if (keyUpdate) {
CertStatus certStatus = certstore.getCertStatusForSubject(caIdent, grantedSubject);
if (certStatus == CertStatus.REVOKED) {
throw new OperationException(ErrorCode.CERT_REVOKED);
} else if (certStatus == CertStatus.UNKNOWN) {
throw new OperationException(ErrorCode.UNKNOWN_CERT);
}
} else {
if (!duplicateKeyPermitted) {
if (certstore.isCertForKeyIssued(caIdent, fpPublicKey)) {
throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate for the given public key already issued");
}
}
// duplicateSubject check will be processed later
}
// end if(keyUpdate)
StringBuilder msgBuilder = new StringBuilder();
if (subjectInfo.getWarning() != null) {
msgBuilder.append(", ").append(subjectInfo.getWarning());
}
CertValidity validity = certprofile.getValidity();
if (validity == null) {
validity = caInfo.getMaxValidity();
} else if (validity.compareTo(caInfo.getMaxValidity()) > 0) {
validity = caInfo.getMaxValidity();
}
Date maxNotAfter = validity.add(grantedNotBefore);
if (maxNotAfter.getTime() > MAX_CERT_TIME_MS) {
maxNotAfter = new Date(MAX_CERT_TIME_MS);
}
// CHECKSTYLE:SKIP
Date origMaxNotAfter = maxNotAfter;
if (certprofile.getspecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
String str = certprofile.setParameter(SpecialX509CertprofileBehavior.PARAMETER_MAXLIFTIME);
long maxLifetimeInDays = Long.parseLong(str);
Date maxLifetime = new Date(gsmckFirstNotBefore.getTime() + maxLifetimeInDays * DAY_IN_MS - MS_PER_SECOND);
if (maxNotAfter.after(maxLifetime)) {
maxNotAfter = maxLifetime;
}
}
Date grantedNotAfter = certTemplate.getNotAfter();
if (grantedNotAfter != null) {
if (grantedNotAfter.after(maxNotAfter)) {
grantedNotAfter = maxNotAfter;
msgBuilder.append(", notAfter modified");
}
} else {
grantedNotAfter = maxNotAfter;
}
if (grantedNotAfter.after(caInfo.getNotAfter())) {
ValidityMode mode = caInfo.getValidityMode();
if (mode == ValidityMode.CUTOFF) {
grantedNotAfter = caInfo.getNotAfter();
} else if (mode == ValidityMode.STRICT) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "notAfter outside of CA's validity is not permitted");
} else if (mode == ValidityMode.LAX) {
// permitted
} else {
throw new RuntimeException("should not reach here, unknown CA ValidityMode " + mode);
}
// end if (mode)
}
if (certprofile.hasMidnightNotBefore() && !maxNotAfter.equals(origMaxNotAfter)) {
Calendar cal = Calendar.getInstance(certprofile.getTimezone());
cal.setTime(new Date(grantedNotAfter.getTime() - DAY_IN_MS));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
grantedNotAfter = cal.getTime();
}
String warning = null;
if (msgBuilder.length() > 2) {
warning = msgBuilder.substring(2);
}
GrantedCertTemplate gct = new GrantedCertTemplate(certTemplate.getExtensions(), certprofile, grantedNotBefore, grantedNotAfter, requestedSubject, grantedPublicKeyInfo, fpPublicKey, subjectPublicKeyData, signer, warning);
gct.setGrantedSubject(grantedSubject);
return gct;
}
use of org.openecard.bouncycastle.asn1.x500.X500Name in project xipki by xipki.
the class X509Ca method incSerialNumber.
// method removeEmptyRdns
private static Object[] incSerialNumber(IdentifiedX509Certprofile profile, X500Name origName, String latestSn) throws BadFormatException {
RDN[] rdns = origName.getRDNs();
int commonNameIndex = -1;
int serialNumberIndex = -1;
for (int i = 0; i < rdns.length; i++) {
RDN rdn = rdns[i];
ASN1ObjectIdentifier type = rdn.getFirst().getType();
if (ObjectIdentifiers.DN_CN.equals(type)) {
commonNameIndex = i;
} else if (ObjectIdentifiers.DN_SERIALNUMBER.equals(type)) {
serialNumberIndex = i;
}
}
String newSerialNumber = profile.incSerialNumber(latestSn);
RDN serialNumberRdn = new RDN(ObjectIdentifiers.DN_SERIALNUMBER, new DERPrintableString(newSerialNumber));
X500Name newName;
if (serialNumberIndex != -1) {
rdns[serialNumberIndex] = serialNumberRdn;
newName = new X500Name(rdns);
} else {
List<RDN> newRdns = new ArrayList<>(rdns.length + 1);
if (commonNameIndex == -1) {
newRdns.add(serialNumberRdn);
}
for (int i = 0; i < rdns.length; i++) {
newRdns.add(rdns[i]);
if (i == commonNameIndex) {
newRdns.add(serialNumberRdn);
}
}
newName = new X500Name(newRdns.toArray(new RDN[0]));
}
return new Object[] { newName, newSerialNumber };
}
Aggregations