Mercurial > hg > nginx-quic
diff src/event/ngx_event_openssl.c @ 7648:b28ea685a56e quic
Moved all QUIC code into ngx_event_quic.c
Introduced ngx_quic_input() and ngx_quic_output() as interface between
nginx and protocol. They are the only functions that are exported.
While there, added copyrights.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Fri, 28 Feb 2020 16:23:25 +0300 |
parents | 3cb4f16426a5 |
children | 253cf267f95a |
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -90,328 +90,6 @@ static char *ngx_openssl_engine(ngx_conf static void ngx_openssl_exit(ngx_cycle_t *cycle); -#if NGX_OPENSSL_QUIC - -static int -quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const uint8_t *read_secret, - const uint8_t *write_secret, size_t secret_len) -{ - u_char *name; - ngx_uint_t i; - const EVP_MD *digest; - const EVP_CIPHER *cipher; - ngx_connection_t *c; - ngx_quic_secret_t *client, *server; - - c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); - - ngx_ssl_handshake_log(c); - -#if (NGX_DEBUG) - if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { - u_char buf[64]; - size_t m; - - m = ngx_hex_dump(buf, (u_char *) read_secret, secret_len) - buf; - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "set_encryption_secrets: read %*s, len: %uz, level:%d", - m, buf, secret_len, (int) level); - - m = ngx_hex_dump(buf, (u_char *) write_secret, secret_len) - buf; - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "set_encryption_secrets: write %*s, len: %uz, level:%d", - m, buf, secret_len, (int) level); - } -#endif - - name = (u_char *) SSL_get_cipher(ssl_conn); - - if (ngx_strcasecmp(name, (u_char *) "TLS_AES_128_GCM_SHA256") == 0 - || ngx_strcasecmp(name, (u_char *) "(NONE)") == 0) - { - cipher = EVP_aes_128_gcm(); - digest = EVP_sha256(); - - } else if (ngx_strcasecmp(name, (u_char *) "TLS_AES_256_GCM_SHA384") == 0) { - cipher = EVP_aes_256_gcm(); - digest = EVP_sha384(); - - } else { - ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); - return 0; - } - - switch (level) { - - case ssl_encryption_handshake: - client = &c->quic->client_hs; - server = &c->quic->server_hs; - - break; - - case ssl_encryption_application: - client = &c->quic->client_ad; - server = &c->quic->server_ad; - - break; - - default: - return 0; - } - - client->key.len = EVP_CIPHER_key_length(cipher); - server->key.len = EVP_CIPHER_key_length(cipher); - - client->iv.len = EVP_CIPHER_iv_length(cipher); - server->iv.len = EVP_CIPHER_iv_length(cipher); - - client->hp.len = EVP_CIPHER_key_length(cipher); - server->hp.len = EVP_CIPHER_key_length(cipher); - - struct { - ngx_str_t label; - ngx_str_t *key; - const uint8_t *secret; - } seq[] = { - { ngx_string("tls13 quic key"), &client->key, read_secret }, - { ngx_string("tls13 quic iv"), &client->iv, read_secret }, - { ngx_string("tls13 quic hp"), &client->hp, read_secret }, - { ngx_string("tls13 quic key"), &server->key, write_secret }, - { ngx_string("tls13 quic iv"), &server->iv, write_secret }, - { ngx_string("tls13 quic hp"), &server->hp, write_secret }, - }; - - for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { - - if (ngx_quic_hkdf_expand(c, digest, seq[i].key, &seq[i].label, - seq[i].secret, secret_len) - != NGX_OK) - { - return 0; - } - } - - return 1; -} - - -static int -quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const uint8_t *data, size_t len) -{ - u_char *p, *pnp, *name, *nonce, *sample; - ngx_int_t m; - ngx_str_t in, out, ad; - static int pn; - const EVP_CIPHER *cipher; - ngx_connection_t *c; - ngx_quic_secret_t *secret; - ngx_quic_connection_t *qc; - u_char buf[2048], mask[16]; - - c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); - qc = c->quic; - - ngx_ssl_handshake_log(c); - - switch (level) { - - case ssl_encryption_initial: - secret = &qc->server_in; - break; - - case ssl_encryption_handshake: - secret = &qc->server_hs; - break; - - default: - return 0; - } - - m = ngx_hex_dump(buf, (u_char *) data, ngx_min(len, 1024)) - buf; - ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data: %*s%s, len: %uz, level:%d", - m, buf, len < 2048 ? "" : "...", len, (int) level); - - in.data = ngx_alloc(4 + len + 5 /*minimal ACK*/, c->log); - if (in.data == 0) { - return 0; - } - - p = in.data; - ngx_quic_build_int(&p, 6); // crypto frame - ngx_quic_build_int(&p, 0); - ngx_quic_build_int(&p, len); - p = ngx_cpymem(p, data, len); - - if (level == ssl_encryption_initial) { - ngx_quic_build_int(&p, 2); // ack frame - ngx_quic_build_int(&p, 0); - ngx_quic_build_int(&p, 0); - ngx_quic_build_int(&p, 0); - ngx_quic_build_int(&p, 0); - } - - in.len = p - in.data; - out.len = in.len + EVP_GCM_TLS_TAG_LEN; - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data: clear_len:%uz, ciphertext_len:%uz", - in.len, out.len); - - ad.data = ngx_alloc(346 /*max header*/, c->log); - if (ad.data == 0) { - return 0; - } - - p = ad.data; - if (level == ssl_encryption_initial) { - *p++ = 0xc0; // initial, packet number len - } else if (level == ssl_encryption_handshake) { - *p++ = 0xe0; // handshake, packet number len - } - p = ngx_quic_write_uint32(p, quic_version); - *p++ = qc->scid.len; - p = ngx_cpymem(p, qc->scid.data, qc->scid.len); - *p++ = qc->dcid.len; - p = ngx_cpymem(p, qc->dcid.data, qc->dcid.len); - if (level == ssl_encryption_initial) { - ngx_quic_build_int(&p, 0); // token length - } - ngx_quic_build_int(&p, out.len + 1); // length (inc. pnl) - pnp = p; - - if (level == ssl_encryption_initial) { - *p++ = 0; // packet number 0 - - } else if (level == ssl_encryption_handshake) { - *p++ = pn++; - } - - ad.len = p - ad.data; - - m = ngx_hex_dump(buf, ad.data, ad.len) - buf; - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data ad: %*s, len: %uz", - m, buf, ad.len); - - - name = (u_char *) SSL_get_cipher(ssl_conn); - - if (ngx_strcasecmp(name, (u_char *) "TLS_AES_128_GCM_SHA256") == 0 - || ngx_strcasecmp(name, (u_char *) "(NONE)") == 0) - { - cipher = EVP_aes_128_gcm(); - - } else if (ngx_strcasecmp(name, (u_char *) "TLS_AES_256_GCM_SHA384") == 0) { - cipher = EVP_aes_256_gcm(); - - } else { - return 0; - } - - nonce = ngx_pstrdup(c->pool, &secret->iv); - if (level == ssl_encryption_handshake) { - nonce[11] ^= (pn - 1); - } - - m = ngx_hex_dump(buf, (u_char *) secret->iv.data, 12) - buf; - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data sample: server_iv %*s", - m, buf); - m = ngx_hex_dump(buf, (u_char *) nonce, 12) - buf; - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data sample: n=%d nonce %*s", - pn - 1, m, buf); - - if (ngx_quic_tls_seal(c, cipher, secret, &out, nonce, &in, &ad) != NGX_OK) - { - return 0; - } - - sample = &out.data[3]; // pnl=0 - if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), secret, mask, sample) != NGX_OK) { - return 0; - } - - m = ngx_hex_dump(buf, (u_char *) sample, 16) - buf; - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data sample: %*s, len: %uz", - m, buf, 16); - - m = ngx_hex_dump(buf, (u_char *) mask, 16) - buf; - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data mask: %*s, len: %uz", - m, buf, 16); - - m = ngx_hex_dump(buf, (u_char *) secret->hp.data, 16) - buf; - ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data hp_key: %*s, len: %uz", - m, buf, 16); - - // header protection, pnl = 0 - ad.data[0] ^= mask[0] & 0x0f; - *pnp ^= mask[1]; - - u_char *packet = ngx_alloc(ad.len + out.len, c->log); - if (packet == 0) { - return 0; - } - - p = ngx_cpymem(packet, ad.data, ad.len); - p = ngx_cpymem(p, out.data, out.len); - - m = ngx_hex_dump(buf, (u_char *) packet, ngx_min(1024, p - packet)) - buf; - ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_add_handshake_data packet: %*s%s, len: %uz", - m, buf, len < 2048 ? "" : "...", p - packet); - - c->send(c, packet, p - packet); - - return 1; -} - - -static int -quic_flush_flight(ngx_ssl_conn_t *ssl_conn) -{ - ngx_connection_t *c; - - c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic_flush_flight()"); - - return 1; -} - - -static int -quic_send_alert(ngx_ssl_conn_t *ssl_conn, enum ssl_encryption_level_t level, - uint8_t alert) -{ - ngx_connection_t *c; - - c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); - - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic_send_alert(), lvl=%d, alert=%d", - (int) level, (int) alert); - - return 1; -} - - -static SSL_QUIC_METHOD quic_method = { - quic_set_encryption_secrets, - quic_add_handshake_data, - quic_flush_flight, - quic_send_alert, -}; - -#endif - - static ngx_command_t ngx_openssl_commands[] = { { ngx_string("ssl_engine"), @@ -1790,7 +1468,7 @@ ngx_ssl_quic(ngx_conf_t *cf, ngx_ssl_t * #if NGX_OPENSSL_QUIC - SSL_CTX_set_quic_method(ssl->ctx, &quic_method); + ngx_quic_init_ssl_methods(ssl->ctx); return NGX_OK; #else