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:
Tatsuhiro Tsujikawa 2013-08-30 22:07:42 +09:00
parent e818d098ec
commit aea036c9d4
4 changed files with 47 additions and 2 deletions

View File

@ -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;
} }

View File

@ -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, ':');

View File

@ -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;

View File

@ -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);