| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-03-20 20:07:54 +08:00
										 |  |  |  * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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/ssl.h>
 | 
					
						
							|  |  |  | #include "internal/recordmethod.h"
 | 
					
						
							|  |  |  | #include "internal/quic_tls.h"
 | 
					
						
							|  |  |  | #include "../ssl_local.h"
 | 
					
						
							| 
									
										
										
										
											2025-02-15 03:21:31 +08:00
										 |  |  | #include "internal/quic_record_util.h"
 | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  | #include "internal/quic_error.h"
 | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #include "internal/quic_types.h"
 | 
					
						
							| 
									
										
										
										
											2024-01-11 16:36:15 +08:00
										 |  |  | #include "internal/ssl_unwrap.h"
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define QUIC_TLS_FATAL(rl, ad, err) \
 | 
					
						
							|  |  |  |     do { \ | 
					
						
							| 
									
										
										
										
											2023-07-27 23:06:42 +08:00
										 |  |  |         if ((rl) != NULL) (rl)->alert = (ad); \ | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         ERR_raise(ERR_LIB_SSL, (err)); \ | 
					
						
							| 
									
										
										
										
											2023-07-27 23:06:42 +08:00
										 |  |  |         if ((rl) != NULL) (rl)->qtls->inerror = 1; \ | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     } while(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct quic_tls_st { | 
					
						
							|  |  |  |     QUIC_TLS_ARGS args; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Transport parameters which client should send. Buffer lifetime must | 
					
						
							|  |  |  |      * exceed the lifetime of the QUIC_TLS object. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     const unsigned char *local_transport_params; | 
					
						
							|  |  |  |     size_t local_transport_params_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |     ERR_STATE *error_state; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * QUIC error code (usually in the TLS Alert-mapped CRYPTO_ERR range). Valid | 
					
						
							|  |  |  |      * only if inerror is 1. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     uint64_t error_code; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |      * Error message with static storage duration. Valid only if inerror is 1. | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |      * Should be suitable for encapsulation in a CONNECTION_CLOSE frame. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     const char *error_msg; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     /* Whether our SSL object for TLS has been configured for use in QUIC */ | 
					
						
							|  |  |  |     unsigned int configured : 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set if we have hit any error state */ | 
					
						
							|  |  |  |     unsigned int inerror : 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Set if the handshake has completed */ | 
					
						
							|  |  |  |     unsigned int complete : 1; | 
					
						
							| 
									
										
										
										
											2024-03-22 15:24:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Set if we have consumed the local transport parameters yet. */ | 
					
						
							|  |  |  |     unsigned int local_transport_params_consumed : 1; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ossl_record_layer_st { | 
					
						
							|  |  |  |     QUIC_TLS *qtls; | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Protection level */ | 
					
						
							|  |  |  |     int level; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     /* Only used for retry flags */ | 
					
						
							|  |  |  |     BIO *dummybio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Number of bytes written so far if we are part way through a write */ | 
					
						
							|  |  |  |     size_t written; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* If we are part way through a write, a copy of the template */ | 
					
						
							|  |  |  |     OSSL_RECORD_TEMPLATE template; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * If we hit an error, what alert code should be used | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     int alert; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     /* Amount of crypto stream data we read in the last call to quic_read_record */ | 
					
						
							| 
									
										
										
										
											2023-02-24 00:31:49 +08:00
										 |  |  |     size_t recread; | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     /* Amount of crypto stream data read but not yet released */ | 
					
						
							|  |  |  |     size_t recunreleased; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  |     /* Callbacks */ | 
					
						
							|  |  |  |     OSSL_FUNC_rlayer_msg_callback_fn *msg_callback; | 
					
						
							|  |  |  |     void *cbarg; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 21:05:58 +08:00
										 |  |  | static int quic_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio); | 
					
						
							| 
									
										
										
										
											2023-10-13 23:33:31 +08:00
										 |  |  | static int quic_free(OSSL_RECORD_LAYER *r); | 
					
						
							| 
									
										
										
										
											2023-08-08 21:05:58 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | static int | 
					
						
							|  |  |  | quic_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, | 
					
						
							|  |  |  |                       int role, int direction, int level, uint16_t epoch, | 
					
						
							|  |  |  |                       unsigned char *secret, size_t secretlen, | 
					
						
							|  |  |  |                       unsigned char *key, size_t keylen, unsigned char *iv, | 
					
						
							|  |  |  |                       size_t ivlen, unsigned char *mackey, size_t mackeylen, | 
					
						
							|  |  |  |                       const EVP_CIPHER *ciph, size_t taglen, | 
					
						
							|  |  |  |                       int mactype, | 
					
						
							|  |  |  |                       const EVP_MD *md, COMP_METHOD *comp, | 
					
						
							|  |  |  |                       const EVP_MD *kdfdigest, BIO *prev, BIO *transport, | 
					
						
							|  |  |  |                       BIO *next, BIO_ADDR *local, BIO_ADDR *peer, | 
					
						
							|  |  |  |                       const OSSL_PARAM *settings, const OSSL_PARAM *options, | 
					
						
							|  |  |  |                       const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, | 
					
						
							|  |  |  |                       OSSL_RECORD_LAYER **retrl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_RECORD_LAYER *rl = OPENSSL_zalloc(sizeof(*rl)); | 
					
						
							|  |  |  |     int qdir; | 
					
						
							|  |  |  |     uint32_t suite_id = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rl == NULL) { | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rl->qtls = (QUIC_TLS *)rlarg; | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  |     rl->level = level; | 
					
						
							| 
									
										
										
										
											2023-08-08 21:05:58 +08:00
										 |  |  |     if (!quic_set1_bio(rl, transport)) { | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  |     rl->cbarg = cbarg; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     *retrl = rl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  |     if (fns != NULL) { | 
					
						
							|  |  |  |         for (; fns->function_id != 0; fns++) { | 
					
						
							|  |  |  |             switch (fns->function_id) { | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case OSSL_FUNC_RLAYER_MSG_CALLBACK: | 
					
						
							|  |  |  |                 rl->msg_callback = OSSL_FUNC_rlayer_msg_callback(fns); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 /* Just ignore anything we don't understand */ | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |     if (level == OSSL_RECORD_PROTECTION_LEVEL_NONE) | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (direction == OSSL_RECORD_DIRECTION_READ) | 
					
						
							|  |  |  |         qdir = 0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         qdir = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |     if (rl->qtls->args.ossl_quic) { | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #ifndef OPENSSL_NO_QUIC
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * We only look up the suite_id/MD for internal callers. Not used in the | 
					
						
							|  |  |  |          * public API. We assume that a 3rd party QUIC stack will want to | 
					
						
							|  |  |  |          * figure this out by itself (e.g. so that they could add new | 
					
						
							|  |  |  |          * ciphersuites at a different pace to us) | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (EVP_CIPHER_is_a(ciph, "AES-128-GCM")) { | 
					
						
							|  |  |  |             suite_id = QRL_SUITE_AES128GCM; | 
					
						
							|  |  |  |         } else if (EVP_CIPHER_is_a(ciph, "AES-256-GCM")) { | 
					
						
							|  |  |  |             suite_id = QRL_SUITE_AES256GCM; | 
					
						
							|  |  |  |         } else if (EVP_CIPHER_is_a(ciph, "CHACHA20-POLY1305")) { | 
					
						
							|  |  |  |             suite_id = QRL_SUITE_CHACHA20POLY1305; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, SSL_R_UNKNOWN_CIPHER_TYPE); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |         /* We pass a ref to the md in a successful yield_secret_cb call */ | 
					
						
							|  |  |  |         /* TODO(QUIC FUTURE): This cast is horrible. We should try and remove it */ | 
					
						
							|  |  |  |         if (!EVP_MD_up_ref((EVP_MD *)kdfdigest)) { | 
					
						
							|  |  |  |             QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #else
 | 
					
						
							|  |  |  |         if (!ossl_assert("Should not happen" == NULL)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |     if (!rl->qtls->args.yield_secret_cb(level, qdir, suite_id, | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |                                         (EVP_MD *)kdfdigest, secret, secretlen, | 
					
						
							|  |  |  |                                         rl->qtls->args.yield_secret_cb_arg)) { | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         EVP_MD_free((EVP_MD *)kdfdigest); | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     *retrl = NULL; | 
					
						
							| 
									
										
										
										
											2023-10-13 23:33:31 +08:00
										 |  |  |     quic_free(rl); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_free(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (rl == NULL) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 21:05:58 +08:00
										 |  |  |     BIO_free(rl->dummybio); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     OPENSSL_free(rl); | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_unprocessed_read_pending(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Read ahead isn't really a thing for QUIC so we never have unprocessed | 
					
						
							|  |  |  |      * data pending | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_processed_read_pending(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * This is currently only ever used by: | 
					
						
							|  |  |  |      * - SSL_has_pending() | 
					
						
							|  |  |  |      * - to check whether we have more records that we want to supply to the | 
					
						
							|  |  |  |      *   upper layers | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * We only ever supply 1 record at a time to the upper layers, and | 
					
						
							|  |  |  |      * SSL_has_pending() will go via the QUIC method not the TLS method so that | 
					
						
							|  |  |  |      * use case doesn't apply here. | 
					
						
							|  |  |  |      * Therefore we can ignore this for now and always return 0. We might | 
					
						
							|  |  |  |      * eventually want to change this to check in the receive buffers to see if | 
					
						
							|  |  |  |      * we have any more data pending. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-24 16:34:53 +08:00
										 |  |  | static size_t quic_get_max_records(OSSL_RECORD_LAYER *rl, uint8_t type, | 
					
						
							|  |  |  |                                    size_t len, | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |                                    size_t maxfrag, size_t *preffrag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_write_records(OSSL_RECORD_LAYER *rl, | 
					
						
							|  |  |  |                               OSSL_RECORD_TEMPLATE *template, | 
					
						
							|  |  |  |                               size_t numtempl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     size_t consumed; | 
					
						
							|  |  |  |     unsigned char alert; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!ossl_assert(numtempl == 1)) { | 
					
						
							|  |  |  |         /* How could this be? quic_get_max_records() always returns 1 */ | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BIO_clear_retry_flags(rl->dummybio); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  |     if (rl->msg_callback != NULL) { | 
					
						
							|  |  |  |         unsigned char dummyrec[SSL3_RT_HEADER_LENGTH]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * For the purposes of the callback we "pretend" to be normal TLS, | 
					
						
							|  |  |  |          * and manufacture a dummy record header | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         dummyrec[0] = (rl->level == OSSL_RECORD_PROTECTION_LEVEL_NONE) | 
					
						
							|  |  |  |                         ? template->type | 
					
						
							|  |  |  |                         : SSL3_RT_APPLICATION_DATA; | 
					
						
							|  |  |  |         dummyrec[1] = (unsigned char)((template->version >> 8) & 0xff); | 
					
						
							|  |  |  |         dummyrec[2] = (unsigned char)(template->version & 0xff); | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * We assume that buflen is always <= UINT16_MAX. Since this is | 
					
						
							|  |  |  |          * generated by libssl itself we actually expect it to never | 
					
						
							|  |  |  |          * exceed SSL3_RT_MAX_PLAIN_LENGTH - so it should be a safe | 
					
						
							|  |  |  |          * assumption | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         dummyrec[3] = (unsigned char)((template->buflen >> 8) & 0xff); | 
					
						
							|  |  |  |         dummyrec[4] = (unsigned char)(template->buflen & 0xff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rl->msg_callback(1, TLS1_3_VERSION, SSL3_RT_HEADER, dummyrec, | 
					
						
							|  |  |  |                             SSL3_RT_HEADER_LENGTH, rl->cbarg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (rl->level != OSSL_RECORD_PROTECTION_LEVEL_NONE) { | 
					
						
							|  |  |  |             rl->msg_callback(1, TLS1_3_VERSION, SSL3_RT_INNER_CONTENT_TYPE, | 
					
						
							|  |  |  |                              &template->type, 1, rl->cbarg); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     switch (template->type) { | 
					
						
							|  |  |  |     case SSL3_RT_ALERT: | 
					
						
							|  |  |  |         if (template->buflen != 2) { | 
					
						
							|  |  |  |             /*
 | 
					
						
							|  |  |  |              * We assume that libssl always sends both bytes of an alert to | 
					
						
							|  |  |  |              * us in one go, and never fragments it. If we ever get more | 
					
						
							|  |  |  |              * or less bytes than exactly 2 then this is very unexpected. | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_VALUE); | 
					
						
							|  |  |  |             return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Byte 0 is the alert level (we ignore it) and byte 1 is the alert | 
					
						
							|  |  |  |          * description that we are actually interested in. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         alert = template->buf[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!rl->qtls->args.alert_cb(rl->qtls->args.alert_cb_arg, alert)) { | 
					
						
							|  |  |  |             QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |             return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case SSL3_RT_HANDSHAKE: | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * We expect this to only fail on some fatal error (e.g. malloc | 
					
						
							|  |  |  |          * failure) | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (!rl->qtls->args.crypto_send_cb(template->buf + rl->written, | 
					
						
							|  |  |  |                                            template->buflen - rl->written, | 
					
						
							|  |  |  |                                            &consumed, | 
					
						
							|  |  |  |                                            rl->qtls->args.crypto_send_cb_arg)) { | 
					
						
							|  |  |  |             QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |             return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * We might have written less than we wanted to if we have filled the | 
					
						
							|  |  |  |          * send stream buffer. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (consumed + rl->written != template->buflen) { | 
					
						
							|  |  |  |             if (!ossl_assert(consumed + rl->written < template->buflen)) { | 
					
						
							|  |  |  |                 QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |                 return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /*
 | 
					
						
							|  |  |  |              * We've not written everything we wanted to. Take a copy of the | 
					
						
							|  |  |  |              * template, remember how much we wrote so far and signal a retry. | 
					
						
							|  |  |  |              * The buffer supplied in the template is guaranteed to be the same | 
					
						
							|  |  |  |              * on a retry for handshake data | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |             rl->written += consumed; | 
					
						
							|  |  |  |             rl->template = *template; | 
					
						
							|  |  |  |             BIO_set_retry_write(rl->dummybio); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return OSSL_RECORD_RETURN_RETRY; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         rl->written = 0; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         /* Anything else is unexpected and an error */ | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return OSSL_RECORD_RETURN_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_retry_write_records(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return quic_write_records(rl, &rl->template, 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, | 
					
						
							| 
									
										
										
										
											2023-08-24 00:12:32 +08:00
										 |  |  |                             int *rversion, uint8_t *type, const unsigned char **data, | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |                             size_t *datalen, uint16_t *epoch, | 
					
						
							|  |  |  |                             unsigned char *seq_num) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     if (rl->recread != 0 || rl->recunreleased != 0) | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     BIO_clear_retry_flags(rl->dummybio); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-24 01:02:54 +08:00
										 |  |  |     if (!rl->qtls->args.crypto_recv_rcd_cb(data, datalen, | 
					
						
							| 
									
										
										
										
											2023-02-24 00:31:49 +08:00
										 |  |  |                                            rl->qtls->args.crypto_recv_rcd_cb_arg)) { | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (*datalen == 0) { | 
					
						
							|  |  |  |         BIO_set_retry_read(rl->dummybio); | 
					
						
							|  |  |  |         return OSSL_RECORD_RETURN_RETRY; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *rechandle = rl; | 
					
						
							|  |  |  |     *rversion = TLS1_3_VERSION; | 
					
						
							|  |  |  |     *type = SSL3_RT_HANDSHAKE; | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     rl->recread = rl->recunreleased = *datalen; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     /* epoch/seq_num are not relevant for TLS */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 19:39:33 +08:00
										 |  |  |     if (rl->msg_callback != NULL) { | 
					
						
							|  |  |  |         unsigned char dummyrec[SSL3_RT_HEADER_LENGTH]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * For the purposes of the callback we "pretend" to be normal TLS, | 
					
						
							|  |  |  |          * and manufacture a dummy record header | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         dummyrec[0] = (rl->level == OSSL_RECORD_PROTECTION_LEVEL_NONE) | 
					
						
							|  |  |  |                       ? SSL3_RT_HANDSHAKE | 
					
						
							|  |  |  |                       : SSL3_RT_APPLICATION_DATA; | 
					
						
							|  |  |  |         dummyrec[1] = (unsigned char)((TLS1_2_VERSION >> 8) & 0xff); | 
					
						
							|  |  |  |         dummyrec[2] = (unsigned char)(TLS1_2_VERSION & 0xff); | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * *datalen will always fit into 2 bytes because our original buffer | 
					
						
							|  |  |  |          * size is less than that. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         dummyrec[3] = (unsigned char)((*datalen >> 8) & 0xff); | 
					
						
							|  |  |  |         dummyrec[4] = (unsigned char)(*datalen & 0xff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rl->msg_callback(0, TLS1_3_VERSION, SSL3_RT_HEADER, dummyrec, | 
					
						
							|  |  |  |                          SSL3_RT_HEADER_LENGTH, rl->cbarg); | 
					
						
							|  |  |  |         rl->msg_callback(0, TLS1_3_VERSION, SSL3_RT_INNER_CONTENT_TYPE, type, 1, | 
					
						
							|  |  |  |                          rl->cbarg); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     return OSSL_RECORD_RETURN_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  | static int quic_release_record(OSSL_RECORD_LAYER *rl, void *rechandle, | 
					
						
							|  |  |  |                                size_t length) | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     if (!ossl_assert(rl->recread > 0) | 
					
						
							|  |  |  |             || !ossl_assert(rl->recunreleased <= rl->recread) | 
					
						
							|  |  |  |             || !ossl_assert(rl == rechandle) | 
					
						
							|  |  |  |             || !ossl_assert(length <= rl->recunreleased)) { | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |         return OSSL_RECORD_RETURN_FATAL; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     rl->recunreleased -= length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rl->recunreleased > 0) | 
					
						
							|  |  |  |         return OSSL_RECORD_RETURN_SUCCESS; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-24 00:31:49 +08:00
										 |  |  |     if (!rl->qtls->args.crypto_release_rcd_cb(rl->recread, | 
					
						
							|  |  |  |                                               rl->qtls->args.crypto_release_rcd_cb_arg)) { | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         return OSSL_RECORD_RETURN_FATAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     rl->recread = 0; | 
					
						
							| 
									
										
										
										
											2023-02-27 17:19:16 +08:00
										 |  |  |     return OSSL_RECORD_RETURN_SUCCESS; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_get_alert_code(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return rl->alert; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_set_protocol_version(OSSL_RECORD_LAYER *rl, int version) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* We only support TLSv1.3, so its bad if we negotiate anything else */ | 
					
						
							|  |  |  |     if (!ossl_assert(version == TLS1_3_VERSION)) { | 
					
						
							|  |  |  |         QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void quic_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* We don't care */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void quic_set_first_handshake(OSSL_RECORD_LAYER *rl, int first) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* We don't care */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void quic_set_max_pipelines(OSSL_RECORD_LAYER *rl, size_t max_pipelines) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* We don't care */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void quic_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr, | 
					
						
							|  |  |  |                     const char **longstr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * According to the docs, valid read state strings are: "RH"/"read header", | 
					
						
							| 
									
										
										
										
											2023-04-25 21:06:54 +08:00
										 |  |  |      * "RB"/"read body", and "unknown"/"unknown". We don't read records in quite | 
					
						
							|  |  |  |      * that way, so we report every "normal" state as "read header". In the | 
					
						
							|  |  |  |      * event of error then we report "unknown". | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rl->qtls->inerror) { | 
					
						
							|  |  |  |         if (shortstr != NULL) | 
					
						
							|  |  |  |             *shortstr = "unknown"; | 
					
						
							|  |  |  |         if (longstr != NULL) | 
					
						
							|  |  |  |             *longstr = "unknown"; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         if (shortstr != NULL) | 
					
						
							| 
									
										
										
										
											2023-04-25 21:06:54 +08:00
										 |  |  |             *shortstr = "RH"; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         if (longstr != NULL) | 
					
						
							| 
									
										
										
										
											2023-04-25 21:06:54 +08:00
										 |  |  |             *longstr = "read header"; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_set_options(OSSL_RECORD_LAYER *rl, const OSSL_PARAM *options) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * We don't support any options yet - but we might do at some point so | 
					
						
							|  |  |  |      * this could be useful. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const COMP_METHOD *quic_get_compression(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* We only support TLSv1.3 which doesn't have compression */ | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void quic_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* This really doesn't make any sense for QUIC. Ignore it */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_alloc_buffers(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * This is a hint only. We don't support it (yet), so just ignore the | 
					
						
							|  |  |  |      * request | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_free_buffers(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * This is a hint only. We don't support it (yet), so just ignore the | 
					
						
							|  |  |  |      * request | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-08 21:05:58 +08:00
										 |  |  |     if (bio != NULL && !BIO_up_ref(bio)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     BIO_free(rl->dummybio); | 
					
						
							|  |  |  |     rl->dummybio = bio; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Never called functions | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Due to the way we are configured and used we never expect any of the next set | 
					
						
							|  |  |  |  * of functions to be called. Therefore we set them to always fail. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static size_t quic_app_data_pending(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | 
					
						
							|  |  |  |     return (size_t)ossl_assert(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static size_t quic_get_max_record_overhead(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | 
					
						
							|  |  |  |     return (size_t)ossl_assert(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int quic_increment_sequence_ctr(OSSL_RECORD_LAYER *rl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QUIC_TLS_FATAL(rl, SSL_AD_INTERNAL_ERROR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | 
					
						
							|  |  |  |     return ossl_assert(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* End of never called functions */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_RECORD_METHOD quic_tls_record_method = { | 
					
						
							|  |  |  |     quic_new_record_layer, | 
					
						
							|  |  |  |     quic_free, | 
					
						
							|  |  |  |     quic_unprocessed_read_pending, | 
					
						
							|  |  |  |     quic_processed_read_pending, | 
					
						
							|  |  |  |     quic_app_data_pending, /* Never called */ | 
					
						
							|  |  |  |     quic_get_max_records, | 
					
						
							|  |  |  |     quic_write_records, | 
					
						
							|  |  |  |     quic_retry_write_records, | 
					
						
							|  |  |  |     quic_read_record, | 
					
						
							|  |  |  |     quic_release_record, | 
					
						
							|  |  |  |     quic_get_alert_code, | 
					
						
							|  |  |  |     quic_set1_bio, | 
					
						
							|  |  |  |     quic_set_protocol_version, | 
					
						
							|  |  |  |     quic_set_plain_alerts, | 
					
						
							|  |  |  |     quic_set_first_handshake, | 
					
						
							|  |  |  |     quic_set_max_pipelines, | 
					
						
							|  |  |  |     NULL, /* set_in_init: Optional - we don't need it */ | 
					
						
							|  |  |  |     quic_get_state, | 
					
						
							|  |  |  |     quic_set_options, | 
					
						
							|  |  |  |     quic_get_compression, | 
					
						
							|  |  |  |     quic_set_max_frag_len, | 
					
						
							|  |  |  |     quic_get_max_record_overhead, /* Never called */ | 
					
						
							|  |  |  |     quic_increment_sequence_ctr, /* Never called */ | 
					
						
							|  |  |  |     quic_alloc_buffers, | 
					
						
							|  |  |  |     quic_free_buffers | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int add_transport_params_cb(SSL *s, unsigned int ext_type, | 
					
						
							|  |  |  |                                    unsigned int context, | 
					
						
							|  |  |  |                                    const unsigned char **out, size_t *outlen, | 
					
						
							|  |  |  |                                    X509 *x, size_t chainidx, int *al, | 
					
						
							|  |  |  |                                    void *add_arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QUIC_TLS *qtls = add_arg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *out = qtls->local_transport_params; | 
					
						
							|  |  |  |     *outlen = qtls->local_transport_params_len; | 
					
						
							| 
									
										
										
										
											2024-03-22 15:24:05 +08:00
										 |  |  |     qtls->local_transport_params_consumed = 1; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_transport_params_cb(SSL *s, unsigned int ext_type, | 
					
						
							|  |  |  |                                      unsigned int context, | 
					
						
							|  |  |  |                                      const unsigned char *out, | 
					
						
							|  |  |  |                                      void *add_arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int parse_transport_params_cb(SSL *s, unsigned int ext_type, | 
					
						
							|  |  |  |                                      unsigned int context, | 
					
						
							|  |  |  |                                      const unsigned char *in, | 
					
						
							|  |  |  |                                      size_t inlen, X509 *x, | 
					
						
							|  |  |  |                                      size_t chainidx, | 
					
						
							|  |  |  |                                      int *al, void *parse_arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QUIC_TLS *qtls = parse_arg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return qtls->args.got_transport_params_cb(in, inlen, | 
					
						
							|  |  |  |                                               qtls->args.got_transport_params_cb_arg); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QUIC_TLS *ossl_quic_tls_new(const QUIC_TLS_ARGS *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QUIC_TLS *qtls; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (args->crypto_send_cb == NULL | 
					
						
							| 
									
										
										
										
											2023-02-24 00:31:49 +08:00
										 |  |  |         || args->crypto_recv_rcd_cb == NULL | 
					
						
							|  |  |  |         || args->crypto_release_rcd_cb == NULL) { | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qtls = OPENSSL_zalloc(sizeof(*qtls)); | 
					
						
							|  |  |  |     if (qtls == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  |     if (args->ossl_quic && (qtls->error_state = OSSL_ERR_STATE_new()) == NULL) { | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |         OPENSSL_free(qtls); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     qtls->args = *args; | 
					
						
							|  |  |  |     return qtls; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ossl_quic_tls_free(QUIC_TLS *qtls) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-10-27 19:22:11 +08:00
										 |  |  |     if (qtls == NULL) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |     OSSL_ERR_STATE_free(qtls->error_state); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     OPENSSL_free(qtls); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  | static int raise_error(QUIC_TLS *qtls, uint64_t error_code, | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |                        const char *error_msg, | 
					
						
							|  |  |  |                        const char *src_file, | 
					
						
							|  |  |  |                        int src_line, | 
					
						
							|  |  |  |                        const char *src_func) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * When QTLS fails, add a "cover letter" error with information, potentially | 
					
						
							|  |  |  |      * with any underlying libssl errors underneath it (but our cover error may | 
					
						
							|  |  |  |      * be the only error in some cases). Then capture this into an ERR_STATE so | 
					
						
							|  |  |  |      * we can report it later if need be when the QUIC_CHANNEL asks for it. | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  |      * For external QUIC TLS we just raise the error. | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     ERR_new(); | 
					
						
							|  |  |  |     ERR_set_debug(src_file, src_line, src_func); | 
					
						
							|  |  |  |     ERR_set_error(ERR_LIB_SSL, SSL_R_QUIC_HANDSHAKE_LAYER_ERROR, | 
					
						
							| 
									
										
										
										
											2023-08-10 00:46:32 +08:00
										 |  |  |                   "handshake layer error, error code %llu (0x%llx) (\"%s\")", | 
					
						
							|  |  |  |                   error_code, error_code, error_msg); | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  |     if (qtls->args.ossl_quic) { | 
					
						
							|  |  |  |         OSSL_ERR_STATE_save_to_mark(qtls->error_state); | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * We record the error information reported via the QUIC protocol | 
					
						
							|  |  |  |          * separately. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         qtls->error_code        = error_code; | 
					
						
							|  |  |  |         qtls->error_msg         = error_msg; | 
					
						
							|  |  |  |         qtls->inerror           = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ERR_pop_to_mark(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  | #define RAISE_ERROR(qtls, error_code, error_msg) \
 | 
					
						
							|  |  |  |     raise_error((qtls), (error_code), (error_msg), \ | 
					
						
							|  |  |  |                 OPENSSL_FILE, OPENSSL_LINE, OPENSSL_FUNC) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #ifndef OPENSSL_NO_QUIC
 | 
					
						
							|  |  |  | # define RAISE_INTERNAL_ERROR(qtls) \
 | 
					
						
							| 
									
										
										
										
											2024-02-15 16:55:36 +08:00
										 |  |  |     RAISE_ERROR((qtls), OSSL_QUIC_ERR_INTERNAL_ERROR, "internal error") | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #else
 | 
					
						
							|  |  |  | # define RAISE_INTERNAL_ERROR(qtls) \
 | 
					
						
							|  |  |  |     RAISE_ERROR((qtls), 0x01, "internal error") | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  | int ossl_quic_tls_configure(QUIC_TLS *qtls) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!SSL_set_min_proto_version(qtls->args.s, TLS1_3_VERSION)) | 
					
						
							|  |  |  |         return RAISE_INTERNAL_ERROR(qtls); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SSL_clear_options(qtls->args.s, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); | 
					
						
							|  |  |  |     ossl_ssl_set_custom_record_layer(sc, &quic_tls_record_method, qtls); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!ossl_tls_add_custom_ext_intern(NULL, &sc->cert->custext, | 
					
						
							|  |  |  |                                         qtls->args.is_server ? ENDPOINT_SERVER | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  |                                                              : ENDPOINT_CLIENT, | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |                                         TLSEXT_TYPE_quic_transport_parameters, | 
					
						
							|  |  |  |                                         SSL_EXT_TLS1_3_ONLY | 
					
						
							|  |  |  |                                         | SSL_EXT_CLIENT_HELLO | 
					
						
							|  |  |  |                                         | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS, | 
					
						
							|  |  |  |                                         add_transport_params_cb, | 
					
						
							|  |  |  |                                         free_transport_params_cb, qtls, | 
					
						
							|  |  |  |                                         parse_transport_params_cb, qtls)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sc->s3.flags |= TLS1_FLAGS_QUIC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #ifndef OPENSSL_NO_QUIC
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | int ossl_quic_tls_tick(QUIC_TLS *qtls) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |     int ret, err; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     const unsigned char *alpn; | 
					
						
							|  |  |  |     unsigned int alpnlen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (qtls->inerror) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * SSL_get_error does not truly know what the cause of an SSL_read failure | 
					
						
							|  |  |  |      * is and to some extent guesses based on contextual information. In | 
					
						
							|  |  |  |      * particular, if there is _any_ ERR on the error stack, SSL_ERROR_SSL or | 
					
						
							|  |  |  |      * SSL_ERROR_SYSCALL will be returned no matter what and there is no | 
					
						
							|  |  |  |      * possibility of SSL_ERROR_WANT_READ/WRITE being returned, even if that was | 
					
						
							|  |  |  |      * the actual cause of the SSL_read() failure. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * This means that ordinarily, the below code might not work right if the | 
					
						
							|  |  |  |      * application has any ERR on the error stack. In order to make this code | 
					
						
							|  |  |  |      * perform correctly regardless of prior ERR state, we use a variant of | 
					
						
							|  |  |  |      * SSL_get_error() which ignores the error stack. However, some ERRs are | 
					
						
							|  |  |  |      * raised by SSL_read() and actually indicate that something has gone wrong | 
					
						
							|  |  |  |      * during the call to SSL_read(). We therefore adopt a strategy of marking | 
					
						
							|  |  |  |      * the ERR stack and seeing if any errors get appended during the call to | 
					
						
							|  |  |  |      * SSL_read(). If they are, we assume SSL_read() has raised an error and | 
					
						
							|  |  |  |      * that we should use normal SSL_get_error() handling. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * NOTE: Ensure all escape paths from this function call | 
					
						
							|  |  |  |      * ERR_clear_to_mark(). The RAISE macros handle this in failure cases. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     ERR_set_mark(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     if (!qtls->configured) { | 
					
						
							|  |  |  |         SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); | 
					
						
							| 
									
										
										
										
											2025-02-19 14:49:06 +08:00
										 |  |  |         SSL_CTX *sctx; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         BIO *nullbio; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 14:49:06 +08:00
										 |  |  |         if (sc == NULL) | 
					
						
							|  |  |  |             return RAISE_INTERNAL_ERROR(qtls); | 
					
						
							|  |  |  |         sctx = SSL_CONNECTION_GET_CTX(sc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * No matter how the user has configured us, there are certain | 
					
						
							|  |  |  |          * requirements for QUIC-TLS that we enforce | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* ALPN is a requirement for QUIC and must be set */ | 
					
						
							| 
									
										
										
										
											2022-11-29 19:26:08 +08:00
										 |  |  |         if (qtls->args.is_server) { | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |             if (sctx->ext.alpn_select_cb == NULL) | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |                 return RAISE_INTERNAL_ERROR(qtls); | 
					
						
							| 
									
										
										
										
											2022-11-29 19:26:08 +08:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |             if (sc->ext.alpn == NULL || sc->ext.alpn_len == 0) | 
					
						
							| 
									
										
										
										
											2024-02-15 16:55:36 +08:00
										 |  |  |                 return RAISE_ERROR(qtls, OSSL_QUIC_ERR_CRYPTO_NO_APP_PROTO, | 
					
						
							| 
									
										
										
										
											2023-08-10 00:46:32 +08:00
										 |  |  |                                    "ALPN must be configured when using QUIC"); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:09:17 +08:00
										 |  |  |         if (!ossl_quic_tls_configure(qtls)) | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |             return RAISE_INTERNAL_ERROR(qtls); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         nullbio = BIO_new(BIO_s_null()); | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |         if (nullbio == NULL) | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |             return RAISE_INTERNAL_ERROR(qtls); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Our custom record layer doesn't use the BIO - but libssl generally | 
					
						
							|  |  |  |          * expects one to be present. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         SSL_set_bio(qtls->args.s, nullbio, nullbio); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  |         if (qtls->args.is_server) | 
					
						
							| 
									
										
										
										
											2022-11-29 19:26:08 +08:00
										 |  |  |             SSL_set_accept_state(qtls->args.s); | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  |         else | 
					
						
							| 
									
										
										
										
											2022-11-29 19:26:08 +08:00
										 |  |  |             SSL_set_connect_state(qtls->args.s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         qtls->configured = 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (qtls->complete) | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * There should never be app data to read, but calling SSL_read() will | 
					
						
							|  |  |  |          * ensure any post-handshake messages are processed. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         ret = SSL_read(qtls->args.s, NULL, 0); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         ret = SSL_do_handshake(qtls->args.s); | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     if (ret <= 0) { | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |         err = ossl_ssl_get_error(qtls->args.s, ret, | 
					
						
							|  |  |  |                                  /*check_err=*/ERR_count_to_mark() > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (err) { | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         case SSL_ERROR_WANT_READ: | 
					
						
							|  |  |  |         case SSL_ERROR_WANT_WRITE: | 
					
						
							| 
									
										
										
										
											2023-08-31 22:31:42 +08:00
										 |  |  |         case SSL_ERROR_WANT_CLIENT_HELLO_CB: | 
					
						
							|  |  |  |         case SSL_ERROR_WANT_X509_LOOKUP: | 
					
						
							|  |  |  |         case SSL_ERROR_WANT_RETRY_VERIFY: | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |             ERR_pop_to_mark(); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |             return 1; | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         default: | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |             return RAISE_INTERNAL_ERROR(qtls); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  |     if (!qtls->complete) { | 
					
						
							|  |  |  |         /* Validate that we have ALPN */ | 
					
						
							|  |  |  |         SSL_get0_alpn_selected(qtls->args.s, &alpn, &alpnlen); | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |         if (alpn == NULL || alpnlen == 0) | 
					
						
							| 
									
										
										
										
											2024-02-15 16:55:36 +08:00
										 |  |  |             return RAISE_ERROR(qtls, OSSL_QUIC_ERR_CRYPTO_NO_APP_PROTO, | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |                                "no application protocol negotiated"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  |         qtls->complete = 1; | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |         ERR_pop_to_mark(); | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  |         return qtls->args.handshake_complete_cb(qtls->args.handshake_complete_cb_arg); | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |     ERR_pop_to_mark(); | 
					
						
							| 
									
										
										
										
											2023-07-27 20:48:02 +08:00
										 |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2025-01-03 23:57:47 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ossl_quic_tls_set_transport_params(QUIC_TLS *qtls, | 
					
						
							|  |  |  |                                        const unsigned char *transport_params, | 
					
						
							|  |  |  |                                        size_t transport_params_len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-03-22 15:24:05 +08:00
										 |  |  |     if (qtls->local_transport_params_consumed) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-18 20:38:38 +08:00
										 |  |  |     qtls->local_transport_params       = transport_params; | 
					
						
							|  |  |  |     qtls->local_transport_params_len   = transport_params_len; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ossl_quic_tls_get_error(QUIC_TLS *qtls, | 
					
						
							|  |  |  |                             uint64_t *error_code, | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |                             const char **error_msg, | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |                             ERR_STATE **error_state) | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (qtls->inerror) { | 
					
						
							| 
									
										
										
										
											2023-07-29 00:48:14 +08:00
										 |  |  |         *error_code     = qtls->error_code; | 
					
						
							|  |  |  |         *error_msg      = qtls->error_msg; | 
					
						
							| 
									
										
										
										
											2023-08-03 18:56:12 +08:00
										 |  |  |         *error_state    = qtls->error_state; | 
					
						
							| 
									
										
										
										
											2023-07-25 18:32:24 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return qtls->inerror; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-08-02 23:43:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns true if the last handshake record message we processed was a | 
					
						
							|  |  |  |  * CertificateRequest | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-19 14:49:06 +08:00
										 |  |  |     if (sc == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 23:43:11 +08:00
										 |  |  |     return sc->s3.tmp.message_type == SSL3_MT_CERTIFICATE_REQUEST; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-08-07 19:21:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns true if the last session associated with the connection has an | 
					
						
							|  |  |  |  * invalid max_early_data value for QUIC. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t max_early_data = SSL_get0_session(qtls->args.s)->ext.max_early_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * If max_early_data was present we always ensure a non-zero value is | 
					
						
							|  |  |  |      * stored in the session for QUIC. Therefore if max_early_data == 0 here | 
					
						
							|  |  |  |      * we can be confident that it was not present in the NewSessionTicket | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     return max_early_data != 0xffffffff && max_early_data != 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2025-02-20 10:28:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ossl_quic_tls_set_early_data_enabled(QUIC_TLS *qtls, int enabled) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!SSL_IS_QUIC_HANDSHAKE(sc) || !SSL_in_before(qtls->args.s)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!enabled) { | 
					
						
							|  |  |  |         sc->max_early_data = 0; | 
					
						
							|  |  |  |         sc->early_data_state = SSL_EARLY_DATA_NONE; | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sc->server) { | 
					
						
							|  |  |  |         sc->max_early_data = 0xffffffff; | 
					
						
							|  |  |  |         sc->early_data_state = SSL_EARLY_DATA_ACCEPTING; | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((sc->session == NULL || sc->session->ext.max_early_data != 0xffffffff) | 
					
						
							|  |  |  |         && sc->psk_use_session_cb == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sc->early_data_state = SSL_EARLY_DATA_CONNECTING; | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } |