On 19/02/2014 18:37, Jeff Trawick wrote: > > > I think this is the trick... > > + rc = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); > + while (rc) { > + x = SSL_CTX_get0_certificate(ctx); > + if (x) { > + chain = NULL; > + SSL_CTX_get0_chain_certs(ctx, &chain); > + if (chain) { > + for (i = 0; i < sk_X509_num(chain); i++) { > + X509 *x = sk_X509_value(chain, i); > + /* do something */ > + } > + } > + } > + rc = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT); > + } > > I'm working on Certificate Transparency support for httpd; as part of > submitting > server certs with any necessary intermediate certs to CT logs I wanted to > extract them straight from the SSL_CTX so that it didn't matter how exactly > they > got there/were configured. >
Unfortunately that wont work in all cases. There are several distinct ways CA certificates can be configured. In OpenSSL versions before 1.0.2 two ways existed. These had origins way back to the SSLeay days. One was a set of extra certificates which are shared amongst all the server certificate types in an SSL_CTX. This is far from ideal because you could have (for example) an RSA and a ECDSA certificate with different chains which you couldn't configure using this method. It could also end up using the wrong chain if the server is misconfigured. It also makes it impossible to have different chains with different SSL structures sharing the same parent SSL_CTX. On the plus side the set of certificates is configured only once and can be retrieved by an application. I notice httpd can use this method. The second method is used in the absence of any extra certificates. An attempt is made to build a complete chain using the normal certificate verification routine and trust store. This is done on the fly on each incoming connection which is inefficient. It also uses the same certificate store used for client certificate verification (which might not be ideal). It does however have the advantage that it can handle different chains for different certificate types. I *think* httpd can use this method too as it's done pretty much automatically. In OpenSSL 1.0.2 this has been extended. One method is the one which you used above. This supports distinct chains per certificate type and per-SSL structure. However for that to work it needs application support either explicitly by using SSL_CTX_add0_chain_cert or via the use of SSL_CTX_use_cetificate_chain_file which uses this transparently in OpenSSL 1.0.2. I just checked and httpd currently doesn't use either of these but an enhancement to tidy up certificate handling by Kaspar Brand does use SSL_CTX_use_certificate_chain_file. That means getting a method that works in all cases is problematical. You can use SSL_CTX_get_extra_chain_certs which retrieves the chain for the current certificate or (if it is empty) the per-ctx chain. That works for two cases above. If however the on the fly chain building is performed it will fail. Steve. -- Dr Stephen Henson. OpenSSL Software Foundation, Inc. 1829 Mount Ephraim Road Adamstown, MD 21710 +1 877-673-6775 shen...@opensslfoundation.com