!2022 支持EAP-TTLS/SIM/AKA/AKA'加密方式-wifi

Merge pull request !2022 from zhangshaocheng/wifi_eap
This commit is contained in:
openharmony_ci 2024-04-20 12:15:15 +00:00 committed by Gitee
commit 976227aca9
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
30 changed files with 1237 additions and 60 deletions

View File

@ -81,6 +81,7 @@
"battery_manager",
"bundle_framework",
"c_utils",
"cellular_data",
"certificate_manager",
"common_event_service",
"core_service",
@ -103,6 +104,7 @@
"netmanager_base",
"netstack",
"os_account",
"openssl",
"safwk",
"samgr",
"power_manager",

View File

@ -111,6 +111,8 @@ napi_status SetValueUnsignedInt32(const napi_env& env, const char* fieldStr, con
napi_value& result);
napi_status SetValueInt64(const napi_env& env, const char* fieldStr, const int64_t intValue, napi_value& result);
napi_status SetValueBool(const napi_env& env, const char* fieldStr, const bool boolValue, napi_value& result);
napi_status SetValueU8Vector(const napi_env& env, const char* fieldStr,
const std::vector<uint8_t> value, napi_value& result);
napi_value DoAsyncWork(const napi_env& env, AsyncContext *asyncContext,
const size_t argc, const napi_value *argv, const size_t nonCallbackArgNum);
void SetNamedPropertyByInteger(napi_env, napi_value dstObj, int32_t objName, const char *propName);

View File

