On 23/08/2011 20:35, [email protected] wrote: > Author: druggeri > Date: Tue Aug 23 19:35:07 2011 > New Revision: 1160863 > > URL: http://svn.apache.org/viewvc?rev=1160863&view=rev > Log: > Add SSLProxyMachineCertificateChainFile directive and documentation for bug > 50812 > > Modified: httpd/httpd/trunk/modules/ssl/ssl_util_ssl.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_util_ssl.c?rev=1160863&r1=1160862&r2=1160863&view=diff > ============================================================================== > --- httpd/httpd/trunk/modules/ssl/ssl_util_ssl.c (original) > +++ httpd/httpd/trunk/modules/ssl/ssl_util_ssl.c Tue Aug 23 19:35:07 2011 > @@ -434,6 +434,45 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t > return ok; > } > > +/* > + * Construct a stack of X509_INFO containing only certificates > + * that have signed the provided certificate or are an intermediary > + * signer of the certificate > +*/ > +int SSL_X509_INFO_create_chain(const X509 *x509, > + STACK_OF(X509_INFO) *ca_certs, > + STACK_OF(X509_INFO) *chain) > +{ > + int can_proceed=1; > + int len=0; > + int i; > + X509 *certificate = (X509 *)x509; > + X509_INFO *info; > + X509_NAME *cert_issuer_name, *ca_name, *ca_issuer_name; > + > + while (can_proceed) { > + can_proceed = 0; > + cert_issuer_name = X509_get_issuer_name(certificate); > + > + for (i = 0; i < sk_X509_INFO_num(ca_certs); i++) { > + info = sk_X509_INFO_value(ca_certs, i); > + ca_name = X509_get_subject_name(info->x509); > + ca_issuer_name = X509_get_issuer_name(info->x509); > + > + if (X509_NAME_cmp(cert_issuer_name, ca_name) == 0) { > + /* Check for a self-signed cert (no issuer) */ > + can_proceed=X509_NAME_cmp(ca_name, ca_issuer_name) == 0 ? 0 > : 1; > + len++; > + certificate = info->x509; > + sk_X509_INFO_unshift(chain, info); > + break; > + } > + } > + } > + > + return len; > +} > + >
The above code is manually building up a certificate chain. While it will work for the simpler cases it cannot handle more complex chains. For example those where several certificates have the same subject name and indicate preferences using SKID/AKID. Also certificates can appear higher in the chain and be "self issued" (matching subject/issuer) but not self signed. Admittedly such cases are comparatively rare outside compliance tests... So instead of manually building the chain why not handle it automatically or at least have the option to do so? The X509_verify_cert function in OpenSSL can do this. This has the advantage that the chain is also checked for validity (expiry for example) and you can't send an invalid chain and have to trace why the peer is rejecting it with a (possibly obscure) error. Steve. -- Dr Stephen Henson. OpenSSL Software Foundation, Inc. 1829 Mount Ephraim Road Adamstown, MD 21710 +1 877-673-6775 [email protected]
