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