@ -24,6 +24,7 @@ namespace OHOS {
namespace Wifi {
DEFINE_WIFILOG_LABEL("WifiNAPIDevice");
static constexpr int DEFAULT_INVALID_VALUE = -1;
static const std::string EAP_METHOD[] = { "NONE", "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'" };
std::shared_ptr<WifiDevice> wifiDevicePtr = WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
std::shared_ptr<WifiScan> wifiScanPtr = WifiScan::GetInstance(WIFI_SCAN_ABILITY_ID);
@ -333,11 +334,10 @@ static void ProcessPassphrase(const SecTypeJs& securityType, WifiDeviceConfig& c
static std::string EapMethod2Str(const int& method)
{
const std::string eapMethod[] = { "NONE", "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'" };
if (method < 0 || method >= static_cast<int>(sizeof(eapMethod) / sizeof(eapMethod[0]))) {
if (method < 0 || method >= static_cast<int>(sizeof(EAP_METHOD) / sizeof(EAP_METHOD[0]))) {
return "NONE";
}
return eapMethod[method];
return EAP_METHOD[method];
}
napi_value ProcessEapConfig(const napi_env& env, const napi_value& object, WifiDeviceConfig& devConfig)
@ -356,7 +356,11 @@ napi_value ProcessEapConfig(const napi_env& env, const napi_value& object, WifiD
// EAP authentication mode
JsObjectToInt(env, napiEap, "eapMethod", eapMethod);
devConfig.wifiEapConfig.eap = EapMethod2Str(eapMethod);
WIFI_LOGI("%{public}s eapMethod: %{public}s", __func__, devConfig.wifiEapConfig.eap.c_str());
if (devConfig.wifiEapConfig.eap == EAP_METHOD_NONE) {
return UndefinedNapiValue(env);
}
WIFI_LOGI("%{public}s eapMethod: %{public}d[%{public}s]",
__func__, eapMethod, devConfig.wifiEapConfig.eap.c_str());
int phase2 = static_cast<int>(Phase2Method::NONE);
JsObjectToInt(env, napiEap, "phase2Method", phase2);
@ -1227,6 +1231,38 @@ static void UpdateSecurityTypeAndPreSharedKey(WifiDeviceConfig& cppConfig)
}
}
static int Str2EapMethod(const std::string& str)
{
WIFI_LOGD("%{public}s: eapMethod is %{public}s", __func__, str.c_str());
int len = sizeof(EAP_METHOD) / sizeof(EAP_METHOD[0]);
for (int i = 0; i < len; i++) {
if (EAP_METHOD[i] == str) {
WIFI_LOGD("%{public}s: index is %{public}d", __func__, i);
return i;
}
}
return 0;
}
static void EapConfigToJs(const napi_env& env, const WifiEapConfig& wifiEapConfig, napi_value& cfgObj)
{
SetValueInt32(env, "eapMethod", Str2EapMethod(wifiEapConfig.eap), cfgObj);
SetValueInt32(env, "phase2Method", static_cast<int>(wifiEapConfig.phase2Method), cfgObj);
SetValueUtf8String(env, "identity", wifiEapConfig.identity.c_str(), cfgObj);
SetValueUtf8String(env, "anonymousIdentity", wifiEapConfig.anonymousIdentity.c_str(), cfgObj);
SetValueUtf8String(env, "password", wifiEapConfig.password.c_str(), cfgObj);
SetValueUtf8String(env, "caCertAlias", wifiEapConfig.caCertAlias.c_str(), cfgObj);
SetValueUtf8String(env, "caPath", wifiEapConfig.caCertPath.c_str(), cfgObj);
SetValueUtf8String(env, "clientCertAlias", wifiEapConfig.caCertAlias.c_str(), cfgObj);
SetValueU8Vector(env, "certEntry", wifiEapConfig.certEntry, cfgObj);
SetValueUtf8String(env, "certPassword", wifiEapConfig.certPassword, cfgObj);
SetValueUtf8String(env, "altSubjectMatch", wifiEapConfig.altSubjectMatch.c_str(), cfgObj);
SetValueUtf8String(env, "domainSuffixMatch", wifiEapConfig.domainSuffixMatch.c_str(), cfgObj);
SetValueUtf8String(env, "realm", wifiEapConfig.realm.c_str(), cfgObj);
SetValueUtf8String(env, "plmn", wifiEapConfig.plmn.c_str(), cfgObj);
SetValueInt32(env, "eapSubId", wifiEapConfig.eapSubId, cfgObj);
}
static void DeviceConfigToJsArray(const napi_env& env, std::vector<WifiDeviceConfig>& vecDeviceConfigs,
const int idx, napi_value& arrayResult)
{
@ -1260,6 +1296,15 @@ static void DeviceConfigToJsArray(const napi_env& env, std::vector<WifiDeviceCon
WIFI_LOGE("Set staticIp field!");
}
ProxyConfigToJs(env, vecDeviceConfigs[idx], result);
napi_value eapCfgObj;
napi_create_object(env, &eapCfgObj);
EapConfigToJs(env, vecDeviceConfigs[idx].wifiEapConfig, eapCfgObj);
status = napi_set_named_property(env, result, "eapConfig", eapCfgObj);
if (status != napi_ok) {
WIFI_LOGE("failed to set eapConfig!");
}
status = napi_set_element(env, arrayResult, idx, result);
if (status != napi_ok) {
WIFI_LOGE("Wifi napi set element error: %{public}d", status);

View File

@ -287,6 +287,35 @@ napi_status SetValueBool(const napi_env& env, const char* fieldStr, const bool b
return status;
}
napi_status SetValueU8Vector(const napi_env& env, const char* fieldStr,
const std::vector<uint8_t> value, napi_value& result)
{
napi_value array;
napi_status status = napi_create_array_with_length(env, value.size(), &array);
if (status != napi_ok) {
WIFI_LOGE("failed to create array! field: %{public}s", fieldStr);
return status;
}
std::vector<uint8_t> vec = value;
for (auto i = 0; i < vec.size(); ++i) {
napi_value value;
napi_status status = napi_create_int32(env, vec[i], &value);
if (status != napi_ok) {
WIFI_LOGE("failed to create int32!");
return status;
}
status = napi_set_element(env, array, i, value);
if (status != napi_ok) {
WIFI_LOGE("failed to set element, status: %{public}d", status);
return status;
}
}
if (napi_set_named_property(env, result, fieldStr, array) != napi_ok) {
WIFI_LOGE("failed to set %{public}s named property!", fieldStr);
}
return status;
}
static napi_value InitAsyncCallBackEnv(const napi_env& env, AsyncContext *asyncContext,
const size_t argc, const napi_value *argv, const size_t nonCallbackArgNum)
{

View File

@ -35,6 +35,9 @@ namespace Wifi {
#define WIFI_INVALID_UID (-1)
#define IPV4_ADDRESS_TYPE 0
#define IPV6_ADDRESS_TYPE 1
#define WIFI_INVALID_SIM_ID (0)
#define WIFI_EAP_OPEN_EXTERNAL_SIM 1
#define WIFI_EAP_CLOSE_EXTERNAL_SIM 0
#define WIFI_PASSWORD_LEN 128
#define MAX_PID_LIST_SIZE 128
@ -44,6 +47,7 @@ const std::string KEY_MGMT_WPA_PSK = "WPA-PSK";
const std::string KEY_MGMT_SAE = "SAE";
const std::string KEY_MGMT_EAP = "WPA-EAP";
const std::string EAP_METHOD_NONE = "NONE";
const std::string EAP_METHOD_PEAP = "PEAP";
const std::string EAP_METHOD_TLS = "TLS";
const std::string EAP_METHOD_TTLS = "TTLS";
@ -676,6 +680,21 @@ struct IpV6Info {
}
};
// SIM authentication
struct EapSimGsmAuthParam {
std::vector<std::string> rands;
};
// AKA/AKA' authentication
struct EapSimUmtsAuthParam {
std::string rand;
std::string autn;
EapSimUmtsAuthParam()
{
rand = "";
autn = "";
}
};
typedef enum {
BG_LIMIT_CONTROL_ID_GAME = 1,
BG_LIMIT_CONTROL_ID_STREAM,

View File

@ -41,6 +41,7 @@
"ohos.permission.GET_NETWORK_STATS",
"ohos.permission.GET_NETWORK_INFO",
"ohos.permission.CONNECTIVITY_INTERNAL",
"ohos.permission.GET_TELEPHONY_STATE",
"ohos.permission.RUNNING_STATE_OBSERVER"
],
"secon" : "u:r:wifi_manager_service:s0"

View File

@ -77,6 +77,7 @@ WifiErrorNo HdiWpaListNetworks(struct HdiWifiWpaNetworkInfo *networkList, uint32
WifiErrorNo HdiWpaGetNetwork(int32_t networkId, const char* param, char* value, uint32_t valueLen);
WifiErrorNo HdiWpaStaSetShellCmd(const char *ifName, const char *cmd);
int ConvertMacToStr(char *mac, int macSize, char *macStr, int strLen);
#ifdef __cplusplus

View File

@ -135,7 +135,6 @@ int32_t OnEventAssociateReject(struct IWpaCallback *self,
int32_t OnEventStaNotify(struct IWpaCallback *self, const char* notifyParam, const char *ifName)
{
LOGI("OnEventStaNotify: callback enter!");
if (strcmp(ifName, "wlan0") != 0) {
return 1;
}
@ -143,23 +142,9 @@ int32_t OnEventStaNotify(struct IWpaCallback *self, const char* notifyParam, con
LOGE("OnEventStaNotify: invalid parameter!");
return 1;
}
constexpr int HILINK_NUM = 0X01;
const OHOS::Wifi::WifiEventCallback &cbk = OHOS::Wifi::WifiStaHalInterface::GetInstance().GetCallbackInst();
int num = std::stoi(notifyParam);
switch (num) {
case HILINK_NUM: {
char *bssid = strchr((char *)notifyParam, ':');
if (bssid != NULL) {
return 1;
}
bssid++;
if (cbk.OnEventStaNotify) {
cbk.OnEventStaNotify(bssid);
}
break;
}
default:
break;
if (cbk.onEventStaNotify) {
cbk.onEventStaNotify(notifyParam);
}
return 0;
}

View File

@ -35,7 +35,7 @@ int32_t OnEventTempDisabled(struct IWpaCallback *self,
const struct HdiWpaTempDisabledParam *tempDisabledParam, const char *ifName);
int32_t OnEventAssociateReject(struct IWpaCallback *self,
const struct HdiWpaAssociateRejectParam *associateRejectParam, const char *ifName);
int32_t OnEventStaNotify(struct IWpaCallback *self, const char *hilinkParam, const char *ifName);
int32_t OnEventStaNotify(struct IWpaCallback *self, const char *notifyParam, const char *ifName);
int32_t OnEventWpsOverlap(struct IWpaCallback *self, const char *ifName);
int32_t OnEventWpsTimeout(struct IWpaCallback *self, const char *ifName);
int32_t OnEventScanResult(struct IWpaCallback *self,

View File

@ -217,8 +217,8 @@ WifiErrorNo WifiHdiWpaClient::SetDeviceConfig(int networkId, const WifiIdlDevice
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_KEYMGMT, config.keyMgmt);
}
EapMethod eapMethod = WifiEapConfig::Str2EapMethod(config.eapConfig.eap);
LOGI("%{public}s, eap:%{public}s, eapMethod:%{public}d, num:%{public}d",
__func__, config.eapConfig.eap.c_str(), eapMethod, num);
LOGI("%{public}s, eap:%{public}s, eapMethod:%{public}d, identity:%{private}s, num:%{public}d",
__func__, config.eapConfig.eap.c_str(), eapMethod, config.eapConfig.identity.c_str(), num);
switch (eapMethod) {
case EapMethod::EAP_PEAP:
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_EAP, config.eapConfig.eap);
@ -255,6 +255,12 @@ WifiErrorNo WifiHdiWpaClient::SetDeviceConfig(int networkId, const WifiIdlDevice
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_IDENTITY, config.eapConfig.identity);
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_PASSWORD, config.eapConfig.password);
break;
case EapMethod::EAP_SIM:
case EapMethod::EAP_AKA:
case EapMethod::EAP_AKA_PRIME:
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_EAP, config.eapConfig.eap);
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_IDENTITY, config.eapConfig.identity);
break;
default:
LOGE("%{public}s, invalid eapMethod:%{public}d", __func__, eapMethod);
break;
@ -781,6 +787,7 @@ WifiErrorNo WifiHdiWpaClient::ReqP2pRegisterCallback(const P2pHalCallback &callb
cWifiHdiWpaCallback.OnEventServDiscResp = OnEventServDiscResp;
cWifiHdiWpaCallback.OnEventStaConnectState = OnEventStaConnectState;
cWifiHdiWpaCallback.OnEventIfaceCreated = OnEventIfaceCreated;
cWifiHdiWpaCallback.OnEventStaNotify = OnEventStaNotify;
}
return RegisterHdiWpaP2pEventCallback(&cWifiHdiWpaCallback);

View File

@ -34,7 +34,7 @@ typedef struct IWifiEventCallback {
void (*onWpsTimeOut)(int status);
void (*onWpsConnectionFull)(int status);
void (*onWpsConnectionReject)(int status);
void (*onWpaEventStaNotify)(const char *bssid);
void (*onEventStaNotify)(const char *notifyParam);
} IWifiEventCallback;
#ifdef __cplusplus

View File

@ -587,6 +587,12 @@ WifiErrorNo WifiIdlClient::SetDeviceConfig(int networkId, const WifiIdlDeviceCon
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_IDENTITY, config.eapConfig.identity);
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_PASSWORD, config.eapConfig.password);
break;
case EapMethod::EAP_SIM:
case EapMethod::EAP_AKA:
case EapMethod::EAP_AKA_PRIME:
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_EAP, config.eapConfig.eap);
num += PushDeviceConfigString(conf + num, DEVICE_CONFIG_IDENTITY, config.eapConfig.identity);
break;
default:
LOGE("%{public}s, invalid eapMethod:%{public}d", __func__, eapMethod);
break;
@ -671,7 +677,7 @@ WifiErrorNo WifiIdlClient::ReqRegisterStaEventCallback(const WifiEventCallback &
cEventCallback.onWpsTimeOut = OnWpsTimeOut;
cEventCallback.onWpsConnectionFull = OnWpaConnectionFull;
cEventCallback.onWpsConnectionReject = OnWpaConnectionReject;
cEventCallback.onWpaEventStaNotify = OnWpaEventStaNotify;
cEventCallback.onEventStaNotify = OnWpaStaNotifyCallBack;
}
return RegisterStaEventCallback(cEventCallback);
}

View File

@ -113,7 +113,7 @@ void OnWpaConnectionReject(int status)
}
}
void OnWpaEventStaNotify(const char *notifyParam)
void OnWpaStaNotifyCallBack(const char *notifyParam)
{
if (notifyParam == nullptr) {
return;

View File

@ -55,7 +55,7 @@ void OnWpsOverlap(int status);
void OnWpsTimeOut(int status);
void OnWpaConnectionFull(int status);
void OnWpaConnectionReject(int status);
void OnWpaEventStaNotify(const char *bssid);
void OnWpaStaNotifyCallBack(const char *notifyParam);
/**
* @Description Get the Supplicant Rpc Client object.

View File

@ -503,6 +503,19 @@ WifiErrorNo WifiStaHalInterface::SetDpiMarkRule(int uid, int protocol, int enabl
#endif
}
WifiErrorNo WifiStaHalInterface::ShellCmd(const std::string &ifName, const std::string &cmd)
{
if ((ifName.length() <= 0) || (cmd.length() <= 0)) {
return WIFI_IDL_OPT_INVALID_PARAM;
}
#ifdef HDI_WPA_INTERFACE_SUPPORT
CHECK_NULL_AND_RETURN(mHdiWpaClient, WIFI_IDL_OPT_FAILED);
return mHdiWpaClient->ReqWpaShellCmd(ifName, cmd);
#else
return WIFI_IDL_OPT_OK;
#endif
}
WifiErrorNo WifiStaHalInterface::GetChipsetCategory(int& chipsetCategory)
{
#ifdef HDI_INTERFACE_SUPPORT
@ -545,19 +558,6 @@ WifiErrorNo WifiStaHalInterface::StopWifiHdi()
#endif
}
WifiErrorNo WifiStaHalInterface::ShellCmd(const std::string &ifName, const std::string &cmd)
{
if ((ifName.length() <= 0) || (cmd.length() <= 0)) {
return WIFI_IDL_OPT_INVALID_PARAM;
}
#ifdef HDI_WPA_INTERFACE_SUPPORT
CHECK_NULL_AND_RETURN(mHdiWpaClient, WIFI_IDL_OPT_FAILED);
return mHdiWpaClient->ReqWpaShellCmd(ifName, cmd);
#else
return WIFI_IDL_OPT_FAILED;
#endif
}
WifiErrorNo WifiStaHalInterface::SetNetworkInterfaceUpDown(const std::string &ifaceName, bool upDown)
{
#ifdef HDI_INTERFACE_SUPPORT

View File

@ -351,6 +351,15 @@ public:
*/
WifiErrorNo SetDpiMarkRule(int uid, int protocol, int enable);
/**
* @Description Send SIM/AKA/AKA' authentication to wpa
*
* @param ifName: Interface name
* @param cmd: Request message content
* @return WifiErrorNo
*/
WifiErrorNo ShellCmd(const std::string &ifName, const std::string &cmd);
/**
* @Description set background limit speed uid&pid list
*
@ -365,16 +374,6 @@ public:
*/
WifiErrorNo GetChipsetWifiFeatrureCapability(int& chipsetFeatrureCapability);
/**
* @Description Send SIM/AKA/AKA' authentication to wpa
*
* @param ifName: Interface name
* @param cmd: Request message content
* @return WifiErrorNo
*/
WifiErrorNo ShellCmd(const std::string &ifName, const std::string &cmd);
/**
* @Description Open Wifi hdi.
*

View File

@ -166,6 +166,8 @@ if (defined(ohos_lite)) {
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"cellular_data:tel_cellular_data_api",
"core_service:tel_core_service_api",
"dhcp:dhcp_sdk",
"hilog:libhilog",
"init:libbegetutil",

View File

@ -66,6 +66,8 @@ namespace Wifi {
#define WIFI_SVR_CMD_STA_BSSID_CHANGED_EVENT 0x301A
#define WIFI_SVR_CMD_STA_DHCP_RESULT_NOTIFY_EVENT 0x301B
#define WIFI_SVR_CMD_STA_NET_DETECTION_NOTIFY_EVENT 0x301C
#define WIFI_SVR_CMD_STA_WPA_EAP_SIM_AUTH_EVENT 0x301D
#define WIFI_SVR_CMD_STA_WPA_EAP_UMTS_AUTH_EVENT 0x301E
#define WPA_BLOCK_LIST_CLEAR_EVENT 0x4001
#define WIFI_SVR_CMD_UPDATE_COUNTRY_CODE 0x4002
@ -81,6 +83,10 @@ namespace Wifi {
#define NETWORK_SELECTED_BY_USER 1
#define NETWORK_SELECTED_BY_RETRY 2
#define WIFI_SIM_GSM_AUTH_MIN_PARAM_COUNT 3
#define WIFI_SIM_GSM_AUTH_MAX_PARAM_COUNT 4
#define WIFI_SIM_UMTS_AUTH_PARAM_COUNT 3
const int NETWORK_24G_BAND = 1;
const int NETWORK_5G_BAND = 2;
const int MAX_RETRY_COUNT = 3;
@ -103,6 +109,14 @@ typedef enum EnumNetWorkState {
NETWORK_IS_PORTAL,
}SystemNetWorkState;
typedef enum EnumStaNetState {
NETWORK_STATE_UNKNOWN,
NETWORK_STATE_WORKING,
NETWORK_CHECK_PORTAL,
NETWORK_STATE_NOINTERNET,
NETWORK_STATE_BUTT,
} StaNetState;
using ArpStateHandler = std::function<void(StaArpState arpState)>;
using DnsStateHandler = std::function<void(StaDnsState dnsState)>;
} // namespace Wifi

View File

@ -45,7 +45,7 @@ ErrCode StaMonitor::InitStaMonitor()
std::bind(&StaMonitor::OnWpsTimeOutCallBack, this, _1),
std::bind(&StaMonitor::onWpaConnectionFullCallBack, this, _1),
std::bind(&StaMonitor::onWpaConnectionRejectCallBack, this, _1),
std::bind(&StaMonitor::OnWpaHilinkCallBack, this, _1)
std::bind(&StaMonitor::OnWpaStaNotifyCallBack, this, _1)
};
if (WifiStaHalInterface::GetInstance().RegisterStaEventCallback(callBack) != WIFI_IDL_OPT_OK) {
@ -101,7 +101,7 @@ void StaMonitor::OnConnectChangedCallBack(int status, int networkId, const std::
break;
}
case WPA_CB_ASSOCIATING:
case WPA_CB_ASSOCIATED:
case WPA_CB_ASSOCIATED:
pStaStateMachine->OnNetworkAssocEvent(status, bssid, pStaStateMachine);
break;
default:
@ -109,6 +109,42 @@ void StaMonitor::OnConnectChangedCallBack(int status, int networkId, const std::
}
}
constexpr int HILINK_NUM = 0X01;
constexpr int EAP_SIM_NUM = 0X02;
void StaMonitor::OnWpaStaNotifyCallBack(const std::string &notifyParam)
{
WIFI_LOGI("OnWpaStaNotifyCallBack() enter, notifyParam=%{private}s", notifyParam.c_str());
if (notifyParam.empty()) {
WIFI_LOGI("OnWpaStaNotifyCallBack() notifyParam is empty");
return;
}
std::string::size_type begPos = 0;
if ((begPos = notifyParam.find(":")) == std::string::npos) {
WIFI_LOGI("OnWpaStaNotifyCallBack() notifyParam not find :");
return;
}
std::string type = notifyParam.substr(0, begPos);
int num = stoi(type);
std::string data = notifyParam.substr(begPos + 1);
if (data.empty()) {
WIFI_LOGI("OnWpaStaNotifyCallBack() data is empty");
return;
}
switch (num) {
case HILINK_NUM:
OnWpaHilinkCallBack(data);
break;
case EAP_SIM_NUM:
OnWpaEapSimAuthCallBack(data);
break;
default:
WIFI_LOGI("OnWpaStaNotifyCallBack() undefine event:%{public}d", num);
break;
}
}
void StaMonitor::OnWpaHilinkCallBack(const std::string &bssid)
{
WIFI_LOGI("OnWpaHilinkCallBack() enter");
@ -207,5 +243,52 @@ void StaMonitor::OnWpsTimeOutCallBack(int status)
/* Notification state machine WPS timeout event */
pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPS_TIMEOUT_EVNET, status);
}
/* SIM authentication data format: [GSM-AUTH][:][Rand1][:][Rand2] or [GSM-AUTH][:][Rand1][:][Rand2][:][Rand3]
AKA/AKA authentication data format: [UMTS-AUTH][:][rand][:][autn]
*/
void StaMonitor::OnWpaEapSimAuthCallBack(const std::string &notifyParam)
{
WIFI_LOGD("OnWpaEapSimAuthCallBack, notifyParam:%{private}s", notifyParam.c_str());
if (pStaStateMachine == nullptr) {
WIFI_LOGE("The statemachine pointer is null.");
return;
}
std::string delimiter = ":";
std::vector<std::string> results = getAuthInfo(notifyParam, delimiter);
int size = results.size();
if (results[0] == "GSM-AUTH") {
if ((size != WIFI_SIM_GSM_AUTH_MIN_PARAM_COUNT) && (size != WIFI_SIM_GSM_AUTH_MAX_PARAM_COUNT)) {
WIFI_LOGE("invalid GSM-AUTH authentication data, size:%{public}d", size);
return;
}
EapSimGsmAuthParam param;
for (int i = 0; i < size; i++) {
if (i == 0) {
continue;
}
param.rands.push_back(results[i]);
WIFI_LOGI("results[%{public}d]:%{public}s", i, results[i].c_str());
}
WIFI_LOGI("%{public}s size:%{public}zu", __func__, param.rands.size());
pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_EAP_SIM_AUTH_EVENT, param);
} else if ((results[0] == "UMTS-AUTH") || (results[0] == "UMTS-AUTS")) {
if (size != WIFI_SIM_UMTS_AUTH_PARAM_COUNT) {
WIFI_LOGE("invalid UMTS-AUTH authentication data, size:%{public}d", size);
return;
}
EapSimUmtsAuthParam param;
param.rand = results[1]; // get rand data
param.autn = results[2]; // get autn data
WIFI_LOGD("%{public}s rand:%{private}s, autn:%{private}s",
__func__, param.rand.c_str(), param.autn.c_str());
pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_EAP_UMTS_AUTH_EVENT, param);
} else {
WIFI_LOGE("Invalid authentication type, authType:%{public}s", results[0].c_str());
return;
}
}
} // namespace Wifi
} // namespace OHOS

