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_api_event_reporter.h"
24 #include "user_auth_helper.h"
25 #include "user_auth_client_impl.h"
26
27 #define LOG_TAG "USER_AUTH_NAPI"
28
29 namespace OHOS {
30 namespace UserIam {
31 namespace UserAuth {
32 namespace {
33 const std::string AUTH_EVENT_RESULT = "result";
34 const std::string AUTH_EVENT_TIP = "tip";
35 }
36
GetAvailableStatusInner(napi_env env,napi_callback_info info)37 UserAuthResultCode AuthInstanceV9::GetAvailableStatusInner(napi_env env, napi_callback_info info)
38 {
39 napi_value argv[ARGS_TWO];
40 size_t argc = ARGS_TWO;
41 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
42 if (ret != napi_ok) {
43 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
44 return UserAuthResultCode::GENERAL_ERROR;
45 }
46 if (argc != ARGS_TWO) {
47 IAM_LOGE("invalid param, argc:%{public}zu", argc);
48 std::string msgStr = "Parameter error. The number of parameters should be 2.";
49 return UserAuthNapiHelper::ThrowErrorMsg(env, UserAuthResultCode::OHOS_INVALID_PARAM, msgStr);
50 }
51 int32_t type;
52 ret = napi_get_value_int32(env, argv[PARAM0], &type);
53 if (ret != napi_ok) {
54 IAM_LOGE("napi_get_value_int32 fail:%{public}d", ret);
55 return UserAuthResultCode::GENERAL_ERROR;
56 }
57 if (!UserAuthHelper::CheckUserAuthType(type)) {
58 IAM_LOGE("CheckUserAuthType fail");
59 return UserAuthResultCode::TYPE_NOT_SUPPORT;
60 }
61 uint32_t level;
62 ret = napi_get_value_uint32(env, argv[PARAM1], &level);
63 if (ret != napi_ok) {
64 IAM_LOGE("napi_get_value_int32 fail:%{public}d", ret);
65 return UserAuthResultCode::GENERAL_ERROR;
66 }
67 if (!UserAuthHelper::CheckAuthTrustLevel(level)) {
68 IAM_LOGE("CheckAuthTrustLevel fail");
69 return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT;
70 }
71 int32_t status = UserAuthClientImpl::Instance().GetNorthAvailableStatus(API_VERSION_9, AuthType(type),
72 AuthTrustLevel(level));
73 IAM_LOGI("result = %{public}d", status);
74 if (status == PIN_EXPIRED) {
75 return UserAuthResultCode::PIN_EXPIRED;
76 }
77 return UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV9(status));
78 }
79
GetAvailableStatus(napi_env env,napi_callback_info info)80 UserAuthResultCode AuthInstanceV9::GetAvailableStatus(napi_env env, napi_callback_info info)
81 {
82 UserAuthApiEventReporter reporter("getAvailableStatus");
83 UserAuthResultCode resultCode = GetAvailableStatusInner(env, info);
84 if (resultCode != UserAuthResultCode::SUCCESS) {
85 reporter.ReportFailed(resultCode);
86 } else {
87 reporter.ReportSuccess();
88 }
89 return resultCode;
90 }
91
AuthInstanceV9(napi_env env)92 AuthInstanceV9::AuthInstanceV9(napi_env env) : callback_(Common::MakeShared<UserAuthCallbackV9>(env))
93 {
94 if (callback_ == nullptr) {
95 IAM_LOGE("get null callback");
96 }
97 }
98
InitChallenge(napi_env env,napi_value value)99 napi_status AuthInstanceV9::InitChallenge(napi_env env, napi_value value)
100 {
101 challenge_.clear();
102 napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
103 if (ret == napi_ok) {
104 IAM_LOGI("challenge is null");
105 return ret;
106 }
107 ret = UserAuthNapiHelper::GetUint8ArrayValue(env, value, MAX_CHALLENG_LEN, challenge_);
108 if (ret != napi_ok) {
109 IAM_LOGE("GetUint8ArrayValue fail:%{public}d", ret);
110 }
111 IAM_LOGI("challenge size:%{public}zu", challenge_.size());
112 return ret;
113 }
114
Init(napi_env env,napi_callback_info info)115 UserAuthResultCode AuthInstanceV9::Init(napi_env env, napi_callback_info info)
116 {
117 if (callback_ == nullptr) {
118 IAM_LOGE("callback is null");
119 return UserAuthResultCode::GENERAL_ERROR;
120 }
121 napi_value argv[ARGS_THREE];
122 size_t argc = ARGS_THREE;
123 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
124 if (ret != napi_ok) {
125 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
126 return UserAuthResultCode::GENERAL_ERROR;
127 }
128 if (argc != ARGS_THREE) {
129 IAM_LOGE("invalid param, argc:%{public}zu", argc);
130 return UserAuthResultCode::OHOS_INVALID_PARAM;
131 }
132 challenge_.clear();
133 ret = InitChallenge(env, argv[PARAM0]);
134 if (ret != napi_ok) {
135 IAM_LOGE("InitChallenge fail:%{public}d", ret);
136 return UserAuthResultCode::OHOS_INVALID_PARAM;
137 }
138 int32_t authType;
139 ret = UserAuthNapiHelper::GetInt32Value(env, argv[PARAM1], authType);
140 if (ret != napi_ok) {
141 IAM_LOGE("GetInt32Value fail:%{public}d", ret);
142 return UserAuthResultCode::OHOS_INVALID_PARAM;
143 }
144 if (!UserAuthNapiHelper::CheckAuthType(authType)) {
145 IAM_LOGE("CheckAuthType fail");
146 return UserAuthResultCode::TYPE_NOT_SUPPORT;
147 }
148 authType_ = AuthType(authType);
149 uint32_t authTrustLevel;
150 ret = UserAuthNapiHelper::GetUint32Value(env, argv[PARAM2], authTrustLevel);
151 if (ret != napi_ok) {
152 IAM_LOGE("GetUint32Value fail:%{public}d", ret);
153 return UserAuthResultCode::OHOS_INVALID_PARAM;
154 }
155 if (!UserAuthHelper::CheckAuthTrustLevel(authTrustLevel)) {
156 IAM_LOGE("CheckAuthTrustLevel fail");
157 return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT;
158 }
159 authTrustLevel_ = AuthTrustLevel(authTrustLevel);
160 return UserAuthResultCode::SUCCESS;
161 }
162
GetCallback(napi_env env,napi_value value)163 std::shared_ptr<JsRefHolder> AuthInstanceV9::GetCallback(napi_env env, napi_value value)
164 {
165 napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_object);
166 if (ret != napi_ok) {
167 IAM_LOGE("CheckNapiType fail:%{public}d", ret);
168 return nullptr;
169 }
170 napi_value callbackValue;
171 ret = napi_get_named_property(env, value, "callback", &callbackValue);
172 if (ret != napi_ok) {
173 IAM_LOGE("napi_get_named_property fail:%{public}d", ret);
174 return nullptr;
175 }
176 return Common::MakeShared<JsRefHolder>(env, callbackValue);
177 }
178
On(napi_env env,napi_callback_info info)179 UserAuthResultCode AuthInstanceV9::On(napi_env env, napi_callback_info info)
180 {
181 if (callback_ == nullptr) {
182 IAM_LOGE("callback is null");
183 return UserAuthResultCode::GENERAL_ERROR;
184 }
185 napi_value argv[ARGS_TWO];
186 size_t argc = ARGS_TWO;
187 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
188 if (ret != napi_ok) {
189 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
190 return UserAuthResultCode::GENERAL_ERROR;
191 }
192 if (argc != ARGS_TWO) {
193 IAM_LOGE("invalid param, argc:%{public}zu", argc);
194 return UserAuthResultCode::OHOS_INVALID_PARAM;
195 }
196 static const size_t maxLen = 10;
197 char str[maxLen] = {0};
198 size_t len = maxLen;
199 ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
200 if (ret != napi_ok) {
201 IAM_LOGE("GetStrValue fail:%{public}d", ret);
202 return UserAuthResultCode::OHOS_INVALID_PARAM;
203 }
204 auto callbackRef = GetCallback(env, argv[PARAM1]);
205 if (callbackRef == nullptr || !callbackRef->IsValid()) {
206 IAM_LOGE("GetCallback fail");
207 return UserAuthResultCode::OHOS_INVALID_PARAM;
208 }
209 if (str == AUTH_EVENT_RESULT) {
210 IAM_LOGI("SetResultCallback");
211 callback_->SetResultCallback(callbackRef);
212 return UserAuthResultCode::SUCCESS;
213 } else if (str == AUTH_EVENT_TIP) {
214 IAM_LOGI("SetAcquireCallback");
215 callback_->SetAcquireCallback(callbackRef);
216 return UserAuthResultCode::SUCCESS;
217 } else {
218 IAM_LOGE("invalid event:%{public}s", str);
219 return UserAuthResultCode::OHOS_INVALID_PARAM;
220 }
221 }
222
Off(napi_env env,napi_callback_info info)223 UserAuthResultCode AuthInstanceV9::Off(napi_env env, napi_callback_info info)
224 {
225 if (callback_ == nullptr) {
226 IAM_LOGE("callback is null");
227 return UserAuthResultCode::GENERAL_ERROR;
228 }
229 napi_value argv[ARGS_ONE];
230 size_t argc = ARGS_ONE;
231 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
232 if (ret != napi_ok) {
233 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
234 return UserAuthResultCode::GENERAL_ERROR;
235 }
236 if (argc != ARGS_ONE) {
237 IAM_LOGE("invalid param, argc:%{public}zu", argc);
238 return UserAuthResultCode::OHOS_INVALID_PARAM;
239 }
240 static const size_t maxLen = 10;
241 char str[maxLen] = {0};
242 size_t len = maxLen;
243 ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
244 if (ret != napi_ok) {
245 IAM_LOGE("GetStrValue fail:%{public}d", ret);
246 return UserAuthResultCode::GENERAL_ERROR;
247 }
248 if (str == AUTH_EVENT_RESULT) {
249 callback_->ClearResultCallback();
250 IAM_LOGI("clear result callback");
251 return UserAuthResultCode::SUCCESS;
252 } else if (str == AUTH_EVENT_TIP) {
253 callback_->ClearAcquireCallback();
254 IAM_LOGI("clear tip callback");
255 return UserAuthResultCode::SUCCESS;
256 } else {
257 IAM_LOGE("invalid event:%{public}s", str);
258 return UserAuthResultCode::OHOS_INVALID_PARAM;
259 }
260 }
261
Start(napi_env env,napi_callback_info info)262 UserAuthResultCode AuthInstanceV9::Start(napi_env env, napi_callback_info info)
263 {
264 if (callback_ == nullptr) {
265 IAM_LOGE("callback is null");
266 return UserAuthResultCode::GENERAL_ERROR;
267 }
268 napi_value argv[ARGS_ONE];
269 size_t argc = ARGS_ONE;
270 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
271 if (ret != napi_ok) {
272 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
273 return UserAuthResultCode::GENERAL_ERROR;
274 }
275 if (argc != ARGS_ZERO) {
276 IAM_LOGE("invalid param, argc:%{public}zu", argc);
277 return UserAuthResultCode::OHOS_INVALID_PARAM;
278 }
279 std::lock_guard<std::mutex> guard(mutex_);
280 if (isAuthStarted_) {
281 IAM_LOGE("auth already started");
282 return UserAuthResultCode::GENERAL_ERROR;
283 }
284 contextId_ = UserAuthClientImpl::Instance().BeginNorthAuthentication(API_VERSION_9,
285 challenge_, authType_, authTrustLevel_, callback_);
286 isAuthStarted_ = true;
287 return UserAuthResultCode::SUCCESS;
288 }
289
Cancel(napi_env env,napi_callback_info info)290 UserAuthResultCode AuthInstanceV9::Cancel(napi_env env, napi_callback_info info)
291 {
292 if (callback_ == nullptr) {
293 IAM_LOGE("callback is null");
294 return UserAuthResultCode::GENERAL_ERROR;
295 }
296 napi_value argv[ARGS_ONE];
297 size_t argc = ARGS_ONE;
298 napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
299 if (ret != napi_ok) {
300 IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
301 return UserAuthResultCode::GENERAL_ERROR;
302 }
303 if (argc != ARGS_ZERO) {
304 IAM_LOGE("invalid param, argc:%{public}zu", argc);
305 return UserAuthResultCode::OHOS_INVALID_PARAM;
306 }
307 std::lock_guard<std::mutex> guard(mutex_);
308 if (!isAuthStarted_) {
309 IAM_LOGE("auth not started");
310 return UserAuthResultCode::GENERAL_ERROR;
311 }
312 int32_t result = UserAuthClient::GetInstance().CancelAuthentication(contextId_);
313 if (result != ResultCode::SUCCESS) {
314 IAM_LOGE("CancelAuthentication fail:%{public}d", result);
315 return UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV9(result));
316 }
317 return UserAuthResultCode::SUCCESS;
318 }
319 } // namespace UserAuth
320 } // namespace UserIam
321 } // namespace OHOS
322