1 /*
2 * Testing tool for TLSv1 client routines
3 * Copyright (c) 2019, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "crypto/tls.h"
13 #include "../fuzzer-common.h"
14
15 #ifndef CERTDIR
16 #define CERTDIR "../../hwsim/auth_serv/"
17 #endif
18
19 struct context {
20 const u8 *data;
21 size_t data_len;
22 size_t data_offset;
23 };
24
25
read_msg(struct context * ctx)26 static struct wpabuf * read_msg(struct context *ctx)
27 {
28 u16 msg_len;
29 struct wpabuf *msg;
30
31 if (ctx->data_len - ctx->data_offset < 2) {
32 wpa_printf(MSG_ERROR, "TEST-ERROR: Could not read msg len");
33 return NULL;
34 }
35 msg_len = WPA_GET_BE16(&ctx->data[ctx->data_offset]);
36 ctx->data_offset += 2;
37
38 msg = wpabuf_alloc(msg_len);
39 if (!msg)
40 return NULL;
41 if (msg_len > 0 && ctx->data_len - ctx->data_offset < msg_len) {
42 wpa_printf(MSG_ERROR, "TEST-ERROR: Truncated msg (msg_len=%u)",
43 msg_len);
44 wpabuf_free(msg);
45 return NULL;
46 }
47 wpabuf_put_data(msg, &ctx->data[ctx->data_offset], msg_len);
48 ctx->data_offset += msg_len;
49 wpa_hexdump_buf(MSG_DEBUG, "TEST: Read message from file", msg);
50
51 return msg;
52 }
53
54
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)55 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
56 {
57 struct context ctx;
58 struct tls_config conf;
59 void *tls_client;
60 struct tls_connection_params params;
61 struct tls_connection *conn_client = NULL;
62 int ret = -1;
63 struct wpabuf *in = NULL, *out = NULL, *appl;
64
65 wpa_fuzzer_set_debug_level();
66
67 os_memset(&ctx, 0, sizeof(ctx));
68 ctx.data = data;
69 ctx.data_len = size;
70
71 os_memset(&conf, 0, sizeof(conf));
72 tls_client = tls_init(&conf);
73 if (!tls_client)
74 goto fail;
75
76 os_memset(¶ms, 0, sizeof(params));
77 params.ca_cert = CERTDIR "ca.pem";
78 params.client_cert = CERTDIR "server.pem";
79 params.private_key = CERTDIR "server.key";
80
81 conn_client = tls_connection_init(tls_client);
82 if (!conn_client)
83 goto fail;
84
85 in = NULL;
86 for (;;) {
87 appl = NULL;
88 out = tls_connection_handshake(tls_client, conn_client, in,
89 &appl);
90 wpabuf_free(in);
91 in = NULL;
92 if (!out)
93 goto fail;
94 if (tls_connection_get_failed(tls_client, conn_client)) {
95 wpa_printf(MSG_ERROR, "TLS handshake failed");
96 goto fail;
97 }
98 if (tls_connection_established(tls_client, conn_client))
99 break;
100
101 appl = NULL;
102 in = read_msg(&ctx);
103 wpabuf_free(out);
104 out = NULL;
105 if (!in)
106 goto fail;
107 if (tls_connection_established(tls_client, conn_client))
108 break;
109 }
110
111 wpabuf_free(in);
112 in = wpabuf_alloc(100);
113 if (!in)
114 goto fail;
115 wpabuf_put_str(in, "PING");
116 wpabuf_free(out);
117 out = tls_connection_encrypt(tls_client, conn_client, in);
118 wpabuf_free(in);
119 in = NULL;
120 if (!out)
121 goto fail;
122
123 wpabuf_free(in);
124 in = wpabuf_alloc(100);
125 if (!in)
126 goto fail;
127 wpabuf_put_str(in, "PONG");
128 wpabuf_free(out);
129 out = read_msg(&ctx);
130 wpabuf_free(in);
131 in = NULL;
132 if (!out)
133 goto fail;
134
135 in = tls_connection_decrypt(tls_client, conn_client, out);
136 wpabuf_free(out);
137 out = NULL;
138 if (!in)
139 goto fail;
140 wpa_hexdump_buf(MSG_DEBUG, "Client decrypted ApplData", in);
141
142 ret = 0;
143 fail:
144 if (tls_client) {
145 if (conn_client)
146 tls_connection_deinit(tls_client, conn_client);
147 tls_deinit(tls_client);
148 }
149 wpabuf_free(in);
150 wpabuf_free(out);
151
152 return ret;
153 }
154