javasecuritydebuggingtestingcertificate

Java 11: Getting an "Empty [client] certificate chain" instead of an "Empty [server] certificate chain"


I am trying to debug some Java 11 test code which uses an SSLServerSocket for the server and an SSLSocket for the reply. The basic code works as follows:

server.setNeedClientAuth(false);
need_Client_Auth = server.getNeedClientAuth();
assertFalse("Unexpected need client authority returned", need_Client_Auth);

server.setNeedClientAuth(true);
need_Client_Auth = server.getNeedClientAuth();
assertTrue("Unexpected need client authority returned", need_Client_Auth);

SSLClient sClient = new SSLClient(client, addr, SSLClient.START_HANDSHAKE);
sClient.start();

SSLSocket reply = (SSLSocket) (server.accept());

reply.startHandshake();       //this throws an SSLException

The idea here is to just play around with the needClientAuth/wantClientAuth and test the output of startHandshake without getting proper client authentication.

The test expects the SSLException to throw a message of "Empty [server] certificate chain" but instead it is "Empty [client] certificate chain". This test is coming from a fully working Java 8 build, and as far as I can tell the certificates being created are correct and identical to their Java 8 counterparts.

I'm just unsure on where to even start debugging and what could be causing this very small change in expected output. Any help is appreciated!


Solution

  • After quite a few days of researching and delving deep into OpenJDK 11, I realized that my test case that was expecting the "Empty server certificate chain" was incorrect.

    In Java 11, the TLS or SSL protocol supports TLSv1.2 and TLSv1.3. The test case was deciding what the expected message was based essentially on this pseudocode:

    if(protocolUsed == "TLSv1.3") 
        expectedMessage = "Empty client certificate chain";
    else
        expectedMessage = "Empty server certificate chain";
    

    However in Java 8 (which is where this test originated from), SSL and TLS only support up to TLSv1.2. This means that the actual handshake was being done in TLSv1.3, but the protocol being used in that if block was still showing up as SSL or TLS. So TLSv1.3 work was being done, but the if block was never properly updated to account for it. I verified all of this through debug output.