> From: [EMAIL PROTECTED] On Behalf Of Michael Simms
> Sent: Wednesday, 19 November, 2008 11:05

> OK, as requested, I'm going to give a detailed breakdown of what the
> client and server does with this error
> 
> As a note: The certificates are *fine* I have used them successfully
> with s_client and s_server tests. They verify perfectly well.
> 
The one you've attached, yes; the one you are generating in code, 
maybe not, because s_client (and s_server) never does that.

> So, the conversation goes as follows. I am abbreviating some of it,
> but only the unimportant bits (like the low level socket negotiation,
> and the values we pass into the generated keys which arent being
> verified).
> 
> SERVER: 
> SERVER: socket()                      // Create socket
> SERVER: fcntl()                       // Nonblocking fcntl
> SERVER: bind()                        // Bind to port
> SERVER: listen()                      // Listen on port
> SERVER: SSL_library_init()
> SERVER: SSL_load_error_strings()
> SERVER: ssl_meth=SSLv23_server_method()
> SERVER: sctx=SSL_CTX_new(ssl_meth)
> SERVER: bio = memory_buf_BIO(private_key, -1)
> SERVER: if (private_key_password)
> SERVER:   key=PEM_read_bio_PrivateKey(bio,NULL,
> ssl_key_password_callback,
>                                       private_key_password)
> SERVER: else
> SERVER:   key=PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL,NULL)
> SERVER: BIO_free(bio)
> SERVER: bio = memory_buf_BIO(public_key, -1)
> SERVER: cert=PEM_read_bio_X509(bio,NULL,NULL,NULL)
> SERVER: SSL_CTX_use_PrivateKey(sctx,key)
> SERVER: SSL_CTX_use_certificate(sctx,cert)
> SERVER: SSL_CTX_check_private_key(sctx)        // PASSES
> 
It seems overwhelmingly likely, but just to be absolutely clear,
I presume private_key and public_key are buffers containing 
the servercert.pem and serverkey.pem files you posted.
You could read the files directly with _use_certificate_file 
and _use_PrivateKey_file, which is usually more convenient.
Also, you don't show BIO_free for second bio (mem leak).

> CLIENT: socket()
> CLIENT: fcntl()                       // Nonblocking fcntl
> CLIENT: connect()          //WAIT for connect to succeed
> 
> SERVER: accept()
> SERVER: fcntl()                  // Nonblocking fcntl on new socket
> SERVER: sssl=SSL_new(sctx)
> SERVER: SSL_set_fd(sssl,newly_accepted_fd)
> 
> SERVER: SSL_accept(sssl)     //Keep on doing this until WANT_READ
> stops
> 
Server didn't do (SSL_CTX|SSL)_set_verify ? If so (as previously noted)
it shouldn't be requesting client to authenticate at all.

> 
>   //CLIENT DOES **NOT** run SSL_library_init, as this is a unit test
>   //run with the server and client in one process, and so it does not
>   //initialise twice.
> 
> CLIENT: ssl_meth=SSLv23_client_method()
> CLIENT: cctx = SSL_CTX_new(ssl_meth)
> CLIENT: SSL_CTX_load_verify_locations(cctx,
>                                       ca_filename,NULL)
> CLIENT: SSL_CTX_set_verify(cctx,SSL_VERIFY_PEER,NULL)
> CLIENT: SSL_CTX_set_verify_depth(cctx,10);
>    //THIS SECTION is all just generating a new keypair
> CLIENT: rsakey=RSA_generate_key(1024,RSA_F4,NULL,NULL)
> CLIENT: ckey = EVP_PKEY_new()
> CLIENT: EVP_PKEY_assign_RSA(ckey, rsakey)
> CLIENT: required_size = i2d_RSAPublicKey(rsakey,NULL)
> CLIENT: len=i2d_RSAPublicKey(rsakey,&correct_sized_buf)
>           //Move correct_sized_buf back to its start
> CLIENT: pubrsa=d2i_RSAPublicKey(NULL,&correct_sized_buf,len)
> CLIENT: tmp_pkey = EVP_PKEY_new();
> CLIENT: EVP_PKEY_assign_RSA(tmp_pkey, pubrsa);

Aside: I THINK you don't actually need this i2d-d2i conversion,
if you just set a (tagged) RSA* that happens to be a privatekey
it can be encoded as a publickey (because of how RSA works).

> CLIENT: ccert=X509_new();
> CLIENT: X509_set_pubkey(ccert,tmp_pkey);
> CLIENT: X509_set_version(ccert,3);

Aside: I'm pretty sure that should be 2. "X.509 version 3" is 
the version of the standard but the certs actually have a 
version field value of 2.  In fact you apparently aren't using 
extensions, so a value of 0 meaning "version 1" would work.

> CLIENT: X509_set_serialNumber(ccert, serial);
> CLIENT: X509_set_notBefore(ccert,timebound);
> CLIENT: X509_set_notAfter(ccert,timebound);

Aside: the same time? Normally you want notBefore=some_time 
and notAfter=some_later_time (typically +3mo/2yr/10yr, etc.)

> CLIENT: X509_set_subject_name(ccert,subject);
> CLIENT: X509_set_issuer_name(ccert,subject);
> CLIENT: X509_sign(ccert, ckey, EVP_md5());
>           //THIS FINISHES the creation
> CLIENT: SSL_CTX_use_PrivateKey(cctx,ckey);
> CLIENT: SSL_CTX_use_certificate(cctx,ckey)

I hope that's a typo and you meant ccert there.
So your client has created its own selfsigned cert, using (and for) 
a key the server knows nothing about. If this was actually used 
for authentication it should fail, because the server has no reason
to trust it. But per above the server is probably not requesting it,
and per below you are getting an error before client auth anyway.

> CLIENT: SSL_CTX_check_private_key(cctx)            //PASS
> CLIENT: cssl=SSL_new(cctx);
> CLIENT: SSL_set_fd(cssl,clients_connected_fd)
> CLIENT: SSL_connect(cssl);    //Keep on doing this until WANT_READ
> stops
> 
> **HERE** We get the error on SSL_connect after a few WANT_READS
> 
> error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate
> verify failed
> 
> So, thats the routine used. The exact reverse, where the client uses
> the same keys and the server has the same ca, works just fine.
> 
I'm not sure what you mean by client uses 'same keys' since you show 
client generating a different, and probably useless, key on each run.

But if server has use_privatekey/certificate of serverkey/cert.pem 
and client has load_verify_locations of rootcert.pem, it should pass
this step = server authentication. (I suspect you will still have 
a problem with client authentication, but that's a different matter.)

You could try writing a verify callback used in the client that logs 
or displays some convenient bits of the received cert/chain and check
they are as they should be, or just debug it and look at the same.
Maybe you have a bug in your multithreading, but those tend to be erratic;
could you perhaps configure one process to run only the client thread 
and a different one to run only the server thread?



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to