From 89b3ddfd5a81b173c9177687b9c0b631a20426a6 Mon Sep 17 00:00:00 2001 From: Hakase Date: Sun, 17 Feb 2019 19:30:18 +0900 Subject: [PATCH] Add esni patch test file. --- esni.patch | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 esni.patch diff --git a/esni.patch b/esni.patch new file mode 100644 index 0000000..3b972d6 --- /dev/null +++ b/esni.patch @@ -0,0 +1,281 @@ +diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c +index 394a8c8..60991ec 100644 +--- a/src/event/ngx_event_openssl.c ++++ b/src/event/ngx_event_openssl.c +@@ -1085,6 +1085,49 @@ ngx_ssl_passwords_cleanup(void *data) + } + + ++ngx_int_t ++ngx_ssl_esni(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *esnipub, ngx_str_t *esnikey) ++{ ++ BIO *bio; ++ ++ if (esnikey->len == 0 || esnipub->len == 0) { ++ return NGX_OK; ++ } ++ ++ if (ngx_conf_full_name(cf->cycle, esnikey, 1) != NGX_OK) { ++ return NGX_ERROR; ++ } ++ ++ if (ngx_conf_full_name(cf->cycle, esnipub, 1) != NGX_OK) { ++ return NGX_ERROR; ++ } ++ ++ bio = BIO_new_file((char *) esnikey->data, "r"); ++ if (bio == NULL) { ++ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, ++ "BIO_new_file(\"%s\") failed", esnikey->data); ++ return NGX_ERROR; ++ } ++ ++ bio = BIO_new_file((char *) esnipub->data, "r"); ++ if (bio == NULL) { ++ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, ++ "BIO_new_file(\"%s\") failed", esnikey->data); ++ return NGX_ERROR; ++ } ++ ++ if (SSL_esni_server_enable(ssl->ctx, (char *)esnikey->data, (char *)esnipub->data) != 1) { ++ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, ++ "ESNI error"); ++ return NGX_ERROR; ++ } ++ ++ BIO_free(bio); ++ ++ return NGX_OK; ++} ++ ++ + ngx_int_t + ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) + { +@@ -4003,6 +4046,37 @@ ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) + } + + ++ngx_int_t ++ngx_ssl_get_esni(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) ++{ ++ s->len = 0; ++ char *hidden=NULL; ++ char *cover=NULL; ++ int esnirv=SSL_get_esni_status(c->ssl->connection, &hidden, &cover); ++ if (esnirv) { ++ } ++ switch (esnirv) { ++ case SSL_ESNI_STATUS_NOT_TRIED: ++ ngx_str_set(s, "not attemped"); ++ break; ++ case SSL_ESNI_STATUS_FAILED: ++ ngx_str_set(s, "tried but failed"); ++ break; ++ case SSL_ESNI_STATUS_BAD_NAME: ++ ngx_str_set(s, "bad name"); ++ break; ++ case SSL_ESNI_STATUS_SUCCESS: ++ ngx_str_set(s, "success"); ++ break; ++ default: ++ ngx_str_set(s, "esni error"); ++break; ++ } ++ //s->data = (u_char *) esnis; ++ return NGX_OK; ++} ++ ++ + ngx_int_t + ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) + { +diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h +index 31d0923..7d08e16 100644 +--- a/src/event/ngx_event_openssl.h ++++ b/src/event/ngx_event_openssl.h +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #define NGX_SSL_NAME "OpenSSL" + +@@ -178,6 +179,8 @@ ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); + ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); ++ngx_int_t ngx_ssl_esni(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *esnipub, ++ ngx_str_t *esnikey); + ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers); + ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, +@@ -205,6 +208,7 @@ ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data); + ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, + ngx_uint_t flags); ++ngx_int_t ngx_ssl_get_esni(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); + + void ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); + ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session); +diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c +index c5ed248..3c88b07 100644 +--- a/src/http/modules/ngx_http_ssl_module.c ++++ b/src/http/modules/ngx_http_ssl_module.c +@@ -176,6 +176,27 @@ static ngx_command_t ngx_http_ssl_commands[] = { + offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers), + NULL }, + ++ { ngx_string("ssl_esni"), ++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, ++ ngx_conf_set_flag_slot, ++ NGX_HTTP_SRV_CONF_OFFSET, ++ offsetof(ngx_http_ssl_srv_conf_t, esni), ++ NULL }, ++ ++ { ngx_string("ssl_esnipub"), ++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_str_slot, ++ NGX_HTTP_SRV_CONF_OFFSET, ++ offsetof(ngx_http_ssl_srv_conf_t, esnipub), ++ NULL }, ++ ++ { ngx_string("ssl_esnikey"), ++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_str_slot, ++ NGX_HTTP_SRV_CONF_OFFSET, ++ offsetof(ngx_http_ssl_srv_conf_t, esnikey), ++ NULL }, ++ + { ngx_string("ssl_session_cache"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12, + ngx_http_ssl_session_cache, +@@ -330,6 +351,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = { + { ngx_string("ssl_curves"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_curves, NGX_HTTP_VAR_CHANGEABLE, 0 }, + ++ { ngx_string("ssl_esni_data"), NULL, ngx_http_ssl_variable, ++ (uintptr_t) ngx_ssl_get_esni, NGX_HTTP_VAR_CHANGEABLE, 0 }, ++ + { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 }, + +@@ -599,11 +623,14 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) + sscf->enable = NGX_CONF_UNSET; + sscf->prefer_server_ciphers = NGX_CONF_UNSET; + sscf->early_data = NGX_CONF_UNSET; ++ sscf->esni = NGX_CONF_UNSET; + sscf->buffer_size = NGX_CONF_UNSET_SIZE; + sscf->verify = NGX_CONF_UNSET_UINT; + sscf->verify_depth = NGX_CONF_UNSET_UINT; + sscf->certificates = NGX_CONF_UNSET_PTR; + sscf->certificate_keys = NGX_CONF_UNSET_PTR; ++ //sscf->esnipub = NGX_CONF_UNSET; ++ //sscf->esnikey = NGX_CONF_UNSET; + sscf->passwords = NGX_CONF_UNSET_PTR; + sscf->builtin_session_cache = NGX_CONF_UNSET; + sscf->session_timeout = NGX_CONF_UNSET; +@@ -647,6 +674,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + prev->prefer_server_ciphers, 1); + + ngx_conf_merge_value(conf->early_data, prev->early_data, 1); ++ ngx_conf_merge_value(conf->esni, prev->esni, 0); + + ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, + (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 +@@ -661,6 +689,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); + ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, + NULL); ++ ngx_conf_merge_str_value(conf->esnipub, prev->esnipub, ++ NULL); ++ ngx_conf_merge_str_value(conf->esnikey, prev->esnikey, ++ NULL); + + ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); + +@@ -761,7 +793,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + "dynamically to an OpenSSL library which has no tlsext support, " + "therefore SNI is not available"); + } +- + #endif + + #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +@@ -788,6 +819,15 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + return NGX_CONF_ERROR; + } + ++ if (conf->esni) { ++ if (ngx_ssl_esni(cf, &conf->ssl, &conf->esnipub, ++ &conf->esnikey) ++ != NGX_OK) ++ { ++ return NGX_CONF_ERROR; ++ } ++ } ++ + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) +diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h +index deeadc3..f71cec7 100644 +--- a/src/http/modules/ngx_http_ssl_module.h ++++ b/src/http/modules/ngx_http_ssl_module.h +@@ -21,6 +21,7 @@ typedef struct { + + ngx_flag_t prefer_server_ciphers; + ngx_flag_t early_data; ++ ngx_flag_t esni; + + ngx_uint_t protocols; + +@@ -36,6 +37,8 @@ typedef struct { + ngx_array_t *certificates; + ngx_array_t *certificate_keys; + ++ ngx_str_t esnipub; ++ ngx_str_t esnikey; + ngx_str_t dhparam; + ngx_str_t ecdh_curve; + ngx_str_t client_certificate; +diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c +index 1901129..ec42395 100644 +--- a/src/http/ngx_http_request.c ++++ b/src/http/ngx_http_request.c +@@ -852,8 +852,25 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) + + clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module); + ++ sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); ++ ++ if (sscf->esni) { ++ if (SSL_esni_server_enable(sscf->ssl.ctx, sscf->esnikey, sscf->esnipub) != 1) { ++ ngx_ssl_error(NGX_LOG_INFO, c->log, 0, ++ "ESNI error"); ++ return NGX_ERROR; ++ } ++ } ++ + servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name); + ++ char *hidden=NULL; ++ char *cover=NULL; ++ ++ SSL_get_esni_status(ssl_conn,&hidden,&cover); ++ ngx_log_error(NGX_LOG_INFO, c->log, 0, ++ "esni cover : %s, hidden: %s, servername: %s", (cover==NULL?"none":cover), (hidden==NULL?"none":hidden), (servername==NULL?"none":servername)); ++ + if (servername == NULL) { + return (clcf->strict_sni) ? SSL_TLSEXT_ERR_ALERT_FATAL : SSL_TLSEXT_ERR_NOACK; + } +@@ -895,8 +912,6 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) + + ngx_set_connection_log(c, clcf->error_log); + +- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); +- + c->ssl->buffer_size = sscf->buffer_size; + + if (sscf->ssl.ctx) {