summaryrefslogtreecommitdiff
path: root/programs/ssl/ssl_test_common_source.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-10-08 13:56:50 -0600
committerTom Rini <trini@konsulko.com>2024-10-08 13:56:50 -0600
commit0344c602eadc0802776b65ff90f0a02c856cf53c (patch)
tree236a705740939b84ff37d68ae650061dd14c3449 /programs/ssl/ssl_test_common_source.c
Squashed 'lib/mbedtls/external/mbedtls/' content from commit 2ca6c285a0dd
git-subtree-dir: lib/mbedtls/external/mbedtls git-subtree-split: 2ca6c285a0dd3f33982dd57299012dacab1ff206
Diffstat (limited to 'programs/ssl/ssl_test_common_source.c')
-rw-r--r--programs/ssl/ssl_test_common_source.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c
new file mode 100644
index 00000000000..1ff2077d4a5
--- /dev/null
+++ b/programs/ssl/ssl_test_common_source.c
@@ -0,0 +1,375 @@
+/*
+ * Common source code for SSL test programs. This file is included by
+ * both ssl_client2.c and ssl_server2.c and is intended for source
+ * code that is textually identical in both programs, but that cannot be
+ * compiled separately because it refers to types or macros that are
+ * different in the two programs, or because it would have an incomplete
+ * type.
+ *
+ * This file is meant to be #include'd and cannot be compiled separately.
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+void eap_tls_key_derivation(void *p_expkey,
+ mbedtls_ssl_key_export_type secret_type,
+ const unsigned char *secret,
+ size_t secret_len,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type)
+{
+ eap_tls_keys *keys = (eap_tls_keys *) p_expkey;
+
+ /* We're only interested in the TLS 1.2 master secret */
+ if (secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET) {
+ return;
+ }
+ if (secret_len != sizeof(keys->master_secret)) {
+ return;
+ }
+
+ memcpy(keys->master_secret, secret, sizeof(keys->master_secret));
+ memcpy(keys->randbytes, client_random, 32);
+ memcpy(keys->randbytes + 32, server_random, 32);
+ keys->tls_prf_type = tls_prf_type;
+}
+
+void nss_keylog_export(void *p_expkey,
+ mbedtls_ssl_key_export_type secret_type,
+ const unsigned char *secret,
+ size_t secret_len,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type)
+{
+ char nss_keylog_line[200];
+ size_t const client_random_len = 32;
+ size_t len = 0;
+ size_t j;
+
+ /* We're only interested in the TLS 1.2 master secret */
+ if (secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET) {
+ return;
+ }
+
+ ((void) p_expkey);
+ ((void) server_random);
+ ((void) tls_prf_type);
+
+ len += sprintf(nss_keylog_line + len,
+ "%s", "CLIENT_RANDOM ");
+
+ for (j = 0; j < client_random_len; j++) {
+ len += sprintf(nss_keylog_line + len,
+ "%02x", client_random[j]);
+ }
+
+ len += sprintf(nss_keylog_line + len, " ");
+
+ for (j = 0; j < secret_len; j++) {
+ len += sprintf(nss_keylog_line + len,
+ "%02x", secret[j]);
+ }
+
+ len += sprintf(nss_keylog_line + len, "\n");
+ nss_keylog_line[len] = '\0';
+
+ mbedtls_printf("\n");
+ mbedtls_printf("---------------- NSS KEYLOG -----------------\n");
+ mbedtls_printf("%s", nss_keylog_line);
+ mbedtls_printf("---------------------------------------------\n");
+
+ if (opt.nss_keylog_file != NULL) {
+ FILE *f;
+
+ if ((f = fopen(opt.nss_keylog_file, "a")) == NULL) {
+ goto exit;
+ }
+
+ /* Ensure no stdio buffering of secrets, as such buffers cannot be
+ * wiped. */
+ mbedtls_setbuf(f, NULL);
+
+ if (fwrite(nss_keylog_line, 1, len, f) != len) {
+ fclose(f);
+ goto exit;
+ }
+
+ fclose(f);
+ }
+
+exit:
+ mbedtls_platform_zeroize(nss_keylog_line,
+ sizeof(nss_keylog_line));
+}
+
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+void dtls_srtp_key_derivation(void *p_expkey,
+ mbedtls_ssl_key_export_type secret_type,
+ const unsigned char *secret,
+ size_t secret_len,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type)
+{
+ dtls_srtp_keys *keys = (dtls_srtp_keys *) p_expkey;
+
+ /* We're only interested in the TLS 1.2 master secret */
+ if (secret_type != MBEDTLS_SSL_KEY_EXPORT_TLS12_MASTER_SECRET) {
+ return;
+ }
+ if (secret_len != sizeof(keys->master_secret)) {
+ return;
+ }
+
+ memcpy(keys->master_secret, secret, sizeof(keys->master_secret));
+ memcpy(keys->randbytes, client_random, 32);
+ memcpy(keys->randbytes + 32, server_random, 32);
+ keys->tls_prf_type = tls_prf_type;
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
+int ssl_check_record(mbedtls_ssl_context const *ssl,
+ unsigned char const *buf, size_t len)
+{
+ int my_ret = 0, ret_cr1, ret_cr2;
+ unsigned char *tmp_buf;
+
+ /* Record checking may modify the input buffer,
+ * so make a copy. */
+ tmp_buf = mbedtls_calloc(1, len);
+ if (tmp_buf == NULL) {
+ return MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ }
+ memcpy(tmp_buf, buf, len);
+
+ ret_cr1 = mbedtls_ssl_check_record(ssl, tmp_buf, len);
+ if (ret_cr1 != MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) {
+ /* Test-only: Make sure that mbedtls_ssl_check_record()
+ * doesn't alter state. */
+ memcpy(tmp_buf, buf, len); /* Restore buffer */
+ ret_cr2 = mbedtls_ssl_check_record(ssl, tmp_buf, len);
+ if (ret_cr2 != ret_cr1) {
+ mbedtls_printf("mbedtls_ssl_check_record() returned inconsistent results.\n");
+ my_ret = -1;
+ goto cleanup;
+ }
+
+ switch (ret_cr1) {
+ case 0:
+ break;
+
+ case MBEDTLS_ERR_SSL_INVALID_RECORD:
+ if (opt.debug_level > 1) {
+ mbedtls_printf("mbedtls_ssl_check_record() detected invalid record.\n");
+ }
+ break;
+
+ case MBEDTLS_ERR_SSL_INVALID_MAC:
+ if (opt.debug_level > 1) {
+ mbedtls_printf("mbedtls_ssl_check_record() detected unauthentic record.\n");
+ }
+ break;
+
+ case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD:
+ if (opt.debug_level > 1) {
+ mbedtls_printf("mbedtls_ssl_check_record() detected unexpected record.\n");
+ }
+ break;
+
+ default:
+ mbedtls_printf("mbedtls_ssl_check_record() failed fatally with -%#04x.\n",
+ (unsigned int) -ret_cr1);
+ my_ret = -1;
+ goto cleanup;
+ }
+
+ /* Regardless of the outcome, forward the record to the stack. */
+ }
+
+cleanup:
+ mbedtls_free(tmp_buf);
+
+ return my_ret;
+}
+
+int recv_cb(void *ctx, unsigned char *buf, size_t len)
+{
+ io_ctx_t *io_ctx = (io_ctx_t *) ctx;
+ size_t recv_len;
+ int ret;
+
+ if (opt.nbio == 2) {
+ ret = delayed_recv(io_ctx->net, buf, len);
+ } else {
+ ret = mbedtls_net_recv(io_ctx->net, buf, len);
+ }
+ if (ret < 0) {
+ return ret;
+ }
+ recv_len = (size_t) ret;
+
+ if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+ /* Here's the place to do any datagram/record checking
+ * in between receiving the packet from the underlying
+ * transport and passing it on to the TLS stack. */
+ if (ssl_check_record(io_ctx->ssl, buf, recv_len) != 0) {
+ return -1;
+ }
+ }
+
+ return (int) recv_len;
+}
+
+int recv_timeout_cb(void *ctx, unsigned char *buf, size_t len,
+ uint32_t timeout)
+{
+ io_ctx_t *io_ctx = (io_ctx_t *) ctx;
+ int ret;
+ size_t recv_len;
+
+ ret = mbedtls_net_recv_timeout(io_ctx->net, buf, len, timeout);
+ if (ret < 0) {
+ return ret;
+ }
+ recv_len = (size_t) ret;
+
+ if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
+ /* Here's the place to do any datagram/record checking
+ * in between receiving the packet from the underlying
+ * transport and passing it on to the TLS stack. */
+ if (ssl_check_record(io_ctx->ssl, buf, recv_len) != 0) {
+ return -1;
+ }
+ }
+
+ return (int) recv_len;
+}
+
+int send_cb(void *ctx, unsigned char const *buf, size_t len)
+{
+ io_ctx_t *io_ctx = (io_ctx_t *) ctx;
+
+ if (opt.nbio == 2) {
+ return delayed_send(io_ctx->net, buf, len);
+ }
+
+ return mbedtls_net_send(io_ctx->net, buf, len);
+}
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) && defined(MBEDTLS_RSA_C)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/*
+ * When GnuTLS/Openssl server is configured in TLS 1.2 mode with a certificate
+ * declaring an RSA public key and Mbed TLS is configured in hybrid mode, if
+ * `rsa_pss_rsae_*` algorithms are before `rsa_pkcs1_*` ones in this list then
+ * the GnuTLS/Openssl server chooses an `rsa_pss_rsae_*` signature algorithm
+ * for its signature in the key exchange message. As Mbed TLS 1.2 does not
+ * support them, the handshake fails.
+ */
+#define MBEDTLS_SSL_SIG_ALG(hash) ((hash << 8) | MBEDTLS_SSL_SIG_ECDSA), \
+ ((hash << 8) | MBEDTLS_SSL_SIG_RSA), \
+ (0x800 | hash),
+#else
+#define MBEDTLS_SSL_SIG_ALG(hash) ((hash << 8) | MBEDTLS_SSL_SIG_ECDSA), \
+ ((hash << 8) | MBEDTLS_SSL_SIG_RSA),
+#endif
+#elif defined(MBEDTLS_PK_CAN_ECDSA_SOME)
+#define MBEDTLS_SSL_SIG_ALG(hash) ((hash << 8) | MBEDTLS_SSL_SIG_ECDSA),
+#elif defined(MBEDTLS_RSA_C)
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
+/* See above */
+#define MBEDTLS_SSL_SIG_ALG(hash) ((hash << 8) | MBEDTLS_SSL_SIG_RSA), \
+ (0x800 | hash),
+#else
+#define MBEDTLS_SSL_SIG_ALG(hash) ((hash << 8) | MBEDTLS_SSL_SIG_RSA),
+#endif
+#else
+#define MBEDTLS_SSL_SIG_ALG(hash)
+#endif
+
+uint16_t ssl_sig_algs_for_test[] = {
+#if defined(MBEDTLS_MD_CAN_SHA512)
+ MBEDTLS_SSL_SIG_ALG(MBEDTLS_SSL_HASH_SHA512)
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA384)
+ MBEDTLS_SSL_SIG_ALG(MBEDTLS_SSL_HASH_SHA384)
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA256)
+ MBEDTLS_SSL_SIG_ALG(MBEDTLS_SSL_HASH_SHA256)
+#endif
+#if defined(MBEDTLS_MD_CAN_SHA224)
+ MBEDTLS_SSL_SIG_ALG(MBEDTLS_SSL_HASH_SHA224)
+#endif
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_MD_CAN_SHA256)
+ MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256,
+#endif /* MBEDTLS_RSA_C && MBEDTLS_MD_CAN_SHA256 */
+#if defined(MBEDTLS_MD_CAN_SHA1)
+ /* Allow SHA-1 as we use it extensively in tests. */
+ MBEDTLS_SSL_SIG_ALG(MBEDTLS_SSL_HASH_SHA1)
+#endif
+ MBEDTLS_TLS1_3_SIG_NONE
+};
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/** Functionally equivalent to mbedtls_x509_crt_verify_info, see that function
+ * for more info.
+ */
+int x509_crt_verify_info(char *buf, size_t size, const char *prefix,
+ uint32_t flags)
+{
+#if !defined(MBEDTLS_X509_REMOVE_INFO)
+ return mbedtls_x509_crt_verify_info(buf, size, prefix, flags);
+
+#else /* !MBEDTLS_X509_REMOVE_INFO */
+ int ret;
+ char *p = buf;
+ size_t n = size;
+
+#define X509_CRT_ERROR_INFO(err, err_str, info) \
+ if ((flags & err) != 0) \
+ { \
+ ret = mbedtls_snprintf(p, n, "%s%s\n", prefix, info); \
+ MBEDTLS_X509_SAFE_SNPRINTF; \
+ flags ^= err; \
+ }
+
+ MBEDTLS_X509_CRT_ERROR_INFO_LIST
+#undef X509_CRT_ERROR_INFO
+
+ if (flags != 0) {
+ ret = mbedtls_snprintf(p, n, "%sUnknown reason "
+ "(this should not happen)\n", prefix);
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+
+ return (int) (size - n);
+#endif /* MBEDTLS_X509_REMOVE_INFO */
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+void mbedtls_print_supported_sig_algs(void)
+{
+ mbedtls_printf("supported signature algorithms:\n");
+ mbedtls_printf("\trsa_pkcs1_sha256 ");
+ mbedtls_printf("rsa_pkcs1_sha384 ");
+ mbedtls_printf("rsa_pkcs1_sha512\n");
+ mbedtls_printf("\tecdsa_secp256r1_sha256 ");
+ mbedtls_printf("ecdsa_secp384r1_sha384 ");
+ mbedtls_printf("ecdsa_secp521r1_sha512\n");
+ mbedtls_printf("\trsa_pss_rsae_sha256 ");
+ mbedtls_printf("rsa_pss_rsae_sha384 ");
+ mbedtls_printf("rsa_pss_rsae_sha512\n");
+ mbedtls_printf("\trsa_pss_pss_sha256 ");
+ mbedtls_printf("rsa_pss_pss_sha384 ");
+ mbedtls_printf("rsa_pss_pss_sha512\n");
+ mbedtls_printf("\ted25519 ");
+ mbedtls_printf("ed448 ");
+ mbedtls_printf("rsa_pkcs1_sha1 ");
+ mbedtls_printf("ecdsa_sha1\n");
+ mbedtls_printf("\n");
+}