Search in sources :

Example 16 with GeneralNames

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);
    }
}
Also used : JcaX509ExtensionUtils(org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) FileWriter(java.io.FileWriter) KeyUsage(org.bouncycastle.asn1.x509.KeyUsage) X500Name(org.bouncycastle.asn1.x500.X500Name) PKCS12BagAttributeCarrier(org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier) PEMEncryptor(org.bouncycastle.openssl.PEMEncryptor) JcaX509CertificateConverter(org.bouncycastle.cert.jcajce.JcaX509CertificateConverter) JcaX509v3CertificateBuilder(org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder) JcePEMEncryptorBuilder(org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder) KeyPair(java.security.KeyPair) ContentSigner(org.bouncycastle.operator.ContentSigner) SecureRandom(java.security.SecureRandom) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) Date(java.util.Date) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) JcaX509v3CertificateBuilder(org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder) X509v3CertificateBuilder(org.bouncycastle.cert.X509v3CertificateBuilder) GeneralName(org.bouncycastle.asn1.x509.GeneralName) JcaPEMWriter(org.bouncycastle.openssl.jcajce.JcaPEMWriter) BasicConstraints(org.bouncycastle.asn1.x509.BasicConstraints) SimpleDateFormat(java.text.SimpleDateFormat) File(java.io.File)

Example 17 with GeneralNames

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);
    }
}
Also used : JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) PrivateKey(java.security.PrivateKey) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) ContentSigner(org.bouncycastle.operator.ContentSigner) PKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) ECKey(java.security.interfaces.ECKey) IOException(java.io.IOException) ExtensionsGenerator(org.bouncycastle.asn1.x509.ExtensionsGenerator) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) GeneralName(org.bouncycastle.asn1.x509.GeneralName) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) InetAddress(java.net.InetAddress)

Example 18 with GeneralNames

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");
}
Also used : Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) KeyPair(java.security.KeyPair) Arrays(java.util.Arrays) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Identifier(org.shredzone.acme4j.Identifier) PKCSObjectIdentifiers(org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers) Extension(org.bouncycastle.asn1.x509.Extension) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Security(java.security.Security) DEROctetString(org.bouncycastle.asn1.DEROctetString) BCStyle(org.bouncycastle.asn1.x500.style.BCStyle) InetAddress(java.net.InetAddress) X500Name(org.bouncycastle.asn1.x500.X500Name) BeforeAll(org.junit.jupiter.api.BeforeAll) Assertions.assertThatExceptionOfType(org.assertj.core.api.Assertions.assertThatExceptionOfType) ASN1IA5String(org.bouncycastle.asn1.ASN1IA5String) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) AutoCloseableSoftAssertions(org.assertj.core.api.AutoCloseableSoftAssertions) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) PEMParser(org.bouncycastle.openssl.PEMParser) StringWriter(java.io.StringWriter) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) StandardCharsets(java.nio.charset.StandardCharsets) Extensions(org.bouncycastle.asn1.x509.Extensions) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider) Test(org.junit.jupiter.api.Test) GeneralName(org.bouncycastle.asn1.x509.GeneralName) StringReader(java.io.StringReader) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) Attribute(org.bouncycastle.asn1.pkcs.Attribute) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) Attribute(org.bouncycastle.asn1.pkcs.Attribute) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) AutoCloseableSoftAssertions(org.assertj.core.api.AutoCloseableSoftAssertions)

Example 19 with GeneralNames

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");
}
Also used : Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) KeyPair(java.security.KeyPair) Arrays(java.util.Arrays) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) ByteArrayOutputStream(java.io.ByteArrayOutputStream) PKCSObjectIdentifiers(org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers) Extension(org.bouncycastle.asn1.x509.Extension) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Security(java.security.Security) DERBitString(org.bouncycastle.asn1.DERBitString) AddressException(jakarta.mail.internet.AddressException) BCStyle(org.bouncycastle.asn1.x500.style.BCStyle) InternetAddress(jakarta.mail.internet.InternetAddress) X500Name(org.bouncycastle.asn1.x500.X500Name) BeforeAll(org.junit.jupiter.api.BeforeAll) AutoCloseableSoftAssertions(org.assertj.core.api.AutoCloseableSoftAssertions) DERIA5String(org.bouncycastle.asn1.DERIA5String) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) UTF_8(java.nio.charset.StandardCharsets.UTF_8) PEMParser(org.bouncycastle.openssl.PEMParser) StringWriter(java.io.StringWriter) IOException(java.io.IOException) Extensions(org.bouncycastle.asn1.x509.Extensions) BouncyCastleProvider(org.bouncycastle.jce.provider.BouncyCastleProvider) Test(org.junit.jupiter.api.Test) GeneralName(org.bouncycastle.asn1.x509.GeneralName) StringReader(java.io.StringReader) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) Attribute(org.bouncycastle.asn1.pkcs.Attribute) KeyUsage(org.bouncycastle.asn1.x509.KeyUsage) KeyPairUtils(org.shredzone.acme4j.util.KeyPairUtils) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) Attribute(org.bouncycastle.asn1.pkcs.Attribute) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1Encodable(org.bouncycastle.asn1.ASN1Encodable) AutoCloseableSoftAssertions(org.assertj.core.api.AutoCloseableSoftAssertions)

Example 20 with GeneralNames

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);
    }
}
Also used : InternetAddress(jakarta.mail.internet.InternetAddress) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) PrivateKey(java.security.PrivateKey) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) ContentSigner(org.bouncycastle.operator.ContentSigner) PKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) KeyUsage(org.bouncycastle.asn1.x509.KeyUsage) ECKey(java.security.interfaces.ECKey) IOException(java.io.IOException) ExtensionsGenerator(org.bouncycastle.asn1.x509.ExtensionsGenerator) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) GeneralName(org.bouncycastle.asn1.x509.GeneralName) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException)

Aggregations

GeneralNames (org.bouncycastle.asn1.x509.GeneralNames)140 GeneralName (org.bouncycastle.asn1.x509.GeneralName)124 IOException (java.io.IOException)68 X509Certificate (java.security.cert.X509Certificate)46 X500Name (org.bouncycastle.asn1.x500.X500Name)45 ContentSigner (org.bouncycastle.operator.ContentSigner)41 ArrayList (java.util.ArrayList)40 JcaContentSignerBuilder (org.bouncycastle.operator.jcajce.JcaContentSignerBuilder)40 BigInteger (java.math.BigInteger)33 JcaX509CertificateConverter (org.bouncycastle.cert.jcajce.JcaX509CertificateConverter)32 List (java.util.List)27 X509CertificateHolder (org.bouncycastle.cert.X509CertificateHolder)27 X509v3CertificateBuilder (org.bouncycastle.cert.X509v3CertificateBuilder)27 Date (java.util.Date)26 JcaX509v3CertificateBuilder (org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder)26 DistributionPoint (org.bouncycastle.asn1.x509.DistributionPoint)25 BasicConstraints (org.bouncycastle.asn1.x509.BasicConstraints)23 CRLDistPoint (org.bouncycastle.asn1.x509.CRLDistPoint)23 X500Principal (javax.security.auth.x500.X500Principal)22 DERIA5String (org.bouncycastle.asn1.DERIA5String)20