Hi all,

I am struggling with a client certificate problem and hope somebody can
help me. I'm on windows here and develop a client/server pair using boost
asio but I'll try to be unspecific. I am also not an expert in SSL speak so
please forgive if I'm using layman's terms here. I'm on windows and using
openssl 1.0.1e

Basically, I want to have client authentication. The server shall only
accept clients that have a certificate signed by my own CA. So I have setup
a self signed CA. This has issued two more certificates. One for the client
and one for the server. Both signed by the CA.
I have done that quite a few times now and I am confident that I got it.

My server side also works fine. It requests client certificates and if I'm
using s_client and give those certs everything works. Also if I'm using a
browser and have my root CA installed as trusted and then import the client
certs.

The only thing that I can't get to work is the libssl client. It always
fails during the handshake and as far as I can see it will not send the
client certficate:

$ openssl.exe s_server -servername localhost -bugs -CAfile myca.crt -cert
server.crt -cert2 server.crt -key private/server.key -key2
private/server.key -accept 8887 -www -state -Verify 5
verify depth is 5, must return a certificate
Setting secondary ctx parameters
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write certificate request A
SSL_accept:SSLv3 flush data
SSL3 alert read:warning:no certificate
SSL3 alert write:fatal:handshake failure
SSL_accept:error in SSLv3 read client certificate B
SSL_accept:error in SSLv3 read client certificate B
2675716:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did
not return a certificate:s3_srvr.c:3193:
ACCEPT

I'm using this s_server as debugging tool but against my real server the
same thing occurs.
s_client will work fine with the same certificates. Also, if I disable
"-Verify" in the server the connection works. So it really seems just the
client refusing to send it's certficate. What can be the reason for that?

Since I'm using boost asio as an SSL wrapper the code looks like this:

        m_ssl_context.set_verify_mode( asio::ssl::context::verify_peer );
        m_ssl_context.load_verify_file( "myca.crt" );
        m_ssl_context.use_certificate_file( "testclient.crt",
asio::ssl::context::pem );
        m_ssl_context.use_private_key_file( "testclient.key",
asio::ssl::context::pem );

I have also tried to bypass asio and access the SSL context directly by
saying:

        SSL_CTX *ctx = m_ssl_context.impl();
        SSL *ssl = m_ssl_socket.impl()->ssl;
        int res = 0;
        res = SSL_CTX_use_certificate_chain_file(ctx, "myca.crt");
        if (res <= 0) {
            // handle error
        }
        res = SSL_CTX_use_certificate_file(ctx, "testclient.crt",
SSL_FILETYPE_PEM);
        if (res <= 0) {
            // handle error
        }
        res = SSL_CTX_use_PrivateKey_file(ctx, "testclient.key",
SSL_FILETYPE_PEM);
        if (res <= 0) {
            // handle error
        }

I can't see any difference in behavior. It should be mentioned that I am
using a very old boost 1.43 asio which I cannot update but I suppose all
relevant calls go more or less directly to OpenSSL anyway and the server
works fine with that version so I think I can rule that out.

I have been debugging this for almost a week now and I'm really stuck. Does
anyone have a suggestion on what to try? I'm out of ideas...

Cheers,
Stephan




PS: Here is what the above s_server debug out would be with s_client and
the same certficate:

$ openssl s_client -CAfile ca.crt -cert testclient.crt -key
private/testclient.key -verify 2 -connect myhost:8887

ACCEPT
SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write certificate request A
SSL_accept:SSLv3 flush data
depth=1 C = DE, // further info
verify return:1
depth=0 C = DE, // further info
verify return:1
SSL_accept:SSLv3 read client certificate A
SSL_accept:SSLv3 read client key exchange A
SSL_accept:SSLv3 read certificate verify A
SSL_accept:SSLv3 read finished A
SSL_accept:SSLv3 write session ticket A
SSL_accept:SSLv3 write change cipher spec A
SSL_accept:SSLv3 write finished A
SSL_accept:SSLv3 flush data
ACCEPT

... handshake completes and data is transferred.

Reply via email to