]>
Commit | Line | Data |
---|---|---|
1ac9c020 JM |
1 | /* |
2 | * Testing tool for TLSv1 client/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 | ||
14 | ||
15 | static void usage(void) { | |
16 | wpa_printf(MSG_INFO, | |
17 | "usage: test-tls <server/client> <read/write> <file>"); | |
18 | exit(-1); | |
19 | } | |
20 | ||
21 | ||
22 | static void write_msg(FILE *f, struct wpabuf *msg) | |
23 | { | |
24 | u8 len[2]; | |
25 | ||
26 | wpa_printf(MSG_DEBUG, "TEST: Write message to file (msg_len=%u)", | |
27 | (unsigned int) wpabuf_len(msg)); | |
28 | WPA_PUT_BE16(len, wpabuf_len(msg)); | |
29 | fwrite(len, 2, 1, f); | |
30 | fwrite(wpabuf_head(msg), wpabuf_len(msg), 1, f); | |
31 | } | |
32 | ||
33 | ||
34 | static struct wpabuf * read_msg(FILE *f) | |
35 | { | |
36 | u8 len[2]; | |
37 | u16 msg_len; | |
38 | struct wpabuf *msg; | |
39 | ||
40 | if (fread(len, 2, 1, f) != 1) { | |
41 | wpa_printf(MSG_ERROR, "TEST-ERROR: Could not read msg len"); | |
42 | return NULL; | |
43 | } | |
44 | msg_len = WPA_GET_BE16(len); | |
45 | ||
46 | msg = wpabuf_alloc(msg_len); | |
47 | if (!msg) | |
48 | return NULL; | |
49 | if (msg_len > 0 && | |
50 | fread(wpabuf_put(msg, msg_len), msg_len, 1, f) != 1) { | |
51 | wpa_printf(MSG_ERROR, "TEST-ERROR: Truncated msg (msg_len=%u)", | |
52 | msg_len); | |
53 | wpabuf_free(msg); | |
54 | return NULL; | |
55 | } | |
56 | wpa_hexdump_buf(MSG_DEBUG, "TEST: Read message from file", msg); | |
57 | ||
58 | return msg; | |
59 | } | |
60 | ||
61 | ||
62 | int main(int argc, char *argv[]) | |
63 | { | |
64 | struct tls_config conf; | |
65 | void *tls_server, *tls_client; | |
66 | struct tls_connection_params params; | |
67 | struct tls_connection *conn_server = NULL, *conn_client = NULL; | |
68 | int ret = -1; | |
69 | struct wpabuf *in = NULL, *out = NULL, *appl; | |
70 | enum { SERVER, CLIENT } test_peer; | |
71 | enum { READ, WRITE } test_oper; | |
72 | const char *file; | |
73 | FILE *f; | |
74 | ||
75 | wpa_debug_level = 0; | |
76 | wpa_debug_show_keys = 1; | |
77 | ||
78 | if (argc < 4) | |
79 | usage(); | |
80 | ||
81 | if (os_strcmp(argv[1], "server") == 0) | |
82 | test_peer = SERVER; | |
83 | else if (os_strcmp(argv[1], "client") == 0) | |
84 | test_peer = CLIENT; | |
85 | else | |
86 | usage(); | |
87 | ||
88 | if (os_strcmp(argv[2], "read") == 0) | |
89 | test_oper = READ; | |
90 | else if (os_strcmp(argv[2], "write") == 0) | |
91 | test_oper = WRITE; | |
92 | else | |
93 | usage(); | |
94 | ||
95 | file = argv[3]; | |
96 | ||
97 | f = fopen(file, test_oper == READ ? "r" : "w"); | |
98 | if (!f) | |
99 | return -1; | |
100 | ||
101 | os_memset(&conf, 0, sizeof(conf)); | |
102 | tls_server = tls_init(&conf); | |
103 | tls_client = tls_init(&conf); | |
104 | if (!tls_server || !tls_client) | |
105 | goto fail; | |
106 | ||
107 | os_memset(¶ms, 0, sizeof(params)); | |
108 | params.ca_cert = "hwsim/auth_serv/ca.pem"; | |
109 | params.client_cert = "hwsim/auth_serv/server.pem"; | |
110 | params.private_key = "hwsim/auth_serv/server.key"; | |
111 | params.dh_file = "hwsim/auth_serv/dh.conf"; | |
112 | ||
113 | if (tls_global_set_params(tls_server, ¶ms)) { | |
114 | wpa_printf(MSG_ERROR, "Failed to set TLS parameters"); | |
115 | goto fail; | |
116 | } | |
117 | ||
118 | conn_server = tls_connection_init(tls_server); | |
119 | conn_client = tls_connection_init(tls_client); | |
120 | if (!conn_server || !conn_client) | |
121 | goto fail; | |
122 | ||
123 | in = NULL; | |
124 | for (;;) { | |
125 | appl = NULL; | |
126 | if (test_peer == CLIENT && test_oper == READ) | |
127 | out = read_msg(f); | |
128 | else | |
129 | out = tls_connection_handshake(tls_client, conn_client, | |
130 | in, &appl); | |
131 | wpabuf_free(in); | |
132 | in = NULL; | |
133 | if (!out) | |
134 | goto fail; | |
135 | if (test_peer == CLIENT && test_oper == WRITE && | |
136 | wpabuf_len(out) > 0) | |
137 | write_msg(f, out); | |
138 | if (!(test_peer == CLIENT && test_oper == READ) && | |
139 | tls_connection_get_failed(tls_client, conn_client)) { | |
140 | wpa_printf(MSG_ERROR, "TLS handshake failed"); | |
141 | goto fail; | |
142 | } | |
143 | if (((test_peer == CLIENT && test_oper == READ) || | |
144 | tls_connection_established(tls_client, conn_client)) && | |
145 | ((test_peer == SERVER && test_oper == READ) || | |
146 | tls_connection_established(tls_server, conn_server))) | |
147 | break; | |
148 | ||
149 | appl = NULL; | |
150 | if (test_peer == SERVER && test_oper == READ) | |
151 | in = read_msg(f); | |
152 | else | |
153 | in = tls_connection_server_handshake(tls_server, | |
154 | conn_server, | |
155 | out, &appl); | |
156 | wpabuf_free(out); | |
157 | out = NULL; | |
158 | if (!in) | |
159 | goto fail; | |
160 | if (test_peer == SERVER && test_oper == WRITE) | |
161 | write_msg(f, in); | |
162 | if (!(test_peer == SERVER && test_oper == READ) && | |
163 | tls_connection_get_failed(tls_server, conn_server)) { | |
164 | wpa_printf(MSG_ERROR, "TLS handshake failed"); | |
165 | goto fail; | |
166 | } | |
167 | if (((test_peer == CLIENT && test_oper == READ) || | |
168 | tls_connection_established(tls_client, conn_client)) && | |
169 | ((test_peer == SERVER && test_oper == READ) || | |
170 | tls_connection_established(tls_server, conn_server))) | |
171 | break; | |
172 | } | |
173 | ||
174 | wpabuf_free(in); | |
175 | in = wpabuf_alloc(100); | |
176 | if (!in) | |
177 | goto fail; | |
178 | wpabuf_put_str(in, "PING"); | |
179 | wpabuf_free(out); | |
180 | if (test_peer == CLIENT && test_oper == READ) | |
181 | out = read_msg(f); | |
182 | else | |
183 | out = tls_connection_encrypt(tls_client, conn_client, in); | |
184 | wpabuf_free(in); | |
185 | in = NULL; | |
186 | if (!out) | |
187 | goto fail; | |
188 | if (test_peer == CLIENT && test_oper == WRITE) | |
189 | write_msg(f, out); | |
190 | ||
191 | if (!(test_peer == SERVER && test_oper == READ)) { | |
192 | in = tls_connection_decrypt(tls_server, conn_server, out); | |
193 | wpabuf_free(out); | |
194 | out = NULL; | |
195 | if (!in) | |
196 | goto fail; | |
197 | wpa_hexdump_buf(MSG_DEBUG, "Server decrypted ApplData", in); | |
198 | } | |
199 | ||
200 | wpabuf_free(in); | |
201 | in = wpabuf_alloc(100); | |
202 | if (!in) | |
203 | goto fail; | |
204 | wpabuf_put_str(in, "PONG"); | |
205 | wpabuf_free(out); | |
206 | if (test_peer == SERVER && test_oper == READ) | |
207 | out = read_msg(f); | |
208 | else | |
209 | out = tls_connection_encrypt(tls_server, conn_server, in); | |
210 | wpabuf_free(in); | |
211 | in = NULL; | |
212 | if (!out) | |
213 | goto fail; | |
214 | if (test_peer == SERVER && test_oper == WRITE) | |
215 | write_msg(f, out); | |
216 | ||
217 | if (!(test_peer == CLIENT && test_oper == READ)) { | |
218 | in = tls_connection_decrypt(tls_client, conn_client, out); | |
219 | wpabuf_free(out); | |
220 | out = NULL; | |
221 | if (!in) | |
222 | goto fail; | |
223 | wpa_hexdump_buf(MSG_DEBUG, "Client decrypted ApplData", in); | |
224 | } | |
225 | ||
226 | ret = 0; | |
227 | fail: | |
228 | if (tls_server) { | |
229 | if (conn_server) | |
230 | tls_connection_deinit(tls_server, conn_server); | |
231 | tls_deinit(tls_server); | |
232 | } | |
233 | if (tls_client) { | |
234 | if (conn_client) | |
235 | tls_connection_deinit(tls_server, conn_client); | |
236 | tls_deinit(tls_client); | |
237 | } | |
238 | wpabuf_free(in); | |
239 | wpabuf_free(out); | |
240 | fclose(f); | |
241 | ||
242 | return ret; | |
243 | } |