blob: 9dcca559630cabcad5597a20d626615bc65ada18 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2 * Testing tool for TLSv1 server routines using HTTPS
3 * Copyright (c) 2011-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
15static void https_tls_event_cb(void *ctx, enum tls_event ev,
16 union tls_event_data *data)
17{
18 wpa_printf(MSG_DEBUG, "HTTPS: TLS event %d", ev);
19}
20
21
22static struct wpabuf * https_recv(int s, int timeout_ms)
23{
24 struct wpabuf *in;
25 int len, ret;
26 fd_set rfds;
27 struct timeval tv;
28
29 in = wpabuf_alloc(20000);
30 if (in == NULL)
31 return NULL;
32
33 FD_ZERO(&rfds);
34 FD_SET(s, &rfds);
35 tv.tv_sec = timeout_ms / 1000;
36 tv.tv_usec = timeout_ms % 1000;
37
38 wpa_printf(MSG_DEBUG, "Waiting for more data");
39 ret = select(s + 1, &rfds, NULL, NULL, &tv);
40 if (ret < 0) {
41 wpa_printf(MSG_ERROR, "select: %s", strerror(errno));
42 wpabuf_free(in);
43 return NULL;
44 }
45 if (ret == 0) {
46 /* timeout */
47 wpa_printf(MSG_INFO, "Timeout on waiting for data");
48 wpabuf_free(in);
49 return NULL;
50 }
51
52 len = recv(s, wpabuf_put(in, 0), wpabuf_tailroom(in), 0);
53 if (len < 0) {
54 wpa_printf(MSG_ERROR, "recv: %s", strerror(errno));
55 wpabuf_free(in);
56 return NULL;
57 }
58 if (len == 0) {
59 wpa_printf(MSG_DEBUG, "No more data available");
60 wpabuf_free(in);
61 return NULL;
62 }
63 wpa_printf(MSG_DEBUG, "Received %d bytes", len);
64 wpabuf_put(in, len);
65
66 return in;
67}
68
69
70#ifdef CONFIG_TLS_INTERNAL_SERVER
71static void https_tls_log_cb(void *ctx, const char *msg)
72{
73 wpa_printf(MSG_DEBUG, "TLS: %s", msg);
74}
75#endif
76
77
78static int https_server(int s)
79{
80 struct tls_config conf;
81 void *tls;
82 struct tls_connection_params params;
83 struct tls_connection *conn;
84 struct wpabuf *in = NULL, *out = NULL, *appl = NULL;
85 int res = -1;
86
87 os_memset(&conf, 0, sizeof(conf));
88 conf.event_cb = https_tls_event_cb;
89 tls = tls_init(&conf);
90 if (!tls)
91 return -1;
92
93 os_memset(&params, 0, sizeof(params));
94 params.ca_cert = "hwsim/auth_serv/ca.pem";
95 params.client_cert = "hwsim/auth_serv/server.pem";
96 params.private_key = "hwsim/auth_serv/server.key";
97 params.dh_file = "hwsim/auth_serv/dh.conf";
98
99 if (tls_global_set_params(tls, &params)) {
100 wpa_printf(MSG_ERROR, "Failed to set TLS parameters");
101 tls_deinit(tls);
102 return -1;
103 }
104
105 conn = tls_connection_init(tls);
106 if (!conn) {
107 tls_deinit(tls);
108 return -1;
109 }
110
111#ifdef CONFIG_TLS_INTERNAL_SERVER
112 tls_connection_set_log_cb(conn, https_tls_log_cb, NULL);
113#endif
114
115 for (;;) {
116 in = https_recv(s, 5000);
117 if (!in)
118 goto done;
119
120 appl = NULL;
121 out = tls_connection_server_handshake(tls, conn, in, &appl);
122 wpabuf_free(in);
123 in = NULL;
124 if (!out) {
125 if (!tls_connection_get_failed(tls, conn) &&
126 !tls_connection_established(tls, conn))
127 continue;
128 goto done;
129 }
130 wpa_printf(MSG_DEBUG, "Sending %d bytes",
131 (int) wpabuf_len(out));
132 if (send(s, wpabuf_head(out), wpabuf_len(out), 0) < 0) {
133 wpa_printf(MSG_ERROR, "send: %s", strerror(errno));
134 goto done;
135 }
136 wpabuf_free(out);
137 out = NULL;
138 if (tls_connection_get_failed(tls, conn)) {
139 wpa_printf(MSG_ERROR, "TLS handshake failed");
140 goto done;
141 }
142 if (tls_connection_established(tls, conn))
143 break;
144 }
145 wpabuf_free(out);
146 out = NULL;
147
148 wpa_printf(MSG_INFO, "TLS connection established");
149 if (appl)
150 wpa_hexdump_buf(MSG_DEBUG, "Received application data", appl);
151
152 wpa_printf(MSG_INFO, "Reading HTTP request");
153 for (;;) {
154 int need_more_data = 0;
155
156 in = https_recv(s, 5000);
157 if (!in)
158 goto done;
159#ifdef CONFIG_TLS_INTERNAL_SERVER
160 out = tls_connection_decrypt2(tls, conn, in, &need_more_data);
161#else
162 out = tls_connection_decrypt(tls, conn, in);
163#endif
164 wpabuf_free(in);
165 in = NULL;
166 if (need_more_data) {
167 wpa_printf(MSG_DEBUG, "HTTP: Need more data");
168 continue;
169 }
170 if (!out)
171 goto done;
172 wpa_hexdump_ascii(MSG_INFO, "Request",
173 wpabuf_head(out), wpabuf_len(out));
174 wpabuf_free(out);
175 out = NULL;
176 break;
177 }
178
179 in = wpabuf_alloc(1000);
180 if (!in)
181 goto done;
182 wpabuf_put_str(in, "HTTP/1.1 200 OK\r\n"
183 "Server: test-https_server\r\n"
184 "\r\n"
185 "<HTML><BODY>HELLO</BODY></HTML>\n");
186 wpa_hexdump_ascii(MSG_DEBUG, "Response",
187 wpabuf_head(in), wpabuf_len(in));
188 out = tls_connection_encrypt(tls, conn, in);
189 wpabuf_free(in);
190 in = NULL;
191 wpa_hexdump_buf(MSG_DEBUG, "Encrypted response", out);
192 if (!out)
193 goto done;
194
195 wpa_printf(MSG_INFO, "Sending HTTP response: %d bytes",
196 (int) wpabuf_len(out));
197 if (send(s, wpabuf_head(out), wpabuf_len(out), 0) < 0) {
198 wpa_printf(MSG_ERROR, "send: %s", strerror(errno));
199 goto done;
200 }
201 wpabuf_free(out);
202 out = NULL;
203
204 res = 0;
205done:
206 wpabuf_free(out);
207 wpabuf_free(in);
208 wpabuf_free(appl);
209 tls_connection_deinit(tls, conn);
210 tls_deinit(tls);
211 close(s);
212
213 return res;
214}
215
216
217int main(int argc, char *argv[])
218{
219 struct sockaddr_in sin;
220 int port, s, conn;
221 int on = 1;
222
223 wpa_debug_level = 0;
224 wpa_debug_show_keys = 1;
225
226 if (argc < 2) {
227 wpa_printf(MSG_INFO, "usage: test-https_server port");
228 return -1;
229 }
230
231 port = atoi(argv[1]);
232
233 s = socket(AF_INET, SOCK_STREAM, 0);
234 if (s < 0) {
235 perror("socket");
236 return -1;
237 }
238
239 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
240 wpa_printf(MSG_DEBUG,
241 "HTTP: setsockopt(SO_REUSEADDR) failed: %s",
242 strerror(errno));
243 /* try to continue anyway */
244 }
245
246 os_memset(&sin, 0, sizeof(sin));
247 sin.sin_family = AF_INET;
248 sin.sin_port = htons(port);
249 if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
250 perror("bind");
251 close(s);
252 return -1;
253 }
254
255 if (listen(s, 10) < 0) {
256 perror("listen");
257 close(s);
258 return -1;
259 }
260
261 for (;;) {
262 struct sockaddr_in addr;
263 socklen_t addr_len = sizeof(addr);
264
265 conn = accept(s, (struct sockaddr *) &addr, &addr_len);
266 if (conn < 0) {
267 perror("accept");
268 break;
269 }
270
271 wpa_printf(MSG_DEBUG, "-------------------------------------");
272 wpa_printf(MSG_DEBUG, "Connection from %s:%d",
273 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
274
275 https_server(conn);
276 wpa_printf(MSG_DEBUG, "Done with the connection");
277 wpa_printf(MSG_DEBUG, "-------------------------------------");
278 }
279
280 close(s);
281
282 return 0;
283}