diff options
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/quic/build.info | 1 | ||||
-rw-r--r-- | ssl/quic/quic_dummy_handshake.c | 575 |
2 files changed, 0 insertions, 576 deletions
diff --git a/ssl/quic/build.info b/ssl/quic/build.info index f8011a4bf7..79aa00dbba 100644 --- a/ssl/quic/build.info +++ b/ssl/quic/build.info @@ -8,7 +8,6 @@ SOURCE[$LIBSSL]=quic_fc.c uint_set.c SOURCE[$LIBSSL]=quic_cfq.c quic_txpim.c quic_fifd.c quic_txp.c SOURCE[$LIBSSL]=quic_stream_map.c SOURCE[$LIBSSL]=quic_sf_list.c quic_rstream.c quic_sstream.c -SOURCE[$LIBSSL]=quic_dummy_handshake.c SOURCE[$LIBSSL]=quic_reactor.c SOURCE[$LIBSSL]=quic_channel.c SOURCE[$LIBSSL]=quic_tserver.c diff --git a/ssl/quic/quic_dummy_handshake.c b/ssl/quic/quic_dummy_handshake.c deleted file mode 100644 index 9c37db98b2..0000000000 --- a/ssl/quic/quic_dummy_handshake.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include <openssl/macros.h> -#include <openssl/objects.h> -#include "internal/quic_dummy_handshake.h" - -#define QUIC_DHS_MSG_TYPE_CH 0x01 -#define QUIC_DHS_MSG_TYPE_SH 0x02 -#define QUIC_DHS_MSG_TYPE_EE 0x08 -#define QUIC_DHS_MSG_TYPE_CERT 0x0B -#define QUIC_DHS_MSG_TYPE_CERT_VERIFY 0x0F -#define QUIC_DHS_MSG_TYPE_FINISHED 0x14 - -#define QUIC_DHS_CLIENT_STATE_INITIAL 0x00 -#define QUIC_DHS_CLIENT_STATE_SENT_CH 0x01 -#define QUIC_DHS_CLIENT_STATE_RECEIVED_SH 0x02 -#define QUIC_DHS_CLIENT_STATE_RECEIVED_EE_HDR 0x08 -#define QUIC_DHS_CLIENT_STATE_RECEIVED_EE 0x03 -#define QUIC_DHS_CLIENT_STATE_RECEIVED_CERT 0x04 -#define QUIC_DHS_CLIENT_STATE_RECEIVED_CERT_VERIFY 0x05 -#define QUIC_DHS_CLIENT_STATE_RECEIVED_FINISHED 0x06 -#define QUIC_DHS_CLIENT_STATE_SENT_FINISHED 0x07 -#define QUIC_DHS_CLIENT_STATE_ERROR 0xFF - -#define QUIC_DHS_SERVER_STATE_INITIAL 0x00 -#define QUIC_DHS_SERVER_STATE_RECEIVED_CH_HDR 0x01 -#define QUIC_DHS_SERVER_STATE_RECEIVED_CH 0x02 -#define QUIC_DHS_SERVER_STATE_SENT_SH 0x03 -#define QUIC_DHS_SERVER_STATE_SENT_EE 0x04 -#define QUIC_DHS_SERVER_STATE_SENT_CERT 0x05 -#define QUIC_DHS_SERVER_STATE_SENT_CERT_VERIFY 0x06 -#define QUIC_DHS_SERVER_STATE_SENT_FINISHED 0x07 -#define QUIC_DHS_SERVER_STATE_RECEIVED_FINISHED 0x08 -#define QUIC_DHS_SERVER_STATE_ERROR 0xFF - -struct quic_dhs_st { - QUIC_DHS_ARGS args; - unsigned char state; - unsigned char *remote_transport_params; - size_t remote_transport_params_len; - const unsigned char *local_transport_params; - size_t local_transport_params_len; - unsigned char rx_hdr[4]; - size_t rx_hdr_bytes_read; - size_t rx_bytes_read; -}; - -QUIC_DHS *ossl_quic_dhs_new(const QUIC_DHS_ARGS *args) -{ - QUIC_DHS *dhs; - - if (args->crypto_send_cb == NULL - || args->crypto_recv_cb == NULL) - return NULL; - - dhs = OPENSSL_zalloc(sizeof(*dhs)); - if (dhs == NULL) - return NULL; - - dhs->args = *args; - return dhs; -} - -void ossl_quic_dhs_free(QUIC_DHS *dhs) -{ - if (dhs == NULL) - return; - - OPENSSL_free(dhs->remote_transport_params); - OPENSSL_free(dhs); -} - -/* Send a handshake message. */ -static int dhs_send(QUIC_DHS *dhs, unsigned char type, - const void *buf, size_t buf_len) -{ - size_t consumed = 0; - uint32_t len; - unsigned char hdr[4]; - - len = buf_len; - hdr[0] = type; - hdr[1] = (len >> 16) & 0xFF; - hdr[2] = (len >> 8) & 0xFF; - hdr[3] = (len ) & 0xFF; - - if (!dhs->args.crypto_send_cb(hdr, sizeof(hdr), &consumed, - dhs->args.crypto_send_cb_arg) - || consumed < sizeof(hdr) - || (buf_len > 0 && (!dhs->args.crypto_send_cb(buf, buf_len, &consumed, - dhs->args.crypto_send_cb_arg) - || consumed < buf_len))) - /* - * We do not handle a full buffer here properly but the DHS produces so - * little data this should not matter. By the time we want to fix this - * the real handshake layer will be ready. - */ - return 0; - - return 1; -} - -/* - * Receive header of a handshake message. Length of body is written to - * *frame_len, and if non-zero this call should be followed by one or more calls - * to dhs_recv_body. - */ -static int dhs_recv_sof(QUIC_DHS *dhs, uint32_t *type, size_t *frame_len) -{ - size_t bytes_read = 0; - uint32_t l; - - if (!dhs->args.crypto_recv_cb(dhs->rx_hdr + dhs->rx_hdr_bytes_read, - sizeof(dhs->rx_hdr) - dhs->rx_hdr_bytes_read, - &bytes_read, - dhs->args.crypto_recv_cb_arg)) - return 0; - - dhs->rx_hdr_bytes_read += bytes_read; - if (dhs->rx_hdr_bytes_read < sizeof(dhs->rx_hdr)) { - /* Not got entire header yet. */ - *type = UINT32_MAX; - *frame_len = 0; - return 2; - } - - l = (((uint32_t)dhs->rx_hdr[1]) << 16) - | (((uint32_t)dhs->rx_hdr[2]) << 8) - | (uint32_t)dhs->rx_hdr[3]; - - if (l > SIZE_MAX) - return 0; - - *type = dhs->rx_hdr[0]; - *frame_len = (size_t)l; - - dhs->rx_hdr_bytes_read = 0; - return 1; -} - -/* Receive the body of an incoming message, or part thereof. */ -static int dhs_recv_body(QUIC_DHS *dhs, unsigned char *buf, size_t buf_len, - size_t *bytes_read) -{ - if (!dhs->args.crypto_recv_cb(buf, buf_len, bytes_read, - dhs->args.crypto_recv_cb_arg)) - return 0; - - if (*bytes_read == 0) - return 2; - - return 1; -} - -static const unsigned char default_handshake_read[32] = {42, 2}; -static const unsigned char default_handshake_write[32] = {42, 1}; -static const unsigned char default_1rtt_read[32] = {43, 2}; -static const unsigned char default_1rtt_write[32] = {43, 1}; - -int ossl_quic_dhs_set_transport_params(QUIC_DHS *dhs, const unsigned char *transport_params, - size_t transport_params_len) -{ - if (!dhs->args.is_server && dhs->state != QUIC_DHS_CLIENT_STATE_INITIAL) - return 0; - - dhs->local_transport_params = transport_params; - dhs->local_transport_params_len = transport_params_len; - return 1; -} - -/* Tick implementation for the client role. */ -static int dhs_tick_client(QUIC_DHS *dhs) -{ - int ret; - uint32_t type; - size_t frame_len, bytes_read = 0; - - for (;;) { - switch (dhs->state) { - case QUIC_DHS_CLIENT_STATE_INITIAL: - /* We need to send a CH */ - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_CH, - dhs->local_transport_params, - dhs->local_transport_params_len)) - return 0; - - dhs->state = QUIC_DHS_CLIENT_STATE_SENT_CH; - break; - - case QUIC_DHS_CLIENT_STATE_SENT_CH: - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_SH && frame_len == 0) { - dhs->state = QUIC_DHS_CLIENT_STATE_RECEIVED_SH; - - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_HANDSHAKE, - /*TX=*/0, - QRL_SUITE_AES128GCM, - NULL, - default_handshake_read, - sizeof(default_handshake_read), - dhs->args.yield_secret_cb_arg)) { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; - } - - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_HANDSHAKE, - /*TX=*/1, - QRL_SUITE_AES128GCM, - NULL, - default_handshake_write, - sizeof(default_handshake_write), - dhs->args.yield_secret_cb_arg)) { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; - } - - } else { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_CLIENT_STATE_RECEIVED_SH: - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_EE) { - dhs->state = QUIC_DHS_CLIENT_STATE_RECEIVED_EE_HDR; - dhs->rx_bytes_read = 0; - dhs->remote_transport_params_len = frame_len; - dhs->remote_transport_params - = OPENSSL_malloc(dhs->remote_transport_params_len); - if (dhs->remote_transport_params == NULL) - return 0; - } else { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_CLIENT_STATE_RECEIVED_EE_HDR: - ret = dhs_recv_body(dhs, dhs->remote_transport_params + dhs->rx_bytes_read, - dhs->remote_transport_params_len - dhs->rx_bytes_read, - &bytes_read); - if (ret == 1) { - dhs->rx_bytes_read += bytes_read; - if (bytes_read == dhs->remote_transport_params_len) { - if (!dhs->args.got_transport_params_cb(dhs->remote_transport_params, - dhs->remote_transport_params_len, - dhs->args.got_transport_params_cb_arg)) { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; - } - - dhs->state = QUIC_DHS_CLIENT_STATE_RECEIVED_EE; - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_CLIENT_STATE_RECEIVED_EE: - /* Expect Cert */ - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_CERT && frame_len == 0) { - dhs->state = QUIC_DHS_CLIENT_STATE_RECEIVED_CERT; - } else { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_CLIENT_STATE_RECEIVED_CERT: - /* Expect CertVerify */ - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_CERT_VERIFY && frame_len == 0) { - dhs->state = QUIC_DHS_CLIENT_STATE_RECEIVED_CERT_VERIFY; - } else { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_CLIENT_STATE_RECEIVED_CERT_VERIFY: - /* Expect Finished */ - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_FINISHED && frame_len == 0) { - dhs->state = QUIC_DHS_CLIENT_STATE_RECEIVED_FINISHED; - } else { - dhs->state = QUIC_DHS_CLIENT_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_CLIENT_STATE_RECEIVED_FINISHED: - /* Send Finished */ - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_FINISHED, NULL, 0)) - return 0; - - dhs->state = QUIC_DHS_CLIENT_STATE_SENT_FINISHED; - - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_1RTT, - /*TX=*/0, - QRL_SUITE_AES128GCM, - NULL, - default_1rtt_read, - sizeof(default_1rtt_read), - dhs->args.yield_secret_cb_arg)) - return 0; - - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_1RTT, - /*TX=*/1, - QRL_SUITE_AES128GCM, - NULL, - default_1rtt_write, - sizeof(default_1rtt_write), - dhs->args.yield_secret_cb_arg)) - return 0; - - if (!dhs->args.handshake_complete_cb(dhs->args.handshake_complete_cb_arg)) - return 0; - - dhs->local_transport_params = NULL; - dhs->local_transport_params_len = 0; - break; - - case QUIC_DHS_CLIENT_STATE_SENT_FINISHED: - /* Nothing to do, handshake complete. */ - return 1; - - default: - return 0; /* error state */ - } - } - - return 1; -} - -/* Tick implementation for the server role. */ -static int dhs_tick_server(QUIC_DHS *dhs) -{ - int ret; - uint32_t type; - size_t frame_len, bytes_read = 0; - - for (;;) { - switch (dhs->state) { - case QUIC_DHS_SERVER_STATE_INITIAL: - /* Waiting for ClientHello message */ - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_CH && frame_len > 0) { - dhs->state = QUIC_DHS_SERVER_STATE_RECEIVED_CH_HDR; - dhs->rx_bytes_read = 0; - dhs->remote_transport_params_len = frame_len; - dhs->remote_transport_params - = OPENSSL_malloc(dhs->remote_transport_params_len); - - if (dhs->remote_transport_params == NULL) - return 0; - - } else { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - - break; - - case QUIC_DHS_SERVER_STATE_RECEIVED_CH_HDR: - ret = dhs_recv_body(dhs, dhs->remote_transport_params + dhs->rx_bytes_read, - dhs->remote_transport_params_len - dhs->rx_bytes_read, - &bytes_read); - if (ret == 1) { - dhs->rx_bytes_read += bytes_read; - if (dhs->rx_bytes_read == dhs->remote_transport_params_len) { - if (!dhs->args.got_transport_params_cb(dhs->remote_transport_params, - dhs->remote_transport_params_len, - dhs->args.got_transport_params_cb_arg)) { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; - } - - dhs->state = QUIC_DHS_SERVER_STATE_RECEIVED_CH; - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_SERVER_STATE_RECEIVED_CH: - /* We need to send a ServerHello message */ - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_SH, NULL, 0)) - return 0; - - /* - * Our send function automatically sends at the highest - * available EL so we need to do this after sending the SH. - */ - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_HANDSHAKE, - /* (Keys reversed - server) */ - /*TX=*/0, - QRL_SUITE_AES128GCM, - NULL, - default_handshake_write, - sizeof(default_handshake_write), - dhs->args.yield_secret_cb_arg)) { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; - } - - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_HANDSHAKE, - /* (Keys reversed - server) */ - /*TX=*/1, - QRL_SUITE_AES128GCM, - NULL, - default_handshake_read, - sizeof(default_handshake_read), - dhs->args.yield_secret_cb_arg)) { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; - } - - dhs->state = QUIC_DHS_SERVER_STATE_SENT_SH; - break; - - case QUIC_DHS_SERVER_STATE_SENT_SH: - /* We need to send an EncryptedExtensions message */ - if (dhs->local_transport_params == NULL - || dhs->local_transport_params_len == 0) - return 0; - - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_EE, - dhs->local_transport_params, - dhs->local_transport_params_len)) - return 0; - - dhs->local_transport_params = NULL; - dhs->local_transport_params_len = 0; - - dhs->state = QUIC_DHS_SERVER_STATE_SENT_EE; - break; - - case QUIC_DHS_SERVER_STATE_SENT_EE: - /* We need to send a Certificate message */ - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_CERT, NULL, 0)) - return 0; - - dhs->state = QUIC_DHS_SERVER_STATE_SENT_CERT; - break; - - case QUIC_DHS_SERVER_STATE_SENT_CERT: - /* We need to send a CertificateVerify message */ - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_CERT_VERIFY, NULL, 0)) - return 0; - - dhs->state = QUIC_DHS_SERVER_STATE_SENT_CERT_VERIFY; - break; - - case QUIC_DHS_SERVER_STATE_SENT_CERT_VERIFY: - /* We need to send a Finished message */ - if (!dhs_send(dhs, QUIC_DHS_MSG_TYPE_FINISHED, NULL, 0)) - return 0; - - dhs->state = QUIC_DHS_SERVER_STATE_SENT_FINISHED; - break; - - case QUIC_DHS_SERVER_STATE_SENT_FINISHED: - /* We are waiting for a Finished message. */ - ret = dhs_recv_sof(dhs, &type, &frame_len); - if (ret == 1) { - if (type == QUIC_DHS_MSG_TYPE_FINISHED && frame_len == 0) { - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_1RTT, - /* (Keys reversed - server) */ - /*TX=*/0, - QRL_SUITE_AES128GCM, - NULL, - default_1rtt_write, - sizeof(default_1rtt_write), - dhs->args.yield_secret_cb_arg)) { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; - } - - if (!dhs->args.yield_secret_cb(QUIC_ENC_LEVEL_1RTT, - /* (Keys reversed - server) */ - /*TX=*/1, - QRL_SUITE_AES128GCM, - NULL, - default_1rtt_read, - sizeof(default_1rtt_read), - dhs->args.yield_secret_cb_arg)) { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; - } - - if (!dhs->args.handshake_complete_cb(dhs->args.handshake_complete_cb_arg)) { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; - } - - dhs->state = QUIC_DHS_SERVER_STATE_RECEIVED_FINISHED; - } else { - dhs->state = QUIC_DHS_SERVER_STATE_ERROR; - return 0; /* error state, unexpected type */ - } - } else if (ret == 2) { - return 1; /* no more data yet, not an error */ - } else { - return 0; - } - break; - - case QUIC_DHS_SERVER_STATE_RECEIVED_FINISHED: - /* Nothing to do, handshake complete. */ - return 1; - - default: - return 0; /* error state */ - } - } - - return 1; -} - -int ossl_quic_dhs_tick(QUIC_DHS *dhs) -{ - if (dhs->args.is_server) - return dhs_tick_server(dhs); - else - return dhs_tick_client(dhs); -} |