]>
Commit | Line | Data |
---|---|---|
6fc6879b | 1 | /* |
81c85c06 | 2 | * TLS interface functions and an internal TLS implementation |
235279e7 | 3 | * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> |
6fc6879b | 4 | * |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
6fc6879b JM |
7 | * |
8 | * This file interface functions for hostapd/wpa_supplicant to use the | |
9 | * integrated TLSv1 implementation. | |
10 | */ | |
11 | ||
12 | #include "includes.h" | |
13 | ||
14 | #include "common.h" | |
15 | #include "tls.h" | |
16 | #include "tls/tlsv1_client.h" | |
17 | #include "tls/tlsv1_server.h" | |
18 | ||
19 | ||
20 | static int tls_ref_count = 0; | |
21 | ||
22 | struct tls_global { | |
23 | int server; | |
24 | struct tlsv1_credentials *server_cred; | |
25 | int check_crl; | |
f2a6ad01 JM |
26 | |
27 | void (*event_cb)(void *ctx, enum tls_event ev, | |
28 | union tls_event_data *data); | |
29 | void *cb_ctx; | |
30 | int cert_in_cb; | |
6fc6879b JM |
31 | }; |
32 | ||
33 | struct tls_connection { | |
34 | struct tlsv1_client *client; | |
35 | struct tlsv1_server *server; | |
994afe33 | 36 | struct tls_global *global; |
6fc6879b JM |
37 | }; |
38 | ||
39 | ||
40 | void * tls_init(const struct tls_config *conf) | |
41 | { | |
42 | struct tls_global *global; | |
43 | ||
44 | if (tls_ref_count == 0) { | |
45 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
46 | if (tlsv1_client_global_init()) | |
47 | return NULL; | |
48 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
49 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
50 | if (tlsv1_server_global_init()) | |
51 | return NULL; | |
52 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
53 | } | |
54 | tls_ref_count++; | |
55 | ||
56 | global = os_zalloc(sizeof(*global)); | |
57 | if (global == NULL) | |
58 | return NULL; | |
f2a6ad01 JM |
59 | if (conf) { |
60 | global->event_cb = conf->event_cb; | |
61 | global->cb_ctx = conf->cb_ctx; | |
62 | global->cert_in_cb = conf->cert_in_cb; | |
63 | } | |
6fc6879b JM |
64 | |
65 | return global; | |
66 | } | |
67 | ||
68 | void tls_deinit(void *ssl_ctx) | |
69 | { | |
70 | struct tls_global *global = ssl_ctx; | |
71 | tls_ref_count--; | |
72 | if (tls_ref_count == 0) { | |
73 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
74 | tlsv1_client_global_deinit(); | |
75 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
76 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
6fc6879b JM |
77 | tlsv1_server_global_deinit(); |
78 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
79 | } | |
2e380795 JM |
80 | #ifdef CONFIG_TLS_INTERNAL_SERVER |
81 | tlsv1_cred_free(global->server_cred); | |
82 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
6fc6879b JM |
83 | os_free(global); |
84 | } | |
85 | ||
86 | ||
87 | int tls_get_errors(void *tls_ctx) | |
88 | { | |
89 | return 0; | |
90 | } | |
91 | ||
92 | ||
93 | struct tls_connection * tls_connection_init(void *tls_ctx) | |
94 | { | |
95 | struct tls_connection *conn; | |
96 | struct tls_global *global = tls_ctx; | |
97 | ||
98 | conn = os_zalloc(sizeof(*conn)); | |
99 | if (conn == NULL) | |
100 | return NULL; | |
994afe33 | 101 | conn->global = global; |
6fc6879b JM |
102 | |
103 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
104 | if (!global->server) { | |
105 | conn->client = tlsv1_client_init(); | |
106 | if (conn->client == NULL) { | |
107 | os_free(conn); | |
108 | return NULL; | |
109 | } | |
f2a6ad01 JM |
110 | tlsv1_client_set_cb(conn->client, global->event_cb, |
111 | global->cb_ctx, global->cert_in_cb); | |
6fc6879b JM |
112 | } |
113 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
114 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
115 | if (global->server) { | |
116 | conn->server = tlsv1_server_init(global->server_cred); | |
117 | if (conn->server == NULL) { | |
118 | os_free(conn); | |
119 | return NULL; | |
120 | } | |
121 | } | |
122 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
123 | ||
124 | return conn; | |
125 | } | |
126 | ||
127 | ||
390b9291 JM |
128 | #ifdef CONFIG_TESTING_OPTIONS |
129 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
130 | void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags) | |
131 | { | |
132 | if (conn->server) | |
133 | tlsv1_server_set_test_flags(conn->server, flags); | |
134 | } | |
135 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
136 | #endif /* CONFIG_TESTING_OPTIONS */ | |
137 | ||
138 | ||
994afe33 JM |
139 | void tls_connection_set_log_cb(struct tls_connection *conn, |
140 | void (*log_cb)(void *ctx, const char *msg), | |
141 | void *ctx) | |
142 | { | |
143 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
144 | if (conn->server) | |
145 | tlsv1_server_set_log_cb(conn->server, log_cb, ctx); | |
146 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
147 | } | |
148 | ||
149 | ||
6fc6879b JM |
150 | void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) |
151 | { | |
152 | if (conn == NULL) | |
153 | return; | |
154 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
155 | if (conn->client) | |
156 | tlsv1_client_deinit(conn->client); | |
157 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
158 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
159 | if (conn->server) | |
160 | tlsv1_server_deinit(conn->server); | |
161 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
162 | os_free(conn); | |
163 | } | |
164 | ||
165 | ||
166 | int tls_connection_established(void *tls_ctx, struct tls_connection *conn) | |
167 | { | |
168 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
169 | if (conn->client) | |
170 | return tlsv1_client_established(conn->client); | |
171 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
172 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
173 | if (conn->server) | |
174 | return tlsv1_server_established(conn->server); | |
175 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
176 | return 0; | |
177 | } | |
178 | ||
179 | ||
0ec3e77a JM |
180 | char * tls_connection_peer_serial_num(void *tls_ctx, |
181 | struct tls_connection *conn) | |
182 | { | |
183 | /* TODO */ | |
184 | return NULL; | |
185 | } | |
186 | ||
187 | ||
6fc6879b JM |
188 | int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn) |
189 | { | |
190 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
191 | if (conn->client) | |
192 | return tlsv1_client_shutdown(conn->client); | |
193 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
194 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
195 | if (conn->server) | |
196 | return tlsv1_server_shutdown(conn->server); | |
197 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
198 | return -1; | |
199 | } | |
200 | ||
201 | ||
202 | int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, | |
203 | const struct tls_connection_params *params) | |
204 | { | |
205 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
206 | struct tlsv1_credentials *cred; | |
207 | ||
208 | if (conn->client == NULL) | |
209 | return -1; | |
210 | ||
3c108b75 JM |
211 | if (params->flags & TLS_CONN_EXT_CERT_CHECK) { |
212 | wpa_printf(MSG_INFO, | |
213 | "TLS: tls_ext_cert_check=1 not supported"); | |
214 | return -1; | |
215 | } | |
216 | ||
6fc6879b JM |
217 | cred = tlsv1_cred_alloc(); |
218 | if (cred == NULL) | |
219 | return -1; | |
220 | ||
59051f8e JM |
221 | if (params->subject_match) { |
222 | wpa_printf(MSG_INFO, "TLS: subject_match not supported"); | |
c4b45c60 | 223 | tlsv1_cred_free(cred); |
59051f8e JM |
224 | return -1; |
225 | } | |
226 | ||
227 | if (params->altsubject_match) { | |
228 | wpa_printf(MSG_INFO, "TLS: altsubject_match not supported"); | |
c4b45c60 | 229 | tlsv1_cred_free(cred); |
59051f8e JM |
230 | return -1; |
231 | } | |
232 | ||
233 | if (params->suffix_match) { | |
234 | wpa_printf(MSG_INFO, "TLS: suffix_match not supported"); | |
c4b45c60 | 235 | tlsv1_cred_free(cred); |
59051f8e JM |
236 | return -1; |
237 | } | |
238 | ||
cebee30f JM |
239 | if (params->domain_match) { |
240 | wpa_printf(MSG_INFO, "TLS: domain_match not supported"); | |
c4b45c60 | 241 | tlsv1_cred_free(cred); |
cebee30f JM |
242 | return -1; |
243 | } | |
244 | ||
224104dd | 245 | if (params->openssl_ciphers) { |
c4b45c60 JM |
246 | wpa_printf(MSG_INFO, "TLS: openssl_ciphers not supported"); |
247 | tlsv1_cred_free(cred); | |
224104dd JM |
248 | return -1; |
249 | } | |
250 | ||
6fc6879b JM |
251 | if (tlsv1_set_ca_cert(cred, params->ca_cert, |
252 | params->ca_cert_blob, params->ca_cert_blob_len, | |
253 | params->ca_path)) { | |
254 | wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " | |
255 | "certificates"); | |
256 | tlsv1_cred_free(cred); | |
257 | return -1; | |
258 | } | |
259 | ||
260 | if (tlsv1_set_cert(cred, params->client_cert, | |
261 | params->client_cert_blob, | |
262 | params->client_cert_blob_len)) { | |
263 | wpa_printf(MSG_INFO, "TLS: Failed to configure client " | |
264 | "certificate"); | |
265 | tlsv1_cred_free(cred); | |
266 | return -1; | |
267 | } | |
268 | ||
269 | if (tlsv1_set_private_key(cred, params->private_key, | |
270 | params->private_key_passwd, | |
271 | params->private_key_blob, | |
272 | params->private_key_blob_len)) { | |
273 | wpa_printf(MSG_INFO, "TLS: Failed to load private key"); | |
274 | tlsv1_cred_free(cred); | |
275 | return -1; | |
276 | } | |
277 | ||
278 | if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, | |
279 | params->dh_blob_len)) { | |
280 | wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); | |
281 | tlsv1_cred_free(cred); | |
282 | return -1; | |
283 | } | |
284 | ||
285 | if (tlsv1_client_set_cred(conn->client, cred) < 0) { | |
286 | tlsv1_cred_free(cred); | |
287 | return -1; | |
288 | } | |
289 | ||
0cbc22b2 | 290 | tlsv1_client_set_flags(conn->client, params->flags); |
235279e7 | 291 | |
6fc6879b JM |
292 | return 0; |
293 | #else /* CONFIG_TLS_INTERNAL_CLIENT */ | |
294 | return -1; | |
295 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
296 | } | |
297 | ||
298 | ||
299 | int tls_global_set_params(void *tls_ctx, | |
300 | const struct tls_connection_params *params) | |
301 | { | |
302 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
303 | struct tls_global *global = tls_ctx; | |
304 | struct tlsv1_credentials *cred; | |
305 | ||
306 | /* Currently, global parameters are only set when running in server | |
307 | * mode. */ | |
308 | global->server = 1; | |
309 | tlsv1_cred_free(global->server_cred); | |
310 | global->server_cred = cred = tlsv1_cred_alloc(); | |
311 | if (cred == NULL) | |
312 | return -1; | |
313 | ||
314 | if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob, | |
315 | params->ca_cert_blob_len, params->ca_path)) { | |
316 | wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA " | |
317 | "certificates"); | |
318 | return -1; | |
319 | } | |
320 | ||
321 | if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob, | |
322 | params->client_cert_blob_len)) { | |
323 | wpa_printf(MSG_INFO, "TLS: Failed to configure server " | |
324 | "certificate"); | |
325 | return -1; | |
326 | } | |
327 | ||
328 | if (tlsv1_set_private_key(cred, params->private_key, | |
329 | params->private_key_passwd, | |
330 | params->private_key_blob, | |
331 | params->private_key_blob_len)) { | |
332 | wpa_printf(MSG_INFO, "TLS: Failed to load private key"); | |
333 | return -1; | |
334 | } | |
335 | ||
336 | if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob, | |
337 | params->dh_blob_len)) { | |
338 | wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters"); | |
339 | return -1; | |
340 | } | |
341 | ||
bca0872d JM |
342 | if (params->ocsp_stapling_response) |
343 | cred->ocsp_stapling_response = | |
344 | os_strdup(params->ocsp_stapling_response); | |
8ea6a270 JM |
345 | if (params->ocsp_stapling_response_multi) |
346 | cred->ocsp_stapling_response_multi = | |
347 | os_strdup(params->ocsp_stapling_response_multi); | |
bca0872d | 348 | |
6fc6879b JM |
349 | return 0; |
350 | #else /* CONFIG_TLS_INTERNAL_SERVER */ | |
351 | return -1; | |
352 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
353 | } | |
354 | ||
355 | ||
356 | int tls_global_set_verify(void *tls_ctx, int check_crl) | |
357 | { | |
358 | struct tls_global *global = tls_ctx; | |
359 | global->check_crl = check_crl; | |
360 | return 0; | |
361 | } | |
362 | ||
363 | ||
364 | int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, | |
bfbebd26 JM |
365 | int verify_peer, unsigned int flags, |
366 | const u8 *session_ctx, size_t session_ctx_len) | |
6fc6879b JM |
367 | { |
368 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
369 | if (conn->server) | |
370 | return tlsv1_server_set_verify(conn->server, verify_peer); | |
371 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
372 | return -1; | |
373 | } | |
374 | ||
375 | ||
1046db8b JM |
376 | int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, |
377 | struct tls_random *data) | |
6fc6879b JM |
378 | { |
379 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
380 | if (conn->client) | |
1046db8b | 381 | return tlsv1_client_get_random(conn->client, data); |
6fc6879b JM |
382 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ |
383 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
384 | if (conn->server) | |
1046db8b | 385 | return tlsv1_server_get_random(conn->server, data); |
6fc6879b JM |
386 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ |
387 | return -1; | |
388 | } | |
389 | ||
390 | ||
af851914 JM |
391 | static int tls_get_keyblock_size(struct tls_connection *conn) |
392 | { | |
393 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
394 | if (conn->client) | |
395 | return tlsv1_client_get_keyblock_size(conn->client); | |
396 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
397 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
398 | if (conn->server) | |
399 | return tlsv1_server_get_keyblock_size(conn->server); | |
400 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
401 | return -1; | |
402 | } | |
403 | ||
404 | ||
73581707 DB |
405 | static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn, |
406 | const char *label, int server_random_first, | |
407 | int skip_keyblock, u8 *out, size_t out_len) | |
af851914 JM |
408 | { |
409 | int ret = -1, skip = 0; | |
410 | u8 *tmp_out = NULL; | |
411 | u8 *_out = out; | |
412 | ||
413 | if (skip_keyblock) { | |
414 | skip = tls_get_keyblock_size(conn); | |
415 | if (skip < 0) | |
416 | return -1; | |
417 | tmp_out = os_malloc(skip + out_len); | |
418 | if (!tmp_out) | |
419 | return -1; | |
420 | _out = tmp_out; | |
421 | } | |
422 | ||
6fc6879b JM |
423 | #ifdef CONFIG_TLS_INTERNAL_CLIENT |
424 | if (conn->client) { | |
af851914 JM |
425 | ret = tlsv1_client_prf(conn->client, label, |
426 | server_random_first, | |
7fff91ae | 427 | _out, skip + out_len); |
6fc6879b JM |
428 | } |
429 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
430 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
431 | if (conn->server) { | |
af851914 JM |
432 | ret = tlsv1_server_prf(conn->server, label, |
433 | server_random_first, | |
7fff91ae | 434 | _out, skip + out_len); |
6fc6879b JM |
435 | } |
436 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
af851914 JM |
437 | if (ret == 0 && skip_keyblock) |
438 | os_memcpy(out, _out + skip, out_len); | |
439 | bin_clear_free(tmp_out, skip); | |
440 | ||
441 | return ret; | |
6fc6879b JM |
442 | } |
443 | ||
444 | ||
73581707 DB |
445 | int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, |
446 | const char *label, u8 *out, size_t out_len) | |
447 | { | |
448 | return tls_connection_prf(tls_ctx, conn, label, 0, 0, out, out_len); | |
449 | } | |
450 | ||
451 | ||
452 | int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, | |
453 | u8 *out, size_t out_len) | |
454 | { | |
455 | return tls_connection_prf(tls_ctx, conn, "key expansion", 1, 1, out, | |
456 | out_len); | |
457 | } | |
458 | ||
459 | ||
81c85c06 JM |
460 | struct wpabuf * tls_connection_handshake(void *tls_ctx, |
461 | struct tls_connection *conn, | |
462 | const struct wpabuf *in_data, | |
463 | struct wpabuf **appl_data) | |
dbdcfa39 JM |
464 | { |
465 | return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data, | |
466 | NULL); | |
467 | } | |
468 | ||
469 | ||
470 | struct wpabuf * tls_connection_handshake2(void *tls_ctx, | |
471 | struct tls_connection *conn, | |
472 | const struct wpabuf *in_data, | |
473 | struct wpabuf **appl_data, | |
474 | int *need_more_data) | |
6fc6879b JM |
475 | { |
476 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
81c85c06 JM |
477 | u8 *res, *ad; |
478 | size_t res_len, ad_len; | |
479 | struct wpabuf *out; | |
480 | ||
6fc6879b JM |
481 | if (conn->client == NULL) |
482 | return NULL; | |
483 | ||
81c85c06 JM |
484 | ad = NULL; |
485 | res = tlsv1_client_handshake(conn->client, | |
486 | in_data ? wpabuf_head(in_data) : NULL, | |
487 | in_data ? wpabuf_len(in_data) : 0, | |
dbdcfa39 | 488 | &res_len, &ad, &ad_len, need_more_data); |
81c85c06 JM |
489 | if (res == NULL) |
490 | return NULL; | |
491 | out = wpabuf_alloc_ext_data(res, res_len); | |
492 | if (out == NULL) { | |
493 | os_free(res); | |
494 | os_free(ad); | |
495 | return NULL; | |
496 | } | |
497 | if (appl_data) { | |
498 | if (ad) { | |
499 | *appl_data = wpabuf_alloc_ext_data(ad, ad_len); | |
500 | if (*appl_data == NULL) | |
501 | os_free(ad); | |
502 | } else | |
503 | *appl_data = NULL; | |
504 | } else | |
505 | os_free(ad); | |
6fc6879b | 506 | |
81c85c06 | 507 | return out; |
6fc6879b JM |
508 | #else /* CONFIG_TLS_INTERNAL_CLIENT */ |
509 | return NULL; | |
510 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
511 | } | |
512 | ||
513 | ||
81c85c06 JM |
514 | struct wpabuf * tls_connection_server_handshake(void *tls_ctx, |
515 | struct tls_connection *conn, | |
516 | const struct wpabuf *in_data, | |
517 | struct wpabuf **appl_data) | |
6fc6879b JM |
518 | { |
519 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
81c85c06 JM |
520 | u8 *res; |
521 | size_t res_len; | |
522 | struct wpabuf *out; | |
523 | ||
6fc6879b JM |
524 | if (conn->server == NULL) |
525 | return NULL; | |
526 | ||
81c85c06 JM |
527 | if (appl_data) |
528 | *appl_data = NULL; | |
529 | ||
530 | res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data), | |
531 | wpabuf_len(in_data), &res_len); | |
532 | if (res == NULL && tlsv1_server_established(conn->server)) | |
533 | return wpabuf_alloc(0); | |
534 | if (res == NULL) | |
535 | return NULL; | |
536 | out = wpabuf_alloc_ext_data(res, res_len); | |
537 | if (out == NULL) { | |
538 | os_free(res); | |
539 | return NULL; | |
4d4233ea | 540 | } |
81c85c06 | 541 | |
6fc6879b JM |
542 | return out; |
543 | #else /* CONFIG_TLS_INTERNAL_SERVER */ | |
544 | return NULL; | |
545 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
546 | } | |
547 | ||
548 | ||
81c85c06 JM |
549 | struct wpabuf * tls_connection_encrypt(void *tls_ctx, |
550 | struct tls_connection *conn, | |
551 | const struct wpabuf *in_data) | |
6fc6879b JM |
552 | { |
553 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
554 | if (conn->client) { | |
81c85c06 JM |
555 | struct wpabuf *buf; |
556 | int res; | |
557 | buf = wpabuf_alloc(wpabuf_len(in_data) + 300); | |
558 | if (buf == NULL) | |
559 | return NULL; | |
560 | res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data), | |
561 | wpabuf_len(in_data), | |
562 | wpabuf_mhead(buf), | |
563 | wpabuf_size(buf)); | |
564 | if (res < 0) { | |
565 | wpabuf_free(buf); | |
566 | return NULL; | |
567 | } | |
568 | wpabuf_put(buf, res); | |
569 | return buf; | |
6fc6879b JM |
570 | } |
571 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
572 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
573 | if (conn->server) { | |
81c85c06 JM |
574 | struct wpabuf *buf; |
575 | int res; | |
576 | buf = wpabuf_alloc(wpabuf_len(in_data) + 300); | |
577 | if (buf == NULL) | |
578 | return NULL; | |
579 | res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data), | |
580 | wpabuf_len(in_data), | |
581 | wpabuf_mhead(buf), | |
582 | wpabuf_size(buf)); | |
583 | if (res < 0) { | |
584 | wpabuf_free(buf); | |
585 | return NULL; | |
586 | } | |
587 | wpabuf_put(buf, res); | |
588 | return buf; | |
6fc6879b JM |
589 | } |
590 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
81c85c06 | 591 | return NULL; |
6fc6879b JM |
592 | } |
593 | ||
594 | ||
81c85c06 JM |
595 | struct wpabuf * tls_connection_decrypt(void *tls_ctx, |
596 | struct tls_connection *conn, | |
597 | const struct wpabuf *in_data) | |
6fc6879b | 598 | { |
dbdcfa39 JM |
599 | return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL); |
600 | } | |
601 | ||
602 | ||
603 | struct wpabuf * tls_connection_decrypt2(void *tls_ctx, | |
604 | struct tls_connection *conn, | |
605 | const struct wpabuf *in_data, | |
606 | int *need_more_data) | |
607 | { | |
608 | if (need_more_data) | |
609 | *need_more_data = 0; | |
610 | ||
6fc6879b JM |
611 | #ifdef CONFIG_TLS_INTERNAL_CLIENT |
612 | if (conn->client) { | |
dbdcfa39 JM |
613 | return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data), |
614 | wpabuf_len(in_data), | |
615 | need_more_data); | |
6fc6879b JM |
616 | } |
617 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
618 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
619 | if (conn->server) { | |
81c85c06 JM |
620 | struct wpabuf *buf; |
621 | int res; | |
622 | buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); | |
623 | if (buf == NULL) | |
624 | return NULL; | |
625 | res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data), | |
626 | wpabuf_len(in_data), | |
627 | wpabuf_mhead(buf), | |
628 | wpabuf_size(buf)); | |
629 | if (res < 0) { | |
630 | wpabuf_free(buf); | |
631 | return NULL; | |
632 | } | |
633 | wpabuf_put(buf, res); | |
634 | return buf; | |
6fc6879b JM |
635 | } |
636 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
81c85c06 | 637 | return NULL; |
6fc6879b JM |
638 | } |
639 | ||
640 | ||
641 | int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn) | |
642 | { | |
643 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
644 | if (conn->client) | |
645 | return tlsv1_client_resumed(conn->client); | |
646 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
647 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
648 | if (conn->server) | |
649 | return tlsv1_server_resumed(conn->server); | |
650 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
651 | return -1; | |
652 | } | |
653 | ||
654 | ||
655 | int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, | |
656 | u8 *ciphers) | |
657 | { | |
658 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
659 | if (conn->client) | |
660 | return tlsv1_client_set_cipher_list(conn->client, ciphers); | |
661 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
662 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
663 | if (conn->server) | |
664 | return tlsv1_server_set_cipher_list(conn->server, ciphers); | |
665 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
666 | return -1; | |
667 | } | |
668 | ||
669 | ||
fe1bf329 JM |
670 | int tls_get_version(void *ssl_ctx, struct tls_connection *conn, |
671 | char *buf, size_t buflen) | |
672 | { | |
20804fe8 JM |
673 | if (conn == NULL) |
674 | return -1; | |
675 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
676 | if (conn->client) | |
677 | return tlsv1_client_get_version(conn->client, buf, buflen); | |
678 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
fe1bf329 JM |
679 | return -1; |
680 | } | |
681 | ||
682 | ||
6fc6879b JM |
683 | int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, |
684 | char *buf, size_t buflen) | |
685 | { | |
686 | if (conn == NULL) | |
687 | return -1; | |
688 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
689 | if (conn->client) | |
690 | return tlsv1_client_get_cipher(conn->client, buf, buflen); | |
691 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
692 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
693 | if (conn->server) | |
694 | return tlsv1_server_get_cipher(conn->server, buf, buflen); | |
695 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
696 | return -1; | |
697 | } | |
698 | ||
699 | ||
700 | int tls_connection_enable_workaround(void *tls_ctx, | |
701 | struct tls_connection *conn) | |
702 | { | |
703 | return -1; | |
704 | } | |
705 | ||
706 | ||
707 | int tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn, | |
708 | int ext_type, const u8 *data, | |
709 | size_t data_len) | |
710 | { | |
711 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
712 | if (conn->client) { | |
713 | return tlsv1_client_hello_ext(conn->client, ext_type, | |
714 | data, data_len); | |
715 | } | |
716 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
717 | return -1; | |
718 | } | |
719 | ||
720 | ||
721 | int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn) | |
722 | { | |
723 | return 0; | |
724 | } | |
725 | ||
726 | ||
727 | int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn) | |
728 | { | |
729 | return 0; | |
730 | } | |
731 | ||
732 | ||
733 | int tls_connection_get_write_alerts(void *tls_ctx, | |
734 | struct tls_connection *conn) | |
735 | { | |
736 | return 0; | |
737 | } | |
738 | ||
739 | ||
6fc6879b JM |
740 | int tls_connection_set_session_ticket_cb(void *tls_ctx, |
741 | struct tls_connection *conn, | |
742 | tls_session_ticket_cb cb, | |
743 | void *ctx) | |
744 | { | |
745 | #ifdef CONFIG_TLS_INTERNAL_CLIENT | |
746 | if (conn->client) { | |
747 | tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx); | |
748 | return 0; | |
749 | } | |
750 | #endif /* CONFIG_TLS_INTERNAL_CLIENT */ | |
751 | #ifdef CONFIG_TLS_INTERNAL_SERVER | |
752 | if (conn->server) { | |
753 | tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx); | |
754 | return 0; | |
755 | } | |
756 | #endif /* CONFIG_TLS_INTERNAL_SERVER */ | |
757 | return -1; | |
758 | } | |
a1651451 JM |
759 | |
760 | ||
761 | int tls_get_library_version(char *buf, size_t buf_len) | |
762 | { | |
763 | return os_snprintf(buf, buf_len, "internal"); | |
764 | } | |
b3b8085a JM |
765 | |
766 | ||
767 | void tls_connection_set_success_data(struct tls_connection *conn, | |
768 | struct wpabuf *data) | |
769 | { | |
770 | } | |
771 | ||
772 | ||
773 | void tls_connection_set_success_data_resumed(struct tls_connection *conn) | |
774 | { | |
775 | } | |
776 | ||
777 | ||
778 | const struct wpabuf * | |
779 | tls_connection_get_success_data(struct tls_connection *conn) | |
780 | { | |
781 | return NULL; | |
782 | } | |
783 | ||
784 | ||
785 | void tls_connection_remove_session(struct tls_connection *conn) | |
786 | { | |
787 | } |