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

Reply via email to