aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2019-09-01 13:44:51 (GMT)
committerJouni Malinen <j@w1.fi>2019-09-01 14:19:43 (GMT)
commit681618246144875281d799f57af29a811a969489 (patch)
tree6543ace3f154b7dcf7c2657f055df287d233412a
parentebee8232d3db0c75254cba5c1823bf4eb146daa6 (diff)
downloadhostap-681618246144875281d799f57af29a811a969489.zip
hostap-681618246144875281d799f57af29a811a969489.tar.gz
hostap-681618246144875281d799f57af29a811a969489.tar.bz2
EAP-TEAP peer: Add support for machine credentials using certificates
This allows EAP-TLS to be used within an EAP-TEAP tunnel when there is an explicit request for machine credentials. The network profile parameters are otherwise same as the Phase 1 parameters, but each one uses a "machine_" prefix for the parameter name. Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--src/eap_peer/eap_config.h16
-rw-r--r--src/eap_peer/eap_fast.c2
-rw-r--r--src/eap_peer/eap_peap.c2
-rw-r--r--src/eap_peer/eap_teap.c19
-rw-r--r--src/eap_peer/eap_tls.c21
-rw-r--r--src/eap_peer/eap_tls_common.c23
-rw-r--r--src/eap_peer/eap_tls_common.h2
-rw-r--r--src/eap_peer/eap_ttls.c4
-rw-r--r--wpa_supplicant/config.c23
-rw-r--r--wpa_supplicant/config_file.c14
-rw-r--r--wpa_supplicant/wpa_supplicant.conf5
11 files changed, 113 insertions, 18 deletions
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index ae1de91..3238f74 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -400,6 +400,15 @@ struct eap_peer_config {
struct eap_peer_cert_config phase2_cert;
/**
+ * machine_cert - Certificate parameters for Phase 2 machine credential
+ *
+ * This is like cert, but used for Phase 2 (inside EAP-TEAP tunnel)
+ * authentication with machine credentials (while phase2_cert is used
+ * for user credentials).
+ */
+ struct eap_peer_cert_config machine_cert;
+
+ /**
* eap_methods - Allowed EAP methods
*
* (vendor=EAP_VENDOR_IETF,method=EAP_TYPE_NONE) terminated list of
@@ -486,6 +495,13 @@ struct eap_peer_config {
char *phase2;
/**
+ * machine_phase2 - Phase2 parameters for machine credentials
+ *
+ * See phase2 for more details.
+ */
+ char *machine_phase2;
+
+ /**
* pcsc - Parameters for PC/SC smartcard interface for USIM and GSM SIM
*
* This field is used to configure PC/SC smartcard interface.
diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c
index 61d0a6b..0ed4a2b 100644
--- a/src/eap_peer/eap_fast.c
+++ b/src/eap_peer/eap_fast.c
@@ -162,7 +162,7 @@ static void * eap_fast_init(struct eap_sm *sm)
if (eap_peer_select_phase2_methods(config, "auth=",
&data->phase2_types,
- &data->num_phase2_types) < 0) {
+ &data->num_phase2_types, 0) < 0) {
eap_fast_deinit(sm, data);
return NULL;
}
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 5ca6145..92b15ec 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -148,7 +148,7 @@ static void * eap_peap_init(struct eap_sm *sm)
if (eap_peer_select_phase2_methods(config, "auth=",
&data->phase2_types,
- &data->num_phase2_types) < 0) {
+ &data->num_phase2_types, 0) < 0) {
eap_peap_deinit(sm, data);
return NULL;
}
diff --git a/src/eap_peer/eap_teap.c b/src/eap_peer/eap_teap.c
index 1695833..06665b9 100644
--- a/src/eap_peer/eap_teap.c
+++ b/src/eap_peer/eap_teap.c
@@ -180,7 +180,7 @@ static void * eap_teap_init(struct eap_sm *sm)
if (eap_peer_select_phase2_methods(config, "auth=",
&data->phase2_types,
- &data->num_phase2_types) < 0) {
+ &data->num_phase2_types, 0) < 0) {
eap_teap_deinit(sm, data);
return NULL;
}
@@ -1296,6 +1296,23 @@ static int eap_teap_process_decrypted(struct eap_sm *sm,
} else if (tlv.identity_type) {
sm->use_machine_cred = 0;
}
+ if (tlv.identity_type) {
+ struct eap_peer_config *config = eap_get_config(sm);
+
+ os_free(data->phase2_types);
+ data->phase2_types = NULL;
+ data->num_phase2_types = 0;
+ if (config &&
+ eap_peer_select_phase2_methods(config, "auth=",
+ &data->phase2_types,
+ &data->num_phase2_types,
+ sm->use_machine_cred) < 0) {
+ wpa_printf(MSG_INFO,
+ "EAP-TEAP: Failed to update Phase 2 EAP types");
+ failed = 1;
+ goto done;
+ }
+ }
if (tlv.basic_auth_req) {
tmp = eap_teap_process_basic_auth_req(sm, data,
diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c
index 1bde997..d9771f6 100644
--- a/src/eap_peer/eap_tls.c
+++ b/src/eap_peer/eap_tls.c
@@ -33,11 +33,17 @@ static void * eap_tls_init(struct eap_sm *sm)
{
struct eap_tls_data *data;
struct eap_peer_config *config = eap_get_config(sm);
- if (config == NULL ||
- ((sm->init_phase2 ? config->phase2_cert.private_key :
- config->cert.private_key) == NULL &&
- (sm->init_phase2 ? config->phase2_cert.engine :
- config->cert.engine) == 0)) {
+ struct eap_peer_cert_config *cert;
+
+ if (!config)
+ return NULL;
+ if (!sm->init_phase2)
+ cert = &config->cert;
+ else if (sm->use_machine_cred)
+ cert = &config->machine_cert;
+ else
+ cert = &config->phase2_cert;
+ if (!cert->private_key && cert->engine == 0) {
wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured");
return NULL;
}
@@ -52,13 +58,12 @@ static void * eap_tls_init(struct eap_sm *sm)
if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TLS)) {
wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
eap_tls_deinit(sm, data);
- if (config->cert.engine) {
+ if (cert->engine) {
wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard "
"PIN");
eap_sm_request_pin(sm);
sm->ignore = TRUE;
- } else if (config->cert.private_key &&
- !config->cert.private_key_passwd) {
+ } else if (cert->private_key && !cert->private_key_passwd) {
wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private "
"key passphrase");
eap_sm_request_passphrase(sm);
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index a59c3a0..80e2d71 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -150,6 +150,14 @@ static void eap_tls_params_from_conf2(struct tls_connection_params *params,
}
+static void eap_tls_params_from_conf2m(struct tls_connection_params *params,
+ struct eap_peer_config *config)
+{
+ eap_tls_cert_params_from_conf(params, &config->machine_cert);
+ eap_tls_params_flags(params, config->machine_phase2);
+}
+
+
static int eap_tls_params_from_conf(struct eap_sm *sm,
struct eap_ssl_data *data,
struct tls_connection_params *params,
@@ -196,7 +204,10 @@ static int eap_tls_params_from_conf(struct eap_sm *sm,
*/
params->flags |= TLS_CONN_DISABLE_TLSv1_3;
}
- if (phase2) {
+ if (phase2 && sm->use_machine_cred) {
+ wpa_printf(MSG_DEBUG, "TLS: using machine config options");
+ eap_tls_params_from_conf2m(params, config);
+ } else if (phase2) {
wpa_printf(MSG_DEBUG, "TLS: using phase2 config options");
eap_tls_params_from_conf2(params, config);
} else {
@@ -1084,17 +1095,21 @@ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
int eap_peer_select_phase2_methods(struct eap_peer_config *config,
const char *prefix,
struct eap_method_type **types,
- size_t *num_types)
+ size_t *num_types, int use_machine_cred)
{
char *start, *pos, *buf;
struct eap_method_type *methods = NULL, *_methods;
u32 method;
size_t num_methods = 0, prefix_len;
+ const char *phase2;
- if (config == NULL || config->phase2 == NULL)
+ if (!config)
+ goto get_defaults;
+ phase2 = use_machine_cred ? config->machine_phase2 : config->phase2;
+ if (!phase2)
goto get_defaults;
- start = buf = os_strdup(config->phase2);
+ start = buf = os_strdup(phase2);
if (buf == NULL)
return -1;
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index e3c9e03..183b7de 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -133,7 +133,7 @@ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
int eap_peer_select_phase2_methods(struct eap_peer_config *config,
const char *prefix,
struct eap_method_type **types,
- size_t *num_types);
+ size_t *num_types, int use_machine_cred);
int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types,
struct eap_hdr *hdr, struct wpabuf **resp);
diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c
index bed4094..662676f 100644
--- a/src/eap_peer/eap_ttls.c
+++ b/src/eap_peer/eap_ttls.c
@@ -146,8 +146,8 @@ static void * eap_ttls_init(struct eap_sm *sm)
if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {
if (eap_peer_select_phase2_methods(config, "autheap=",
&data->phase2_eap_types,
- &data->num_phase2_eap_types)
- < 0) {
+ &data->num_phase2_eap_types,
+ 0) < 0) {
eap_ttls_deinit(sm, data);
return NULL;
}
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 067585b..cc197ae 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2415,6 +2415,7 @@ static const struct parse_data ssid_fields[] = {
{ STRe(domain_match2, phase2_cert.domain_match) },
{ STRe(phase1, phase1) },
{ STRe(phase2, phase2) },
+ { STRe(machine_phase2, machine_phase2) },
{ STRe(pcsc, pcsc) },
{ STR_KEYe(pin, cert.pin) },
{ STRe(engine_id, cert.engine_id) },
@@ -2428,6 +2429,26 @@ static const struct parse_data ssid_fields[] = {
{ STRe(ca_cert_id2, phase2_cert.ca_cert_id) },
{ INTe(engine, cert.engine) },
{ INTe(engine2, phase2_cert.engine) },
+ { STRe(machine_ca_cert, machine_cert.ca_cert) },
+ { STRe(machine_ca_path, machine_cert.ca_path) },
+ { STRe(machine_client_cert, machine_cert.client_cert) },
+ { STRe(machine_private_key, machine_cert.private_key) },
+ { STR_KEYe(machine_private_key_passwd,
+ machine_cert.private_key_passwd) },
+ { STRe(machine_dh_file, machine_cert.dh_file) },
+ { STRe(machine_subject_match, machine_cert.subject_match) },
+ { STRe(machine_check_cert_subject, machine_cert.check_cert_subject) },
+ { STRe(machine_altsubject_match, machine_cert.altsubject_match) },
+ { STRe(machine_domain_suffix_match,
+ machine_cert.domain_suffix_match) },
+ { STRe(machine_domain_match, machine_cert.domain_match) },
+ { STR_KEYe(machine_pin, machine_cert.pin) },
+ { STRe(machine_engine_id, machine_cert.engine_id) },
+ { STRe(machine_key_id, machine_cert.key_id) },
+ { STRe(machine_cert_id, machine_cert.cert_id) },
+ { STRe(machine_ca_cert_id, machine_cert.ca_cert_id) },
+ { INTe(machine_engine, machine_cert.engine) },
+ { INTe(machine_ocsp, machine_cert.ocsp) },
{ INT(eapol_flags) },
{ INTe(sim_num, sim_num) },
{ STRe(openssl_ciphers, openssl_ciphers) },
@@ -2689,8 +2710,10 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
bin_clear_free(eap->machine_password, eap->machine_password_len);
eap_peer_config_free_cert(&eap->cert);
eap_peer_config_free_cert(&eap->phase2_cert);
+ eap_peer_config_free_cert(&eap->machine_cert);
os_free(eap->phase1);
os_free(eap->phase2);
+ os_free(eap->machine_phase2);
os_free(eap->pcsc);
os_free(eap->otp);
os_free(eap->pending_req_otp);
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index c47300b..a1f8b7f 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -799,8 +799,20 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
STR(altsubject_match2);
STR(domain_suffix_match2);
STR(domain_match2);
+ STR(machine_ca_cert);
+ STR(machine_ca_path);
+ STR(machine_client_cert);
+ STR(machine_private_key);
+ STR(machine_private_key_passwd);
+ STR(machine_dh_file);
+ STR(machine_subject_match);
+ STR(machine_check_cert_subject);
+ STR(machine_altsubject_match);
+ STR(machine_domain_suffix_match);
+ STR(machine_domain_match);
STR(phase1);
STR(phase2);
+ STR(machine_phase2);
STR(pcsc);
STR(pin);
STR(engine_id);
@@ -814,6 +826,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
STR(ca_cert2_id);
INTe(engine, cert.engine);
INTe(engine2, phase2_cert.engine);
+ INTe(machine_engine, machine_cert.engine);
INT_DEF(eapol_flags, DEFAULT_EAPOL_FLAGS);
STR(openssl_ciphers);
INTe(erp, erp);
@@ -828,6 +841,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
INT_DEFe(fragment_size, fragment_size, DEFAULT_FRAGMENT_SIZE);
INTe(ocsp, cert.ocsp);
INTe(ocsp2, phase2_cert.ocsp);
+ INTe(machine_ocsp, machine_cert.ocsp);
INT_DEFe(sim_num, sim_num, DEFAULT_USER_SELECTED_SIM);
#endif /* IEEE8021X_EAPOL */
INT(mode);
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index f7a3652..26df78a 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1325,6 +1325,11 @@ fast_reauth=1
# domain_suffix_match for more details.
# ocsp2: See ocsp for more details.
#
+# Separate machine credentials can be configured for EAP-TEAP Phase 2 with
+# "machine_" prefix (e.g., "machine_identity") in the configuration parameters.
+# See the parameters without that prefix for more details on the meaning and
+# format of each such parameter.
+#
# fragment_size: Maximum EAP fragment size in bytes (default 1398).
# This value limits the fragment size for EAP methods that support
# fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set