| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- /** \file ssl_helpers.h
- *
- * \brief This file contains helper functions to set up a TLS connection.
- */
- /*
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef SSL_HELPERS_H
- #define SSL_HELPERS_H
- #include "mbedtls/build_info.h"
- #include <string.h>
- #include <test/helpers.h>
- #include <test/macros.h>
- #include <test/random.h>
- #include <test/psa_crypto_helpers.h>
- #if defined(MBEDTLS_SSL_TLS_C)
- #include <ssl_misc.h>
- #include <mbedtls/timing.h>
- #include <mbedtls/debug.h>
- #include "hash_info.h"
- #include "test/certs.h"
- #if defined(MBEDTLS_SSL_CACHE_C)
- #include "mbedtls/ssl_cache.h"
- #endif
- #if defined(MBEDTLS_USE_PSA_CRYPTO)
- #define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
- psa_to_ssl_errors, \
- psa_generic_status_to_mbedtls)
- #endif
- #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
- #define MBEDTLS_CAN_HANDLE_RSA_TEST_KEY
- #endif
- enum {
- #define MBEDTLS_SSL_TLS1_3_LABEL(name, string) \
- tls13_label_ ## name,
- MBEDTLS_SSL_TLS1_3_LABEL_LIST
- #undef MBEDTLS_SSL_TLS1_3_LABEL
- };
- typedef struct mbedtls_test_ssl_log_pattern {
- const char *pattern;
- size_t counter;
- } mbedtls_test_ssl_log_pattern;
- typedef struct mbedtls_test_handshake_test_options {
- const char *cipher;
- mbedtls_ssl_protocol_version client_min_version;
- mbedtls_ssl_protocol_version client_max_version;
- mbedtls_ssl_protocol_version server_min_version;
- mbedtls_ssl_protocol_version server_max_version;
- mbedtls_ssl_protocol_version expected_negotiated_version;
- int expected_handshake_result;
- int expected_ciphersuite;
- int pk_alg;
- int opaque_alg;
- int opaque_alg2;
- int opaque_usage;
- data_t *psk_str;
- int dtls;
- int srv_auth_mode;
- int serialize;
- int mfl;
- int cli_msg_len;
- int srv_msg_len;
- int expected_cli_fragments;
- int expected_srv_fragments;
- int renegotiate;
- int legacy_renegotiation;
- void *srv_log_obj;
- void *cli_log_obj;
- void (*srv_log_fun)(void *, int, const char *, int, const char *);
- void (*cli_log_fun)(void *, int, const char *, int, const char *);
- int resize_buffers;
- #if defined(MBEDTLS_SSL_CACHE_C)
- mbedtls_ssl_cache_context *cache;
- #endif
- } mbedtls_test_handshake_test_options;
- typedef struct mbedtls_test_ssl_buffer {
- size_t start;
- size_t content_length;
- size_t capacity;
- unsigned char *buffer;
- } mbedtls_test_ssl_buffer;
- /*
- * Context for a message metadata queue (fifo) that is on top of the ring buffer.
- */
- typedef struct mbedtls_test_ssl_message_queue {
- size_t *messages;
- int pos;
- int num;
- int capacity;
- } mbedtls_test_ssl_message_queue;
- /*
- * Context for the I/O callbacks simulating network connection.
- */
- #define MBEDTLS_MOCK_SOCKET_CONNECTED 1
- typedef struct mbedtls_test_mock_socket {
- int status;
- mbedtls_test_ssl_buffer *input;
- mbedtls_test_ssl_buffer *output;
- struct mbedtls_test_mock_socket *peer;
- } mbedtls_test_mock_socket;
- /* Errors used in the message socket mocks */
- #define MBEDTLS_TEST_ERROR_CONTEXT_ERROR -55
- #define MBEDTLS_TEST_ERROR_SEND_FAILED -66
- #define MBEDTLS_TEST_ERROR_RECV_FAILED -77
- /*
- * Structure used as an addon, or a wrapper, around the mocked sockets.
- * Contains an input queue, to which the other socket pushes metadata,
- * and an output queue, to which this one pushes metadata. This context is
- * considered as an owner of the input queue only, which is initialized and
- * freed in the respective setup and free calls.
- */
- typedef struct mbedtls_test_message_socket_context {
- mbedtls_test_ssl_message_queue *queue_input;
- mbedtls_test_ssl_message_queue *queue_output;
- mbedtls_test_mock_socket *socket;
- } mbedtls_test_message_socket_context;
- #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
- /*
- * Structure with endpoint's certificates for SSL communication tests.
- */
- typedef struct mbedtls_test_ssl_endpoint_certificate {
- mbedtls_x509_crt *ca_cert;
- mbedtls_x509_crt *cert;
- mbedtls_pk_context *pkey;
- } mbedtls_test_ssl_endpoint_certificate;
- /*
- * Endpoint structure for SSL communication tests.
- */
- typedef struct mbedtls_test_ssl_endpoint {
- const char *name;
- mbedtls_ssl_context ssl;
- mbedtls_ssl_config conf;
- mbedtls_test_mock_socket socket;
- mbedtls_test_ssl_endpoint_certificate cert;
- } mbedtls_test_ssl_endpoint;
- #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
- /*
- * This function can be passed to mbedtls to receive output logs from it. In
- * this case, it will count the instances of a mbedtls_test_ssl_log_pattern
- * in the received logged messages.
- */
- void mbedtls_test_ssl_log_analyzer(void *ctx, int level,
- const char *file, int line,
- const char *str);
- void mbedtls_test_init_handshake_options(
- mbedtls_test_handshake_test_options *opts);
- void mbedtls_test_free_handshake_options(
- mbedtls_test_handshake_test_options *opts);
- /*
- * Initialises \p buf. After calling this function it is safe to call
- * `mbedtls_test_ssl_buffer_free()` on \p buf.
- */
- void mbedtls_test_ssl_buffer_init(mbedtls_test_ssl_buffer *buf);
- /*
- * Sets up \p buf. After calling this function it is safe to call
- * `mbedtls_test_ssl_buffer_put()` and `mbedtls_test_ssl_buffer_get()`
- * on \p buf.
- */
- int mbedtls_test_ssl_buffer_setup(mbedtls_test_ssl_buffer *buf,
- size_t capacity);
- void mbedtls_test_ssl_buffer_free(mbedtls_test_ssl_buffer *buf);
- /*
- * Puts \p input_len bytes from the \p input buffer into the ring buffer \p buf.
- *
- * \p buf must have been initialized and set up by calling
- * `mbedtls_test_ssl_buffer_init()` and `mbedtls_test_ssl_buffer_setup()`.
- *
- * \retval \p input_len, if the data fits.
- * \retval 0 <= value < \p input_len, if the data does not fit.
- * \retval -1, if \p buf is NULL, it hasn't been set up or \p input_len is not
- * zero and \p input is NULL.
- */
- int mbedtls_test_ssl_buffer_put(mbedtls_test_ssl_buffer *buf,
- const unsigned char *input, size_t input_len);
- /*
- * Gets \p output_len bytes from the ring buffer \p buf into the
- * \p output buffer. The output buffer can be NULL, in this case a part of the
- * ring buffer will be dropped, if the requested length is available.
- *
- * \p buf must have been initialized and set up by calling
- * `mbedtls_test_ssl_buffer_init()` and `mbedtls_test_ssl_buffer_setup()`.
- *
- * \retval \p output_len, if the data is available.
- * \retval 0 <= value < \p output_len, if the data is not available.
- * \retval -1, if \buf is NULL or it hasn't been set up.
- */
- int mbedtls_test_ssl_buffer_get(mbedtls_test_ssl_buffer *buf,
- unsigned char *output, size_t output_len);
- /*
- * Errors used in the message transport mock tests
- */
- #define MBEDTLS_TEST_ERROR_ARG_NULL -11
- #define MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED -44
- /*
- * Setup and free functions for the message metadata queue.
- *
- * \p capacity describes the number of message metadata chunks that can be held
- * within the queue.
- *
- * \retval 0, if a metadata queue of a given length can be allocated.
- * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation failed.
- */
- int mbedtls_test_ssl_message_queue_setup(
- mbedtls_test_ssl_message_queue *queue, size_t capacity);
- void mbedtls_test_ssl_message_queue_free(
- mbedtls_test_ssl_message_queue *queue);
- /*
- * Push message length information onto the message metadata queue.
- * This will become the last element to leave it (fifo).
- *
- * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null.
- * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the queue is full.
- * \retval \p len, if the push was successful.
- */
- int mbedtls_test_ssl_message_queue_push_info(
- mbedtls_test_ssl_message_queue *queue, size_t len);
- /*
- * Pop information about the next message length from the queue. This will be
- * the oldest inserted message length(fifo). \p msg_len can be null, in which
- * case the data will be popped from the queue but not copied anywhere.
- *
- * \retval MBEDTLS_TEST_ERROR_ARG_NULL, if the queue is null.
- * \retval MBEDTLS_ERR_SSL_WANT_READ, if the queue is empty.
- * \retval message length, if the pop was successful, up to the given
- \p buf_len.
- */
- int mbedtls_test_ssl_message_queue_pop_info(
- mbedtls_test_ssl_message_queue *queue, size_t buf_len);
- /*
- * Setup and teardown functions for mock sockets.
- */
- void mbedtls_mock_socket_init(mbedtls_test_mock_socket *socket);
- /*
- * Closes the socket \p socket.
- *
- * \p socket must have been previously initialized by calling
- * mbedtls_mock_socket_init().
- *
- * This function frees all allocated resources and both sockets are aware of the
- * new connection state.
- *
- * That is, this function does not simulate half-open TCP connections and the
- * phenomenon that when closing a UDP connection the peer is not aware of the
- * connection having been closed.
- */
- void mbedtls_test_mock_socket_close(mbedtls_test_mock_socket *socket);
- /*
- * Establishes a connection between \p peer1 and \p peer2.
- *
- * \p peer1 and \p peer2 must have been previously initialized by calling
- * mbedtls_mock_socket_init().
- *
- * The capacities of the internal buffers are set to \p bufsize. Setting this to
- * the correct value allows for simulation of MTU, sanity testing the mock
- * implementation and mocking TCP connections with lower memory cost.
- */
- int mbedtls_test_mock_socket_connect(mbedtls_test_mock_socket *peer1,
- mbedtls_test_mock_socket *peer2,
- size_t bufsize);
- /*
- * Callbacks for simulating blocking I/O over connection-oriented transport.
- */
- int mbedtls_test_mock_tcp_send_b(void *ctx,
- const unsigned char *buf, size_t len);
- int mbedtls_test_mock_tcp_recv_b(void *ctx, unsigned char *buf, size_t len);
- /*
- * Callbacks for simulating non-blocking I/O over connection-oriented transport.
- */
- int mbedtls_test_mock_tcp_send_nb(void *ctx,
- const unsigned char *buf, size_t len);
- int mbedtls_test_mock_tcp_recv_nb(void *ctx, unsigned char *buf, size_t len);
- void mbedtls_test_message_socket_init(
- mbedtls_test_message_socket_context *ctx);
- /*
- * Setup a given message socket context including initialization of
- * input/output queues to a chosen capacity of messages. Also set the
- * corresponding mock socket.
- *
- * \retval 0, if everything succeeds.
- * \retval MBEDTLS_ERR_SSL_ALLOC_FAILED, if allocation of a message
- * queue failed.
- */
- int mbedtls_test_message_socket_setup(
- mbedtls_test_ssl_message_queue *queue_input,
- mbedtls_test_ssl_message_queue *queue_output,
- size_t queue_capacity, mbedtls_test_mock_socket *socket,
- mbedtls_test_message_socket_context *ctx);
- /*
- * Close a given message socket context, along with the socket itself. Free the
- * memory allocated by the input queue.
- */
- void mbedtls_test_message_socket_close(
- mbedtls_test_message_socket_context *ctx);
- /*
- * Send one message through a given message socket context.
- *
- * \retval \p len, if everything succeeds.
- * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context
- * elements or the context itself is null.
- * \retval MBEDTLS_TEST_ERROR_SEND_FAILED if
- * mbedtls_test_mock_tcp_send_b failed.
- * \retval MBEDTLS_ERR_SSL_WANT_WRITE, if the output queue is full.
- *
- * This function will also return any error from
- * mbedtls_test_ssl_message_queue_push_info.
- */
- int mbedtls_test_mock_tcp_send_msg(void *ctx,
- const unsigned char *buf, size_t len);
- /*
- * Receive one message from a given message socket context and return message
- * length or an error.
- *
- * \retval message length, if everything succeeds.
- * \retval MBEDTLS_TEST_ERROR_CONTEXT_ERROR, if any of the needed context
- * elements or the context itself is null.
- * \retval MBEDTLS_TEST_ERROR_RECV_FAILED if
- * mbedtls_test_mock_tcp_recv_b failed.
- *
- * This function will also return any error other than
- * MBEDTLS_TEST_ERROR_MESSAGE_TRUNCATED from
- * mbedtls_test_message_queue_peek_info.
- */
- int mbedtls_test_mock_tcp_recv_msg(void *ctx,
- unsigned char *buf, size_t buf_len);
- #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
- /*
- * Initializes \p ep_cert structure and assigns it to endpoint
- * represented by \p ep.
- *
- * \retval 0 on success, otherwise error code.
- */
- int mbedtls_test_ssl_endpoint_certificate_init(mbedtls_test_ssl_endpoint *ep,
- int pk_alg,
- int opaque_alg, int opaque_alg2,
- int opaque_usage);
- /*
- * Initializes \p ep structure. It is important to call
- * `mbedtls_test_ssl_endpoint_free()` after calling this function
- * even if it fails.
- *
- * \p endpoint_type must be set as MBEDTLS_SSL_IS_SERVER or
- * MBEDTLS_SSL_IS_CLIENT.
- * \p pk_alg the algorithm to use, currently only MBEDTLS_PK_RSA and
- * MBEDTLS_PK_ECDSA are supported.
- * \p dtls_context - in case of DTLS - this is the context handling metadata.
- * \p input_queue - used only in case of DTLS.
- * \p output_queue - used only in case of DTLS.
- *
- * \retval 0 on success, otherwise error code.
- */
- int mbedtls_test_ssl_endpoint_init(
- mbedtls_test_ssl_endpoint *ep, int endpoint_type,
- mbedtls_test_handshake_test_options *options,
- mbedtls_test_message_socket_context *dtls_context,
- mbedtls_test_ssl_message_queue *input_queue,
- mbedtls_test_ssl_message_queue *output_queue,
- uint16_t *group_list);
- /*
- * Deinitializes endpoint represented by \p ep.
- */
- void mbedtls_test_ssl_endpoint_free(
- mbedtls_test_ssl_endpoint *ep,
- mbedtls_test_message_socket_context *context);
- /*
- * This function moves ssl handshake from \p ssl to prescribed \p state.
- * /p second_ssl is used as second endpoint and their sockets have to be
- * connected before calling this function.
- *
- * \retval 0 on success, otherwise error code.
- */
- int mbedtls_test_move_handshake_to_state(mbedtls_ssl_context *ssl,
- mbedtls_ssl_context *second_ssl,
- int state);
- #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
- /*
- * Helper function setting up inverse record transformations
- * using given cipher, hash, EtM mode, authentication tag length,
- * and version.
- */
- #define CHK(x) \
- do \
- { \
- if (!(x)) \
- { \
- ret = -1; \
- goto cleanup; \
- } \
- } while (0)
- #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_AES_C)
- int mbedtls_test_psa_cipher_encrypt_helper(mbedtls_ssl_transform *transform,
- const unsigned char *iv,
- size_t iv_len,
- const unsigned char *input,
- size_t ilen,
- unsigned char *output,
- size_t *olen);
- #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_CIPHER_MODE_CBC &&
- MBEDTLS_AES_C */
- int mbedtls_test_ssl_build_transforms(mbedtls_ssl_transform *t_in,
- mbedtls_ssl_transform *t_out,
- int cipher_type, int hash_id,
- int etm, int tag_mode,
- mbedtls_ssl_protocol_version tls_version,
- size_t cid0_len,
- size_t cid1_len);
- /*
- * Populate a session structure for serialization tests.
- * Choose dummy values, mostly non-0 to distinguish from the init default.
- */
- int mbedtls_test_ssl_tls12_populate_session(mbedtls_ssl_session *session,
- int ticket_len,
- const char *crt_file);
- #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
- int mbedtls_test_ssl_tls13_populate_session(mbedtls_ssl_session *session,
- int ticket_len,
- int endpoint_type);
- #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
- /*
- * Perform data exchanging between \p ssl_1 and \p ssl_2 and check if the
- * message was sent in the correct number of fragments.
- *
- * /p ssl_1 and /p ssl_2 Endpoints represented by mbedtls_ssl_context. Both
- * of them must be initialized and connected
- * beforehand.
- * /p msg_len_1 and /p msg_len_2 specify the size of the message to send.
- * /p expected_fragments_1 and /p expected_fragments_2 determine in how many
- * fragments the message should be sent.
- * expected_fragments is 0: can be used for DTLS testing while the message
- * size is larger than MFL. In that case the message
- * cannot be fragmented and sent to the second
- * endpoint.
- * This value can be used for negative tests.
- * expected_fragments is 1: can be used for TLS/DTLS testing while the
- * message size is below MFL
- * expected_fragments > 1: can be used for TLS testing while the message
- * size is larger than MFL
- *
- * \retval 0 on success, otherwise error code.
- */
- int mbedtls_exchange_data(mbedtls_ssl_context *ssl_1,
- int msg_len_1, const int expected_fragments_1,
- mbedtls_ssl_context *ssl_2,
- int msg_len_2, const int expected_fragments_2);
- #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
- void mbedtls_test_ssl_perform_handshake(
- mbedtls_test_handshake_test_options *options);
- #endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
- #if defined(MBEDTLS_TEST_HOOKS)
- /*
- * Tweak vector lengths in a TLS 1.3 Certificate message
- *
- * \param[in] buf Buffer containing the Certificate message to tweak
- * \param[in]]out] end End of the buffer to parse
- * \param tweak Tweak identifier (from 1 to the number of tweaks).
- * \param[out] expected_result Error code expected from the parsing function
- * \param[out] args Arguments of the MBEDTLS_SSL_CHK_BUF_READ_PTR call that
- * is expected to fail. All zeroes if no
- * MBEDTLS_SSL_CHK_BUF_READ_PTR failure is expected.
- */
- int tweak_tls13_certificate_msg_vector_len(
- unsigned char *buf, unsigned char **end, int tweak,
- int *expected_result, mbedtls_ssl_chk_buf_ptr_args *args);
- #endif /* MBEDTLS_TEST_HOOKS */
- #define ECJPAKE_TEST_PWD "bla"
- #if defined(MBEDTLS_USE_PSA_CRYPTO)
- #define ECJPAKE_TEST_SET_PASSWORD(exp_ret_val) \
- ret = (use_opaque_arg) ? \
- mbedtls_ssl_set_hs_ecjpake_password_opaque(&ssl, pwd_slot) : \
- mbedtls_ssl_set_hs_ecjpake_password(&ssl, pwd_string, pwd_len); \
- TEST_EQUAL(ret, exp_ret_val)
- #else
- #define ECJPAKE_TEST_SET_PASSWORD(exp_ret_val) \
- ret = mbedtls_ssl_set_hs_ecjpake_password(&ssl, \
- pwd_string, pwd_len); \
- TEST_EQUAL(ret, exp_ret_val)
- #endif /* MBEDTLS_USE_PSA_CRYPTO */
- #define TEST_AVAILABLE_ECC(tls_id_, group_id_, psa_family_, psa_bits_) \
- TEST_EQUAL(mbedtls_ssl_get_ecp_group_id_from_tls_id(tls_id_), \
- group_id_); \
- TEST_EQUAL(mbedtls_ssl_get_tls_id_from_ecp_group_id(group_id_), \
- tls_id_); \
- TEST_EQUAL(mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id_, \
- &psa_family, &psa_bits), PSA_SUCCESS); \
- TEST_EQUAL(psa_family_, psa_family); \
- TEST_EQUAL(psa_bits_, psa_bits);
- #define TEST_UNAVAILABLE_ECC(tls_id_, group_id_, psa_family_, psa_bits_) \
- TEST_EQUAL(mbedtls_ssl_get_ecp_group_id_from_tls_id(tls_id_), \
- MBEDTLS_ECP_DP_NONE); \
- TEST_EQUAL(mbedtls_ssl_get_tls_id_from_ecp_group_id(group_id_), \
- 0); \
- TEST_EQUAL(mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id_, \
- &psa_family, &psa_bits), \
- PSA_ERROR_NOT_SUPPORTED);
- #endif /* MBEDTLS_SSL_TLS_C */
- #endif /* SSL_HELPERS_H */
|