mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-07 04:34:04 -05:00
EAP peer: Add framework for external SIM/USIM processing
The new configuration parameter external_sim=<0/1> can now be used to configure wpa_supplicant to use external SIM/USIM processing (e.g., GSM authentication for EAP-SIM or UMTS authentication for EAP-AKA). The requests and responses for such operations are sent over the ctrl_iface CTRL-REQ-SIM and CTRL-RSP-SIM commands similarly to the existing password query mechanism. Changes to the EAP methods to use this new mechanism will be added in separate commits. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
7e8bc7d6fb
commit
a5d44ac083
@ -312,6 +312,7 @@ enum wpa_ctrl_req_type {
|
|||||||
WPA_CTRL_REQ_EAP_PIN,
|
WPA_CTRL_REQ_EAP_PIN,
|
||||||
WPA_CTRL_REQ_EAP_OTP,
|
WPA_CTRL_REQ_EAP_OTP,
|
||||||
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
||||||
|
WPA_CTRL_REQ_SIM,
|
||||||
NUM_WPA_CTRL_REQS
|
NUM_WPA_CTRL_REQS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1638,7 +1638,8 @@ static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
|
|||||||
const char *msg, size_t msglen)
|
const char *msg, size_t msglen)
|
||||||
{
|
{
|
||||||
struct eap_peer_config *config;
|
struct eap_peer_config *config;
|
||||||
char *txt = NULL, *tmp;
|
const char *txt = NULL;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
if (sm == NULL)
|
if (sm == NULL)
|
||||||
return;
|
return;
|
||||||
@ -1681,6 +1682,9 @@ static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
|
|||||||
case WPA_CTRL_REQ_EAP_PASSPHRASE:
|
case WPA_CTRL_REQ_EAP_PASSPHRASE:
|
||||||
config->pending_req_passphrase++;
|
config->pending_req_passphrase++;
|
||||||
break;
|
break;
|
||||||
|
case WPA_CTRL_REQ_SIM:
|
||||||
|
txt = msg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1791,6 +1795,17 @@ void eap_sm_request_passphrase(struct eap_sm *sm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eap_sm_request_sim - Request external SIM processing
|
||||||
|
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||||
|
* @req: EAP method specific request
|
||||||
|
*/
|
||||||
|
void eap_sm_request_sim(struct eap_sm *sm, const char *req)
|
||||||
|
{
|
||||||
|
eap_sm_request(sm, WPA_CTRL_REQ_SIM, req, os_strlen(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eap_sm_notify_ctrl_attached - Notification of attached monitor
|
* eap_sm_notify_ctrl_attached - Notification of attached monitor
|
||||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||||
@ -2304,6 +2319,17 @@ void eap_set_force_disabled(struct eap_sm *sm, int disabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eap_set_external_sim - Set external_sim flag
|
||||||
|
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||||
|
* @external_sim: Whether external SIM/USIM processing is used
|
||||||
|
*/
|
||||||
|
void eap_set_external_sim(struct eap_sm *sm, int external_sim)
|
||||||
|
{
|
||||||
|
sm->external_sim = external_sim;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eap_notify_pending - Notify that EAP method is ready to re-process a request
|
* eap_notify_pending - Notify that EAP method is ready to re-process a request
|
||||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||||
|
@ -296,6 +296,7 @@ void eap_sm_request_new_password(struct eap_sm *sm);
|
|||||||
void eap_sm_request_pin(struct eap_sm *sm);
|
void eap_sm_request_pin(struct eap_sm *sm);
|
||||||
void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len);
|
void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len);
|
||||||
void eap_sm_request_passphrase(struct eap_sm *sm);
|
void eap_sm_request_passphrase(struct eap_sm *sm);
|
||||||
|
void eap_sm_request_sim(struct eap_sm *sm, const char *req);
|
||||||
void eap_sm_notify_ctrl_attached(struct eap_sm *sm);
|
void eap_sm_notify_ctrl_attached(struct eap_sm *sm);
|
||||||
u32 eap_get_phase2_type(const char *name, int *vendor);
|
u32 eap_get_phase2_type(const char *name, int *vendor);
|
||||||
struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
|
struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
|
||||||
@ -303,6 +304,7 @@ struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
|
|||||||
void eap_set_fast_reauth(struct eap_sm *sm, int enabled);
|
void eap_set_fast_reauth(struct eap_sm *sm, int enabled);
|
||||||
void eap_set_workaround(struct eap_sm *sm, unsigned int workaround);
|
void eap_set_workaround(struct eap_sm *sm, unsigned int workaround);
|
||||||
void eap_set_force_disabled(struct eap_sm *sm, int disabled);
|
void eap_set_force_disabled(struct eap_sm *sm, int disabled);
|
||||||
|
void eap_set_external_sim(struct eap_sm *sm, int external_sim);
|
||||||
int eap_key_available(struct eap_sm *sm);
|
int eap_key_available(struct eap_sm *sm);
|
||||||
void eap_notify_success(struct eap_sm *sm);
|
void eap_notify_success(struct eap_sm *sm);
|
||||||
void eap_notify_lower_layer_success(struct eap_sm *sm);
|
void eap_notify_lower_layer_success(struct eap_sm *sm);
|
||||||
|
@ -669,6 +669,15 @@ struct eap_peer_config {
|
|||||||
* 2 = require valid OCSP stapling response
|
* 2 = require valid OCSP stapling response
|
||||||
*/
|
*/
|
||||||
int ocsp;
|
int ocsp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* external_sim_resp - Response from external SIM processing
|
||||||
|
*
|
||||||
|
* This field should not be set in configuration step. It is only used
|
||||||
|
* internally when control interface is used to request external
|
||||||
|
* SIM/USIM processing.
|
||||||
|
*/
|
||||||
|
char *external_sim_resp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,6 +348,8 @@ struct eap_sm {
|
|||||||
|
|
||||||
struct ext_password_data *ext_pw;
|
struct ext_password_data *ext_pw;
|
||||||
struct wpabuf *ext_pw_buf;
|
struct wpabuf *ext_pw_buf;
|
||||||
|
|
||||||
|
int external_sim;
|
||||||
};
|
};
|
||||||
|
|
||||||
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
|
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
|
||||||
|
@ -1479,6 +1479,7 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
|
|||||||
eap_set_fast_reauth(sm->eap, conf->fast_reauth);
|
eap_set_fast_reauth(sm->eap, conf->fast_reauth);
|
||||||
eap_set_workaround(sm->eap, conf->workaround);
|
eap_set_workaround(sm->eap, conf->workaround);
|
||||||
eap_set_force_disabled(sm->eap, conf->eap_disabled);
|
eap_set_force_disabled(sm->eap, conf->eap_disabled);
|
||||||
|
eap_set_external_sim(sm->eap, conf->external_sim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,11 @@ struct eapol_config {
|
|||||||
* eap_disabled - Whether EAP is disabled
|
* eap_disabled - Whether EAP is disabled
|
||||||
*/
|
*/
|
||||||
int eap_disabled;
|
int eap_disabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* external_sim - Use external processing for SIM/USIM operations
|
||||||
|
*/
|
||||||
|
int external_sim;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eapol_sm;
|
struct eapol_sm;
|
||||||
|
@ -284,6 +284,17 @@ OK
|
|||||||
Note: the return value of add_cred is used as the first argument to
|
Note: the return value of add_cred is used as the first argument to
|
||||||
the following set_cred commands.
|
the following set_cred commands.
|
||||||
|
|
||||||
|
Add a SIM credential using a external SIM/USIM processing:
|
||||||
|
|
||||||
|
> set external_sim 1
|
||||||
|
OK
|
||||||
|
> add_cred
|
||||||
|
1
|
||||||
|
> set_cred 1 imsi "23456-0000000000"
|
||||||
|
OK
|
||||||
|
> set_cred 1 eap SIM
|
||||||
|
OK
|
||||||
|
|
||||||
|
|
||||||
Add a WPA2-Enterprise network:
|
Add a WPA2-Enterprise network:
|
||||||
|
|
||||||
|
@ -1815,6 +1815,7 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
|
|||||||
os_free(eap->pending_req_otp);
|
os_free(eap->pending_req_otp);
|
||||||
os_free(eap->pac_file);
|
os_free(eap->pac_file);
|
||||||
os_free(eap->new_password);
|
os_free(eap->new_password);
|
||||||
|
os_free(eap->external_sim_resp);
|
||||||
}
|
}
|
||||||
#endif /* IEEE8021X_EAPOL */
|
#endif /* IEEE8021X_EAPOL */
|
||||||
|
|
||||||
@ -3194,6 +3195,7 @@ static const struct global_parse_data global_fields[] = {
|
|||||||
{ STR(pkcs11_module_path), 0 },
|
{ STR(pkcs11_module_path), 0 },
|
||||||
{ STR(pcsc_reader), 0 },
|
{ STR(pcsc_reader), 0 },
|
||||||
{ STR(pcsc_pin), 0 },
|
{ STR(pcsc_pin), 0 },
|
||||||
|
{ INT(external_sim), 0 },
|
||||||
{ STR(driver_param), 0 },
|
{ STR(driver_param), 0 },
|
||||||
{ INT(dot11RSNAConfigPMKLifetime), 0 },
|
{ INT(dot11RSNAConfigPMKLifetime), 0 },
|
||||||
{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
|
{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
|
||||||
|
@ -452,6 +452,11 @@ struct wpa_config {
|
|||||||
*/
|
*/
|
||||||
char *pcsc_pin;
|
char *pcsc_pin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* external_sim - Use external processing for SIM/USIM operations
|
||||||
|
*/
|
||||||
|
int external_sim;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* driver_param - Driver interface parameters
|
* driver_param - Driver interface parameters
|
||||||
*
|
*
|
||||||
|
@ -1055,6 +1055,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
|||||||
if (config->sched_scan_interval)
|
if (config->sched_scan_interval)
|
||||||
fprintf(f, "sched_scan_interval=%u\n",
|
fprintf(f, "sched_scan_interval=%u\n",
|
||||||
config->sched_scan_interval);
|
config->sched_scan_interval);
|
||||||
|
|
||||||
|
if (config->external_sim)
|
||||||
|
fprintf(f, "external_sim=%d\n", config->external_sim);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NO_CONFIG_WRITE */
|
#endif /* CONFIG_NO_CONFIG_WRITE */
|
||||||
|
@ -623,6 +623,9 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
|
|||||||
wpa_config_write_reg_dword(hk, TEXT("okc"), config->okc, 0);
|
wpa_config_write_reg_dword(hk, TEXT("okc"), config->okc, 0);
|
||||||
wpa_config_write_reg_dword(hk, TEXT("pmf"), config->pmf, 0);
|
wpa_config_write_reg_dword(hk, TEXT("pmf"), config->pmf, 0);
|
||||||
|
|
||||||
|
wpa_config_write_reg_dword(hk, TEXT("external_sim"),
|
||||||
|
config->external_sim, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +551,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
|
|||||||
eapol_conf.required_keys = 0;
|
eapol_conf.required_keys = 0;
|
||||||
eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
|
eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
|
||||||
eapol_conf.workaround = ssid->eap_workaround;
|
eapol_conf.workaround = ssid->eap_workaround;
|
||||||
|
eapol_conf.external_sim = wpa_s->conf->external_sim;
|
||||||
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
|
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
|
||||||
eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
|
eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
|
||||||
|
|
||||||
|
@ -275,7 +275,8 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
|
|||||||
#ifdef PCSC_FUNCS
|
#ifdef PCSC_FUNCS
|
||||||
int aka = 0, sim = 0;
|
int aka = 0, sim = 0;
|
||||||
|
|
||||||
if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL)
|
if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL ||
|
||||||
|
wpa_s->conf->external_sim)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ssid->eap.eap_methods == NULL) {
|
if (ssid->eap.eap_methods == NULL) {
|
||||||
|
@ -1407,7 +1407,8 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
|
|||||||
#endif /* CONFIG_EAP_PROXY */
|
#endif /* CONFIG_EAP_PROXY */
|
||||||
|
|
||||||
if (cred->imsi == NULL || !cred->imsi[0] ||
|
if (cred->imsi == NULL || !cred->imsi[0] ||
|
||||||
cred->milenage == NULL || !cred->milenage[0])
|
(!wpa_s->conf->external_sim &&
|
||||||
|
(cred->milenage == NULL || !cred->milenage[0])))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sep = os_strchr(cred->imsi, '-');
|
sep = os_strchr(cred->imsi, '-');
|
||||||
|
@ -625,7 +625,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
|
|||||||
"wps_nfc_dev_pw", "ext_password_backend",
|
"wps_nfc_dev_pw", "ext_password_backend",
|
||||||
"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
|
"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
|
||||||
"sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
|
"sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
|
||||||
"ignore_old_scan_res", "freq_list"
|
"ignore_old_scan_res", "freq_list", "external_sim"
|
||||||
};
|
};
|
||||||
int i, num_fields = sizeof(fields) / sizeof(fields[0]);
|
int i, num_fields = sizeof(fields) / sizeof(fields[0]);
|
||||||
|
|
||||||
@ -1270,6 +1270,38 @@ static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char cmd[256], *pos, *end;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Invalid SIM command: needs two arguments "
|
||||||
|
"(network id and SIM operation response)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = cmd + sizeof(cmd);
|
||||||
|
pos = cmd;
|
||||||
|
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
|
||||||
|
argv[0], argv[1]);
|
||||||
|
if (ret < 0 || ret >= end - pos) {
|
||||||
|
printf("Too long SIM command.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pos += ret;
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
|
||||||
|
if (ret < 0 || ret >= end - pos) {
|
||||||
|
printf("Too long SIM command.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pos += ret;
|
||||||
|
}
|
||||||
|
return wpa_ctrl_command(ctrl, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
|
static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
@ -2466,6 +2498,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
|||||||
cli_cmd_flag_sensitive,
|
cli_cmd_flag_sensitive,
|
||||||
"<network id> <passphrase> = configure private key passphrase\n"
|
"<network id> <passphrase> = configure private key passphrase\n"
|
||||||
" for an SSID" },
|
" for an SSID" },
|
||||||
|
{ "sim", wpa_cli_cmd_sim, NULL,
|
||||||
|
cli_cmd_flag_sensitive,
|
||||||
|
"<network id> <pin> = report SIM operation result" },
|
||||||
{ "bssid", wpa_cli_cmd_bssid, NULL,
|
{ "bssid", wpa_cli_cmd_bssid, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"<network id> <BSSID> = set preferred BSSID for an SSID" },
|
"<network id> <BSSID> = set preferred BSSID for an SSID" },
|
||||||
|
@ -303,6 +303,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
|
|||||||
!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
|
!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
|
||||||
wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
|
wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
|
||||||
wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
|
wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
|
||||||
|
eapol_conf.external_sim = wpa_s->conf->external_sim;
|
||||||
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
|
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
|
||||||
#endif /* IEEE8021X_EAPOL */
|
#endif /* IEEE8021X_EAPOL */
|
||||||
}
|
}
|
||||||
@ -3750,6 +3751,10 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
|
|||||||
if (ssid == wpa_s->current_ssid)
|
if (ssid == wpa_s->current_ssid)
|
||||||
wpa_s->reassociate = 1;
|
wpa_s->reassociate = 1;
|
||||||
break;
|
break;
|
||||||
|
case WPA_CTRL_REQ_SIM:
|
||||||
|
os_free(eap->external_sim_resp);
|
||||||
|
eap->external_sim_resp = os_strdup(value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -611,6 +611,8 @@ enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
|
|||||||
return WPA_CTRL_REQ_EAP_OTP;
|
return WPA_CTRL_REQ_EAP_OTP;
|
||||||
else if (os_strcmp(field, "PASSPHRASE") == 0)
|
else if (os_strcmp(field, "PASSPHRASE") == 0)
|
||||||
return WPA_CTRL_REQ_EAP_PASSPHRASE;
|
return WPA_CTRL_REQ_EAP_PASSPHRASE;
|
||||||
|
else if (os_strcmp(field, "SIM") == 0)
|
||||||
|
return WPA_CTRL_REQ_SIM;
|
||||||
return WPA_CTRL_REQ_UNKNOWN;
|
return WPA_CTRL_REQ_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,6 +649,9 @@ const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
|||||||
*txt = "Private key passphrase";
|
*txt = "Private key passphrase";
|
||||||
ret = "PASSPHRASE";
|
ret = "PASSPHRASE";
|
||||||
break;
|
break;
|
||||||
|
case WPA_CTRL_REQ_SIM:
|
||||||
|
ret = "SIM";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user