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>
This commit is contained in:
parent
ebee8232d3
commit
6816182461
11 changed files with 113 additions and 18 deletions
|
@ -399,6 +399,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
|
||||
*
|
||||
|
@ -485,6 +494,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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue