1 /*
2 * Testing tool for TLSv1 server 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_server;
60 struct tls_connection_params params;
61 struct tls_connection *conn_server = 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_server = tls_init(&conf);
73 if (!tls_server)
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 params.dh_file = CERTDIR "dh.conf";
81
82 if (tls_global_set_params(tls_server, ¶ms)) {
83 wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
84 goto fail;
85 }
86
87 conn_server = tls_connection_init(tls_server);
88 if (!conn_server)
89 goto fail;
90
91 in = NULL;
92 for (;;) {
93 appl = NULL;
94 out = read_msg(&ctx);
95 wpabuf_free(in);
96 in = NULL;
97 if (!out)
98 goto fail;
99
100 appl = NULL;
101 in = tls_connection_server_handshake(tls_server, conn_server,
102 out, &appl);
103 wpabuf_free(out);
104 out = NULL;
105 if (!in)
106 goto fail;
107 if (tls_connection_get_failed(tls_server, conn_server)) {
108 wpa_printf(MSG_ERROR, "TLS handshake failed");
109 goto fail;
110 }
111 if (tls_connection_established(tls_server, conn_server))
112 break;
113 }
114
115 wpabuf_free(in);
116 in = wpabuf_alloc(100);
117 if (!in)
118 goto fail;
119 wpabuf_put_str(in, "PING");
120 wpabuf_free(out);
121 out = read_msg(&ctx);
122 wpabuf_free(in);
123 in = NULL;
124 if (!out)
125 goto fail;
126
127 in = tls_connection_decrypt(tls_server, conn_server, out);
128 wpabuf_free(out);
129 out = NULL;
130 if (!in)
131 goto fail;
132 wpa_hexdump_buf(MSG_DEBUG, "Server decrypted ApplData", in);
133
134 wpabuf_free(in);
135 in = wpabuf_alloc(100);
136 if (!in)
137 goto fail;
138 wpabuf_put_str(in, "PONG");
139 wpabuf_free(out);
140 out = tls_connection_encrypt(tls_server, conn_server, in);
141 wpabuf_free(in);
142 in = NULL;
143 if (!out)
144 goto fail;
145
146 ret = 0;
147 fail:
148 if (tls_server) {
149 if (conn_server)
150 tls_connection_deinit(tls_server, conn_server);
151 tls_deinit(tls_server);
152 }
153 wpabuf_free(in);
154 wpabuf_free(out);
155
156 return ret;
157 }
158