Commit 4fd2be09 authored by Daniel Ruggeri's avatar Daniel Ruggeri
Browse files

Modify SSLProxyMachineCertificateChainFile to use X509 instead of X509_INFO...

Modify SSLProxyMachineCertificateChainFile to use X509 instead of X509_INFO and use openssl to construct the chain

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1170833 13f79535-47bb-0310-9956-ffa450edef68
parent 978e7595
Loading
Loading
Loading
Loading
+5 −0
Changes for docs/manual/mod/mod_ssl.xml: 5 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1549,6 +1549,11 @@ This referenced file is simply the concatenation of the various PEM-encoded
certificate files. Upon startup, each client certificate configured will
be examined and a chain of trust will be constructed.
</p>
<note type="warning"><title>Security warning</title>
<p>If this directive is enabled, all of the certificates in the file will be
trusted as if they were also in <directive module="mod_ssl">
SSLProxyCACertificateFile</directive>.</p>
</note>
<example><title>Example</title>
SSLProxyMachineCertificateChainFile /usr/local/apache2/conf/ssl.crt/proxyCA.pem
</example>
+25 −10
Changes for modules/ssl/ssl_engine_init.c: 25 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -1115,7 +1115,9 @@ static void ssl_init_proxy_certs(server_rec *s,
    int n, ncerts = 0;
    STACK_OF(X509_INFO) *sk;
    modssl_pk_proxy_t *pkp = mctx->pkp;
    STACK_OF(X509_INFO) *chain;
    STACK_OF(X509) *chain;
    X509_STORE_CTX *sctx;
    X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);

    SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
                               ssl_callback_proxy_cert);
@@ -1161,29 +1163,42 @@ static void ssl_init_proxy_certs(server_rec *s,
                 ncerts);
    pkp->certs = sk;

    if (!pkp->ca_cert_file) {

    if (!pkp->ca_cert_file || !store) {
        return;
    }

    /* Load all of the CA certs and construct a chain */
    sk = sk_X509_INFO_new_null();
    pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk));
    sctx = X509_STORE_CTX_new();

    if (!sctx) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
                     "SSL proxy client cert initialization failed");
        ssl_die();
    }

    SSL_X509_INFO_load_file(ptemp, sk, pkp->ca_cert_file);
    pkp->ca_certs = (STACK_OF(X509_INFO) **) apr_pcalloc(p, ncerts * sizeof(sk));
    X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);

    for (n = 0; n < ncerts; n++) {
        int len;
        int i;
        X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
        chain = sk_X509_INFO_new_null();
        len = SSL_X509_INFO_create_chain(inf->x509, sk, chain);
        X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
        X509_verify_cert(sctx);
        ERR_clear_error();

        chain = X509_STORE_CTX_get1_chain(sctx);
        sk_X509_shift(chain);
        i=sk_X509_num(chain);
        pkp->ca_certs[n] = chain;
        X509_STORE_CTX_cleanup(sctx);

        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     "client certificate %i has loaded %i "
                     "intermediary signers ", n, len);
                     "intermediate CA%s", n, i, i == 1 ? "" : "s");
    }

    sk_X509_INFO_free(sk);
    X509_STORE_CTX_free(sctx);
}

static void ssl_init_proxy_ctx(server_rec *s,
+9 −8
Changes for modules/ssl/ssl_engine_kernel.c: 9 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -1588,11 +1588,12 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
    server_rec *s = mySrvFromConn(c);
    SSLSrvConfigRec *sc = mySrvConfig(s);
    X509_NAME *ca_name, *issuer, *ca_issuer;
    X509_INFO *info, *ca_info;
    X509_INFO *info;
    X509 *ca_cert;
    STACK_OF(X509_NAME) *ca_list;
    STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
    STACK_OF(X509_INFO) *ca_certs;
    STACK_OF(X509_INFO) **ca_cert_chains;
    STACK_OF(X509) *ca_certs;
    STACK_OF(X509) **ca_cert_chains;
    int i, j, k;

    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
@@ -1642,16 +1643,16 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)

           if (ca_cert_chains) {
                /*
                 * Failed to find direct issuer - search intermediaries
                 * Failed to find direct issuer - search intermediates
                 * (by issuer name), if provided.
                 */
                ca_certs = ca_cert_chains[j];
                for (k = 0; k < sk_X509_INFO_num(ca_certs); k++) {
                    ca_info = sk_X509_INFO_value(ca_certs, k);
                    ca_issuer = X509_get_issuer_name(ca_info->x509);
                for (k = 0; k < sk_X509_num(ca_certs); k++) {
                    ca_cert = sk_X509_value(ca_certs, k);
                    ca_issuer = X509_get_issuer_name(ca_cert);

                    if(X509_NAME_cmp(ca_issuer, ca_name) == 0 ) {
                        modssl_proxy_info_log(c, info, "found acceptable cert by intermediary");
                        modssl_proxy_info_log(c, info, "found acceptable cert by intermediate CA");

                        modssl_set_cert_info(info, x509, pkey);

+1 −1
Changes for modules/ssl/ssl_private.h: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -539,7 +539,7 @@ typedef struct {
    const char  *cert_path;
    const char  *ca_cert_file;
    STACK_OF(X509_INFO) *certs;
    STACK_OF(X509_INFO) **ca_certs; /* ptr to array of ptrs */
    STACK_OF(X509) **ca_certs; /* ptr to array of ptrs */
} modssl_pk_proxy_t;

/** stuff related to authentication that can also be per-dir */
+0 −40
Changes for modules/ssl/ssl_util_ssl.c: 0 added lines, 40 removed lines.
Original line number Diff line number Diff line
@@ -385,46 +385,6 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp,
    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;
}

/*  _________________________________________________________________
**
**  Extra Server Certificate Chain Support
Loading