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