On 9/19/2011 3:28 PM, Kaspar Brand wrote:
> IMO, you can always drop the first element of the chain, since you only
> want to remember CA certs in pkp->ca_certs.
>

OK, cool - I was unsure if the chain would ALWAYS contain the cert in
cases of validation OK or error. I'll make this quick update.

>> +        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));
>> +        }
> Here, cert_cn holds the X509_NAME_oneline() string of the subject DN.
> Either the variable name is a misnomer or a typo (did you mean cert_dn
> instead of cert_cn?)

Yes, indeed. s/_cn/_dn/g

>
> I have just added ssl_log_xerror() and SSL_X509_NAME_to_string() in
> r1172797, can you adapt the code in ssl_callback_proxy_cert() to make
> use of these where applicable/possible? Hopefully this makes logging
> cert details in mod_ssl more straightforward.
>
> Kaspar

Sure - no problem. Have a look at the update below. If this jives, I'll
commit to trunk when I have a minute to do so.

Also - any opposition to including SSL_X509_NAME_to_string as part of
the backport proposal? I would like to keep the patches consistent. If
not, would you prefer me to roll it into the
SSLProxyMachineCertificateChainFile patch or propose it separately?



Update...

    X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);

    for (n = 0; n < ncerts; n++) {
        int i, res;

        X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
        X509_NAME *name = X509_get_subject_name(inf->x509);
        char *cert_dn = SSL_X509_NAME_to_string(ptemp, name, 0);
        X509_STORE_CTX_init(sctx, store, inf->x509, NULL);

        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_dn, X509_verify_cert_error_string(err));
        }

        chain = X509_STORE_CTX_get1_chain(sctx);

        /* 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));

        ERR_clear_error();
        i = sk_X509_num(chain);
        pkp->ca_certs[n] = chain;

        if (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,
                     "loaded %i intermediate CA%s for cert %i (%s)",
                     i, i == 1 ? "" : "s", n, cert_dn);
        if (i > 0) {
            int j;
            for (j=0; j<i; j++) {
                X509_NAME *ca_name =
X509_get_subject_name(sk_X509_value(chain, j));
                char *ca_dn = SSL_X509_NAME_to_string(ptemp, ca_name, 0);
                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%i: %s", j,
ca_dn);
            }
        }
    }

    X509_STORE_CTX_free(sctx);



-- 
Daniel Ruggeri

Reply via email to