1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "auth_instance_v9.h"
17
18 #include <string>
19
20 #include "iam_logger.h"
21 #include "iam_ptr.h"
22
23 #include "user_auth_client_impl.h"
24
25 #define LOG_TAG "USER_AUTH_NAPI"
26
27 namespace OHOS {
28 namespace UserIam {
29 namespace UserAuth {
30 namespace {
31 const std::string AUTH_EVENT_RESULT = "result";
32 const std::string AUTH_EVENT_TIP = "tip";
33 }
34
GetAvailableStatus(napi_env env,napi_callback_info info)35 UserAuthResultCode AuthInstanceV9::GetAvailableStatus(napi_env env, napi_callback_info info)
36 {
37 napi_value argv[ARGS_TWO];
38 size_t argc = ARGS_TWO;
39 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
40 if (ret != napi_ok) {
41 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
42 return UserAuthResultCode::GENERAL_ERROR;
43 }
44 if (argc != ARGS_TWO) {
45 IAM_LOGE("invalid param, argc:%{public}zu", argc);
46 std::string msgStr = "Parameter error. The number of parameters should be 2.";
47 return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
48 }
49 int32_t type;
50 ret = napi_get_value_int32(env, argv[PARAM0], &type);
51 if (ret != napi_ok) {
52 IAM_LOGE("napi_get_value_int32 fail:%{public}d", ret);
53 return UserAuthResultCode::GENERAL_ERROR;
54 }
55 if (!UserAuthNapiHelper::CheckUserAuthType(type)) {
56 IAM_LOGE("CheckUserAuthType fail");
57 return UserAuthResultCode::TYPE_NOT_SUPPORT;
58 }
59 uint32_t level;
60 ret = napi_get_value_uint32(env, argv[PARAM1], &level);
61 if (ret != napi_ok) {
62 IAM_LOGE("napi_get_value_int32 fail:%{public}d", ret);
63 return UserAuthResultCode::GENERAL_ERROR;
64 }
65 if (!UserAuthNapiHelper::CheckAuthTrustLevel(level)) {
66 IAM_LOGE("CheckAuthTrustLevel fail");
67 return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT;
68 }
69 AuthType authType = AuthType(type);
70 AuthTrustLevel authTrustLevel = AuthTrustLevel(level);
71 int32_t status = UserAuthClientImpl::Instance().GetNorthAvailableStatus(API_VERSION_9, authType, authTrustLevel);
72 IAM_LOGI("result = %{public}d", status);
73 if (status == PIN_EXPIRED) {
74 return UserAuthResultCode::PIN_EXPIRED;
75 }
76 return UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV9(status));
77 }
78
AuthInstanceV9(napi_env env)79 AuthInstanceV9::AuthInstanceV9(napi_env env) : callback_(Common::MakeShared<UserAuthCallbackV9>(env))
80 {
81 if (callback_ == nullptr) {
82 IAM_LOGE("get null callback");
83 }
84 }
85
InitChallenge(napi_env env,napi_value value)86 napi_status AuthInstanceV9::InitChallenge(napi_env env, napi_value value)
87 {
88 challenge_.clear();
89 napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
90 if (ret == napi_ok) {
91 IAM_LOGI("challenge is null");
92 return ret;
93 }
94 ret = UserAuthNapiHelper::GetUint8ArrayValue(env, value, MAX_CHALLENG_LEN, challenge_);
95 if (ret != napi_ok) {
96 IAM_LOGE("GetUint8ArrayValue fail:%{public}d", ret);
97 }
98 IAM_LOGI("challenge size:%{public}zu", challenge_.size());
99 return ret;
100 }
101
Init(napi_env env,napi_callback_info info)102 UserAuthResultCode AuthInstanceV9::Init(napi_env env, napi_callback_info info)
103 {
104 if (callback_ == nullptr) {
105 IAM_LOGE("callback is null");
106 return UserAuthResultCode::GENERAL_ERROR;
107 }
108 napi_value argv[ARGS_THREE];
109 size_t argc = ARGS_THREE;
110 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
111 if (ret != napi_ok) {
112 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
113 return UserAuthResultCode::GENERAL_ERROR;
114 }
115 if (argc != ARGS_THREE) {
116 IAM_LOGE("invalid param, argc:%{public}zu", argc);
117 return UserAuthResultCode::OHOS_INVALID_PARAM;
118 }
119 challenge_.clear();
120 ret = InitChallenge(env, argv[PARAM0]);
121 if (ret != napi_ok) {
122 IAM_LOGE("InitChallenge fail:%{public}d", ret);
123 return UserAuthResultCode::OHOS_INVALID_PARAM;
124 }
125 int32_t authType;
126 ret = UserAuthNapiHelper::GetInt32Value(env, argv[PARAM1], authType);
127 if (ret != napi_ok) {
128 IAM_LOGE("GetInt32Value fail:%{public}d", ret);
129 return UserAuthResultCode::OHOS_INVALID_PARAM;
130 }
131 if (!UserAuthNapiHelper::CheckAuthType(authType)) {
132 IAM_LOGE("CheckAuthType fail");
133 return UserAuthResultCode::TYPE_NOT_SUPPORT;
134 }
135 authType_ = AuthType(authType);
136 uint32_t authTrustLevel;
137 ret = UserAuthNapiHelper::GetUint32Value(env, argv[PARAM2], authTrustLevel);
138 if (ret != napi_ok) {
139 IAM_LOGE("GetUint32Value fail:%{public}d", ret);
140 return UserAuthResultCode::OHOS_INVALID_PARAM;
141 }
142 if (!UserAuthNapiHelper::CheckAuthTrustLevel(authTrustLevel)) {
143 IAM_LOGE("CheckAuthTrustLevel fail");
144 return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT;
145 }
146 authTrustLevel_ = AuthTrustLevel(authTrustLevel);
147 return UserAuthResultCode::SUCCESS;
148 }
149
GetCallback(napi_env env,napi_value value)150 std::shared_ptr<JsRefHolder> AuthInstanceV9::GetCallback(napi_env env, napi_value value)
151 {
152 napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_object);
153 if (ret != napi_ok) {
154 IAM_LOGE("CheckNapiType fail:%{public}d", ret);
155 return nullptr;
156 }
157 napi_value callbackValue;
158 ret = napi_get_named_property(env, value, "callback", &callbackValue);
159 if (ret != napi_ok) {
160 IAM_LOGE("napi_get_named_property fail:%{public}d", ret);
161 return nullptr;
162 }
163 return Common::MakeShared<JsRefHolder>(env, callbackValue);
164 }
165
On(napi_env env,napi_callback_info info)166 UserAuthResultCode AuthInstanceV9::On(napi_env env, napi_callback_info info)
167 {
168 if (callback_ == nullptr) {
169 IAM_LOGE("callback is null");
170 return UserAuthResultCode::GENERAL_ERROR;
171 }
172 napi_value argv[ARGS_TWO];
173 size_t argc = ARGS_TWO;
174 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
175 if (ret != napi_ok) {
176 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
177 return UserAuthResultCode::GENERAL_ERROR;
178 }
179 if (argc != ARGS_TWO) {
180 IAM_LOGE("invalid param, argc:%{public}zu", argc);
181 return UserAuthResultCode::OHOS_INVALID_PARAM;
182 }
183 static const size_t maxLen = 10;
184 char str[maxLen] = {0};
185 size_t len = maxLen;
186 ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
187 if (ret != napi_ok) {
188 IAM_LOGE("GetStrValue fail:%{public}d", ret);
189 return UserAuthResultCode::OHOS_INVALID_PARAM;
190 }
191 auto callbackRef = GetCallback(env, argv[PARAM1]);
192 if (callbackRef == nullptr || !callbackRef->IsValid()) {
193 IAM_LOGE("GetCallback fail");
194 return UserAuthResultCode::OHOS_INVALID_PARAM;
195 }
196 if (str == AUTH_EVENT_RESULT) {
197 IAM_LOGI("SetResultCallback");
198 callback_->SetResultCallback(callbackRef);
199 return UserAuthResultCode::SUCCESS;
200 } else if (str == AUTH_EVENT_TIP) {
201 IAM_LOGI("SetAcquireCallback");
202 callback_->SetAcquireCallback(callbackRef);
203 return UserAuthResultCode::SUCCESS;
204 } else {
205 IAM_LOGE("invalid event:%{public}s", str);
206 return UserAuthResultCode::OHOS_INVALID_PARAM;
207 }
208 }
209
Off(napi_env env,napi_callback_info info)210 UserAuthResultCode AuthInstanceV9::Off(napi_env env, napi_callback_info info)
211 {
212 if (callback_ == nullptr) {
213 IAM_LOGE("callback is null");
214 return UserAuthResultCode::GENERAL_ERROR;
215 }
216 napi_value argv[ARGS_ONE];
217 size_t argc = ARGS_ONE;
218 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
219 if (ret != napi_ok) {
220 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
221 return UserAuthResultCode::GENERAL_ERROR;
222 }
223 if (argc != ARGS_ONE) {
224 IAM_LOGE("invalid param, argc:%{public}zu", argc);
225 return UserAuthResultCode::OHOS_INVALID_PARAM;
226 }
227 static const size_t maxLen = 10;
228 char str[maxLen] = {0};
229 size_t len = maxLen;
230 ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
231 if (ret != napi_ok) {
232 IAM_LOGE("GetStrValue fail:%{public}d", ret);
233 return UserAuthResultCode::GENERAL_ERROR;
234 }
235 if (str == AUTH_EVENT_RESULT) {
236 callback_->ClearResultCallback();
237 IAM_LOGI("clear result callback");
238 return UserAuthResultCode::SUCCESS;
239 } else if (str == AUTH_EVENT_TIP) {
240 callback_->ClearAcquireCallback();
241 IAM_LOGI("clear tip callback");
242 return UserAuthResultCode::SUCCESS;
243 } else {
244 IAM_LOGE("invalid event:%{public}s", str);
245 return UserAuthResultCode::OHOS_INVALID_PARAM;
246 }
247 }
248
Start(napi_env env,napi_callback_info info)249 UserAuthResultCode AuthInstanceV9::Start(napi_env env, napi_callback_info info)
250 {
251 if (callback_ == nullptr) {
252 IAM_LOGE("callback is null");
253 return UserAuthResultCode::GENERAL_ERROR;
254 }
255 napi_value argv[ARGS_ONE];
256 size_t argc = ARGS_ONE;
257 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
258 if (ret != napi_ok) {
259 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
260 return UserAuthResultCode::GENERAL_ERROR;
261 }
262 if (argc != ARGS_ZERO) {
263 IAM_LOGE("invalid param, argc:%{public}zu", argc);
264 return UserAuthResultCode::OHOS_INVALID_PARAM;
265 }
266 std::lock_guard<std::mutex> guard(mutex_);
267 if (isAuthStarted_) {
268 IAM_LOGE("auth already started");
269 return UserAuthResultCode::GENERAL_ERROR;
270 }
271 contextId_ = UserAuthClientImpl::Instance().BeginNorthAuthentication(API_VERSION_9,
272 challenge_, authType_, authTrustLevel_, callback_);
273 isAuthStarted_ = true;
274 return UserAuthResultCode::SUCCESS;
275 }
276
Cancel(napi_env env,napi_callback_info info)277 UserAuthResultCode AuthInstanceV9::Cancel(napi_env env, napi_callback_info info)
278 {
279 if (callback_ == nullptr) {
280 IAM_LOGE("callback is null");
281 return UserAuthResultCode::GENERAL_ERROR;
282 }
283 napi_value argv[ARGS_ONE];
284 size_t argc = ARGS_ONE;
285 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
286 if (ret != napi_ok) {
287 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
288 return UserAuthResultCode::GENERAL_ERROR;
289 }
290 if (argc != ARGS_ZERO) {
291 IAM_LOGE("invalid param, argc:%{public}zu", argc);
292 return UserAuthResultCode::OHOS_INVALID_PARAM;
293 }
294 std::lock_guard<std::mutex> guard(mutex_);
295 if (!isAuthStarted_) {
296 IAM_LOGE("auth not started");
297 return UserAuthResultCode::GENERAL_ERROR;
298 }
299 int32_t result = UserAuthClient::GetInstance().CancelAuthentication(contextId_);
300 if (result != ResultCode::SUCCESS) {
301 IAM_LOGE("CancelAuthentication fail:%{public}d", result);
302 return UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV9(result));
303 }
304 return UserAuthResultCode::SUCCESS;
305 }
306 } // namespace UserAuth
307 } // namespace UserIam
308 } // namespace OHOS
309