package net.lulli.certsigner.ca; import net.lulli.certsigner.Settings; import net.lulli.certsigner.util.ValidityUtil; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import java.math.BigInteger; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.X509Certificate; public class CertificateIssue { private CertificateIssue(){} public static X509Certificate rootCertificate( PublicKey publicKey, PrivateKey privateKey, String subject) throws Exception { BigInteger rootSerialNum = new BigInteger(Long.toString(new SecureRandom().nextLong())); X500Name rootCertIssuer = new X500Name(subject); X500Name rootCertSubject = rootCertIssuer; ContentSigner rootCertContentSigner = new JcaContentSignerBuilder(Settings.SIGNATURE_ALGORITHM).setProvider(Settings.BC_PROVIDER).build(privateKey); X509v3CertificateBuilder rootCertBuilder = new JcaX509v3CertificateBuilder(rootCertIssuer, rootSerialNum, ValidityUtil.yesterday(), ValidityUtil.plusYears(1), rootCertSubject, publicKey); JcaX509ExtensionUtils rootCertExtUtils = new JcaX509ExtensionUtils(); rootCertBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(true)); rootCertBuilder.addExtension(Extension.subjectKeyIdentifier, false, rootCertExtUtils.createSubjectKeyIdentifier(publicKey)); X509CertificateHolder rootCertHolder = rootCertBuilder.build(rootCertContentSigner); return new JcaX509CertificateConverter().setProvider(Settings.BC_PROVIDER).getCertificate(rootCertHolder); } public static X509Certificate clientCertificate( PrivateKey privateKey, String certificateSubject, X509Certificate rootCert, PKCS10CertificationRequest csr ) { try { X500Name issuedCertSubject = new X500Name(certificateSubject); BigInteger issuedCertSerialNum = new BigInteger(Long.toString(new SecureRandom().nextLong())); //PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(issuedCertSubject, issuedCertKeyPair.getPublic()); JcaContentSignerBuilder csrBuilder = new JcaContentSignerBuilder(Settings.SIGNATURE_ALGORITHM).setProvider(Settings.BC_PROVIDER); ContentSigner csrContentSigner = csrBuilder.build(privateKey); X509v3CertificateBuilder issuedCertBuilder = new X509v3CertificateBuilder(new X500Name("CN=root-cert"), issuedCertSerialNum, ValidityUtil.yesterday(), ValidityUtil.plusYears(1), csr.getSubject(), csr.getSubjectPublicKeyInfo()); JcaX509ExtensionUtils issuedCertExtUtils = new JcaX509ExtensionUtils(); issuedCertBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(false)); issuedCertBuilder.addExtension(Extension.authorityKeyIdentifier, false, issuedCertExtUtils.createAuthorityKeyIdentifier(rootCert)); issuedCertBuilder.addExtension(Extension.subjectKeyIdentifier, false, issuedCertExtUtils.createSubjectKeyIdentifier(csr.getSubjectPublicKeyInfo())); issuedCertBuilder.addExtension(Extension.keyUsage, false, new KeyUsage(KeyUsage.keyEncipherment)); // Add DNS name is cert is to used for SSL /* issuedCertBuilder.addExtension(Extension.subjectAlternativeName, false, new DERSequence(new ASN1Encodable[]{ new GeneralName(GeneralName.dNSName, "mydomain.local"), new GeneralName(GeneralName.iPAddress, "127.0.0.1") })); */ X509CertificateHolder issuedCertHolder = issuedCertBuilder.build(csrContentSigner); return new JcaX509CertificateConverter().setProvider(Settings.BC_PROVIDER).getCertificate(issuedCertHolder); } catch (Exception e) { throw new IllegalStateException(e.getMessage()); } } }