Thats very cool! 

Maybe this is the right thread to discuss the future of the sun.security.x509 
package.

Currently your implementation will only work if that package is exported. The 
Depth of implementation of those classes however would be a nice Addition to an 
(optional?) API.

Gruss
Bernd
-- 
http://bernd.eckenfels.net

Von: Will Sargent
Gesendet: Montag, 15. Oktober 2018 22:13
An: security-dev@openjdk.java.net
Betreff: Fluent builder API for JCA/JSSE classes

Hi all,

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 https://github.com/tersesystems/securitybuilder

Example below of building up an SSLContext from scratch:

public class X509CertificateCreatorTest {
  @Test
  public void testFunctionalStyle() throws Exception {
    FinalStage<RSAKeyPair> keyPairCreator = 
KeyPairCreator.creator().withRSA().withKeySize(2048);
    RSAKeyPair rootKeyPair = keyPairCreator.create();
    RSAKeyPair intermediateKeyPair = keyPairCreator.create();
    RSAKeyPair eePair = keyPairCreator.create();

    IssuerStage<RSAPrivateKey> creator =
        
X509CertificateCreator.creator().withSHA256withRSA().withDuration(Duration.ofDays(365));

    String issuer = "CN=letsencrypt.derp,O=Root CA";
    X509Certificate[] chain =
        creator
            .withRootCA(issuer, rootKeyPair, 2)
            .chain(
                rootKeyPair.getPrivate(),
                rootCreator ->
                    rootCreator
                        .withPublicKey(intermediateKeyPair.getPublic())
                        .withSubject("OU=intermediate CA")
                        .withCertificateAuthorityExtensions(0)
                        .chain(
                            intermediateKeyPair.getPrivate(),
                            intCreator ->
                                intCreator
                                    .withPublicKey(eePair.getPublic())
                                    .withSubject("CN=tersesystems.com")
                                    .withEndEntityExtensions()
                                    .chain()))
            .create();

    PrivateKeyStore privateKeyStore =
        PrivateKeyStore.create("tersesystems.com", eePair.getPrivate(), chain);
    TrustStore trustStore = TrustStore.create(singletonList(chain[2]), cert -> 
"letsencrypt.derp");

    try {
      final PKIXCertPathValidatorResult result = 
CertificateChainValidator.validator()
          .withAnchor(new TrustAnchor(issuer, rootKeyPair.getPublic(), null))
          .withCertificates(chain)
          .validate();
      final PublicKey subjectPublicKey = result.getPublicKey();
      assertThat(subjectPublicKey).isEqualTo(eePair.getPublic());
    } catch (final CertPathValidatorException cpve) {
      fail("Cannot test exception", cpve);
    }

    SSLContext sslContext =
        SSLContextBuilder.builder()
            .withTLS()
            .withKeyManager(
                KeyManagerBuilder.builder()
                    .withSunX509()
                    .withPrivateKeyStore(privateKeyStore)
                    .build())
            .withTrustManager(
                TrustManagerBuilder.builder()
                    .withDefaultAlgorithm()
                    .withTrustStore(trustStore)
                    .build())
            .build();
    assertThat(sslContext).isNotNull();
  }
}

Thanks,
Will.

Reply via email to