> 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]