Re: Reasons for OpenSSL client not sending certificate

2013-06-11 Thread Stephan Menzel
Dave, thanks so much for your response.

I really was on the verge of giving up on this.
Let me start by saying that it is solved. You gave the hint that made the
difference. Also, you let me understand more what was going on. You have
pointed out some apparent mistakes that were indeed caused by copy and
pasting and on several occasions editing stuff to omit sensitive
information. What really made the difference was this:

On Tue, Jun 11, 2013 at 9:12 AM, Dave Thompson dthomp...@prinpay.comwrote:

  SSL_CTX *ctx = m_ssl_context.impl();
  SSL *ssl = m_ssl_socket.impl()-ssl;

 Is an SSL pointer actually set here? See below.


Yes. Asio wraps it in a ssl_socket type object. I can access it any time.
Which turned out to be a hint towards the real problem. See below.

 int res = 0;
 res = SSL_CTX_use_certificate_chain_file(ctx, myca.crt);
 if (res = 0) {
  // handle error
 }

 This is (almost certainly) not the analog of load_verify_file.
 You want SSL_CTX_load_verify_locations (ctx, myca.crt, NULL)
 to set a CAfile and no CApath. However, I'm surprised this
 didn't cause the client to reject the server before even
 attempting to authenticate itself (during handshake) --
 unless you have set or defaulted it somewhere else,
 or put in a callback that overrides the verify error.

 _use__chain_file of (only) a CA cert is completely wrong,
 but fortunately immediately overridden by your next call.

  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
  }

 Those two calls, assuming no error, should have caused libssl to send
 the client cert (and the chain=root if available) and use the key --
 as long as they occur before the SSL object is created from the SSL_CTX,
 and no subsequent calls modify these settings in the SSL object.


That's the point. As long as the SSL object is created _after_ the context
was modified. That was not the case. The asio code created the context and
the socket upon it (that wraps the ssl*) in the initializer list, pretty
much making all my modifications afterwards obsolete. As they were all in
the c'tor. My server code did it right but the client was wrong. I have
verified it by replacing the SSL_CTX_something(ctx...) functions with
SSL_something(ssl... ) and now it works just fine. I will restructure it to
reflect this and try to get back to the asio versions so I don't have to
bypass that layer but in any case, it works.

I can now use the SSL connection and client certs and everything. The magic
silver bullet indeed. And I have to say, at least in this version asio
almost encourages this mistake in my opinion. Also, there's no equivalent
SSL_something() functions on the socket like OpenSSL has, only the ones on
the context and they were always ignored. Also, there's nothing in asio's
docs hinting at this essential fact.

Well, I can utter a huge sigh of relief now and than you very much for your
help.

Cheers,

Stephan


Re: ssl_connect fails Windows Non-blocking

2013-06-11 Thread Stephan Menzel
Hi Titonus,

would you care to share the solution? I am interested too.

Cheers,
Stephan


On Tue, Jun 11, 2013 at 12:07 PM, titonus tito...@gmail.com wrote:

 Solved!



 --
 View this message in context:
 http://openssl.6102.n7.nabble.com/ssl-connect-fails-Windows-Non-blocking-tp45348p45480.html
 Sent from the OpenSSL - User mailing list archive at Nabble.com.
 __
 OpenSSL Project http://www.openssl.org
 User Support Mailing Listopenssl-users@openssl.org
 Automated List Manager   majord...@openssl.org



Reasons for OpenSSL client not sending certificate

2013-06-10 Thread Stephan Menzel
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.


Re: Reasons for OpenSSL client not sending certificate

2013-06-10 Thread Stephan Menzel
I have continued debugging this today and can add an observation that might
be of interest.
First I forced the protocol on both client and server to TLS1. Then I
experimented with different combinations of SSL_CTX_use_certificate*

I have also created what I think is a certificate chain by concatenating my
client certificate and the CA certificate that issued it.

When I do this:
SSL_CTX_use_certificate_chain_file(ctx, chain.crt);

instead of
SSL_CTX_use_certificate_file(ctx, clientcert.crt, SSL_FILETYPE_PEM);

I get further in the protocol that eventually ends with the message

SSL_accept:SSLv3 flush data
 TLS 1.0 Handshake [length 063d], Certificate

...lots of base64
1c c0 a4 63 88 3e 7d 2d a1 f6 cb e5 a4 89 43 cf
0b 1d e8 65 69 c9 32 6a 5d 37 38 8b 1a
depth=0 C = DE, // * lots of info 
verify return:1
SSL_accept:SSLv3 read client certificate A
 TLS 1.0 Handshake [length 0046], ClientKeyExchange
10 00 00 42 41 04 bf bd c4 0c 78 e7 c1 2d 20 47
d3 0a 7c 7c 1b ae af bc 6d 6d 4c f5 83 43 d9 2c
91 6e a3 19 f5 53 f4 18 cb 3b df f7 8f 71 33 a1
cc 57 28 e4 cd 16 e1 f5 6d 06 b0 8b 1a ff 0c 82
56 86 63 86 25 2c
SSL_accept:SSLv3 read client key exchange A
 TLS 1.0 ChangeCipherSpec [length 0001]
01
 TLS 1.0 Handshake [length 0010], Finished
14 00 00 0c 24 9b 6d fa f2 4c 08 0f fb 2d 57 8b
 TLS 1.0 Alert [length 0002], fatal unexpected_message
02 0a
SSL3 alert write:fatal:unexpected_message
SSL_accept:failed in SSLv3 read certificate verify B
2675716:error:140880AE:SSL routines:SSL3_GET_CERT_VERIFY:missing verify
message:s3_srvr.c:2951:
2675716:error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake
failure:s3_pkt.c:989:

Interestingly, if I do the same thing with the s_client tool, the output
differs a little:

6a 6f 78 78 54 27 b6 c0 f6 cc 43 72 32 fb 94 b4
7c 08 b2 67 bf 06 f9 5a 99 f0 bf 79 7f 69 2e f6
f4 a9 31 b4 e2 ce 0e 09 fe 25 1d 13 49 17 2c c8
d8 83 47 7f 9b fe 31 4b 0e 95 d5 f5 ed 3d
depth=1 C = DE, // * lots of info ***
verify return:1
depth=0 C = DE, // * lots of info ***
verify return:1
SSL_accept:SSLv3 read client certificate A
 TLS 1.0 Handshake [length 0046], ClientKeyExchange
10 00 00 42 41 04 57 d1 78 67 df 6f 64 d9 0e d0
d3 95 d0 8a 05 13 52 0f 73 9c e1 a9 64 e6 45 d5
... handshake completes

An interesting difference is the lines starting with depth=. I cannot
print the actual info there but there's two such lines with the s_client
tool and only one with my client. Also, s_client seems to send both
certificates. Where I put in that comment I see the textual description of
first the root CA (after depth=1) and then my client cert (after depth=0).

My client however only causes one such line and the info there is the root
CA. His own client certificate doesn't appear. That leads me to believe
that the client doesn't trust his own certificate and therefore doesn't
send it. But since the root CA is in the chain, he sends this instead.
Which in turn s_server will not accept since it doesn't state SSL client
as purpose. Can that be? And if so, why will my client not send the
certificate while the s_client will? Not really a big step forward but at
this point I'm glad for half a baby step.

Cheers,
Stephan




On Mon, Jun 10, 2013 at 10:06 AM, Stephan Menzel
stephan.men...@gmail.comwrote:

 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