blob: b59622e5e7ec7a7f2fd7403479386e7758d235f1 [file] [log] [blame]
Roshan Pius3a1667e2018-07-03 15:17:14 -07001/*
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"
13#include "crypto/sha1.h"
14#include "crypto/sha256.h"
15#include "tls.h"
16
17/* wolfSSL includes */
18#include <wolfssl/options.h>
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
Hai Shalom39ba6fc2019-01-22 12:40:38 -0800350char * tls_connection_peer_serial_num(void *tls_ctx,
351 struct tls_connection *conn)
352{
353 /* TODO */
354 return NULL;
355}
356
357
Roshan Pius3a1667e2018-07-03 15:17:14 -0700358int 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) {
469 if (wolfSSL_use_certificate_chain_buffer_format(
470 conn->ssl, client_cert_blob, blob_len,
471 SSL_FILETYPE_ASN1) < 0) {
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) {
481 if (wolfSSL_use_certificate_chain_file(conn->ssl,
482 client_cert) < 0) {
483 wpa_printf(MSG_INFO,
484 "SSL: use client cert PEM file failed");
485 if (wolfSSL_use_certificate_chain_file_format(
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
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);
888 if (gen->type != GEN_EMAIL &&
889 gen->type != GEN_DNS &&
890 gen->type != GEN_URI)
891 continue;
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
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 }
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
1087#ifdef HAVE_OCSP_WOLFSSL
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 }
1111#endif /* HAVE_OCSP_WOLFSSL */
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);
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
1357 if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
1358 SSL_FILETYPE_ASN1) !=
1359 SSL_SUCCESS &&
1360 wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
1361 SSL_SUCCESS) {
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
1490 if (tls_global_ca_cert(tls_ctx, params->ca_cert) < 0) {
1491 wpa_printf(MSG_INFO, "SSL: Failed to load ca cert file '%s'",
1492 params->ca_cert);
1493 return -1;
1494 }
1495
1496 if (tls_global_client_cert(tls_ctx, params->client_cert) < 0) {
1497 wpa_printf(MSG_INFO,
1498 "SSL: Failed to load client cert file '%s'",
1499 params->client_cert);
1500 return -1;
1501 }
1502
1503 if (tls_global_private_key(tls_ctx, params->private_key,
1504 params->private_key_passwd) < 0) {
1505 wpa_printf(MSG_INFO,
1506 "SSL: Failed to load private key file '%s'",
1507 params->private_key);
1508 return -1;
1509 }
1510
1511 if (tls_global_dh(tls_ctx, params->dh_file, params->dh_blob,
1512 params->dh_blob_len) < 0) {
1513 wpa_printf(MSG_INFO, "SSL: Failed to load DH file '%s'",
1514 params->dh_file);
1515 return -1;
1516 }
1517
1518 if (params->openssl_ciphers &&
1519 wolfSSL_CTX_set_cipher_list(tls_ctx,
1520 params->openssl_ciphers) != 1) {
1521 wpa_printf(MSG_INFO,
1522 "wolfSSL: Failed to set cipher string '%s'",
1523 params->openssl_ciphers);
1524 return -1;
1525 }
1526
Hai Shalom74f70d42019-02-11 14:42:39 -08001527 if (params->openssl_ecdh_curves) {
1528 wpa_printf(MSG_INFO,
1529 "wolfSSL: openssl_ecdh_curves not supported");
1530 return -1;
1531 }
1532
Roshan Pius3a1667e2018-07-03 15:17:14 -07001533#ifdef HAVE_SESSION_TICKET
1534 /* Session ticket is off by default - can't disable once on. */
1535 if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
1536 wolfSSL_CTX_UseSessionTicket(tls_ctx);
1537#endif /* HAVE_SESSION_TICKET */
1538
1539#ifdef HAVE_OCSP
1540 if (params->ocsp_stapling_response) {
1541 wolfSSL_CTX_SetOCSP_OverrideURL(tls_ctx,
1542 params->ocsp_stapling_response);
1543 wolfSSL_CTX_SetOCSP_Cb(tls_ctx, ocsp_status_cb,
1544 ocsp_resp_free_cb, NULL);
1545 }
1546#endif /* HAVE_OCSP */
1547
1548 return 0;
1549}
1550
1551
Hai Shalom74f70d42019-02-11 14:42:39 -08001552int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
Roshan Pius3a1667e2018-07-03 15:17:14 -07001553{
1554 wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);
1555
1556 if (check_crl) {
1557 /* Hack to Enable CRLs. */
1558 wolfSSL_CTX_LoadCRLBuffer(tls_ctx, NULL, 0, SSL_FILETYPE_PEM);
1559 }
1560
1561 return 0;
1562}
1563
1564
1565int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1566 int verify_peer, unsigned int flags,
1567 const u8 *session_ctx, size_t session_ctx_len)
1568{
1569 if (!conn)
1570 return -1;
1571
1572 wpa_printf(MSG_DEBUG, "SSL: set verify: %d", verify_peer);
1573
1574 if (verify_peer) {
1575 conn->ca_cert_verify = 1;
1576 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1577 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1578 tls_verify_cb);
1579 } else {
1580 conn->ca_cert_verify = 0;
1581 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1582 }
1583
1584 wolfSSL_set_accept_state(conn->ssl);
1585
1586 /* TODO: do we need to fake a session like OpenSSL does here? */
1587
1588 return 0;
1589}
1590
1591
1592static struct wpabuf * wolfssl_handshake(struct tls_connection *conn,
1593 const struct wpabuf *in_data,
1594 int server)
1595{
1596 int res;
1597
1598 wolfssl_reset_out_data(&conn->output);
1599
1600 /* Initiate TLS handshake or continue the existing handshake */
1601 if (server) {
1602 wolfSSL_set_accept_state(conn->ssl);
1603 res = wolfSSL_accept(conn->ssl);
1604 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_accept: %d", res);
1605 } else {
1606 wolfSSL_set_connect_state(conn->ssl);
1607 res = wolfSSL_connect(conn->ssl);
1608 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_connect: %d", res);
1609 }
1610
1611 if (res != 1) {
1612 int err = wolfSSL_get_error(conn->ssl, res);
1613
1614 if (err == SSL_ERROR_WANT_READ) {
1615 wpa_printf(MSG_DEBUG,
1616 "SSL: wolfSSL_connect - want more data");
1617 } else if (err == SSL_ERROR_WANT_WRITE) {
1618 wpa_printf(MSG_DEBUG,
1619 "SSL: wolfSSL_connect - want to write");
1620 } else {
1621 char msg[80];
1622
1623 wpa_printf(MSG_DEBUG,
1624 "SSL: wolfSSL_connect - failed %s",
1625 wolfSSL_ERR_error_string(err, msg));
1626 conn->failed++;
1627 }
1628 }
1629
1630 return conn->output.out_data;
1631}
1632
1633
1634static struct wpabuf * wolfssl_get_appl_data(struct tls_connection *conn,
1635 size_t max_len)
1636{
1637 int res;
1638 struct wpabuf *appl_data = wpabuf_alloc(max_len + 100);
1639
1640 if (!appl_data)
1641 return NULL;
1642
1643 res = wolfSSL_read(conn->ssl, wpabuf_mhead(appl_data),
1644 wpabuf_size(appl_data));
1645 if (res < 0) {
1646 int err = wolfSSL_get_error(conn->ssl, res);
1647
1648 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1649 wpa_printf(MSG_DEBUG,
1650 "SSL: No Application Data included");
1651 } else {
1652 char msg[80];
1653
1654 wpa_printf(MSG_DEBUG,
1655 "Failed to read possible Application Data %s",
1656 wolfSSL_ERR_error_string(err, msg));
1657 }
1658
1659 wpabuf_free(appl_data);
1660 return NULL;
1661 }
1662
1663 wpabuf_put(appl_data, res);
1664 wpa_hexdump_buf_key(MSG_MSGDUMP,
1665 "SSL: Application Data in Finished message",
1666 appl_data);
1667 return appl_data;
1668}
1669
1670
1671static struct wpabuf *
1672wolfssl_connection_handshake(struct tls_connection *conn,
1673 const struct wpabuf *in_data,
1674 struct wpabuf **appl_data, int server)
1675{
1676 struct wpabuf *out_data;
1677
1678 wolfssl_reset_in_data(&conn->input, in_data);
1679
1680 if (appl_data)
1681 *appl_data = NULL;
1682
1683 out_data = wolfssl_handshake(conn, in_data, server);
1684 if (!out_data)
1685 return NULL;
1686
1687 if (wolfSSL_is_init_finished(conn->ssl)) {
1688 wpa_printf(MSG_DEBUG,
1689 "wolfSSL: Handshake finished - resumed=%d",
1690 tls_connection_resumed(NULL, conn));
1691 if (appl_data && in_data)
1692 *appl_data = wolfssl_get_appl_data(conn,
1693 wpabuf_len(in_data));
1694 }
1695
1696 return out_data;
1697}
1698
1699
1700struct wpabuf * tls_connection_handshake(void *tls_ctx,
1701 struct tls_connection *conn,
1702 const struct wpabuf *in_data,
1703 struct wpabuf **appl_data)
1704{
1705 return wolfssl_connection_handshake(conn, in_data, appl_data, 0);
1706}
1707
1708
1709struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1710 struct tls_connection *conn,
1711 const struct wpabuf *in_data,
1712 struct wpabuf **appl_data)
1713{
1714 return wolfssl_connection_handshake(conn, in_data, appl_data, 1);
1715}
1716
1717
1718struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1719 struct tls_connection *conn,
1720 const struct wpabuf *in_data)
1721{
1722 int res;
1723
1724 if (!conn)
1725 return NULL;
1726
1727 wpa_printf(MSG_DEBUG, "SSL: encrypt: %ld bytes", wpabuf_len(in_data));
1728
1729 wolfssl_reset_out_data(&conn->output);
1730
1731 res = wolfSSL_write(conn->ssl, wpabuf_head(in_data),
1732 wpabuf_len(in_data));
1733 if (res < 0) {
1734 int err = wolfSSL_get_error(conn->ssl, res);
1735 char msg[80];
1736
1737 wpa_printf(MSG_INFO, "Encryption failed - SSL_write: %s",
1738 wolfSSL_ERR_error_string(err, msg));
1739 return NULL;
1740 }
1741
1742 return conn->output.out_data;
1743}
1744
1745
1746struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1747 struct tls_connection *conn,
1748 const struct wpabuf *in_data)
1749{
1750 int res;
1751 struct wpabuf *buf;
1752
1753 if (!conn)
1754 return NULL;
1755
1756 wpa_printf(MSG_DEBUG, "SSL: decrypt");
1757
1758 wolfssl_reset_in_data(&conn->input, in_data);
1759
1760 /* Read decrypted data for further processing */
1761 /*
1762 * Even though we try to disable TLS compression, it is possible that
1763 * this cannot be done with all TLS libraries. Add extra buffer space
1764 * to handle the possibility of the decrypted data being longer than
1765 * input data.
1766 */
1767 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1768 if (!buf)
1769 return NULL;
1770 res = wolfSSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
1771 if (res < 0) {
1772 wpa_printf(MSG_INFO, "Decryption failed - SSL_read");
1773 wpabuf_free(buf);
1774 return NULL;
1775 }
1776 wpabuf_put(buf, res);
1777
1778 wpa_printf(MSG_DEBUG, "SSL: decrypt: %ld bytes", wpabuf_len(buf));
1779
1780 return buf;
1781}
1782
1783
1784int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
1785{
1786 return conn ? wolfSSL_session_reused(conn->ssl) : 0;
1787}
1788
1789
1790int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1791 u8 *ciphers)
1792{
1793 char buf[128], *pos, *end;
1794 u8 *c;
1795 int ret;
1796
1797 if (!conn || !conn->ssl || !ciphers)
1798 return -1;
1799
1800 buf[0] = '\0';
1801 pos = buf;
1802 end = pos + sizeof(buf);
1803
1804 c = ciphers;
1805 while (*c != TLS_CIPHER_NONE) {
1806 const char *suite;
1807
1808 switch (*c) {
1809 case TLS_CIPHER_RC4_SHA:
1810 suite = "RC4-SHA";
1811 break;
1812 case TLS_CIPHER_AES128_SHA:
1813 suite = "AES128-SHA";
1814 break;
1815 case TLS_CIPHER_RSA_DHE_AES128_SHA:
1816 suite = "DHE-RSA-AES128-SHA";
1817 break;
1818 case TLS_CIPHER_ANON_DH_AES128_SHA:
1819 suite = "ADH-AES128-SHA";
1820 break;
1821 case TLS_CIPHER_RSA_DHE_AES256_SHA:
1822 suite = "DHE-RSA-AES256-SHA";
1823 break;
1824 case TLS_CIPHER_AES256_SHA:
1825 suite = "AES256-SHA";
1826 break;
1827 default:
1828 wpa_printf(MSG_DEBUG,
1829 "TLS: Unsupported cipher selection: %d", *c);
1830 return -1;
1831 }
1832 ret = os_snprintf(pos, end - pos, ":%s", suite);
1833 if (os_snprintf_error(end - pos, ret))
1834 break;
1835 pos += ret;
1836
1837 c++;
1838 }
1839
1840 wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s", buf + 1);
1841
1842 if (wolfSSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
1843 wpa_printf(MSG_DEBUG, "Cipher suite configuration failed");
1844 return -1;
1845 }
1846
1847 return 0;
1848}
1849
1850
1851int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
1852 char *buf, size_t buflen)
1853{
1854 WOLFSSL_CIPHER *cipher;
1855 const char *name;
1856
1857 if (!conn || !conn->ssl)
1858 return -1;
1859
1860 cipher = wolfSSL_get_current_cipher(conn->ssl);
1861 if (!cipher)
1862 return -1;
1863
1864 name = wolfSSL_CIPHER_get_name(cipher);
1865 if (!name)
1866 return -1;
1867
1868 if (os_strcmp(name, "SSL_RSA_WITH_RC4_128_SHA") == 0)
1869 os_strlcpy(buf, "RC4-SHA", buflen);
1870 else if (os_strcmp(name, "TLS_RSA_WITH_AES_128_CBC_SHA") == 0)
1871 os_strlcpy(buf, "AES128-SHA", buflen);
1872 else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") == 0)
1873 os_strlcpy(buf, "DHE-RSA-AES128-SHA", buflen);
1874 else if (os_strcmp(name, "TLS_DH_anon_WITH_AES_128_CBC_SHA") == 0)
1875 os_strlcpy(buf, "ADH-AES128-SHA", buflen);
1876 else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA") == 0)
1877 os_strlcpy(buf, "DHE-RSA-AES256-SHA", buflen);
1878 else if (os_strcmp(name, "TLS_RSA_WITH_AES_256_CBC_SHA") == 0)
1879 os_strlcpy(buf, "AES256-SHA", buflen);
1880 else
1881 os_strlcpy(buf, name, buflen);
1882
1883 return 0;
1884}
1885
1886
1887int tls_connection_enable_workaround(void *tls_ctx,
1888 struct tls_connection *conn)
1889{
1890 /* no empty fragments in wolfSSL for now */
1891 return 0;
1892}
1893
1894
1895int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
1896{
1897 if (!conn)
1898 return -1;
1899
1900 return conn->failed;
1901}
1902
1903
1904int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
1905{
1906 if (!conn)
1907 return -1;
1908
1909 /* TODO: this is not incremented anywhere */
1910 return conn->read_alerts;
1911}
1912
1913
1914int tls_connection_get_write_alerts(void *tls_ctx,
1915 struct tls_connection *conn)
1916{
1917 if (!conn)
1918 return -1;
1919
1920 /* TODO: this is not incremented anywhere */
1921 return conn->write_alerts;
1922}
1923
1924
1925
1926int tls_get_library_version(char *buf, size_t buf_len)
1927{
1928 return os_snprintf(buf, buf_len, "wolfSSL build=%s run=%s",
1929 WOLFSSL_VERSION, wolfSSL_lib_version());
1930}
1931
1932int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
1933 char *buf, size_t buflen)
1934{
1935 const char *name;
1936
1937 if (!conn || !conn->ssl)
1938 return -1;
1939
1940 name = wolfSSL_get_version(conn->ssl);
1941 if (!name)
1942 return -1;
1943
1944 os_strlcpy(buf, name, buflen);
1945 return 0;
1946}
1947
1948
1949int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
1950 struct tls_random *keys)
1951{
1952 WOLFSSL *ssl;
1953
1954 if (!conn || !keys)
1955 return -1;
1956 ssl = conn->ssl;
1957 if (!ssl)
1958 return -1;
1959
1960 os_memset(keys, 0, sizeof(*keys));
1961 keys->client_random = conn->client_random;
1962 keys->client_random_len = wolfSSL_get_client_random(
1963 ssl, conn->client_random, sizeof(conn->client_random));
1964 keys->server_random = conn->server_random;
1965 keys->server_random_len = wolfSSL_get_server_random(
1966 ssl, conn->server_random, sizeof(conn->server_random));
1967
1968 return 0;
1969}
1970
1971
1972int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
1973 const char *label, u8 *out, size_t out_len)
1974{
1975 if (!conn || wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
1976 return -1;
1977 return 0;
1978}
1979
1980
1981#define SEED_LEN (RAN_LEN + RAN_LEN)
1982
1983int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
1984 u8 *out, size_t out_len)
1985{
1986 byte seed[SEED_LEN];
1987 int ret = -1;
1988 WOLFSSL *ssl;
1989 byte *tmp_out;
1990 byte *_out;
1991 int skip = 0;
1992 byte *master_key;
1993 unsigned int master_key_len;
1994 byte *server_random;
1995 unsigned int server_len;
1996 byte *client_random;
1997 unsigned int client_len;
1998
1999 if (!conn || !conn->ssl)
2000 return -1;
2001 ssl = conn->ssl;
2002
2003 skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
2004 wolfSSL_GetIVSize(ssl));
2005
2006 tmp_out = os_malloc(skip + out_len);
2007 if (!tmp_out)
2008 return -1;
2009 _out = tmp_out;
2010
2011 wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
2012 &server_len, &client_random, &client_len);
2013 os_memcpy(seed, server_random, RAN_LEN);
2014 os_memcpy(seed + RAN_LEN, client_random, RAN_LEN);
2015
2016 if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
2017 tls_prf_sha256(master_key, master_key_len,
2018 "key expansion", seed, sizeof(seed),
2019 _out, skip + out_len);
2020 ret = 0;
2021 } else {
2022 ret = tls_prf_sha1_md5(master_key, master_key_len,
2023 "key expansion", seed, sizeof(seed),
2024 _out, skip + out_len);
2025 }
2026
2027 os_memset(master_key, 0, master_key_len);
2028 if (ret == 0)
2029 os_memcpy(out, _out + skip, out_len);
2030 bin_clear_free(tmp_out, skip + out_len);
2031
2032 return ret;
2033}
2034
2035
2036#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2037
2038int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2039 int ext_type, const u8 *data,
2040 size_t data_len)
2041{
2042 (void) ssl_ctx;
2043
2044 if (!conn || !conn->ssl || ext_type != 35)
2045 return -1;
2046
2047 if (wolfSSL_set_SessionTicket(conn->ssl, data,
2048 (unsigned int) data_len) != 1)
2049 return -1;
2050
2051 return 0;
2052}
2053
2054
2055static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
2056{
2057 struct tls_connection *conn = arg;
2058 int ret;
2059 unsigned char client_random[RAN_LEN];
2060 unsigned char server_random[RAN_LEN];
2061 word32 ticket_len = sizeof(conn->session_ticket);
2062
2063 if (!conn || !conn->session_ticket_cb)
2064 return 1;
2065
2066 if (wolfSSL_get_client_random(s, client_random,
2067 sizeof(client_random)) == 0 ||
2068 wolfSSL_get_server_random(s, server_random,
2069 sizeof(server_random)) == 0 ||
2070 wolfSSL_get_SessionTicket(s, conn->session_ticket,
2071 &ticket_len) != 1)
2072 return 1;
2073
2074 if (ticket_len == 0)
2075 return 0;
2076
2077 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
2078 conn->session_ticket, ticket_len,
2079 client_random, server_random, secret);
2080 if (ret <= 0)
2081 return 1;
2082
2083 *secret_len = SECRET_LEN;
2084 return 0;
2085}
2086
2087#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2088
2089
2090int tls_connection_set_session_ticket_cb(void *tls_ctx,
2091 struct tls_connection *conn,
2092 tls_session_ticket_cb cb,
2093 void *ctx)
2094{
2095#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2096 conn->session_ticket_cb = cb;
2097 conn->session_ticket_cb_ctx = ctx;
2098
2099 if (cb) {
2100 if (wolfSSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
2101 conn) != 1)
2102 return -1;
2103 } else {
2104 if (wolfSSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
2105 return -1;
2106 }
2107
2108 return 0;
2109#else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2110 return -1;
2111#endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2112}
2113
2114
2115void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2116{
2117 wpa_printf(MSG_DEBUG,
2118 "wolfSSL: Success data accepted for resumed session");
2119}
2120
2121
2122void tls_connection_remove_session(struct tls_connection *conn)
2123{
2124 WOLFSSL_SESSION *sess;
2125
2126 sess = wolfSSL_get_session(conn->ssl);
2127 if (!sess)
2128 return;
2129
2130 wolfSSL_SSL_SESSION_set_timeout(sess, 0);
2131 wpa_printf(MSG_DEBUG,
2132 "wolfSSL: Removed cached session to disable session resumption");
2133}
2134
2135
2136void tls_connection_set_success_data(struct tls_connection *conn,
2137 struct wpabuf *data)
2138{
2139 WOLFSSL_SESSION *sess;
2140 struct wpabuf *old;
2141
2142 wpa_printf(MSG_DEBUG, "wolfSSL: Set success data");
2143
2144 sess = wolfSSL_get_session(conn->ssl);
2145 if (!sess) {
2146 wpa_printf(MSG_DEBUG,
2147 "wolfSSL: No session found for success data");
2148 goto fail;
2149 }
2150
2151 old = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2152 if (old) {
2153 wpa_printf(MSG_DEBUG, "wolfSSL: Replacing old success data %p",
2154 old);
2155 wpabuf_free(old);
2156 }
2157 if (wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
2158 goto fail;
2159
2160 wpa_printf(MSG_DEBUG, "wolfSSL: Stored success data %p", data);
2161 conn->success_data = 1;
2162 return;
2163
2164fail:
2165 wpa_printf(MSG_INFO, "wolfSSL: Failed to store success data");
2166 wpabuf_free(data);
2167}
2168
2169
2170const struct wpabuf *
2171tls_connection_get_success_data(struct tls_connection *conn)
2172{
2173 WOLFSSL_SESSION *sess;
2174
2175 wpa_printf(MSG_DEBUG, "wolfSSL: Get success data");
2176
2177 sess = wolfSSL_get_session(conn->ssl);
2178 if (!sess)
2179 return NULL;
2180 return wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2181}