View File

@ -119,6 +119,20 @@ public:
*/
void OnWpsTimeOutCallBack(int status);
/**
* @Description : Callback of the SIM/AKA/AKA' authentication event.
*
* @param notifyParam - authentication information [in]
*/
void OnWpaEapSimAuthCallBack(const std::string &notifyParam);
/**
* @Description : Callback of the STA event.
*
* @param notifyParam - authentication information [in]
*/
void OnWpaStaNotifyCallBack(const std::string &notifyParam);
private:
StaStateMachine *pStaStateMachine;
int m_instId;

View File

@ -19,6 +19,8 @@
#ifndef OHOS_ARCH_LITE
#include "wifi_internal_event_dispatcher.h"
#include "wifi_country_code_manager.h"
#include "core_service_client.h"
#include "cellular_data_client.h"
#endif
#include "wifi_logger.h"
#include "wifi_settings.h"
@ -38,6 +40,23 @@ namespace Wifi {
constexpr const char *ANCO_SERVICE_BROKER = "anco_service_broker";
constexpr const int REMOVE_ALL_DEVICECONFIG = 0x7FFFFFFF;
#define EAP_AUTH_IMSI_MCC_POS 0
#define EAP_AUTH_MAX_MCC_LEN 3
#define EAP_AUTH_IMSI_MNC_POS 3
#define EAP_AUTH_MIN_MNC_LEN 2
#define EAP_AUTH_MAX_MNC_LEN 3
#define EAP_AUTH_MIN_PLMN_LEN 5
#define EAP_AUTH_MAX_PLMN_LEN 6
#define EAP_AUTH_MAX_IMSI_LENGTH 15
#define EAP_AKA_PERMANENT_PREFIX "0"
#define EAP_SIM_PERMANENT_PREFIX "1"
#define EAP_AKA_PRIME_PERMANENT_PREFIX "6"
#define EAP_AUTH_WLAN_MNC "@wlan.mnc"
#define EAP_AUTH_WLAN_MCC ".mcc"
#define EAP_AUTH_PERMANENT_SUFFIX ".3gppnetwork.org"
StaService::StaService(int instId)
: pStaStateMachine(nullptr),
pStaMonitor(nullptr),
@ -276,6 +295,103 @@ ErrCode StaService::ConnectToCandidateConfig(const int uid, const int networkId)
return WIFI_OPT_SUCCESS;
}
std::string StaService::ConvertString(const std::u16string &wideText) const
{
return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(wideText);
}
#ifndef OHOS_ARCH_LITE
int32_t StaService::GetDataSlotId() const
{
auto slotId = CellularDataClient::GetInstance().GetDefaultCellularDataSlotId();
int32_t simCount = CoreServiceClient::GetInstance().GetMaxSimCount();
if ((slotId < 0) || (slotId >= simCount)) {
LOGE("failed to get default slotId, slotId:%{public}d, simCount:%{public}d", slotId, simCount);
return -1;
}
LOGI("slotId: %{public}d, simCount:%{public}d", slotId, simCount);
return slotId;
}
std::string StaService::GetImsi(int32_t slotId) const
{
std::u16string imsi;
int32_t errCode = CoreServiceClient::GetInstance().GetIMSI(slotId, imsi);
if (errCode != 0) {
LOGE("failed to get imsi, errCode: %{public}d", errCode);
return "";
}
return ConvertString(imsi);
}
std::string StaService::GetPlmn(int32_t slotId) const
{
std::u16string plmn;
int32_t errCode = CoreServiceClient::GetInstance().GetSimOperatorNumeric(slotId, plmn);
if (errCode != 0) {
LOGE("failed to get plmn, errCode: %{public}d", errCode);
return "";
}
return ConvertString(plmn);
}
#endif
std::string StaService::GetMcc(const std::string &imsi) const
{
return imsi.substr(EAP_AUTH_IMSI_MCC_POS, EAP_AUTH_MAX_MCC_LEN);
}
std::string StaService::GetMnc(const std::string &imsi, const int mncLen) const
{
return imsi.substr(EAP_AUTH_IMSI_MNC_POS, mncLen);
}
void StaService::UpdateEapConfig(const WifiDeviceConfig &config, WifiEapConfig &wifiEapConfig) const
{
std::string eapMethod = config.wifiEapConfig.eap;
LOGI("Enter StaService::UpdateEapConfig, eapMethod:%{public}s", eapMethod.c_str());
std::string prefix;
if (eapMethod == EAP_METHOD_SIM) {
prefix = EAP_SIM_PERMANENT_PREFIX;
} else if (eapMethod == EAP_METHOD_AKA) {
prefix = EAP_AKA_PERMANENT_PREFIX;
} else if (eapMethod == EAP_METHOD_AKA_PRIME) {
prefix = EAP_AKA_PRIME_PERMANENT_PREFIX;
} else {
return;
}
int32_t slotId = GetDataSlotId();
if (slotId == -1) {
return;
}
std::string imsi = GetImsi(slotId);
if (imsi.empty() || imsi.length() > EAP_AUTH_MAX_IMSI_LENGTH) {
LOGE("invalid imsi, length: %{public}zu", imsi.length());
return;
}
std::string mnc;
std::string plmn = GetPlmn(slotId);
LOGI("imsi: %{private}s, plmn: %{public}s", imsi.c_str(), plmn.c_str());
if (plmn.length() == EAP_AUTH_MIN_PLMN_LEN) {
mnc = "0" + GetMnc(imsi, EAP_AUTH_MIN_MNC_LEN);
} else if (plmn.length() == EAP_AUTH_MAX_PLMN_LEN) {
mnc = GetMnc(imsi, EAP_AUTH_MAX_MNC_LEN);
} else {
LOGE("invalid plmn, length: %{public}zu", plmn.length());
return;
}
// identity: prefix + imsi + "@wlan.mnc" + mnc + ".mcc" + mcc + ".3gppnetwork.org"
std::string identity = prefix + imsi + EAP_AUTH_WLAN_MNC + mnc +
EAP_AUTH_WLAN_MCC + GetMcc(imsi) + EAP_AUTH_PERMANENT_SUFFIX;
LOGI("StaService::UpdateEapConfig, identity: %{public}s", identity.c_str());
wifiEapConfig.identity = identity;
}
int StaService::AddDeviceConfig(const WifiDeviceConfig &config) const
{
LOGI("Enter AddDeviceConfig, bssid=%{public}s\n", MacAnonymize(config.bssid).c_str());
@ -321,12 +437,14 @@ int StaService::AddDeviceConfig(const WifiDeviceConfig &config) const
if (ret == 0) {
tempDeviceConfig.wifiEapConfig.clientCert = uri;
tempDeviceConfig.wifiEapConfig.privateKey = uri;
LOGE("install cert: %{public}s", tempDeviceConfig.wifiEapConfig.clientCert.c_str());
LOGI("success to install cert: %{public}s", tempDeviceConfig.wifiEapConfig.clientCert.c_str());
} else {
LOGE("install cert: %{public}d, alias: %{public}s", ret, alias.c_str());
LOGE("failed to install cert: %{public}d, alias: %{public}s", ret, alias.c_str());
}
}
UpdateEapConfig(config, tempDeviceConfig.wifiEapConfig);
/* Add the new network to WifiSettings. */
if (WifiSettings::GetInstance().EncryptionDeviceConfig(tempDeviceConfig)) {
LOGE("AddDeviceConfig EncryptionDeviceConfig failed");

View File

@ -16,6 +16,7 @@
#ifndef OHOS_WIFI_SERVICE_H
#define OHOS_WIFI_SERVICE_H
#include <codecvt>
#include "wifi_internal_msg.h"
#include "sta_auto_connect_service.h"
#include "sta_monitor.h"
@ -335,6 +336,13 @@ public:
private:
void NotifyDeviceConfigChange(ConfigChange value) const;
int FindDeviceConfig(const WifiDeviceConfig &config, WifiDeviceConfig &outConfig) const;
std::string ConvertString(const std::u16string &wideText) const;
int32_t GetDataSlotId() const;
std::string GetImsi(int32_t slotId) const;
std::string GetPlmn(int32_t slotId) const;
std::string GetMcc(const std::string &imsi) const;
std::string GetMnc(const std::string &imsi, const int mncLen) const;
void UpdateEapConfig(const WifiDeviceConfig &config, WifiEapConfig &wifiEapConfig) const;
private:
#ifndef OHOS_ARCH_LITE
class WifiCountryCodeChangeObserver : public IWifiCountryCodeChangeListener {

View File

@ -78,6 +78,38 @@ DEFINE_WIFILOG_LABEL("StaStateMachine");
#define SELF_CURE_FAC_MAC_REASSOC 2
#define SELF_CURE_RAND_MAC_REASSOC 3
#define CMD_BUFFER_SIZE 1024
#define GSM_AUTH_RAND_LEN 16
#define GSM_AUTH_CHALLENGE_SRES_LEN 4
#define GSM_AUTH_CHALLENGE_KC_LEN 8
#define MAX_SRES_STR_LEN (2 * GSM_AUTH_CHALLENGE_SRES_LEN)
#define MAX_KC_STR_LEN (2 * GSM_AUTH_CHALLENGE_KC_LEN)
#define UMTS_AUTH_TYPE_TAG 0xdb
#define UMTS_AUTS_TYPE_TAG 0xdc
#define UMTS_AUTH_CHALLENGE_RESULT_INDEX 0
#define UMTS_AUTH_CHALLENGE_DATA_START_IDNEX 1
#define UMTS_AUTH_CHALLENGE_RAND_LEN 16
#define UMTS_AUTH_CHALLENGE_AUTN_LEN 16
#define UMTS_AUTH_CHALLENGE_RES_LEN 8
#define UMTS_AUTH_CHALLENGE_CK_LEN 16
#define UMTS_AUTH_CHALLENGE_IK_LEN 16
#define UMTS_AUTH_CHALLENGE_AUTS_LEN 16
#define UMTS_AUTH_REQUEST_CONTENT_LEN (UMTS_AUTH_CHALLENGE_RAND_LEN + UMTS_AUTH_CHALLENGE_AUTN_LEN + 2)
// res[9] + ck[17] + ik[17] + unknown[9]
#define UMTS_AUTH_RESPONSE_CONENT_LEN 52
#define MAX_RES_STR_LEN (2 * UMTS_AUTH_CHALLENGE_RES_LEN)
#define MAX_CK_STR_LEN (2 * UMTS_AUTH_CHALLENGE_CK_LEN)
#define MAX_IK_STR_LEN (2 * UMTS_AUTH_CHALLENGE_IK_LEN)
#define MAX_RAND_STR_LEN (2 * UMTS_AUTH_CHALLENGE_RAND_LEN)
#define MAX_AUTN_STR_LEN (2 * UMTS_AUTH_CHALLENGE_AUTN_LEN)
StaStateMachine::StaStateMachine(int instId)
: StateMachine("StaStateMachine"),
lastNetworkId(INVALID_NETWORK_ID),
@ -450,7 +482,7 @@ ErrCode StaStateMachine::FillEapCfg(const WifiDeviceConfig &config, WifiIdlDevic
idlConfig.eapConfig.anonymousIdentity = config.wifiEapConfig.anonymousIdentity;
if (memcpy_s(idlConfig.eapConfig.password, sizeof(idlConfig.eapConfig.password),
config.wifiEapConfig.password.c_str(), config.wifiEapConfig.password.length()) != EOK) {
LOGE("%{public}s: failed to copy the content", __func__);
WIFI_LOGE("%{public}s: failed to copy the content", __func__);
return WIFI_OPT_FAILED;
}
idlConfig.eapConfig.caCertPath = config.wifiEapConfig.caCertPath;
@ -458,7 +490,7 @@ ErrCode StaStateMachine::FillEapCfg(const WifiDeviceConfig &config, WifiIdlDevic
idlConfig.eapConfig.clientCert = config.wifiEapConfig.clientCert;
if (memcpy_s(idlConfig.eapConfig.certPassword, sizeof(idlConfig.eapConfig.certPassword),
config.wifiEapConfig.certPassword, sizeof(config.wifiEapConfig.certPassword)) != EOK) {
LOGE("%{public}s: failed to copy the content", __func__);
WIFI_LOGE("%{public}s: failed to copy the content", __func__);
return WIFI_OPT_FAILED;
}
idlConfig.eapConfig.privateKey = config.wifiEapConfig.privateKey;
@ -470,6 +502,29 @@ ErrCode StaStateMachine::FillEapCfg(const WifiDeviceConfig &config, WifiIdlDevic
return WIFI_OPT_SUCCESS;
}
ErrCode StaStateMachine::SetExternalSim(const std::string ifName, const std::string &eap, int value) const
{
if ((eap != EAP_METHOD_SIM) &&
(eap != EAP_METHOD_AKA) &&
(eap != EAP_METHOD_AKA_PRIME)) {
return WIFI_OPT_SUCCESS;
}
WIFI_LOGI("%{public}s ifName: %{public}s, eap: %{public}s, value: %{public}d",
__func__, ifName.c_str(), eap.c_str(), value);
char cmd[CMD_BUFFER_SIZE] = { 0 };
if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "set external_sim %d", value) < 0) {
WIFI_LOGE("StaStateMachine::ConvertDeviceCfg: failed to snprintf_s");
return WIFI_OPT_FAILED;
}
if (WifiStaHalInterface::GetInstance().ShellCmd(ifName, cmd) != WIFI_IDL_OPT_OK) {
WIFI_LOGI("%{public}s: failed to set StaShellCmd, cmd:%{private}s", __func__, cmd);
return WIFI_OPT_FAILED;
}
return WIFI_OPT_SUCCESS;
}
ErrCode StaStateMachine::ConvertDeviceCfg(const WifiDeviceConfig &config) const
{
LOGI("Enter ConvertDeviceCfg.\n");
@ -515,6 +570,11 @@ ErrCode StaStateMachine::ConvertDeviceCfg(const WifiDeviceConfig &config) const
LOGE("ConvertDeviceCfg SetDeviceConfig failed!");
return WIFI_OPT_FAILED;
}
if (SetExternalSim("wlan0", idlConfig.eapConfig.eap, WIFI_EAP_OPEN_EXTERNAL_SIM)) {
LOGE("StaStateMachine::ConvertDeviceCfg: failed to set external_sim");
return WIFI_OPT_FAILED;
}
return WIFI_OPT_SUCCESS;
}
@ -814,6 +874,10 @@ int StaStateMachine::InitStaSMHandleMap()
staSmHandleFuncMap[CMD_START_RENEWAL_TIMEOUT] = &StaStateMachine::DealRenewalTimeout;
staSmHandleFuncMap[WIFI_SCREEN_STATE_CHANGED_NOTIFY_EVENT] = &StaStateMachine::DealScreenStateChangedEvent;
staSmHandleFuncMap[CMD_AP_ROAMING_TIMEOUT_CHECK] = &StaStateMachine::DealApRoamingStateTimeout;
#ifndef OHOS_ARCH_LITE
staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_EAP_SIM_AUTH_EVENT] = &StaStateMachine::DealWpaEapSimAuthEvent;
staSmHandleFuncMap[WIFI_SVR_CMD_STA_WPA_EAP_UMTS_AUTH_EVENT] = &StaStateMachine::DealWpaEapUmtsAuthEvent;
#endif
staSmHandleFuncMap[WIFI_SVR_COM_STA_ENABLE_HILINK] = &StaStateMachine::DealHiLinkDataToWpa;
staSmHandleFuncMap[WIFI_SVR_COM_STA_HILINK_DELIVER_MAC] = &StaStateMachine::DealHiLinkDataToWpa;
staSmHandleFuncMap[WIFI_SVR_COM_STA_HILINK_TRIGGER_WPS] = &StaStateMachine::DealHiLinkDataToWpa;
@ -1860,6 +1924,479 @@ void StaStateMachine::OnDhcpResultNotifyEvent(DhcpReturnCode result, int ipType)
SendMessage(msg);
}
#ifndef OHOS_ARCH_LITE
int32_t StaStateMachine::GetDataSlotId()
{
auto slotId = CellularDataClient::GetInstance().GetDefaultCellularDataSlotId();
if (slotId < 0 || slotId >= CoreServiceClient::GetInstance().GetMaxSimCount()) {
LOGE("failed to get default slotId, slotId:%{public}d", slotId);
return -1;
}
LOGI("slotId: %{public}d", slotId);
return slotId;
}
int32_t StaStateMachine::GetCardType(CardType &cardType)
{
return CoreServiceClient::GetInstance().GetCardType(GetDataSlotId(), cardType);
}
int32_t StaStateMachine::GetDefaultId(int32_t slotId)
{
LOGI("StaStateMachine::GetDefaultId in, slotId: %{public}d", slotId);
if (slotId == WIFI_INVALID_SIM_ID) {
return GetDataSlotId();
}
return slotId;
}
int32_t StaStateMachine::GetSimCardState(int32_t slotId)
{
LOGI("StaStateMachine::GetSimCardState in, slotId: %{public}d", slotId);
slotId = GetDefaultId(slotId);
LOGI("slotId: %{public}d", slotId);
SimState simState = SimState::SIM_STATE_UNKNOWN;
int32_t result = CoreServiceClient::GetInstance().GetSimState(slotId, simState);
if (result != WIFI_OPT_SUCCESS) {
LOGE("StaStateMachine::GetSimCardState result:%{public}d, simState:%{public}d", result, simState);
return static_cast<int32_t>(simState);
}
LOGI("StaStateMachine::GetSimCardState out, simState:%{public}d", simState);
return static_cast<int32_t>(simState);
}
bool StaStateMachine::IsValidSimId(int32_t simId)
{
if (simId > 0) {
return true;
}
return false;
}
bool StaStateMachine::IsMultiSimEnabled() {
int32_t simCount = CoreServiceClient::GetInstance().GetMaxSimCount();
LOGI("StaStateMachine::IsMultiSimEnabled simCount:%{public}d", simCount);
if (simCount > 1) {
return true;
}
return false;
}
std::string StaStateMachine::SimAkaAuth(const std::string &nonce, AuthType authType)
{
LOGD("StaStateMachine::SimAkaAuth in, authType:%{public}d, nonce:%{private}s", authType, nonce.c_str());
auto slotId = GetDataSlotId();
SimAuthenticationResponse response;
int32_t result = CoreServiceClient::GetInstance().SimAuthentication(slotId, authType, nonce, response);
if (result != WIFI_OPT_SUCCESS) {
LOGE("StaStateMachine::SimAkaAuth: errCode=%{public}d", result);
return "";
}
return response.response;
}
/* Calculate SRES and KC as 2G authentication.
* Protocol: 3GPP TS 31.102 2G_authentication
* Request messge: [Length][RAND1][Length][RAND2]...[Length][RANDn]
* Response messge: [SRES Length][SRES][KC Length][Cipher Key Kc]
*/
std::string StaStateMachine::GetGsmAuthResponseWithLength(EapSimGsmAuthParam param)
{
int i = 0;
std::string authRsp;
uint8_t randArray[GSM_AUTH_RAND_LEN] = { 0 };
LOGI("%{public}s size:%{public}zu", __func__, param.rands.size());
for (auto iter = param.rands.begin(); iter != param.rands.end(); ++iter) {
// data pre-processing
memset_s(randArray, sizeof(randArray), 0x0, sizeof(randArray));
char tmpRand[MAX_RAND_STR_LEN + 1] = { 0 };
if (strncpy_s(tmpRand, sizeof(tmpRand), (*iter).c_str(), (*iter).length()) != EOK) {
LOGE("%{public}s: failed to copy", __func__);
return "";
}
LOGD("%{public}s rand[%{public}d]: %{private}s, tmpRand: %{private}s",
__func__, i, (*iter).c_str(), tmpRand);
// converting a hexadecimal character string to an array
int ret = HexString2Byte(tmpRand, randArray, sizeof(randArray));
if (ret != 0) {
LOGE("%{public}s: failed to convert a hexadecimal character string to integer", __func__);
return "";
}
std::vector<uint8_t> randVec;
randVec.push_back(sizeof(randArray));
for (size_t j = 0; j < sizeof(randArray); j++) {
randVec.push_back(randArray[j]);
}
// encode data and initiate a challenge request
std::string base64Challenge = EncodeBase64(randVec);
std::string response = SimAkaAuth(base64Challenge, SIM_AUTH_EAP_SIM_TYPE);
if (response.empty()) {
LOGE("%{public}s: fail to sim authentication", __func__);
return "";
}
LOGD("telephony response: %{private}s", response.c_str());
// decode data: data format is [SRES Length][SRES][KC Length][Cipher Key Kc]
std::vector<uint8_t> nonce;
if (!DecodeBase64(response, nonce)) {
LOGE("%{public}s: failed to decode sim authentication, size:%{public}zu", __func__, nonce.size());
return "";
}
// [SRES Length]: the length is 4 bytes
uint8_t sresLen = nonce[0];
if (sresLen >= nonce.size()) {
LOGE("%{public}s: invalid length, sresLen: %{public}d, size: %{public}zu",
__func__, sresLen, nonce.size());
return "";
}
// [SRES]
int offset = 1; // offset [SRES Length]
char sresBuf[MAX_SRES_STR_LEN + 1] = { 0 };
Byte2HexString(&nonce[offset], sresLen, sresBuf, sizeof(sresBuf));
LOGD("%{public}s sresLen: %{public}d, sresBuf: %{private}s", __func__, sresLen, sresBuf);
// [KC Length]: the length is 8 bytes
size_t kcOffset = 1 + sresLen; // offset [SRES Length][SRES]
if (kcOffset >= nonce.size()) {
LOGE("%{public}s: invalid kcOffset: %{public}zu", __func__, kcOffset);
return "";
}
uint8_t kcLen = nonce[kcOffset];
if ((kcLen + kcOffset) >= nonce.size()) {
LOGE("%{public}s: invalid kcLen: %{public}d, kcOffset: %{public}zu", __func__, kcLen, kcOffset);
return "";
}
// [Cipher Key Kc]
char kcBuf[MAX_KC_STR_LEN + 1] = {0};
Byte2HexString(&nonce[kcOffset + 1], kcLen, kcBuf, sizeof(kcBuf));
LOGD("%{public}s kcLen:%{public}d, kcBuf:%{private}s", __func__, kcLen, kcBuf);
// strcat request message
if (i == 0) {
authRsp += std::string(kcBuf) + ":" + std::string(sresBuf);
} else {
authRsp += ":" + std::string(kcBuf) + ":" + std::string(sresBuf);
}
i++;
}
LOGD("%{public}s authRsp: %{private}s, len: %{public}zu", __func__, authRsp.c_str(), authRsp.length());
return authRsp;
}
/* Calculate SRES and KC as 2G authentication.
* Protocol: 3GPP TS 11.11 2G_authentication
* Request messge: [RAND1][RAND2]...[RANDn]
* Response messge: [SRES][Cipher Key Kc]
*/
std::string StaStateMachine::GetGsmAuthResponseWithoutLength(EapSimGsmAuthParam param)
{
int i = 0;
std::string authRsp;
uint8_t randArray[GSM_AUTH_RAND_LEN];
LOGI("%{public}s size: %{public}zu", __func__, param.rands.size());
for (auto iter = param.rands.begin(); iter != param.rands.end(); ++iter) {
// data pre-processing
memset_s(randArray, sizeof(randArray), 0x0, sizeof(randArray));
char tmpRand[MAX_RAND_STR_LEN + 1] = { 0 };
if (strncpy_s(tmpRand, sizeof(tmpRand), (*iter).c_str(), (*iter).length()) != EOK) {
LOGE("%{public}s: failed to copy", __func__);
return "";
}
LOGD("%{public}s rand[%{public}d]: %{public}s, tmpRand: %{public}s", __func__, i, (*iter).c_str(), tmpRand);
// converting a hexadecimal character string to an array
int ret = HexString2Byte(tmpRand, randArray, sizeof(randArray));
if (ret != 0) {
LOGE("%{public}s: fail to data conversion", __func__);
return "";
}
std::vector<uint8_t> randVec;
for (size_t j = 0; j < sizeof(randArray); j++) {
randVec.push_back(randArray[j]);
}
// encode data and initiate a challenge request
std::string base64Challenge = EncodeBase64(randVec);
std::string response = SimAkaAuth(base64Challenge, SIM_AUTH_EAP_SIM_TYPE);
if (response.empty()) {
LOGE("%{public}s: fail to authenticate", __func__);
return "";
}
LOGD("telephony response: %{private}s", response.c_str());
// data format: [SRES][Cipher Key Kc]
std::vector<uint8_t> nonce;
if (!DecodeBase64(response, nonce)) {
LOGE("%{public}s: failed to decode sim authentication, size:%{public}zu", __func__, nonce.size());
return "";
}
if (GSM_AUTH_CHALLENGE_SRES_LEN + GSM_AUTH_CHALLENGE_KC_LEN != nonce.size()) {
LOGE("%{public}s: invalid length, size: %{public}zu", __func__, nonce.size());
return "";
}
// [SRES]
std::string sres;
char sresBuf[MAX_SRES_STR_LEN + 1] = {0};
Byte2HexString(&nonce[0], GSM_AUTH_CHALLENGE_SRES_LEN, sresBuf, sizeof(sresBuf));
// [Cipher Key Kc]
size_t kcOffset = GSM_AUTH_CHALLENGE_SRES_LEN;
if (kcOffset >= nonce.size()) {
LOGE("%{public}s: invalid length, kcOffset: %{public}zu", __func__, kcOffset);
return "";
}
std::string kc;
char kcBuf[MAX_KC_STR_LEN + 1] = {0};
Byte2HexString(&nonce[kcOffset], GSM_AUTH_CHALLENGE_KC_LEN, kcBuf, sizeof(kcBuf));
// strcat request message
if (i == 0) {
authRsp += std::string(kcBuf) + ":" + std::string(sresBuf);
} else {
authRsp += ":" + std::string(kcBuf) + ":" + std::string(sresBuf);
}
i++;
}
LOGI("%{public}s authReq: %{private}s, len: %{public}zu", __func__, authRsp.c_str(), authRsp.length());
return authRsp;
}
bool StaStateMachine::PreWpaEapUmtsAuthEvent()
{
CardType cardType;
int32_t ret = GetCardType(cardType);
if (ret != 0) {
LOGE("failed to get cardType: %{public}d", ret);
return false;
}
if (cardType == CardType::SINGLE_MODE_SIM_CARD) {
LOGE("invalid cardType: %{public}d", cardType);
return false;
}
return true;
}
std::vector<uint8_t> StaStateMachine::FillUmtsAuthReq(EapSimUmtsAuthParam &param)
{
// request data format: [RAND LENGTH][RAND][AUTN LENGTH][AUTN]
std::vector<uint8_t> inputChallenge;
// rand hexadecimal string convert to binary
char rand[MAX_RAND_STR_LEN + 1] = { 0 };
if (strncpy_s(rand, sizeof(rand), param.rand.c_str(), param.rand.length()) != EOK) {
LOGE("%{public}s: failed to copy rand", __func__);
return inputChallenge;
}
uint8_t randArray[UMTS_AUTH_CHALLENGE_RAND_LEN];
int32_t ret = HexString2Byte(rand, randArray, sizeof(randArray));
if (ret != 0) {
LOGE("%{public}s: failed to convert to rand", __func__);
return inputChallenge;
}
// [RAND LENGTH]: rand length
inputChallenge.push_back(sizeof(randArray));
// [RAND]: rand data
for (size_t i = 0; i < sizeof(randArray); i++) {
inputChallenge.push_back(randArray[i]);
}
// autn hexadecimal string convert to binary
char autn[MAX_AUTN_STR_LEN + 1] = { 0 };
if (strncpy_s(autn, sizeof(autn), param.autn.c_str(), param.autn.length()) != EOK) {
LOGE("%{public}s: failed to copy autn", __func__);
return inputChallenge;
}
uint8_t autnArray[UMTS_AUTH_CHALLENGE_RAND_LEN];
ret = HexString2Byte(autn, autnArray, sizeof(autnArray));
if (ret != 0) {
LOGE("%{public}s: failed to convert to autn", __func__);
return inputChallenge;
}
// [AUTN LENGTH]: autn length
inputChallenge.push_back(sizeof(autnArray));
// [AUTN]: autn data
for (size_t i = 0; i < sizeof(autnArray); i++) {
inputChallenge.push_back(autnArray[i]);
}
return inputChallenge;
}
std::string StaStateMachine::ParseAndFillUmtsAuthParam(std::vector<uint8_t> &nonce)
{
std::string authReq;
uint8_t tag = nonce[UMTS_AUTH_CHALLENGE_RESULT_INDEX]; // nonce[0]: the 1st byte is authentication type
if (tag == UMTS_AUTH_TYPE_TAG) {
char nonceBuf[UMTS_AUTH_RESPONSE_CONENT_LEN * 2 + 1] = { 0 }; // length of auth data
Byte2HexString(&nonce[0], UMTS_AUTH_RESPONSE_CONENT_LEN, nonceBuf, sizeof(nonceBuf));
LOGD("Raw Response: %{private}s", nonceBuf);
authReq = "UMTS-AUTH:";
// res
uint8_t resLen = nonce[UMTS_AUTH_CHALLENGE_DATA_START_IDNEX]; // nonce[1]: the 2nd byte is the length of res
int resOffset = UMTS_AUTH_CHALLENGE_DATA_START_IDNEX + 1;
std::string res;
char resBuf[MAX_RES_STR_LEN + 1] = { 0 };
/* nonce[2]~nonce[9]: the 3rd byte ~ 10th byte is res data */
Byte2HexString(&nonce[resOffset], resLen, resBuf, sizeof(resBuf));
LOGD("%{public}s resLen: %{public}d, resBuf: %{private}s", __func__, resLen, resBuf);
// ck
int ckOffset = resOffset + resLen;
uint8_t ckLen = nonce[ckOffset]; // nonce[10]: the 11th byte is ck length
std::string ck;
char ckBuf[MAX_CK_STR_LEN + 1] = { 0 };
/* nonce[11]~nonce[26]: the 12th byte ~ 27th byte is ck data */
Byte2HexString(&nonce[ckOffset + 1], ckLen, ckBuf, sizeof(ckBuf));
LOGD("ckLen: %{public}d, ckBuf:%{private}s", ckLen, ckBuf);
// ik
int ikOffset = ckOffset + ckLen + 1;
uint8_t ikLen = nonce[ikOffset]; // nonce[27]: the 28th byte is the length of ik
std::string ik;
char ikBuf[MAX_IK_STR_LEN + 1] = { 0 };
/* nonce[28]~nonce[43]: the 29th byte ~ 44th byte is ck data */
Byte2HexString(&nonce[ikOffset + 1], ikLen, ikBuf, sizeof(ikBuf));
LOGD("ikLen: %{public}d, ikBuf:%{private}s", ikLen, ikBuf);
std::string authRsp = std::string(ikBuf) + ":" + std::string(ckBuf) + ":" + std::string(resBuf);
authReq += authRsp;
LOGD("%{public}s ik: %{private}s, ck: %{private}s, res: %{private}s, authRsp: %{private}s",
__func__, ikBuf, ckBuf, resBuf, authRsp.c_str());
} else {
authReq = "UMTS-AUTS:";
// auts
uint8_t autsLen = nonce[UMTS_AUTH_CHALLENGE_DATA_START_IDNEX];
LOGD("autsLen: %{public}d", autsLen);
int offset = UMTS_AUTH_CHALLENGE_DATA_START_IDNEX + 1;
std::string auts;
char autsBuf[MAX_AUTN_STR_LEN + 1] = { 0 };
Byte2HexString(&nonce[offset], autsLen, autsBuf, sizeof(autsBuf));
LOGD("%{public}s auts: %{private}s", __func__, auts.c_str());
std::string authRsp = auts;
authReq += authRsp;
LOGD("%{public}s authRsp: %{private}s", __func__, authRsp.c_str());
}
return authReq;
}
std::string StaStateMachine::GetUmtsAuthResponse(EapSimUmtsAuthParam &param)
{
// request data format: [RAND LENGTH][RAND][AUTN LENGTH][AUTN]
std::vector<uint8_t> inputChallenge = FillUmtsAuthReq(param);
if (inputChallenge.size() != UMTS_AUTH_REQUEST_CONTENT_LEN) {
return "";
}
std::string challenge = EncodeBase64(inputChallenge);
return SimAkaAuth(challenge, SIM_AUTH_EAP_AKA_TYPE);
}
void StaStateMachine::DealWpaEapSimAuthEvent(InternalMessage *msg)
{
if (msg == NULL) {
LOGE("%{public}s: msg is null", __func__);
return;
}
EapSimGsmAuthParam param;
msg->GetMessageObj(param);
LOGI("%{public}s size: %{public}zu", __func__, param.rands.size());
std::string cmd = "GSM-AUTH:";
if (param.rands.size() <= 0) {
LOGE("%{public}s: invalid rands", __func__);
return;
}
std::string authRsp = GetGsmAuthResponseWithLength(param);
if (authRsp.empty()) {
authRsp = GetGsmAuthResponseWithoutLength(param);
if (authRsp.empty()) {
LOGE("failed to sim authentication");
return;
}
}
cmd += authRsp;
if (WifiStaHalInterface::GetInstance().ShellCmd("wlan0", cmd) != WIFI_IDL_OPT_OK) {
LOGI("%{public}s: failed to send the message, authReq: %{private}s", __func__, cmd.c_str());
return;
}
LOGD("%{public}s: success to send the message, authReq: %{private}s", __func__, cmd.c_str());
}
void StaStateMachine::DealWpaEapUmtsAuthEvent(InternalMessage *msg)
{
if (msg == NULL) {
LOGE("%{public}s: msg is null", __func__);
return;
}
EapSimUmtsAuthParam param;
msg->GetMessageObj(param);
if (param.rand.empty() || param.autn.empty()) {
LOGE("invalid rand = %{public}zu or autn = %{public}zu", param.rand.length(), param.autn.length());
return;
}
LOGD("%{public}s rand: %{private}s, autn: %{private}s", __func__, param.rand.c_str(), param.autn.c_str());
if (!PreWpaEapUmtsAuthEvent()) {
return;
}
// get challenge information
std::string response = GetUmtsAuthResponse(param);
if (response.empty()) {
LOGE("response is empty");
return;
}
// parse authentication information
std::vector<uint8_t> nonce;
if (!DecodeBase64(response, nonce)) {
LOGE("%{public}s: failed to decode aka authentication, size:%{public}zu", __func__, nonce.size());
return;
}
// data format: [0xdb][RES Length][RES][CK Length][CK][IK Length][IK]
uint8_t tag = nonce[UMTS_AUTH_CHALLENGE_RESULT_INDEX];
if ((tag != UMTS_AUTH_TYPE_TAG) && (tag != UMTS_AUTS_TYPE_TAG)) {
LOGE("%{public}s: unsupport type: 0x%{public}02x", __func__, tag);
return;
}
LOGI("tag: 0x%{public}02x", tag);
// request authentication to wpa
std::string reqCmd = ParseAndFillUmtsAuthParam(nonce);
if (WifiStaHalInterface::GetInstance().ShellCmd("wlan0", reqCmd) != WIFI_IDL_OPT_OK) {
LOGI("%{public}s: failed to send the message, authReq: %{private}s", __func__, reqCmd.c_str());
return;
}
LOGD("%{public}s: success to send the message, authReq: %{private}s", __func__, reqCmd.c_str());
}
#endif
/* --------------------------- state machine Separating State ------------------------------ */
StaStateMachine::SeparatingState::SeparatingState() : State("SeparatingState")
{}

