summaryrefslogtreecommitdiff
path: root/src/eap_server/eap_server_tls_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eap_server/eap_server_tls_common.c')
-rw-r--r--src/eap_server/eap_server_tls_common.c70
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);