use of com.github.zhenwei.core.asn1.x509.GeneralNames in project gitblit by gitblit.
the class X509Utils method newClientCertificate.
/**
* Creates a new client certificate PKCS#12 and PEM store. Any existing
* stores are destroyed.
*
* @param clientMetadata a container for dynamic parameters needed for generation
* @param caKeystoreFile
* @param caKeystorePassword
* @param targetFolder
* @return
*/
public static X509Certificate newClientCertificate(X509Metadata clientMetadata, PrivateKey caPrivateKey, X509Certificate caCert, File targetFolder) {
try {
KeyPair pair = newKeyPair();
X500Name userDN = buildDistinguishedName(clientMetadata);
X500Name issuerDN = new X500Name(PrincipalUtil.getIssuerX509Principal(caCert).getName());
// create a new certificate signed by the Gitblit CA certificate
X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(issuerDN, BigInteger.valueOf(System.currentTimeMillis()), clientMetadata.notBefore, clientMetadata.notAfter, userDN, pair.getPublic());
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
certBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));
certBuilder.addExtension(X509Extension.keyUsage, true, new KeyUsage(KeyUsage.keyEncipherment | KeyUsage.digitalSignature));
if (!StringUtils.isEmpty(clientMetadata.emailAddress)) {
GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.rfc822Name, clientMetadata.emailAddress));
certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
}
ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPrivateKey);
X509Certificate userCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certBuilder.build(signer));
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) pair.getPrivate();
bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
// confirm the validity of the user certificate
userCert.checkValidity();
userCert.verify(caCert.getPublicKey());
userCert.getIssuerDN().equals(caCert.getSubjectDN());
// verify user certificate chain
verifyChain(userCert, caCert);
targetFolder.mkdirs();
// save certificate, stamped with unique name
String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
String id = date;
File certFile = new File(targetFolder, id + ".cer");
int count = 0;
while (certFile.exists()) {
id = date + "_" + Character.toString((char) (0x61 + count));
certFile = new File(targetFolder, id + ".cer");
count++;
}
// save user private key, user certificate and CA certificate to a PKCS#12 store
File p12File = new File(targetFolder, clientMetadata.commonName + ".p12");
if (p12File.exists()) {
p12File.delete();
}
KeyStore userStore = openKeyStore(p12File, clientMetadata.password);
userStore.setKeyEntry(MessageFormat.format("Gitblit ({0}) {1} {2}", clientMetadata.serverHostname, clientMetadata.userDisplayname, id), pair.getPrivate(), null, new Certificate[] { userCert });
userStore.setCertificateEntry(MessageFormat.format("Gitblit ({0}) Certificate Authority", clientMetadata.serverHostname), caCert);
saveKeyStore(p12File, userStore, clientMetadata.password);
// save user private key, user certificate, and CA certificate to a PEM store
File pemFile = new File(targetFolder, clientMetadata.commonName + ".pem");
if (pemFile.exists()) {
pemFile.delete();
}
JcePEMEncryptorBuilder builder = new JcePEMEncryptorBuilder("DES-EDE3-CBC");
builder.setSecureRandom(new SecureRandom());
PEMEncryptor pemEncryptor = builder.build(clientMetadata.password.toCharArray());
JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter(pemFile));
pemWriter.writeObject(pair.getPrivate(), pemEncryptor);
pemWriter.writeObject(userCert);
pemWriter.writeObject(caCert);
pemWriter.flush();
pemWriter.close();
// save certificate after successfully creating the key stores
saveCertificate(userCert, certFile);
// update serial number in metadata object
clientMetadata.serialNumber = userCert.getSerialNumber().toString();
return userCert;
} catch (Throwable t) {
throw new RuntimeException("Failed to generate client certificate!", t);
}
}
use of com.github.zhenwei.core.asn1.x509.GeneralNames in project acme4j by shred.
the class CSRBuilder method sign.
/**
* Signs the completed CSR.
*
* @param keypair
* {@link KeyPair} to sign the CSR with
*/
public void sign(KeyPair keypair) throws IOException {
Objects.requireNonNull(keypair, "keypair");
if (namelist.isEmpty() && iplist.isEmpty()) {
throw new IllegalStateException("No domain or IP address was set");
}
try {
int ix = 0;
GeneralName[] gns = new GeneralName[namelist.size() + iplist.size()];
for (String name : namelist) {
gns[ix++] = new GeneralName(GeneralName.dNSName, name);
}
for (InetAddress ip : iplist) {
gns[ix++] = new GeneralName(GeneralName.iPAddress, ip.getHostAddress());
}
GeneralNames subjectAltName = new GeneralNames(gns);
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(namebuilder.build(), keypair.getPublic());
ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
extensionsGenerator.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
p10Builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extensionsGenerator.generate());
PrivateKey pk = keypair.getPrivate();
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder(pk instanceof ECKey ? EC_SIGNATURE_ALG : SIGNATURE_ALG);
ContentSigner signer = csBuilder.build(pk);
csr = p10Builder.build(signer);
} catch (OperatorCreationException ex) {
throw new IOException("Could not generate CSR", ex);
}
}
use of com.github.zhenwei.core.asn1.x509.GeneralNames in project acme4j by shred.
the class CSRBuilderTest method csrTest.
/**
* Checks if the CSR contains the right parameters.
* <p>
* This is not supposed to be a Bouncy Castle test. If the
* {@link PKCS10CertificationRequest} contains the right parameters, we assume that
* Bouncy Castle encodes it properly.
*/
private void csrTest(PKCS10CertificationRequest csr) {
X500Name name = csr.getSubject();
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
softly.assertThat(name.getRDNs(BCStyle.CN)).as("CN").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("abc.de");
softly.assertThat(name.getRDNs(BCStyle.C)).as("C").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("XX");
softly.assertThat(name.getRDNs(BCStyle.L)).as("L").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("Testville");
softly.assertThat(name.getRDNs(BCStyle.O)).as("O").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("Testing Co");
softly.assertThat(name.getRDNs(BCStyle.OU)).as("OU").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("Testunit");
softly.assertThat(name.getRDNs(BCStyle.ST)).as("ST").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("ABC");
}
Attribute[] attr = csr.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
assertThat(attr).hasSize(1);
ASN1Encodable[] extensions = attr[0].getAttrValues().toArray();
assertThat(extensions).hasSize(1);
GeneralNames names = GeneralNames.fromExtensions((Extensions) extensions[0], Extension.subjectAlternativeName);
assertThat(names.getNames()).filteredOn(gn -> gn.getTagNo() == GeneralName.dNSName).extracting(gn -> ASN1IA5String.getInstance(gn.getName()).getString()).containsExactlyInAnyOrder("abc.de", "fg.hi", "jklm.no", "pqr.st", "uv.wx", "y.z", "*.wild.card", "ide1.nt", "ide2.nt", "ide3.nt");
assertThat(names.getNames()).filteredOn(gn -> gn.getTagNo() == GeneralName.iPAddress).extracting(gn -> getIP(gn.getName()).getHostAddress()).containsExactlyInAnyOrder("192.168.0.1", "192.168.0.2", "10.0.0.1", "10.0.0.2", "fd00:0:0:0:0:0:0:1", "fd00:0:0:0:0:0:0:2", "192.168.5.5", "192.168.5.6", "192.168.5.7");
}
use of com.github.zhenwei.core.asn1.x509.GeneralNames in project acme4j by shred.
the class SMIMECSRBuilderTest method smimeCsrTest.
/**
* Checks if the S/MIME CSR contains the right parameters.
* <p>
* This is not supposed to be a Bouncy Castle test. If the
* {@link PKCS10CertificationRequest} contains the right parameters, we assume that
* Bouncy Castle encodes it properly.
*/
private void smimeCsrTest(PKCS10CertificationRequest csr) {
X500Name name = csr.getSubject();
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
softly.assertThat(name.getRDNs(BCStyle.CN)).as("CN").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("mail@example.com");
softly.assertThat(name.getRDNs(BCStyle.C)).as("C").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("XX");
softly.assertThat(name.getRDNs(BCStyle.L)).as("L").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("Testville");
softly.assertThat(name.getRDNs(BCStyle.O)).as("O").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("Testing Co");
softly.assertThat(name.getRDNs(BCStyle.OU)).as("OU").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("Testunit");
softly.assertThat(name.getRDNs(BCStyle.ST)).as("ST").extracting(rdn -> rdn.getFirst().getValue().toString()).contains("ABC");
}
Attribute[] attr = csr.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
assertThat(attr).hasSize(1);
ASN1Encodable[] extensions = attr[0].getAttrValues().toArray();
assertThat(extensions).hasSize(1);
GeneralNames names = GeneralNames.fromExtensions((Extensions) extensions[0], Extension.subjectAlternativeName);
assertThat(names.getNames()).filteredOn(gn -> gn.getTagNo() == GeneralName.rfc822Name).extracting(gn -> DERIA5String.getInstance(gn.getName()).getString()).containsExactlyInAnyOrder("mail@example.com", "info@example.com", "sales@example.com", "shop@example.com", "support@example.com", "help@example.com");
}
use of com.github.zhenwei.core.asn1.x509.GeneralNames in project acme4j by shred.
the class SMIMECSRBuilder method sign.
/**
* Signs the completed S/MIME CSR.
*
* @param keypair
* {@link KeyPair} to sign the CSR with
*/
public void sign(KeyPair keypair) throws IOException {
requireNonNull(keypair, "keypair");
if (emaillist.isEmpty()) {
throw new IllegalStateException("No email address was set");
}
try {
int ix = 0;
GeneralName[] gns = new GeneralName[emaillist.size()];
for (InternetAddress email : emaillist) {
gns[ix++] = new GeneralName(GeneralName.rfc822Name, email.getAddress());
}
GeneralNames subjectAltName = new GeneralNames(gns);
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(namebuilder.build(), keypair.getPublic());
ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
extensionsGenerator.addExtension(Extension.subjectAlternativeName, false, subjectAltName);
KeyUsage keyUsage = new KeyUsage(keyUsageType.getKeyUsageBits());
extensionsGenerator.addExtension(Extension.keyUsage, true, keyUsage);
p10Builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extensionsGenerator.generate());
PrivateKey pk = keypair.getPrivate();
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder(pk instanceof ECKey ? EC_SIGNATURE_ALG : SIGNATURE_ALG);
ContentSigner signer = csBuilder.build(pk);
csr = p10Builder.build(signer);
} catch (OperatorCreationException ex) {
throw new IOException("Could not generate CSR", ex);
}
}
Aggregations