View File

@ -35,10 +35,18 @@
#include "want.h"
#include "wifi_net_agent.h"
#include "wifi_net_observer.h"
#include "sim_state_type.h"
#include "core_service_client.h"
#include "cellular_data_client.h"
#include "core_manager_inner.h"
#include "telephony_errors.h"
#endif
namespace OHOS {
namespace Wifi {
#ifndef OHOS_ARCH_LITE
using namespace OHOS::Telephony;
#endif
constexpr int STA_CONNECT_MODE = 1;
constexpr int STA_SCAN_ONLY_MODE = 2;
constexpr int STA_CAN_ONLY_WITH_WIFI_OFF_MODE = 3;
@ -946,8 +954,132 @@ private:
* @param msg - Message body received by the state machine[in]
*/
void DealScreenStateChangedEvent(InternalMessage *msg);
/**
* @Description set external sim
*
* @param ifName - port name(in)
* @param eap - eap method(in)
* @Return success: 0 fail: others
*/
ErrCode SetExternalSim(const std::string ifName, const std::string &eap, int value) const;
#ifndef OHOS_ARCH_LITE
/**
* @Description Get slot id.
* @Return int32_t - 0:success, other value:failed
*/
int32_t GetDataSlotId();
/**
* @Description Get card type.
* @param cardType - card type
* @Return int32_t - 0:success, other value:failed
*/
int32_t GetCardType(CardType &cardType);
/**
* @Description Get default slot id.
* @param slotId - slot id
* @Return int32_t - 0 success, other value:failed
*/
int32_t GetDefaultId(int32_t slotId);
/**
* @Description Get card state.
* @param slotId - slot id
* @Return int32_t - card state
*/
int32_t GetSimCardState(int32_t slotId);
/**
* @Description verify simId.
* @param simId - sim id
* @Return int32_t - true: success, false: failed
*/
bool IsValidSimId(int32_t simId);
/**
* @Description Check whether the SIM card is a multi-SIM card.
* @Return int32_t - true: success, false: failed
*/
bool IsMultiSimEnabled();
/**
* @Description sim authenticate
* @param nonce - sim id
* @Return int32_t - 0:success, other value:failed
*/
std::string SimAkaAuth(const std::string &nonce, AuthType authType);
/**
* @Description Get SIM card authentication information.
* @param param - authentication information
* @Return int32_t - 0:success, other value:failed
*/
std::string GetGsmAuthResponseWithLength(EapSimGsmAuthParam param);
/**
* @Description Get SIM card authentication information.
* @param param - authentication information
* @Return int32_t - 0:success, other value:failed
*/
std::string GetGsmAuthResponseWithoutLength(EapSimGsmAuthParam param);
/**
* @Description sim authentication notify events
*
* @param msg: authentication data
*/
void DealWpaEapSimAuthEvent(InternalMessage *msg);
/**
* @Description aka/aka' authentication Pre-process
*
*/
bool PreWpaEapUmtsAuthEvent();
/**
* @Description fill aka/aka' authentication request message
*
* @param param: authentication data
*/
std::vector<uint8_t> FillUmtsAuthReq(EapSimUmtsAuthParam &param);
/**
* @Description fill aka/aka' authentication request message
*
* @param nonce: authentication data
*/
std::string ParseAndFillUmtsAuthParam(std::vector<uint8_t> &nonce);
/**
* @Description Get aka/aka' card authentication information
*
* @param param: authentication data
*/
std::string GetUmtsAuthResponse(EapSimUmtsAuthParam &param);
/**
* @Description aka/aka' authentication notify events
*
* @param msg: authentication data
*/
void DealWpaEapUmtsAuthEvent(InternalMessage *msg);
/**
* @Description Get the SIM card ID.
*
*/
int32_t GetSimId();
/**
* @Description Set the SIM card ID.
*
* @param id - Sim card id
*/
void SetSimId(int32_t simId);
/**
* @Description Subscribe system ability changed.
*/

View File

@ -228,9 +228,9 @@ bool WifiDeviceServiceImpl::CheckConfigEap(const WifiDeviceConfig &config)
}
return true;
} else {
WIFI_LOGE("EAP:%{public}s unsupported!", config.wifiEapConfig.eap.c_str());
WIFI_LOGW("EAP:%{public}s unsupported!", config.wifiEapConfig.eap.c_str());
}
return false;
return true;
}
bool WifiDeviceServiceImpl::CheckConfigPwd(const WifiDeviceConfig &config)

