|
|
|
@ -1520,6 +1520,14 @@ mod_openssl_alpn_select_cb (SSL *ssl, const unsigned char **out, unsigned char *
|
|
|
|
|
#endif /* OPENSSL_NO_TLSEXT */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(BORINGSSL_API_VERSION) \ |
|
|
|
|
|| defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| defined(WOLFSSL_VERSION) |
|
|
|
|
static int |
|
|
|
|
mod_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
network_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s) |
|
|
|
|
{ |
|
|
|
@ -1567,6 +1575,12 @@ network_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s)
|
|
|
|
|
SSL_CONF_CTX_free(cctx); |
|
|
|
|
return rc; |
|
|
|
|
|
|
|
|
|
#elif defined(BORINGSSL_API_VERSION) \ |
|
|
|
|
|| defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| defined(WOLFSSL_VERSION) |
|
|
|
|
|
|
|
|
|
return mod_openssl_ssl_conf_cmd(srv, s); |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
UNUSED(s); |
|
|
|
@ -3183,3 +3197,197 @@ int mod_openssl_plugin_init (plugin *p)
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(BORINGSSL_API_VERSION) \ |
|
|
|
|
|| defined(LIBRESSL_VERSION_NUMBER) \
|
|
|
|
|
|| defined(WOLFSSL_VERSION) |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
mod_openssl_ssl_conf_proto_val (server *srv, plugin_config_socket *s, const buffer *b, int max) |
|
|
|
|
{ |
|
|
|
|
if (NULL == b) /* default: min TLSv1.2, max TLSv1.3 */ |
|
|
|
|
#ifdef TLS1_3_VERSION |
|
|
|
|
return max ? TLS1_3_VERSION : TLS1_2_VERSION; |
|
|
|
|
#else |
|
|
|
|
return TLS1_2_VERSION; |
|
|
|
|
#endif |
|
|
|
|
else if (buffer_eq_icase_slen(b, CONST_STR_LEN("None"))) /*"disable" limit*/ |
|
|
|
|
return max |
|
|
|
|
? |
|
|
|
|
#ifdef TLS1_3_VERSION |
|
|
|
|
TLS1_3_VERSION |
|
|
|
|
#else |
|
|
|
|
TLS1_2_VERSION |
|
|
|
|
#endif |
|
|
|
|
: (s->ssl_use_sslv3 ? SSL3_VERSION : TLS1_VERSION); |
|
|
|
|
else if (buffer_eq_icase_slen(b, CONST_STR_LEN("SSLv3"))) |
|
|
|
|
return SSL3_VERSION; |
|
|
|
|
else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.0"))) |
|
|
|
|
return TLS1_VERSION; |
|
|
|
|
else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.1"))) |
|
|
|
|
return TLS1_1_VERSION; |
|
|
|
|
else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.2"))) |
|
|
|
|
return TLS1_2_VERSION; |
|
|
|
|
#ifdef TLS1_3_VERSION |
|
|
|
|
else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.3"))) |
|
|
|
|
return TLS1_3_VERSION; |
|
|
|
|
#endif |
|
|
|
|
else { |
|
|
|
|
if (buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1")) |
|
|
|
|
|| buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1.2"))) |
|
|
|
|
log_error(srv->errh, __FILE__, __LINE__, |
|
|
|
|
"SSL: ssl.openssl.ssl-conf-cmd %s %s ignored", |
|
|
|
|
max ? "MaxProtocol" : "MinProtocol", b->ptr); |
|
|
|
|
else |
|
|
|
|
log_error(srv->errh, __FILE__, __LINE__, |
|
|
|
|
"SSL: ssl.openssl.ssl-conf-cmd %s %s invalid; ignored", |
|
|
|
|
max ? "MaxProtocol" : "MinProtocol", b->ptr); |
|
|
|
|
} |
|
|
|
|
#ifdef TLS1_3_VERSION |
|
|
|
|
return max ? TLS1_3_VERSION : TLS1_2_VERSION; |
|
|
|
|
#else |
|
|
|
|
return TLS1_2_VERSION; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
mod_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s) |
|
|
|
|
{ |
|
|
|
|
/* reference:
|
|
|
|
|
* https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html */
|
|
|
|
|
int rc = 0; |
|
|
|
|
buffer *cipherstring = NULL; |
|
|
|
|
/*buffer *ciphersuites = NULL;*/ |
|
|
|
|
buffer *minb = NULL; |
|
|
|
|
buffer *maxb = NULL; |
|
|
|
|
buffer *curves = NULL; |
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < s->ssl_conf_cmd->used; ++i) { |
|
|
|
|
data_string *ds = (data_string *)s->ssl_conf_cmd->data[i]; |
|
|
|
|
if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("CipherString"))) |
|
|
|
|
cipherstring = &ds->value; |
|
|
|
|
#if 0 |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Ciphersuites"))) |
|
|
|
|
ciphersuites = &ds->value; |
|
|
|
|
#endif |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Curves")) |
|
|
|
|
|| buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Groups"))) |
|
|
|
|
curves = &ds->value; |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MaxProtocol"))) |
|
|
|
|
maxb = &ds->value; |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MinProtocol"))) |
|
|
|
|
minb = &ds->value; |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Protocol"))) { |
|
|
|
|
/* openssl config for Protocol=... is complex and deprecated */ |
|
|
|
|
log_error(srv->errh, __FILE__, __LINE__, |
|
|
|
|
"SSL: ssl.openssl.ssl-conf-cmd %s ignored; " |
|
|
|
|
"use MinProtocol=... and MaxProtocol=... instead", |
|
|
|
|
ds->key.ptr); |
|
|
|
|
} |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Options"))) { |
|
|
|
|
for (char *v = ds->value.ptr, *e; *v; v = e) { |
|
|
|
|
while (*v == ' ' || *v == '\t' || *v == ',') ++v; |
|
|
|
|
int flag = 1; |
|
|
|
|
if (*v == '-') { |
|
|
|
|
flag = 0; |
|
|
|
|
++v; |
|
|
|
|
} |
|
|
|
|
for (e = v; light_isalpha(*e); ++e) ; |
|
|
|
|
switch ((int)(e-v)) { |
|
|
|
|
case 11: |
|
|
|
|
if (buffer_eq_icase_ssn(v, "Compression", 11)) { |
|
|
|
|
if (flag) |
|
|
|
|
SSL_CTX_clear_options(s->ssl_ctx, |
|
|
|
|
SSL_OP_NO_COMPRESSION); |
|
|
|
|
else |
|
|
|
|
SSL_CTX_set_options(s->ssl_ctx, |
|
|
|
|
SSL_OP_NO_COMPRESSION); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 13: |
|
|
|
|
if (buffer_eq_icase_ssn(v, "SessionTicket", 13)) { |
|
|
|
|
if (flag) |
|
|
|
|
SSL_CTX_clear_options(s->ssl_ctx, |
|
|
|
|
SSL_OP_NO_TICKET); |
|
|
|
|
else |
|
|
|
|
SSL_CTX_set_options(s->ssl_ctx, |
|
|
|
|
SSL_OP_NO_TICKET); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 16: |
|
|
|
|
if (buffer_eq_icase_ssn(v, "ServerPreference", 16)) { |
|
|
|
|
if (flag) |
|
|
|
|
SSL_CTX_set_options(s->ssl_ctx, |
|
|
|
|
SSL_OP_CIPHER_SERVER_PREFERENCE); |
|
|
|
|
else |
|
|
|
|
SSL_CTX_clear_options(s->ssl_ctx, |
|
|
|
|
SSL_OP_CIPHER_SERVER_PREFERENCE); |
|
|
|
|
s->ssl_honor_cipher_order = flag; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
/* warn if not explicitly handled or ignored above */ |
|
|
|
|
if (!flag) --v; |
|
|
|
|
log_error(srv->errh, __FILE__, __LINE__, |
|
|
|
|
"SSL: ssl.openssl.ssl-conf-cmd Options %.*s " |
|
|
|
|
"ignored", (int)(e-v), v); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#if 0 |
|
|
|
|
else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("..."))) { |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
else { |
|
|
|
|
/* warn if not explicitly handled or ignored above */ |
|
|
|
|
log_error(srv->errh, __FILE__, __LINE__, |
|
|
|
|
"SSL: ssl.openssl.ssl-conf-cmd %s ignored", |
|
|
|
|
ds->key.ptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (minb) { |
|
|
|
|
/*(wolfSSL_CTX_SetMinVersion() alt uses enums with different values)*/ |
|
|
|
|
int n = mod_openssl_ssl_conf_proto_val(srv, s, minb, 0); |
|
|
|
|
if (!SSL_CTX_set_min_proto_version(s->ssl_ctx, n)) |
|
|
|
|
rc = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (maxb) { |
|
|
|
|
#ifndef WOLFSSL_VERSION /*WolfSSL max ver is set at WolfSSL compile-time*/ |
|
|
|
|
int x = mod_openssl_ssl_conf_proto_val(srv, s, maxb, 1); |
|
|
|
|
if (!SSL_CTX_set_max_proto_version(s->ssl_ctx, x)) |
|
|
|
|
rc = -1; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cipherstring) { |
|
|
|
|
/* Disable support for low encryption ciphers */ |
|
|
|
|
buffer_append_string_len(cipherstring, |
|
|
|
|
CONST_STR_LEN(":!aNULL:!eNULL:!EXP")); |
|
|
|
|
if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { |
|
|
|
|
log_error(srv->errh, __FILE__, __LINE__, |
|
|
|
|
"SSL: %s", ERR_error_string(ERR_get_error(), NULL)); |
|
|
|
|
rc = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->ssl_honor_cipher_order) |
|
|
|
|
SSL_CTX_set_options(s->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (curves) { |
|
|
|
|
if (!mod_openssl_ssl_conf_curves(srv, s, curves)) |
|
|
|
|
rc = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return rc; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* BORINGSSL_API_VERSION || LIBRESSL_VERSION_NUMBER || WOLFSSL_VERSION */ |
|
|
|
|