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

📄 ssl_engine_kernel.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 5 页
字号:
 * |    multiple transactions, it must be signed each time it is used. * | * |    RSA key generation is a time-consuming process. In many cases, a * |    low-priority process can be assigned the task of key generation. * |    Whenever a new key is completed, the existing temporary key can be * |    replaced with the new one. * * XXX: base on comment above, if thread support is enabled, * we should spawn a low-priority thread to generate new keys * on the fly. * * So we generated 512 and 1024 bit temporary keys on startup * which we now just hand out on demand.... */RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen){    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);    SSLModConfigRec *mc = myModConfig(c->base_server);    int idx;    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,                  "handing out temporary %d bit RSA key", keylen);    /* doesn't matter if export flag is on,     * we won't be asked for keylen > 512 in that case.     * if we are asked for a keylen > 1024, it is too expensive     * to generate on the fly.     * XXX: any reason not to generate 2048 bit keys at startup?     */    switch (keylen) {      case 512:        idx = SSL_TMP_KEY_RSA_512;        break;      case 1024:      default:        idx = SSL_TMP_KEY_RSA_1024;    }    return (RSA *)mc->pTmpKeys[idx];}/* * Hand out the already generated DH parameters... */DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen){    conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);    SSLModConfigRec *mc = myModConfig(c->base_server);    int idx;    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,                  "handing out temporary %d bit DH key", keylen);    switch (keylen) {      case 512:        idx = SSL_TMP_KEY_DH_512;        break;      case 1024:      default:        idx = SSL_TMP_KEY_DH_1024;    }    return (DH *)mc->pTmpKeys[idx];}/* * This OpenSSL callback function is called when OpenSSL * does client authentication and verifies the certificate chain. */int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx){    /* Get Apache context back through OpenSSL context */    SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,                                          SSL_get_ex_data_X509_STORE_CTX_idx());    conn_rec *conn      = (conn_rec *)SSL_get_app_data(ssl);    server_rec *s       = conn->base_server;    request_rec *r      = (request_rec *)SSL_get_app_data2(ssl);    SSLSrvConfigRec *sc = mySrvConfig(s);    SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;    SSLConnRec *sslconn = myConnConfig(conn);    modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);    /* Get verify ingredients */    int errnum   = X509_STORE_CTX_get_error(ctx);    int errdepth = X509_STORE_CTX_get_error_depth(ctx);    int depth, verify;    /*     * Log verification information     */    if (s->loglevel >= APLOG_DEBUG) {        X509 *cert  = X509_STORE_CTX_get_current_cert(ctx);        char *sname = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);        char *iname = X509_NAME_oneline(X509_get_issuer_name(cert),  NULL, 0);        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                     "Certificate Verification: "                     "depth: %d, subject: %s, issuer: %s",                     errdepth,                     sname ? sname : "-unknown-",                     iname ? iname : "-unknown-");        if (sname) {            modssl_free(sname);        }        if (iname) {            modssl_free(iname);        }    }    /*     * Check for optionally acceptable non-verifiable issuer situation     */    if (dc && (dc->nVerifyClient != SSL_CVERIFY_UNSET)) {        verify = dc->nVerifyClient;    }    else {        verify = mctx->auth.verify_mode;    }    if (verify == SSL_CVERIFY_NONE) {        /*         * SSLProxyVerify is either not configured or set to "none".         * (this callback doesn't happen in the server context if SSLVerify         *  is not configured or set to "none")         */        return TRUE;    }    if (ssl_verify_error_is_optional(errnum) &&        (verify == SSL_CVERIFY_OPTIONAL_NO_CA))    {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,                     "Certificate Verification: Verifiable Issuer is "                     "configured as optional, therefore we're accepting "                     "the certificate");        sslconn->verify_info = "GENEROUS";        ok = TRUE;    }    /*     * Additionally perform CRL-based revocation checks     */    if (ok) {        if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) {            errnum = X509_STORE_CTX_get_error(ctx);        }    }    /*     * If we already know it's not ok, log the real reason     */    if (!ok) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                     "Certificate Verification: Error (%d): %s",                     errnum, X509_verify_cert_error_string(errnum));        if (sslconn->client_cert) {            X509_free(sslconn->client_cert);            sslconn->client_cert = NULL;        }        sslconn->client_dn = NULL;        sslconn->verify_error = X509_verify_cert_error_string(errnum);    }    /*     * Finally check the depth of the certificate verification     */    if (dc && (dc->nVerifyDepth != UNSET)) {        depth = dc->nVerifyDepth;    }    else {        depth = mctx->auth.verify_depth;    }    if (errdepth > depth) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                     "Certificate Verification: Certificate Chain too long "                     "(chain has %d certificates, but maximum allowed are "                     "only %d)",                     errdepth, depth);        errnum = X509_V_ERR_CERT_CHAIN_TOO_LONG;        sslconn->verify_error = X509_verify_cert_error_string(errnum);        ok = FALSE;    }    /*     * And finally signal OpenSSL the (perhaps changed) state     */    return ok;}int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c){    server_rec *s       = c->base_server;    SSLSrvConfigRec *sc = mySrvConfig(s);    SSLConnRec *sslconn = myConnConfig(c);    modssl_ctx_t *mctx  = myCtxConfig(sslconn, sc);    X509_OBJECT obj;    X509_NAME *subject, *issuer;    X509 *cert;    X509_CRL *crl;    EVP_PKEY *pubkey;    int i, n, rc;    /*     * Unless a revocation store for CRLs was created we     * cannot do any CRL-based verification, of course.     */    if (!mctx->crl) {        return ok;    }    /*     * Determine certificate ingredients in advance     */    cert    = X509_STORE_CTX_get_current_cert(ctx);    subject = X509_get_subject_name(cert);    issuer  = X509_get_issuer_name(cert);    /*     * OpenSSL provides the general mechanism to deal with CRLs but does not     * use them automatically when verifying certificates, so we do it     * explicitly here. We will check the CRL for the currently checked     * certificate, if there is such a CRL in the store.     *     * We come through this procedure for each certificate in the certificate     * chain, starting with the root-CA's certificate. At each step we've to     * both verify the signature on the CRL (to make sure it's a valid CRL)     * and it's revocation list (to make sure the current certificate isn't     * revoked).  But because to check the signature on the CRL we need the     * public key of the issuing CA certificate (which was already processed     * one round before), we've a little problem. But we can both solve it and     * at the same time optimize the processing by using the following     * verification scheme (idea and code snippets borrowed from the GLOBUS     * project):     *     * 1. We'll check the signature of a CRL in each step when we find a CRL     *    through the _subject_ name of the current certificate. This CRL     *    itself will be needed the first time in the next round, of course.     *    But we do the signature processing one round before this where the     *    public key of the CA is available.     *     * 2. We'll check the revocation list of a CRL in each step when     *    we find a CRL through the _issuer_ name of the current certificate.     *    This CRLs signature was then already verified one round before.     *     * This verification scheme allows a CA to revoke its own certificate as     * well, of course.     */    /*     * Try to retrieve a CRL corresponding to the _subject_ of     * the current certificate in order to verify it's integrity.     */    memset((char *)&obj, 0, sizeof(obj));    rc = SSL_X509_STORE_lookup(mctx->crl,                               X509_LU_CRL, subject, &obj);    crl = obj.data.crl;    if ((rc > 0) && crl) {        /*         * Log information about CRL         * (A little bit complicated because of ASN.1 and BIOs...)         */        if (s->loglevel >= APLOG_DEBUG) {            char buff[512]; /* should be plenty */            BIO *bio = BIO_new(BIO_s_mem());            BIO_printf(bio, "CA CRL: Issuer: ");            X509_NAME_print(bio, issuer, 0);            BIO_printf(bio, ", lastUpdate: ");            ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl));            BIO_printf(bio, ", nextUpdate: ");            ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl));            n = BIO_read(bio, buff, sizeof(buff) - 1);            buff[n] = '\0';            BIO_free(bio);            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", buff);        }        /*         * Verify the signature on this CRL         */        pubkey = X509_get_pubkey(cert);        rc = X509_CRL_verify(crl, pubkey);#ifdef OPENSSL_VERSION_NUMBER        /* Only refcounted in OpenSSL */        if (pubkey)            EVP_PKEY_free(pubkey);#endif        if (rc <= 0) {            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                         "Invalid signature on CRL");            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);            X509_OBJECT_free_contents(&obj);            return FALSE;        }        /*         * Check date of CRL to make sure it's not expired         */        i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));        if (i == 0) {            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                         "Found CRL has invalid nextUpdate field");            X509_STORE_CTX_set_error(ctx,                                     X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);            X509_OBJECT_free_contents(&obj);            return FALSE;        }        if (i < 0) {            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                         "Found CRL is expired - "                         "revoking all certificates until you get updated CRL");            X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED);            X509_OBJECT_free_contents(&obj);            return FALSE;        }        X509_OBJECT_free_contents(&obj);    }    /*     * Try to retrieve a CRL corresponding to the _issuer_ of     * the current certificate in order to check for revocation.     */    memset((char *)&obj, 0, sizeof(obj));    rc = SSL_X509_STORE_lookup(mctx->crl,                               X509_LU_CRL, issuer, &obj);    crl = obj.data.crl;    if ((rc > 0) && crl) {        /*         * Check if the current certificate is revoked by this CRL         */        n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));        for (i = 0; i < n; i++) {            X509_REVOKED *revoked =                sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);

⌨️ 快捷键说明

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