mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
eap-peap: Fix failures with session resumption
The PEAP RFC wants implementations to enforce that Phase2 methods have been successfully completed prior to accepting a successful result TLV. However, when TLS session resumption is used, some servers will skip phase2 methods entirely and simply send a Result TLV with a success code. This results in iwd (erroneously) rejecting the authentication attempt. Fix this by marking phase2 method as successful if session resumption is being used.
This commit is contained in:
parent
58d70a8c10
commit
eda02fb929
@ -468,7 +468,8 @@ static void eap_extensions_handle_request(struct eap_state *eap,
|
||||
}
|
||||
|
||||
static bool eap_peap_tunnel_ready(struct eap_state *eap,
|
||||
const char *peer_identity)
|
||||
const char *peer_identity,
|
||||
bool resumed)
|
||||
{
|
||||
struct peap_state *peap_state = eap_tls_common_get_variant_data(eap);
|
||||
|
||||
@ -480,6 +481,15 @@ static bool eap_peap_tunnel_ready(struct eap_state *eap,
|
||||
*/
|
||||
eap_discard_success_and_failure(eap, true);
|
||||
|
||||
/*
|
||||
* In case of a resumed session, the server will typically not run
|
||||
* phase2 methods at all, but will instead send a result TLV right
|
||||
* away. Treat this like a successful phase2. In case the server
|
||||
* does proceed with phase2, the success/failure state will be updated.
|
||||
*/
|
||||
if (resumed)
|
||||
eap_method_success(peap_state->phase2);
|
||||
|
||||
/* MSK, EMSK and challenge derivation */
|
||||
eap_tls_common_tunnel_prf_get_bytes(eap, true, "client EAP encryption",
|
||||
peap_state->key, 128);
|
||||
|
@ -244,6 +244,7 @@ static void eap_tls_tunnel_ready(const char *peer_identity, void *user_data)
|
||||
{
|
||||
struct eap_state *eap = user_data;
|
||||
struct eap_tls_state *eap_tls = eap_get_data(eap);
|
||||
bool resumed = l_tls_get_session_resumed(eap_tls->tunnel);
|
||||
|
||||
if (eap_tls->ca_cert && !peer_identity) {
|
||||
l_error("%s: TLS did not verify AP identity",
|
||||
@ -264,7 +265,7 @@ static void eap_tls_tunnel_ready(const char *peer_identity, void *user_data)
|
||||
if (!eap_tls->variant_ops->tunnel_ready)
|
||||
return;
|
||||
|
||||
if (!eap_tls->variant_ops->tunnel_ready(eap, peer_identity))
|
||||
if (!eap_tls->variant_ops->tunnel_ready(eap, peer_identity, resumed))
|
||||
l_tls_close(eap_tls->tunnel);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,8 @@ enum eap_tls_version {
|
||||
struct eap_tls_variant_ops {
|
||||
enum eap_tls_version version_max_supported;
|
||||
|
||||
bool (*tunnel_ready)(struct eap_state *eap, const char *peer_identity);
|
||||
bool (*tunnel_ready)(struct eap_state *eap, const char *peer_identity,
|
||||
bool resumed);
|
||||
bool (*tunnel_handle_request)(struct eap_state *eap,
|
||||
const uint8_t *data, size_t data_len);
|
||||
void (*reset)(void *variant_data);
|
||||
|
@ -35,7 +35,8 @@
|
||||
#include "src/eap-tls-common.h"
|
||||
|
||||
static bool eap_tls_tunnel_ready(struct eap_state *eap,
|
||||
const char *peer_identity)
|
||||
const char *peer_identity,
|
||||
bool resumed)
|
||||
{
|
||||
uint8_t msk_emsk[128];
|
||||
uint8_t iv[64];
|
||||
|
@ -902,7 +902,8 @@ static const struct phase2_method_ops phase2_eap_ops = {
|
||||
};
|
||||
|
||||
static bool eap_ttls_tunnel_ready(struct eap_state *eap,
|
||||
const char *peer_identity)
|
||||
const char *peer_identity,
|
||||
bool resumed)
|
||||
{
|
||||
struct phase2_method *phase2 = eap_tls_common_get_variant_data(eap);
|
||||
uint8_t msk_emsk[128];
|
||||
|
Loading…
Reference in New Issue
Block a user