<div dir="ltr"><div dir="ltr"><div dir="ltr">Hi all,<div><br></div><div>I've released a library that adds a fluent builder API library for JCA factory and generator classes. The primary use of this package is to set up test X.509 certificates, private keys and trust stores, but it's also helpful for picking out good defaults and working on a higher level than the raw JCA classes themselves. It's available at <a href="https://github.com/tersesystems/securitybuilder">https://github.com/tersesystems/securitybuilder</a></div><div><br></div><div>Example below of building up an SSLContext from scratch:</div><div><br></div><div><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-radius:3px;word-break:normal;color:rgb(36,41,46)"><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">public</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">class</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">X509CertificateCreatorTest</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">@Test</span>
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">public</span> <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">void</span> <span class="gmail-pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">testFunctionalStyle</span>() <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">throws</span> <span class="gmail-pl-smi" style="box-sizing:border-box">Exception</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">FinalStage<<span class="gmail-pl-smi" style="box-sizing:border-box;color:rgb(36,41,46)">RSAKeyPair</span>></span> keyPairCreator <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> <span class="gmail-pl-smi" style="box-sizing:border-box">KeyPairCreator</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>creator()<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>withRSA()<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>withKeySize(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">2048</span>);
<span class="gmail-pl-smi" style="box-sizing:border-box">RSAKeyPair</span> rootKeyPair <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> keyPairCreator<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>create();
<span class="gmail-pl-smi" style="box-sizing:border-box">RSAKeyPair</span> intermediateKeyPair <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> keyPairCreator<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>create();
<span class="gmail-pl-smi" style="box-sizing:border-box">RSAKeyPair</span> eePair <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> keyPairCreator<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>create();
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">IssuerStage<<span class="gmail-pl-smi" style="box-sizing:border-box;color:rgb(36,41,46)">RSAPrivateKey</span>></span> creator <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span>
<span class="gmail-pl-smi" style="box-sizing:border-box">X509CertificateCreator</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>creator()<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>withSHA256withRSA()<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>withDuration(<span class="gmail-pl-smi" style="box-sizing:border-box">Duration</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>ofDays(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">365</span>));
<span class="gmail-pl-smi" style="box-sizing:border-box">String</span> issuer <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> <span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>CN=letsencrypt.derp,O=Root CA<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>;
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">X509Certificate</span>[] chain <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span>
creator
.withRootCA(issuer, rootKeyPair, <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">2</span>)
.chain(
rootKeyPair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPrivate(),
rootCreator <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">></span>
rootCreator
.withPublicKey(intermediateKeyPair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPublic())
.withSubject(<span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>OU=intermediate CA<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>)
.withCertificateAuthorityExtensions(<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">0</span>)
.chain(
intermediateKeyPair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPrivate(),
intCreator <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">></span>
intCreator
.withPublicKey(eePair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPublic())
.withSubject(<span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>CN=<a href="http://tersesystems.com">tersesystems.com</a><span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>)
.withEndEntityExtensions()
.chain()))
.create();
<span class="gmail-pl-smi" style="box-sizing:border-box">PrivateKeyStore</span> privateKeyStore <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span>
<span class="gmail-pl-smi" style="box-sizing:border-box">PrivateKeyStore</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>create(<span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span><a href="http://tersesystems.com">tersesystems.com</a><span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>, eePair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPrivate(), chain);
<span class="gmail-pl-smi" style="box-sizing:border-box">TrustStore</span> trustStore <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> <span class="gmail-pl-smi" style="box-sizing:border-box">TrustStore</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>create(singletonList(chain[<span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">2</span>]), cert <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">-</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">></span> <span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>letsencrypt.derp<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>);
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">try</span> {
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">final</span> <span class="gmail-pl-smi" style="box-sizing:border-box">PKIXCertPathValidatorResult</span> result <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> <span class="gmail-pl-smi" style="box-sizing:border-box">CertificateChainValidator</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>validator()
.withAnchor(<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">new</span> <span class="gmail-pl-smi" style="box-sizing:border-box">TrustAnchor</span>(issuer, rootKeyPair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPublic(), <span class="gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">null</span>))
.withCertificates(chain)
.validate();
<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">final</span> <span class="gmail-pl-smi" style="box-sizing:border-box">PublicKey</span> subjectPublicKey <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span> result<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPublicKey();
assertThat(subjectPublicKey)<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>isEqualTo(eePair<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>getPublic());
} <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">catch</span> (<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">final</span> <span class="gmail-pl-smi" style="box-sizing:border-box">CertPathValidatorException</span> cpve) {
fail(<span class="gmail-pl-s" style="box-sizing:border-box;color:rgb(3,47,98)"><span class="gmail-pl-pds" style="box-sizing:border-box">"</span>Cannot test exception<span class="gmail-pl-pds" style="box-sizing:border-box">"</span></span>, cpve);
}
<span class="gmail-pl-smi" style="box-sizing:border-box">SSLContext</span> sslContext <span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">=</span>
<span class="gmail-pl-smi" style="box-sizing:border-box">SSLContextBuilder</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>builder()
.withTLS()
.withKeyManager(
<span class="gmail-pl-smi" style="box-sizing:border-box">KeyManagerBuilder</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>builder()
.withSunX509()
.withPrivateKeyStore(privateKeyStore)
.build())
.withTrustManager(
<span class="gmail-pl-smi" style="box-sizing:border-box">TrustManagerBuilder</span><span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>builder()
.withDefaultAlgorithm()
.withTrustStore(trustStore)
.build())
.build();
assertThat(sslContext)<span class="gmail-pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">.</span>isNotNull();
}
}</pre><div><br></div>Thanks,<br>Will.</div></div></div></div>