src/event/quic/ngx_event_quic_ssl.c - nginx

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Nginx, Inc.
  3. */


  4. #include <ngx_config.h>
  5. #include <ngx_core.h>
  6. #include <ngx_event.h>
  7. #include <ngx_event_quic_connection.h>


  8. /*
  9. * RFC 9000, 7.5.  Cryptographic Message Buffering
  10. *
  11. * Implementations MUST support buffering at least 4096 bytes of data
  12. */
  13. #define NGX_QUIC_MAX_BUFFERED    65535


  14. #if (NGX_QUIC_OPENSSL_API)

  15. static int ngx_quic_cbs_send(ngx_ssl_conn_t *ssl_conn,
  16.     const unsigned char *data, size_t len, size_t *consumed, void *arg);
  17. static int ngx_quic_cbs_recv_rcd(ngx_ssl_conn_t *ssl_conn,
  18.     const unsigned char **data, size_t *bytes_read, void *arg);
  19. static int ngx_quic_cbs_release_rcd(ngx_ssl_conn_t *ssl_conn,
  20.     size_t bytes_read, void *arg);
  21. static int ngx_quic_cbs_yield_secret(ngx_ssl_conn_t *ssl_conn, uint32_t level,
  22.     int direction, const unsigned char *secret, size_t secret_len, void *arg);
  23. static int ngx_quic_cbs_got_transport_params(ngx_ssl_conn_t *ssl_conn,
  24.     const unsigned char *params, size_t params_len, void *arg);
  25. static int ngx_quic_cbs_alert(ngx_ssl_conn_t *ssl_conn, unsigned char alert,
  26.     void *arg);

  27. #else /* NGX_QUIC_BORINGSSL_API || NGX_QUIC_QUICTLS_API */

  28. static ngx_inline ngx_uint_t ngx_quic_map_encryption_level(
  29.     enum ssl_encryption_level_t ssl_level);

  30. #if (NGX_QUIC_BORINGSSL_API)
  31. static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
  32.     enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher,
  33.     const uint8_t *secret, size_t secret_len);
  34. static int ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn,
  35.     enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher,
  36.     const uint8_t *secret, size_t secret_len);
  37. #else /* NGX_QUIC_QUICTLS_API */
  38. static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn,
  39.     enum ssl_encryption_level_t ssl_level, const uint8_t *read_secret,
  40.     const uint8_t *write_secret, size_t secret_len);
  41. #endif

  42. static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
  43.     enum ssl_encryption_level_t ssl_level, const uint8_t *data, size_t len);
  44. static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn);
  45. static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
  46.     enum ssl_encryption_level_t ssl_level, uint8_t alert);

  47. #endif

  48. static ngx_int_t ngx_quic_handshake(ngx_connection_t *c);
  49. static ngx_int_t ngx_quic_crypto_provide(ngx_connection_t *c, ngx_uint_t level);


  50. #if (NGX_QUIC_OPENSSL_API)

  51. static int
  52. ngx_quic_cbs_send(ngx_ssl_conn_t *ssl_conn,
  53.     const unsigned char *data, size_t len, size_t *consumed, void *arg)
  54. {
  55.     ngx_connection_t  *c = arg;

  56.     ngx_chain_t            *out;
  57.     unsigned int            alpn_len;
  58.     ngx_quic_frame_t       *frame;
  59.     const unsigned char    *alpn_data;
  60.     ngx_quic_send_ctx_t    *ctx;
  61.     ngx_quic_connection_t  *qc;

  62.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  63.                    "quic ngx_quic_cbs_send len:%uz", len);

  64.     qc = ngx_quic_get_connection(c);

  65.     *consumed = 0;

  66.     SSL_get0_alpn_selected(ssl_conn, &alpn_data, &alpn_len);

  67.     if (alpn_len == 0) {
  68.         qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_NO_APPLICATION_PROTOCOL);
  69.         qc->error_reason = "missing ALPN extension";

  70.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  71.                       "quic missing ALPN extension");
  72.         return 1;
  73.     }

  74.     if (!qc->client_tp_done) {
  75.         /* RFC 9001, 8.2.  QUIC Transport Parameters Extension */
  76.         qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_MISSING_EXTENSION);
  77.         qc->error_reason = "missing transport parameters";

  78.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  79.                       "missing transport parameters");
  80.         return 1;
  81.     }

  82.     ctx = ngx_quic_get_send_ctx(qc, qc->write_level);

  83.     out = ngx_quic_copy_buffer(c, (u_char *) data, len);
  84.     if (out == NGX_CHAIN_ERROR) {
  85.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  86.         return 1;
  87.     }

  88.     frame = ngx_quic_alloc_frame(c);
  89.     if (frame == NULL) {
  90.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  91.         return 1;
  92.     }

  93.     frame->data = out;
  94.     frame->level = qc->write_level;
  95.     frame->type = NGX_QUIC_FT_CRYPTO;
  96.     frame->u.crypto.offset = ctx->crypto_sent;
  97.     frame->u.crypto.length = len;

  98.     ctx->crypto_sent += len;
  99.     *consumed = len;

  100.     ngx_quic_queue_frame(qc, frame);

  101.     return 1;
  102. }


  103. static int
  104. ngx_quic_cbs_recv_rcd(ngx_ssl_conn_t *ssl_conn,
  105.     const unsigned char **data, size_t *bytes_read, void *arg)
  106. {
  107.     ngx_connection_t  *c = arg;

  108.     ngx_buf_t              *b;
  109.     ngx_chain_t            *cl;
  110.     ngx_quic_send_ctx_t    *ctx;
  111.     ngx_quic_connection_t  *qc;

  112.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  113.                    "quic ngx_quic_cbs_recv_rcd");

  114.     qc = ngx_quic_get_connection(c);
  115.     ctx = ngx_quic_get_send_ctx(qc, qc->read_level);

  116.     cl = ctx->crypto.chain;

  117.     if (cl == NULL || cl->buf->sync) {
  118.         *data = NULL;
  119.         *bytes_read = 0;

  120.     } else {
  121.         b = cl->buf;

  122.         *data = b->pos;
  123.         *bytes_read = b->last - b->pos;
  124.     }

  125.     return 1;
  126. }


  127. static int
  128. ngx_quic_cbs_release_rcd(ngx_ssl_conn_t *ssl_conn, size_t bytes_read, void *arg)
  129. {
  130.     ngx_connection_t  *c = arg;

  131.     ngx_chain_t            *cl;
  132.     ngx_quic_send_ctx_t    *ctx;
  133.     ngx_quic_connection_t  *qc;

  134.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  135.                    "quic ngx_quic_cbs_release_rcd len:%uz", bytes_read);

  136.     /* already closed on handshake failure */

  137.     qc = ngx_quic_get_connection(c);
  138.     if (qc == NULL) {
  139.         return 1;
  140.     }

  141.     ctx = ngx_quic_get_send_ctx(qc, qc->read_level);

  142.     cl = ngx_quic_read_buffer(c, &ctx->crypto, bytes_read);
  143.     if (cl == NGX_CHAIN_ERROR) {
  144.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  145.         return 1;
  146.     }

  147.     ngx_quic_free_chain(c, cl);

  148.     return 1;
  149. }


  150. static int
  151. ngx_quic_cbs_yield_secret(ngx_ssl_conn_t *ssl_conn, uint32_t ssl_level,
  152.     int direction, const unsigned char *secret, size_t secret_len, void *arg)
  153. {
  154.     ngx_connection_t  *c = arg;

  155.     ngx_uint_t              level;
  156.     const SSL_CIPHER       *cipher;
  157.     ngx_quic_connection_t  *qc;

  158.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  159.                    "quic ngx_quic_cbs_yield_secret() level:%uD", ssl_level);
  160. #ifdef NGX_QUIC_DEBUG_CRYPTO
  161.     ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
  162.                    "quic %s secret len:%uz %*xs",
  163.                    direction ? "write" : "read", secret_len,
  164.                    secret_len, secret);
  165. #endif

  166.     qc = ngx_quic_get_connection(c);
  167.     cipher = SSL_get_current_cipher(ssl_conn);

  168.     switch (ssl_level) {
  169.     case OSSL_RECORD_PROTECTION_LEVEL_NONE:
  170.         level = NGX_QUIC_ENCRYPTION_INITIAL;
  171.         break;
  172.     case OSSL_RECORD_PROTECTION_LEVEL_EARLY:
  173.         level = NGX_QUIC_ENCRYPTION_EARLY_DATA;
  174.         break;
  175.     case OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE:
  176.         level = NGX_QUIC_ENCRYPTION_HANDSHAKE;
  177.         break;
  178.     default: /* OSSL_RECORD_PROTECTION_LEVEL_APPLICATION */
  179.         level = NGX_QUIC_ENCRYPTION_APPLICATION;
  180.         break;
  181.     }

  182.     if (ngx_quic_keys_set_encryption_secret(c->log, direction, qc->keys, level,
  183.                                             cipher, secret, secret_len)
  184.         != NGX_OK)
  185.     {
  186.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  187.         return 1;
  188.     }

  189.     if (direction) {
  190.         qc->write_level = level;

  191.     } else {
  192.         qc->read_level = level;
  193.     }

  194.     return 1;
  195. }


  196. static int
  197. ngx_quic_cbs_got_transport_params(ngx_ssl_conn_t *ssl_conn,
  198.     const unsigned char *params, size_t params_len, void *arg)
  199. {
  200.     ngx_connection_t  *c = arg;

  201.     u_char                 *p, *end;
  202.     ngx_quic_tp_t           ctp;
  203.     ngx_quic_connection_t  *qc;

  204.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  205.                    "quic ngx_quic_cbs_got_transport_params() len:%uz",
  206.                    params_len);

  207.     qc = ngx_quic_get_connection(c);

  208.     /* defaults for parameters not sent by client */
  209.     ngx_memcpy(&ctp, &qc->ctp, sizeof(ngx_quic_tp_t));

  210.     p = (u_char *) params;
  211.     end = p + params_len;

  212.     if (ngx_quic_parse_transport_params(p, end, &ctp, c->log) != NGX_OK) {
  213.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  214.         qc->error_reason = "failed to process transport parameters";

  215.         return 1;
  216.     }

  217.     if (ngx_quic_apply_transport_params(c, &ctp) != NGX_OK) {
  218.         return 1;
  219.     }

  220.     qc->client_tp_done = 1;

  221.     return 1;
  222. }


  223. static int
  224. ngx_quic_cbs_alert(ngx_ssl_conn_t *ssl_conn, unsigned char alert, void *arg)
  225. {
  226.     ngx_connection_t  *c = arg;

  227.     ngx_quic_connection_t  *qc;

  228.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  229.                    "quic ngx_quic_cbs_alert() alert:%d", (int) alert);

  230.     /* already closed on regular shutdown */

  231.     qc = ngx_quic_get_connection(c);
  232.     if (qc == NULL) {
  233.         return 1;
  234.     }

  235.     qc->error = NGX_QUIC_ERR_CRYPTO(alert);
  236.     qc->error_reason = "handshake failed";

  237.     return 1;
  238. }


  239. #else /* NGX_QUIC_BORINGSSL_API || NGX_QUIC_QUICTLS_API */


  240. static ngx_inline ngx_uint_t
  241. ngx_quic_map_encryption_level(enum ssl_encryption_level_t ssl_level)
  242. {
  243.     switch (ssl_level) {
  244.     case ssl_encryption_initial:
  245.         return NGX_QUIC_ENCRYPTION_INITIAL;
  246.     case ssl_encryption_early_data:
  247.         return NGX_QUIC_ENCRYPTION_EARLY_DATA;
  248.     case ssl_encryption_handshake:
  249.         return NGX_QUIC_ENCRYPTION_HANDSHAKE;
  250.     default: /* ssl_encryption_application */
  251.         return NGX_QUIC_ENCRYPTION_APPLICATION;
  252.     }
  253. }


  254. #if (NGX_QUIC_BORINGSSL_API)

  255. static int
  256. ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
  257.     enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher,
  258.     const uint8_t *rsecret, size_t secret_len)
  259. {
  260.     ngx_uint_t              level;
  261.     ngx_connection_t       *c;
  262.     ngx_quic_connection_t  *qc;

  263.     c = ngx_ssl_get_connection(ssl_conn);
  264.     qc = ngx_quic_get_connection(c);
  265.     level = ngx_quic_map_encryption_level(ssl_level);

  266.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  267.                    "quic ngx_quic_set_read_secret() level:%d", ssl_level);
  268. #ifdef NGX_QUIC_DEBUG_CRYPTO
  269.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  270.                    "quic read secret len:%uz %*xs", secret_len,
  271.                    secret_len, rsecret);
  272. #endif

  273.     if (ngx_quic_keys_set_encryption_secret(c->log, 0, qc->keys, level,
  274.                                             cipher, rsecret, secret_len)
  275.         != NGX_OK)
  276.     {
  277.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  278.     }

  279.     return 1;
  280. }


  281. static int
  282. ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn,
  283.     enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher,
  284.     const uint8_t *wsecret, size_t secret_len)
  285. {
  286.     ngx_uint_t              level;
  287.     ngx_connection_t       *c;
  288.     ngx_quic_connection_t  *qc;

  289.     c = ngx_ssl_get_connection(ssl_conn);
  290.     qc = ngx_quic_get_connection(c);
  291.     level = ngx_quic_map_encryption_level(ssl_level);

  292.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  293.                    "quic ngx_quic_set_write_secret() level:%d", ssl_level);
  294. #ifdef NGX_QUIC_DEBUG_CRYPTO
  295.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  296.                    "quic write secret len:%uz %*xs", secret_len,
  297.                    secret_len, wsecret);
  298. #endif

  299.     if (ngx_quic_keys_set_encryption_secret(c->log, 1, qc->keys, level,
  300.                                             cipher, wsecret, secret_len)
  301.         != NGX_OK)
  302.     {
  303.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  304.     }

  305.     return 1;
  306. }

  307. #else /* NGX_QUIC_QUICTLS_API */

  308. static int
  309. ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn,
  310.     enum ssl_encryption_level_t ssl_level, const uint8_t *rsecret,
  311.     const uint8_t *wsecret, size_t secret_len)
  312. {
  313.     ngx_uint_t              level;
  314.     ngx_connection_t       *c;
  315.     const SSL_CIPHER       *cipher;
  316.     ngx_quic_connection_t  *qc;

  317.     c = ngx_ssl_get_connection(ssl_conn);
  318.     qc = ngx_quic_get_connection(c);
  319.     level = ngx_quic_map_encryption_level(ssl_level);

  320.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  321.                    "quic ngx_quic_set_encryption_secrets() level:%d",
  322.                    ssl_level);
  323. #ifdef NGX_QUIC_DEBUG_CRYPTO
  324.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  325.                    "quic read secret len:%uz %*xs", secret_len,
  326.                    secret_len, rsecret);
  327. #endif

  328.     cipher = SSL_get_current_cipher(ssl_conn);

  329.     if (ngx_quic_keys_set_encryption_secret(c->log, 0, qc->keys, level,
  330.                                             cipher, rsecret, secret_len)
  331.         != NGX_OK)
  332.     {
  333.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  334.         return 1;
  335.     }

  336.     if (level == NGX_QUIC_ENCRYPTION_EARLY_DATA) {
  337.         return 1;
  338.     }

  339. #ifdef NGX_QUIC_DEBUG_CRYPTO
  340.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  341.                    "quic write secret len:%uz %*xs", secret_len,
  342.                    secret_len, wsecret);
  343. #endif

  344.     if (ngx_quic_keys_set_encryption_secret(c->log, 1, qc->keys, level,
  345.                                             cipher, wsecret, secret_len)
  346.         != NGX_OK)
  347.     {
  348.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  349.     }

  350.     return 1;
  351. }

  352. #endif


  353. static int
  354. ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
  355.     enum ssl_encryption_level_t ssl_level, const uint8_t *data, size_t len)
  356. {
  357.     u_char                 *p, *end;
  358.     size_t                  client_params_len;
  359.     ngx_uint_t              level;
  360.     ngx_chain_t            *out;
  361.     unsigned int            alpn_len;
  362.     const uint8_t          *client_params;
  363.     ngx_quic_tp_t           ctp;
  364.     ngx_quic_frame_t       *frame;
  365.     ngx_connection_t       *c;
  366.     const unsigned char    *alpn_data;
  367.     ngx_quic_send_ctx_t    *ctx;
  368.     ngx_quic_connection_t  *qc;

  369.     c = ngx_ssl_get_connection(ssl_conn);
  370.     qc = ngx_quic_get_connection(c);
  371.     level = ngx_quic_map_encryption_level(ssl_level);

  372.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  373.                    "quic ngx_quic_add_handshake_data");

  374.     if (!qc->client_tp_done) {
  375.         /*
  376.          * things to do once during handshake: check ALPN and transport
  377.          * parameters; we want to break handshake if something is wrong
  378.          * here;
  379.          */

  380.         SSL_get0_alpn_selected(ssl_conn, &alpn_data, &alpn_len);

  381.         if (alpn_len == 0) {
  382.             if (qc->error == 0) {
  383.                 qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_NO_APPLICATION_PROTOCOL);
  384.                 qc->error_reason = "missing ALPN extension";

  385.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  386.                               "quic missing ALPN extension");
  387.             }

  388.             return 1;
  389.         }

  390.         SSL_get_peer_quic_transport_params(ssl_conn, &client_params,
  391.                                            &client_params_len);

  392.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  393.                        "quic SSL_get_peer_quic_transport_params():"
  394.                        " params_len:%ui", client_params_len);

  395.         if (client_params_len == 0) {
  396.             /* RFC 9001, 8.2.  QUIC Transport Parameters Extension */

  397.             if (qc->error == 0) {
  398.                 qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_MISSING_EXTENSION);
  399.                 qc->error_reason = "missing transport parameters";

  400.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  401.                               "missing transport parameters");
  402.             }

  403.             return 1;
  404.         }

  405.         p = (u_char *) client_params;
  406.         end = p + client_params_len;

  407.         /* defaults for parameters not sent by client */
  408.         ngx_memcpy(&ctp, &qc->ctp, sizeof(ngx_quic_tp_t));

  409.         if (ngx_quic_parse_transport_params(p, end, &ctp, c->log)
  410.             != NGX_OK)
  411.         {
  412.             qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  413.             qc->error_reason = "failed to process transport parameters";

  414.             return 1;
  415.         }

  416.         if (ngx_quic_apply_transport_params(c, &ctp) != NGX_OK) {
  417.             return 1;
  418.         }

  419.         qc->client_tp_done = 1;
  420.     }

  421.     ctx = ngx_quic_get_send_ctx(qc, level);

  422.     out = ngx_quic_copy_buffer(c, (u_char *) data, len);
  423.     if (out == NGX_CHAIN_ERROR) {
  424.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  425.         return 1;
  426.     }

  427.     frame = ngx_quic_alloc_frame(c);
  428.     if (frame == NULL) {
  429.         qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  430.         return 1;
  431.     }

  432.     frame->data = out;
  433.     frame->level = level;
  434.     frame->type = NGX_QUIC_FT_CRYPTO;
  435.     frame->u.crypto.offset = ctx->crypto_sent;
  436.     frame->u.crypto.length = len;

  437.     ctx->crypto_sent += len;

  438.     ngx_quic_queue_frame(qc, frame);

  439.     return 1;
  440. }


  441. static int
  442. ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn)
  443. {
  444. #if (NGX_DEBUG)
  445.     ngx_connection_t  *c;

  446.     c = ngx_ssl_get_connection(ssl_conn);

  447.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  448.                    "quic ngx_quic_flush_flight()");
  449. #endif
  450.     return 1;
  451. }


  452. static int
  453. ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
  454.     enum ssl_encryption_level_t ssl_level, uint8_t alert)
  455. {
  456.     ngx_connection_t       *c;
  457.     ngx_quic_connection_t  *qc;

  458.     c = ngx_ssl_get_connection(ssl_conn);

  459.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  460.                    "quic ngx_quic_send_alert() level:%d alert:%d",
  461.                    ssl_level, (int) alert);

  462.     /* already closed on regular shutdown */

  463.     qc = ngx_quic_get_connection(c);
  464.     if (qc == NULL) {
  465.         return 1;
  466.     }

  467.     qc->error = NGX_QUIC_ERR_CRYPTO(alert);
  468.     qc->error_reason = "handshake failed";

  469.     return 1;
  470. }

  471. #endif


  472. ngx_int_t
  473. ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
  474.     ngx_quic_frame_t *frame)
  475. {
  476.     uint64_t                  last;
  477.     ngx_quic_send_ctx_t      *ctx;
  478.     ngx_quic_connection_t    *qc;
  479.     ngx_quic_crypto_frame_t  *f;

  480.     qc = ngx_quic_get_connection(c);

  481.     if (!ngx_quic_keys_available(qc->keys, pkt->level, 0)) {
  482.         return NGX_OK;
  483.     }

  484.     ctx = ngx_quic_get_send_ctx(qc, pkt->level);
  485.     f = &frame->u.crypto;

  486.     /* no overflow since both values are 62-bit */
  487.     last = f->offset + f->length;

  488.     if (last > ctx->crypto.offset + NGX_QUIC_MAX_BUFFERED) {
  489.         qc->error = NGX_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED;
  490.         return NGX_ERROR;
  491.     }

  492.     if (last <= ctx->crypto.offset) {
  493.         if (pkt->level == NGX_QUIC_ENCRYPTION_INITIAL) {
  494.             /* speeding up handshake completion */

  495.             if (!ngx_queue_empty(&ctx->sent)) {
  496.                 ngx_quic_resend_frames(c, ctx);

  497.                 ctx = ngx_quic_get_send_ctx(qc, NGX_QUIC_ENCRYPTION_HANDSHAKE);
  498.                 while (!ngx_queue_empty(&ctx->sent)) {
  499.                     ngx_quic_resend_frames(c, ctx);
  500.                 }
  501.             }
  502.         }

  503.         return NGX_OK;
  504.     }

  505.     if (ngx_quic_write_buffer(c, &ctx->crypto, frame->data, f->length,
  506.                               f->offset)
  507.         == NGX_CHAIN_ERROR)
  508.     {
  509.         return NGX_ERROR;
  510.     }

  511.     if (ngx_quic_crypto_provide(c, pkt->level) != NGX_OK) {
  512.         return NGX_ERROR;
  513.     }

  514.     return ngx_quic_handshake(c);
  515. }


  516. static ngx_int_t
  517. ngx_quic_handshake(ngx_connection_t *c)
  518. {
  519.     int                     n, sslerr;
  520.     ngx_ssl_conn_t         *ssl_conn;
  521.     ngx_quic_frame_t       *frame;
  522.     ngx_quic_connection_t  *qc;

  523.     qc = ngx_quic_get_connection(c);

  524.     ssl_conn = c->ssl->connection;

  525.     n = SSL_do_handshake(ssl_conn);

  526.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);

  527.     if (n <= 0) {
  528.         sslerr = SSL_get_error(ssl_conn, n);

  529.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d",
  530.                        sslerr);

  531.         if (c->ssl->handshake_rejected) {
  532.             ngx_connection_error(c, 0, "handshake rejected");
  533.             ERR_clear_error();
  534.             return NGX_ERROR;
  535.         }

  536.         if (qc->error) {
  537.             ngx_connection_error(c, 0, "SSL_do_handshake() failed");
  538.             ERR_clear_error();
  539.             return NGX_ERROR;
  540.         }

  541.         if (sslerr != SSL_ERROR_WANT_READ) {
  542.             ngx_ssl_connection_error(c, sslerr, 0, "SSL_do_handshake() failed");
  543.             return NGX_ERROR;
  544.         }
  545.     }

  546.     if (qc->error) {
  547.         ngx_connection_error(c, 0, "SSL_do_handshake() failed");
  548.         return NGX_ERROR;
  549.     }

  550.     if (!SSL_is_init_finished(ssl_conn)) {
  551.         if (ngx_quic_keys_available(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA, 0)
  552.             && qc->client_tp_done)
  553.         {
  554.             if (ngx_quic_init_streams(c) != NGX_OK) {
  555.                 return NGX_ERROR;
  556.             }
  557.         }

  558.         return NGX_OK;
  559.     }

  560. #if (NGX_DEBUG)
  561.     ngx_ssl_handshake_log(c);
  562. #endif

  563.     c->ssl->handshaked = 1;

  564.     frame = ngx_quic_alloc_frame(c);
  565.     if (frame == NULL) {
  566.         return NGX_ERROR;
  567.     }

  568.     frame->level = NGX_QUIC_ENCRYPTION_APPLICATION;
  569.     frame->type = NGX_QUIC_FT_HANDSHAKE_DONE;
  570.     ngx_quic_queue_frame(qc, frame);

  571.     if (qc->conf->retry) {
  572.         if (ngx_quic_send_new_token(c, qc->path) != NGX_OK) {
  573.             return NGX_ERROR;
  574.         }
  575.     }

  576.     /*
  577.      * RFC 9001, 9.5.  Header Protection Timing Side Channels
  578.      *
  579.      * Generating next keys before a key update is received.
  580.      */

  581.     ngx_post_event(&qc->key_update, &ngx_posted_events);

  582.     /*
  583.      * RFC 9001, 4.9.2.  Discarding Handshake Keys
  584.      *
  585.      * An endpoint MUST discard its Handshake keys
  586.      * when the TLS handshake is confirmed.
  587.      */
  588.     ngx_quic_discard_ctx(c, NGX_QUIC_ENCRYPTION_HANDSHAKE);

  589.     ngx_quic_discover_path_mtu(c, qc->path);

  590.     /* start accepting clients on negotiated number of server ids */
  591.     if (ngx_quic_create_sockets(c) != NGX_OK) {
  592.         return NGX_ERROR;
  593.     }

  594.     if (ngx_quic_init_streams(c) != NGX_OK) {
  595.         return NGX_ERROR;
  596.     }

  597.     return NGX_OK;
  598. }


  599. static ngx_int_t
  600. ngx_quic_crypto_provide(ngx_connection_t *c, ngx_uint_t level)
  601. {
  602. #if (NGX_QUIC_BORINGSSL_API || NGX_QUIC_QUICTLS_API)

  603.     ngx_buf_t                    *b;
  604.     ngx_chain_t                  *out, *cl;
  605.     ngx_quic_send_ctx_t          *ctx;
  606.     ngx_quic_connection_t        *qc;
  607.     enum ssl_encryption_level_t   ssl_level;

  608.     qc = ngx_quic_get_connection(c);
  609.     ctx = ngx_quic_get_send_ctx(qc, level);

  610.     out = ngx_quic_read_buffer(c, &ctx->crypto, (uint64_t) -1);
  611.     if (out == NGX_CHAIN_ERROR) {
  612.         return NGX_ERROR;
  613.     }

  614.     switch (level) {
  615.     case NGX_QUIC_ENCRYPTION_INITIAL:
  616.         ssl_level = ssl_encryption_initial;
  617.         break;
  618.     case NGX_QUIC_ENCRYPTION_EARLY_DATA:
  619.         ssl_level = ssl_encryption_early_data;
  620.         break;
  621.     case NGX_QUIC_ENCRYPTION_HANDSHAKE:
  622.         ssl_level = ssl_encryption_handshake;
  623.         break;
  624.     default: /* NGX_QUIC_ENCRYPTION_APPLICATION */
  625.         ssl_level = ssl_encryption_application;
  626.         break;
  627.     }

  628.     for (cl = out; cl; cl = cl->next) {
  629.         b = cl->buf;

  630.         if (!SSL_provide_quic_data(c->ssl->connection, ssl_level, b->pos,
  631.                                    b->last - b->pos))
  632.         {
  633.             ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  634.                           "SSL_provide_quic_data() failed");
  635.             return NGX_ERROR;
  636.         }
  637.     }

  638.     ngx_quic_free_chain(c, out);

  639. #endif

  640.     return NGX_OK;
  641. }


  642. ngx_int_t
  643. ngx_quic_init_connection(ngx_connection_t *c)
  644. {
  645.     u_char                 *p;
  646.     size_t                  clen;
  647.     ssize_t                 len;
  648.     ngx_str_t               dcid;
  649.     ngx_ssl_conn_t         *ssl_conn;
  650.     ngx_quic_socket_t      *qsock;
  651.     ngx_quic_connection_t  *qc;

  652. #if (NGX_QUIC_OPENSSL_API)
  653.     static const OSSL_DISPATCH  qtdis[] = {

  654.         { OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_SEND,
  655.           (void (*)(void)) ngx_quic_cbs_send },

  656.         { OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_RECV_RCD,
  657.           (void (*)(void)) ngx_quic_cbs_recv_rcd },

  658.         { OSSL_FUNC_SSL_QUIC_TLS_CRYPTO_RELEASE_RCD,
  659.           (void (*)(void)) ngx_quic_cbs_release_rcd },

  660.         { OSSL_FUNC_SSL_QUIC_TLS_YIELD_SECRET,
  661.           (void (*)(void)) ngx_quic_cbs_yield_secret },

  662.         { OSSL_FUNC_SSL_QUIC_TLS_GOT_TRANSPORT_PARAMS,
  663.           (void (*)(void)) ngx_quic_cbs_got_transport_params },

  664.         { OSSL_FUNC_SSL_QUIC_TLS_ALERT,
  665.           (void (*)(void)) ngx_quic_cbs_alert },

  666.         { 0, NULL }
  667.     };
  668. #else /* NGX_QUIC_BORINGSSL_API || NGX_QUIC_QUICTLS_API */
  669.     static SSL_QUIC_METHOD  quic_method;
  670. #endif

  671.     qc = ngx_quic_get_connection(c);

  672.     if (ngx_ssl_create_connection(qc->conf->ssl, c, 0) != NGX_OK) {
  673.         return NGX_ERROR;
  674.     }

  675.     c->ssl->no_wait_shutdown = 1;

  676.     ssl_conn = c->ssl->connection;

  677. #if (NGX_QUIC_OPENSSL_API)

  678.     if (SSL_set_quic_tls_cbs(ssl_conn, qtdis, c) == 0) {
  679.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  680.                       "quic SSL_set_quic_tls_cbs() failed");
  681.         return NGX_ERROR;
  682.     }

  683.     if (SSL_CTX_get_max_early_data(qc->conf->ssl->ctx)) {
  684.         SSL_set_quic_tls_early_data_enabled(ssl_conn, 1);
  685.     }

  686. #else /* NGX_QUIC_BORINGSSL_API || NGX_QUIC_QUICTLS_API */

  687.     if (!quic_method.send_alert) {
  688. #if (NGX_QUIC_BORINGSSL_API)
  689.         quic_method.set_read_secret = ngx_quic_set_read_secret;
  690.         quic_method.set_write_secret = ngx_quic_set_write_secret;
  691. #else
  692.         quic_method.set_encryption_secrets = ngx_quic_set_encryption_secrets;
  693. #endif
  694.         quic_method.add_handshake_data = ngx_quic_add_handshake_data;
  695.         quic_method.flush_flight = ngx_quic_flush_flight;
  696.         quic_method.send_alert = ngx_quic_send_alert;
  697.     }

  698.     if (SSL_set_quic_method(ssl_conn, &quic_method) == 0) {
  699.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  700.                       "quic SSL_set_quic_method() failed");
  701.         return NGX_ERROR;
  702.     }

  703. #if (NGX_QUIC_QUICTLS_API)
  704.     if (SSL_CTX_get_max_early_data(qc->conf->ssl->ctx)) {
  705.         SSL_set_quic_early_data_enabled(ssl_conn, 1);
  706.     }
  707. #endif

  708. #endif

  709.     qsock = ngx_quic_get_socket(c);

  710.     dcid.data = qsock->sid.id;
  711.     dcid.len = qsock->sid.len;

  712.     if (ngx_quic_new_sr_token(c, &dcid, qc->conf->sr_token_key, qc->tp.sr_token)
  713.         != NGX_OK)
  714.     {
  715.         return NGX_ERROR;
  716.     }

  717.     len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp, &clen);
  718.     /* always succeeds */

  719.     p = ngx_pnalloc(c->pool, len);
  720.     if (p == NULL) {
  721.         return NGX_ERROR;
  722.     }

  723.     len = ngx_quic_create_transport_params(p, p + len, &qc->tp, NULL);
  724.     if (len < 0) {
  725.         return NGX_ERROR;
  726.     }

  727. #ifdef NGX_QUIC_DEBUG_PACKETS
  728.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  729.                    "quic transport parameters len:%uz %*xs", len, len, p);
  730. #endif

  731. #if (NGX_QUIC_OPENSSL_API)
  732.     if (SSL_set_quic_tls_transport_params(ssl_conn, p, len) == 0) {
  733.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  734.                       "quic SSL_set_quic_tls_transport_params() failed");
  735.         return NGX_ERROR;
  736.     }
  737. #else
  738.     if (SSL_set_quic_transport_params(ssl_conn, p, len) == 0) {
  739.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  740.                       "quic SSL_set_quic_transport_params() failed");
  741.         return NGX_ERROR;
  742.     }
  743. #endif

  744. #if (defined OPENSSL_IS_BORINGSSL || defined OPENSSL_IS_AWSLC)
  745.     if (SSL_set_quic_early_data_context(ssl_conn, p, clen) == 0) {
  746.         ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
  747.                       "quic SSL_set_quic_early_data_context() failed");
  748.         return NGX_ERROR;
  749.     }
  750. #endif

  751.     return NGX_OK;
  752. }