- `tls_get_tls_unique` - `tls_connection_get_cipher_suite` - `tls_connection_get_peer_subject` - `tls_connection_get_own_cert_used` The necessary wolfSSL changes are located in https://github.com/wolfSSL/wolfssl/pull/4205 . Signed-off-by: Juliusz Sosinowicz <juliusz@xxxxxxxxxxx> --- src/crypto/crypto_wolfssl.c | 12 ++++ src/crypto/tls_wolfssl.c | 83 +++++++++++++++++++++-- tests/hwsim/example-hostapd.config | 3 + tests/hwsim/example-wpa_supplicant.config | 3 + tests/hwsim/test_ap_eap.py | 8 +-- tests/hwsim/test_dpp.py | 2 +- tests/hwsim/test_eap.py | 2 +- tests/hwsim/test_fils.py | 13 ++-- 8 files changed, 110 insertions(+), 16 deletions(-) diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c index 2e4bf8962..afb8f40d4 100644 --- a/src/crypto/crypto_wolfssl.c +++ b/src/crypto/crypto_wolfssl.c @@ -409,8 +409,11 @@ int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) } +#ifndef CONFIG_FIPS +#ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) { +#ifdef HAVE_AES_KEYWRAP int ret; if (TEST_FAIL()) @@ -419,12 +422,16 @@ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8, NULL); return ret != (n + 1) * 8 ? -1 : 0; +#else + return -1; +#endif /* HAVE_AES_KEYWRAP */ } int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, u8 *plain) { +#ifdef HAVE_AES_KEYWRAP int ret; if (TEST_FAIL()) @@ -433,7 +440,12 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8, NULL); return ret != n * 8 ? -1 : 0; +#else + return -1; +#endif /* HAVE_AES_KEYWRAP */ } +#endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */ +#endif /* CONFIG_FIPS */ #ifndef CONFIG_NO_RC4 diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c index cf482bfc3..1f695985f 100644 --- a/src/crypto/tls_wolfssl.c +++ b/src/crypto/tls_wolfssl.c @@ -58,6 +58,7 @@ struct tls_context { void *cb_ctx; int cert_in_cb; char *ocsp_stapling_response; + unsigned int tls_session_lifetime; }; static struct tls_context *tls_global = NULL; @@ -94,6 +95,7 @@ struct tls_connection { WOLFSSL_X509 *peer_cert; WOLFSSL_X509 *peer_issuer; WOLFSSL_X509 *peer_issuer_issuer; + char *peer_subject; /* peer subject info for authenticated peer */ }; @@ -189,6 +191,11 @@ static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess) wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL); } +void wolfSSL_logging_cb(const int logLevel, const char *const logMessage) +{ + (void)logLevel; + wpa_printf(MSG_DEBUG, "wolfSSL log:%s", logMessage); +} void * tls_init(const struct tls_config *conf) { @@ -197,6 +204,7 @@ void * tls_init(const struct tls_config *conf) const char *ciphers; #ifdef DEBUG_WOLFSSL + wolfSSL_SetLoggingCb(wolfSSL_logging_cb); wolfSSL_Debugging_ON(); #endif /* DEBUG_WOLFSSL */ @@ -227,17 +235,20 @@ void * tls_init(const struct tls_config *conf) } wolfSSL_SetIORecv(ssl_ctx, wolfssl_receive_cb); wolfSSL_SetIOSend(ssl_ctx, wolfssl_send_cb); + context->tls_session_lifetime = conf->tls_session_lifetime; wolfSSL_CTX_set_ex_data(ssl_ctx, 0, context); if (conf->tls_session_lifetime > 0) { + wolfSSL_CTX_set_session_id_context(ssl_ctx, + (const unsigned char*)"hostapd", 7); wolfSSL_CTX_set_quiet_shutdown(ssl_ctx, 1); wolfSSL_CTX_set_session_cache_mode(ssl_ctx, - SSL_SESS_CACHE_SERVER); + WOLFSSL_SESS_CACHE_SERVER); wolfSSL_CTX_set_timeout(ssl_ctx, conf->tls_session_lifetime); wolfSSL_CTX_sess_set_remove_cb(ssl_ctx, remove_session_cb); } else { wolfSSL_CTX_set_session_cache_mode(ssl_ctx, - SSL_SESS_CACHE_CLIENT); + WOLFSSL_SESS_CACHE_OFF); } if (conf && conf->openssl_ciphers) @@ -336,6 +347,7 @@ void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn) os_free(conn->alt_subject_match); os_free(conn->suffix_match); os_free(conn->domain_match); + os_free(conn->peer_subject); /* self */ os_free(conn); @@ -1134,6 +1146,11 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx) context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_SUCCESS, NULL); + if (depth == 0 && preverify_ok) { + os_free(conn->peer_subject); + conn->peer_subject = os_strdup(buf); + } + return preverify_ok; } @@ -1238,10 +1255,8 @@ static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn, static void tls_set_conn_flags(WOLFSSL *ssl, unsigned int flags) { #ifdef HAVE_SESSION_TICKET -#if 0 if (!(flags & TLS_CONN_DISABLE_SESSION_TICKET)) wolfSSL_UseSessionTicket(ssl); -#endif #endif /* HAVE_SESSION_TICKET */ if (flags & TLS_CONN_DISABLE_TLSv1_0) @@ -1590,6 +1605,8 @@ int 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) { + static int counter = 0; + struct tls_context *context; if (!conn) return -1; @@ -1607,6 +1624,23 @@ int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, wolfSSL_set_accept_state(conn->ssl); + context = wolfSSL_CTX_get_ex_data((WOLFSSL_CTX*)ssl_ctx, 0); + if (context && context->tls_session_lifetime == 0) { + /* + * Set session id context to a unique value to make sure + * session resumption cannot be used either through session + * caching or TLS ticket extension. + */ + counter++; + wolfSSL_set_session_id_context(conn->ssl, + (const unsigned char *) &counter, + sizeof(counter)); + } + else + wolfSSL_set_session_id_context(conn->ssl, session_ctx, + session_ctx_len); + (void)context; + /* TODO: do we need to fake a session like OpenSSL does here? */ return 0; @@ -2160,6 +2194,39 @@ void tls_connection_remove_session(struct tls_connection *conn) } +int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len) +{ + size_t len; + int reused; + + reused = wolfSSL_session_reused(conn->ssl); + if ((wolfSSL_is_server(conn->ssl) && !reused) || + (!wolfSSL_is_server(conn->ssl) && reused)) + len = wolfSSL_get_peer_finished(conn->ssl, buf, max_len); + else + len = wolfSSL_get_finished(conn->ssl, buf, max_len); + + if (len == 0 || len > max_len) + return -1; + + return len; +} + + +u16 tls_connection_get_cipher_suite(struct tls_connection *conn) +{ + return (u16)wolfSSL_get_current_cipher_suite(conn->ssl); +} + + +const char * tls_connection_get_peer_subject(struct tls_connection *conn) +{ + if (conn) + return conn->peer_subject; + return NULL; +} + + void tls_connection_set_success_data(struct tls_connection *conn, struct wpabuf *data) { @@ -2206,3 +2273,11 @@ tls_connection_get_success_data(struct tls_connection *conn) return NULL; return wolfSSL_SESSION_get_ex_data(sess, tls_ex_idx_session); } + + +bool tls_connection_get_own_cert_used(struct tls_connection *conn) +{ + if (conn) + return wolfSSL_get_certificate(conn->ssl) != NULL; + return false; +} diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config index d01a1d2ed..5b7130fdc 100644 --- a/tests/hwsim/example-hostapd.config +++ b/tests/hwsim/example-hostapd.config @@ -36,6 +36,9 @@ CONFIG_EAP_UNAUTH_TLS=y ifeq ($(CONFIG_TLS), openssl) CONFIG_EAP_PWD=y endif +ifeq ($(CONFIG_TLS), wolfssl) +CONFIG_EAP_PWD=y +endif CONFIG_EAP_EKE=y CONFIG_PKCS12=y CONFIG_RADIUS_SERVER=y diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config index 5e5acd695..ea6ef7d27 100644 --- a/tests/hwsim/example-wpa_supplicant.config +++ b/tests/hwsim/example-wpa_supplicant.config @@ -38,6 +38,9 @@ CONFIG_EAP_IKEV2=y ifeq ($(CONFIG_TLS), openssl) CONFIG_EAP_PWD=y endif +ifeq ($(CONFIG_TLS), wolfssl) +CONFIG_EAP_PWD=y +endif CONFIG_USIM_SIMULATOR=y CONFIG_SIM_SIMULATOR=y diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py index 269500a93..7cf5d9242 100644 --- a/tests/hwsim/test_ap_eap.py +++ b/tests/hwsim/test_ap_eap.py @@ -50,7 +50,7 @@ def check_subject_match_support(dev): def check_check_cert_subject_support(dev): tls = dev.request("GET tls_library") - if not tls.startswith("OpenSSL"): + if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): raise HwsimSkip("check_cert_subject not supported with this TLS library: " + tls) def check_altsubject_match_support(dev): @@ -3881,7 +3881,7 @@ def test_ap_wpa2_eap_fast_prf_oom(dev, apdev): """WPA2-Enterprise connection using EAP-FAST and OOM in PRF""" check_eap_capa(dev[0], "FAST") tls = dev[0].request("GET tls_library") - if tls.startswith("OpenSSL"): + if tls.startswith("OpenSSL") or tls.startswith("wolfSSL"): func = "tls_connection_get_eap_fast_key" count = 2 elif tls.startswith("internal"): @@ -6161,11 +6161,11 @@ def test_rsn_ie_proto_eap_sta(dev, apdev): def check_tls_session_resumption_capa(dev, hapd): tls = hapd.request("GET tls_library") - if not tls.startswith("OpenSSL"): + if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): raise HwsimSkip("hostapd TLS library is not OpenSSL or wolfSSL: " + tls) tls = dev.request("GET tls_library") - if not tls.startswith("OpenSSL"): + if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): raise HwsimSkip("Session resumption not supported with this TLS library: " + tls) def test_eap_ttls_pap_session_resumption(dev, apdev): diff --git a/tests/hwsim/test_dpp.py b/tests/hwsim/test_dpp.py index 71df7fc64..dba30bd0a 100644 --- a/tests/hwsim/test_dpp.py +++ b/tests/hwsim/test_dpp.py @@ -38,7 +38,7 @@ def check_dpp_capab(dev, brainpool=False, min_ver=1): raise HwsimSkip("DPP not supported") if brainpool: tls = dev.request("GET tls_library") - if not tls.startswith("OpenSSL") or "run=BoringSSL" in tls: + if (not tls.startswith("OpenSSL") or "run=BoringSSL" in tls) and not tls.startswith("wolfSSL"): raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) capa = dev.request("GET_CAPABILITY dpp") ver = 1 diff --git a/tests/hwsim/test_eap.py b/tests/hwsim/test_eap.py index 144e4d314..d3bbec3d4 100644 --- a/tests/hwsim/test_eap.py +++ b/tests/hwsim/test_eap.py @@ -440,7 +440,7 @@ def test_eap_teap_tls_cs_sha384(dev, apdev): def run_eap_teap_tls_cs(dev, apdev, cipher): check_eap_capa(dev[0], "TEAP") tls = dev[0].request("GET tls_library") - if not tls.startswith("OpenSSL"): + if not tls.startswith("OpenSSL") and not tls.startswith("wolfSSL"): raise HwsimSkip("TLS library not supported for TLS CS configuration: " + tls) params = int_teap_server_params(eap_teap_auth="1") params['openssl_ciphers'] = cipher diff --git a/tests/hwsim/test_fils.py b/tests/hwsim/test_fils.py index 4d4ddc39a..ffb063ba4 100644 --- a/tests/hwsim/test_fils.py +++ b/tests/hwsim/test_fils.py @@ -1419,12 +1419,13 @@ def run_fils_sk_pfs(dev, apdev, group, params): check_erp_capa(dev[0]) tls = dev[0].request("GET tls_library") - if int(group) in [25]: - if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)): - raise HwsimSkip("EC group not supported") - if int(group) in [27, 28, 29, 30]: - if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)): - raise HwsimSkip("Brainpool EC group not supported") + if not tls.startswith("wolfSSL"): + if int(group) in [25]: + if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)): + raise HwsimSkip("EC group not supported") + if int(group) in [27, 28, 29, 30]: + if not (tls.startswith("OpenSSL") and ("build=OpenSSL 1.0.2" in tls or "build=OpenSSL 1.1" in tls) and ("run=OpenSSL 1.0.2" in tls or "run=OpenSSL 1.1" in tls)): + raise HwsimSkip("Brainpool EC group not supported") start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst")) -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap