Example usage for org.bouncycastle.operator.jcajce JcaContentSignerBuilder build

List of usage examples for org.bouncycastle.operator.jcajce JcaContentSignerBuilder build

Introduction

In this page you can find the example usage for org.bouncycastle.operator.jcajce JcaContentSignerBuilder build.

Prototype

public ContentSigner build(PrivateKey privateKey) throws OperatorCreationException 

Source Link

Usage

From source file:net.maritimecloud.pki.CertificateBuilder.java

License:Apache License

/**
 * Builds and signs a certificate. The certificate will be build on the given subject-public-key and signed with
 * the given issuer-private-key. The issuer and subject will be identified in the strings provided.
 *
 * @param serialNumber The serialnumber of the new certificate.
 * @param signerPrivateKey Private key for signing the certificate
 * @param signerPublicKey Public key of the signing certificate
 * @param subjectPublicKey Public key for the new certificate
 * @param issuer DN of the signing certificate
 * @param subject DN of the new certificate
 * @param customAttrs The custom MC attributes to include in the certificate
 * @param type Type of certificate, can be "ROOT", "INTERMEDIATE" or "ENTITY".
 * @param ocspUrl OCSP endpoint/* ww  w.  j  a  va 2 s. c om*/
 * @param crlUrl CRL endpoint - can be null
 * @return A signed X509Certificate
 * @throws Exception Throws exception on certificate generation errors.
 */
public X509Certificate buildAndSignCert(BigInteger serialNumber, PrivateKey signerPrivateKey,
        PublicKey signerPublicKey, PublicKey subjectPublicKey, X500Name issuer, X500Name subject,
        Map<String, String> customAttrs, String type, String ocspUrl, String crlUrl) throws Exception {
    // Dates are converted to GMT/UTC inside the cert builder
    Calendar cal = Calendar.getInstance();
    Date now = cal.getTime();
    Date expire = new GregorianCalendar(CERT_EXPIRE_YEAR, 0, 1).getTime();
    X509v3CertificateBuilder certV3Bldr = new JcaX509v3CertificateBuilder(issuer, serialNumber, now, // Valid from now...
            expire, // until CERT_EXPIRE_YEAR
            subject, subjectPublicKey);
    JcaX509ExtensionUtils extensionUtil = new JcaX509ExtensionUtils();
    // Create certificate extensions
    if ("ROOTCA".equals(type)) {
        certV3Bldr = certV3Bldr.addExtension(Extension.basicConstraints, true, new BasicConstraints(true))
                .addExtension(Extension.keyUsage, true,
                        new X509KeyUsage(X509KeyUsage.digitalSignature | X509KeyUsage.nonRepudiation
                                | X509KeyUsage.keyEncipherment | X509KeyUsage.keyCertSign
                                | X509KeyUsage.cRLSign));
    } else if ("INTERMEDIATE".equals(type)) {
        certV3Bldr = certV3Bldr.addExtension(Extension.basicConstraints, true, new BasicConstraints(true))
                .addExtension(Extension.keyUsage, true,
                        new X509KeyUsage(X509KeyUsage.digitalSignature | X509KeyUsage.nonRepudiation
                                | X509KeyUsage.keyEncipherment | X509KeyUsage.keyCertSign
                                | X509KeyUsage.cRLSign));
    } else {
        // Subject Alternative Name
        GeneralName[] genNames = null;
        if (customAttrs != null && !customAttrs.isEmpty()) {
            genNames = new GeneralName[customAttrs.size()];
            Iterator<Map.Entry<String, String>> it = customAttrs.entrySet().iterator();
            int idx = 0;
            while (it.hasNext()) {
                Map.Entry<String, String> pair = it.next();
                if (PKIConstants.X509_SAN_DNSNAME.equals(pair.getKey())) {
                    genNames[idx] = new GeneralName(GeneralName.dNSName, pair.getValue());
                } else {
                    //genNames[idx] = new GeneralName(GeneralName.otherName, new DERUTF8String(pair.getKey() + ";" + pair.getValue()));
                    DERSequence othernameSequence = new DERSequence(
                            new ASN1Encodable[] { new ASN1ObjectIdentifier(pair.getKey()),
                                    new DERTaggedObject(true, 0, new DERUTF8String(pair.getValue())) });
                    genNames[idx] = new GeneralName(GeneralName.otherName, othernameSequence);
                }
                idx++;
            }
        }
        if (genNames != null) {
            certV3Bldr = certV3Bldr.addExtension(Extension.subjectAlternativeName, false,
                    new GeneralNames(genNames));
        }
    }
    // Basic extension setup
    certV3Bldr = certV3Bldr
            .addExtension(Extension.authorityKeyIdentifier, false,
                    extensionUtil.createAuthorityKeyIdentifier(signerPublicKey))
            .addExtension(Extension.subjectKeyIdentifier, false,
                    extensionUtil.createSubjectKeyIdentifier(subjectPublicKey));
    // CRL Distribution Points
    DistributionPointName distPointOne = new DistributionPointName(
            new GeneralNames(new GeneralName(GeneralName.uniformResourceIdentifier, crlUrl)));
    DistributionPoint[] distPoints = new DistributionPoint[1];
    distPoints[0] = new DistributionPoint(distPointOne, null, null);
    certV3Bldr.addExtension(Extension.cRLDistributionPoints, false, new CRLDistPoint(distPoints));
    // OCSP endpoint - is not available for the CAs
    if (ocspUrl != null) {
        GeneralName ocspName = new GeneralName(GeneralName.uniformResourceIdentifier, ocspUrl);
        AuthorityInformationAccess authorityInformationAccess = new AuthorityInformationAccess(
                X509ObjectIdentifiers.ocspAccessMethod, ocspName);
        certV3Bldr.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess);
    }
    // Create the key signer
    JcaContentSignerBuilder builder = new JcaContentSignerBuilder(SIGNER_ALGORITHM);
    builder.setProvider(BC_PROVIDER_NAME);
    ContentSigner signer = builder.build(signerPrivateKey);
    return new JcaX509CertificateConverter().setProvider(BC_PROVIDER_NAME)
            .getCertificate(certV3Bldr.build(signer));
}

From source file:net.maritimecloud.pki.Revocation.java

License:Apache License

/**
 * Creates a Certificate RevocationInfo List (CRL) for the certificate serialnumbers given.
 *
 * @param revokedCerts  List of the serialnumbers that should be revoked.
 * @param keyEntry Private key to sign the CRL
 * @return a CRL/*  w w w  .  ja va2 s . c o m*/
 */
public static X509CRL generateCRL(List<RevocationInfo> revokedCerts, KeyStore.PrivateKeyEntry keyEntry) {
    Date now = new Date();
    Calendar cal = Calendar.getInstance();
    cal.setTime(now);
    cal.add(Calendar.DATE, 7);
    String signCertX500Name;
    try {
        signCertX500Name = new JcaX509CertificateHolder((X509Certificate) keyEntry.getCertificate())
                .getSubject().toString();
    } catch (CertificateEncodingException e) {
        e.printStackTrace();
        return null;
    }
    X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(new X500Name(signCertX500Name), now);
    crlBuilder.setNextUpdate(new Date(now.getTime() + 24 * 60 * 60 * 1000 * 7)); // The next CRL is next week (dummy value)
    for (RevocationInfo cert : revokedCerts) {
        crlBuilder.addCRLEntry(cert.getSerialNumber(), cert.getRevokedAt(), cert.getRevokeReason().ordinal());
    }
    //crlBuilder.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert));
    //crlBuilder.addExtension(X509Extensions.CRLNumber, false, new CRLNumber(BigInteger.valueOf(1)));

    JcaContentSignerBuilder signBuilder = new JcaContentSignerBuilder(SIGNER_ALGORITHM);
    signBuilder.setProvider(BC_PROVIDER_NAME);
    ContentSigner signer;
    try {
        signer = signBuilder.build(keyEntry.getPrivateKey());
    } catch (OperatorCreationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
        return null;
    }

    X509CRLHolder cRLHolder = crlBuilder.build(signer);
    JcaX509CRLConverter converter = new JcaX509CRLConverter();
    converter.setProvider(BC_PROVIDER_NAME);
    X509CRL crl = null;
    try {
        crl = converter.getCRL(cRLHolder);
    } catch (CRLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return crl;
}

From source file:net.maritimecloud.pki.Revocation.java

License:Apache License

/**
 * Creates a Certificate RevocationInfo List (CRL) for the certificate serialnumbers given.
 *
 * @param signName DN name of the signing certificate
 * @param revokedCerts  List of the serialnumbers that should be revoked.
 * @param keyEntry Private key to sign the CRL
 * @param outputCaCrlPath Where to place the CRL
 *//*from ww  w . j av a2  s .  c  o  m*/
public static void generateRootCACRL(String signName, List<RevocationInfo> revokedCerts,
        KeyStore.PrivateKeyEntry keyEntry, String outputCaCrlPath) {
    Date now = new Date();
    Calendar cal = Calendar.getInstance();
    cal.setTime(now);
    cal.add(Calendar.YEAR, 1);
    X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(new X500Name(signName), now);
    crlBuilder.setNextUpdate(cal.getTime()); // The next CRL is next year (dummy value)
    if (revokedCerts != null) {
        for (RevocationInfo cert : revokedCerts) {
            crlBuilder.addCRLEntry(cert.getSerialNumber(), cert.getRevokedAt(),
                    cert.getRevokeReason().ordinal());
        }
    }
    //crlBuilder.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert));
    //crlBuilder.addExtension(X509Extensions.CRLNumber, false, new CRLNumber(BigInteger.valueOf(1)));

    JcaContentSignerBuilder signBuilder = new JcaContentSignerBuilder(SIGNER_ALGORITHM);
    signBuilder.setProvider(BC_PROVIDER_NAME);
    ContentSigner signer;
    try {
        signer = signBuilder.build(keyEntry.getPrivateKey());
    } catch (OperatorCreationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
        return;
    }

    X509CRLHolder cRLHolder = crlBuilder.build(signer);
    JcaX509CRLConverter converter = new JcaX509CRLConverter();
    converter.setProvider(BC_PROVIDER_NAME);
    X509CRL crl;
    try {
        crl = converter.getCRL(cRLHolder);
    } catch (CRLException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
    String pemCrl;
    try {
        pemCrl = getPemFromEncoded("X509 CRL", crl.getEncoded());
    } catch (CRLException e) {
        //log.warn("unable to generate RootCACRL", e);
        return;
    }
    try {
        BufferedWriter writer = new BufferedWriter(new FileWriter(outputCaCrlPath));
        writer.write(pemCrl);
        writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

From source file:net.sf.keystore_explorer.crypto.signing.JarSigner.java

License:Open Source License

private static byte[] createSignatureBlock(byte[] toSign, PrivateKey privateKey,
        X509Certificate[] certificateChain, SignatureType signatureType, String tsaUrl, Provider provider)
        throws CryptoException {

    try {//from w  w  w. j  a v a 2 s . c om
        List<X509Certificate> certList = new ArrayList<X509Certificate>();

        Collections.addAll(certList, certificateChain);

        DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider("BC")
                .build();
        JcaContentSignerBuilder csb = new JcaContentSignerBuilder(signatureType.jce())
                .setSecureRandom(SecureRandom.getInstance("SHA1PRNG"));
        if (provider != null) {
            csb.setProvider(provider);
        }
        JcaSignerInfoGeneratorBuilder siGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(digCalcProv);

        // remove cmsAlgorithmProtect for compatibility reasons
        SignerInfoGenerator sigGen = siGeneratorBuilder.build(csb.build(privateKey), certificateChain[0]);
        final CMSAttributeTableGenerator sAttrGen = sigGen.getSignedAttributeTableGenerator();
        sigGen = new SignerInfoGenerator(sigGen, new DefaultSignedAttributeTableGenerator() {
            @Override
            public AttributeTable getAttributes(@SuppressWarnings("rawtypes") Map parameters) {
                AttributeTable ret = sAttrGen.getAttributes(parameters);
                return ret.remove(CMSAttributes.cmsAlgorithmProtect);
            }
        }, sigGen.getUnsignedAttributeTableGenerator());

        CMSSignedDataGenerator dataGen = new CMSSignedDataGenerator();
        dataGen.addSignerInfoGenerator(sigGen);
        dataGen.addCertificates(new JcaCertStore(certList));

        CMSSignedData signedData = dataGen.generate(new CMSProcessableByteArray(toSign), true);

        // now let TSA time-stamp the signature
        if (tsaUrl != null && !tsaUrl.isEmpty()) {
            signedData = addTimestamp(tsaUrl, signedData);
        }

        return signedData.getEncoded();
    } catch (Exception ex) {
        throw new CryptoException(res.getString("SignatureBlockCreationFailed.exception.message"), ex);
    }
}

From source file:net.sf.portecle.crypto.X509CertUtil.java

License:Open Source License

/**
 * Create a PKCS #10 certification request (CSR) using the supplied certificate and private key.
 * /*  w w w  .  j  a v a  2s  .  c  om*/
 * @param cert The certificate
 * @param privateKey The private key
 * @throws CryptoException If there was a problem generating the CSR
 * @return The CSR
 */
public static PKCS10CertificationRequest generatePKCS10CSR(X509Certificate cert, PrivateKey privateKey)
        throws CryptoException {
    X500Name subject = new X500Name(cert.getSubjectDN().toString());

    JcaPKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(subject,
            cert.getPublicKey());
    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(cert.getSigAlgName());

    try {
        ContentVerifierProvider prov = new JcaContentVerifierProviderBuilder().build(cert);
        PKCS10CertificationRequest csr = csrBuilder.build(signerBuilder.build(privateKey));

        if (!csr.isSignatureValid(prov)) {
            throw new CryptoException(RB.getString("NoVerifyGenCsr.exception.message"));
        }

        return csr;
    } catch (OperatorCreationException | PKCSException ex) {
        throw new CryptoException(RB.getString("NoGenerateCsr.exception.message"), ex);
    }
}

From source file:net.solarnetwork.node.setup.test.DefaultSetupServiceTest.java

License:Open Source License

@Test
public void handleRenewCertificateInstruction() throws Exception {
    SetupIdentityInfo info = new SetupIdentityInfo(1L, TEST_CONF_VALUE, "localhost", 80, false, TEST_PW_VALUE);
    expect(setupIdentityDao.getSetupIdentityInfo()).andReturn(info).atLeastOnce();
    replayAll();//from w  ww  .j a  va  2s .  c  om
    keystoreService.saveCACertificate(CA_CERT);
    keystoreService.generateNodeSelfSignedCertificate(TEST_DN);
    String csr = keystoreService.generateNodePKCS10CertificateRequestString();

    X509Certificate originalCert;

    PemReader pemReader = new PemReader(new StringReader(csr));
    try {
        PemObject pem = pemReader.readPemObject();
        PKCS10CertificationRequest req = new PKCS10CertificationRequest(pem.getContent());
        originalCert = PKITestUtils.sign(req, CA_CERT, CA_KEY_PAIR.getPrivate());
        String signedPem = PKITestUtils.getPKCS7Encoding(new X509Certificate[] { originalCert });
        keystoreService.saveNodeSignedCertificate(signedPem);

        log.debug("Saved signed node certificate {}:\n{}", originalCert.getSerialNumber(), signedPem);

        assertThat("Generated CSR", csr, notNullValue());
    } finally {
        pemReader.close();
    }

    // now let's renew!
    KeyStore keyStore = loadKeyStore();
    PrivateKey nodeKey = (PrivateKey) keyStore.getKey("node", TEST_PW_VALUE.toCharArray());
    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder("SHA256WithRSA");
    ContentSigner signer = signerBuilder.build(nodeKey);
    PKCS10CertificationRequestBuilder builder = new PKCS10CertificationRequestBuilder(
            JcaX500NameUtil.getSubject(originalCert),
            SubjectPublicKeyInfo.getInstance(originalCert.getPublicKey().getEncoded()));
    X509Certificate renewedCert = PKITestUtils.sign(builder.build(signer), CA_CERT, CA_KEY_PAIR.getPrivate());
    String renewedSignedPem = PKITestUtils.getPKCS7Encoding(new X509Certificate[] { renewedCert });

    BasicInstruction instr = new BasicInstruction(DefaultSetupService.INSTRUCTION_TOPIC_RENEW_CERTIFICATE,
            new Date(), "123", "456", new BasicInstructionStatus(456L, InstructionState.Received, new Date()));
    for (int i = 0; i < renewedSignedPem.length(); i += 256) {
        int end = i + (i + 256 < renewedSignedPem.length() ? 256 : renewedSignedPem.length() - i);
        instr.addParameter(DefaultSetupService.INSTRUCTION_PARAM_CERTIFICATE,
                renewedSignedPem.substring(i, end));
    }

    InstructionState state = service.processInstruction(instr);
    assertThat("Instruction state", state, equalTo(InstructionState.Completed));

    X509Certificate nodeCert = keystoreService.getNodeCertificate();
    assertThat("Node cert is now renewed cert", nodeCert, equalTo(renewedCert));
}

From source file:net.solarnetwork.node.setup.test.PKITestUtils.java

License:Open Source License

public static X509Certificate generateNewCACert(PublicKey publicKey, String subject, X509Certificate issuer,
        PrivateKey issuerKey, String caDN) throws Exception {
    final X500Name issuerDn = (issuer == null ? new X500Name(subject) : JcaX500NameUtil.getSubject(issuer));
    final X500Name subjectDn = new X500Name(subject);
    final BigInteger serial = getNextSerialNumber();
    final Date notBefore = new Date();
    final Date notAfter = new Date(System.currentTimeMillis() + 1000L * 60L * 60L);
    JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(issuerDn, serial, notBefore, notAfter,
            subjectDn, publicKey);//from   w w  w .j av  a 2  s . com

    // add "CA" extension
    BasicConstraints basicConstraints;
    if (issuer == null) {
        basicConstraints = new BasicConstraints(true);
    } else {
        int issuerPathLength = issuer.getBasicConstraints();
        basicConstraints = new BasicConstraints(issuerPathLength - 1);
    }
    builder.addExtension(X509Extension.basicConstraints, true, basicConstraints);

    // add subjectKeyIdentifier
    JcaX509ExtensionUtils utils = new JcaX509ExtensionUtils();
    SubjectKeyIdentifier ski = utils.createSubjectKeyIdentifier(publicKey);
    builder.addExtension(X509Extension.subjectKeyIdentifier, false, ski);

    // add authorityKeyIdentifier
    GeneralNames issuerName = new GeneralNames(new GeneralName(GeneralName.directoryName, caDN));
    AuthorityKeyIdentifier aki = utils.createAuthorityKeyIdentifier(publicKey);
    aki = new AuthorityKeyIdentifier(aki.getKeyIdentifier(), issuerName, serial);
    builder.addExtension(X509Extension.authorityKeyIdentifier, false, aki);

    // add keyUsage
    X509KeyUsage keyUsage = new X509KeyUsage(X509KeyUsage.cRLSign | X509KeyUsage.digitalSignature
            | X509KeyUsage.keyCertSign | X509KeyUsage.nonRepudiation);
    builder.addExtension(X509Extension.keyUsage, true, keyUsage);

    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder("SHA256WithRSA");
    ContentSigner signer = signerBuilder.build(issuerKey);

    X509CertificateHolder holder = builder.build(signer);
    JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
    return converter.getCertificate(holder);
}

From source file:net.solarnetwork.node.setup.test.PKITestUtils.java

License:Open Source License

public static X509Certificate sign(PKCS10CertificationRequest csr, X509Certificate issuer,
        PrivateKey issuerPrivateKey)
        throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, SignatureException,
        IOException, OperatorCreationException, CertificateException, java.security.cert.CertificateException {

    final BigInteger serial = getNextSerialNumber();
    final Date notBefore = new Date();
    final Date notAfter = new Date(System.currentTimeMillis() + 24L * 60L * 60L * 1000L);

    X500Name issuerName = JcaX500NameUtil.getSubject(issuer);
    X509v3CertificateBuilder myCertificateGenerator = new X509v3CertificateBuilder(issuerName, serial,
            notBefore, notAfter, csr.getSubject(), csr.getSubjectPublicKeyInfo());

    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder("SHA256WithRSA");
    ContentSigner signer = signerBuilder.build(issuerPrivateKey);
    X509CertificateHolder holder = myCertificateGenerator.build(signer);

    JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
    return converter.getCertificate(holder);
}

From source file:net.solarnetwork.pki.bc.BCCertificateService.java

License:Open Source License

@Override
public X509Certificate generateCertificate(String dn, PublicKey publicKey, PrivateKey privateKey) {
    X500Principal issuer = new X500Principal(dn);
    Date now = new Date();
    Date expire = new Date(now.getTime() + (1000L * 60L * 60L * 24L * certificateExpireDays));
    JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(issuer,
            new BigInteger(String.valueOf(counter.incrementAndGet())), now, expire, issuer, publicKey);
    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm);
    ContentSigner signer;//from   w  ww  . j av  a2  s .  c  om
    try {
        signer = signerBuilder.build(privateKey);
    } catch (OperatorCreationException e) {
        throw new CertificateException("Error signing certificate", e);
    }
    X509CertificateHolder holder = builder.build(signer);
    JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
    try {
        return converter.getCertificate(holder);
    } catch (java.security.cert.CertificateException e) {
        throw new CertificateException("Error creating certificate", e);
    }
}

From source file:net.solarnetwork.pki.bc.BCCertificateService.java

License:Open Source License

@Override
public X509Certificate generateCertificationAuthorityCertificate(String dn, PublicKey publicKey,
        PrivateKey privateKey) {//from  w  w w . j  a v a 2 s.  co m
    X500Principal issuer = new X500Principal(dn);
    Date now = new Date();
    Date expire = new Date(now.getTime() + (1000L * 60L * 60L * 24L * authorityExpireDays));
    JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(issuer, new BigInteger("0"), now,
            expire, issuer, publicKey);
    JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm);
    DefaultDigestAlgorithmIdentifierFinder digestAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
    ContentSigner signer;
    try {
        DigestCalculatorProvider digestCalcProvider = new JcaDigestCalculatorProviderBuilder()
                .setProvider(new BouncyCastleProvider()).build();
        JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(
                digestCalcProvider.get(digestAlgFinder.find("SHA-256")));
        builder.addExtension(X509Extension.basicConstraints, true, new BasicConstraints(true));
        builder.addExtension(X509Extension.subjectKeyIdentifier, false,
                extUtils.createSubjectKeyIdentifier(publicKey));
        builder.addExtension(X509Extension.keyUsage, true, new KeyUsage(
                KeyUsage.digitalSignature | KeyUsage.nonRepudiation | KeyUsage.keyCertSign | KeyUsage.cRLSign));
        builder.addExtension(X509Extension.authorityKeyIdentifier, false,
                extUtils.createAuthorityKeyIdentifier(publicKey));

        signer = signerBuilder.build(privateKey);
    } catch (OperatorCreationException e) {
        log.error("Error generating CA certificate [{}]", dn, e);
        throw new CertificateException("Error signing CA certificate", e);
    } catch (CertIOException e) {
        log.error("Error generating CA certificate [{}]", dn, e);
        throw new CertificateException("Error signing CA certificate", e);
    }
    X509CertificateHolder holder = builder.build(signer);
    JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
    try {
        return converter.getCertificate(holder);
    } catch (java.security.cert.CertificateException e) {
        throw new CertificateException("Error creating certificate", e);
    }
}