⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_engine_kernel.c

📁 mod_ssl-2.8.31-1.3.41.tar.gz 好用的ssl工具
💻 C
📖 第 1 页 / 共 5 页
字号:
    sc  = mySrvConfig(r->server);    ssl = ap_ctx_get(r->connection->client->ctx, "ssl");    if (ssl != NULL)        ctx = SSL_get_SSL_CTX(ssl);    /*     * Support for SSLRequireSSL directive     */    if (dc->bSSLRequired && ssl == NULL) {        ap_log_reason("SSL connection required", r->filename, r);        /* remember forbidden access for strict require option */        ap_table_setn(r->notes, "ssl-access-forbidden", (void *)1);        return FORBIDDEN;    }    /*     * Check to see if SSL protocol is on     */    if (!sc->bEnabled)        return DECLINED;    if (ssl == NULL)        return DECLINED;    /*     * Support for per-directory reconfigured SSL connection parameters.     *     * This is implemented by forcing an SSL renegotiation with the     * reconfigured parameter suite. But Apache's internal API processing     * makes our life very hard here, because when internal sub-requests occur     * we nevertheless should avoid multiple unnecessary SSL handshakes (they     * require extra network I/O and especially time to perform).      *      * But the optimization for filtering out the unnecessary handshakes isn't     * obvious and trivial.  Especially because while Apache is in its     * sub-request processing the client could force additional handshakes,     * too. And these take place perhaps without our notice. So the only     * possibility is to explicitly _ask_ OpenSSL whether the renegotiation     * has to be performed or not. It has to performed when some parameters     * which were previously known (by us) are not those we've now     * reconfigured (as known by OpenSSL) or (in optimized way) at least when     * the reconfigured parameter suite is stronger (more restrictions) than     * the currently active one.     */    renegotiate            = FALSE;    renegotiate_quick      = FALSE;#ifdef SSL_EXPERIMENTAL_PERDIRCA    reconfigured_locations = FALSE;#endif    /*     * Override of SSLCipherSuite     *     * We provide two options here:     *     * o The paranoid and default approach where we force a renegotiation when     *   the cipher suite changed in _any_ way (which is straight-forward but     *   often forces renegotiations too often and is perhaps not what the     *   user actually wanted).     *     * o The optimized and still secure way where we force a renegotiation     *   only if the currently active cipher is no longer contained in the     *   reconfigured/new cipher suite. Any other changes are not important     *   because it's the servers choice to select a cipher from the ones the     *   client supports. So as long as the current cipher is still in the new     *   cipher suite we're happy. Because we can assume we would have     *   selected it again even when other (better) ciphers exists now in the     *   new cipher suite. This approach is fine because the user explicitly     *   has to enable this via ``SSLOptions +OptRenegotiate''. So we do no     *   implicit optimizations.     */    if (dc->szCipherSuite != NULL) {        /* remember old state */        pCipher = NULL;        skCipherOld = NULL;        if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE)            pCipher = SSL_get_current_cipher(ssl);        else {            skCipherOld = SSL_get_ciphers(ssl);            if (skCipherOld != NULL)                skCipherOld = sk_SSL_CIPHER_dup(skCipherOld);        }        /* configure new state */        if (!SSL_set_cipher_list(ssl, dc->szCipherSuite)) {            ssl_log(r->server, SSL_LOG_WARN|SSL_ADD_SSLERR,                    "Unable to reconfigure (per-directory) permitted SSL ciphers");            if (skCipherOld != NULL)                sk_SSL_CIPHER_free(skCipherOld);            return FORBIDDEN;        }        /* determine whether a renegotiation has to be forced */        skCipher = SSL_get_ciphers(ssl);        if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {            /* optimized way */            if ((pCipher == NULL && skCipher != NULL) ||                (pCipher != NULL && skCipher == NULL)   )                renegotiate = TRUE;            else if (pCipher != NULL && skCipher != NULL                     && sk_SSL_CIPHER_find(skCipher, pCipher) < 0) {                renegotiate = TRUE;            }        }        else {            /* paranoid way */            if ((skCipherOld == NULL && skCipher != NULL) ||                (skCipherOld != NULL && skCipher == NULL)   )                renegotiate = TRUE;            else if (skCipherOld != NULL && skCipher != NULL) {                for (n = 0; !renegotiate && n < sk_SSL_CIPHER_num(skCipher); n++) {                    if (sk_SSL_CIPHER_find(skCipherOld, sk_SSL_CIPHER_value(skCipher, n)) < 0)                        renegotiate = TRUE;                }                for (n = 0; !renegotiate && n < sk_SSL_CIPHER_num(skCipherOld); n++) {                    if (sk_SSL_CIPHER_find(skCipher, sk_SSL_CIPHER_value(skCipherOld, n)) < 0)                        renegotiate = TRUE;                }            }        }        /* cleanup */        if (skCipherOld != NULL)            sk_SSL_CIPHER_free(skCipherOld);        /* tracing */        if (renegotiate)            ssl_log(r->server, SSL_LOG_TRACE,                    "Reconfigured cipher suite will force renegotiation");    }    /*     * override of SSLVerifyDepth     *     * The depth checks are handled by us manually inside the verify callback     * function and not by OpenSSL internally (and our function is aware of     * both the per-server and per-directory contexts). So we cannot ask     * OpenSSL about the currently verify depth. Instead we remember it in our     * ap_ctx attached to the SSL* of OpenSSL.  We've to force the     * renegotiation if the reconfigured/new verify depth is less than the     * currently active/remembered verify depth (because this means more     * restriction on the certificate chain).     */    if (dc->nVerifyDepth != UNSET) {        apctx = SSL_get_app_data2(ssl);        if ((vp = ap_ctx_get(apctx, "ssl::verify::depth")) != NULL)            n = (int)AP_CTX_PTR2NUM(vp);        else            n = sc->nVerifyDepth;        ap_ctx_set(apctx, "ssl::verify::depth",                   AP_CTX_NUM2PTR(dc->nVerifyDepth));        /* determine whether a renegotiation has to be forced */        if (dc->nVerifyDepth < n) {            renegotiate = TRUE;            ssl_log(r->server, SSL_LOG_TRACE,                    "Reduced client verification depth will force renegotiation");        }    }    /*     * override of SSLVerifyClient     *     * We force a renegotiation if the reconfigured/new verify type is     * stronger than the currently active verify type.      *     * The order is: none << optional_no_ca << optional << require     *     * Additionally the following optimization is possible here: When the     * currently active verify type is "none" but a client certificate is     * already known/present, it's enough to manually force a client     * verification but at least skip the I/O-intensive renegotation     * handshake.     */    if (dc->nVerifyClient != SSL_CVERIFY_UNSET) {        /* remember old state */        nVerifyOld = SSL_get_verify_mode(ssl);        /* configure new state */        nVerify = SSL_VERIFY_NONE;        if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE)            nVerify |= SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;        if (   (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL)            || (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) )            nVerify |= SSL_VERIFY_PEER;        SSL_set_verify(ssl, nVerify, ssl_callback_SSLVerify);        SSL_set_verify_result(ssl, X509_V_OK);        /* determine whether we've to force a renegotiation */        if (!renegotiate && nVerify != nVerifyOld) {            if (   (   (nVerifyOld == SSL_VERIFY_NONE)                    && (nVerify    != SSL_VERIFY_NONE))                || (  !(nVerifyOld &  SSL_VERIFY_PEER)                    && (nVerify    &  SSL_VERIFY_PEER))                || (  !(nVerifyOld &  SSL_VERIFY_FAIL_IF_NO_PEER_CERT)                    && (nVerify    &  SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {                renegotiate = TRUE;                /* optimization */                if (   dc->nOptions & SSL_OPT_OPTRENEGOTIATE                    && nVerifyOld == SSL_VERIFY_NONE                    && (cert = SSL_get_peer_certificate(ssl)) != NULL) {                    renegotiate_quick = TRUE;                    X509_free(cert);                }                ssl_log(r->server, SSL_LOG_TRACE,                        "Changed client verification type will force %srenegotiation",                        renegotiate_quick ? "quick " : "");             }        }    }    /*     *  override SSLCACertificateFile & SSLCACertificatePath     *  This is tagged experimental because it has to use an ugly kludge: We     *  have to change the locations inside the SSL_CTX* (per-server global)     *  instead inside SSL* (per-connection local) and reconfigure it to the     *  old values later. That's problematic at least for the threaded process     *  model of Apache under Win32 or when an error occurs. But unless     *  OpenSSL provides a SSL_load_verify_locations() function we've no other     *  chance to provide this functionality...     */#ifdef SSL_EXPERIMENTAL_PERDIRCA    if (   (   dc->szCACertificateFile != NULL            && (   sc->szCACertificateFile == NULL                || (   sc->szCACertificateFile != NULL                    && strNE(dc->szCACertificateFile, sc->szCACertificateFile))))        || (   dc->szCACertificatePath != NULL            && (   sc->szCACertificatePath == NULL                || (   sc->szCACertificatePath != NULL                    && strNE(dc->szCACertificatePath, sc->szCACertificatePath)))) ) {        cpCAFile = dc->szCACertificateFile != NULL ?                   dc->szCACertificateFile : sc->szCACertificateFile;        cpCAPath = dc->szCACertificatePath != NULL ?                   dc->szCACertificatePath : sc->szCACertificatePath;        /*           FIXME: This should be...           if (!SSL_load_verify_locations(ssl, cpCAFile, cpCAPath)) {           ...but OpenSSL still doesn't provide this!         */        if (!SSL_CTX_load_verify_locations(ctx, cpCAFile, cpCAPath)) {            ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,                    "Unable to reconfigure verify locations "                    "for client authentication");            return FORBIDDEN;        }        if ((skCAList = ssl_init_FindCAList(r->server, r->pool,                                            cpCAFile, cpCAPath)) == NULL) {            ssl_log(r->server, SSL_LOG_ERROR,                    "Unable to determine list of available "                    "CA certificates for client authentication");            return FORBIDDEN;        }        SSL_set_client_CA_list(ssl, skCAList);        renegotiate = TRUE;        reconfigured_locations = TRUE;        ssl_log(r->server, SSL_LOG_TRACE,                "Changed client verification locations will force renegotiation");    }#endif /* SSL_EXPERIMENTAL_PERDIRCA */#ifdef SSL_CONSERVATIVE     /*      *  SSL renegotiations in conjunction with HTTP     *  requests using the POST method are not supported.     */    if (renegotiate && r->method_number == M_POST) {        ssl_log(r->server, SSL_LOG_ERROR,                "SSL Re-negotiation in conjunction with POST method not supported!");        ssl_log(r->server, SSL_LOG_INFO,                "You have to compile without -DSSL_CONSERVATIVE to enabled support for this.");        return METHOD_NOT_ALLOWED;    }#endif /* SSL_CONSERVATIVE */    /*     * now do the renegotiation if anything was actually reconfigured     */    if (renegotiate) {        /*         * Now we force the SSL renegotation by sending the Hello Request         * message to the client. Here we have to do a workaround: Actually         * OpenSSL returns immediately after sending the Hello Request (the         * intent AFAIK is because the SSL/TLS protocol says it's not a must         * that the client replies to a Hello Request). But because we insist         * on a reply (anything else is an error for us) we have to go to the         * ACCEPT state manually. Using SSL_set_accept_state() doesn't work         * here because it resets too much of the connection.  So we set the         * state explicitly and continue the handshake manually.         */        ssl_log(r->server, SSL_LOG_INFO, "Requesting connection re-negotiation");        if (renegotiate_quick) {            /* perform just a manual re-verification of the peer */            ssl_log(r->server, SSL_LOG_TRACE,                    "Performing quick renegotiation: just re-verifying the peer");            certstack = SSL_get_peer_cert_chain(ssl);            cert = SSL_get_peer_certificate(ssl);            if (certstack == NULL && cert != NULL) {                /* client certificate is in the SSL session cache, but                   there is no chain, since ssl3_get_client_certificate()                   sk_X509_shift()'ed the peer certificate out of the                   chain. So we put it back here for the purpose of quick                   renegotiation. */                certstack = sk_new_null();                sk_X509_push(certstack, cert);            }            if (certstack == NULL || sk_X509_num(certstack) == 0) {                ssl_log(r->server, SSL_LOG_ERROR, "Cannot find peer certificate chain");                return FORBIDDEN;            }            if (cert == NULL)                cert = sk_X509_value(certstack, 0);            if ((certstore = SSL_CTX_get_cert_store(ctx)) == NULL) {                ssl_log(r->server, SSL_LOG_ERROR, "Cannot find certificate storage");                return FORBIDDEN;            }            X509_STORE_CTX_init(&certstorectx, certstore, cert, certstack);            depth = SSL_get_verify_depth(ssl);            if (depth >= 0)                X509_STORE_CTX_set_depth(&certstorectx, depth);            X509_STORE_CTX_set_ex_data(&certstorectx,                SSL_get_ex_data_X509_STORE_CTX_idx(), (char *)ssl);            if (!X509_verify_cert(&certstorectx))                ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR,                         "Re-negotiation verification step failed");            SSL_set_verify_result(ssl, certstorectx.error);            X509_STORE_CTX_cleanup(&certstorectx);            if (SSL_get_peer_cert_chain(ssl) != certstack) {                /* created by us above, so free it */                sk_X509_pop_free(certstack, X509_free);            }            else {                /* X509_free(cert); not necessary AFAIK --rse */            }        }        else {            /* do a full renegotiation */            ssl_log(r->server, SSL_LOG_TRACE,                    "Performing full renegotiation: complete handshake protocol");            if (r->main != NULL)                SSL_set_session_id_context(ssl, (unsigned char *)&(r->main), sizeof(r->main));            else                SSL_set_session_id_context(ssl, (unsigned char *)&r, sizeof(r));#ifndef SSL_CONSERVATIVE            ssl_io_suck(r, ssl);#endif            SSL_renegotiate(ssl);            SSL_do_handshake(ssl);            if (SSL_get_state(ssl) != SSL_ST_OK) {                ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation request failed");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -