comparison src/event/ngx_event_openssl.c @ 6553:2014ed60f17f

SSL: support for multiple curves (ticket #885). OpenSSL 1.0.2+ allows configuring a curve list instead of a single curve previously supported. This allows use of different curves depending on what client supports (as available via the elliptic_curves extension), and also allows use of different curves in an ECDHE key exchange and in the ECDSA certificate. The special value "auto" was introduced (now the default for ssl_ecdh_curve), which means "use an internal list of curves as available in the OpenSSL library used". For versions prior to OpenSSL 1.0.2 it maps to "prime256v1" as previously used. The default in 1.0.2b+ prefers prime256v1 as well (and X25519 in OpenSSL 1.1.0+). As client vs. server preference of curves is controlled by the same option as used for ciphers (SSL_OP_CIPHER_SERVER_PREFERENCE), the ssl_prefer_server_ciphers directive now controls both.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 19 May 2016 14:46:32 +0300
parents addd98357629
children 1aa9650a8154
comparison
equal deleted inserted replaced
6552:addd98357629 6553:2014ed60f17f
1061 ngx_int_t 1061 ngx_int_t
1062 ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name) 1062 ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
1063 { 1063 {
1064 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL 1064 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
1065 #ifndef OPENSSL_NO_ECDH 1065 #ifndef OPENSSL_NO_ECDH
1066 int nid;
1067 EC_KEY *ecdh;
1068 1066
1069 /* 1067 /*
1070 * Elliptic-Curve Diffie-Hellman parameters are either "named curves" 1068 * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
1071 * from RFC 4492 section 5.1.1, or explicitly described curves over 1069 * from RFC 4492 section 5.1.1, or explicitly described curves over
1072 * binary fields. OpenSSL only supports the "named curves", which provide 1070 * binary fields. OpenSSL only supports the "named curves", which provide
1073 * maximum interoperability. 1071 * maximum interoperability.
1074 */ 1072 */
1075 1073
1076 nid = OBJ_sn2nid((char *) name->data); 1074 #ifdef SSL_CTRL_SET_CURVES_LIST
1075
1076 /*
1077 * OpenSSL 1.0.2+ allows configuring a curve list instead of a single
1078 * curve previously supported. By default an internal list is used,
1079 * with prime256v1 being preferred by server in OpenSSL 1.0.2b+
1080 * and X25519 in OpenSSL 1.1.0+.
1081 *
1082 * By default a curve preferred by the client will be used for
1083 * key exchange. The SSL_OP_CIPHER_SERVER_PREFERENCE option can
1084 * be used to prefer server curves instead, similar to what it
1085 * does for ciphers.
1086 */
1087
1088 SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
1089
1090 #if SSL_CTRL_SET_ECDH_AUTO
1091 /* not needed in OpenSSL 1.1.0+ */
1092 SSL_CTX_set_ecdh_auto(ssl->ctx, 1);
1093 #endif
1094
1095 if (ngx_strcmp(name->data, "auto") == 0) {
1096 return NGX_OK;
1097 }
1098
1099 if (SSL_CTX_set1_curves_list(ssl->ctx, (char *) name->data) == 0) {
1100 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1101 "SSL_CTX_set1_curves_list(\"%s\") failed", name->data);
1102 return NGX_ERROR;
1103 }
1104
1105 #else
1106
1107 int nid;
1108 char *curve;
1109 EC_KEY *ecdh;
1110
1111 if (ngx_strcmp(name->data, "auto") == 0) {
1112 curve = "prime256v1";
1113
1114 } else {
1115 curve = (char *) name->data;
1116 }
1117
1118 nid = OBJ_sn2nid(curve);
1077 if (nid == 0) { 1119 if (nid == 0) {
1078 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, 1120 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1079 "OBJ_sn2nid(\"%s\") failed: unknown curve", name->data); 1121 "OBJ_sn2nid(\"%s\") failed: unknown curve", curve);
1080 return NGX_ERROR; 1122 return NGX_ERROR;
1081 } 1123 }
1082 1124
1083 ecdh = EC_KEY_new_by_curve_name(nid); 1125 ecdh = EC_KEY_new_by_curve_name(nid);
1084 if (ecdh == NULL) { 1126 if (ecdh == NULL) {
1085 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, 1127 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
1086 "EC_KEY_new_by_curve_name(\"%s\") failed", name->data); 1128 "EC_KEY_new_by_curve_name(\"%s\") failed", curve);
1087 return NGX_ERROR; 1129 return NGX_ERROR;
1088 } 1130 }
1089 1131
1090 SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE); 1132 SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
1091 1133
1092 SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh); 1134 SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
1093 1135
1094 EC_KEY_free(ecdh); 1136 EC_KEY_free(ecdh);
1137 #endif
1095 #endif 1138 #endif
1096 #endif 1139 #endif
1097 1140
1098 return NGX_OK; 1141 return NGX_OK;
1099 } 1142 }