📄 ssl_engine_init.c
字号:
if (!(protocol & SSL_PROTOCOL_SSLV2)) { SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); } if (!(protocol & SSL_PROTOCOL_SSLV3)) { SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); } if (!(protocol & SSL_PROTOCOL_TLSV1)) { SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); }#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE { SSLSrvConfigRec *sc = mySrvConfig(s); if (sc->cipher_server_pref == TRUE) { SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } }#endif SSL_CTX_set_app_data(ctx, s); /* * Configure additional context ingredients */ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* * Disallow a session from being resumed during a renegotiation, * so that an acceptable cipher suite can be negotiated. */ SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);#endif}static void ssl_init_ctx_session_cache(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ SSL_CTX *ctx = mctx->ssl_ctx; SSLModConfigRec *mc = myModConfig(s); long cache_mode = SSL_SESS_CACHE_OFF; if (mc->nSessionCacheMode != SSL_SCMODE_NONE) { /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL * to ignore process local-caching and * to always get/set/delete sessions using mod_ssl's callbacks. */ cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL; } SSL_CTX_set_session_cache_mode(ctx, cache_mode); SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry); SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry); SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);}static void ssl_init_ctx_callbacks(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ SSL_CTX *ctx = mctx->ssl_ctx; SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); if (s->loglevel >= APLOG_DEBUG) { /* this callback only logs if LogLevel >= info */ SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); }}static void ssl_init_ctx_verify(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ SSL_CTX *ctx = mctx->ssl_ctx; int verify = SSL_VERIFY_NONE; STACK_OF(X509_NAME) *ca_list; if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) { mctx->auth.verify_mode = SSL_CVERIFY_NONE; } if (mctx->auth.verify_depth == UNSET) { mctx->auth.verify_depth = 1; } /* * Configure callbacks for SSL context */ if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) { verify |= SSL_VERIFY_PEER_STRICT; } if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) || (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) { verify |= SSL_VERIFY_PEER; } SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify); /* * Configure Client Authentication details */ if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Configuring client authentication"); if (!SSL_CTX_load_verify_locations(ctx, MODSSL_PCHAR_CAST mctx->auth.ca_cert_file, MODSSL_PCHAR_CAST mctx->auth.ca_cert_path)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to configure verify locations " "for client authentication"); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) { ca_list = ssl_init_FindCAList(s, ptemp, mctx->pks->ca_name_file, mctx->pks->ca_name_path); } else ca_list = ssl_init_FindCAList(s, ptemp, mctx->auth.ca_cert_file, mctx->auth.ca_cert_path); if (!ca_list) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to determine list of acceptable " "CA certificates for client authentication"); ssl_die(); } SSL_CTX_set_client_CA_list(ctx, (STACK *)ca_list); } /* * Give a warning when no CAs were configured but client authentication * should take place. This cannot work. */ if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) { ca_list = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx); if (sk_X509_NAME_num(ca_list) == 0) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "Init: Oops, you want to request client " "authentication, but no CAs are known for " "verification!? [Hint: SSLCACertificate*]"); } }}static void ssl_init_ctx_cipher_suite(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ SSL_CTX *ctx = mctx->ssl_ctx; const char *suite = mctx->auth.cipher_suite; /* * Configure SSL Cipher Suite */ if (!suite) { return; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Configuring permitted SSL ciphers [%s]", suite); if (!SSL_CTX_set_cipher_list(ctx, MODSSL_PCHAR_CAST suite)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to configure permitted SSL ciphers"); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); }}static void ssl_init_ctx_crl(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ /* * Configure Certificate Revocation List (CRL) Details */ if (!(mctx->crl_file || mctx->crl_path)) { return; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Configuring certificate revocation facility"); mctx->crl = SSL_X509_STORE_create((char *)mctx->crl_file, (char *)mctx->crl_path); if (!mctx->crl) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to configure X.509 CRL storage " "for certificate revocation"); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); }}static void ssl_init_ctx_cert_chain(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ BOOL skip_first = FALSE; int i, n; const char *chain = mctx->cert_chain; /* * Optionally configure extra server certificate chain certificates. * This is usually done by OpenSSL automatically when one of the * server cert issuers are found under SSLCACertificatePath or in * SSLCACertificateFile. But because these are intended for client * authentication it can conflict. For instance when you use a * Global ID server certificate you've to send out the intermediate * CA certificate, too. When you would just configure this with * SSLCACertificateFile and also use client authentication mod_ssl * would accept all clients also issued by this CA. Obviously this * isn't what we want in this situation. So this feature here exists * to allow one to explicity configure CA certificates which are * used only for the server certificate chain. */ if (!chain) { return; } for (i = 0; (i < SSL_AIDX_MAX) && mctx->pks->cert_files[i]; i++) { if (strEQ(mctx->pks->cert_files[i], chain)) { skip_first = TRUE; break; } } n = SSL_CTX_use_certificate_chain(mctx->ssl_ctx, (char *)chain, skip_first, NULL); if (n < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Failed to configure CA certificate chain!"); ssl_die(); } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Configuring server certificate chain " "(%d CA certificate%s)", n, n == 1 ? "" : "s");}static void ssl_init_ctx(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ ssl_init_ctx_protocol(s, p, ptemp, mctx); ssl_init_ctx_session_cache(s, p, ptemp, mctx); ssl_init_ctx_callbacks(s, p, ptemp, mctx); ssl_init_ctx_verify(s, p, ptemp, mctx); ssl_init_ctx_cipher_suite(s, p, ptemp, mctx); ssl_init_ctx_crl(s, p, ptemp, mctx); if (mctx->pks) { /* XXX: proxy support? */ ssl_init_ctx_cert_chain(s, p, ptemp, mctx); }}static int ssl_server_import_cert(server_rec *s, modssl_ctx_t *mctx, const char *id, int idx){ SSLModConfigRec *mc = myModConfig(s); ssl_asn1_t *asn1; MODSSL_D2I_X509_CONST unsigned char *ptr; const char *type = ssl_asn1_keystr(idx); X509 *cert; if (!(asn1 = ssl_asn1_table_get(mc->tPublicCert, id))) { return FALSE; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Configuring %s server certificate", type); ptr = asn1->cpData; if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to import %s server certificate", type); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to configure %s server certificate", type); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } mctx->pks->certs[idx] = cert; return TRUE;}static int ssl_server_import_key(server_rec *s, modssl_ctx_t *mctx, const char *id, int idx){ SSLModConfigRec *mc = myModConfig(s); ssl_asn1_t *asn1; MODSSL_D2I_PrivateKey_CONST unsigned char *ptr; const char *type = ssl_asn1_keystr(idx); int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA; EVP_PKEY *pkey; if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) { return FALSE; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Configuring %s server private key", type); ptr = asn1->cpData; if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to import %s server private key", type); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Unable to configure %s server private key", type); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } /* * XXX: wonder if this is still needed, this is old todo doc. * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html) */ if ((pkey_type == EVP_PKEY_DSA) && mctx->pks->certs[idx]) { EVP_PKEY *pubkey = X509_get_pubkey(mctx->pks->certs[idx]); if (pubkey && EVP_PKEY_missing_parameters(pubkey)) { EVP_PKEY_copy_parameters(pubkey, pkey); ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Copying DSA parameters from private key to certificate"); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); EVP_PKEY_free(pubkey); } } mctx->pks->keys[idx] = pkey; return TRUE;}static void ssl_check_public_cert(server_rec *s, apr_pool_t *ptemp, X509 *cert, int type){ int is_ca, pathlen; char *cn; if (!cert) { return; } /* * Some information about the certificate(s) */ if (SSL_X509_isSGC(cert)) { ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%s server certificate enables " "Server Gated Cryptography (SGC)", ssl_asn1_keystr(type)); } if (SSL_X509_getBC(cert, &is_ca, &pathlen)) { if (is_ca) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "%s server certificate is a CA certificate " "(BasicConstraints: CA == TRUE !?)", ssl_asn1_keystr(type)); } if (pathlen > 0) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "%s server certificate is not a leaf certificate " "(BasicConstraints: pathlen == %d > 0 !?)", ssl_asn1_keystr(type), pathlen); } } if (SSL_X509_getCN(ptemp, cert, &cn)) { int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -