1 /** \file ssl_helpers.h 2 * 3 * \brief This file contains helper functions to set up a TLS connection. 4 */ 5 6 /* 7 * Copyright The Mbed TLS Contributors 8 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 9 */ 10 11 #ifndef SSL_HELPERS_H 12 #define SSL_HELPERS_H 13 14 #include <string.h> 15 16 #include <test/helpers.h> 17 #include <test/macros.h> 18 #include <test/random.h> 19 #include <test/psa_crypto_helpers.h> 20 21 #if defined(MBEDTLS_SSL_TLS_C) 22 #include <mbedtls/ssl_internal.h> 23 #include <mbedtls/ctr_drbg.h> 24 #include <mbedtls/entropy.h> 25 #include <mbedtls/certs.h> 26 #include <mbedtls/timing.h> 27 #include <mbedtls/debug.h> 28 #include <ssl_tls13_keys.h> 29 30 #if defined(MBEDTLS_SSL_CACHE_C) 31 #include "mbedtls/ssl_cache.h" 32 #endif 33 34 #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ 35 defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 36 defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) 37 #define MBEDTLS_CAN_HANDLE_RSA_TEST_KEY 38 #endif 39 40 enum { 41 #define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \ 42 tls1_3_label_ ## name, 43 MBEDTLS_SSL_TLS1_3_LABEL_LIST 44 #undef MBEDTLS_SSL_TLS1_3_LABEL 45 }; 46 47 typedef struct mbedtls_test_ssl_log_pattern { 48 const char *pattern; 49 size_t counter; 50 } mbedtls_test_ssl_log_pattern; 51 52 /* Invalid minor version used when not specifying a min/max version or expecting a test to fail */ 53 #define TEST_SSL_MINOR_VERSION_NONE -1 54 55 typedef struct mbedtls_test_handshake_test_options { 56 const char *cipher; 57 int client_min_version; 58 int client_max_version; 59 int server_min_version; 60 int server_max_version; 61 int expected_negotiated_version; 62 int pk_alg; 63 data_t *psk_str; 64 int dtls; 65 int srv_auth_mode; 66 int serialize; 67 int mfl; 68 int cli_msg_len; 69 int srv_msg_len; 70 int expected_cli_fragments; 71 int expected_srv_fragments; 72 int renegotiate; 73 int legacy_renegotiation; 74 void *srv_log_obj; 75 void *cli_log_obj; 76 void (*srv_log_fun)(void *, int, const char *, int, const char *); 77 void (*cli_log_fun)(void *, int, const char *, int, const char *); 78 int resize_buffers; 79 } mbedtls_test_handshake_test_options; 80 81 /* 82 * Buffer structure for custom I/O callbacks. 83 */ 84 typedef struct mbedtls_test_ssl_buffer { 85 size_t start; 86 size_t content_length; 87 size_t capacity; 88 unsigned char *buffer; 89 } mbedtls_test_ssl_buffer; 90 91 /* 92 * Context for a message metadata queue (fifo) that is on top of the ring buffer. 93 */ 94 typedef struct mbedtls_test_ssl_message_queue { 95 size_t *messages; 96 int pos; 97 int num; 98 int capacity; 99 } mbedtls_test_ssl_message_queue; 100 101 /* 102 * Context for the I/O callbacks simulating network connection. 103 */ 104 105 #define MBEDTLS_MOCK_SOCKET_CONNECTED 1 106 107 typedef struct mbedtls_test_mock_socket { 108 int status; 109 mbedtls_test_ssl_buffer *input; 110 mbedtls_test_ssl_buffer *output; 111 struct mbedtls_test_mock_socket *peer; 112 } mbedtls_test_mock_socket; 113 114 /* Errors used in the message socket mocks */ 115 116 #define MBEDTLS_TEST_ERROR_CONTEXT_ERROR -55 117 #define MBEDTLS_TEST_ERROR_SEND_FAILED -66 118 #define MBEDTLS_TEST_ERROR_RECV_FAILED -77 119 120 /* 121 * Structure used as an addon, or a wrapper, around the mocked sockets. 122 * Contains an input queue, to which the other socket pushes metadata, 123 * and an output queue, to which this one pushes metadata. This context is 124 * considered as an owner of the input queue only, which is initialized and 125 * freed in the respective setup and free calls. 126 */ 127 typedef struct mbedtls_test_message_socket_context { 128 mbedtls_test_ssl_message_queue *queue_input; 129 mbedtls_test_ssl_message_queue *queue_output; 130 mbedtls_test_mock_socket *socket; 131 } mbedtls_test_message_socket_context; 132 133 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ 134 defined(MBEDTLS_CERTS_C) && \ 135 defined(MBEDTLS_ENTROPY_C) && \ 136 defined(MBEDTLS_CTR_DRBG_C) 137 138 /* 139 * Structure with endpoint's certificates for SSL communication tests. 140 */ 141 typedef struct mbedtls_test_ssl_endpoint_certificate { 142 mbedtls_x509_crt *ca_cert; 143 mbedtls_x509_crt *cert; 144 mbedtls_pk_context *pkey; 145 } mbedtls_test_ssl_endpoint_certificate; 146 147 /* 148 * Endpoint structure for SSL communication tests. 149 */ 150 typedef struct mbedtls_test_ssl_endpoint { 151 const char *name; 152 mbedtls_ssl_context ssl; 153 mbedtls_ssl_config conf; 154 mbedtls_ctr_drbg_context ctr_drbg; 155 mbedtls_entropy_context entropy; 156 mbedtls_test_mock_socket socket; 157 mbedtls_test_ssl_endpoint_certificate cert; 158 } mbedtls_test_ssl_endpoint; 159 160 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && 161 MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ 162 163 /* 164 * This function can be passed to mbedtls to receive output logs from it. In 165 * this case, it will count the instances of a mbedtls_test_ssl_log_pattern 166 * in the received logged messages. 167 */ 168 void mbedtls_test_ssl_log_analyzer(void *ctx, int level, 169 const char *file, int line, 170 const char *str); 171 172 void mbedtls_test_init_handshake_options( 173 mbedtls_test_handshake_test_options *opts); 174 175 /* 176 * Initialises \p buf. After calling this function it is safe to call 177 * `mbedtls_test_ssl_buffer_free()` on \p buf. 178 */ 179 void mbedtls_test_ssl_buffer_init(mbedtls_test_ssl_buffer *buf); 180 181 /* 182 * Sets up \p buf. After calling this function it is safe to call 183 * `mbedtls_test_ssl_buffer_put()` and `mbedtls_test_ssl_buffer_get()` 184 * on \p buf. 185 */ 186 int mbedtls_test_ssl_buffer_setup(mbedtls_test_ssl_buffer *buf, 187 size_t capacity); 188 189 void mbedtls_test_ssl_buffer_free(mbedtls_test_ssl_buffer *buf); 190 191 /* 192 * Puts \p input_len bytes from the \p input buffer into the ring buffer \p buf. 193 * 194 * \p buf must have been initialized and set up by calling 195 * `mbedtls_test_ssl_buffer_init()` and `mbedtls_test_ssl_buffer_setup()`. 196 * 197 * \retval \p input_len, if the data fits. 198 * \retval 0 <= value < \p input_len, if the data does not fit. 199 * \retval -1, if \p buf is NULL, it hasn't been set up or \p input_len is not 200 * zero and \p input is NULL. 201 */ 202 int mbedtls_test_ssl_buffer_put(mbedtls_test_ssl_buffer *buf, 203 const unsigned char *input, size_t input_len); 204 205 /* 206 * Gets \p output_len bytes from the ring buffer \p buf into the 207 * \p output buffer. The output buffer can be NULL, in this case a part of the 208 * ring buffer will be dropped, if the requested length is available. 209 * 210 * \p buf must have been initialized and set up by calling 211 * `mbedtls_test_ssl_buffer_init()` and `mbedtls_test_ssl_buffer_setup()`. 212 * 213 * \retval \p output_len, if the data is available. 214 * \retval 0 <= value < \p output_len, if the data is not available. 215 * \retval -1, if \buf is NULL or it hasn't been set up. 216 */ 217 int mbedtls_test_ssl_buffer_get(mbedtls_test_ssl_buffer *buf, 218 unsigned char *output, size_t output_len); 219 220 /* 221 * Errors used in the message transport mock tests 222 */ 223 #define MBEDTLS_TEST_ERROR_ARG_NULL -11 224 #define MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED -44 225 226 /* 227 * Setup and free functions for the message metadata queue. 228 * 229 * \p capacity describes the number of message metadata chunks that can be held 230 * within the queue. 231 * 232 * \retval 0, if a metadata queue of a given length can be allocated. 233 * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation failed. 234 */ 235 int mbedtls_test_ssl_message_queue_setup( 236 mbedtls_test_ssl_message_queue *queue, size_t capacity); 237 238 void mbedtls_test_ssl_message_queue_free( 239 mbedtls_test_ssl_message_queue *queue); 240 241 /* 242 * Push message length information onto the message metadata queue. 243 * This will become the last element to leave it (fifo). 244 * 245 * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. 246 * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the queue is full. 247 * \retval \p len, if the push was successful. 248 */ 249 int mbedtls_test_ssl_message_queue_push_info( 250 mbedtls_test_ssl_message_queue *queue, size_t len); 251 252 /* 253 * Pop information about the next message length from the queue. This will be 254 * the oldest inserted message length(fifo). \p msg_len can be null, in which 255 * case the data will be popped from the queue but not copied anywhere. 256 * 257 * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null. 258 * \retval MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty. 259 * \retval message length, if the pop was successful, up to the given 260 \p buf_len. 261 */ 262 int mbedtls_test_ssl_message_queue_pop_info( 263 mbedtls_test_ssl_message_queue *queue, size_t buf_len); 264 265 /* 266 * Setup and teardown functions for mock sockets. 267 */ 268 void mbedtls_test_mock_socket_init(mbedtls_test_mock_socket *socket); 269 270 /* 271 * Closes the socket \p socket. 272 * 273 * \p socket must have been previously initialized by calling 274 * mbedtls_test_mock_socket_init(). 275 * 276 * This function frees all allocated resources and both sockets are aware of the 277 * new connection state. 278 * 279 * That is, this function does not simulate half-open TCP connections and the 280 * phenomenon that when closing a UDP connection the peer is not aware of the 281 * connection having been closed. 282 */ 283 void mbedtls_test_mock_socket_close(mbedtls_test_mock_socket *socket); 284 285 /* 286 * Establishes a connection between \p peer1 and \p peer2. 287 * 288 * \p peer1 and \p peer2 must have been previously initialized by calling 289 * mbedtls_test_mock_socket_init(). 290 * 291 * The capacities of the internal buffers are set to \p bufsize. Setting this to 292 * the correct value allows for simulation of MTU, sanity testing the mock 293 * implementation and mocking TCP connections with lower memory cost. 294 */ 295 int mbedtls_test_mock_socket_connect(mbedtls_test_mock_socket *peer1, 296 mbedtls_test_mock_socket *peer2, 297 size_t bufsize); 298 299 /* 300 * Callbacks for simulating blocking I/O over connection-oriented transport. 301 */ 302 int mbedtls_test_mock_tcp_send_b(void *ctx, 303 const unsigned char *buf, size_t len); 304 305 int mbedtls_test_mock_tcp_recv_b(void *ctx, unsigned char *buf, size_t len); 306 307 /* 308 * Callbacks for simulating non-blocking I/O over connection-oriented transport. 309 */ 310 int mbedtls_test_mock_tcp_send_nb(void *ctx, 311 const unsigned char *buf, size_t len); 312 313 int mbedtls_test_mock_tcp_recv_nb(void *ctx, unsigned char *buf, size_t len); 314 315 void mbedtls_test_message_socket_init( 316 mbedtls_test_message_socket_context *ctx); 317 318 /* 319 * Setup a given message socket context including initialization of 320 * input/output queues to a chosen capacity of messages. Also set the 321 * corresponding mock socket. 322 * 323 * \retval 0, if everything succeeds. 324 * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation of a message 325 * queue failed. 326 */ 327 int mbedtls_test_message_socket_setup( 328 mbedtls_test_ssl_message_queue *queue_input, 329 mbedtls_test_ssl_message_queue *queue_output, 330 size_t queue_capacity, 331 mbedtls_test_mock_socket *socket, 332 mbedtls_test_message_socket_context *ctx); 333 334 /* 335 * Close a given message socket context, along with the socket itself. Free the 336 * memory allocated by the input queue. 337 */ 338 void mbedtls_test_message_socket_close( 339 mbedtls_test_message_socket_context *ctx); 340 341 /* 342 * Send one message through a given message socket context. 343 * 344 * \retval \p len, if everything succeeds. 345 * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context 346 * elements or the context itself is null. 347 * \retval MBEDTLS_TEST_ERROR_SEND_FAILED if 348 * mbedtls_test_mock_tcp_send_b failed. 349 * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the output queue is full. 350 * 351 * This function will also return any error from 352 * mbedtls_test_ssl_message_queue_push_info. 353 */ 354 int mbedtls_test_mock_tcp_send_msg(void *ctx, 355 const unsigned char *buf, size_t len); 356 357 /* 358 * Receive one message from a given message socket context and return message 359 * length or an error. 360 * 361 * \retval message length, if everything succeeds. 362 * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context 363 * elements or the context itself is null. 364 * \retval MBEDTLS_TEST_ERROR_RECV_FAILED if 365 * mbedtls_test_mock_tcp_recv_b failed. 366 * 367 * This function will also return any error other than 368 * MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED from test_ssl_message_queue_peek_info. 369 */ 370 int mbedtls_test_mock_tcp_recv_msg(void *ctx, 371 unsigned char *buf, size_t buf_len); 372 373 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ 374 defined(MBEDTLS_CERTS_C) && \ 375 defined(MBEDTLS_ENTROPY_C) && \ 376 defined(MBEDTLS_CTR_DRBG_C) 377 378 /* 379 * Initializes \p ep_cert structure and assigns it to endpoint 380 * represented by \p ep. 381 * 382 * \retval 0 on success, otherwise error code. 383 */ 384 int mbedtls_test_ssl_endpoint_certificate_init(mbedtls_test_ssl_endpoint *ep, 385 int pk_alg); 386 387 /* 388 * Initializes \p ep structure. It is important to call 389 * `mbedtls_test_ssl_endpoint_free()` after calling this function 390 * even if it fails. 391 * 392 * \p endpoint_type must be set as MBEDTLS_SSL_IS_SERVER or 393 * MBEDTLS_SSL_IS_CLIENT. 394 * \p pk_alg the algorithm to use, currently only MBEDTLS_PK_RSA and 395 * MBEDTLS_PK_ECDSA are supported. 396 * \p dtls_context - in case of DTLS - this is the context handling metadata. 397 * \p input_queue - used only in case of DTLS. 398 * \p output_queue - used only in case of DTLS. 399 * 400 * \retval 0 on success, otherwise error code. 401 */ 402 int mbedtls_test_ssl_endpoint_init( 403 mbedtls_test_ssl_endpoint *ep, int endpoint_type, int pk_alg, 404 mbedtls_test_message_socket_context *dtls_context, 405 mbedtls_test_ssl_message_queue *input_queue, 406 mbedtls_test_ssl_message_queue *output_queue, 407 const mbedtls_ecp_group_id *curves); 408 409 /* 410 * Deinitializes endpoint represented by \p ep. 411 */ 412 void mbedtls_test_ssl_endpoint_free( 413 mbedtls_test_ssl_endpoint *ep, 414 mbedtls_test_message_socket_context *context); 415 416 /* 417 * This function moves ssl handshake from \p ssl to prescribed \p state. 418 * /p second_ssl is used as second endpoint and their sockets have to be 419 * connected before calling this function. 420 * 421 * \retval 0 on success, otherwise error code. 422 */ 423 int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl, 424 mbedtls_ssl_context *second_ssl, 425 int state); 426 427 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && 428 MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ 429 430 /* 431 * Helper function setting up inverse record transformations 432 * using given cipher, hash, EtM mode, authentication tag length, 433 * and version. 434 */ 435 436 #define CHK(x) \ 437 do \ 438 { \ 439 if (!(x)) \ 440 { \ 441 ret = -1; \ 442 goto cleanup; \ 443 } \ 444 } while (0) 445 446 #if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX 447 #define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_IN_LEN_MAX 448 #else 449 #define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX 450 #endif 451 452 int mbedtls_test_ssl_build_transforms(mbedtls_ssl_transform *t_in, 453 mbedtls_ssl_transform *t_out, 454 int cipher_type, int hash_id, 455 int etm, int tag_mode, int ver, 456 size_t cid0_len, 457 size_t cid1_len); 458 459 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) 460 /** 461 * \param[in,out] record The record to prepare. 462 * It must contain the data to MAC at offset 463 * `record->data_offset`, of length 464 * `record->data_length`. 465 * On success, write the MAC immediately 466 * after the data and increment 467 * `record->data_length` accordingly. 468 * \param[in,out] transform_out The out transform, typically prepared by 469 * mbedtls_test_ssl_build_transforms(). 470 * Its HMAC context may be used. Other than that 471 * it is treated as an input parameter. 472 * 473 * \return 0 on success, an `MBEDTLS_ERR_xxx` error code 474 * or -1 on error. 475 */ 476 int mbedtls_test_ssl_prepare_record_mac(mbedtls_record *record, 477 mbedtls_ssl_transform *transform_out); 478 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */ 479 480 /* 481 * Populate a session structure for serialization tests. 482 * Choose dummy values, mostly non-0 to distinguish from the init default. 483 */ 484 int mbedtls_test_ssl_populate_session(mbedtls_ssl_session *session, 485 int ticket_len, 486 const char *crt_file); 487 488 /* 489 * Perform data exchanging between \p ssl_1 and \p ssl_2 and check if the 490 * message was sent in the correct number of fragments. 491 * 492 * /p ssl_1 and /p ssl_2 Endpoints represented by mbedtls_ssl_context. Both 493 * of them must be initialized and connected 494 * beforehand. 495 * /p msg_len_1 and /p msg_len_2 specify the size of the message to send. 496 * /p expected_fragments_1 and /p expected_fragments_2 determine in how many 497 * fragments the message should be sent. 498 * expected_fragments is 0: can be used for DTLS testing while the message 499 * size is larger than MFL. In that case the message 500 * cannot be fragmented and sent to the second 501 * endpoint. 502 * This value can be used for negative tests. 503 * expected_fragments is 1: can be used for TLS/DTLS testing while the 504 * message size is below MFL 505 * expected_fragments > 1: can be used for TLS testing while the message 506 * size is larger than MFL 507 * 508 * \retval 0 on success, otherwise error code. 509 */ 510 int mbedtls_test_ssl_exchange_data( 511 mbedtls_ssl_context *ssl_1, 512 int msg_len_1, const int expected_fragments_1, 513 mbedtls_ssl_context *ssl_2, 514 int msg_len_2, const int expected_fragments_2); 515 516 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ 517 defined(MBEDTLS_CERTS_C) && \ 518 defined(MBEDTLS_ENTROPY_C) && \ 519 defined(MBEDTLS_CTR_DRBG_C) 520 void mbedtls_test_ssl_perform_handshake( 521 mbedtls_test_handshake_test_options *options); 522 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED && MBEDTLS_CERTS_C && 523 MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */ 524 #endif /* MBEDTLS_SSL_TLS_C */ 525 526 #endif /* SSL_HELPERS_H */ 527