Security::ServerOptions::ServerOptions(const Security::ServerOptions &s) :
dh(s.dh),
dhParamsFile(s.dhParamsFile),
- eecdhCurve(s.eecdhCurve)
+ eecdhCurve(s.eecdhCurve),
+ parsedDhParams(s.parsedDhParams)
{
}
}
}
+ loadDhParams();
+
} else if (strncmp(token, "dhparams=", 9) == 0) {
if (!eecdhCurve.isEmpty()) {
debugs(83, DBG_PARSE_NOTE(1), "UPGRADE WARNING: EECDH settings in tls-dh= override dhparams=");
dh.append(token + 9);
dhParamsFile = dh;
+ loadDhParams();
+
} else {
// parse generic TLS options
Security::PeerOptions::parse(token);
}
void
-Security::ServerOptions::updateContextEecdh(Security::ContextPointer &ctx)
+Security::ServerOptions::loadDhParams()
{
- if (eecdhCurve.isEmpty())
+ if (dhParamsFile.isEmpty())
return;
- debugs(83, 9, "Setting Ephemeral ECDH curve to " << eecdhCurve << ".");
-
-#if USE_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_ECDH)
- int nid = OBJ_sn2nid(eecdhCurve.c_str());
- if (!nid) {
- debugs(83, DBG_CRITICAL, "ERROR: Unknown EECDH curve '" << eecdhCurve << "'");
- return;
+#if USE_OPENSSL
+ DH *dhp = nullptr;
+ if (FILE *in = fopen(dhParamsFile.c_str(), "r")) {
+ dhp = PEM_read_DHparams(in, NULL, NULL, NULL);
+ fclose(in);
}
- auto ecdh = EC_KEY_new_by_curve_name(nid);
- if (!ecdh) {
- auto ssl_error = ERR_get_error();
- debugs(83, DBG_CRITICAL, "ERROR: Unable to configure Ephemeral ECDH: " << ERR_error_string(ssl_error, NULL));
+ if (!dhp) {
+ debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << dhParamsFile << "'");
return;
}
- if (SSL_CTX_set_tmp_ecdh(ctx, ecdh) != 0) {
- auto ssl_error = ERR_get_error();
- debugs(83, DBG_CRITICAL, "ERROR: Unable to set Ephemeral ECDH: " << ERR_error_string(ssl_error, NULL));
+ int codes;
+ if (DH_check(dhp, &codes) == 0) {
+ if (codes) {
+ debugs(83, DBG_IMPORTANT, "WARNING: Failed to verify DH parameters '" << dhParamsFile << "' (" << std::hex << codes << ")");
+ DH_free(dhp);
+ dhp = nullptr;
+ }
}
- EC_KEY_free(ecdh);
+
+ parsedDhParams.reset(dhp);
+#endif
+}
+
+void
+Security::ServerOptions::updateContextEecdh(Security::ContextPointer &ctx)
+{
+ // set Elliptic Curve details into the server context
+ if (!eecdhCurve.isEmpty()) {
+ debugs(83, 9, "Setting Ephemeral ECDH curve to " << eecdhCurve << ".");
+
+#if USE_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_ECDH)
+ int nid = OBJ_sn2nid(eecdhCurve.c_str());
+ if (!nid) {
+ debugs(83, DBG_CRITICAL, "ERROR: Unknown EECDH curve '" << eecdhCurve << "'");
+ return;
+ }
+
+ auto ecdh = EC_KEY_new_by_curve_name(nid);
+ if (!ecdh) {
+ auto ssl_error = ERR_get_error();
+ debugs(83, DBG_CRITICAL, "ERROR: Unable to configure Ephemeral ECDH: " << ERR_error_string(ssl_error, NULL));
+ return;
+ }
+
+ if (SSL_CTX_set_tmp_ecdh(ctx, ecdh) != 0) {
+ auto ssl_error = ERR_get_error();
+ debugs(83, DBG_CRITICAL, "ERROR: Unable to set Ephemeral ECDH: " << ERR_error_string(ssl_error, NULL));
+ }
+ EC_KEY_free(ecdh);
+
#else
- debugs(83, DBG_CRITICAL, "ERROR: EECDH is not available in this build." <<
- " Please link against OpenSSL>=0.9.8 and ensure OPENSSL_NO_ECDH is not set.");
+ debugs(83, DBG_CRITICAL, "ERROR: EECDH is not available in this build." <<
+ " Please link against OpenSSL>=0.9.8 and ensure OPENSSL_NO_ECDH is not set.");
+#endif
+ }
+
+ // set DH parameters into the server context
+#if USE_OPENSSL
+ if (parsedDhParams.get()) {
+ SSL_CTX_set_tmp_dh(ctx, parsedDhParams.get());
+ }
#endif
}
ssl_ex_index_ssl_validation_counter = SSL_get_ex_new_index(0, (void *) "ssl_validation_counter", NULL, NULL, &ssl_free_int);
}
-DH *
-Ssl::readDHParams(const char *dhfile)
-{
- FILE *in = fopen(dhfile, "r");
- DH *dh = NULL;
- int codes;
-
- if (in) {
- dh = PEM_read_DHparams(in, NULL, NULL, NULL);
- fclose(in);
- }
-
- if (!dh)
- debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << dhfile << "'");
- else if (dh && DH_check(dh, &codes) == 0) {
- if (codes) {
- debugs(83, DBG_IMPORTANT, "WARNING: Failed to verify DH parameters '" << dhfile << "' (" << std::hex << codes << ")");
- DH_free(dh);
- dh = NULL;
- }
- }
- return dh;
-}
-
#if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
static void
ssl_info_cb(const SSL *ssl, int where, int ret)
SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
}
- if (port.dhParams.get()) {
- SSL_CTX_set_tmp_dh(sslContext, port.dhParams.get());
- }
-
if (port.secure.parsedFlags & SSL_FLAG_DONT_VERIFY_DOMAIN)
SSL_CTX_set_ex_data(sslContext, ssl_ctx_ex_index_dont_verify_domain, (void *) -1);