Note that there are some explanatory texts on larger screens.

plurals
  1. POHandling multiple certificates in Netty's SSL Handler used in Play Framework 1.2.7
    primarykey
    data
    text
    <p>I have a Java Key Store where I store certificates for each of my customer's sub-domain. I am planning to use the server alias to differentiate between multiple customers in the key store as suggested <a href="https://stackoverflow.com/questions/6370745/can-we-load-multiple-certificates-keys-in-a-key-store">here</a>. Play framework 1.2.7 uses Netty's SslHandler to support SSL on the server-side. I tried implementing a custom SslHttpServerContextFactory that uses this <a href="https://stackoverflow.com/a/9217941/794988">solution</a>.</p> <pre><code>import play.Play; import javax.net.ssl.*; import java.io.FileInputStream; import java.net.InetAddress; import java.net.Socket; import java.security.KeyStore; import java.security.Principal; import java.security.PrivateKey; import java.security.Security; import java.security.cert.X509Certificate; import java.util.Properties; public class CustomSslHttpServerContextFactory { private static final String PROTOCOL = "SSL"; private static final SSLContext SERVER_CONTEXT; static { String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); if (algorithm == null) { algorithm = "SunX509"; } SSLContext serverContext = null; KeyStore ks = null; try { final Properties p = Play.configuration; // Try to load it from the keystore ks = KeyStore.getInstance(p.getProperty("keystore.algorithm", "JKS")); // Load the file from the conf char[] certificatePassword = p.getProperty("keystore.password", "secret").toCharArray(); ks.load(new FileInputStream(Play.getFile(p.getProperty("keystore.file", "conf/certificate.jks"))), certificatePassword); // Set up key manager factory to use our key store KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); kmf.init(ks, certificatePassword); TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); tmf.init(ks); final X509KeyManager origKm = (X509KeyManager) kmf.getKeyManagers()[0]; X509KeyManager km = new X509KeyManagerWrapper(origKm); // Initialize the SSLContext to work with our key managers. serverContext = SSLContext.getInstance(PROTOCOL); serverContext.init(new KeyManager[]{km}, tmf.getTrustManagers(), null); } catch (Exception e) { throw new Error("Failed to initialize the server-side SSLContext", e); } SERVER_CONTEXT = serverContext; } public static SSLContext getServerContext() { return SERVER_CONTEXT; } public static class X509KeyManagerWrapper implements X509KeyManager { final X509KeyManager origKm; public X509KeyManagerWrapper(X509KeyManager origKm) { this.origKm = origKm; } public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) { InetAddress remoteAddress = socket.getInetAddress(); //TODO: Implement alias selection based on remoteAddress return origKm.chooseServerAlias(keyType, issuers, socket); } @Override public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { return origKm.chooseClientAlias(keyType, issuers, socket); } @Override public String[] getClientAliases(String s, Principal[] principals) { return origKm.getClientAliases(s, principals); } @Override public String[] getServerAliases(String s, Principal[] principals) { return origKm.getServerAliases(s, principals); } @Override public X509Certificate[] getCertificateChain(String s) { return origKm.getCertificateChain(s); } @Override public PrivateKey getPrivateKey(String s) { return origKm.getPrivateKey(s); } } } </code></pre> <p>But, this approach did not work for some reason. I get this message in my SSL debug log.</p> <pre><code>X509KeyManager passed to SSLContext.init(): need an X509ExtendedKeyManager for SSLEngine use </code></pre> <p>This is the SSL <a href="https://gist.github.com/aruld/8152111" rel="nofollow noreferrer">trace</a>, which fails with "no cipher suites in common". Now, I switched the wrapper to:</p> <pre><code>public static class X509KeyManagerWrapper extends X509ExtendedKeyManager </code></pre> <p>With this change, I got rid of the warning, but I still see the same error as before "no cipher suites in common" and here is the SSL <a href="https://gist.github.com/aruld/8152172" rel="nofollow noreferrer">trace</a>. I am not sure why the delegation of key manager won't work.</p> <p>Some more information that may be useful in this context.</p> <ul> <li><a href="http://netty.io/3.8/guide/#architecture.8.4" rel="nofollow noreferrer">Netty</a> uses javax.net.ssl.SSLEngine to support SSL in NIO server.</li> <li>As per the recommendation in this bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6448723" rel="nofollow noreferrer">report</a>, it is intentional that X509ExtendedKeyManager must be used with an SSLEngine. So, the wrapper must extend X509ExtendedKeyManager.</li> </ul> <p>This is hindering me to move further with the custom alias selection logic in X509KeyManagerWrapper. Any clues on what might be happening here? Is there any other way to implement this in Netty/Play? Appreciate any suggestions. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload