]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/test-https.c
AOSP: P2P find stopped ctrl_iface event of p2p_flush
[thirdparty/hostap.git] / tests / test-https.c
1 /*
2 * Testing tool for TLSv1 client routines using HTTPS
3 * Copyright (c) 2011, 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 #include <netdb.h>
11
12 #include "common.h"
13 #include "crypto/tls.h"
14
15 extern int wpa_debug_level;
16 extern int wpa_debug_show_keys;
17
18
19 static void https_tls_event_cb(void *ctx, enum tls_event ev,
20 union tls_event_data *data)
21 {
22 wpa_printf(MSG_DEBUG, "HTTPS: TLS event %d", ev);
23 }
24
25
26 static struct wpabuf * https_recv(int s)
27 {
28 struct wpabuf *in;
29 int len, ret;
30 fd_set rfds;
31 struct timeval tv;
32
33 in = wpabuf_alloc(20000);
34 if (in == NULL)
35 return NULL;
36
37 FD_ZERO(&rfds);
38 FD_SET(s, &rfds);
39 tv.tv_sec = 5;
40 tv.tv_usec = 0;
41
42 wpa_printf(MSG_DEBUG, "Waiting for more data");
43 ret = select(s + 1, &rfds, NULL, NULL, &tv);
44 if (ret < 0) {
45 wpa_printf(MSG_ERROR, "select: %s", strerror(errno));
46 wpabuf_free(in);
47 return NULL;
48 }
49 if (ret == 0) {
50 /* timeout */
51 wpa_printf(MSG_INFO, "Timeout on waiting for data");
52 wpabuf_free(in);
53 return NULL;
54 }
55
56 len = recv(s, wpabuf_put(in, 0), wpabuf_tailroom(in), 0);
57 if (len < 0) {
58 wpa_printf(MSG_ERROR, "recv: %s", strerror(errno));
59 wpabuf_free(in);
60 return NULL;
61 }
62 if (len == 0) {
63 wpa_printf(MSG_DEBUG, "No more data available");
64 wpabuf_free(in);
65 return NULL;
66 }
67 wpa_printf(MSG_DEBUG, "Received %d bytes", len);
68 wpabuf_put(in, len);
69
70 return in;
71 }
72
73
74 static int https_client(int s, const char *path)
75 {
76 struct tls_config conf;
77 void *tls;
78 struct tls_connection *conn;
79 struct wpabuf *in, *out, *appl;
80 int res = -1;
81 int need_more_data;
82
83 os_memset(&conf, 0, sizeof(conf));
84 conf.event_cb = https_tls_event_cb;
85 tls = tls_init(&conf);
86 if (tls == NULL)
87 return -1;
88
89 conn = tls_connection_init(tls);
90 if (conn == NULL) {
91 tls_deinit(tls);
92 return -1;
93 }
94
95 in = NULL;
96
97 for (;;) {
98 appl = NULL;
99 out = tls_connection_handshake2(tls, conn, in, &appl,
100 &need_more_data);
101 wpabuf_free(in);
102 in = NULL;
103 if (out == NULL) {
104 if (need_more_data)
105 goto read_more;
106 goto done;
107 }
108 if (tls_connection_get_failed(tls, conn)) {
109 wpa_printf(MSG_ERROR, "TLS handshake failed");
110 goto done;
111 }
112 if (tls_connection_established(tls, conn))
113 break;
114 wpa_printf(MSG_DEBUG, "Sending %d bytes",
115 (int) wpabuf_len(out));
116 if (send(s, wpabuf_head(out), wpabuf_len(out), 0) < 0) {
117 wpa_printf(MSG_ERROR, "send: %s", strerror(errno));
118 goto done;
119 }
120 wpabuf_free(out);
121 out = NULL;
122
123 read_more:
124 in = https_recv(s);
125 if (in == NULL)
126 goto done;
127 }
128 wpabuf_free(out);
129 out = NULL;
130
131 wpa_printf(MSG_INFO, "TLS connection established");
132 if (appl)
133 wpa_hexdump_buf(MSG_DEBUG, "Received application data", appl);
134
135 in = wpabuf_alloc(100 + os_strlen(path));
136 if (in == NULL)
137 goto done;
138 wpabuf_put_str(in, "GET ");
139 wpabuf_put_str(in, path);
140 wpabuf_put_str(in, " HTTP/1.0\r\n\r\n");
141 out = tls_connection_encrypt(tls, conn, in);
142 wpabuf_free(in);
143 in = NULL;
144 if (out == NULL)
145 goto done;
146
147 wpa_printf(MSG_INFO, "Sending HTTP request: %d bytes",
148 (int) wpabuf_len(out));
149 if (send(s, wpabuf_head(out), wpabuf_len(out), 0) < 0) {
150 wpa_printf(MSG_ERROR, "send: %s", strerror(errno));
151 goto done;
152 }
153 wpabuf_free(out);
154 out = NULL;
155
156 wpa_printf(MSG_INFO, "Reading HTTP response");
157 for (;;) {
158 int need_more_data;
159 in = https_recv(s);
160 if (in == NULL)
161 goto done;
162 out = tls_connection_decrypt2(tls, conn, in, &need_more_data);
163 if (need_more_data)
164 wpa_printf(MSG_DEBUG, "HTTP: Need more data");
165 wpabuf_free(in);
166 in = NULL;
167 if (out == NULL)
168 goto done;
169 wpa_hexdump_ascii(MSG_INFO, "Response", wpabuf_head(out),
170 wpabuf_len(out));
171 wpabuf_free(out);
172 out = NULL;
173 }
174
175 res = 0;
176 done:
177 wpabuf_free(out);
178 wpabuf_free(in);
179 wpabuf_free(appl);
180 tls_connection_deinit(tls, conn);
181 tls_deinit(tls);
182
183 return res;
184 }
185
186
187 int main(int argc, char *argv[])
188 {
189 struct addrinfo hints, *result, *rp;
190 int res, s;
191
192 wpa_debug_level = 0;
193 wpa_debug_show_keys = 1;
194
195 if (argc < 4) {
196 wpa_printf(MSG_INFO, "usage: test-https server port path");
197 return -1;
198 }
199
200 os_memset(&hints, 0, sizeof(hints));
201 hints.ai_family = AF_UNSPEC;
202 hints.ai_socktype = SOCK_STREAM;
203 res = getaddrinfo(argv[1], argv[2], &hints, &result);
204 if (res) {
205 wpa_printf(MSG_ERROR, "getaddrinfo: %s", gai_strerror(res));
206 return -1;
207 }
208
209 for (rp = result; rp; rp = rp->ai_next) {
210 s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
211 if (s < 0)
212 continue;
213 if (connect(s, rp->ai_addr, rp->ai_addrlen) == 0)
214 break;
215 close(s);
216 }
217 freeaddrinfo(result);
218
219 if (rp == NULL) {
220 wpa_printf(MSG_ERROR, "Could not connect");
221 return -1;
222 }
223
224 https_client(s, argv[3]);
225 close(s);
226
227 return 0;
228 }