]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/crypto/tls_wolfssl.c
tests: Python coding style cleanup (pylint3 bad-whitespace)
[thirdparty/hostap.git] / src / crypto / tls_wolfssl.c
CommitLineData
fec03f98
SP
1/*
2 * SSL/TLS interface functions for wolfSSL TLS case
3 * Copyright (c) 2004-2017, 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.h"
ab35793e
SP
13#include "crypto/sha1.h"
14#include "crypto/sha256.h"
fec03f98
SP
15#include "tls.h"
16
fec03f98 17/* wolfSSL includes */
7be46208 18#include <wolfssl/options.h>
fec03f98
SP
19#include <wolfssl/ssl.h>
20#include <wolfssl/error-ssl.h>
21#include <wolfssl/wolfcrypt/asn.h>
22
23#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
24#define HAVE_AESGCM
25#include <wolfssl/wolfcrypt/aes.h>
26#endif
27
28#if !defined(CONFIG_FIPS) && \
29 (defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || \
30 defined(EAP_SERVER_FAST))
31#define WOLFSSL_NEED_EAP_FAST_PRF
32#endif
33
34#define SECRET_LEN 48
35#define RAN_LEN 32
36#define SESSION_TICKET_LEN 256
37
38static int tls_ref_count = 0;
39
40static int tls_ex_idx_session = 0;
41
42
43/* tls input data for wolfSSL Read Callback */
44struct tls_in_data {
45 const struct wpabuf *in_data;
46 size_t consumed; /* how many bytes have we used already */
47};
48
49/* tls output data for wolfSSL Write Callback */
50struct tls_out_data {
51 struct wpabuf *out_data;
52};
53
54struct tls_context {
55 void (*event_cb)(void *ctx, enum tls_event ev,
56 union tls_event_data *data);
57 void *cb_ctx;
58 int cert_in_cb;
59 char *ocsp_stapling_response;
60};
61
62static struct tls_context *tls_global = NULL;
63
64/* wolfssl tls_connection */
65struct tls_connection {
66 struct tls_context *context;
67 WOLFSSL *ssl;
68 int read_alerts;
69 int write_alerts;
70 int failed;
71 struct tls_in_data input;
72 struct tls_out_data output;
73 char *subject_match;
74 char *alt_subject_match;
75 char *suffix_match;
76 char *domain_match;
77
78 u8 srv_cert_hash[32];
79
80 unsigned char client_random[RAN_LEN];
81 unsigned char server_random[RAN_LEN];
82 unsigned int flags;
83#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
84 tls_session_ticket_cb session_ticket_cb;
85 void *session_ticket_cb_ctx;
86 byte session_ticket[SESSION_TICKET_LEN];
87#endif
88 unsigned int ca_cert_verify:1;
89 unsigned int cert_probe:1;
90 unsigned int server_cert_only:1;
91 unsigned int success_data:1;
92
93 WOLFSSL_X509 *peer_cert;
94 WOLFSSL_X509 *peer_issuer;
95 WOLFSSL_X509 *peer_issuer_issuer;
96};
97
98
99static struct tls_context * tls_context_new(const struct tls_config *conf)
100{
101 struct tls_context *context = os_zalloc(sizeof(*context));
102
103 if (!context)
104 return NULL;
105
106 if (conf) {
107 context->event_cb = conf->event_cb;
108 context->cb_ctx = conf->cb_ctx;
109 context->cert_in_cb = conf->cert_in_cb;
110 }
111
112 return context;
113}
114
115
116static void wolfssl_reset_in_data(struct tls_in_data *in,
117 const struct wpabuf *buf)
118{
119 /* old one not owned by us so don't free */
120 in->in_data = buf;
121 in->consumed = 0;
122}
123
124
125static void wolfssl_reset_out_data(struct tls_out_data *out)
126{
127 /* old one not owned by us so don't free */
128 out->out_data = wpabuf_alloc_copy("", 0);
129}
130
131
132/* wolfSSL I/O Receive CallBack */
133static int wolfssl_receive_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
134{
135 size_t get = sz;
136 struct tls_in_data *data = ctx;
137
138 if (!data)
139 return -1;
140
141 if (get > (wpabuf_len(data->in_data) - data->consumed))
142 get = wpabuf_len(data->in_data) - data->consumed;
143
144 os_memcpy(buf, wpabuf_head(data->in_data) + data->consumed, get);
145 data->consumed += get;
146
147 if (get == 0)
148 return -2; /* WANT_READ */
149
150 return (int) get;
151}
152
153
154/* wolfSSL I/O Send CallBack */
155static int wolfssl_send_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
156{
157 struct wpabuf *tmp;
158 struct tls_out_data *data = ctx;
159
160 if (!data)
161 return -1;
162
163 wpa_printf(MSG_DEBUG, "SSL: adding %d bytes", sz);
164
165 tmp = wpabuf_alloc_copy(buf, sz);
166 if (!tmp)
167 return -1;
168 data->out_data = wpabuf_concat(data->out_data, tmp);
169 if (!data->out_data)
170 return -1;
171
172 return sz;
173}
174
175
176static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
177{
178 struct wpabuf *buf;
179
180 buf = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
181 if (!buf)
182 return;
183 wpa_printf(MSG_DEBUG,
184 "wolfSSL: Free application session data %p (sess %p)",
185 buf, sess);
186 wpabuf_free(buf);
187
188 wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
189}
190
191
192void * tls_init(const struct tls_config *conf)
193{
194 WOLFSSL_CTX *ssl_ctx;
195 struct tls_context *context;
196 const char *ciphers;
197
198#ifdef DEBUG_WOLFSSL
199 wolfSSL_Debugging_ON();
200#endif /* DEBUG_WOLFSSL */
201
202 context = tls_context_new(conf);
203 if (!context)
204 return NULL;
205
206 if (tls_ref_count == 0) {
207 tls_global = context;
208
209 if (wolfSSL_Init() < 0)
210 return NULL;
211 /* wolfSSL_Debugging_ON(); */
212 }
213
214 tls_ref_count++;
215
216 /* start as client */
217 ssl_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
218 if (!ssl_ctx) {
219 tls_ref_count--;
220 if (context != tls_global)
221 os_free(context);
222 if (tls_ref_count == 0) {
223 os_free(tls_global);
224 tls_global = NULL;
225 }
226 }
227 wolfSSL_SetIORecv(ssl_ctx, wolfssl_receive_cb);
228 wolfSSL_SetIOSend(ssl_ctx, wolfssl_send_cb);
229 wolfSSL_CTX_set_ex_data(ssl_ctx, 0, context);
230
231 if (conf->tls_session_lifetime > 0) {
232 wolfSSL_CTX_set_quiet_shutdown(ssl_ctx, 1);
233 wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
234 SSL_SESS_CACHE_SERVER);
235 wolfSSL_CTX_set_timeout(ssl_ctx, conf->tls_session_lifetime);
236 wolfSSL_CTX_sess_set_remove_cb(ssl_ctx, remove_session_cb);
237 } else {
238 wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
239 SSL_SESS_CACHE_CLIENT);
240 }
241
242 if (conf && conf->openssl_ciphers)
243 ciphers = conf->openssl_ciphers;
244 else
245 ciphers = "ALL";
246 if (wolfSSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
247 wpa_printf(MSG_ERROR,
248 "wolfSSL: Failed to set cipher string '%s'",
249 ciphers);
250 tls_deinit(ssl_ctx);
251 return NULL;
252 }
253
254 return ssl_ctx;
255}
256
257
258void tls_deinit(void *ssl_ctx)
259{
260 struct tls_context *context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
261
262 if (context != tls_global)
263 os_free(context);
264
265 wolfSSL_CTX_free((WOLFSSL_CTX *) ssl_ctx);
266
267 tls_ref_count--;
268 if (tls_ref_count == 0) {
269 wolfSSL_Cleanup();
270 os_free(tls_global);
271 tls_global = NULL;
272 }
273}
274
275
276int tls_get_errors(void *tls_ctx)
277{
278#ifdef DEBUG_WOLFSSL
279#if 0
280 unsigned long err;
281
282 err = wolfSSL_ERR_peek_last_error_line(NULL, NULL);
283 if (err != 0) {
284 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
285 wolfSSL_ERR_error_string(err, NULL));
286 return 1;
287 }
288#endif
289#endif /* DEBUG_WOLFSSL */
290 return 0;
291}
292
293
294struct tls_connection * tls_connection_init(void *tls_ctx)
295{
296 WOLFSSL_CTX *ssl_ctx = tls_ctx;
297 struct tls_connection *conn;
298
299 wpa_printf(MSG_DEBUG, "SSL: connection init");
300
301 conn = os_zalloc(sizeof(*conn));
302 if (!conn)
303 return NULL;
304 conn->ssl = wolfSSL_new(ssl_ctx);
305 if (!conn->ssl) {
306 os_free(conn);
307 return NULL;
308 }
309
310 wolfSSL_SetIOReadCtx(conn->ssl, &conn->input);
311 wolfSSL_SetIOWriteCtx(conn->ssl, &conn->output);
312 wolfSSL_set_ex_data(conn->ssl, 0, conn);
313 conn->context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
314
315 /* Need randoms post-hanshake for EAP-FAST, export key and deriving
316 * session ID in EAP methods. */
317 wolfSSL_KeepArrays(conn->ssl);
318 wolfSSL_KeepHandshakeResources(conn->ssl);
319 wolfSSL_UseClientSuites(conn->ssl);
320
321 return conn;
322}
323
324
325void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
326{
327 if (!conn)
328 return;
329
330 wpa_printf(MSG_DEBUG, "SSL: connection deinit");
331
332 /* parts */
333 wolfSSL_free(conn->ssl);
334 os_free(conn->subject_match);
335 os_free(conn->alt_subject_match);
336 os_free(conn->suffix_match);
337 os_free(conn->domain_match);
338
339 /* self */
340 os_free(conn);
341}
342
343
344int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
345{
346 return conn ? wolfSSL_is_init_finished(conn->ssl) : 0;
347}
348
349
0ec3e77a
JM
350char * tls_connection_peer_serial_num(void *tls_ctx,
351 struct tls_connection *conn)
352{
353 /* TODO */
354 return NULL;
355}
356
357
fec03f98
SP
358int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
359{
360 WOLFSSL_SESSION *session;
361
362 if (!conn)
363 return -1;
364
365 wpa_printf(MSG_DEBUG, "SSL: connection shutdown");
366
367 /* Set quiet as OpenSSL does */
368 wolfSSL_set_quiet_shutdown(conn->ssl, 1);
369 wolfSSL_shutdown(conn->ssl);
370
371 session = wolfSSL_get_session(conn->ssl);
372 if (wolfSSL_clear(conn->ssl) != 1)
373 return -1;
374 wolfSSL_set_session(conn->ssl, session);
375
376 return 0;
377}
378
379
380static int tls_connection_set_subject_match(struct tls_connection *conn,
381 const char *subject_match,
382 const char *alt_subject_match,
383 const char *suffix_match,
384 const char *domain_match)
385{
386 os_free(conn->subject_match);
387 conn->subject_match = NULL;
388 if (subject_match) {
389 conn->subject_match = os_strdup(subject_match);
390 if (!conn->subject_match)
391 return -1;
392 }
393
394 os_free(conn->alt_subject_match);
395 conn->alt_subject_match = NULL;
396 if (alt_subject_match) {
397 conn->alt_subject_match = os_strdup(alt_subject_match);
398 if (!conn->alt_subject_match)
399 return -1;
400 }
401
402 os_free(conn->suffix_match);
403 conn->suffix_match = NULL;
404 if (suffix_match) {
405 conn->suffix_match = os_strdup(suffix_match);
406 if (!conn->suffix_match)
407 return -1;
408 }
409
410 os_free(conn->domain_match);
411 conn->domain_match = NULL;
412 if (domain_match) {
413 conn->domain_match = os_strdup(domain_match);
414 if (!conn->domain_match)
415 return -1;
416 }
417
418 return 0;
419}
420
421
422static int tls_connection_dh(struct tls_connection *conn, const char *dh_file,
423 const u8 *dh_blob, size_t blob_len)
424{
425 if (!dh_file && !dh_blob)
426 return 0;
427
428 wolfSSL_set_accept_state(conn->ssl);
429
430 if (dh_blob) {
431 if (wolfSSL_SetTmpDH_buffer(conn->ssl, dh_blob, blob_len,
432 SSL_FILETYPE_ASN1) < 0) {
433 wpa_printf(MSG_INFO, "SSL: use DH DER blob failed");
434 return -1;
435 }
436 wpa_printf(MSG_DEBUG, "SSL: use DH blob OK");
437 return 0;
438 }
439
440 if (dh_file) {
441 wpa_printf(MSG_INFO, "SSL: use DH PEM file: %s", dh_file);
442 if (wolfSSL_SetTmpDH_file(conn->ssl, dh_file,
443 SSL_FILETYPE_PEM) < 0) {
444 wpa_printf(MSG_INFO, "SSL: use DH PEM file failed");
445 if (wolfSSL_SetTmpDH_file(conn->ssl, dh_file,
446 SSL_FILETYPE_ASN1) < 0) {
447 wpa_printf(MSG_INFO,
448 "SSL: use DH DER file failed");
449 return -1;
450 }
451 }
452 wpa_printf(MSG_DEBUG, "SSL: use DH file OK");
453 return 0;
454 }
455
456 return 0;
457}
458
459
460static int tls_connection_client_cert(struct tls_connection *conn,
461 const char *client_cert,
462 const u8 *client_cert_blob,
463 size_t blob_len)
464{
465 if (!client_cert && !client_cert_blob)
466 return 0;
467
468 if (client_cert_blob) {
6590d846
SP
469 if (wolfSSL_use_certificate_chain_buffer_format(
470 conn->ssl, client_cert_blob, blob_len,
471 SSL_FILETYPE_ASN1) < 0) {
fec03f98
SP
472 wpa_printf(MSG_INFO,
473 "SSL: use client cert DER blob failed");
474 return -1;
475 }
476 wpa_printf(MSG_DEBUG, "SSL: use client cert blob OK");
477 return 0;
478 }
479
480 if (client_cert) {
6590d846
SP
481 if (wolfSSL_use_certificate_chain_file(conn->ssl,
482 client_cert) < 0) {
fec03f98
SP
483 wpa_printf(MSG_INFO,
484 "SSL: use client cert PEM file failed");
6590d846 485 if (wolfSSL_use_certificate_chain_file_format(
fec03f98
SP
486 conn->ssl, client_cert,
487 SSL_FILETYPE_ASN1) < 0) {
488 wpa_printf(MSG_INFO,
489 "SSL: use client cert DER file failed");
490 return -1;
491 }
492 }
493 wpa_printf(MSG_DEBUG, "SSL: use client cert file OK");
494 return 0;
495 }
496
497 return 0;
498}
499
500
501static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
502{
503 if (!password)
504 return 0;
505 os_strlcpy(buf, (char *) password, size);
506 return os_strlen(buf);
507}
508
509
510static int tls_connection_private_key(void *tls_ctx,
511 struct tls_connection *conn,
512 const char *private_key,
513 const char *private_key_passwd,
514 const u8 *private_key_blob,
515 size_t blob_len)
516{
517 WOLFSSL_CTX *ctx = tls_ctx;
518 char *passwd = NULL;
519 int ok = 0;
520
521 if (!private_key && !private_key_blob)
522 return 0;
523
524 if (private_key_passwd) {
525 passwd = os_strdup(private_key_passwd);
526 if (!passwd)
527 return -1;
528 }
529
530 wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
531 wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
532
533 if (private_key_blob) {
534 if (wolfSSL_use_PrivateKey_buffer(conn->ssl,
535 private_key_blob, blob_len,
536 SSL_FILETYPE_ASN1) < 0) {
537 wpa_printf(MSG_INFO,
538 "SSL: use private DER blob failed");
539 } else {
540 wpa_printf(MSG_DEBUG, "SSL: use private key blob OK");
541 ok = 1;
542 }
543 }
544
545 if (!ok && private_key) {
546 if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
547 SSL_FILETYPE_PEM) < 0) {
548 wpa_printf(MSG_INFO,
549 "SSL: use private key PEM file failed");
550 if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
551 SSL_FILETYPE_ASN1) < 0)
552 {
553 wpa_printf(MSG_INFO,
554 "SSL: use private key DER file failed");
555 } else {
556 ok = 1;
557 }
558 } else {
559 ok = 1;
560 }
561
562 if (ok)
563 wpa_printf(MSG_DEBUG, "SSL: use private key file OK");
564 }
565
566 wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
567 os_free(passwd);
568
569 if (!ok)
570 return -1;
571
572 return 0;
573}
574
575
fec03f98
SP
576static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
577 const char *value, size_t len)
578{
579 WOLFSSL_ASN1_OBJECT *gen;
580 void *ext;
581 int found = 0;
582 int i;
583
584 ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
585
586 for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
587 gen = wolfSSL_sk_value(ext, i);
588 if (gen->type != type)
589 continue;
590 if (os_strlen((char *) gen->obj) == len &&
591 os_memcmp(value, gen->obj, len) == 0)
592 found++;
593 }
594
595 wolfSSL_sk_ASN1_OBJECT_free(ext);
596
597 return found;
598}
599
600
601static int tls_match_alt_subject(WOLFSSL_X509 *cert, const char *match)
602{
603 int type;
604 const char *pos, *end;
605 size_t len;
606
607 pos = match;
608 do {
609 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
610 type = GEN_EMAIL;
611 pos += 6;
612 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
613 type = GEN_DNS;
614 pos += 4;
615 } else if (os_strncmp(pos, "URI:", 4) == 0) {
616 type = GEN_URI;
617 pos += 4;
618 } else {
619 wpa_printf(MSG_INFO,
620 "TLS: Invalid altSubjectName match '%s'",
621 pos);
622 return 0;
623 }
624 end = os_strchr(pos, ';');
625 while (end) {
626 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
627 os_strncmp(end + 1, "DNS:", 4) == 0 ||
628 os_strncmp(end + 1, "URI:", 4) == 0)
629 break;
630 end = os_strchr(end + 1, ';');
631 }
632 if (end)
633 len = end - pos;
634 else
635 len = os_strlen(pos);
636 if (tls_match_alt_subject_component(cert, type, pos, len) > 0)
637 return 1;
638 pos = end + 1;
639 } while (end);
640
641 return 0;
642}
643
644
645static int domain_suffix_match(const char *val, size_t len, const char *match,
646 int full)
647{
648 size_t i, match_len;
649
650 /* Check for embedded nuls that could mess up suffix matching */
651 for (i = 0; i < len; i++) {
652 if (val[i] == '\0') {
653 wpa_printf(MSG_DEBUG,
654 "TLS: Embedded null in a string - reject");
655 return 0;
656 }
657 }
658
659 match_len = os_strlen(match);
660 if (match_len > len || (full && match_len != len))
661 return 0;
662
663 if (os_strncasecmp(val + len - match_len, match, match_len) != 0)
664 return 0; /* no match */
665
666 if (match_len == len)
667 return 1; /* exact match */
668
669 if (val[len - match_len - 1] == '.')
670 return 1; /* full label match completes suffix match */
671
672 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
673 return 0;
674}
675
676
677static int tls_match_suffix(WOLFSSL_X509 *cert, const char *match, int full)
678{
679 WOLFSSL_ASN1_OBJECT *gen;
680 void *ext;
681 int i;
682 int j;
683 int dns_name = 0;
684 WOLFSSL_X509_NAME *name;
685
686 wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
687 full ? "" : "suffix ", match);
688
689 ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
690
691 for (j = 0; ext && j < wolfSSL_sk_num(ext); j++) {
692 gen = wolfSSL_sk_value(ext, j);
693 if (gen->type != ALT_NAMES_OID)
694 continue;
695 dns_name++;
696 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
697 gen->obj, os_strlen((char *)gen->obj));
698 if (domain_suffix_match((const char *) gen->obj,
699 os_strlen((char *) gen->obj), match,
700 full) == 1) {
701 wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
702 full ? "Match" : "Suffix match");
703 wolfSSL_sk_ASN1_OBJECT_free(ext);
704 return 1;
705 }
706 }
707 wolfSSL_sk_ASN1_OBJECT_free(ext);
708
709 if (dns_name) {
710 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
711 return 0;
712 }
713
714 name = wolfSSL_X509_get_subject_name(cert);
715 i = -1;
716 for (;;) {
717 WOLFSSL_X509_NAME_ENTRY *e;
718 WOLFSSL_ASN1_STRING *cn;
719
720 i = wolfSSL_X509_NAME_get_index_by_NID(name, ASN_COMMON_NAME,
721 i);
722 if (i == -1)
723 break;
724 e = wolfSSL_X509_NAME_get_entry(name, i);
725 if (!e)
726 continue;
727 cn = wolfSSL_X509_NAME_ENTRY_get_data(e);
728 if (!cn)
729 continue;
730 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
731 cn->data, cn->length);
732 if (domain_suffix_match(cn->data, cn->length, match, full) == 1)
733 {
734 wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
735 full ? "Match" : "Suffix match");
736 return 1;
737 }
738 }
739
740 wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
741 full ? "" : "suffix ");
742 return 0;
743}
744
745
746static enum tls_fail_reason wolfssl_tls_fail_reason(int err)
747{
748 switch (err) {
749 case X509_V_ERR_CERT_REVOKED:
750 return TLS_FAIL_REVOKED;
751 case ASN_BEFORE_DATE_E:
752 case X509_V_ERR_CERT_NOT_YET_VALID:
753 case X509_V_ERR_CRL_NOT_YET_VALID:
754 return TLS_FAIL_NOT_YET_VALID;
755 case ASN_AFTER_DATE_E:
756 case X509_V_ERR_CERT_HAS_EXPIRED:
757 case X509_V_ERR_CRL_HAS_EXPIRED:
758 return TLS_FAIL_EXPIRED;
759 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
760 case X509_V_ERR_UNABLE_TO_GET_CRL:
761 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
762 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
763 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
764 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
765 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
766 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
767 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
768 case X509_V_ERR_INVALID_CA:
769 return TLS_FAIL_UNTRUSTED;
770 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
771 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
772 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
773 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
774 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
775 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
776 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
777 case X509_V_ERR_CERT_UNTRUSTED:
778 case X509_V_ERR_CERT_REJECTED:
779 return TLS_FAIL_BAD_CERTIFICATE;
780 default:
781 return TLS_FAIL_UNSPECIFIED;
782 }
783}
784
785
786static const char * wolfssl_tls_err_string(int err, const char *err_str)
787{
788 switch (err) {
789 case ASN_BEFORE_DATE_E:
790 return "certificate is not yet valid";
791 case ASN_AFTER_DATE_E:
792 return "certificate has expired";
793 default:
794 return err_str;
795 }
796}
797
798
799static struct wpabuf * get_x509_cert(WOLFSSL_X509 *cert)
800{
801 struct wpabuf *buf = NULL;
802 const u8 *data;
803 int cert_len;
804
805 data = wolfSSL_X509_get_der(cert, &cert_len);
806 if (!data)
807 buf = wpabuf_alloc_copy(data, cert_len);
808
809 return buf;
810}
811
812
813static void wolfssl_tls_fail_event(struct tls_connection *conn,
814 WOLFSSL_X509 *err_cert, int err, int depth,
815 const char *subject, const char *err_str,
816 enum tls_fail_reason reason)
817{
818 union tls_event_data ev;
819 struct wpabuf *cert = NULL;
820 struct tls_context *context = conn->context;
821
822 if (!context->event_cb)
823 return;
824
825 cert = get_x509_cert(err_cert);
826 os_memset(&ev, 0, sizeof(ev));
827 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
828 reason : wolfssl_tls_fail_reason(err);
829 ev.cert_fail.depth = depth;
830 ev.cert_fail.subject = subject;
831 ev.cert_fail.reason_txt = wolfssl_tls_err_string(err, err_str);
832 ev.cert_fail.cert = cert;
833 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
834 wpabuf_free(cert);
835}
836
837
838static void wolfssl_tls_cert_event(struct tls_connection *conn,
839 WOLFSSL_X509 *err_cert, int depth,
840 const char *subject)
841{
842 struct wpabuf *cert = NULL;
843 union tls_event_data ev;
844 struct tls_context *context = conn->context;
845 char *alt_subject[TLS_MAX_ALT_SUBJECT];
846 int alt, num_alt_subject = 0;
847 WOLFSSL_ASN1_OBJECT *gen;
848 void *ext;
849 int i;
850#ifdef CONFIG_SHA256
851 u8 hash[32];
852#endif /* CONFIG_SHA256 */
853
854 if (!context->event_cb)
855 return;
856
857 os_memset(&ev, 0, sizeof(ev));
858 if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
859 context->cert_in_cb) {
860 cert = get_x509_cert(err_cert);
861 ev.peer_cert.cert = cert;
862 }
863
864#ifdef CONFIG_SHA256
865 if (cert) {
866 const u8 *addr[1];
867 size_t len[1];
868
869 addr[0] = wpabuf_head(cert);
870 len[0] = wpabuf_len(cert);
871 if (sha256_vector(1, addr, len, hash) == 0) {
872 ev.peer_cert.hash = hash;
873 ev.peer_cert.hash_len = sizeof(hash);
874 }
875 }
876#endif /* CONFIG_SHA256 */
877
878 ev.peer_cert.depth = depth;
879 ev.peer_cert.subject = subject;
880
881 ext = wolfSSL_X509_get_ext_d2i(err_cert, ALT_NAMES_OID, NULL, NULL);
882 for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
883 char *pos;
884
885 if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
886 break;
887 gen = wolfSSL_sk_value((void *) ext, i);
fec03f98
SP
888 if (gen->type != GEN_EMAIL &&
889 gen->type != GEN_DNS &&
890 gen->type != GEN_URI)
891 continue;
fec03f98
SP
892
893 pos = os_malloc(10 + os_strlen((char *) gen->obj) + 1);
894 if (!pos)
895 break;
896 alt_subject[num_alt_subject++] = pos;
897
fec03f98
SP
898 switch (gen->type) {
899 case GEN_EMAIL:
900 os_memcpy(pos, "EMAIL:", 6);
901 pos += 6;
902 break;
903 case GEN_DNS:
904 os_memcpy(pos, "DNS:", 4);
905 pos += 4;
906 break;
907 case GEN_URI:
908 os_memcpy(pos, "URI:", 4);
909 pos += 4;
910 break;
911 }
fec03f98
SP
912
913 os_memcpy(pos, gen->obj, os_strlen((char *)gen->obj));
914 pos += os_strlen((char *)gen->obj);
915 *pos = '\0';
916 }
917 wolfSSL_sk_ASN1_OBJECT_free(ext);
918
919 for (alt = 0; alt < num_alt_subject; alt++)
920 ev.peer_cert.altsubject[alt] = alt_subject[alt];
921 ev.peer_cert.num_altsubject = num_alt_subject;
922
923 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
924 wpabuf_free(cert);
925 for (alt = 0; alt < num_alt_subject; alt++)
926 os_free(alt_subject[alt]);
927}
928
929
930static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
931{
932 char buf[256];
933 WOLFSSL_X509 *err_cert;
934 int err, depth;
935 WOLFSSL *ssl;
936 struct tls_connection *conn;
937 struct tls_context *context;
938 char *match, *altmatch, *suffix_match, *domain_match;
939 const char *err_str;
940
941 err_cert = wolfSSL_X509_STORE_CTX_get_current_cert(x509_ctx);
942 if (!err_cert) {
943 wpa_printf(MSG_DEBUG, "wolfSSL: No Cert");
944 return 0;
945 }
946
947 err = wolfSSL_X509_STORE_CTX_get_error(x509_ctx);
948 depth = wolfSSL_X509_STORE_CTX_get_error_depth(x509_ctx);
949 ssl = wolfSSL_X509_STORE_CTX_get_ex_data(
950 x509_ctx, wolfSSL_get_ex_data_X509_STORE_CTX_idx());
951 wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(err_cert), buf,
952 sizeof(buf));
953
954 conn = wolfSSL_get_ex_data(ssl, 0);
955 if (!conn) {
956 wpa_printf(MSG_DEBUG, "wolfSSL: No ex_data");
957 return 0;
958 }
959
960 if (depth == 0)
961 conn->peer_cert = err_cert;
962 else if (depth == 1)
963 conn->peer_issuer = err_cert;
964 else if (depth == 2)
965 conn->peer_issuer_issuer = err_cert;
966
967 context = conn->context;
968 match = conn->subject_match;
969 altmatch = conn->alt_subject_match;
970 suffix_match = conn->suffix_match;
971 domain_match = conn->domain_match;
972
973 if (!preverify_ok && !conn->ca_cert_verify)
974 preverify_ok = 1;
975 if (!preverify_ok && depth > 0 && conn->server_cert_only)
976 preverify_ok = 1;
977 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
978 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
979 err == ASN_AFTER_DATE_E || err == ASN_BEFORE_DATE_E ||
980 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
981 wpa_printf(MSG_DEBUG,
982 "wolfSSL: Ignore certificate validity time mismatch");
983 preverify_ok = 1;
984 }
985
986 err_str = wolfSSL_X509_verify_cert_error_string(err);
987
988#ifdef CONFIG_SHA256
989 /*
990 * Do not require preverify_ok so we can explicity allow otherwise
991 * invalid pinned server certificates.
992 */
993 if (depth == 0 && conn->server_cert_only) {
994 struct wpabuf *cert;
995
996 cert = get_x509_cert(err_cert);
997 if (!cert) {
998 wpa_printf(MSG_DEBUG,
999 "wolfSSL: Could not fetch server certificate data");
1000 preverify_ok = 0;
1001 } else {
1002 u8 hash[32];
1003 const u8 *addr[1];
1004 size_t len[1];
1005
1006 addr[0] = wpabuf_head(cert);
1007 len[0] = wpabuf_len(cert);
1008 if (sha256_vector(1, addr, len, hash) < 0 ||
1009 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1010 err_str = "Server certificate mismatch";
1011 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1012 preverify_ok = 0;
1013 } else if (!preverify_ok) {
1014 /*
1015 * Certificate matches pinned certificate, allow
1016 * regardless of other problems.
1017 */
1018 wpa_printf(MSG_DEBUG,
1019 "wolfSSL: Ignore validation issues for a pinned server certificate");
1020 preverify_ok = 1;
1021 }
1022 wpabuf_free(cert);
1023 }
1024 }
1025#endif /* CONFIG_SHA256 */
1026
1027 if (!preverify_ok) {
1028 wpa_printf(MSG_WARNING,
1029 "TLS: Certificate verification failed, error %d (%s) depth %d for '%s'",
1030 err, err_str, depth, buf);
1031 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1032 err_str, TLS_FAIL_UNSPECIFIED);
1033 return preverify_ok;
1034 }
1035
1036 wpa_printf(MSG_DEBUG,
1037 "TLS: %s - preverify_ok=%d err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1038 __func__, preverify_ok, err, err_str,
1039 conn->ca_cert_verify, depth, buf);
1040 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1041 wpa_printf(MSG_WARNING,
1042 "TLS: Subject '%s' did not match with '%s'",
1043 buf, match);
1044 preverify_ok = 0;
1045 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1046 "Subject mismatch",
1047 TLS_FAIL_SUBJECT_MISMATCH);
1048 } else if (depth == 0 && altmatch &&
1049 !tls_match_alt_subject(err_cert, altmatch)) {
1050 wpa_printf(MSG_WARNING,
1051 "TLS: altSubjectName match '%s' not found",
1052 altmatch);
1053 preverify_ok = 0;
1054 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1055 "AltSubject mismatch",
1056 TLS_FAIL_ALTSUBJECT_MISMATCH);
1057 } else if (depth == 0 && suffix_match &&
1058 !tls_match_suffix(err_cert, suffix_match, 0)) {
1059 wpa_printf(MSG_WARNING,
1060 "TLS: Domain suffix match '%s' not found",
1061 suffix_match);
1062 preverify_ok = 0;
1063 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1064 "Domain suffix mismatch",
1065 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1066 } else if (depth == 0 && domain_match &&
1067 !tls_match_suffix(err_cert, domain_match, 1)) {
1068 wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
1069 domain_match);
1070 preverify_ok = 0;
1071 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1072 "Domain mismatch",
1073 TLS_FAIL_DOMAIN_MISMATCH);
1074 } else {
1075 wolfssl_tls_cert_event(conn, err_cert, depth, buf);
1076 }
1077
1078 if (conn->cert_probe && preverify_ok && depth == 0) {
1079 wpa_printf(MSG_DEBUG,
1080 "wolfSSL: Reject server certificate on probe-only run");
1081 preverify_ok = 0;
1082 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1083 "Server certificate chain probe",
1084 TLS_FAIL_SERVER_CHAIN_PROBE);
1085 }
1086
b7f5b0ec 1087#ifdef HAVE_OCSP_WOLFSSL
fec03f98
SP
1088 if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
1089 preverify_ok) {
1090 enum ocsp_result res;
1091
1092 res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
1093 conn->peer_issuer,
1094 conn->peer_issuer_issuer);
1095 if (res == OCSP_REVOKED) {
1096 preverify_ok = 0;
1097 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1098 "certificate revoked",
1099 TLS_FAIL_REVOKED);
1100 if (err == X509_V_OK)
1101 X509_STORE_CTX_set_error(
1102 x509_ctx, X509_V_ERR_CERT_REVOKED);
1103 } else if (res != OCSP_GOOD &&
1104 (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
1105 preverify_ok = 0;
1106 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1107 "bad certificate status response",
1108 TLS_FAIL_UNSPECIFIED);
1109 }
1110 }
b7f5b0ec 1111#endif /* HAVE_OCSP_WOLFSSL */
fec03f98
SP
1112 if (depth == 0 && preverify_ok && context->event_cb != NULL)
1113 context->event_cb(context->cb_ctx,
1114 TLS_CERT_CHAIN_SUCCESS, NULL);
1115
1116 return preverify_ok;
1117}
1118
1119
1120static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
1121 const char *ca_cert,
1122 const u8 *ca_cert_blob, size_t blob_len,
1123 const char *ca_path)
1124{
1125 WOLFSSL_CTX *ctx = tls_ctx;
1126
1127 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1128 conn->ca_cert_verify = 1;
1129
1130 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1131 wpa_printf(MSG_DEBUG,
1132 "wolfSSL: Probe for server certificate chain");
1133 conn->cert_probe = 1;
1134 conn->ca_cert_verify = 0;
1135 return 0;
1136 }
1137
1138 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1139#ifdef CONFIG_SHA256
1140 const char *pos = ca_cert + 7;
1141
1142 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1143 wpa_printf(MSG_DEBUG,
1144 "wolfSSL: Unsupported ca_cert hash value '%s'",
1145 ca_cert);
1146 return -1;
1147 }
1148 pos += 14;
1149 if (os_strlen(pos) != 32 * 2) {
1150 wpa_printf(MSG_DEBUG,
1151 "wolfSSL: Unexpected SHA256 hash length in ca_cert '%s'",
1152 ca_cert);
1153 return -1;
1154 }
1155 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1156 wpa_printf(MSG_DEBUG,
1157 "wolfSSL: Invalid SHA256 hash value in ca_cert '%s'",
1158 ca_cert);
1159 return -1;
1160 }
1161 conn->server_cert_only = 1;
1162 wpa_printf(MSG_DEBUG,
1163 "wolfSSL: Checking only server certificate match");
1164 return 0;
1165#else /* CONFIG_SHA256 */
1166 wpa_printf(MSG_INFO,
1167 "No SHA256 included in the build - cannot validate server certificate hash");
1168 return -1;
1169#endif /* CONFIG_SHA256 */
1170 }
1171
1172 if (ca_cert_blob) {
1173 if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_blob, blob_len,
1174 SSL_FILETYPE_ASN1) !=
1175 SSL_SUCCESS) {
1176 wpa_printf(MSG_INFO, "SSL: failed to load CA blob");
1177 return -1;
1178 }
1179 wpa_printf(MSG_DEBUG, "SSL: use CA cert blob OK");
1180 return 0;
1181 }
1182
1183 if (ca_cert || ca_path) {
1184 WOLFSSL_X509_STORE *cm = wolfSSL_X509_STORE_new();
1185
1186 if (!cm) {
1187 wpa_printf(MSG_INFO,
1188 "SSL: failed to create certificate store");
1189 return -1;
1190 }
1191 wolfSSL_CTX_set_cert_store(ctx, cm);
fec03f98
SP
1192
1193 if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
1194 SSL_SUCCESS) {
1195 wpa_printf(MSG_INFO,
1196 "SSL: failed to load ca_cert as PEM");
1197
1198 if (!ca_cert)
1199 return -1;
1200
1201 if (wolfSSL_CTX_der_load_verify_locations(
1202 ctx, ca_cert, SSL_FILETYPE_ASN1) !=
1203 SSL_SUCCESS) {
1204 wpa_printf(MSG_INFO,
1205 "SSL: failed to load ca_cert as DER");
1206 return -1;
1207 }
1208 }
1209 return 0;
1210 }
1211
1212 conn->ca_cert_verify = 0;
1213 return 0;
1214}
1215
1216
1217static void tls_set_conn_flags(WOLFSSL *ssl, unsigned int flags)
1218{
1219#ifdef HAVE_SESSION_TICKET
1220#if 0
1221 if (!(flags & TLS_CONN_DISABLE_SESSION_TICKET))
1222 wolfSSL_UseSessionTicket(ssl);
1223#endif
1224#endif /* HAVE_SESSION_TICKET */
1225
1226 if (flags & TLS_CONN_DISABLE_TLSv1_0)
1227 wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1);
1228 if (flags & TLS_CONN_DISABLE_TLSv1_1)
1229 wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
1230 if (flags & TLS_CONN_DISABLE_TLSv1_2)
1231 wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
1232}
1233
1234
1235int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
1236 const struct tls_connection_params *params)
1237{
1238 wpa_printf(MSG_DEBUG, "SSL: set params");
1239
1240 if (tls_connection_set_subject_match(conn, params->subject_match,
1241 params->altsubject_match,
1242 params->suffix_match,
1243 params->domain_match) < 0) {
1244 wpa_printf(MSG_INFO, "Error setting subject match");
1245 return -1;
1246 }
1247
1248 if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
1249 params->ca_cert_blob,
1250 params->ca_cert_blob_len,
1251 params->ca_path) < 0) {
1252 wpa_printf(MSG_INFO, "Error setting CA cert");
1253 return -1;
1254 }
1255
1256 if (tls_connection_client_cert(conn, params->client_cert,
1257 params->client_cert_blob,
1258 params->client_cert_blob_len) < 0) {
1259 wpa_printf(MSG_INFO, "Error setting client cert");
1260 return -1;
1261 }
1262
1263 if (tls_connection_private_key(tls_ctx, conn, params->private_key,
1264 params->private_key_passwd,
1265 params->private_key_blob,
1266 params->private_key_blob_len) < 0) {
1267 wpa_printf(MSG_INFO, "Error setting private key");
1268 return -1;
1269 }
1270
1271 if (tls_connection_dh(conn, params->dh_file, params->dh_blob,
1272 params->dh_blob_len) < 0) {
1273 wpa_printf(MSG_INFO, "Error setting DH");
1274 return -1;
1275 }
1276
1277 if (params->openssl_ciphers &&
1278 wolfSSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) {
1279 wpa_printf(MSG_INFO,
1280 "wolfSSL: Failed to set cipher string '%s'",
1281 params->openssl_ciphers);
1282 return -1;
1283 }
1284
1285 tls_set_conn_flags(conn->ssl, params->flags);
1286
1287#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
1288 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1289 if (wolfSSL_UseOCSPStapling(conn->ssl, WOLFSSL_CSR_OCSP,
1290 WOLFSSL_CSR_OCSP_USE_NONCE) !=
1291 SSL_SUCCESS)
1292 return -1;
1293 wolfSSL_CTX_EnableOCSP(tls_ctx, 0);
1294 }
1295#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
1296#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
1297 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1298 if (wolfSSL_UseOCSPStaplingV2(conn->ssl,
1299 WOLFSSL_CSR2_OCSP_MULTI, 0) !=
1300 SSL_SUCCESS)
1301 return -1;
1302 wolfSSL_CTX_EnableOCSP(tls_ctx, 0);
1303 }
1304#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1305#if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
1306 !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
1307#ifdef HAVE_OCSP
1308 if (params->flags & TLS_CONN_REQUEST_OCSP)
1309 wolfSSL_CTX_EnableOCSP(ctx, 0);
1310#else /* HAVE_OCSP */
1311 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
1312 wpa_printf(MSG_INFO,
1313 "wolfSSL: No OCSP support included - reject configuration");
1314 return -1;
1315 }
1316 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1317 wpa_printf(MSG_DEBUG,
1318 "wolfSSL: No OCSP support included - allow optional OCSP case to continue");
1319 }
1320#endif /* HAVE_OCSP */
1321#endif /* !HAVE_CERTIFICATE_STATUS_REQUEST &&
1322 * !HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1323
1324 conn->flags = params->flags;
1325
1326 return 0;
1327}
1328
1329
1330static int tls_global_ca_cert(void *ssl_ctx, const char *ca_cert)
1331{
1332 WOLFSSL_CTX *ctx = ssl_ctx;
1333
1334 if (ca_cert) {
1335 if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1)
1336 {
1337 wpa_printf(MSG_WARNING,
1338 "Failed to load root certificates");
1339 return -1;
1340 }
1341
1342 wpa_printf(MSG_DEBUG,
1343 "TLS: Trusted root certificate(s) loaded");
1344 }
1345
1346 return 0;
1347}
1348
1349
1350static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
1351{
1352 WOLFSSL_CTX *ctx = ssl_ctx;
1353
1354 if (!client_cert)
1355 return 0;
1356
6590d846
SP
1357 if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
1358 SSL_FILETYPE_ASN1) !=
fec03f98 1359 SSL_SUCCESS &&
6590d846
SP
1360 wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
1361 SSL_SUCCESS) {
fec03f98
SP
1362 wpa_printf(MSG_INFO, "Failed to load client certificate");
1363 return -1;
1364 }
1365
1366 wpa_printf(MSG_DEBUG, "SSL: Loaded global client certificate: %s",
1367 client_cert);
1368
1369 return 0;
1370}
1371
1372
1373static int tls_global_private_key(void *ssl_ctx, const char *private_key,
1374 const char *private_key_passwd)
1375{
1376 WOLFSSL_CTX *ctx = ssl_ctx;
1377 char *passwd = NULL;
1378 int ret = 0;
1379
1380 if (!private_key)
1381 return 0;
1382
1383 if (private_key_passwd) {
1384 passwd = os_strdup(private_key_passwd);
1385 if (!passwd)
1386 return -1;
1387 }
1388
1389 wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
1390 wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
1391
1392 if (wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1393 SSL_FILETYPE_ASN1) != 1 &&
1394 wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1395 SSL_FILETYPE_PEM) != 1) {
1396 wpa_printf(MSG_INFO, "Failed to load private key");
1397 ret = -1;
1398 }
1399
1400 wpa_printf(MSG_DEBUG, "SSL: Loaded global private key");
1401
1402 os_free(passwd);
1403 wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
1404
1405 return ret;
1406}
1407
1408
1409static int tls_global_dh(void *ssl_ctx, const char *dh_file,
1410 const u8 *dh_blob, size_t blob_len)
1411{
1412 WOLFSSL_CTX *ctx = ssl_ctx;
1413
1414 if (!dh_file && !dh_blob)
1415 return 0;
1416
1417 if (dh_blob) {
1418 if (wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_blob, blob_len,
1419 SSL_FILETYPE_ASN1) < 0) {
1420 wpa_printf(MSG_INFO,
1421 "SSL: global use DH DER blob failed");
1422 return -1;
1423 }
1424 wpa_printf(MSG_DEBUG, "SSL: global use DH blob OK");
1425 return 0;
1426 }
1427
1428 if (dh_file) {
1429 if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file, SSL_FILETYPE_PEM) <
1430 0) {
1431 wpa_printf(MSG_INFO,
1432 "SSL: global use DH PEM file failed");
1433 if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file,
1434 SSL_FILETYPE_ASN1) < 0) {
1435 wpa_printf(MSG_INFO,
1436 "SSL: global use DH DER file failed");
1437 return -1;
1438 }
1439 }
1440 wpa_printf(MSG_DEBUG, "SSL: global use DH file OK");
1441 return 0;
1442 }
1443
1444 return 0;
1445}
1446
1447
1448#ifdef HAVE_OCSP
1449
1450int ocsp_status_cb(void *unused, const char *url, int url_sz,
1451 unsigned char *request, int request_sz,
1452 unsigned char **response)
1453{
1454 size_t len;
1455
1456 (void) unused;
1457
1458 if (!url) {
1459 wpa_printf(MSG_DEBUG,
1460 "wolfSSL: OCSP status callback - no response configured");
1461 *response = NULL;
1462 return 0;
1463 }
1464
1465 *response = (unsigned char *) os_readfile(url, &len);
1466 if (!*response) {
1467 wpa_printf(MSG_DEBUG,
1468 "wolfSSL: OCSP status callback - could not read response file");
1469 return -1;
1470 }
1471 wpa_printf(MSG_DEBUG,
1472 "wolfSSL: OCSP status callback - send cached response");
1473 return len;
1474}
1475
1476
1477void ocsp_resp_free_cb(void *ocsp_stapling_response, unsigned char *response)
1478{
1479 os_free(response);
1480}
1481
1482#endif /* HAVE_OCSP */
1483
1484
1485int tls_global_set_params(void *tls_ctx,
1486 const struct tls_connection_params *params)
1487{
1488 wpa_printf(MSG_DEBUG, "SSL: global set params");
1489
841205a1
JB
1490 if (params->check_cert_subject)
1491 return -1; /* not yet supported */
1492
fec03f98
SP
1493 if (tls_global_ca_cert(tls_ctx, params->ca_cert) < 0) {
1494 wpa_printf(MSG_INFO, "SSL: Failed to load ca cert file '%s'",
1495 params->ca_cert);
1496 return -1;
1497 }
1498
1499 if (tls_global_client_cert(tls_ctx, params->client_cert) < 0) {
1500 wpa_printf(MSG_INFO,
1501 "SSL: Failed to load client cert file '%s'",
1502 params->client_cert);
1503 return -1;
1504 }
1505
1506 if (tls_global_private_key(tls_ctx, params->private_key,
1507 params->private_key_passwd) < 0) {
1508 wpa_printf(MSG_INFO,
1509 "SSL: Failed to load private key file '%s'",
1510 params->private_key);
1511 return -1;
1512 }
1513
1514 if (tls_global_dh(tls_ctx, params->dh_file, params->dh_blob,
1515 params->dh_blob_len) < 0) {
1516 wpa_printf(MSG_INFO, "SSL: Failed to load DH file '%s'",
1517 params->dh_file);
1518 return -1;
1519 }
1520
1521 if (params->openssl_ciphers &&
1522 wolfSSL_CTX_set_cipher_list(tls_ctx,
1523 params->openssl_ciphers) != 1) {
1524 wpa_printf(MSG_INFO,
1525 "wolfSSL: Failed to set cipher string '%s'",
1526 params->openssl_ciphers);
1527 return -1;
1528 }
1529
0521c6eb
HV
1530 if (params->openssl_ecdh_curves) {
1531 wpa_printf(MSG_INFO,
1532 "wolfSSL: openssl_ecdh_curves not supported");
1533 return -1;
1534 }
1535
fec03f98
SP
1536#ifdef HAVE_SESSION_TICKET
1537 /* Session ticket is off by default - can't disable once on. */
1538 if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
1539 wolfSSL_CTX_UseSessionTicket(tls_ctx);
1540#endif /* HAVE_SESSION_TICKET */
1541
1542#ifdef HAVE_OCSP
1543 if (params->ocsp_stapling_response) {
1544 wolfSSL_CTX_SetOCSP_OverrideURL(tls_ctx,
1545 params->ocsp_stapling_response);
1546 wolfSSL_CTX_SetOCSP_Cb(tls_ctx, ocsp_status_cb,
1547 ocsp_resp_free_cb, NULL);
1548 }
1549#endif /* HAVE_OCSP */
1550
1551 return 0;
1552}
1553
1554
dd5d325b 1555int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
fec03f98
SP
1556{
1557 wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);
1558
1559 if (check_crl) {
1560 /* Hack to Enable CRLs. */
1561 wolfSSL_CTX_LoadCRLBuffer(tls_ctx, NULL, 0, SSL_FILETYPE_PEM);
1562 }
1563
1564 return 0;
1565}
1566
1567
1568int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1569 int verify_peer, unsigned int flags,
1570 const u8 *session_ctx, size_t session_ctx_len)
1571{
1572 if (!conn)
1573 return -1;
1574
1575 wpa_printf(MSG_DEBUG, "SSL: set verify: %d", verify_peer);
1576
1577 if (verify_peer) {
1578 conn->ca_cert_verify = 1;
1579 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1580 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1581 tls_verify_cb);
1582 } else {
1583 conn->ca_cert_verify = 0;
1584 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1585 }
1586
1587 wolfSSL_set_accept_state(conn->ssl);
1588
1589 /* TODO: do we need to fake a session like OpenSSL does here? */
1590
1591 return 0;
1592}
1593
1594
1595static struct wpabuf * wolfssl_handshake(struct tls_connection *conn,
1596 const struct wpabuf *in_data,
1597 int server)
1598{
1599 int res;
1600
1601 wolfssl_reset_out_data(&conn->output);
1602
1603 /* Initiate TLS handshake or continue the existing handshake */
1604 if (server) {
1605 wolfSSL_set_accept_state(conn->ssl);
1606 res = wolfSSL_accept(conn->ssl);
1607 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_accept: %d", res);
1608 } else {
1609 wolfSSL_set_connect_state(conn->ssl);
1610 res = wolfSSL_connect(conn->ssl);
1611 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_connect: %d", res);
1612 }
1613
1614 if (res != 1) {
1615 int err = wolfSSL_get_error(conn->ssl, res);
1616
1617 if (err == SSL_ERROR_WANT_READ) {
1618 wpa_printf(MSG_DEBUG,
1619 "SSL: wolfSSL_connect - want more data");
1620 } else if (err == SSL_ERROR_WANT_WRITE) {
1621 wpa_printf(MSG_DEBUG,
1622 "SSL: wolfSSL_connect - want to write");
1623 } else {
1624 char msg[80];
1625
1626 wpa_printf(MSG_DEBUG,
1627 "SSL: wolfSSL_connect - failed %s",
1628 wolfSSL_ERR_error_string(err, msg));
1629 conn->failed++;
1630 }
1631 }
1632
1633 return conn->output.out_data;
1634}
1635
1636
1637static struct wpabuf * wolfssl_get_appl_data(struct tls_connection *conn,
1638 size_t max_len)
1639{
1640 int res;
1641 struct wpabuf *appl_data = wpabuf_alloc(max_len + 100);
1642
1643 if (!appl_data)
1644 return NULL;
1645
1646 res = wolfSSL_read(conn->ssl, wpabuf_mhead(appl_data),
1647 wpabuf_size(appl_data));
1648 if (res < 0) {
1649 int err = wolfSSL_get_error(conn->ssl, res);
1650
1651 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1652 wpa_printf(MSG_DEBUG,
1653 "SSL: No Application Data included");
1654 } else {
1655 char msg[80];
1656
1657 wpa_printf(MSG_DEBUG,
1658 "Failed to read possible Application Data %s",
1659 wolfSSL_ERR_error_string(err, msg));
1660 }
1661
1662 wpabuf_free(appl_data);
1663 return NULL;
1664 }
1665
1666 wpabuf_put(appl_data, res);
1667 wpa_hexdump_buf_key(MSG_MSGDUMP,
1668 "SSL: Application Data in Finished message",
1669 appl_data);
1670 return appl_data;
1671}
1672
1673
1674static struct wpabuf *
1675wolfssl_connection_handshake(struct tls_connection *conn,
1676 const struct wpabuf *in_data,
1677 struct wpabuf **appl_data, int server)
1678{
1679 struct wpabuf *out_data;
1680
1681 wolfssl_reset_in_data(&conn->input, in_data);
1682
1683 if (appl_data)
1684 *appl_data = NULL;
1685
1686 out_data = wolfssl_handshake(conn, in_data, server);
1687 if (!out_data)
1688 return NULL;
1689
1690 if (wolfSSL_is_init_finished(conn->ssl)) {
1691 wpa_printf(MSG_DEBUG,
1692 "wolfSSL: Handshake finished - resumed=%d",
1693 tls_connection_resumed(NULL, conn));
1694 if (appl_data && in_data)
1695 *appl_data = wolfssl_get_appl_data(conn,
1696 wpabuf_len(in_data));
1697 }
1698
1699 return out_data;
1700}
1701
1702
1703struct wpabuf * tls_connection_handshake(void *tls_ctx,
1704 struct tls_connection *conn,
1705 const struct wpabuf *in_data,
1706 struct wpabuf **appl_data)
1707{
1708 return wolfssl_connection_handshake(conn, in_data, appl_data, 0);
1709}
1710
1711
1712struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1713 struct tls_connection *conn,
1714 const struct wpabuf *in_data,
1715 struct wpabuf **appl_data)
1716{
1717 return wolfssl_connection_handshake(conn, in_data, appl_data, 1);
1718}
1719
1720
1721struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1722 struct tls_connection *conn,
1723 const struct wpabuf *in_data)
1724{
1725 int res;
1726
1727 if (!conn)
1728 return NULL;
1729
1730 wpa_printf(MSG_DEBUG, "SSL: encrypt: %ld bytes", wpabuf_len(in_data));
1731
1732 wolfssl_reset_out_data(&conn->output);
1733
1734 res = wolfSSL_write(conn->ssl, wpabuf_head(in_data),
1735 wpabuf_len(in_data));
1736 if (res < 0) {
1737 int err = wolfSSL_get_error(conn->ssl, res);
1738 char msg[80];
1739
1740 wpa_printf(MSG_INFO, "Encryption failed - SSL_write: %s",
1741 wolfSSL_ERR_error_string(err, msg));
1742 return NULL;
1743 }
1744
1745 return conn->output.out_data;
1746}
1747
1748
1749struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1750 struct tls_connection *conn,
1751 const struct wpabuf *in_data)
1752{
1753 int res;
1754 struct wpabuf *buf;
1755
1756 if (!conn)
1757 return NULL;
1758
1759 wpa_printf(MSG_DEBUG, "SSL: decrypt");
1760
1761 wolfssl_reset_in_data(&conn->input, in_data);
1762
1763 /* Read decrypted data for further processing */
1764 /*
1765 * Even though we try to disable TLS compression, it is possible that
1766 * this cannot be done with all TLS libraries. Add extra buffer space
1767 * to handle the possibility of the decrypted data being longer than
1768 * input data.
1769 */
1770 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1771 if (!buf)
1772 return NULL;
1773 res = wolfSSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
1774 if (res < 0) {
1775 wpa_printf(MSG_INFO, "Decryption failed - SSL_read");
1776 wpabuf_free(buf);
1777 return NULL;
1778 }
1779 wpabuf_put(buf, res);
1780
1781 wpa_printf(MSG_DEBUG, "SSL: decrypt: %ld bytes", wpabuf_len(buf));
1782
1783 return buf;
1784}
1785
1786
1787int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
1788{
1789 return conn ? wolfSSL_session_reused(conn->ssl) : 0;
1790}
1791
1792
1793int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1794 u8 *ciphers)
1795{
1796 char buf[128], *pos, *end;
1797 u8 *c;
1798 int ret;
1799
1800 if (!conn || !conn->ssl || !ciphers)
1801 return -1;
1802
1803 buf[0] = '\0';
1804 pos = buf;
1805 end = pos + sizeof(buf);
1806
1807 c = ciphers;
1808 while (*c != TLS_CIPHER_NONE) {
1809 const char *suite;
1810
1811 switch (*c) {
1812 case TLS_CIPHER_RC4_SHA:
1813 suite = "RC4-SHA";
1814 break;
1815 case TLS_CIPHER_AES128_SHA:
1816 suite = "AES128-SHA";
1817 break;
1818 case TLS_CIPHER_RSA_DHE_AES128_SHA:
1819 suite = "DHE-RSA-AES128-SHA";
1820 break;
1821 case TLS_CIPHER_ANON_DH_AES128_SHA:
1822 suite = "ADH-AES128-SHA";
1823 break;
1824 case TLS_CIPHER_RSA_DHE_AES256_SHA:
1825 suite = "DHE-RSA-AES256-SHA";
1826 break;
1827 case TLS_CIPHER_AES256_SHA:
1828 suite = "AES256-SHA";
1829 break;
1830 default:
1831 wpa_printf(MSG_DEBUG,
1832 "TLS: Unsupported cipher selection: %d", *c);
1833 return -1;
1834 }
1835 ret = os_snprintf(pos, end - pos, ":%s", suite);
1836 if (os_snprintf_error(end - pos, ret))
1837 break;
1838 pos += ret;
1839
1840 c++;
1841 }
1842
1843 wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s", buf + 1);
1844
1845 if (wolfSSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
1846 wpa_printf(MSG_DEBUG, "Cipher suite configuration failed");
1847 return -1;
1848 }
1849
1850 return 0;
1851}
1852
1853
1854int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
1855 char *buf, size_t buflen)
1856{
1857 WOLFSSL_CIPHER *cipher;
1858 const char *name;
1859
1860 if (!conn || !conn->ssl)
1861 return -1;
1862
1863 cipher = wolfSSL_get_current_cipher(conn->ssl);
1864 if (!cipher)
1865 return -1;
1866
1867 name = wolfSSL_CIPHER_get_name(cipher);
1868 if (!name)
1869 return -1;
1870
1871 if (os_strcmp(name, "SSL_RSA_WITH_RC4_128_SHA") == 0)
1872 os_strlcpy(buf, "RC4-SHA", buflen);
1873 else if (os_strcmp(name, "TLS_RSA_WITH_AES_128_CBC_SHA") == 0)
1874 os_strlcpy(buf, "AES128-SHA", buflen);
1875 else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") == 0)
1876 os_strlcpy(buf, "DHE-RSA-AES128-SHA", buflen);
1877 else if (os_strcmp(name, "TLS_DH_anon_WITH_AES_128_CBC_SHA") == 0)
1878 os_strlcpy(buf, "ADH-AES128-SHA", buflen);
1879 else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA") == 0)
1880 os_strlcpy(buf, "DHE-RSA-AES256-SHA", buflen);
1881 else if (os_strcmp(name, "TLS_RSA_WITH_AES_256_CBC_SHA") == 0)
1882 os_strlcpy(buf, "AES256-SHA", buflen);
1883 else
1884 os_strlcpy(buf, name, buflen);
1885
1886 return 0;
1887}
1888
1889
1890int tls_connection_enable_workaround(void *tls_ctx,
1891 struct tls_connection *conn)
1892{
1893 /* no empty fragments in wolfSSL for now */
1894 return 0;
1895}
1896
1897
1898int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
1899{
1900 if (!conn)
1901 return -1;
1902
1903 return conn->failed;
1904}
1905
1906
1907int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
1908{
1909 if (!conn)
1910 return -1;
1911
1912 /* TODO: this is not incremented anywhere */
1913 return conn->read_alerts;
1914}
1915
1916
1917int tls_connection_get_write_alerts(void *tls_ctx,
1918 struct tls_connection *conn)
1919{
1920 if (!conn)
1921 return -1;
1922
1923 /* TODO: this is not incremented anywhere */
1924 return conn->write_alerts;
1925}
1926
1927
1928
1929int tls_get_library_version(char *buf, size_t buf_len)
1930{
1931 return os_snprintf(buf, buf_len, "wolfSSL build=%s run=%s",
1932 WOLFSSL_VERSION, wolfSSL_lib_version());
1933}
1934
1935int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
1936 char *buf, size_t buflen)
1937{
1938 const char *name;
1939
1940 if (!conn || !conn->ssl)
1941 return -1;
1942
1943 name = wolfSSL_get_version(conn->ssl);
1944 if (!name)
1945 return -1;
1946
1947 os_strlcpy(buf, name, buflen);
1948 return 0;
1949}
1950
1951
1952int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
1953 struct tls_random *keys)
1954{
1955 WOLFSSL *ssl;
1956
1957 if (!conn || !keys)
1958 return -1;
1959 ssl = conn->ssl;
1960 if (!ssl)
1961 return -1;
1962
1963 os_memset(keys, 0, sizeof(*keys));
1964 keys->client_random = conn->client_random;
1965 keys->client_random_len = wolfSSL_get_client_random(
1966 ssl, conn->client_random, sizeof(conn->client_random));
1967 keys->server_random = conn->server_random;
1968 keys->server_random_len = wolfSSL_get_server_random(
1969 ssl, conn->server_random, sizeof(conn->server_random));
1970
1971 return 0;
1972}
1973
1974
1975int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
1976 const char *label, u8 *out, size_t out_len)
1977{
1978 if (!conn || wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
1979 return -1;
1980 return 0;
1981}
1982
1983
ab35793e
SP
1984#define SEED_LEN (RAN_LEN + RAN_LEN)
1985
fec03f98
SP
1986int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
1987 u8 *out, size_t out_len)
1988{
ab35793e
SP
1989 byte seed[SEED_LEN];
1990 int ret = -1;
1991 WOLFSSL *ssl;
1992 byte *tmp_out;
1993 byte *_out;
1994 int skip = 0;
1995 byte *master_key;
1996 unsigned int master_key_len;
1997 byte *server_random;
1998 unsigned int server_len;
1999 byte *client_random;
2000 unsigned int client_len;
fec03f98
SP
2001
2002 if (!conn || !conn->ssl)
2003 return -1;
ab35793e
SP
2004 ssl = conn->ssl;
2005
2006 skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
2007 wolfSSL_GetIVSize(ssl));
fec03f98 2008
ab35793e
SP
2009 tmp_out = os_malloc(skip + out_len);
2010 if (!tmp_out)
fec03f98 2011 return -1;
ab35793e
SP
2012 _out = tmp_out;
2013
2014 wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
2015 &server_len, &client_random, &client_len);
2016 os_memcpy(seed, server_random, RAN_LEN);
2017 os_memcpy(seed + RAN_LEN, client_random, RAN_LEN);
2018
2019 if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
2020 tls_prf_sha256(master_key, master_key_len,
2021 "key expansion", seed, sizeof(seed),
2022 _out, skip + out_len);
2023 ret = 0;
2024 } else {
2025 ret = tls_prf_sha1_md5(master_key, master_key_len,
2026 "key expansion", seed, sizeof(seed),
2027 _out, skip + out_len);
2028 }
2029
2030 os_memset(master_key, 0, master_key_len);
2031 if (ret == 0)
2032 os_memcpy(out, _out + skip, out_len);
2033 bin_clear_free(tmp_out, skip + out_len);
2034
2035 return ret;
fec03f98
SP
2036}
2037
2038
2039#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2040
2041int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2042 int ext_type, const u8 *data,
2043 size_t data_len)
2044{
2045 (void) ssl_ctx;
2046
2047 if (!conn || !conn->ssl || ext_type != 35)
2048 return -1;
2049
2050 if (wolfSSL_set_SessionTicket(conn->ssl, data,
2051 (unsigned int) data_len) != 1)
2052 return -1;
2053
2054 return 0;
2055}
2056
2057
2058static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
2059{
2060 struct tls_connection *conn = arg;
2061 int ret;
2062 unsigned char client_random[RAN_LEN];
2063 unsigned char server_random[RAN_LEN];
2064 word32 ticket_len = sizeof(conn->session_ticket);
2065
2066 if (!conn || !conn->session_ticket_cb)
2067 return 1;
2068
2069 if (wolfSSL_get_client_random(s, client_random,
2070 sizeof(client_random)) == 0 ||
2071 wolfSSL_get_server_random(s, server_random,
2072 sizeof(server_random)) == 0 ||
847665eb
SP
2073 wolfSSL_get_SessionTicket(s, conn->session_ticket,
2074 &ticket_len) != 1)
fec03f98
SP
2075 return 1;
2076
2077 if (ticket_len == 0)
2078 return 0;
2079
2080 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
847665eb 2081 conn->session_ticket, ticket_len,
fec03f98
SP
2082 client_random, server_random, secret);
2083 if (ret <= 0)
2084 return 1;
2085
2086 *secret_len = SECRET_LEN;
2087 return 0;
2088}
2089
2090#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2091
2092
2093int tls_connection_set_session_ticket_cb(void *tls_ctx,
2094 struct tls_connection *conn,
2095 tls_session_ticket_cb cb,
2096 void *ctx)
2097{
2098#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2099 conn->session_ticket_cb = cb;
2100 conn->session_ticket_cb_ctx = ctx;
2101
2102 if (cb) {
2103 if (wolfSSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
2104 conn) != 1)
2105 return -1;
2106 } else {
2107 if (wolfSSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
2108 return -1;
2109 }
2110
2111 return 0;
2112#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2113 return -1;
2114#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2115}
2116
2117
2118void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2119{
2120 wpa_printf(MSG_DEBUG,
2121 "wolfSSL: Success data accepted for resumed session");
2122}
2123
2124
2125void tls_connection_remove_session(struct tls_connection *conn)
2126{
2127 WOLFSSL_SESSION *sess;
2128
2129 sess = wolfSSL_get_session(conn->ssl);
2130 if (!sess)
2131 return;
2132
2133 wolfSSL_SSL_SESSION_set_timeout(sess, 0);
2134 wpa_printf(MSG_DEBUG,
2135 "wolfSSL: Removed cached session to disable session resumption");
2136}
2137
2138
2139void tls_connection_set_success_data(struct tls_connection *conn,
2140 struct wpabuf *data)
2141{
2142 WOLFSSL_SESSION *sess;
2143 struct wpabuf *old;
2144
2145 wpa_printf(MSG_DEBUG, "wolfSSL: Set success data");
2146
2147 sess = wolfSSL_get_session(conn->ssl);
2148 if (!sess) {
2149 wpa_printf(MSG_DEBUG,
2150 "wolfSSL: No session found for success data");
2151 goto fail;
2152 }
2153
2154 old = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2155 if (old) {
2156 wpa_printf(MSG_DEBUG, "wolfSSL: Replacing old success data %p",
2157 old);
2158 wpabuf_free(old);
2159 }
2160 if (wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
2161 goto fail;
2162
2163 wpa_printf(MSG_DEBUG, "wolfSSL: Stored success data %p", data);
2164 conn->success_data = 1;
2165 return;
2166
2167fail:
2168 wpa_printf(MSG_INFO, "wolfSSL: Failed to store success data");
2169 wpabuf_free(data);
2170}
2171
2172
2173const struct wpabuf *
2174tls_connection_get_success_data(struct tls_connection *conn)
2175{
2176 WOLFSSL_SESSION *sess;
2177
2178 wpa_printf(MSG_DEBUG, "wolfSSL: Get success data");
2179
2180 sess = wolfSSL_get_session(conn->ssl);
2181 if (!sess)
2182 return NULL;
2183 return wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2184}