SSL: support for TLSv1.3 early data with BoringSSL.
Early data AKA 0-RTT mode is enabled as long as "ssl_early_data on" is
specified in the configuration (default is off).
The $ssl_early_data variable evaluates to "1" if the SSL handshake
isn't yet completed, and can be used to set the Early-Data header as
per draft-ietf-httpbis-replay-04.
Maxim Dounin
3 years ago
1161 | 1161 | EC_KEY_free(ecdh); |
1162 | 1162 | #endif |
1163 | 1163 | #endif |
1164 | #endif | |
1165 | ||
1166 | return NGX_OK; | |
1167 | } | |
1168 | ||
1169 | ||
1170 | ngx_int_t | |
1171 | ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_uint_t enable) | |
1172 | { | |
1173 | if (!enable) { | |
1174 | return NGX_OK; | |
1175 | } | |
1176 | ||
1177 | #ifdef SSL_ERROR_EARLY_DATA_REJECTED | |
1178 | ||
1179 | /* BoringSSL */ | |
1180 | ||
1181 | SSL_CTX_set_early_data_enabled(ssl->ctx, 1); | |
1182 | ||
1183 | #else | |
1184 | ngx_log_error(NGX_LOG_WARN, ssl->log, 0, | |
1185 | "\"ssl_early_data\" is not supported on this platform, " | |
1186 | "ignored"); | |
1164 | 1187 | #endif |
1165 | 1188 | |
1166 | 1189 | return NGX_OK; |
3623 | 3646 | |
3624 | 3647 | |
3625 | 3648 | ngx_int_t |
3649 | ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) | |
3650 | { | |
3651 | s->len = 0; | |
3652 | ||
3653 | #ifdef SSL_ERROR_EARLY_DATA_REJECTED | |
3654 | if (SSL_in_early_data(c->ssl->connection)) { | |
3655 | ngx_str_set(s, "1"); | |
3656 | } | |
3657 | #endif | |
3658 | ||
3659 | return NGX_OK; | |
3660 | } | |
3661 | ||
3662 | ||
3663 | ngx_int_t | |
3626 | 3664 | ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) |
3627 | 3665 | { |
3628 | 3666 | #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME |
170 | 170 | ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file); |
171 | 171 | ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file); |
172 | 172 | ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name); |
173 | ngx_int_t ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl, | |
174 | ngx_uint_t enable); | |
173 | 175 | ngx_int_t ngx_ssl_client_session_cache(ngx_conf_t *cf, ngx_ssl_t *ssl, |
174 | 176 | ngx_uint_t enable); |
175 | 177 | ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, |
211 | 213 | ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, |
212 | 214 | ngx_str_t *s); |
213 | 215 | ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, |
216 | ngx_str_t *s); | |
217 | ngx_int_t ngx_ssl_get_early_data(ngx_connection_t *c, ngx_pool_t *pool, | |
214 | 218 | ngx_str_t *s); |
215 | 219 | ngx_int_t ngx_ssl_get_server_name(ngx_connection_t *c, ngx_pool_t *pool, |
216 | 220 | ngx_str_t *s); |
236 | 236 | ngx_conf_set_flag_slot, |
237 | 237 | NGX_HTTP_SRV_CONF_OFFSET, |
238 | 238 | offsetof(ngx_http_ssl_srv_conf_t, stapling_verify), |
239 | NULL }, | |
240 | ||
241 | { ngx_string("ssl_early_data"), | |
242 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, | |
243 | ngx_conf_set_flag_slot, | |
244 | NGX_HTTP_SRV_CONF_OFFSET, | |
245 | offsetof(ngx_http_ssl_srv_conf_t, early_data), | |
239 | 246 | NULL }, |
240 | 247 | |
241 | 248 | ngx_null_command |
293 | 300 | { ngx_string("ssl_session_reused"), NULL, ngx_http_ssl_variable, |
294 | 301 | (uintptr_t) ngx_ssl_get_session_reused, NGX_HTTP_VAR_CHANGEABLE, 0 }, |
295 | 302 | |
303 | { ngx_string("ssl_early_data"), NULL, ngx_http_ssl_variable, | |
304 | (uintptr_t) ngx_ssl_get_early_data, | |
305 | NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 }, | |
306 | ||
296 | 307 | { ngx_string("ssl_server_name"), NULL, ngx_http_ssl_variable, |
297 | 308 | (uintptr_t) ngx_ssl_get_server_name, NGX_HTTP_VAR_CHANGEABLE, 0 }, |
298 | 309 | |
551 | 562 | |
552 | 563 | sscf->enable = NGX_CONF_UNSET; |
553 | 564 | sscf->prefer_server_ciphers = NGX_CONF_UNSET; |
565 | sscf->early_data = NGX_CONF_UNSET; | |
554 | 566 | sscf->buffer_size = NGX_CONF_UNSET_SIZE; |
555 | 567 | sscf->verify = NGX_CONF_UNSET_UINT; |
556 | 568 | sscf->verify_depth = NGX_CONF_UNSET_UINT; |
593 | 605 | ngx_conf_merge_value(conf->prefer_server_ciphers, |
594 | 606 | prev->prefer_server_ciphers, 0); |
595 | 607 | |
608 | ngx_conf_merge_value(conf->early_data, prev->early_data, 0); | |
609 | ||
596 | 610 | ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, |
597 | 611 | (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |
598 | 612 | |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); |
806 | 820 | return NGX_CONF_ERROR; |
807 | 821 | } |
808 | 822 | |
823 | } | |
824 | ||
825 | if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) { | |
826 | return NGX_CONF_ERROR; | |
809 | 827 | } |
810 | 828 | |
811 | 829 | return NGX_CONF_OK; |