Browse Source

[mod_openssl] basic SSL_CONF_cmd for alt TLS libs

provide *basic* (limited) parsing of ssl.openssl.ssl-conf-cmd
for BoringSSL, LibreSSL, WolfSSL
personal/stbuehler/ci-build
Glenn Strauss 2 years ago
parent
commit
60ddaf26c4
  1. 208
      src/mod_openssl.c

208
src/mod_openssl.c

@ -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 */

Loading…
Cancel
Save