On the client side, double check that you are creating the SSL object from the context AFTER you set the client cert for the context, and not the other way around. On Sun, Jan 10, 2016 at 2:18 PM, Karl Denninger <karl at denninger.net> wrote: > I'm sure this is a function of my lack of understanding of the > documentation, but here it is... > > I have an application that implements SSL-encrypted transport between two > or more devices. For those that are clients without certificates (e.g. > someone connecting with a web browser) it is working fine. > > However, I also want certain "things" to connect *with* a certificate. > Toward that end I have set up a separate context for said connections, with > (simplified a bit): > > master_method = (SSL_METHOD *) SSLv23_server_method(); > /* Create instance */ > master_context = SSL_CTX_new(master_method); /* Get SSL > context for later */ > > Then I set up the CA that is going to verify the client certificates that > are presented, with: > > sprintf(tmp, "%s/ssl/ca.pem", CONFIG_DIR); > if (!SSL_CTX_load_verify_locations(master_context, tmp, > NULL)) { > syslog(LOG_ERR, "Cannot load verification; MASTER > will not validate"); > } > > and then load the server-side certificate and key, plus tell it to verify > the peer. > > sprintf(tmp, "%s/ssl/%s", CONFIG_DIR, cert); > if (SSL_CTX_use_certificate_file(master_context, tmp, > SSL_FILETYPE_PEM) < 0) { > syslog(LOG_WARNING, "Cannot load SSL Certificate - > SSL MASTER DISABLED"); > } else { > sprintf(tmp, "%s/ssl/%s", CONFIG_DIR, pkey); > if (SSL_CTX_use_PrivateKey_file(master_context, > tmp, SSL_FILETYPE_PEM) < 0) { > syslog(LOG_WARNING, "Cannot load SSL Key - > SSL MASTER DISABLED"); > } else { > SSL_CTX_set_verify(master_context, > SSL_VERIFY_PEER, verify_callback); > master_ssl_possible = 1; /* Enable */ > syslog(LOG_INFO, "SSL MASTER capability > initalized."); > } > } > > verify_callback just returns the preverify_ok flag back; I don't care WHY > the verification failed, just whether it did or not. In other words > looking at the "last reason" is good enough (which I can get once the > accept fails, if it does.) > > Now the client has a very similar set of code in it and when it connects > it gets the verification (with the callback set to NULL) and, provided the > certificate verifies against the CA file provided, all is well and it > works. The client's certificate and key are loaded and the same basic code > as up above is used to load the cert and key without errors being thrown > (except, of course, that I call SSLv23_client_method() to get the method > structure.) It also connects *and* properly verifies the server's > certificate. > > However, on the server side I never get a client certificate back despite > having loaded one into the context on the client and asking for it with > SSL_VERIFY_PEER on the server. > > If I INSIST on a client certificate by adding the > SSL_VERIFY_FAIL_IF_NO_PEER_CERT, the connections always fail at > SSL_accept() with an error indicating that no client certificate was > provided. > > If not, however, the accept succeeds, the verification callback routine is > never called (!) and when I attempt to get the peer certificate with > SSL_get_peer_certificate() so I can walk through it and check the returned > attributes (I wish to use the subjectAltName field among others) I get back > a NULL. > > This has to be something stupid on my part, because I should get the > verify_callback in any event, I believe -- but I never do. > > -- > Karl Denninger > karl at denninger.net > *The Market Ticker* > *[S/MIME encrypted email preferred]* > > _______________________________________________ > openssl-users mailing list > To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20160110/897618ff/attachment-0001.html>