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.