httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Ruggeri <DRugg...@primary.net>
Subject Re: svn commit: r1160863 - in /httpd/httpd/trunk: docs/manual/mod/ modules/ssl/
Date Sat, 17 Sep 2011 16:31:54 GMT
On 9/17/2011 6:02 AM, Dr Stephen Henson wrote:
> Yes you need store the returned value and free it with X509_free().
>
> Note also that because you ignore return values of X509_verify_cert() you might
> have a situation where the chain is not complete and so deleting the last
> element will remove a non-root CA.

Both suggestions make sense - here is what was just committed to
trunk... I also added logging of verification failures at WARNING level.
Since I was in the file again anyhow, I added logging at DEBUG of what
gets loaded and the order so there is no ambiguity.

...
    for (n = 0; n < ncerts; n++) {
        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);

        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 {
            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,
                     "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);
            }
        }
    }

    X509_STORE_CTX_free(sctx);
...

-- 
Daniel Ruggeri


Mime
View raw message