From patchwork Thu Aug 26 09:25:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Juliusz Sosinowicz X-Patchwork-Id: 1521093 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=q2u7YKmn; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GwMm90HGzz9sWc for ; Thu, 26 Aug 2021 22:36:41 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=2xMnr8UQfUwEwunsb8p/h7ivVo7FB0X4dRiGgnqSj2Y=; b=q2u7YKmnA/Mt9W g31gx0UIBFP4QgzqxOmmhqKUmx6Q8hKozZFYouJWSO/fZaKlDhGIie/Z0e3gEBThLT2Y5xZSuyi0Y ZOS+zjDvcc4We6bPehBZiVnEhdQJBNMw/CG2kHIu7RAPHAjFhD/tQO/H72wJ5OPZZOAvsg8n+PMLv pP3S4pG4aN2BpBcHkPXR449+8bpI9aFHtYyIs/G7DVb8q9RR81qxjkO5yM+nmkAPIpuUwNJWrxeV2 Xz9CPKE0Ypq2d7iYo3Jzwx5VJNa9FQDhFf8tm8I/AlJddgfp8ZABMjyLhr5MuVJCCaJM/DxsHrTrv DrsJbYf77kRTduilQFag==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJEbQ-00A5jm-LP; Thu, 26 Aug 2021 12:35:28 +0000 Received: from p3plsmtpa11-02.prod.phx3.secureserver.net ([68.178.252.103]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mJBeF-009fa7-Rr for hostap@lists.infradead.org; Thu, 26 Aug 2021 09:26:14 +0000 Received: from localhost.localdomain ([188.212.135.26]) by :SMTPAUTH: with ESMTPSA id JBdkmuHZVUwxVJBeAm9bjH; Thu, 26 Aug 2021 02:26:07 -0700 X-CMAE-Analysis: v=2.4 cv=faFod2cF c=1 sm=1 tr=0 ts=61275e2f a=vHIsqjMKpocq46m/8280sQ==:117 a=vHIsqjMKpocq46m/8280sQ==:17 a=17OIDZiGAAAA:20 a=VTTltBjBAAAA:8 a=w_UktyYekynntdl6lMoA:9 a=on_vo79ac8RWgsiwd8Ea:22 X-SECURESERVER-ACCT: juliusz@wolfssl.com From: Juliusz Sosinowicz To: hostap@lists.infradead.org Cc: Juliusz Sosinowicz Subject: [PATCH] Implement new functions for EAP: Date: Thu, 26 Aug 2021 11:25:34 +0200 Message-Id: <20210826092534.14538-1-juliusz@wolfssl.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-CMAE-Envelope: MS4xfAO/Aj0HIrLDVHL6yxqhkmc2H6V+ryYpcD63DYGkPKYu5akgom5NWTy2EuMuOouQQ/gUAEwDq/VJY1F1ds9hCRzJpu4PjMjbq9M0/ygtN0wIKCw9LrdU gqypl/Pfc0YzRaICzmPilVAK9U6SfRTZqmSWpxqCqTZkOd9kbrrM3vhPpMA1VTfNI9JfMP4PQC/i98WfP27Jgw7hcnsTlh0vW2/yr0tfv9jD4UZyqTzAg74e S02E7spjRAgI/XdI9B6DzA== X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210826_022611_986116_DD4D0AC4 X-CRM114-Status: GOOD ( 19.89 ) X-Spam-Score: -0.0 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: - `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 . Content analysis details: (-0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [68.178.252.103 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [68.178.252.103 listed in list.dnswl.org] X-Mailman-Approved-At: Thu, 26 Aug 2021 05:35:22 -0700 X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org - `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 --- 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"))