Commit aeb6b988 authored by Doug MacEachern's avatar Doug MacEachern
Browse files

support "SSLVerifyClient optional_no_ca"


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90599 13f79535-47bb-0310-9956-ffa450edef68
parent 665e489c
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ int ssl_hook_process_connection(SSLFilterRec *pRec)
    char *cp = NULL;
    conn_rec *c = (conn_rec*)SSL_get_app_data (pRec->pssl);
    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
    long verify_result;

    if (!SSL_is_init_finished(pRec->pssl))
    {
@@ -445,15 +446,38 @@ int ssl_hook_process_connection(SSLFilterRec *pRec)
        /*
         * Check for failed client authentication
         */
        if (SSL_get_verify_result(pRec->pssl) != X509_V_OK ||
        verify_result = SSL_get_verify_result(pRec->pssl);

        if (verify_result != X509_V_OK ||
            ((cp = (char *)apr_table_get(c->notes,
                                         "ssl::verify::error")) != NULL))
        {
            if (ssl_verify_error_is_optional(verify_result) &&
                (sc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA))
            {
                /* leaving this log message as an error for the moment,
                 * according to the mod_ssl docs:
                 * "level optional_no_ca is actually against the idea
                 *  of authentication (but can be used to establish 
                 * SSL test pages, etc.)"
                 * optional_no_ca doesn't appear to work as advertised
                 * in 1.x
                 */
                ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
                        "SSL client authentication failed, "
                        "accepting certificate based on "
                        "\"SSLVerifyClient optional_no_ca\" configuration");

            }
            else {
                const char *verror =
                    X509_verify_cert_error_string(verify_result);
                ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
                        "SSL client authentication failed: %s",
                    cp != NULL ? cp : "unknown reason");
                        cp ? cp : verror ? verror : "unknown");
                return ssl_abort(pRec, c);
            }
        }

        /*
         * Remember the peer certificate's DN
+11 −0
Original line number Diff line number Diff line
@@ -344,6 +344,17 @@ typedef enum {
    SSL_CVERIFY_OPTIONAL_NO_CA  = 3
} ssl_verify_t;

#ifndef X509_V_ERR_CERT_UNTRUSTED
#define X509_V_ERR_CERT_UNTRUSTED 27
#endif

#define ssl_verify_error_is_optional(errnum) \
   ((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) \
    || (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) \
    || (errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) \
    || (errnum == X509_V_ERR_CERT_UNTRUSTED) \
    || (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE))

/*
 * Define the SSL pass phrase dialog types
 */
+3 −8
Original line number Diff line number Diff line
@@ -1237,14 +1237,9 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
        verify = dc->nVerifyClient;
    else
        verify = sc->nVerifyClient;
    if (   (   errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
            || errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
            || errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
#if SSL_LIBRARY_VERSION >= 0x00905000
            || errnum == X509_V_ERR_CERT_UNTRUSTED
#endif
            || errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE  )
        && verify == SSL_CVERIFY_OPTIONAL_NO_CA                       ) {
    if (ssl_verify_error_is_optional(errnum) &&
        verify == SSL_CVERIFY_OPTIONAL_NO_CA)
    {
        ssl_log(s, SSL_LOG_TRACE,
                "Certificate Verification: Verifiable Issuer is configured as "
                "optional, therefore we're accepting the certificate");