package com.xjeffrose.xio.SSL;

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
import java.security.cert.*;
import javax.net.ssl.SSLException;

public class SslContextFactory {

  static private SslContextBuilder configure(TlsConfig config, SslContextBuilder builder) {
    return builder
      .applicationProtocolConfig(config.getAlpnConfig())
      .ciphers(config.getCiphers(), SupportedCipherSuiteFilter.INSTANCE)
      .clientAuth(config.getClientAuth())
      .enableOcsp(config.isEnableOcsp())
      .protocols(config.getProtocols())
      .sessionCacheSize(config.getSessionCacheSize())
      .sessionTimeout(config.getSessionTimeout())
      .sslProvider(config.getSslProvider())
      ;
  }

  static public SslContext buildServerContext(TlsConfig config) {
    try {
      SslContextBuilder builder = SslContextBuilder
        .forServer(config.getPrivateKey(), config.getCertificateAndTrustChain());
      return configure(config, builder)
        // servers will trust only certs in trust chain
        .trustManager(config.getTrustChain())
        .build();
    } catch (SSLException e) {
      return null;
    }
  }

  static public SslContext buildClientContext(TlsConfig config) {
    try {
      return configure(config, SslContextBuilder.forClient())
        .keyManager(config.getPrivateKey(), config.getCertificateAndTrustChain())
        // clients will trust only certs in trust chain
        .trustManager(config.getTrustChain())
        .build();
    } catch (SSLException e) {
      return null;
    }
  }
}

@@ -184,58 +184,337 @@
 ava.
-security.cert.*;%0Aimport javax.net.ssl.SSLException
+io.IOException;%0Aimport java.security.KeyStore;%0Aimport java.security.KeyStoreException;%0Aimport java.security.NoSuchAlgorithmException;%0Aimport java.security.cert.*;%0Aimport java.security.cert.CertificateException;%0Aimport java.security.cert.X509Certificate;%0Aimport javax.net.ssl.SSLException;%0Aimport javax.net.ssl.TrustManagerFactory
 ;%0A%0Ap
@@ -1556,32 +1556,66 @@
 TlsConfig config
+, TrustManagerFactory trustManager
 ) %7B%0A    try %7B%0A  
@@ -1834,38 +1834,28 @@
 Manager(
-config.getTrustChain()
+trustManager
 )%0A      
@@ -1925,11 +1925,853 @@
    %7D%0A  %7D
+%0A%0A  static TrustManagerFactory buildTrustManagerFactory(X509Certificate%5B%5D certCollection) %7B%0A    try %7B%0A      KeyStore ks = KeyStore.getInstance(%22JKS%22);%0A      ks.load(null, null);%0A%0A      int i = 1;%0A      for (X509Certificate cert: certCollection) %7B%0A        String alias = Integer.toString(i);%0A        ks.setCertificateEntry(alias, cert);%0A        i++;%0A      %7D%0A%0A      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());%0A%0A      trustManagerFactory.init(ks);%0A%0A      return trustManagerFactory;%0A    %7D catch (NoSuchAlgorithmException %7C CertificateException %7C KeyStoreException %7C IOException e) %7B%0A      return null;%0A    %7D%0A  %7D%0A%0A  static public SslContext buildClientContext(TlsConfig config) %7B%0A    return buildClientContext(config, buildTrustManagerFactory(config.getTrustChain()));%0A  %7D
 %0A%7D%0A

Copy netty cert TrustManager, allow users to specify TrustManager