On 03/09/2011 07:06, Kaspar Brand wrote: > >> 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; >> +} >> + > > I think it's preferrable to let OpenSSL build the chain (instead of > doing it ourselves). There's no readily available function for this, > unfortunately, but could you try something along the lines in OpenSSL's > s3_both.c:ssl3_output_cert_chain()? See > > http://cvs.openssl.org/chngview?cn=18326 > > I.e., use X509_verify_cert(), ignore its result, but grab the chain from > the X509_STORE_CTX afterwards. (And when you're done, it's probably > wise to call ERR_clear_error, see http://cvs.openssl.org/chngview?cn=19472). >
Sorry for the duplicate comment missed this. There are a few side effects with using X509_verify_cert(). Some errors (signature error, expired certificates) should arguably logged or even treated as fatal errors. This would be because the cause is a badly configured server and it is better to get the user to fix their configuration than send a certificate chain that is invalid. In other cases you may hit problems because sometimes a certificate "chain" which doesn't quite fit the PKIX definition is used. An example would be a proxy certificate chain (for some value of "proxy", not necessarily standard) where some certificates in the chain are not CA certificates in the normal definition (basic constraints CA=TRUE). That kind of "chain" cannot directly be built up using X509_verify_cert(). Steve. -- Dr Stephen Henson. OpenSSL Software Foundation, Inc. 1829 Mount Ephraim Road Adamstown, MD 21710 +1 877-673-6775 [email protected]