View File

@ -146,6 +146,8 @@ ohos_unittest("wifi_sta_unittest") {
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"cellular_data:tel_cellular_data_api",
"core_service:tel_core_service_api",
"dhcp:dhcp_sdk",
"hilog:libhilog",
"init:libbegetutil",

View File

@ -58,6 +58,8 @@ ohos_unittest("utils_unittest") {
"hisysevent:libhisysevent",
"ipc:ipc_single",
"jsoncpp:jsoncpp",
"openssl:libcrypto_shared",
"openssl:libssl_shared",
"samgr:samgr_proxy",
]

View File

@ -87,6 +87,8 @@ if (defined(ohos_lite)) {
"hisysevent:libhisysevent",
"ipc:ipc_single",
"jsoncpp:jsoncpp",
"openssl:libcrypto_shared",
"openssl:libssl_shared",
"samgr:samgr_proxy",
]

View File

@ -259,6 +259,11 @@ int FrequencyToChannel(int freq);
*/
int ChannelToFrequency(int channel);
bool IsOtherVapConnect();
int HexString2Byte(const char *hex, uint8_t *buf, size_t len);
void Byte2HexString(const uint8_t* byte, uint8_t bytesLen, char* hexstr, uint8_t hexstrLen);
bool DecodeBase64(const std::string &input, std::vector<uint8_t> &output);
std::string EncodeBase64(const std::vector<uint8_t> &input);
std::vector<std::string> getAuthInfo(const std::string &input, const std::string &delimiter);
} // namespace Wifi
} // namespace OHOS
#endif

