nghttpx: Support ECDHE and DHE cipher suites
Use --dh-param-file option to specify a file including DH parameters in PEM format. For example, you can create DH parameters with 1024 bit key using following command: $ openssl dhparam -outform PEM -out dhparam.pem 1024
This commit is contained in:
parent
e818d098ec
commit
aea036c9d4
10
src/shrpx.cc
10
src/shrpx.cc
|
@ -529,6 +529,10 @@ void print_help(std::ostream& out)
|
||||||
<< " Explicitly set the content of the TLS SNI\n"
|
<< " Explicitly set the content of the TLS SNI\n"
|
||||||
<< " extension. This will default to the backend\n"
|
<< " extension. This will default to the backend\n"
|
||||||
<< " HOST name.\n"
|
<< " HOST name.\n"
|
||||||
|
<< " --dh-param-file=<PATH>\n"
|
||||||
|
<< " Path to file that contains DH parameters in\n"
|
||||||
|
<< " PEM format. Without this option, DHE cipher\n"
|
||||||
|
<< " suites are not available."
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< " HTTP/2.0 and SPDY:\n"
|
<< " HTTP/2.0 and SPDY:\n"
|
||||||
<< " -c, --spdy-max-concurrent-streams=<NUM>\n"
|
<< " -c, --spdy-max-concurrent-streams=<NUM>\n"
|
||||||
|
@ -660,6 +664,7 @@ int main(int argc, char **argv)
|
||||||
{"frontend-no-tls", no_argument, &flag, 29},
|
{"frontend-no-tls", no_argument, &flag, 29},
|
||||||
{"backend-tls-sni-field", required_argument, &flag, 31},
|
{"backend-tls-sni-field", required_argument, &flag, 31},
|
||||||
{"honor-cipher-order", no_argument, &flag, 32},
|
{"honor-cipher-order", no_argument, &flag, 32},
|
||||||
|
{"dh-param-file", required_argument, &flag, 33},
|
||||||
{nullptr, 0, nullptr, 0 }
|
{nullptr, 0, nullptr, 0 }
|
||||||
};
|
};
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
|
@ -839,7 +844,10 @@ int main(int argc, char **argv)
|
||||||
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_HONOR_CIPHER_ORDER,
|
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_HONOR_CIPHER_ORDER,
|
||||||
"yes"));
|
"yes"));
|
||||||
break;
|
break;
|
||||||
|
case 33:
|
||||||
|
// --dh-param-file
|
||||||
|
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_DH_PARAM_FILE, optarg));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace shrpx {
|
||||||
const char SHRPX_OPT_PRIVATE_KEY_FILE[] = "private-key-file";
|
const char SHRPX_OPT_PRIVATE_KEY_FILE[] = "private-key-file";
|
||||||
const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[] = "private-key-passwd-file";
|
const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[] = "private-key-passwd-file";
|
||||||
const char SHRPX_OPT_CERTIFICATE_FILE[] = "certificate-file";
|
const char SHRPX_OPT_CERTIFICATE_FILE[] = "certificate-file";
|
||||||
|
const char SHRPX_OPT_DH_PARAM_FILE[] = "dh-param-file";
|
||||||
const char SHRPX_OPT_SUBCERT[] = "subcert";
|
const char SHRPX_OPT_SUBCERT[] = "subcert";
|
||||||
|
|
||||||
const char SHRPX_OPT_BACKEND[] = "backend";
|
const char SHRPX_OPT_BACKEND[] = "backend";
|
||||||
|
@ -296,6 +297,8 @@ int parse_config(const char *opt, const char *optarg)
|
||||||
set_config_str(&mod_config()->private_key_passwd, passwd.c_str());
|
set_config_str(&mod_config()->private_key_passwd, passwd.c_str());
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_CERTIFICATE_FILE)) {
|
} else if(util::strieq(opt, SHRPX_OPT_CERTIFICATE_FILE)) {
|
||||||
set_config_str(&mod_config()->cert_file, optarg);
|
set_config_str(&mod_config()->cert_file, optarg);
|
||||||
|
} else if(util::strieq(opt, SHRPX_OPT_DH_PARAM_FILE)) {
|
||||||
|
set_config_str(&mod_config()->dh_param_file, optarg);
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_SUBCERT)) {
|
} else if(util::strieq(opt, SHRPX_OPT_SUBCERT)) {
|
||||||
// Private Key file and certificate file separated by ':'.
|
// Private Key file and certificate file separated by ':'.
|
||||||
const char *sp = strchr(optarg, ':');
|
const char *sp = strchr(optarg, ':');
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct CertLookupTree;
|
||||||
extern const char SHRPX_OPT_PRIVATE_KEY_FILE[];
|
extern const char SHRPX_OPT_PRIVATE_KEY_FILE[];
|
||||||
extern const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[];
|
extern const char SHRPX_OPT_PRIVATE_KEY_PASSWD_FILE[];
|
||||||
extern const char SHRPX_OPT_CERTIFICATE_FILE[];
|
extern const char SHRPX_OPT_CERTIFICATE_FILE[];
|
||||||
|
extern const char SHRPX_OPT_DH_PARAM_FILE[];
|
||||||
extern const char SHRPX_OPT_SUBCERT[];
|
extern const char SHRPX_OPT_SUBCERT[];
|
||||||
extern const char SHRPX_OPT_BACKEND[];
|
extern const char SHRPX_OPT_BACKEND[];
|
||||||
extern const char SHRPX_OPT_FRONTEND[];
|
extern const char SHRPX_OPT_FRONTEND[];
|
||||||
|
@ -105,6 +106,7 @@ struct Config {
|
||||||
char *private_key_file;
|
char *private_key_file;
|
||||||
char *private_key_passwd;
|
char *private_key_passwd;
|
||||||
char *cert_file;
|
char *cert_file;
|
||||||
|
char *dh_param_file;
|
||||||
SSL_CTX *default_ssl_ctx;
|
SSL_CTX *default_ssl_ctx;
|
||||||
ssl::CertLookupTree *cert_tree;
|
ssl::CertLookupTree *cert_tree;
|
||||||
bool verify_client;
|
bool verify_client;
|
||||||
|
|
|
@ -138,7 +138,9 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||||
}
|
}
|
||||||
SSL_CTX_set_options(ssl_ctx,
|
SSL_CTX_set_options(ssl_ctx,
|
||||||
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION |
|
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
||||||
|
SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_DH_USE |
|
||||||
|
SSL_OP_NO_TICKET);
|
||||||
|
|
||||||
const unsigned char sid_ctx[] = "shrpx";
|
const unsigned char sid_ctx[] = "shrpx";
|
||||||
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx)-1);
|
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx)-1);
|
||||||
|
@ -155,6 +157,36 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use P-256, which is sufficiently secure at the time of this
|
||||||
|
// writing.
|
||||||
|
auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||||
|
if(ecdh == nullptr) {
|
||||||
|
LOG(FATAL) << "EC_KEY_new_by_curv_name failed: "
|
||||||
|
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||||
|
DIE();
|
||||||
|
}
|
||||||
|
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
|
||||||
|
EC_KEY_free(ecdh);
|
||||||
|
|
||||||
|
if(get_config()->dh_param_file) {
|
||||||
|
// Read DH parameters from file
|
||||||
|
auto bio = BIO_new_file(get_config()->dh_param_file, "r");
|
||||||
|
if(bio == nullptr) {
|
||||||
|
LOG(FATAL) << "BIO_new_file() failed: "
|
||||||
|
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||||
|
DIE();
|
||||||
|
}
|
||||||
|
auto dh = PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
|
||||||
|
if(dh == nullptr) {
|
||||||
|
LOG(FATAL) << "PEM_read_bio_DHparams() failed: "
|
||||||
|
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||||
|
DIE();
|
||||||
|
}
|
||||||
|
SSL_CTX_set_tmp_dh(ssl_ctx, dh);
|
||||||
|
DH_free(dh);
|
||||||
|
BIO_free(bio);
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||||
|
|
Loading…
Reference in New Issue