use of org.bouncycastle.asn1.x509.BasicConstraints in project xipki by xipki.
the class CertprofileValidator method validate.
public static void validate(Certprofile certprofile) throws CertprofileException {
StringBuilder msg = new StringBuilder();
Map<ASN1ObjectIdentifier, ExtensionControl> controls = certprofile.getExtensionControls();
Set<ASN1ObjectIdentifier> types = new HashSet<>(controls.keySet());
CertLevel certLevel = certprofile.getCertLevel();
CertDomain certDomain = certprofile.getCertDomain();
ExtensionSpec spec = ExtensionSpec.getExtensionSpec(certDomain, certLevel);
// make sure that non-request extensions are not permitted in requests
Set<ASN1ObjectIdentifier> set = new HashSet<>();
for (ASN1ObjectIdentifier type : types) {
ExtensionControl control = controls.get(type);
if (control.isRequest() && spec.isNonRequest(type)) {
set.add(type);
}
}
if (CollectionUtil.isNotEmpty(set)) {
msg.append("extensions ").append(toString(set)).append(" must not be contained in request, ");
}
// make sure that non-permitted extensions are not configured
set.clear();
for (ASN1ObjectIdentifier type : types) {
if (spec.isNotPermitted(type)) {
set.add(type);
}
}
if (CollectionUtil.isNotEmpty(set)) {
msg.append("extensions ").append(toString(set)).append(" must not be contained, ");
}
// make sure that critical only extensions are not marked as non-critical.
set.clear();
for (ASN1ObjectIdentifier type : types) {
ExtensionControl control = controls.get(type);
if (control.isCritical() && spec.isNonCriticalOnly(type)) {
set.add(type);
}
}
if (CollectionUtil.isNotEmpty(set)) {
msg.append("critical only extensions are marked as non-critical ").append(toString(set)).append(", ");
}
// make sure that non-critical only extensions are not marked as critical.
set.clear();
for (ASN1ObjectIdentifier type : types) {
ExtensionControl control = controls.get(type);
if (!control.isCritical() && spec.isCriticalOnly(type)) {
set.add(type);
}
}
if (CollectionUtil.isNotEmpty(set)) {
msg.append("non-critical only extensions are marked as critical ").append(toString(set)).append(", ");
}
// make sure that required extensions are present
set.clear();
Set<ASN1ObjectIdentifier> requiredTypes = spec.getRequiredExtensions();
for (ASN1ObjectIdentifier type : requiredTypes) {
ExtensionControl extCtrl = controls.get(type);
if (extCtrl == null || !extCtrl.isRequired()) {
set.add(type);
}
}
if (!set.isEmpty()) {
msg.append("required extensions are not configured or not marked as required ").append(toString(set)).append(", ");
}
// KeyUsage
Set<KeyUsageControl> usages = certprofile.getKeyUsage();
if (certLevel == CertLevel.SubCA || certLevel == CertLevel.RootCA) {
// make sure the CA certificate contains usage keyCertSign and cRLSign
KeyUsage[] requiredUsages = new KeyUsage[] { KeyUsage.keyCertSign, KeyUsage.cRLSign };
for (KeyUsage usage : requiredUsages) {
if (!containsKeyusage(usages, usage)) {
msg.append("CA profile does not contain keyUsage ").append(usage).append(", ");
}
}
} else {
// make sure the EE certificate does not contain CA-only usages
KeyUsage[] caOnlyUsages = { KeyUsage.keyCertSign };
Set<KeyUsage> setUsages = new HashSet<>();
for (KeyUsage caOnlyUsage : caOnlyUsages) {
if (containsKeyusage(usages, caOnlyUsage)) {
setUsages.add(caOnlyUsage);
}
}
if (CollectionUtil.isNotEmpty(setUsages)) {
msg.append("EndEntity profile must not contain CA-only keyUsage ").append(setUsages).append(", ");
}
}
// BasicConstraints
if (certLevel == CertLevel.RootCA) {
Integer pathLen = certprofile.getPathLenBasicConstraint();
if (pathLen != null) {
msg.append("Root CA must not set PathLen, ");
}
}
if (certDomain == CertDomain.CABForumBR) {
validateCABForumBR(certprofile, msg);
}
// Edwards or Montgomery Curves (RFC8410)
Map<ASN1ObjectIdentifier, KeyParametersOption> keyAlgorithms = certprofile.getKeyAlgorithms();
boolean withEdwardsCurves = keyAlgorithms.containsKey(EdECConstants.id_ED25519) || keyAlgorithms.containsKey(EdECConstants.id_ED448);
boolean withMontgomeryCurves = keyAlgorithms.containsKey(EdECConstants.id_X25519) || keyAlgorithms.containsKey(EdECConstants.id_X448);
if (withEdwardsCurves || withMontgomeryCurves) {
Set<KeyUsage> requiredUsages = new HashSet<>();
Set<KeyUsage> optionalUsages = new HashSet<>();
for (KeyUsageControl m : usages) {
if (m.isRequired()) {
requiredUsages.add(m.getKeyUsage());
} else {
optionalUsages.add(m.getKeyUsage());
}
}
List<KeyUsage> allowedUsages;
if (withMontgomeryCurves) {
if (certLevel != CertLevel.EndEntity) {
msg.append("montgomery curves are not permitted in CA certificates, ");
}
if (!requiredUsages.contains(KeyUsage.keyAgreement)) {
msg.append("required KeyUsage KeyAgreement is not marked as 'required', ");
}
allowedUsages = Arrays.asList(KeyUsage.keyAgreement, KeyUsage.encipherOnly, KeyUsage.decipherOnly);
} else {
if (certLevel == CertLevel.EndEntity) {
if (!(requiredUsages.contains(KeyUsage.digitalSignature) || requiredUsages.contains(KeyUsage.contentCommitment))) {
msg.append("required KeyUsage digitalSignature or contentCommitment is not marked " + "as 'required', ");
}
allowedUsages = Arrays.asList(KeyUsage.digitalSignature, KeyUsage.contentCommitment);
} else {
allowedUsages = Arrays.asList(KeyUsage.digitalSignature, KeyUsage.contentCommitment, KeyUsage.keyCertSign, KeyUsage.cRLSign);
}
}
requiredUsages.removeAll(allowedUsages);
optionalUsages.removeAll(allowedUsages);
if (!requiredUsages.isEmpty()) {
msg.append("Required KeyUsage items ").append(requiredUsages).append(" are not permitted, ");
}
if (!optionalUsages.isEmpty()) {
msg.append("Optional KeyUsage items ").append(requiredUsages).append(" are not permitted, ");
}
}
final int len = msg.length();
if (len > 2) {
msg.delete(len - 2, len);
throw new CertprofileException(msg.toString());
}
}
use of org.bouncycastle.asn1.x509.BasicConstraints in project xipki by xipki.
the class CabProfileConfDemo method certprofileCabSubCa.
// method certprofileCabRootCa
private static void certprofileCabSubCa(String destFilename) {
X509ProfileType profile = getBaseCabProfile("certprofile SubCA (CA/Browser Forum BR)", CertLevel.SubCA, "8y");
// Subject
Subject subject = profile.getSubject();
List<RdnType> rdnControls = subject.getRdns();
rdnControls.add(createRdn(DN.C, 1, 1));
rdnControls.add(createRdn(DN.O, 1, 1));
rdnControls.add(createRdn(DN.OU, 0, 1));
rdnControls.add(createRdn(DN.SN, 0, 1));
rdnControls.add(createRdn(DN.CN, 1, 1));
// Extensions
List<ExtensionType> list = profile.getExtensions();
// Extensions - controls
list.add(createExtension(Extension.subjectKeyIdentifier, true, false));
list.add(createExtension(Extension.cRLDistributionPoints, true, false));
last(list).setCrlDistributionPoints(createCrlDistibutoionPoints());
// Extensions - basicConstraints
list.add(createExtension(Extension.basicConstraints, true, true));
last(list).setBasicConstrains(createBasicConstraints(1));
// Extensions - AuthorityInfoAccess
list.add(createExtension(Extension.authorityInfoAccess, true, false));
last(list).setAuthorityInfoAccess(createAuthorityInfoAccess());
// Extensions - AuthorityKeyIdentifier
list.add(createExtension(Extension.authorityKeyIdentifier, true, false));
// Extensions - keyUsage
list.add(createExtension(Extension.keyUsage, true, true));
last(list).setKeyUsage(createKeyUsage(new KeyUsage[] { KeyUsage.keyCertSign, KeyUsage.cRLSign }, null));
// Extensions - CertificatePolicies
list.add(createExtension(Extension.certificatePolicies, true, false));
Map<ASN1ObjectIdentifier, String> policiesIdAndCpsMap = new HashMap<>();
policiesIdAndCpsMap.put(new ASN1ObjectIdentifier("1.2.3.4"), "http://abc.def.de/cfp");
last(list).setCertificatePolicies(createCertificatePolicies(policiesIdAndCpsMap));
marshall(profile, destFilename, true);
}
use of org.bouncycastle.asn1.x509.BasicConstraints in project xipki by xipki.
the class ProfileConfDemo method certprofileGmt0015.
// method certprofileMaxTime
private static void certprofileGmt0015(String destFilename) {
String desc = "certprofile GMT 0015";
X509ProfileType profile = getBaseProfile(desc, CertLevel.EndEntity, "5y", false);
// Subject
Subject subject = profile.getSubject();
List<RdnType> rdnControls = subject.getRdns();
rdnControls.add(createRdn(DN.C, 1, 1));
rdnControls.add(createRdn(DN.O, 1, 1));
rdnControls.add(createRdn(DN.OU, 0, 1));
rdnControls.add(createRdn(DN.CN, 1, 1));
rdnControls.add(createRdn(Extn.id_GMT_0015_ICRegistrationNumber, 0, 1));
rdnControls.add(createRdn(Extn.id_GMT_0015_IdentityCode, 0, 1));
rdnControls.add(createRdn(Extn.id_GMT_0015_InsuranceNumber, 0, 1));
rdnControls.add(createRdn(Extn.id_GMT_0015_OrganizationCode, 0, 1));
rdnControls.add(createRdn(Extn.id_GMT_0015_TaxationNumber, 0, 1));
// Extensions
// Extensions - controls
List<ExtensionType> list = profile.getExtensions();
list.add(createExtension(Extension.subjectKeyIdentifier, true, false, null));
list.add(createExtension(Extension.cRLDistributionPoints, false, false, null));
list.add(createExtension(Extension.freshestCRL, false, false, null));
// Extensions - basicConstraints
list.add(createExtension(Extension.basicConstraints, true, true));
// Extensions - AuthorityInfoAccess
list.add(createExtension(Extension.authorityInfoAccess, true, false));
last(list).setAuthorityInfoAccess(createAuthorityInfoAccess());
// Extensions - AuthorityKeyIdentifier
list.add(createExtension(Extension.authorityKeyIdentifier, true, false));
// Extensions - keyUsage
list.add(createExtension(Extension.keyUsage, true, true));
last(list).setKeyUsage(createKeyUsage(new KeyUsage[] { KeyUsage.digitalSignature, KeyUsage.dataEncipherment, KeyUsage.keyEncipherment }, null));
// Extensions - extendedKeyUsage
list.add(createExtension(Extension.extendedKeyUsage, true, false));
last(list).setExtendedKeyUsage(createExtendedKeyUsage(new ASN1ObjectIdentifier[] { ObjectIdentifiers.XKU.id_kp_clientAuth }, null));
// Extension id_GMT_0015_ICRegistrationNumber
ASN1ObjectIdentifier[] gmtOids = new ASN1ObjectIdentifier[] { Extn.id_GMT_0015_ICRegistrationNumber, Extn.id_GMT_0015_IdentityCode, Extn.id_GMT_0015_InsuranceNumber, Extn.id_GMT_0015_OrganizationCode, Extn.id_GMT_0015_TaxationNumber };
for (ASN1ObjectIdentifier m : gmtOids) {
list.add(createExtension(m, true, false));
last(list).setPermittedInRequest(true);
}
marshall(profile, destFilename, true);
}
use of org.bouncycastle.asn1.x509.BasicConstraints in project athenz by AthenZ.
the class Crypto method generateX509Certificate.
public static X509Certificate generateX509Certificate(PKCS10CertificationRequest certReq, PrivateKey caPrivateKey, X500Name issuer, int validityTimeout, boolean basicConstraints) {
// set validity for the given number of minutes from now
Date notBefore = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(notBefore);
cal.add(Calendar.MINUTE, validityTimeout);
Date notAfter = cal.getTime();
// Generate self-signed certificate
X509Certificate cert;
try {
JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = new JcaPKCS10CertificationRequest(certReq);
PublicKey publicKey = jcaPKCS10CertificationRequest.getPublicKey();
X509v3CertificateBuilder caBuilder = new JcaX509v3CertificateBuilder(issuer, BigInteger.valueOf(System.currentTimeMillis()), notBefore, notAfter, certReq.getSubject(), publicKey).addExtension(Extension.basicConstraints, false, new BasicConstraints(basicConstraints)).addExtension(Extension.keyUsage, true, new X509KeyUsage(X509KeyUsage.digitalSignature | X509KeyUsage.keyEncipherment)).addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(new KeyPurposeId[] { KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth }));
// see if we have the dns/rfc822/ip address extensions specified in the csr
ArrayList<GeneralName> altNames = new ArrayList<>();
Attribute[] certAttributes = jcaPKCS10CertificationRequest.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
if (certAttributes != null && certAttributes.length > 0) {
for (Attribute attribute : certAttributes) {
Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
GeneralNames gns = GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName);
if (gns == null) {
continue;
}
GeneralName[] names = gns.getNames();
for (GeneralName name : names) {
switch(name.getTagNo()) {
case GeneralName.dNSName:
case GeneralName.iPAddress:
case GeneralName.rfc822Name:
case GeneralName.uniformResourceIdentifier:
altNames.add(name);
break;
}
}
}
if (!altNames.isEmpty()) {
caBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(altNames.toArray(new GeneralName[0])));
}
}
String signatureAlgorithm = getSignatureAlgorithm(caPrivateKey.getAlgorithm(), SHA256);
ContentSigner caSigner = new JcaContentSignerBuilder(signatureAlgorithm).setProvider(BC_PROVIDER).build(caPrivateKey);
JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider(BC_PROVIDER);
cert = converter.getCertificate(caBuilder.build(caSigner));
} catch (CertificateException ex) {
LOG.error("generateX509Certificate: Caught CertificateException when generating certificate: " + ex.getMessage());
throw new CryptoException(ex);
} catch (OperatorCreationException ex) {
LOG.error("generateX509Certificate: Caught OperatorCreationException when creating JcaContentSignerBuilder: " + ex.getMessage());
throw new CryptoException(ex);
} catch (InvalidKeyException ex) {
LOG.error("generateX509Certificate: Caught InvalidKeySpecException, invalid key spec is being used: " + ex.getMessage());
throw new CryptoException(ex);
} catch (NoSuchAlgorithmException ex) {
LOG.error("generateX509Certificate: Caught NoSuchAlgorithmException, check to make sure the algorithm is supported by the provider: " + ex.getMessage());
throw new CryptoException(ex);
} catch (Exception ex) {
LOG.error("generateX509Certificate: unable to generate X509 Certificate: {}", ex.getMessage());
throw new CryptoException("Unable to generate X509 Certificate");
}
return cert;
}
use of org.bouncycastle.asn1.x509.BasicConstraints in project radixdlt by radixdlt.
the class RadixKeyStore method selfSignedCert.
/**
* Creates a self-signed certificate from the specified key-pair.
*
* <p>The validity period for the certificate extends from the current local clock time for the
* specified validity period in years.
*
* @param keyPair The key-pair to create the self-signed certificate for.
* @param validityYears Years The validity period in years.
* @param subjectDN The key's distinguished subject name.
* @return A self-signed certificate
* @throws KeyStoreException If an error occurs while building the certificate
* @throws IOException If an I/O error occurs while building the certificate
*/
@VisibleForTesting
static Certificate selfSignedCert(KeyPair keyPair, int validityYears, String subjectDN) throws KeyStoreException, IOException {
X500Name dnName = new X500Name(subjectDN);
LocalDateTime startDate = LocalDateTime.now();
LocalDateTime endDate = startDate.plusYears(validityYears);
BigInteger certSerialNumber = BigInteger.valueOf(toDate(startDate).getTime());
var certBuilder = new JcaX509v3CertificateBuilder(dnName, certSerialNumber, toDate(startDate), toDate(endDate), dnName, keyPair.getPublic());
BasicConstraints basicConstraints = new BasicConstraints(true);
certBuilder.addExtension(OID_BASIC_CONSTRAINTS, true, basicConstraints);
try {
ContentSigner contentSigner = new JcaContentSignerBuilder(CERT_SIGNATURE_ALG).build(keyPair.getPrivate());
return new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner));
} catch (OperatorCreationException | CertificateException ex) {
throw new KeyStoreException("Error creating certificate", ex);
}
}
Aggregations