From 7aa3f2283a7ee3ec53a655244ed6342418a2e5d9 Mon Sep 17 00:00:00 2001 From: huitema <huitema@huitema.net> Date: Wed, 30 May 2018 21:55:17 -0700 Subject: [PATCH] Unified function for header parse and packet decrypt, plus unit test. --- UnitTest1/unittest1.cpp | 8 + picoquic/packet.c | 89 ++++++++++ picoquic/picoquic.h | 1 + picoquic/picoquic_internal.h | 17 ++ picoquic/sender.c | 56 +++--- picoquic/tls_api.c | 22 +++ picoquic/tls_api.h | 3 + picoquic_t/picoquic_t.c | 3 +- picoquictest/cleartext_aead_test.c | 3 +- picoquictest/parseheadertest.c | 264 ++++++++++++++++++++++++++++- picoquictest/picoquictest.h | 1 + 11 files changed, 442 insertions(+), 25 deletions(-) diff --git a/UnitTest1/unittest1.cpp b/UnitTest1/unittest1.cpp index 67bec4fd..08c802f1 100644 --- a/UnitTest1/unittest1.cpp +++ b/UnitTest1/unittest1.cpp @@ -533,5 +533,13 @@ namespace UnitTest1 Assert::AreEqual(ret, 0); } + + TEST_METHOD(test_packet_enc_dec) + { + int ret = packet_enc_dec_test(); + + Assert::AreEqual(ret, 0); + } + }; } diff --git a/picoquic/packet.c b/picoquic/packet.c index 688f6f50..22e81a28 100644 --- a/picoquic/packet.c +++ b/picoquic/packet.c @@ -404,6 +404,95 @@ size_t picoquic_decrypt_cleartext(picoquic_cnx_t* cnx, return decoded_length; } +int picoquic_parse_header_and_decrypt( + picoquic_quic_t* quic, + uint8_t* bytes, + uint32_t length, + uint32_t packet_length, + struct sockaddr* addr_from, + uint64_t current_time, + picoquic_packet_header* ph, + picoquic_cnx_t** pcnx, + uint32_t * consumed, + int receiving) +{ + /* Parse the clear text header. Ret == 0 means an incorrect packet that could not be parsed */ + int already_received = 0; + size_t decoded_length = 0; + int ret = picoquic_parse_packet_header(quic, bytes, length, addr_from, ph, pcnx, receiving); + int cmp_reset_secret = 0; + + if (ret == 0) { + length = ph->offset + ph->payload_length; + *consumed = length; + + if (*pcnx == NULL && ph->ptype == picoquic_packet_client_initial) { + /* Create a connection context if the CI is acceptable */ + if (packet_length < PICOQUIC_ENFORCED_INITIAL_MTU) { + /* Unexpected packet. Reject, drop and log. */ + ret = PICOQUIC_ERROR_INITIAL_TOO_SHORT; + } + else { + /* if listening is OK, listen */ + *pcnx = picoquic_create_cnx(quic, ph->dest_cnx_id, ph->srce_cnx_id, addr_from, current_time, ph->vn, NULL, NULL, 0); + } + } + + if (*pcnx != NULL) { + /* Decrypt the sequence number if needed, and then decrypt the packet */ + switch (ph->ptype) { + case picoquic_packet_version_negotiation: + /* Packet is not encrypted */ + break; + case picoquic_packet_client_initial: + decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph, + (*pcnx)->pn_dec_cleartext, (*pcnx)->aead_decrypt_cleartext_ctx, &already_received); + break; + case picoquic_packet_server_stateless: + decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph, + (*pcnx)->pn_dec_cleartext, (*pcnx)->aead_decrypt_cleartext_ctx, &already_received); + break; + case picoquic_packet_handshake: + decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph, + (*pcnx)->pn_dec_cleartext, (*pcnx)->aead_decrypt_cleartext_ctx, &already_received); + break; + case picoquic_packet_0rtt_protected: + decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph, (*pcnx)->pn_enc_0rtt, + (*pcnx)->aead_0rtt_decrypt_ctx, &already_received); + break; + case picoquic_packet_1rtt_protected_phi0: + case picoquic_packet_1rtt_protected_phi1: + /* TODO : roll key based on PHI */ + /* Check the possible reset before performing in place AEAD decrypt */ + cmp_reset_secret = memcmp(bytes + length - PICOQUIC_RESET_SECRET_SIZE, + (*pcnx)->reset_secret, PICOQUIC_RESET_SECRET_SIZE); + /* AEAD Decrypt, in place */ + decoded_length = picoquic_decrypt_packet(*pcnx, bytes, length, ph, (*pcnx)->pn_dec, + (*pcnx)->aead_decrypt_ctx, &already_received); + break; + default: + /* Packet type error. Log and ignore */ + ret = PICOQUIC_ERROR_DETECTED; + break; + } + + /* TODO: consider the error "too soon" */ + if (decoded_length > (length - ph->offset)) { + if (cmp_reset_secret == 0) { + ret = PICOQUIC_ERROR_STATELESS_RESET; + } else { + ret = PICOQUIC_ERROR_AEAD_CHECK; + } + } else if (already_received != 0) { + ret = PICOQUIC_ERROR_DUPLICATE; + } else { + ph->payload_length = (uint16_t)decoded_length; + } + } + } + + return ret; +} /* * Processing of a version renegotiation packet. * diff --git a/picoquic/picoquic.h b/picoquic/picoquic.h index 89d27ef2..07bc895e 100644 --- a/picoquic/picoquic.h +++ b/picoquic/picoquic.h @@ -69,6 +69,7 @@ extern "C" { #define PICOQUIC_ERROR_UNEXPECTED_ERROR (PICOQUIC_ERROR_CLASS + 27) #define PICOQUIC_ERROR_TLS_SERVER_CON_WITHOUT_CERT (PICOQUIC_ERROR_CLASS + 28) #define PICOQUIC_ERROR_NO_SUCH_FILE (PICOQUIC_ERROR_CLASS + 29) +#define PICOQUIC_ERROR_STATELESS_RESET (PICOQUIC_ERROR_CLASS + 30) /* * Protocol errors defined in the QUIC spec diff --git a/picoquic/picoquic_internal.h b/picoquic/picoquic_internal.h index 7a736657..7369ab15 100644 --- a/picoquic/picoquic_internal.h +++ b/picoquic/picoquic_internal.h @@ -585,6 +585,23 @@ uint32_t picoquic_protect_packet(picoquic_cnx_t* cnx, uint8_t* send_buffer, void * aead_context, void* pn_enc); +void picoquic_finalize_and_protect_packet(picoquic_cnx_t *cnx, picoquic_packet * packet, int ret, + uint32_t length, uint32_t header_length, uint32_t checksum_overhead, + size_t * send_length, uint8_t * send_buffer, picoquic_path_t * path_x, + uint64_t current_time); + +int picoquic_parse_header_and_decrypt( + picoquic_quic_t* quic, + uint8_t* bytes, + uint32_t length, + uint32_t packet_length, + struct sockaddr* addr_from, + uint64_t current_time, + picoquic_packet_header* ph, + picoquic_cnx_t** pcnx, + uint32_t * consumed, + int receiving); + /* handling of ACK logic */ int picoquic_is_ack_needed(picoquic_cnx_t* cnx, uint64_t current_time); diff --git a/picoquic/sender.c b/picoquic/sender.c index 034855c5..3484a00d 100644 --- a/picoquic/sender.c +++ b/picoquic/sender.c @@ -468,37 +468,51 @@ void picoquic_queue_for_retransmit(picoquic_cnx_t* cnx, picoquic_path_t * path_x */ void picoquic_finalize_and_protect_packet(picoquic_cnx_t *cnx, picoquic_packet * packet, int ret, - int is_cleartext_mode, uint32_t length, uint32_t header_length, uint32_t checksum_overhead, + uint32_t length, uint32_t header_length, uint32_t checksum_overhead, size_t * send_length, uint8_t * send_buffer, picoquic_path_t * path_x, uint64_t current_time) { if (ret == 0 && length > 0) { packet->length = length; cnx->send_sequence++; - /* Make sure that the payload length is encoded in the header */ - picoquic_update_payload_length(packet->bytes, header_length, length + checksum_overhead); - if (is_cleartext_mode == 1) { - /* AEAD Encrypt, to the send buffer */ + switch (packet->ptype) { + + case picoquic_packet_version_negotiation: + /* Packet is not encrypted */ + break; + case picoquic_packet_client_initial: + case picoquic_packet_server_stateless: + case picoquic_packet_handshake: length = picoquic_protect_packet(cnx, packet->ptype, packet->bytes, packet->sequence_number, - length, header_length, + length, header_length, send_buffer, cnx->aead_encrypt_cleartext_ctx, cnx->pn_enc_cleartext); - } else if (is_cleartext_mode == 0) { - /* AEAD Encrypt, to the send buffer */ - length = picoquic_protect_packet(cnx, packet->ptype, packet->bytes, packet->sequence_number, - length, header_length, - send_buffer, cnx->aead_encrypt_ctx, cnx->pn_enc); - } else if (is_cleartext_mode == -1) { - /* AEAD Encrypt, to the send buffer */ + break; + case picoquic_packet_0rtt_protected: length = picoquic_protect_packet(cnx, packet->ptype, packet->bytes, packet->sequence_number, - length, header_length, + length, header_length, send_buffer, cnx->aead_0rtt_encrypt_ctx, cnx->pn_enc_0rtt); + break; + case picoquic_packet_1rtt_protected_phi0: + case picoquic_packet_1rtt_protected_phi1: + length = picoquic_protect_packet(cnx, packet->ptype, packet->bytes, packet->sequence_number, + length, header_length, + send_buffer, cnx->aead_encrypt_ctx, cnx->pn_enc); + break; + default: + /* Packet type error. Do nothing at all. */ + length = 0; + break; } - packet->checksum_overhead = checksum_overhead; *send_length = length; - picoquic_queue_for_retransmit(cnx, path_x, packet, length, current_time); + if (length > 0) { + packet->checksum_overhead = checksum_overhead; + picoquic_queue_for_retransmit(cnx, path_x, packet, length, current_time); + } else { + *send_length = 0; + } } else { *send_length = 0; @@ -1080,7 +1094,7 @@ int picoquic_prepare_packet_0rtt(picoquic_cnx_t* cnx, picoquic_path_t * path_x, } picoquic_finalize_and_protect_packet(cnx, packet, - ret, -1, length, header_length, checksum_overhead, + ret, length, header_length, checksum_overhead, send_length, send_buffer, path_x, current_time); if (length > 0) { @@ -1244,7 +1258,7 @@ int picoquic_prepare_packet_client_init(picoquic_cnx_t* cnx, picoquic_path_t * p ret = picoquic_prepare_packet_0rtt(cnx, path_x, packet, current_time, send_buffer, send_length); } else { picoquic_finalize_and_protect_packet(cnx, packet, - ret, is_cleartext_mode, length, header_length, checksum_overhead, + ret, length, header_length, checksum_overhead, send_length, send_buffer, path_x, current_time); if (cnx->cnx_state != picoquic_state_draining) { @@ -1365,7 +1379,7 @@ int picoquic_prepare_packet_server_init(picoquic_cnx_t* cnx, picoquic_path_t * p } picoquic_finalize_and_protect_packet(cnx, packet, - ret, is_cleartext_mode, length, header_length, checksum_overhead, + ret, length, header_length, checksum_overhead, send_length, send_buffer, path_x, current_time); picoquic_cnx_set_next_wake_time(cnx, current_time); @@ -1558,7 +1572,7 @@ int picoquic_prepare_packet_closing(picoquic_cnx_t* cnx, picoquic_path_t * path_ } picoquic_finalize_and_protect_packet(cnx, packet, - ret, is_cleartext_mode, length, header_length, checksum_overhead, + ret, length, header_length, checksum_overhead, send_length, send_buffer, path_x, current_time); return ret; @@ -1750,7 +1764,7 @@ int picoquic_prepare_packet_ready(picoquic_cnx_t* cnx, picoquic_path_t * path_x, } picoquic_finalize_and_protect_packet(cnx, packet, - ret, is_cleartext_mode, length, header_length, checksum_overhead, + ret, length, header_length, checksum_overhead, send_length, send_buffer, path_x, current_time); picoquic_cnx_set_next_wake_time(cnx, current_time); diff --git a/picoquic/tls_api.c b/picoquic/tls_api.c index d8b0857d..91784c89 100644 --- a/picoquic/tls_api.c +++ b/picoquic/tls_api.c @@ -1048,6 +1048,17 @@ void * picoquic_pn_enc_create( return (void *)pn_enc; } +void * picoquic_pn_enc_create_for_test(const uint8_t * secret) +{ + void * ret = NULL; + ptls_hash_algorithm_t* algo = &ptls_openssl_sha256; + ptls_aead_algorithm_t* aead = &ptls_openssl_aes128gcm; + + ret = picoquic_pn_enc_create(aead, algo, (uint8_t *) secret, PICOQUIC_QUIC_BASE_LABEL); + + return ret; +} + void picoquic_pn_encrypt(void *pn_enc, void * iv, void *output, const void *input, size_t len) { ptls_cipher_init((ptls_cipher_context_t *) pn_enc, iv); @@ -1147,6 +1158,17 @@ uint32_t picoquic_aead_get_checksum_length(void* aead_context) return ((uint32_t)((ptls_aead_context_t*)aead_context)->algo->tag_size); } +/* Setting of encryption contexts for test */ +void * picoquic_setup_test_aead_context(int is_encrypt, const uint8_t * secret) +{ + void * ret = NULL; + ptls_hash_algorithm_t* algo = &ptls_openssl_sha256; + ptls_aead_algorithm_t* aead = &ptls_openssl_aes128gcm; + + ret = (void *)picoquic_aead_new(aead, algo, is_encrypt, secret, PICOQUIC_QUIC_BASE_LABEL); + return ret; +} + /* Computation of the encryption and decryption methods for 0-RTT data */ int picoquic_setup_0RTT_aead_contexts(picoquic_cnx_t* cnx, int is_server) diff --git a/picoquic/tls_api.h b/picoquic/tls_api.h index 18f86261..1cc65d16 100644 --- a/picoquic/tls_api.h +++ b/picoquic/tls_api.h @@ -67,6 +67,9 @@ void picoquic_pn_encrypt(void *pn_enc, void * iv, void *output, const void *inpu void picoquic_pn_enc_free(void * pn_enc); +void * picoquic_setup_test_aead_context(int is_encrypt, const uint8_t * secret); +void * picoquic_pn_enc_create_for_test(const uint8_t * secret); + int picoquic_compare_cleartext_aead_contexts(picoquic_cnx_t* cnx1, picoquic_cnx_t* cnx2); int picoquic_create_cnxid_reset_secret(picoquic_quic_t* quic, picoquic_connection_id_t cnx_id, diff --git a/picoquic_t/picoquic_t.c b/picoquic_t/picoquic_t.c index 03b4ad42..14599a9f 100644 --- a/picoquic_t/picoquic_t.c +++ b/picoquic_t/picoquic_t.c @@ -105,7 +105,8 @@ static const picoquic_test_def_t test_table[] = { { "nat_rebinding", nat_rebinding_test }, { "nat_rebinding_loss", nat_rebinding_loss_test }, { "spin_bit", spin_bit_test}, - { "client_error", client_error_test } + { "client_error", client_error_test }, + { "packet_enc_dec", packet_enc_dec_test} }; static size_t const nb_tests = sizeof(test_table) / sizeof(picoquic_test_def_t); diff --git a/picoquictest/cleartext_aead_test.c b/picoquictest/cleartext_aead_test.c index 87d361d2..a068808b 100644 --- a/picoquictest/cleartext_aead_test.c +++ b/picoquictest/cleartext_aead_test.c @@ -514,5 +514,4 @@ int cleartext_pn_enc_test() } return ret; -} - +} \ No newline at end of file diff --git a/picoquictest/parseheadertest.c b/picoquictest/parseheadertest.c index 8799c5b6..f13579a7 100644 --- a/picoquictest/parseheadertest.c +++ b/picoquictest/parseheadertest.c @@ -19,9 +19,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "../picoquic/picoquic_internal.h" #include <stdlib.h> #include <string.h> +#include "../picoquic/tls_api.h" +#include "../picoquic/picoquic_internal.h" /* test vectors and corresponding structure */ #define TEST_CNXID_LEN_BYTE 0x51 @@ -383,3 +384,264 @@ int parseheadertest() return ret; } + + +/* Test a range of variations of packet encryption and decryption */ +int test_packet_decrypt_one( + picoquic_quic_t* q_server, + uint8_t * send_buffer, + size_t send_length, + size_t packet_length, + struct sockaddr * addr_from, + picoquic_cnx_t* cnx_target, + picoquic_packet_header * expected_ph, + int expected_return +) +{ + int ret = 0; + int decoding_return; + uint64_t current_time = 0; + picoquic_packet_header received_ph; + picoquic_cnx_t* server_cnx = NULL; + uint32_t consumed = 0; + + /* Decrypt the packet */ + decoding_return = picoquic_parse_header_and_decrypt(q_server, + send_buffer, send_length, packet_length, + addr_from, + current_time, &received_ph, &server_cnx, + &consumed, 1); + + /* verify that decryption matches original value */ + if (decoding_return != expected_return) { + DBG_PRINTF("Return %x instead of %x.\n", decoding_return, expected_return); + ret = -1; + } else if (cnx_target != NULL && server_cnx != cnx_target) { + DBG_PRINTF("%s", "Could not retrieve the connection\n"); + ret = -1; + } + else if (received_ph.ptype != expected_ph->ptype) { + DBG_PRINTF("PTYPE %x instead of %x.\n", received_ph.ptype, expected_ph->ptype); + ret = -1; + } + else if (received_ph.offset != expected_ph->offset) { + DBG_PRINTF("Offset %x instead of %x.\n", received_ph.offset, expected_ph->offset); + ret = -1; + } + else if (received_ph.vn != expected_ph->vn) { + DBG_PRINTF("Version %x instead of %x.\n", received_ph.vn, expected_ph->vn); + ret = -1; + } + else if (received_ph.pn64 != expected_ph->pn64) { + DBG_PRINTF("PN64 %llx instead of %llx.\n", (unsigned long long)received_ph.pn64, (unsigned long long)expected_ph->pn64); + ret = -1; + } + else if (received_ph.payload_length != expected_ph->payload_length) { + DBG_PRINTF("Payload length %x instead of %x.\n", received_ph.payload_length, expected_ph->payload_length); + ret = -1; + } + else if (picoquic_compare_connection_id(&received_ph.dest_cnx_id, &expected_ph->dest_cnx_id) != 0) { + DBG_PRINTF("%s", "Dest CNXID does not match.\n"); + ret = -1; + } + else if (picoquic_compare_connection_id(&received_ph.srce_cnx_id, &expected_ph->srce_cnx_id) != 0) { + DBG_PRINTF("%s", "Srce CNXID does not match.\n"); + ret = -1; + } + + return ret; +} + +int test_packet_encrypt_one( + struct sockaddr * addr_from, + picoquic_cnx_t* cnx_client, + picoquic_quic_t* q_server, + picoquic_cnx_t* server_cnx, + picoquic_packet_type_enum ptype, + uint32_t length +) +{ + int ret = 0; + uint32_t header_length = 0; + uint32_t checksum_overhead = 0; + size_t send_length = 0; + uint8_t send_buffer[PICOQUIC_MAX_PACKET_SIZE]; + picoquic_path_t * path_x = cnx_client->path[0]; + uint64_t current_time = 0; + uint32_t consumed = 0; + picoquic_packet_header expected_header; + picoquic_packet * packet = (picoquic_packet *) malloc(sizeof(picoquic_packet)); + + if (packet == NULL) { + DBG_PRINTF("%s", "Out of memory\n"); + ret = -1; + } + else { + memset(packet, 0, sizeof(picoquic_packet)); + memset(packet->bytes, 0xbb, length); + header_length = picoquic_predict_packet_header_length(cnx_client, ptype); + packet->ptype = ptype; + packet->offset = header_length; + packet->length = length; + packet->sequence_number = cnx_client->send_sequence; + packet->send_path = cnx_client->path[0]; + + /* Create a packet with specified parameters */ + picoquic_finalize_and_protect_packet(cnx_client, packet, + ret, length, header_length, checksum_overhead, + &send_length, send_buffer, path_x, current_time); + + expected_header.ptype = packet->ptype; + expected_header.offset = packet->offset; + expected_header.pn64 = packet->sequence_number; + expected_header.vn = picoquic_supported_versions[cnx_client->version_index].version; + expected_header.payload_length = packet->length - packet->offset; + + if (packet->ptype == picoquic_packet_0rtt_protected || + packet->ptype == picoquic_packet_client_initial) { + expected_header.dest_cnx_id = cnx_client->initial_cnxid; + } + else { + expected_header.dest_cnx_id = cnx_client->remote_cnxid; + } + + if (packet->ptype == picoquic_packet_1rtt_protected_phi0 || + packet->ptype == picoquic_packet_1rtt_protected_phi0) { + expected_header.vn = 0; + expected_header.srce_cnx_id = picoquic_null_connection_id; + } + else { + expected_header.vn = picoquic_supported_versions[cnx_client->version_index].version; + expected_header.srce_cnx_id = cnx_client->local_cnxid; + } + + /* Decrypt the packet */ + ret = test_packet_decrypt_one(q_server, + send_buffer, send_length, send_length, + addr_from, server_cnx, &expected_header, 0); + } + return ret; +} + +static const uint8_t test_0rtt_secret[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 0, 1 +}; + +static const uint8_t test_1rtt_secret[] = { + 0, 1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +}; + +static uint8_t const addr1[4] = { 10, 0, 0, 1 }; +static uint8_t const addr2[4] = { 10, 0, 0, 2 }; + +int packet_enc_dec_test() +{ + int ret = 0; + struct sockaddr_in test_addr_c; + picoquic_cnx_t* cnx_client = NULL; + picoquic_cnx_t* cnx_server = NULL; + picoquic_quic_t* qclient = picoquic_create(8, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, 0, NULL, NULL, NULL, 0); + picoquic_quic_t* qserver = picoquic_create(8, +#ifdef _WINDOWS +#ifdef _WINDOWS64 + "..\\..\\certs\\cert.pem", "..\\..\\certs\\key.pem", +#else + "..\\certs\\cert.pem", "..\\certs\\key.pem", +#endif +#else + "certs/cert.pem", "certs/key.pem", +#endif + "test", NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, 0); + if (qclient == NULL || qserver == NULL) { + DBG_PRINTF("%s", "Could not create Quic contexts.\n"); + ret = -1; + } + + if (ret == 0) { + memset(&test_addr_c, 0, sizeof(struct sockaddr_in)); + test_addr_c.sin_family = AF_INET; + memcpy(&test_addr_c.sin_addr, addr1, 4); + test_addr_c.sin_port = 12345; + + cnx_client = picoquic_create_cnx(qclient, picoquic_null_connection_id, picoquic_null_connection_id, + (struct sockaddr*)&test_addr_c, 0, 0, NULL, NULL, 1); + if (cnx_client == NULL) { + DBG_PRINTF("%s", "Could not create client connection context.\n"); + ret = -1; + } + else { + ret = picoquic_start_client_cnx(cnx_client); + } + } + + /* Test with a series of packets */ + /* First, client initial */ + if (ret == 0) { + ret = test_packet_encrypt_one( + (struct sockaddr *) &test_addr_c, + cnx_client, qserver, NULL, picoquic_packet_client_initial, 1256); + } + /* If that work, update the connection context */ + if (ret == 0) { + cnx_server = qserver->cnx_list; + if (cnx_server == NULL) { + DBG_PRINTF("%s", "Did not create the server connection context.\n"); + ret = -1; + } else { + /* Set the remote context ID for the client */ + cnx_client->remote_cnxid = cnx_server->local_cnxid; + } + } + + /* Try handshake packet from client */ + if (ret == 0) { + ret = test_packet_encrypt_one( + (struct sockaddr *) &test_addr_c, + cnx_client, qserver, cnx_server, picoquic_packet_handshake, 1256); + } + + /* Now try a zero RTT packet */ + if (ret == 0) { + cnx_client->aead_0rtt_encrypt_ctx = picoquic_setup_test_aead_context(1, test_0rtt_secret); + cnx_server->aead_0rtt_decrypt_ctx = picoquic_setup_test_aead_context(0, test_0rtt_secret); + cnx_client->pn_enc_0rtt = picoquic_pn_enc_create_for_test(test_0rtt_secret); + cnx_server->pn_enc_0rtt = picoquic_pn_enc_create_for_test(test_0rtt_secret); + + ret = test_packet_encrypt_one( + (struct sockaddr *) &test_addr_c, + cnx_client, qserver, cnx_server, picoquic_packet_0rtt_protected, 256); + } + + /* And try a 1 RTT packet */ + if (ret == 0) { + cnx_client->aead_encrypt_ctx = picoquic_setup_test_aead_context(1, test_1rtt_secret); + cnx_server->aead_decrypt_ctx = picoquic_setup_test_aead_context(0, test_1rtt_secret); + cnx_client->pn_enc = picoquic_pn_enc_create_for_test(test_1rtt_secret); + cnx_server->pn_dec = picoquic_pn_enc_create_for_test(test_1rtt_secret); + + ret = test_packet_encrypt_one( + (struct sockaddr *) &test_addr_c, + cnx_client, qserver, cnx_server, picoquic_packet_1rtt_protected_phi0, 1024); + } + + if (cnx_client != NULL) { + picoquic_delete_cnx(cnx_client); + } + + if (qclient != NULL) { + picoquic_free(qclient); + } + + if (qserver != NULL) { + picoquic_free(qserver); + } + + return ret; +} \ No newline at end of file diff --git a/picoquictest/picoquictest.h b/picoquictest/picoquictest.h index 3a283584..8233626a 100644 --- a/picoquictest/picoquictest.h +++ b/picoquictest/picoquictest.h @@ -100,6 +100,7 @@ int nat_rebinding_test(); int nat_rebinding_loss_test(); int spin_bit_test(); int client_error_test(); +int packet_enc_dec_test(); #ifdef __cplusplus } -- GitLab