3

I have developed a Java 7 HTTPS server (I use com.sun.net.httpserver.HttpsServer) for a SOAP web service (mostly influenced by this SO answer) with the difference that the server is set to need client authentication. This is the server's configuration code I use:

final InetSocketAddress address = new InetSocketAddress( localhost, 8888 );
this.httpsServer = HttpsServer.create( address, 0 );

// ... KeyStore configuration ...

// configure the HTTPS server
this.httpsServer.setHttpsConfigurator( new HttpsConfigurator( sslContext )
{
   @Override
   public void configure(final HttpsParameters params)
   {
      try
      {
         // initialize the SSL context
         final SSLContext c = SSLContext.getDefault();
         final SSLEngine engine = c.createSSLEngine();
         params.setNeedClientAuth( true );
         params.setCipherSuites( engine.getEnabledCipherSuites() );
         params.setProtocols( engine.getEnabledProtocols() );

         // get the default parameters
         final SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
         params.setSSLParameters( defaultSSLParameters );
      }
      catch ( final Exception e )
      {
         LOG.error( ExceptionUtils.getStackTrace( e ) );
      }
   }
} );

However, upon connections from clients I notice that client authentication is not enforced! I'm currently testing on localhost with self-signed certificates but it seems that any client is able to connect. I tested with SoapUI (which I have not configured to send any certificates to my knowlegde) as well as openssl in client mode with and without a certificate.

openssl s_client -cert client.pem -connect localhost:8888 -debug
openssl s_client -connect localhost:8888 -debug

I have already started the server with the java option -Djavax.net.debug=all but didn't see any relevant parts which indicate a client authentication or a request that the client shall present its certificate. I see that clients validate the server's certificate indeed!

I want to reject any clients which do not present a valid certificate. How can I do this?

Markus L
  • 932
  • 2
  • 20
  • 38
  • I don't see you initializing the SSLContext with your keystore sslContext.init(myKeyManagerFactory.getKeyManagers(), myTrustManagerFactory.getTrustManagers(), null); See the code example here: http://stackoverflow.com/questions/36819113/how-to-require-client-certificate-with-com-sun-net-httpserver-httpsserver – Mike Jul 12 '16 at 14:01
  • Yes, this code is omitted because it's not relevant for this problem. – Markus L Jul 12 '16 at 18:48

1 Answers1

5

After very long searching I noticed that the configure(..) method of the HttpsConfigurator is wrong. I didn't set the SSLParameters correctly!

It should look like this:

@Override
public void configure(final HttpsParameters params)
{
   try
   {
      final SSLParameters sslParams = getSSLContext().getDefaultSSLParameters();
      final SSLEngine sslEngine = getSSLContext().createSSLEngine();
      sslParams.setNeedClientAuth( true );
      sslParams.setCipherSuites( sslEngine.getEnabledCipherSuites() );
      sslParams.setProtocols( sslEngine.getEnabledProtocols() );
      params.setSSLParameters( sslParams );
   }
   catch ( final Exception e )
   {
      LOG.error( ExceptionUtils.getStackTrace( e ) );
   }
}
Markus L
  • 932
  • 2
  • 20
  • 38