View File

@ -17,7 +17,13 @@
#include <sstream>
#include <iterator>
#include <regex>
#ifndef OHOS_ARCH_LITE
#include <vector>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include "app_mgr_client.h"
#include "bundle_mgr_interface.h"
#include "if_system_ability_manager.h"
@ -56,6 +62,12 @@ constexpr int FREQ_CHANNEL_1 = 2412;
constexpr int FREQ_CHANNEL_36 = 5180;
constexpr int SECOND_TO_MICROSECOND = 1000 * 1000;
constexpr int MICROSECOND_TO_NANOSECOND = 1000;
const uint32_t BASE64_UNIT_ONE_PADDING = 1;
const uint32_t BASE64_UNIT_TWO_PADDING = 2;
const uint32_t BASE64_SRC_UNIT_SIZE = 3;
const uint32_t BASE64_DEST_UNIT_SIZE = 4;
static std::pair<std::string, int> g_brokerProcessInfo;
static std::string DataAnonymize(const std::string str, const char delim,
@ -398,5 +410,155 @@ bool IsOtherVapConnect()
return p2pOrHmlConnected && hotspotEnable;
}
static int Hex2num(char c)
{
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'a' && c <= 'f') {
return c - 'a' + 10; // convert to decimal
}
if (c >= 'A' && c <= 'F') {
return c - 'A' + 10; // convert to decimal
}
return -1;
}
int Hex2byte(const char *hex)
{
int a = Hex2num(*hex++);
if (a < 0) {
return -1;
}
int b = Hex2num(*hex++);
if (b < 0) {
return -1;
}
return (a << 4) | b; // convert to binary
}
int HexString2Byte(const char *hex, uint8_t *buf, size_t len)
{
size_t i;
int a;
const char *ipos = hex;
uint8_t *opos = buf;
for (i = 0; i < len; i++) {
a = Hex2byte(ipos);
if (a < 0) {
return -1;
}
*opos++ = a;
ipos += 2; // convert to binary
}
return 0;
}
void Byte2HexString(const uint8_t* byte, uint8_t bytesLen, char* hexstr, uint8_t hexstrLen)
{
if ((byte == nullptr) || (hexstr == nullptr)) {
WIFI_LOGE("%{public}s: invalid parameter", __func__);
return;
}
if (hexstrLen < bytesLen * 2) { // verify length
WIFI_LOGE("%{public}s: invalid byteLen:%{public}d or hexStrLen:%{public}d",
__func__, bytesLen, hexstrLen);
return;
}
WIFI_LOGI("%{public}s byteLen:%{public}d, hexStrLen:%{public}d", __func__, bytesLen, hexstrLen);
uint8_t hexstrIndex = 0;
for (uint8_t i = 0; i < bytesLen; i++) {
if (snprintf(hexstr + hexstrIndex, hexstrLen - hexstrIndex, "%02x", byte[i]) <= 0) {
WIFI_LOGI("%{public}s: failed to snprintf", __func__);
}
hexstrIndex += 2; // offset
if (hexstrIndex >= hexstrLen) {
break;
}
}
}
bool DecodeBase64(const std::string &input, std::vector<uint8_t> &output)
{
#ifndef OHOS_ARCH_LITE
WIFI_LOGD("%{public}s input:%{private}s, length:%{public}zu", __func__, input.c_str(), input.length());
if (input.length() % BASE64_DEST_UNIT_SIZE != 0) {
WIFI_LOGE("%{public}s: wrong data length for base64 encode string", __func__);
return false;
}
uint32_t decodedLen = input.length() * BASE64_SRC_UNIT_SIZE / BASE64_DEST_UNIT_SIZE;
if (input.at(input.length() - BASE64_UNIT_ONE_PADDING) == '=') {
decodedLen--;
if (input.at(input.length() - BASE64_UNIT_TWO_PADDING) == '=') {
decodedLen--;
}
}
output.resize(decodedLen);
BIO *b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO *bio = BIO_new_mem_buf(input.c_str(), input.length());
bio = BIO_push(b64, bio);
if (BIO_read(bio, &output[0], input.length()) != static_cast<int32_t>(decodedLen)) {
WIFI_LOGE("%{public}s: wrong data length for decoded buffer", __func__);
return false;
}
BIO_free_all(bio);
#endif
return true;
}
std::string EncodeBase64(const std::vector<uint8_t> &input)
{
#ifndef OHOS_ARCH_LITE
WIFI_LOGD("%{public}s: size:%{public}zu", __func__, input.size());
BIO *b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
BIO *bio = BIO_new(BIO_s_mem());
bio = BIO_push(b64, bio);
BIO_write(bio, &input[0], input.size());
BIO_flush(bio);
BUF_MEM *bptr = nullptr;
BIO_get_mem_ptr(bio, &bptr);
std::string output = "";
if (bptr != nullptr) {
std::vector<char> outputBuffer {};
WIFI_LOGI("%{public}s: length is %{public}zu", __func__, bptr->length);
outputBuffer.insert(outputBuffer.end(), bptr->data, bptr->data + bptr->length);
outputBuffer[bptr->length] = 0;
output = static_cast<char*>(&outputBuffer[0]);
}
BIO_free_all(bio);
return output;
#else
return "";
#endif
}
std::vector<std::string> getAuthInfo(const std::string &input, const std::string &delimiter)
{
size_t pos = 0;
std::string token;
std::vector<std::string> results;
std::string splitStr = input;
WIFI_LOGD("%{public}s input:%{private}s, delimiter:%{public}s", __func__, input.c_str(), delimiter.c_str());
while ((pos = splitStr.find(delimiter)) != std::string::npos) {
token = splitStr.substr(0, pos);
if (token.length() > 0) {
results.push_back(token);
splitStr.erase(0, pos + delimiter.length());
WIFI_LOGD("%{public}s token:%{private}s, splitStr:%{public}s", __func__, token.c_str(), splitStr.c_str());
}
}
results.push_back(splitStr);
WIFI_LOGD("%{public}s size:%{public}zu", __func__, results.size());
return results;
}
} // namespace Wifi
} // namespace OHOS