diff options
Diffstat (limited to 'src/eap_server/eap_server_tls_common.c')
-rw-r--r-- | src/eap_server/eap_server_tls_common.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c index 9efb5b2938538..56916c45ac69a 100644 --- a/src/eap_server/eap_server_tls_common.c +++ b/src/eap_server/eap_server_tls_common.c @@ -25,14 +25,32 @@ struct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, code, identifier); + else if (type == EAP_WFA_UNAUTH_TLS_TYPE) + return eap_msg_alloc(EAP_VENDOR_WFA_NEW, + EAP_VENDOR_WFA_UNAUTH_TLS, payload_len, + code, identifier); return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, identifier); } +#ifdef CONFIG_TLS_INTERNAL +static void eap_server_tls_log_cb(void *ctx, const char *msg) +{ + struct eap_sm *sm = ctx; + eap_log_msg(sm, "TLS: %s", msg); +} +#endif /* CONFIG_TLS_INTERNAL */ + + int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, int verify_peer) { + if (sm->ssl_ctx == NULL) { + wpa_printf(MSG_ERROR, "TLS context not initialized - cannot use TLS-based EAP method"); + return -1; + } + data->eap = sm; data->phase2 = sm->init_phase2; @@ -43,6 +61,13 @@ int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, return -1; } +#ifdef CONFIG_TLS_INTERNAL + tls_connection_set_log_cb(data->conn, eap_server_tls_log_cb, sm); +#ifdef CONFIG_TESTING_OPTIONS + tls_connection_set_test_flags(data->conn, sm->tls_test_flags); +#endif /* CONFIG_TESTING_OPTIONS */ +#endif /* CONFIG_TLS_INTERNAL */ + if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) { wpa_printf(MSG_INFO, "SSL: Failed to configure verification " "of TLS peer certificate"); @@ -115,6 +140,47 @@ fail: } +/** + * eap_server_tls_derive_session_id - Derive a Session-Id based on TLS data + * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() + * @data: Data for TLS processing + * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) + * @len: Pointer to length of the session ID generated + * Returns: Pointer to allocated Session-Id on success or %NULL on failure + * + * This function derive the Session-Id based on the TLS session data + * (client/server random and method type). + * + * The caller is responsible for freeing the returned buffer. + */ +u8 * eap_server_tls_derive_session_id(struct eap_sm *sm, + struct eap_ssl_data *data, u8 eap_type, + size_t *len) +{ + struct tls_keys keys; + u8 *out; + + if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) + return NULL; + + if (keys.client_random == NULL || keys.server_random == NULL) + return NULL; + + *len = 1 + keys.client_random_len + keys.server_random_len; + out = os_malloc(*len); + if (out == NULL) + return NULL; + + /* Session-Id = EAP type || client.random || server.random */ + out[0] = eap_type; + os_memcpy(out + 1, keys.client_random, keys.client_random_len); + os_memcpy(out + 1 + keys.client_random_len, keys.server_random, + keys.server_random_len); + + return out; +} + + struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, int eap_type, int version, u8 id) { @@ -388,6 +454,10 @@ int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, EAP_VENDOR_TYPE_UNAUTH_TLS, respData, &left); + else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) + pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, + EAP_VENDOR_WFA_UNAUTH_TLS, respData, + &left); else pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, &left); |