1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.handler.ssl.util;
18
19 import org.bouncycastle.asn1.x500.X500Name;
20 import org.bouncycastle.cert.X509CertificateHolder;
21 import org.bouncycastle.cert.X509v3CertificateBuilder;
22 import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
23 import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
24 import org.bouncycastle.operator.ContentSigner;
25 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
26
27 import java.math.BigInteger;
28 import java.security.KeyPair;
29 import java.security.PrivateKey;
30 import java.security.Provider;
31 import java.security.SecureRandom;
32 import java.security.cert.X509Certificate;
33 import java.util.Date;
34
35 import static io.netty.handler.ssl.util.SelfSignedCertificate.newSelfSignedCertificate;
36
37
38
39
40 final class BouncyCastleSelfSignedCertGenerator {
41
42 private static final Provider PROVIDER;
43
44 static {
45 Class<?> providerClass;
46 try {
47 providerClass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
48 } catch (ClassNotFoundException e) {
49 try {
50 providerClass = Class.forName("org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider");
51 } catch (ClassNotFoundException ignore) {
52 throw new RuntimeException("Neither BouncyCastleProvider nor BouncyCastleFipsProvider found");
53 }
54 }
55 try {
56 PROVIDER = (Provider) providerClass.newInstance();
57 } catch (Exception e) {
58 throw new RuntimeException("Failed to instantiate BouncyCastle provider", e);
59 }
60 }
61
62 static String[] generate(String fqdn, KeyPair keypair, SecureRandom random, Date notBefore, Date notAfter,
63 String algorithm) throws Exception {
64 PrivateKey key = keypair.getPrivate();
65
66
67 X500Name owner = new X500Name("CN=" + fqdn);
68 X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
69 owner, new BigInteger(64, random), notBefore, notAfter, owner, keypair.getPublic());
70
71 ContentSigner signer = new JcaContentSignerBuilder(
72 algorithm.equalsIgnoreCase("EC") ? "SHA256withECDSA" : "SHA256WithRSAEncryption").build(key);
73 X509CertificateHolder certHolder = builder.build(signer);
74 X509Certificate cert = new JcaX509CertificateConverter().setProvider(PROVIDER).getCertificate(certHolder);
75 cert.verify(keypair.getPublic());
76
77 return newSelfSignedCertificate(fqdn, key, cert);
78 }
79
80 private BouncyCastleSelfSignedCertGenerator() { }
81 }