From 362f424e78b54a6d176aaf1b94a116905a80a290 Mon Sep 17 00:00:00 2001 From: Daniel Ruggeri Date: Sat, 17 Sep 2011 16:25:17 +0000 Subject: [PATCH] Log better information and prevent leak of an X509 structure for SSLProxyMachineCertificateChainFile git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1172010 13f79535-47bb-0310-9956-ffa450edef68 --- modules/ssl/ssl_engine_init.c | 48 ++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 59fea93d01..0d8ec06faa 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -1181,21 +1181,57 @@ static void ssl_init_proxy_certs(server_rec *s, X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); for (n = 0; n < ncerts; n++) { - int i; + int i, res; + char cert_cn[256]; + X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n); + X509_NAME *name = X509_get_subject_name(inf->x509); + X509_NAME_oneline(name, cert_cn, sizeof(cert_cn)); X509_STORE_CTX_init(sctx, store, inf->x509, NULL); - X509_verify_cert(sctx); - ERR_clear_error(); + res=X509_verify_cert(sctx); chain = X509_STORE_CTX_get1_chain(sctx); - sk_X509_shift(chain); + + if (res == 1) { + /* Removing the client cert if verification is OK + * could save a loop when choosing which cert to send + * when more than one is available */ + /* XXX: This is not needed if we collapse the two + * checks in ssl_engine_kernel in the future */ + X509_free(sk_X509_shift(chain)); + } + else { + int n=X509_STORE_CTX_get_error(sctx); + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, + "SSL proxy client cert chain verification failed for %s: %s", + cert_cn, X509_verify_cert_error_string(n)); + } + ERR_clear_error(); i=sk_X509_num(chain); pkp->ca_certs[n] = chain; + + if (i == 0 || (res != 1 && i == 1) ) { + /* zero or only the client cert won't be very useful + * due to verification failure */ + sk_X509_pop_free(chain, X509_free); + i = 0; + pkp->ca_certs[n] = NULL; + } + X509_STORE_CTX_cleanup(sctx); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "client certificate %i has loaded %i " - "intermediate CA%s", n, i, i == 1 ? "" : "s"); + "loaded %i intermediate CA%s for cert %i (%s)", + i, i == 1 ? "" : "s", n, cert_cn); + if (i > 0) { + int j; + for (j=0; j