Client authentication bugs and fixes.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I have been trying to make SSL/TLS connection using client authentication.
I have found several issues in the class SSLSocket.

As the code for this class is pretty much the same between Jessie v1.0.1 and Classpath v0.92,
I am cross posting to Jessie and Classpath.

1. Digest cloning
In the following piece of code, the clone of digest was badly placed after receiving the CertificateVerify instead of being done BEFORE. This is a problem as this digest is computed on the fly from data read from the stream Since the digest is computed on the client side before creating the verify message, this was causing a mismatch.

2. In the same code, the read was call without specifying the cipher suite. As this info is used to determine how to read the signature, a NPE was thrown with the original code. Providing the cipher suite fixes the bug.
==========
(Around line 2890)
        if (clientCanSign && (wantClientAuth || needClientAuth))
          {
        	
// FIX the digest need to be cloned before the verify message is read since their have been computed by the client
        	// BEFORE sending the CertificateVerify Message
          IMessageDigest cvMD5 = (IMessageDigest) md5.clone();
          IMessageDigest cvSHA = (IMessageDigest) sha.clone();

//FIX CH If suite is null, the signature cannot be read since the key type/cipher signature type is used.
	//        msg = Handshake.read(din);
        	msg = Handshake.read(din, suite, null);
            if (msg.getType() != Handshake.Type.CERTIFICATE_VERIFY)
              {
                throwUnexpectedMessage();
              }
CertificateVerify verify = (CertificateVerify) msg.getBody();
            if (clientChain != null && clientChain.length > 0)
              {
//              IMessageDigest cvMD5 = (IMessageDigest) md5.clone();
//              IMessageDigest cvSHA = (IMessageDigest) sha.clone();
==========
3. When reading the client certificate, the call to Handshake.read() missed the certificate type. The fix as shown in the code below is to add the CertificateType.X509 argument.
========
(around line 2690)
        if (suite.getKeyExchange() == "RSA")
          {
msg = Handshake.read(din, suite, kexPair.getPublic(), CertificateType.X509);
          }
        else
          {
msg = Handshake.read(din, suite, null, CertificateType.X509);
          }
        boolean clientCertOk = false;
        boolean clientCanSign = false;
        X509Certificate[] clientChain = null;
        PublicKey clientKey = null;

        // Read the client's certificate, if sent.
        if (msg.getType() == Handshake.Type.CERTIFICATE)
========
4. This is one more general: It's not clear what certificate the code expect to find in the trust store (self-issued ok?, external root certificate ?, certificate stored in the key store with or without its private key?), on the client side, and on the server side. This is maybe a system-level issue but for some configuration, the code just crash with a NPE. After analysis of the error, the 'correct' usage can be understood, but some explanation would be needed, especially when client authentication is on.

Anyway, after few hours of debugging, I am happy to have TLS working with server AND client authentication.
Thanks for the nice piece of code.

Cheers,
Cedric



[Index of Archives]     [Linux Kernel]     [Linux Cryptography]     [Fedora]     [Fedora Directory]     [Red Hat Development]

  Powered by Linux