WPA_CTRL_REQ_EAP_PIN,
WPA_CTRL_REQ_EAP_OTP,
WPA_CTRL_REQ_EAP_PASSPHRASE,
+ WPA_CTRL_REQ_SIM,
NUM_WPA_CTRL_REQS
};
const char *msg, size_t msglen)
{
struct eap_peer_config *config;
- char *txt = NULL, *tmp;
+ const char *txt = NULL;
+ char *tmp;
if (sm == NULL)
return;
case WPA_CTRL_REQ_EAP_PASSPHRASE:
config->pending_req_passphrase++;
break;
+ case WPA_CTRL_REQ_SIM:
+ txt = msg;
+ break;
default:
return;
}
}
+/**
+ * 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
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
}
+/**
+ * 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
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
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_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);
u32 eap_get_phase2_type(const char *name, int *vendor);
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_workaround(struct eap_sm *sm, unsigned int workaround);
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);
void eap_notify_success(struct eap_sm *sm);
void eap_notify_lower_layer_success(struct eap_sm *sm);
* 2 = require valid OCSP stapling response
*/
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;
};
struct ext_password_data *ext_pw;
struct wpabuf *ext_pw_buf;
+
+ int external_sim;
};
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
eap_set_fast_reauth(sm->eap, conf->fast_reauth);
eap_set_workaround(sm->eap, conf->workaround);
eap_set_force_disabled(sm->eap, conf->eap_disabled);
+ eap_set_external_sim(sm->eap, conf->external_sim);
}
}
* eap_disabled - Whether EAP is disabled
*/
int eap_disabled;
+
+ /**
+ * external_sim - Use external processing for SIM/USIM operations
+ */
+ int external_sim;
};
struct eapol_sm;
Note: the return value of add_cred is used as the first argument to
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:
os_free(eap->pending_req_otp);
os_free(eap->pac_file);
os_free(eap->new_password);
+ os_free(eap->external_sim_resp);
}
#endif /* IEEE8021X_EAPOL */
{ STR(pkcs11_module_path), 0 },
{ STR(pcsc_reader), 0 },
{ STR(pcsc_pin), 0 },
+ { INT(external_sim), 0 },
{ STR(driver_param), 0 },
{ INT(dot11RSNAConfigPMKLifetime), 0 },
{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
*/
char *pcsc_pin;
+ /**
+ * external_sim - Use external processing for SIM/USIM operations
+ */
+ int external_sim;
+
/**
* driver_param - Driver interface parameters
*
if (config->sched_scan_interval)
fprintf(f, "sched_scan_interval=%u\n",
config->sched_scan_interval);
+
+ if (config->external_sim)
+ fprintf(f, "external_sim=%d\n", config->external_sim);
}
#endif /* CONFIG_NO_CONFIG_WRITE */
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("external_sim"),
+ config->external_sim, 0);
+
return 0;
}
eapol_conf.required_keys = 0;
eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
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_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
#ifdef PCSC_FUNCS
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;
if (ssid->eap.eap_methods == NULL) {
#endif /* CONFIG_EAP_PROXY */
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;
sep = os_strchr(cred->imsi, '-');
"wps_nfc_dev_pw", "ext_password_backend",
"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
"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]);
}
+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,
char *argv[])
{
cli_cmd_flag_sensitive,
"<network id> <passphrase> = configure private key passphrase\n"
" 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,
cli_cmd_flag_none,
"<network id> <BSSID> = set preferred BSSID for an SSID" },
!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_WPS;
+ eapol_conf.external_sim = wpa_s->conf->external_sim;
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
#endif /* IEEE8021X_EAPOL */
}
if (ssid == wpa_s->current_ssid)
wpa_s->reassociate = 1;
break;
+ case WPA_CTRL_REQ_SIM:
+ os_free(eap->external_sim_resp);
+ eap->external_sim_resp = os_strdup(value);
+ break;
default:
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
return -1;
return WPA_CTRL_REQ_EAP_OTP;
else if (os_strcmp(field, "PASSPHRASE") == 0)
return WPA_CTRL_REQ_EAP_PASSPHRASE;
+ else if (os_strcmp(field, "SIM") == 0)
+ return WPA_CTRL_REQ_SIM;
return WPA_CTRL_REQ_UNKNOWN;
}
*txt = "Private key passphrase";
ret = "PASSPHRASE";
break;
+ case WPA_CTRL_REQ_SIM:
+ ret = "SIM";
+ break;
default:
break;
}