diff --git a/configuration.c b/configuration.c index ff3409f..1c49773 100644 --- a/configuration.c +++ b/configuration.c @@ -30,6 +30,7 @@ #define CFG_CIPHERS "ciphers" #define CFG_SSL_ENGINE "ssl-engine" #define CFG_PREFER_SERVER_CIPHERS "prefer-server-ciphers" +#define CFG_NAMED_CURVE "named-curve" #define CFG_BACKEND "backend" #define CFG_FRONTEND "frontend" #define CFG_WORKERS "workers" @@ -123,6 +124,7 @@ stud_config * config_new (void) { r->NCORES = 1; r->CERT_FILE = NULL; r->CIPHER_SUITE = NULL; + r->NAMED_CURVE = NULL; r->ENGINE = NULL; r->BACKLOG = 100; @@ -160,6 +162,7 @@ void config_destroy (stud_config *cfg) { if (cfg->BACK_PORT != NULL) free(cfg->BACK_PORT); if (cfg->CERT_FILE != NULL) free(cfg->CERT_FILE); if (cfg->CIPHER_SUITE != NULL) free(cfg->CIPHER_SUITE); + if (cfg->NAMED_CURVE != NULL) free(cfg->NAMED_CURVE); if (cfg->ENGINE != NULL) free(cfg->ENGINE); #ifdef USE_SHARED_CACHE @@ -538,7 +541,11 @@ void config_param_validate (char *k, char *v, stud_config *cfg, char *file, int config_assign_str(&cfg->CIPHER_SUITE, v); } } - else if (strcmp(k, CFG_SSL_ENGINE) == 0) { + else if (strcmp(k, CFG_NAMED_CURVE) == 0) { + if (v != NULL && strlen(v) > 0) { + config_assign_str(&cfg->NAMED_CURVE, v); + } + } else if (strcmp(k, CFG_SSL_ENGINE) == 0) { if (v != NULL && strlen(v) > 0) { config_assign_str(&cfg->ENGINE, v); } @@ -853,6 +860,7 @@ void config_print_usage_fd (char *prog, stud_config *cfg, FILE *out) { fprintf(out, " -c --ciphers=SUITE Sets allowed ciphers (Default: \"%s\")\n", config_disp_str(cfg->CIPHER_SUITE)); fprintf(out, " -e --ssl-engine=NAME Sets OpenSSL engine (Default: \"%s\")\n", config_disp_str(cfg->ENGINE)); fprintf(out, " -O --prefer-server-ciphers Prefer server list order\n"); + fprintf(out, " -N --named-curve=NAME Named curve for ECDH (Default: prime256v1, see openssl ecparams -list_curves)\n"); fprintf(out, "\n"); fprintf(out, "SOCKET:\n"); fprintf(out, "\n"); @@ -1110,6 +1118,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { { "ssl", 0, &ssl, 1}, { CFG_CIPHERS, 1, NULL, 'c' }, { CFG_PREFER_SERVER_CIPHERS, 0, NULL, 'O' }, + { CFG_NAMED_CURVE, 1, NULL, 'N' }, { CFG_BACKEND, 1, NULL, 'b' }, { CFG_FRONTEND, 1, NULL, 'f' }, { CFG_WORKERS, 1, NULL, 'n' }, @@ -1141,7 +1150,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { int option_index = 0; c = getopt_long( argc, argv, - "c:e:Ob:f:n:B:C:U:P:M:k:r:u:g:qstVh", + "c:N:e:Ob:f:n:B:C:U:P:M:k:r:u:g:qstVh", long_options, &option_index ); @@ -1167,6 +1176,9 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) { case 'c': config_param_validate(CFG_CIPHERS, optarg, cfg, NULL, 0); break; + case 'N': + config_param_validate(CFG_NAMED_CURVE, optarg, cfg, NULL, 0); + break; case 'e': config_param_validate(CFG_SSL_ENGINE, optarg, cfg, NULL, 0); break; diff --git a/configuration.h b/configuration.h index 44be7f6..80040ba 100644 --- a/configuration.h +++ b/configuration.h @@ -41,6 +41,7 @@ struct __stud_config { long NCORES; char *CERT_FILE; char *CIPHER_SUITE; + char *NAMED_CURVE; char *ENGINE; int BACKLOG; #ifdef USE_SHARED_CACHE diff --git a/stud.c b/stud.c index 0ed6581..62aa14b 100644 --- a/stud.c +++ b/stud.c @@ -225,18 +225,36 @@ static int init_dh(SSL_CTX *ctx, const char *cert) { LOG("{core} DH initialized with %d bit key\n", 8*DH_size(dh)); DH_free(dh); + return 0; +} + #ifndef OPENSSL_NO_EC -#ifdef NID_X9_62_prime256v1 +static int init_ecdh(SSL_CTX *ctx, const char *named_curve) { EC_KEY *ecdh = NULL; - ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + int nid = 0; + + if (named_curve) { + nid = OBJ_sn2nid(named_curve); + } else { + nid = OBJ_sn2nid("prime256v1"); + } + if (nid == 0) { + LOG("{core} ECDH initialization failed: unknown curve %s\n", named_curve); + return -1; + } + ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) { + ERR("{core} ECDH initialization failed for curve %s\n", named_curve); + return -1; + } SSL_CTX_set_tmp_ecdh(ctx,ecdh); EC_KEY_free(ecdh); - LOG("{core} ECDH Initialized with NIST P-256\n"); -#endif /* NID_X9_62_prime256v1 */ -#endif /* OPENSSL_NO_EC */ + LOG("{core} ECDH initialized with %s\n", named_curve); - return 0; + return 0; } +#endif /* OPENSSL_NO_EC */ + #endif /* OPENSSL_NO_DH */ /* This callback function is executed while OpenSSL processes the SSL @@ -572,6 +590,9 @@ SSL_CTX * init_openssl() { #ifndef OPENSSL_NO_DH init_dh(ctx, CONFIG->CERT_FILE); +#ifndef OPENSSL_NO_EC + init_ecdh(ctx, CONFIG->NAMED_CURVE); +#endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_NO_DH */ if (CONFIG->ENGINE) {