2 * SSL/TLS interface functions for wolfSSL TLS case
3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
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>
23 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
25 #include <wolfssl/wolfcrypt/aes.h>
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
36 #define SESSION_TICKET_LEN 256
38 static int tls_ref_count = 0;
40 static int tls_ex_idx_session = 0;
43 /* tls input data for wolfSSL Read Callback */
45 const struct wpabuf *in_data;
46 size_t consumed; /* how many bytes have we used already */
49 /* tls output data for wolfSSL Write Callback */
51 struct wpabuf *out_data;
55 void (*event_cb)(void *ctx, enum tls_event ev,
56 union tls_event_data *data);
59 char *ocsp_stapling_response;
62 static struct tls_context *tls_global = NULL;
64 /* wolfssl tls_connection */
65 struct tls_connection {
66 struct tls_context *context;
71 struct tls_in_data input;
72 struct tls_out_data output;
74 char *alt_subject_match;
80 unsigned char client_random[RAN_LEN];
81 unsigned char server_random[RAN_LEN];
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];
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;
93 WOLFSSL_X509 *peer_cert;
94 WOLFSSL_X509 *peer_issuer;
95 WOLFSSL_X509 *peer_issuer_issuer;
99 static struct tls_context * tls_context_new(const struct tls_config *conf)
101 struct tls_context *context = os_zalloc(sizeof(*context));
107 context->event_cb = conf->event_cb;
108 context->cb_ctx = conf->cb_ctx;
109 context->cert_in_cb = conf->cert_in_cb;
116 static void wolfssl_reset_in_data(struct tls_in_data *in,
117 const struct wpabuf *buf)
119 /* old one not owned by us so don't free */
125 static void wolfssl_reset_out_data(struct tls_out_data *out)
127 /* old one not owned by us so don't free */
128 out->out_data = wpabuf_alloc_copy("", 0);
132 /* wolfSSL I/O Receive CallBack */
133 static int wolfssl_receive_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
136 struct tls_in_data *data = ctx;
141 if (get > (wpabuf_len(data->in_data) - data->consumed))
142 get = wpabuf_len(data->in_data) - data->consumed;
144 os_memcpy(buf, wpabuf_head(data->in_data) + data->consumed, get);
145 data->consumed += get;
148 return -2; /* WANT_READ */
154 /* wolfSSL I/O Send CallBack */
155 static int wolfssl_send_cb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
158 struct tls_out_data *data = ctx;
163 wpa_printf(MSG_DEBUG, "SSL: adding %d bytes", sz);
165 tmp = wpabuf_alloc_copy(buf, sz);
168 data->out_data = wpabuf_concat(data->out_data, tmp);
176 static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
180 buf = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
183 wpa_printf(MSG_DEBUG,
184 "wolfSSL: Free application session data %p (sess %p)",
188 wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
192 void * tls_init(const struct tls_config *conf)
194 WOLFSSL_CTX *ssl_ctx;
195 struct tls_context *context;
199 wolfSSL_Debugging_ON();
200 #endif /* DEBUG_WOLFSSL */
202 context = tls_context_new(conf);
206 if (tls_ref_count == 0) {
207 tls_global = context;
209 if (wolfSSL_Init() < 0)
211 /* wolfSSL_Debugging_ON(); */
216 /* start as client */
217 ssl_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
220 if (context != tls_global)
222 if (tls_ref_count == 0) {
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);
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);
238 wolfSSL_CTX_set_session_cache_mode(ssl_ctx,
239 SSL_SESS_CACHE_CLIENT);
242 if (conf && conf->openssl_ciphers)
243 ciphers = conf->openssl_ciphers;
246 if (wolfSSL_CTX_set_cipher_list(ssl_ctx, ciphers) != 1) {
247 wpa_printf(MSG_ERROR,
248 "wolfSSL: Failed to set cipher string '%s'",
258 void tls_deinit(void *ssl_ctx)
260 struct tls_context *context = wolfSSL_CTX_get_ex_data(ssl_ctx, 0);
262 if (context != tls_global)
265 wolfSSL_CTX_free((WOLFSSL_CTX *) ssl_ctx);
268 if (tls_ref_count == 0) {
276 int tls_get_errors(void *tls_ctx)
282 err = wolfSSL_ERR_peek_last_error_line(NULL, NULL);
284 wpa_printf(MSG_INFO, "TLS - SSL error: %s",
285 wolfSSL_ERR_error_string(err, NULL));
289 #endif /* DEBUG_WOLFSSL */
294 struct tls_connection * tls_connection_init(void *tls_ctx)
296 WOLFSSL_CTX *ssl_ctx = tls_ctx;
297 struct tls_connection *conn;
299 wpa_printf(MSG_DEBUG, "SSL: connection init");
301 conn = os_zalloc(sizeof(*conn));
304 conn->ssl = wolfSSL_new(ssl_ctx);
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);
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);
325 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
330 wpa_printf(MSG_DEBUG, "SSL: connection deinit");
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);
344 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
346 return conn ? wolfSSL_is_init_finished(conn->ssl) : 0;
350 char * tls_connection_peer_serial_num(void *tls_ctx,
351 struct tls_connection *conn)
358 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
360 WOLFSSL_SESSION *session;
365 wpa_printf(MSG_DEBUG, "SSL: connection shutdown");
367 /* Set quiet as OpenSSL does */
368 wolfSSL_set_quiet_shutdown(conn->ssl, 1);
369 wolfSSL_shutdown(conn->ssl);
371 session = wolfSSL_get_session(conn->ssl);
372 if (wolfSSL_clear(conn->ssl) != 1)
374 wolfSSL_set_session(conn->ssl, session);
380 static int tls_connection_set_subject_match(struct tls_connection *conn,
381 const char *subject_match,
382 const char *alt_subject_match,
383 const char *suffix_match,
384 const char *domain_match)
386 os_free(conn->subject_match);
387 conn->subject_match = NULL;
389 conn->subject_match = os_strdup(subject_match);
390 if (!conn->subject_match)
394 os_free(conn->alt_subject_match);
395 conn->alt_subject_match = NULL;
396 if (alt_subject_match) {
397 conn->alt_subject_match = os_strdup(alt_subject_match);
398 if (!conn->alt_subject_match)
402 os_free(conn->suffix_match);
403 conn->suffix_match = NULL;
405 conn->suffix_match = os_strdup(suffix_match);
406 if (!conn->suffix_match)
410 os_free(conn->domain_match);
411 conn->domain_match = NULL;
413 conn->domain_match = os_strdup(domain_match);
414 if (!conn->domain_match)
422 static int tls_connection_dh(struct tls_connection *conn, const char *dh_file,
423 const u8 *dh_blob, size_t blob_len)
425 if (!dh_file && !dh_blob)
428 wolfSSL_set_accept_state(conn->ssl);
431 if (wolfSSL_SetTmpDH_buffer(conn->ssl, dh_blob, blob_len,
432 SSL_FILETYPE_ASN1) < 0) {
433 wpa_printf(MSG_INFO, "SSL: use DH DER blob failed");
436 wpa_printf(MSG_DEBUG, "SSL: use DH blob OK");
441 wpa_printf(MSG_INFO, "SSL: use DH PEM file: %s", dh_file);
442 if (wolfSSL_SetTmpDH_file(conn->ssl, dh_file,
443 SSL_FILETYPE_PEM) < 0) {
444 wpa_printf(MSG_INFO, "SSL: use DH PEM file failed");
445 if (wolfSSL_SetTmpDH_file(conn->ssl, dh_file,
446 SSL_FILETYPE_ASN1) < 0) {
448 "SSL: use DH DER file failed");
452 wpa_printf(MSG_DEBUG, "SSL: use DH file OK");
460 static int tls_connection_client_cert(struct tls_connection *conn,
461 const char *client_cert,
462 const u8 *client_cert_blob,
465 if (!client_cert && !client_cert_blob)
468 if (client_cert_blob) {
469 if (wolfSSL_use_certificate_chain_buffer_format(
470 conn->ssl, client_cert_blob, blob_len,
471 SSL_FILETYPE_ASN1) < 0) {
473 "SSL: use client cert DER blob failed");
476 wpa_printf(MSG_DEBUG, "SSL: use client cert blob OK");
481 if (wolfSSL_use_certificate_chain_file(conn->ssl,
484 "SSL: use client cert PEM file failed");
485 if (wolfSSL_use_certificate_chain_file_format(
486 conn->ssl, client_cert,
487 SSL_FILETYPE_ASN1) < 0) {
489 "SSL: use client cert DER file failed");
493 wpa_printf(MSG_DEBUG, "SSL: use client cert file OK");
501 static int tls_passwd_cb(char *buf, int size, int rwflag, void *password)
505 os_strlcpy(buf, (char *) password, size);
506 return os_strlen(buf);
510 static int tls_connection_private_key(void *tls_ctx,
511 struct tls_connection *conn,
512 const char *private_key,
513 const char *private_key_passwd,
514 const u8 *private_key_blob,
517 WOLFSSL_CTX *ctx = tls_ctx;
521 if (!private_key && !private_key_blob)
524 if (private_key_passwd) {
525 passwd = os_strdup(private_key_passwd);
530 wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
531 wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
533 if (private_key_blob) {
534 if (wolfSSL_use_PrivateKey_buffer(conn->ssl,
535 private_key_blob, blob_len,
536 SSL_FILETYPE_ASN1) < 0) {
538 "SSL: use private DER blob failed");
540 wpa_printf(MSG_DEBUG, "SSL: use private key blob OK");
545 if (!ok && private_key) {
546 if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
547 SSL_FILETYPE_PEM) < 0) {
549 "SSL: use private key PEM file failed");
550 if (wolfSSL_use_PrivateKey_file(conn->ssl, private_key,
551 SSL_FILETYPE_ASN1) < 0)
554 "SSL: use private key DER file failed");
563 wpa_printf(MSG_DEBUG, "SSL: use private key file OK");
566 wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
576 static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
577 const char *value, size_t len)
579 WOLFSSL_ASN1_OBJECT *gen;
584 ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
586 for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
587 gen = wolfSSL_sk_value(ext, i);
588 if (gen->type != type)
590 if (os_strlen((char *) gen->obj) == len &&
591 os_memcmp(value, gen->obj, len) == 0)
595 wolfSSL_sk_ASN1_OBJECT_free(ext);
601 static int tls_match_alt_subject(WOLFSSL_X509 *cert, const char *match)
604 const char *pos, *end;
609 if (os_strncmp(pos, "EMAIL:", 6) == 0) {
612 } else if (os_strncmp(pos, "DNS:", 4) == 0) {
615 } else if (os_strncmp(pos, "URI:", 4) == 0) {
620 "TLS: Invalid altSubjectName match '%s'",
624 end = os_strchr(pos, ';');
626 if (os_strncmp(end + 1, "EMAIL:", 6) == 0 ||
627 os_strncmp(end + 1, "DNS:", 4) == 0 ||
628 os_strncmp(end + 1, "URI:", 4) == 0)
630 end = os_strchr(end + 1, ';');
635 len = os_strlen(pos);
636 if (tls_match_alt_subject_component(cert, type, pos, len) > 0)
645 static int domain_suffix_match(const char *val, size_t len, const char *match,
650 /* Check for embedded nuls that could mess up suffix matching */
651 for (i = 0; i < len; i++) {
652 if (val[i] == '\0') {
653 wpa_printf(MSG_DEBUG,
654 "TLS: Embedded null in a string - reject");
659 match_len = os_strlen(match);
660 if (match_len > len || (full && match_len != len))
663 if (os_strncasecmp(val + len - match_len, match, match_len) != 0)
664 return 0; /* no match */
666 if (match_len == len)
667 return 1; /* exact match */
669 if (val[len - match_len - 1] == '.')
670 return 1; /* full label match completes suffix match */
672 wpa_printf(MSG_DEBUG, "TLS: Reject due to incomplete label match");
677 static int tls_match_suffix(WOLFSSL_X509 *cert, const char *match, int full)
679 WOLFSSL_ASN1_OBJECT *gen;
684 WOLFSSL_X509_NAME *name;
686 wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s",
687 full ? "" : "suffix ", match);
689 ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
691 for (j = 0; ext && j < wolfSSL_sk_num(ext); j++) {
692 gen = wolfSSL_sk_value(ext, j);
693 if (gen->type != ALT_NAMES_OID)
696 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate dNSName",
697 gen->obj, os_strlen((char *)gen->obj));
698 if (domain_suffix_match((const char *) gen->obj,
699 os_strlen((char *) gen->obj), match,
701 wpa_printf(MSG_DEBUG, "TLS: %s in dNSName found",
702 full ? "Match" : "Suffix match");
703 wolfSSL_sk_ASN1_OBJECT_free(ext);
707 wolfSSL_sk_ASN1_OBJECT_free(ext);
710 wpa_printf(MSG_DEBUG, "TLS: None of the dNSName(s) matched");
714 name = wolfSSL_X509_get_subject_name(cert);
717 WOLFSSL_X509_NAME_ENTRY *e;
718 WOLFSSL_ASN1_STRING *cn;
720 i = wolfSSL_X509_NAME_get_index_by_NID(name, ASN_COMMON_NAME,
724 e = wolfSSL_X509_NAME_get_entry(name, i);
727 cn = wolfSSL_X509_NAME_ENTRY_get_data(e);
730 wpa_hexdump_ascii(MSG_DEBUG, "TLS: Certificate commonName",
731 cn->data, cn->length);
732 if (domain_suffix_match(cn->data, cn->length, match, full) == 1)
734 wpa_printf(MSG_DEBUG, "TLS: %s in commonName found",
735 full ? "Match" : "Suffix match");
740 wpa_printf(MSG_DEBUG, "TLS: No CommonName %smatch found",
741 full ? "" : "suffix ");
746 static enum tls_fail_reason wolfssl_tls_fail_reason(int err)
749 case X509_V_ERR_CERT_REVOKED:
750 return TLS_FAIL_REVOKED;
751 case ASN_BEFORE_DATE_E:
752 case X509_V_ERR_CERT_NOT_YET_VALID:
753 case X509_V_ERR_CRL_NOT_YET_VALID:
754 return TLS_FAIL_NOT_YET_VALID;
755 case ASN_AFTER_DATE_E:
756 case X509_V_ERR_CERT_HAS_EXPIRED:
757 case X509_V_ERR_CRL_HAS_EXPIRED:
758 return TLS_FAIL_EXPIRED;
759 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
760 case X509_V_ERR_UNABLE_TO_GET_CRL:
761 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
762 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
763 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
764 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
765 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
766 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
767 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
768 case X509_V_ERR_INVALID_CA:
769 return TLS_FAIL_UNTRUSTED;
770 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
771 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
772 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
773 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
774 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
775 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
776 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
777 case X509_V_ERR_CERT_UNTRUSTED:
778 case X509_V_ERR_CERT_REJECTED:
779 return TLS_FAIL_BAD_CERTIFICATE;
781 return TLS_FAIL_UNSPECIFIED;
786 static const char * wolfssl_tls_err_string(int err, const char *err_str)
789 case ASN_BEFORE_DATE_E:
790 return "certificate is not yet valid";
791 case ASN_AFTER_DATE_E:
792 return "certificate has expired";
799 static struct wpabuf * get_x509_cert(WOLFSSL_X509 *cert)
801 struct wpabuf *buf = NULL;
805 data = wolfSSL_X509_get_der(cert, &cert_len);
807 buf = wpabuf_alloc_copy(data, cert_len);
813 static void wolfssl_tls_fail_event(struct tls_connection *conn,
814 WOLFSSL_X509 *err_cert, int err, int depth,
815 const char *subject, const char *err_str,
816 enum tls_fail_reason reason)
818 union tls_event_data ev;
819 struct wpabuf *cert = NULL;
820 struct tls_context *context = conn->context;
822 if (!context->event_cb)
825 cert = get_x509_cert(err_cert);
826 os_memset(&ev, 0, sizeof(ev));
827 ev.cert_fail.reason = reason != TLS_FAIL_UNSPECIFIED ?
828 reason : wolfssl_tls_fail_reason(err);
829 ev.cert_fail.depth = depth;
830 ev.cert_fail.subject = subject;
831 ev.cert_fail.reason_txt = wolfssl_tls_err_string(err, err_str);
832 ev.cert_fail.cert = cert;
833 context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
838 static void wolfssl_tls_cert_event(struct tls_connection *conn,
839 WOLFSSL_X509 *err_cert, int depth,
842 struct wpabuf *cert = NULL;
843 union tls_event_data ev;
844 struct tls_context *context = conn->context;
845 char *alt_subject[TLS_MAX_ALT_SUBJECT];
846 int alt, num_alt_subject = 0;
847 WOLFSSL_ASN1_OBJECT *gen;
852 #endif /* CONFIG_SHA256 */
854 if (!context->event_cb)
857 os_memset(&ev, 0, sizeof(ev));
858 if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) ||
859 context->cert_in_cb) {
860 cert = get_x509_cert(err_cert);
861 ev.peer_cert.cert = cert;
869 addr[0] = wpabuf_head(cert);
870 len[0] = wpabuf_len(cert);
871 if (sha256_vector(1, addr, len, hash) == 0) {
872 ev.peer_cert.hash = hash;
873 ev.peer_cert.hash_len = sizeof(hash);
876 #endif /* CONFIG_SHA256 */
878 ev.peer_cert.depth = depth;
879 ev.peer_cert.subject = subject;
881 ext = wolfSSL_X509_get_ext_d2i(err_cert, ALT_NAMES_OID, NULL, NULL);
882 for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
885 if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
887 gen = wolfSSL_sk_value((void *) ext, i);
888 if (gen->type != GEN_EMAIL &&
889 gen->type != GEN_DNS &&
890 gen->type != GEN_URI)
893 pos = os_malloc(10 + os_strlen((char *) gen->obj) + 1);
896 alt_subject[num_alt_subject++] = pos;
900 os_memcpy(pos, "EMAIL:", 6);
904 os_memcpy(pos, "DNS:", 4);
908 os_memcpy(pos, "URI:", 4);
913 os_memcpy(pos, gen->obj, os_strlen((char *)gen->obj));
914 pos += os_strlen((char *)gen->obj);
917 wolfSSL_sk_ASN1_OBJECT_free(ext);
919 for (alt = 0; alt < num_alt_subject; alt++)
920 ev.peer_cert.altsubject[alt] = alt_subject[alt];
921 ev.peer_cert.num_altsubject = num_alt_subject;
923 context->event_cb(context->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
925 for (alt = 0; alt < num_alt_subject; alt++)
926 os_free(alt_subject[alt]);
930 static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
933 WOLFSSL_X509 *err_cert;
936 struct tls_connection *conn;
937 struct tls_context *context;
938 char *match, *altmatch, *suffix_match, *domain_match;
941 err_cert = wolfSSL_X509_STORE_CTX_get_current_cert(x509_ctx);
943 wpa_printf(MSG_DEBUG, "wolfSSL: No Cert");
947 err = wolfSSL_X509_STORE_CTX_get_error(x509_ctx);
948 depth = wolfSSL_X509_STORE_CTX_get_error_depth(x509_ctx);
949 ssl = wolfSSL_X509_STORE_CTX_get_ex_data(
950 x509_ctx, wolfSSL_get_ex_data_X509_STORE_CTX_idx());
951 wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(err_cert), buf,
954 conn = wolfSSL_get_ex_data(ssl, 0);
956 wpa_printf(MSG_DEBUG, "wolfSSL: No ex_data");
961 conn->peer_cert = err_cert;
963 conn->peer_issuer = err_cert;
965 conn->peer_issuer_issuer = err_cert;
967 context = conn->context;
968 match = conn->subject_match;
969 altmatch = conn->alt_subject_match;
970 suffix_match = conn->suffix_match;
971 domain_match = conn->domain_match;
973 if (!preverify_ok && !conn->ca_cert_verify)
975 if (!preverify_ok && depth > 0 && conn->server_cert_only)
977 if (!preverify_ok && (conn->flags & TLS_CONN_DISABLE_TIME_CHECKS) &&
978 (err == X509_V_ERR_CERT_HAS_EXPIRED ||
979 err == ASN_AFTER_DATE_E || err == ASN_BEFORE_DATE_E ||
980 err == X509_V_ERR_CERT_NOT_YET_VALID)) {
981 wpa_printf(MSG_DEBUG,
982 "wolfSSL: Ignore certificate validity time mismatch");
986 err_str = wolfSSL_X509_verify_cert_error_string(err);
990 * Do not require preverify_ok so we can explicity allow otherwise
991 * invalid pinned server certificates.
993 if (depth == 0 && conn->server_cert_only) {
996 cert = get_x509_cert(err_cert);
998 wpa_printf(MSG_DEBUG,
999 "wolfSSL: Could not fetch server certificate data");
1006 addr[0] = wpabuf_head(cert);
1007 len[0] = wpabuf_len(cert);
1008 if (sha256_vector(1, addr, len, hash) < 0 ||
1009 os_memcmp(conn->srv_cert_hash, hash, 32) != 0) {
1010 err_str = "Server certificate mismatch";
1011 err = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
1013 } else if (!preverify_ok) {
1015 * Certificate matches pinned certificate, allow
1016 * regardless of other problems.
1018 wpa_printf(MSG_DEBUG,
1019 "wolfSSL: Ignore validation issues for a pinned server certificate");
1025 #endif /* CONFIG_SHA256 */
1027 if (!preverify_ok) {
1028 wpa_printf(MSG_WARNING,
1029 "TLS: Certificate verification failed, error %d (%s) depth %d for '%s'",
1030 err, err_str, depth, buf);
1031 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1032 err_str, TLS_FAIL_UNSPECIFIED);
1033 return preverify_ok;
1036 wpa_printf(MSG_DEBUG,
1037 "TLS: %s - preverify_ok=%d err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
1038 __func__, preverify_ok, err, err_str,
1039 conn->ca_cert_verify, depth, buf);
1040 if (depth == 0 && match && os_strstr(buf, match) == NULL) {
1041 wpa_printf(MSG_WARNING,
1042 "TLS: Subject '%s' did not match with '%s'",
1045 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1047 TLS_FAIL_SUBJECT_MISMATCH);
1048 } else if (depth == 0 && altmatch &&
1049 !tls_match_alt_subject(err_cert, altmatch)) {
1050 wpa_printf(MSG_WARNING,
1051 "TLS: altSubjectName match '%s' not found",
1054 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1055 "AltSubject mismatch",
1056 TLS_FAIL_ALTSUBJECT_MISMATCH);
1057 } else if (depth == 0 && suffix_match &&
1058 !tls_match_suffix(err_cert, suffix_match, 0)) {
1059 wpa_printf(MSG_WARNING,
1060 "TLS: Domain suffix match '%s' not found",
1063 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1064 "Domain suffix mismatch",
1065 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1066 } else if (depth == 0 && domain_match &&
1067 !tls_match_suffix(err_cert, domain_match, 1)) {
1068 wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found",
1071 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1073 TLS_FAIL_DOMAIN_MISMATCH);
1075 wolfssl_tls_cert_event(conn, err_cert, depth, buf);
1078 if (conn->cert_probe && preverify_ok && depth == 0) {
1079 wpa_printf(MSG_DEBUG,
1080 "wolfSSL: Reject server certificate on probe-only run");
1082 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1083 "Server certificate chain probe",
1084 TLS_FAIL_SERVER_CHAIN_PROBE);
1087 #ifdef HAVE_OCSP_WOLFSSL
1088 if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
1090 enum ocsp_result res;
1092 res = check_ocsp_resp(conn->ssl_ctx, conn->ssl, err_cert,
1094 conn->peer_issuer_issuer);
1095 if (res == OCSP_REVOKED) {
1097 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1098 "certificate revoked",
1100 if (err == X509_V_OK)
1101 X509_STORE_CTX_set_error(
1102 x509_ctx, X509_V_ERR_CERT_REVOKED);
1103 } else if (res != OCSP_GOOD &&
1104 (conn->flags & TLS_CONN_REQUIRE_OCSP)) {
1106 wolfssl_tls_fail_event(conn, err_cert, err, depth, buf,
1107 "bad certificate status response",
1108 TLS_FAIL_UNSPECIFIED);
1111 #endif /* HAVE_OCSP_WOLFSSL */
1112 if (depth == 0 && preverify_ok && context->event_cb != NULL)
1113 context->event_cb(context->cb_ctx,
1114 TLS_CERT_CHAIN_SUCCESS, NULL);
1116 return preverify_ok;
1120 static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
1121 const char *ca_cert,
1122 const u8 *ca_cert_blob, size_t blob_len,
1123 const char *ca_path)
1125 WOLFSSL_CTX *ctx = tls_ctx;
1127 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
1128 conn->ca_cert_verify = 1;
1130 if (ca_cert && os_strncmp(ca_cert, "probe://", 8) == 0) {
1131 wpa_printf(MSG_DEBUG,
1132 "wolfSSL: Probe for server certificate chain");
1133 conn->cert_probe = 1;
1134 conn->ca_cert_verify = 0;
1138 if (ca_cert && os_strncmp(ca_cert, "hash://", 7) == 0) {
1139 #ifdef CONFIG_SHA256
1140 const char *pos = ca_cert + 7;
1142 if (os_strncmp(pos, "server/sha256/", 14) != 0) {
1143 wpa_printf(MSG_DEBUG,
1144 "wolfSSL: Unsupported ca_cert hash value '%s'",
1149 if (os_strlen(pos) != 32 * 2) {
1150 wpa_printf(MSG_DEBUG,
1151 "wolfSSL: Unexpected SHA256 hash length in ca_cert '%s'",
1155 if (hexstr2bin(pos, conn->srv_cert_hash, 32) < 0) {
1156 wpa_printf(MSG_DEBUG,
1157 "wolfSSL: Invalid SHA256 hash value in ca_cert '%s'",
1161 conn->server_cert_only = 1;
1162 wpa_printf(MSG_DEBUG,
1163 "wolfSSL: Checking only server certificate match");
1165 #else /* CONFIG_SHA256 */
1166 wpa_printf(MSG_INFO,
1167 "No SHA256 included in the build - cannot validate server certificate hash");
1169 #endif /* CONFIG_SHA256 */
1173 if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_blob, blob_len,
1174 SSL_FILETYPE_ASN1) !=
1176 wpa_printf(MSG_INFO, "SSL: failed to load CA blob");
1179 wpa_printf(MSG_DEBUG, "SSL: use CA cert blob OK");
1183 if (ca_cert || ca_path) {
1184 WOLFSSL_X509_STORE *cm = wolfSSL_X509_STORE_new();
1187 wpa_printf(MSG_INFO,
1188 "SSL: failed to create certificate store");
1191 wolfSSL_CTX_set_cert_store(ctx, cm);
1193 if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
1195 wpa_printf(MSG_INFO,
1196 "SSL: failed to load ca_cert as PEM");
1201 if (wolfSSL_CTX_der_load_verify_locations(
1202 ctx, ca_cert, SSL_FILETYPE_ASN1) !=
1204 wpa_printf(MSG_INFO,
1205 "SSL: failed to load ca_cert as DER");
1212 conn->ca_cert_verify = 0;
1217 static void tls_set_conn_flags(WOLFSSL *ssl, unsigned int flags)
1219 #ifdef HAVE_SESSION_TICKET
1221 if (!(flags & TLS_CONN_DISABLE_SESSION_TICKET))
1222 wolfSSL_UseSessionTicket(ssl);
1224 #endif /* HAVE_SESSION_TICKET */
1226 if (flags & TLS_CONN_DISABLE_TLSv1_0)
1227 wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1);
1228 if (flags & TLS_CONN_DISABLE_TLSv1_1)
1229 wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
1230 if (flags & TLS_CONN_DISABLE_TLSv1_2)
1231 wolfSSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
1235 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
1236 const struct tls_connection_params *params)
1238 wpa_printf(MSG_DEBUG, "SSL: set params");
1240 if (tls_connection_set_subject_match(conn, params->subject_match,
1241 params->altsubject_match,
1242 params->suffix_match,
1243 params->domain_match) < 0) {
1244 wpa_printf(MSG_INFO, "Error setting subject match");
1248 if (tls_connection_ca_cert(tls_ctx, conn, params->ca_cert,
1249 params->ca_cert_blob,
1250 params->ca_cert_blob_len,
1251 params->ca_path) < 0) {
1252 wpa_printf(MSG_INFO, "Error setting CA cert");
1256 if (tls_connection_client_cert(conn, params->client_cert,
1257 params->client_cert_blob,
1258 params->client_cert_blob_len) < 0) {
1259 wpa_printf(MSG_INFO, "Error setting client cert");
1263 if (tls_connection_private_key(tls_ctx, conn, params->private_key,
1264 params->private_key_passwd,
1265 params->private_key_blob,
1266 params->private_key_blob_len) < 0) {
1267 wpa_printf(MSG_INFO, "Error setting private key");
1271 if (tls_connection_dh(conn, params->dh_file, params->dh_blob,
1272 params->dh_blob_len) < 0) {
1273 wpa_printf(MSG_INFO, "Error setting DH");
1277 if (params->openssl_ciphers &&
1278 wolfSSL_set_cipher_list(conn->ssl, params->openssl_ciphers) != 1) {
1279 wpa_printf(MSG_INFO,
1280 "wolfSSL: Failed to set cipher string '%s'",
1281 params->openssl_ciphers);
1285 tls_set_conn_flags(conn->ssl, params->flags);
1287 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
1288 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1289 if (wolfSSL_UseOCSPStapling(conn->ssl, WOLFSSL_CSR_OCSP,
1290 WOLFSSL_CSR_OCSP_USE_NONCE) !=
1293 wolfSSL_CTX_EnableOCSP(tls_ctx, 0);
1295 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
1296 #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
1297 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1298 if (wolfSSL_UseOCSPStaplingV2(conn->ssl,
1299 WOLFSSL_CSR2_OCSP_MULTI, 0) !=
1302 wolfSSL_CTX_EnableOCSP(tls_ctx, 0);
1304 #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1305 #if !defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \
1306 !defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
1308 if (params->flags & TLS_CONN_REQUEST_OCSP)
1309 wolfSSL_CTX_EnableOCSP(ctx, 0);
1310 #else /* HAVE_OCSP */
1311 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
1312 wpa_printf(MSG_INFO,
1313 "wolfSSL: No OCSP support included - reject configuration");
1316 if (params->flags & TLS_CONN_REQUEST_OCSP) {
1317 wpa_printf(MSG_DEBUG,
1318 "wolfSSL: No OCSP support included - allow optional OCSP case to continue");
1320 #endif /* HAVE_OCSP */
1321 #endif /* !HAVE_CERTIFICATE_STATUS_REQUEST &&
1322 * !HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
1324 conn->flags = params->flags;
1330 static int tls_global_ca_cert(void *ssl_ctx, const char *ca_cert)
1332 WOLFSSL_CTX *ctx = ssl_ctx;
1335 if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1)
1337 wpa_printf(MSG_WARNING,
1338 "Failed to load root certificates");
1342 wpa_printf(MSG_DEBUG,
1343 "TLS: Trusted root certificate(s) loaded");
1350 static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
1352 WOLFSSL_CTX *ctx = ssl_ctx;
1357 if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
1358 SSL_FILETYPE_ASN1) !=
1360 wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
1362 wpa_printf(MSG_INFO, "Failed to load client certificate");
1366 wpa_printf(MSG_DEBUG, "SSL: Loaded global client certificate: %s",
1373 static int tls_global_private_key(void *ssl_ctx, const char *private_key,
1374 const char *private_key_passwd)
1376 WOLFSSL_CTX *ctx = ssl_ctx;
1377 char *passwd = NULL;
1383 if (private_key_passwd) {
1384 passwd = os_strdup(private_key_passwd);
1389 wolfSSL_CTX_set_default_passwd_cb(ctx, tls_passwd_cb);
1390 wolfSSL_CTX_set_default_passwd_cb_userdata(ctx, passwd);
1392 if (wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1393 SSL_FILETYPE_ASN1) != 1 &&
1394 wolfSSL_CTX_use_PrivateKey_file(ctx, private_key,
1395 SSL_FILETYPE_PEM) != 1) {
1396 wpa_printf(MSG_INFO, "Failed to load private key");
1400 wpa_printf(MSG_DEBUG, "SSL: Loaded global private key");
1403 wolfSSL_CTX_set_default_passwd_cb(ctx, NULL);
1409 static int tls_global_dh(void *ssl_ctx, const char *dh_file,
1410 const u8 *dh_blob, size_t blob_len)
1412 WOLFSSL_CTX *ctx = ssl_ctx;
1414 if (!dh_file && !dh_blob)
1418 if (wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_blob, blob_len,
1419 SSL_FILETYPE_ASN1) < 0) {
1420 wpa_printf(MSG_INFO,
1421 "SSL: global use DH DER blob failed");
1424 wpa_printf(MSG_DEBUG, "SSL: global use DH blob OK");
1429 if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file, SSL_FILETYPE_PEM) <
1431 wpa_printf(MSG_INFO,
1432 "SSL: global use DH PEM file failed");
1433 if (wolfSSL_CTX_SetTmpDH_file(ctx, dh_file,
1434 SSL_FILETYPE_ASN1) < 0) {
1435 wpa_printf(MSG_INFO,
1436 "SSL: global use DH DER file failed");
1440 wpa_printf(MSG_DEBUG, "SSL: global use DH file OK");
1450 int ocsp_status_cb(void *unused, const char *url, int url_sz,
1451 unsigned char *request, int request_sz,
1452 unsigned char **response)
1459 wpa_printf(MSG_DEBUG,
1460 "wolfSSL: OCSP status callback - no response configured");
1465 *response = (unsigned char *) os_readfile(url, &len);
1467 wpa_printf(MSG_DEBUG,
1468 "wolfSSL: OCSP status callback - could not read response file");
1471 wpa_printf(MSG_DEBUG,
1472 "wolfSSL: OCSP status callback - send cached response");
1477 void ocsp_resp_free_cb(void *ocsp_stapling_response, unsigned char *response)
1482 #endif /* HAVE_OCSP */
1485 int tls_global_set_params(void *tls_ctx,
1486 const struct tls_connection_params *params)
1488 wpa_printf(MSG_DEBUG, "SSL: global set params");
1490 if (tls_global_ca_cert(tls_ctx, params->ca_cert) < 0) {
1491 wpa_printf(MSG_INFO, "SSL: Failed to load ca cert file '%s'",
1496 if (tls_global_client_cert(tls_ctx, params->client_cert) < 0) {
1497 wpa_printf(MSG_INFO,
1498 "SSL: Failed to load client cert file '%s'",
1499 params->client_cert);
1503 if (tls_global_private_key(tls_ctx, params->private_key,
1504 params->private_key_passwd) < 0) {
1505 wpa_printf(MSG_INFO,
1506 "SSL: Failed to load private key file '%s'",
1507 params->private_key);
1511 if (tls_global_dh(tls_ctx, params->dh_file, params->dh_blob,
1512 params->dh_blob_len) < 0) {
1513 wpa_printf(MSG_INFO, "SSL: Failed to load DH file '%s'",
1518 if (params->openssl_ciphers &&
1519 wolfSSL_CTX_set_cipher_list(tls_ctx,
1520 params->openssl_ciphers) != 1) {
1521 wpa_printf(MSG_INFO,
1522 "wolfSSL: Failed to set cipher string '%s'",
1523 params->openssl_ciphers);
1527 #ifdef HAVE_SESSION_TICKET
1528 /* Session ticket is off by default - can't disable once on. */
1529 if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
1530 wolfSSL_CTX_UseSessionTicket(tls_ctx);
1531 #endif /* HAVE_SESSION_TICKET */
1534 if (params->ocsp_stapling_response) {
1535 wolfSSL_CTX_SetOCSP_OverrideURL(tls_ctx,
1536 params->ocsp_stapling_response);
1537 wolfSSL_CTX_SetOCSP_Cb(tls_ctx, ocsp_status_cb,
1538 ocsp_resp_free_cb, NULL);
1540 #endif /* HAVE_OCSP */
1546 int tls_global_set_verify(void *tls_ctx, int check_crl)
1548 wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);
1551 /* Hack to Enable CRLs. */
1552 wolfSSL_CTX_LoadCRLBuffer(tls_ctx, NULL, 0, SSL_FILETYPE_PEM);
1559 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
1560 int verify_peer, unsigned int flags,
1561 const u8 *session_ctx, size_t session_ctx_len)
1566 wpa_printf(MSG_DEBUG, "SSL: set verify: %d", verify_peer);
1569 conn->ca_cert_verify = 1;
1570 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_PEER |
1571 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1574 conn->ca_cert_verify = 0;
1575 wolfSSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
1578 wolfSSL_set_accept_state(conn->ssl);
1580 /* TODO: do we need to fake a session like OpenSSL does here? */
1586 static struct wpabuf * wolfssl_handshake(struct tls_connection *conn,
1587 const struct wpabuf *in_data,
1592 wolfssl_reset_out_data(&conn->output);
1594 /* Initiate TLS handshake or continue the existing handshake */
1596 wolfSSL_set_accept_state(conn->ssl);
1597 res = wolfSSL_accept(conn->ssl);
1598 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_accept: %d", res);
1600 wolfSSL_set_connect_state(conn->ssl);
1601 res = wolfSSL_connect(conn->ssl);
1602 wpa_printf(MSG_DEBUG, "SSL: wolfSSL_connect: %d", res);
1606 int err = wolfSSL_get_error(conn->ssl, res);
1608 if (err == SSL_ERROR_WANT_READ) {
1609 wpa_printf(MSG_DEBUG,
1610 "SSL: wolfSSL_connect - want more data");
1611 } else if (err == SSL_ERROR_WANT_WRITE) {
1612 wpa_printf(MSG_DEBUG,
1613 "SSL: wolfSSL_connect - want to write");
1617 wpa_printf(MSG_DEBUG,
1618 "SSL: wolfSSL_connect - failed %s",
1619 wolfSSL_ERR_error_string(err, msg));
1624 return conn->output.out_data;
1628 static struct wpabuf * wolfssl_get_appl_data(struct tls_connection *conn,
1632 struct wpabuf *appl_data = wpabuf_alloc(max_len + 100);
1637 res = wolfSSL_read(conn->ssl, wpabuf_mhead(appl_data),
1638 wpabuf_size(appl_data));
1640 int err = wolfSSL_get_error(conn->ssl, res);
1642 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1643 wpa_printf(MSG_DEBUG,
1644 "SSL: No Application Data included");
1648 wpa_printf(MSG_DEBUG,
1649 "Failed to read possible Application Data %s",
1650 wolfSSL_ERR_error_string(err, msg));
1653 wpabuf_free(appl_data);
1657 wpabuf_put(appl_data, res);
1658 wpa_hexdump_buf_key(MSG_MSGDUMP,
1659 "SSL: Application Data in Finished message",
1665 static struct wpabuf *
1666 wolfssl_connection_handshake(struct tls_connection *conn,
1667 const struct wpabuf *in_data,
1668 struct wpabuf **appl_data, int server)
1670 struct wpabuf *out_data;
1672 wolfssl_reset_in_data(&conn->input, in_data);
1677 out_data = wolfssl_handshake(conn, in_data, server);
1681 if (wolfSSL_is_init_finished(conn->ssl)) {
1682 wpa_printf(MSG_DEBUG,
1683 "wolfSSL: Handshake finished - resumed=%d",
1684 tls_connection_resumed(NULL, conn));
1685 if (appl_data && in_data)
1686 *appl_data = wolfssl_get_appl_data(conn,
1687 wpabuf_len(in_data));
1694 struct wpabuf * tls_connection_handshake(void *tls_ctx,
1695 struct tls_connection *conn,
1696 const struct wpabuf *in_data,
1697 struct wpabuf **appl_data)
1699 return wolfssl_connection_handshake(conn, in_data, appl_data, 0);
1703 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1704 struct tls_connection *conn,
1705 const struct wpabuf *in_data,
1706 struct wpabuf **appl_data)
1708 return wolfssl_connection_handshake(conn, in_data, appl_data, 1);
1712 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1713 struct tls_connection *conn,
1714 const struct wpabuf *in_data)
1721 wpa_printf(MSG_DEBUG, "SSL: encrypt: %ld bytes", wpabuf_len(in_data));
1723 wolfssl_reset_out_data(&conn->output);
1725 res = wolfSSL_write(conn->ssl, wpabuf_head(in_data),
1726 wpabuf_len(in_data));
1728 int err = wolfSSL_get_error(conn->ssl, res);
1731 wpa_printf(MSG_INFO, "Encryption failed - SSL_write: %s",
1732 wolfSSL_ERR_error_string(err, msg));
1736 return conn->output.out_data;
1740 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1741 struct tls_connection *conn,
1742 const struct wpabuf *in_data)
1750 wpa_printf(MSG_DEBUG, "SSL: decrypt");
1752 wolfssl_reset_in_data(&conn->input, in_data);
1754 /* Read decrypted data for further processing */
1756 * Even though we try to disable TLS compression, it is possible that
1757 * this cannot be done with all TLS libraries. Add extra buffer space
1758 * to handle the possibility of the decrypted data being longer than
1761 buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1764 res = wolfSSL_read(conn->ssl, wpabuf_mhead(buf), wpabuf_size(buf));
1766 wpa_printf(MSG_INFO, "Decryption failed - SSL_read");
1770 wpabuf_put(buf, res);
1772 wpa_printf(MSG_DEBUG, "SSL: decrypt: %ld bytes", wpabuf_len(buf));
1778 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
1780 return conn ? wolfSSL_session_reused(conn->ssl) : 0;
1784 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1787 char buf[128], *pos, *end;
1791 if (!conn || !conn->ssl || !ciphers)
1796 end = pos + sizeof(buf);
1799 while (*c != TLS_CIPHER_NONE) {
1803 case TLS_CIPHER_RC4_SHA:
1806 case TLS_CIPHER_AES128_SHA:
1807 suite = "AES128-SHA";
1809 case TLS_CIPHER_RSA_DHE_AES128_SHA:
1810 suite = "DHE-RSA-AES128-SHA";
1812 case TLS_CIPHER_ANON_DH_AES128_SHA:
1813 suite = "ADH-AES128-SHA";
1815 case TLS_CIPHER_RSA_DHE_AES256_SHA:
1816 suite = "DHE-RSA-AES256-SHA";
1818 case TLS_CIPHER_AES256_SHA:
1819 suite = "AES256-SHA";
1822 wpa_printf(MSG_DEBUG,
1823 "TLS: Unsupported cipher selection: %d", *c);
1826 ret = os_snprintf(pos, end - pos, ":%s", suite);
1827 if (os_snprintf_error(end - pos, ret))
1834 wpa_printf(MSG_DEBUG, "wolfSSL: cipher suites: %s", buf + 1);
1836 if (wolfSSL_set_cipher_list(conn->ssl, buf + 1) != 1) {
1837 wpa_printf(MSG_DEBUG, "Cipher suite configuration failed");
1845 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
1846 char *buf, size_t buflen)
1848 WOLFSSL_CIPHER *cipher;
1851 if (!conn || !conn->ssl)
1854 cipher = wolfSSL_get_current_cipher(conn->ssl);
1858 name = wolfSSL_CIPHER_get_name(cipher);
1862 if (os_strcmp(name, "SSL_RSA_WITH_RC4_128_SHA") == 0)
1863 os_strlcpy(buf, "RC4-SHA", buflen);
1864 else if (os_strcmp(name, "TLS_RSA_WITH_AES_128_CBC_SHA") == 0)
1865 os_strlcpy(buf, "AES128-SHA", buflen);
1866 else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") == 0)
1867 os_strlcpy(buf, "DHE-RSA-AES128-SHA", buflen);
1868 else if (os_strcmp(name, "TLS_DH_anon_WITH_AES_128_CBC_SHA") == 0)
1869 os_strlcpy(buf, "ADH-AES128-SHA", buflen);
1870 else if (os_strcmp(name, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA") == 0)
1871 os_strlcpy(buf, "DHE-RSA-AES256-SHA", buflen);
1872 else if (os_strcmp(name, "TLS_RSA_WITH_AES_256_CBC_SHA") == 0)
1873 os_strlcpy(buf, "AES256-SHA", buflen);
1875 os_strlcpy(buf, name, buflen);
1881 int tls_connection_enable_workaround(void *tls_ctx,
1882 struct tls_connection *conn)
1884 /* no empty fragments in wolfSSL for now */
1889 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
1894 return conn->failed;
1898 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
1903 /* TODO: this is not incremented anywhere */
1904 return conn->read_alerts;
1908 int tls_connection_get_write_alerts(void *tls_ctx,
1909 struct tls_connection *conn)
1914 /* TODO: this is not incremented anywhere */
1915 return conn->write_alerts;
1920 int tls_get_library_version(char *buf, size_t buf_len)
1922 return os_snprintf(buf, buf_len, "wolfSSL build=%s run=%s",
1923 WOLFSSL_VERSION, wolfSSL_lib_version());
1926 int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
1927 char *buf, size_t buflen)
1931 if (!conn || !conn->ssl)
1934 name = wolfSSL_get_version(conn->ssl);
1938 os_strlcpy(buf, name, buflen);
1943 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
1944 struct tls_random *keys)
1954 os_memset(keys, 0, sizeof(*keys));
1955 keys->client_random = conn->client_random;
1956 keys->client_random_len = wolfSSL_get_client_random(
1957 ssl, conn->client_random, sizeof(conn->client_random));
1958 keys->server_random = conn->server_random;
1959 keys->server_random_len = wolfSSL_get_server_random(
1960 ssl, conn->server_random, sizeof(conn->server_random));
1966 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
1967 const char *label, u8 *out, size_t out_len)
1969 if (!conn || wolfSSL_make_eap_keys(conn->ssl, out, out_len, label) != 0)
1975 #define SEED_LEN (RAN_LEN + RAN_LEN)
1977 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
1978 u8 *out, size_t out_len)
1980 byte seed[SEED_LEN];
1987 unsigned int master_key_len;
1988 byte *server_random;
1989 unsigned int server_len;
1990 byte *client_random;
1991 unsigned int client_len;
1993 if (!conn || !conn->ssl)
1997 skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
1998 wolfSSL_GetIVSize(ssl));
2000 tmp_out = os_malloc(skip + out_len);
2005 wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
2006 &server_len, &client_random, &client_len);
2007 os_memcpy(seed, server_random, RAN_LEN);
2008 os_memcpy(seed + RAN_LEN, client_random, RAN_LEN);
2010 if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
2011 tls_prf_sha256(master_key, master_key_len,
2012 "key expansion", seed, sizeof(seed),
2013 _out, skip + out_len);
2016 ret = tls_prf_sha1_md5(master_key, master_key_len,
2017 "key expansion", seed, sizeof(seed),
2018 _out, skip + out_len);
2021 os_memset(master_key, 0, master_key_len);
2023 os_memcpy(out, _out + skip, out_len);
2024 bin_clear_free(tmp_out, skip + out_len);
2030 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2032 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
2033 int ext_type, const u8 *data,
2038 if (!conn || !conn->ssl || ext_type != 35)
2041 if (wolfSSL_set_SessionTicket(conn->ssl, data,
2042 (unsigned int) data_len) != 1)
2049 static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
2051 struct tls_connection *conn = arg;
2053 unsigned char client_random[RAN_LEN];
2054 unsigned char server_random[RAN_LEN];
2055 word32 ticket_len = sizeof(conn->session_ticket);
2057 if (!conn || !conn->session_ticket_cb)
2060 if (wolfSSL_get_client_random(s, client_random,
2061 sizeof(client_random)) == 0 ||
2062 wolfSSL_get_server_random(s, server_random,
2063 sizeof(server_random)) == 0 ||
2064 wolfSSL_get_SessionTicket(s, conn->session_ticket,
2068 if (ticket_len == 0)
2071 ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
2072 conn->session_ticket, ticket_len,
2073 client_random, server_random, secret);
2077 *secret_len = SECRET_LEN;
2081 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2084 int tls_connection_set_session_ticket_cb(void *tls_ctx,
2085 struct tls_connection *conn,
2086 tls_session_ticket_cb cb,
2089 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
2090 conn->session_ticket_cb = cb;
2091 conn->session_ticket_cb_ctx = ctx;
2094 if (wolfSSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
2098 if (wolfSSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
2103 #else /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2105 #endif /* EAP_FAST || EAP_FAST_DYNAMIC || EAP_SERVER_FAST */
2109 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2111 wpa_printf(MSG_DEBUG,
2112 "wolfSSL: Success data accepted for resumed session");
2116 void tls_connection_remove_session(struct tls_connection *conn)
2118 WOLFSSL_SESSION *sess;
2120 sess = wolfSSL_get_session(conn->ssl);
2124 wolfSSL_SSL_SESSION_set_timeout(sess, 0);
2125 wpa_printf(MSG_DEBUG,
2126 "wolfSSL: Removed cached session to disable session resumption");
2130 void tls_connection_set_success_data(struct tls_connection *conn,
2131 struct wpabuf *data)
2133 WOLFSSL_SESSION *sess;
2136 wpa_printf(MSG_DEBUG, "wolfSSL: Set success data");
2138 sess = wolfSSL_get_session(conn->ssl);
2140 wpa_printf(MSG_DEBUG,
2141 "wolfSSL: No session found for success data");
2145 old = wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);
2147 wpa_printf(MSG_DEBUG, "wolfSSL: Replacing old success data %p",
2151 if (wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, data) != 1)
2154 wpa_printf(MSG_DEBUG, "wolfSSL: Stored success data %p", data);
2155 conn->success_data = 1;
2159 wpa_printf(MSG_INFO, "wolfSSL: Failed to store success data");
2164 const struct wpabuf *
2165 tls_connection_get_success_data(struct tls_connection *conn)
2167 WOLFSSL_SESSION *sess;
2169 wpa_printf(MSG_DEBUG, "wolfSSL: Get success data");
2171 sess = wolfSSL_get_session(conn->ssl);
2174 return wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session);