/* Maximum supported PEAP version
* 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt
* 1 = draft-josefsson-ppext-eap-tls-eap-05.txt
- * 2 = draft-josefsson-ppext-eap-tls-eap-10.txt
*/
#define EAP_PEAP_VERSION 1
len[1] = 1;
tlv_type = EAP_TLV_CRYPTO_BINDING_TLV;
- if (data->peap_version >= 2)
- tlv_type |= EAP_TLV_TYPE_MANDATORY;
wpabuf_put_be16(buf, tlv_type);
wpabuf_put_be16(buf, 56);
}
-static struct wpabuf * eap_peapv2_tlv_eap_payload(struct wpabuf *buf)
-{
- struct wpabuf *e;
- struct eap_tlv_hdr *tlv;
-
- if (buf == NULL)
- return NULL;
-
- /* Encapsulate EAP packet in EAP-Payload TLV */
- wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Add EAP-Payload TLV");
- e = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
- if (e == NULL) {
- wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Failed to allocate memory "
- "for TLV encapsulation");
- wpabuf_free(buf);
- return NULL;
- }
- tlv = wpabuf_put(e, sizeof(*tlv));
- tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
- EAP_TLV_EAP_PAYLOAD_TLV);
- tlv->length = host_to_be16(wpabuf_len(buf));
- wpabuf_put_buf(e, buf);
- wpabuf_free(buf);
- return e;
-}
-
-
static int eap_peap_phase2_request(struct eap_sm *sm,
struct eap_peap_data *data,
struct eap_method_ret *ret,
in_decrypted = nmsg;
}
- if (data->peap_version >= 2) {
- struct eap_tlv_hdr *tlv;
- struct wpabuf *nmsg;
-
- if (wpabuf_len(in_decrypted) < sizeof(*tlv) + sizeof(*hdr)) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Too short Phase 2 "
- "EAP TLV");
- wpabuf_free(in_decrypted);
- return 0;
- }
- tlv = wpabuf_mhead(in_decrypted);
- if ((be_to_host16(tlv->tlv_type) & 0x3fff) !=
- EAP_TLV_EAP_PAYLOAD_TLV) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Not an EAP TLV");
- wpabuf_free(in_decrypted);
- return 0;
- }
- if (sizeof(*tlv) + be_to_host16(tlv->length) >
- wpabuf_len(in_decrypted)) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Invalid EAP TLV "
- "length");
- wpabuf_free(in_decrypted);
- return 0;
- }
- hdr = (struct eap_hdr *) (tlv + 1);
- if (be_to_host16(hdr->length) > be_to_host16(tlv->length)) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: No room for full "
- "EAP packet in EAP TLV");
- wpabuf_free(in_decrypted);
- return 0;
- }
-
- nmsg = wpabuf_alloc(be_to_host16(hdr->length));
- if (nmsg == NULL) {
- wpabuf_free(in_decrypted);
- return 0;
- }
-
- wpabuf_put_data(nmsg, hdr, be_to_host16(hdr->length));
- wpabuf_free(in_decrypted);
- in_decrypted = nmsg;
- }
-
hdr = wpabuf_mhead(in_decrypted);
if (wpabuf_len(in_decrypted) < sizeof(*hdr)) {
wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
wpa_hexdump_buf_key(MSG_DEBUG,
"EAP-PEAP: Encrypting Phase 2 data", resp);
/* PEAP version changes */
- if (data->peap_version >= 2) {
- resp = eap_peapv2_tlv_eap_payload(resp);
- if (resp == NULL)
- return -1;
- }
if (wpabuf_len(resp) >= 5 &&
wpabuf_head_u8(resp)[0] == EAP_CODE_RESPONSE &&
eap_get_type(resp) == EAP_TYPE_TLV)
* label, "client EAP encryption", instead. Use the old
* label by default, but allow it to be configured with
* phase1 parameter peaplabel=1. */
- if (data->peap_version > 1 || data->force_new_label)
+ if (data->force_new_label)
label = "client PEAP encryption";
else
label = "client EAP encryption";
/* Maximum supported PEAP version
* 0 = Microsoft's PEAP version 0; draft-kamath-pppext-peapv0-00.txt
* 1 = draft-josefsson-ppext-eap-tls-eap-05.txt
- * 2 = draft-josefsson-ppext-eap-tls-eap-10.txt
*/
#define EAP_PEAP_VERSION 1
}
-static struct wpabuf * eap_peapv2_tlv_eap_payload(struct wpabuf *buf)
-{
- struct wpabuf *e;
- struct eap_tlv_hdr *tlv;
-
- if (buf == NULL)
- return NULL;
-
- /* Encapsulate EAP packet in EAP-Payload TLV */
- wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Add EAP-Payload TLV");
- e = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
- if (e == NULL) {
- wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Failed to allocate memory "
- "for TLV encapsulation");
- wpabuf_free(buf);
- return NULL;
- }
- tlv = wpabuf_put(e, sizeof(*tlv));
- tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
- EAP_TLV_EAP_PAYLOAD_TLV);
- tlv->length = host_to_be16(wpabuf_len(buf));
- wpabuf_put_buf(e, buf);
- wpabuf_free(buf);
- return e;
-}
-
-
static void eap_peap_req_success(struct eap_sm *sm,
struct eap_peap_data *data)
{
return NULL;
}
buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
- if (data->peap_version >= 2 && buf)
- buf = eap_peapv2_tlv_eap_payload(buf);
if (buf == NULL)
return NULL;
len[1] = 1;
tlv_type = EAP_TLV_CRYPTO_BINDING_TLV;
- if (data->peap_version >= 2)
- tlv_type |= EAP_TLV_TYPE_MANDATORY;
wpabuf_put_be16(buf, tlv_type);
wpabuf_put_be16(buf, 56);
return eap_peap_build_start(sm, data, id);
case PHASE1:
case PHASE1_ID2:
- if (data->peap_version < 2 &&
- tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
+ if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, "
"starting Phase2");
eap_peap_state(data, PHASE2_START);
wpabuf_free(in_decrypted);
in_decrypted = nbuf;
- } else if (data->peap_version >= 2) {
- struct eap_tlv_hdr *tlv;
- struct wpabuf *nmsg;
-
- if (wpabuf_len(in_decrypted) < sizeof(*tlv) + sizeof(*hdr)) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Too short Phase 2 "
- "EAP TLV");
- wpabuf_free(in_decrypted);
- return;
- }
- tlv = wpabuf_mhead(in_decrypted);
- if ((be_to_host16(tlv->tlv_type) & EAP_TLV_TYPE_MASK) !=
- EAP_TLV_EAP_PAYLOAD_TLV) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Not an EAP TLV");
- wpabuf_free(in_decrypted);
- return;
- }
- if (sizeof(*tlv) + be_to_host16(tlv->length) >
- wpabuf_len(in_decrypted)) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Invalid EAP TLV "
- "length");
- wpabuf_free(in_decrypted);
- return;
- }
- hdr = (struct eap_hdr *) (tlv + 1);
- if (be_to_host16(hdr->length) > be_to_host16(tlv->length)) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: No room for full "
- "EAP packet in EAP TLV");
- wpabuf_free(in_decrypted);
- return;
- }
-
- nmsg = wpabuf_alloc(be_to_host16(hdr->length));
- if (nmsg == NULL) {
- wpabuf_free(in_decrypted);
- return;
- }
-
- wpabuf_put_data(nmsg, hdr, be_to_host16(hdr->length));
- wpabuf_free(in_decrypted);
- in_decrypted = nmsg;
}
hdr = wpabuf_head(in_decrypted);
}
-static int eap_peapv2_start_phase2(struct eap_sm *sm,
- struct eap_peap_data *data)
-{
- struct wpabuf *buf, *buf2;
-
- wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Phase1 done, include first Phase2 "
- "payload in the same message");
- eap_peap_state(data, PHASE1_ID2);
- if (eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY))
- return -1;
-
- /* TODO: which Id to use here? */
- buf = data->phase2_method->buildReq(sm, data->phase2_priv, 6);
- if (buf == NULL)
- return -1;
-
- buf2 = eap_peapv2_tlv_eap_payload(buf);
- if (buf2 == NULL)
- return -1;
-
- wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAPv2: Identity Request", buf2);
-
- buf = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
- buf2);
- wpabuf_free(buf2);
-
- if (buf == NULL) {
- wpa_printf(MSG_INFO, "EAP-PEAPv2: Failed to encrypt Phase 2 "
- "data");
- return -1;
- }
-
- wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAPv2: Encrypted Identity Request",
- buf);
-
- /* Append TLS data into the pending buffer after the Server Finished */
- if (wpabuf_resize(&data->ssl.tls_out, wpabuf_len(buf)) < 0) {
- wpabuf_free(buf);
- return -1;
- }
- wpabuf_put_buf(data->ssl.tls_out, buf);
- wpabuf_free(buf);
-
- return 0;
-}
-
-
static int eap_peap_process_version(struct eap_sm *sm, void *priv,
int peer_version)
{
eap_peap_state(data, FAILURE);
break;
}
-
- if (data->peap_version >= 2 &&
- tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
- if (eap_peapv2_start_phase2(sm, data)) {
- eap_peap_state(data, FAILURE);
- break;
- }
- }
break;
case PHASE2_START:
eap_peap_state(data, PHASE2_ID);