3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-26 10:39:23 +01:00

eap-tls-common: allow for EAP_TYPE_EXPANDED in TLS

The Hotspot 2.0 spec introduces 'Anonymous EAP-TLS' as a new EAP method
to be used with OSEN/Hotspot. The protocol details of this aren't
relevant to this patch, but one major difference is that it uses the
expanded EAP type rather than the TLS type. Since the common TLS code
was written with only EAP_TYPE_TLS in mind the vendor ID/type cause the
EAP packet to be malformed when using the expanded EAP type.

To handle this the common TLS code now checks the EAP type, and if its
expanded we shift the payload 7 bytes further to account for the extra
header data.
This commit is contained in:
James Prestwood 2019-06-05 14:59:58 -07:00 committed by Denis Kenzior
parent e0c9b68467
commit 233804d7fc

View File

@ -289,19 +289,26 @@ static void eap_tls_send_fragment(struct eap_state *eap)
uint8_t buf[mtu]; uint8_t buf[mtu];
size_t len = eap_tls->tx_pdu_buf->len - eap_tls->tx_frag_offset; size_t len = eap_tls->tx_pdu_buf->len - eap_tls->tx_frag_offset;
size_t header_len = EAP_TLS_HEADER_LEN; size_t header_len = EAP_TLS_HEADER_LEN;
uint8_t position = 0;
buf[EAP_TLS_HEADER_OCTET_FLAGS] = eap_tls->version_negotiated; if (eap_get_method_type(eap) == EAP_TYPE_EXPANDED) {
header_len += 7;
position += 7;
}
if (len > mtu - EAP_TLS_HEADER_LEN) { buf[EAP_TLS_HEADER_OCTET_FLAGS + position] =
len = mtu - EAP_TLS_HEADER_LEN; eap_tls->version_negotiated;
buf[EAP_TLS_HEADER_OCTET_FLAGS] |= EAP_TLS_FLAG_M;
if (len > mtu - EAP_TLS_HEADER_LEN - position) {
len = mtu - EAP_TLS_HEADER_LEN - position;
buf[EAP_TLS_HEADER_OCTET_FLAGS + position] |= EAP_TLS_FLAG_M;
eap_tls->expecting_frag_ack = true; eap_tls->expecting_frag_ack = true;
} }
if (!eap_tls->tx_frag_offset) { if (!eap_tls->tx_frag_offset) {
buf[EAP_TLS_HEADER_OCTET_FLAGS] |= EAP_TLS_FLAG_L; buf[EAP_TLS_HEADER_OCTET_FLAGS + position] |= EAP_TLS_FLAG_L;
l_put_be32(eap_tls->tx_pdu_buf->len, l_put_be32(eap_tls->tx_pdu_buf->len,
&buf[EAP_TLS_HEADER_OCTET_FRAG_LEN]); &buf[EAP_TLS_HEADER_OCTET_FRAG_LEN + position]);
len -= 4; len -= 4;
header_len += 4; header_len += 4;
} }
@ -320,10 +327,20 @@ static void eap_tls_send_response(struct eap_state *eap,
size_t msg_len = EAP_TLS_HEADER_LEN + pdu_len; size_t msg_len = EAP_TLS_HEADER_LEN + pdu_len;
if (msg_len <= eap_get_mtu(eap)) { if (msg_len <= eap_get_mtu(eap)) {
uint8_t *buf = l_malloc(msg_len); uint8_t *buf;
uint8_t extra = 0;
buf[EAP_TLS_HEADER_OCTET_FLAGS] = eap_tls->version_negotiated; if (eap_get_method_type(eap) == EAP_TYPE_EXPANDED) {
memcpy(buf + EAP_TLS_HEADER_LEN, pdu, pdu_len); extra += 7;
msg_len += 7;
}
buf = l_malloc(msg_len);
buf[EAP_TLS_HEADER_OCTET_FLAGS + extra] =
eap_tls->version_negotiated;
memcpy(buf + EAP_TLS_HEADER_LEN + extra, pdu, pdu_len);
eap_send_response(eap, eap_get_method_type(eap), buf, msg_len); eap_send_response(eap, eap_get_method_type(eap), buf, msg_len);
l_free(buf); l_free(buf);
@ -337,12 +354,16 @@ static void eap_tls_send_response(struct eap_state *eap,
void eap_tls_common_send_empty_response(struct eap_state *eap) void eap_tls_common_send_empty_response(struct eap_state *eap)
{ {
struct eap_tls_state *eap_tls = eap_get_data(eap); struct eap_tls_state *eap_tls = eap_get_data(eap);
uint8_t buf[EAP_TLS_HEADER_LEN]; uint8_t buf[EAP_TLS_HEADER_LEN + 7];
uint8_t position = 0;
buf[EAP_TLS_HEADER_OCTET_FLAGS] = eap_tls->version_negotiated; if (eap_get_method_type(eap) == EAP_TYPE_EXPANDED)
position += 7;
buf[EAP_TLS_HEADER_OCTET_FLAGS + position] = eap_tls->version_negotiated;
eap_send_response(eap, eap_get_method_type(eap), buf, eap_send_response(eap, eap_get_method_type(eap), buf,
EAP_TLS_HEADER_LEN); EAP_TLS_HEADER_LEN + position);
} }
static int eap_tls_init_request_assembly(struct eap_state *eap, static int eap_tls_init_request_assembly(struct eap_state *eap,