From: Daniel Ruggeri <druggeri@apache.org> Date: Mon, 26 Sep 2011 16:39:00 +0000 (+0000) Subject: Final update to SSLProxyMachineCertificateChainFile X-Git-Tag: 2.3.15~193 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c4736a532685b3585971a446d6b93cb2d5d18b12;p=apache Final update to SSLProxyMachineCertificateChainFile git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1175946 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index 71a91047aa..341ee43431 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -1175,63 +1175,60 @@ static void ssl_init_proxy_certs(server_rec *s, if (!sctx) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "SSL proxy client cert initialization failed"); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); ssl_die(); } X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); for (n = 0; n < ncerts; n++) { - int i, res; - char cert_cn[256]; + int i; 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); - res = X509_verify_cert(sctx); - chain = X509_STORE_CTX_get1_chain(sctx); - - 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 { + /* Attempt to verify the client cert */ + if (X509_verify_cert(sctx) != 1) { int err = 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(err)); + ssl_log_xerror(SSLLOG_MARK, APLOG_WARNING, 0, ptemp, s, inf->x509, + "SSL proxy client cert chain verification failed: %s :", + X509_verify_cert_error_string(err)); } + + /* Clear X509_verify_cert errors */ 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); + /* Obtain a copy of the verified chain */ + chain = X509_STORE_CTX_get1_chain(sctx); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 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<i; j++) { - char ca_cn[256]; - X509_NAME *ca_name = X509_get_subject_name(sk_X509_value(chain, j)); - X509_NAME_oneline(ca_name, ca_cn, sizeof(ca_cn)); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%i: %s", j, ca_cn); + if (chain != NULL) { + /* Discard end entity cert from the chain */ + X509_free(sk_X509_shift(chain)); + + if ((i = sk_X509_num(chain)) > 0) { + /* Store the chain for later use */ + pkp->ca_certs[n] = chain; + } + else { + /* Discard empty chain */ + sk_X509_pop_free(chain, X509_free); + pkp->ca_certs[n] = NULL; + } + + ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509, + "loaded %i intermediate CA%s for cert %i: ", + i, i == 1 ? "" : "s", n); + if (i > 0) { + int j; + for (j = 0; j < i; j++) { + ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, + sk_X509_value(chain, j), "%i:", j); + } } } + + /* get ready for next X509_STORE_CTX_init */ + X509_STORE_CTX_cleanup(sctx); } X509_STORE_CTX_free(sctx); diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 584b836b24..561168c677 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -538,8 +538,10 @@ typedef struct { const char *cert_file; const char *cert_path; const char *ca_cert_file; - STACK_OF(X509_INFO) *certs; - STACK_OF(X509) **ca_certs; /* ptr to array of ptrs */ + STACK_OF(X509_INFO) *certs; /* Contains End Entity certs */ + STACK_OF(X509) **ca_certs; /* Contains ONLY chain certs for + * each item in certs. + * (ptr to array of ptrs) */ } modssl_pk_proxy_t; /** stuff related to authentication that can also be per-dir */