blob: 7702bf268752149b89d6898c93fcecc77f273ef7 [file] [log] [blame]
Mateusz Starzyk6c2e9b62021-05-19 17:54:54 +02001#define MBEDTLS_ALLOW_PRIVATE_ACCESS
2
Philippe Antoine72333522018-05-03 16:40:24 +02003#include "mbedtls/ssl.h"
4#include "mbedtls/entropy.h"
5#include "mbedtls/ctr_drbg.h"
Mateusz Starzyk1aec6462021-02-08 15:34:42 +01006#include "test/certs.h"
Philippe Antoine08633822019-06-04 14:03:06 +02007#include "common.h"
Philippe Antoine72333522018-05-03 16:40:24 +02008#include <string.h>
9#include <stdlib.h>
Philippe Antoine72333522018-05-03 16:40:24 +020010#include <stdint.h>
11
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020012#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_ENTROPY_C) && \
Manuel Pégourié-Gonnarda89040c2020-05-20 10:35:01 +020013 defined(MBEDTLS_CTR_DRBG_C)
Philippe Antoine42a2ce82019-07-10 14:26:31 +020014static int initialized = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020015# if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
Philippe Antoine72333522018-05-03 16:40:24 +020016static mbedtls_x509_crt cacert;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020017# endif
Philippe Antoine72333522018-05-03 16:40:24 +020018const char *alpn_list[3];
19
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020020# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
21const unsigned char psk[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
22 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
Philippe Antoine72333522018-05-03 16:40:24 +020023const char psk_id[] = "Client_identity";
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020024# endif
Philippe Antoine72333522018-05-03 16:40:24 +020025
26const char *pers = "fuzz_client";
Manuel Pégourié-Gonnarda89040c2020-05-20 10:35:01 +020027#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
Philippe Antoine72333522018-05-03 16:40:24 +020028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
30{
31#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_ENTROPY_C) && \
Manuel Pégourié-Gonnarda89040c2020-05-20 10:35:01 +020032 defined(MBEDTLS_CTR_DRBG_C)
Philippe Antoine72333522018-05-03 16:40:24 +020033 int ret;
34 size_t len;
35 mbedtls_ssl_context ssl;
36 mbedtls_ssl_config conf;
37 mbedtls_ctr_drbg_context ctr_drbg;
38 mbedtls_entropy_context entropy;
39 unsigned char buf[4096];
40 fuzzBufferOffset_t biomemfuzz;
41 uint16_t options;
42
43 if (initialized == 0) {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020044# if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
45 mbedtls_x509_crt_init(&cacert);
46 if (mbedtls_x509_crt_parse(&cacert,
47 (const unsigned char *)mbedtls_test_cas_pem,
48 mbedtls_test_cas_pem_len) != 0)
Philippe Antoine72333522018-05-03 16:40:24 +020049 return 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020050# endif
Philippe Antoine72333522018-05-03 16:40:24 +020051
52 alpn_list[0] = "HTTP";
53 alpn_list[1] = "fuzzalpn";
54 alpn_list[2] = NULL;
55
Philippe Antoine08633822019-06-04 14:03:06 +020056 dummy_init();
57
Philippe Antoine72333522018-05-03 16:40:24 +020058 initialized = 1;
59 }
60
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020061 // we take 1 byte as options input
Philippe Antoine72333522018-05-03 16:40:24 +020062 if (Size < 2) {
63 return 0;
64 }
65 options = (Data[Size - 2] << 8) | Data[Size - 1];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020066 // Avoid warnings if compile options imply no options
67 (void)options;
Philippe Antoine72333522018-05-03 16:40:24 +020068
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020069 mbedtls_ssl_init(&ssl);
70 mbedtls_ssl_config_init(&conf);
71 mbedtls_ctr_drbg_init(&ctr_drbg);
72 mbedtls_entropy_init(&entropy);
Philippe Antoine72333522018-05-03 16:40:24 +020073
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020074 if (mbedtls_ctr_drbg_seed(&ctr_drbg, dummy_entropy, &entropy,
75 (const unsigned char *)pers, strlen(pers)) != 0)
Philippe Antoine72333522018-05-03 16:40:24 +020076 goto exit;
77
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020078 if (mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT,
Philippe Antoine72333522018-05-03 16:40:24 +020079 MBEDTLS_SSL_TRANSPORT_STREAM,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080 MBEDTLS_SSL_PRESET_DEFAULT) != 0)
Philippe Antoine72333522018-05-03 16:40:24 +020081 goto exit;
82
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
Philippe Antoine72333522018-05-03 16:40:24 +020084 if (options & 2) {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020085 mbedtls_ssl_conf_psk(&conf, psk, sizeof(psk),
86 (const unsigned char *)psk_id, sizeof(psk_id) - 1);
Philippe Antoine72333522018-05-03 16:40:24 +020087 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020088# endif
Philippe Antoine72333522018-05-03 16:40:24 +020089
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090# if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
Philippe Antoine72333522018-05-03 16:40:24 +020091 if (options & 4) {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020092 mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
93 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
Philippe Antoine72333522018-05-03 16:40:24 +020094 } else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020095# endif
Philippe Antoine72333522018-05-03 16:40:24 +020096 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020097 mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_NONE);
Philippe Antoine72333522018-05-03 16:40:24 +020098 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020099# if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
100 mbedtls_ssl_conf_extended_master_secret(
101 &conf, (options & 0x10) ? MBEDTLS_SSL_EXTENDED_MS_DISABLED :
102 MBEDTLS_SSL_EXTENDED_MS_ENABLED);
103# endif
104# if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
105 mbedtls_ssl_conf_encrypt_then_mac(&conf, (options & 0x20) ?
106 MBEDTLS_SSL_ETM_DISABLED :
107 MBEDTLS_SSL_ETM_ENABLED);
108# endif
109# if defined(MBEDTLS_SSL_RENEGOTIATION)
110 mbedtls_ssl_conf_renegotiation(
111 &conf, (options & 0x80) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED :
112 MBEDTLS_SSL_RENEGOTIATION_DISABLED);
113# endif
114# if defined(MBEDTLS_SSL_SESSION_TICKETS)
115 mbedtls_ssl_conf_session_tickets(
116 &conf, (options & 0x100) ? MBEDTLS_SSL_SESSION_TICKETS_DISABLED :
117 MBEDTLS_SSL_SESSION_TICKETS_ENABLED);
118# endif
119# if defined(MBEDTLS_SSL_ALPN)
Philippe Antoine72333522018-05-03 16:40:24 +0200120 if (options & 0x200) {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200121 mbedtls_ssl_conf_alpn_protocols(&conf, alpn_list);
Philippe Antoine72333522018-05-03 16:40:24 +0200122 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200123# endif
124 // There may be other options to add :
Philippe Antoine72333522018-05-03 16:40:24 +0200125 // mbedtls_ssl_conf_cert_profile, mbedtls_ssl_conf_sig_hashes
126
Philippe Antoine2b7c9a22019-06-04 12:05:36 +0200127 srand(1);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200128 mbedtls_ssl_conf_rng(&conf, dummy_random, &ctr_drbg);
Philippe Antoine72333522018-05-03 16:40:24 +0200129
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200130 if (mbedtls_ssl_setup(&ssl, &conf) != 0)
Philippe Antoine72333522018-05-03 16:40:24 +0200131 goto exit;
132
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200133# if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_PEM_PARSE_C)
Philippe Antoine72333522018-05-03 16:40:24 +0200134 if ((options & 1) == 0) {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 if (mbedtls_ssl_set_hostname(&ssl, "localhost") != 0)
Philippe Antoine72333522018-05-03 16:40:24 +0200136 goto exit;
137 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200138# endif
Philippe Antoine72333522018-05-03 16:40:24 +0200139
140 biomemfuzz.Data = Data;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200141 biomemfuzz.Size = Size - 2;
Philippe Antoine72333522018-05-03 16:40:24 +0200142 biomemfuzz.Offset = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200143 mbedtls_ssl_set_bio(&ssl, &biomemfuzz, dummy_send, fuzz_recv, NULL);
Philippe Antoine72333522018-05-03 16:40:24 +0200144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145 ret = mbedtls_ssl_handshake(&ssl);
146 if (ret == 0) {
147 // keep reading data from server until the end
148 do {
149 len = sizeof(buf) - 1;
150 ret = mbedtls_ssl_read(&ssl, buf, len);
Philippe Antoine72333522018-05-03 16:40:24 +0200151
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 if (ret == MBEDTLS_ERR_SSL_WANT_READ)
Philippe Antoine72333522018-05-03 16:40:24 +0200153 continue;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200154 else if (ret <= 0)
155 // EOF or error
Philippe Antoine72333522018-05-03 16:40:24 +0200156 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200157 } while (1);
Philippe Antoine72333522018-05-03 16:40:24 +0200158 }
159
160exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161 mbedtls_entropy_free(&entropy);
162 mbedtls_ctr_drbg_free(&ctr_drbg);
163 mbedtls_ssl_config_free(&conf);
164 mbedtls_ssl_free(&ssl);
Philippe Antoine72333522018-05-03 16:40:24 +0200165
Philippe Antoinec32fd242019-06-06 09:12:53 +0200166#else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200167 (void)Data;
168 (void)Size;
Manuel Pégourié-Gonnarda89040c2020-05-20 10:35:01 +0200169#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_ENTROPY_C && MBEDTLS_CTR_DRBG_C */
Philippe Antoinec32fd242019-06-06 09:12:53 +0200170
Philippe Antoine72333522018-05-03 16:40:24 +0200171 return 0;
172}