• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 "el5_filekey_manager_napi.h"
17 
18 #include <unordered_map>
19 
20 #include "data_lock_type.h"
21 #include "el5_filekey_manager_error.h"
22 #include "el5_filekey_manager_kit.h"
23 #include "el5_filekey_manager_log.h"
24 
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 constexpr uint32_t MAX_PARAM_SIZE = 1;
30 const std::unordered_map<uint32_t, std::string> ErrMsgMap {
31     {EFM_ERR_NO_PERMISSION, "Permission denied."},
32     {EFM_ERR_NOT_SYSTEM_APP, "Not system app."},
33     {EFM_ERR_INVALID_PARAMETER, "Parameter error."},
34     {EFM_ERR_SYSTEMCAP_NOT_SUPPORT, "The specified SystemCapability name was not found."},
35     {EFM_ERR_INVALID_DATATYPE, "Invalid DataType."},
36     {EFM_ERR_REMOTE_CONNECTION, "The system ability work abnormally."},
37     {EFM_ERR_FIND_ACCESS_FAILED, "The application is not enabled the data protection under lock screen."},
38     {EFM_ERR_ACCESS_RELEASED, "File access is denied."},
39     {EFM_ERR_RELEASE_ACCESS_FAILED, "File access was not acquired."},
40 };
41 }
42 
ThrowError(napi_env env,int32_t errCode)43 void ThrowError(napi_env env, int32_t errCode)
44 {
45     napi_value businessError = nullptr;
46 
47     napi_value code = nullptr;
48     napi_create_int32(env, errCode, &code);
49 
50     std::string errMsg = "Unknown error, errCode + " + std::to_string(errCode) + ".";
51     auto iter = ErrMsgMap.find(errCode);
52     if (iter != ErrMsgMap.end()) {
53         errMsg = iter->second;
54     }
55 
56     napi_value msg = nullptr;
57     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msg);
58 
59     napi_create_error(env, nullptr, msg, &businessError);
60     napi_set_named_property(env, businessError, "code", code);
61     napi_set_named_property(env, businessError, "message", msg);
62 
63     napi_throw(env, businessError);
64 }
65 
ParseDataType(const napi_env & env,napi_value args,int32_t & dataLockType)66 bool ParseDataType(const napi_env &env, napi_value args, int32_t &dataLockType)
67 {
68     // data-lock-type
69     napi_valuetype valuetype = napi_undefined;
70     napi_typeof(env, args, &valuetype);
71     if (valuetype != napi_number) {
72         LOG_ERROR("Parameter type %{public}d error. Number expected.", valuetype);
73         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
74         return false;
75     }
76     napi_get_value_int32(env, args, &dataLockType);
77     return true;
78 }
79 
CheckDataType(napi_env env,int32_t dataLockType)80 bool CheckDataType(napi_env env, int32_t dataLockType)
81 {
82     if ((static_cast<DataLockType>(dataLockType) != DataLockType::DEFAULT_DATA) &&
83         (static_cast<DataLockType>(dataLockType) != DataLockType::MEDIA_DATA) &&
84         (static_cast<DataLockType>(dataLockType) != DataLockType::GROUP_ID_DATA) &&
85         (static_cast<DataLockType>(dataLockType) != DataLockType::ALL_DATA)) {
86         ThrowError(env, EFM_ERR_INVALID_DATATYPE);
87         return false;
88     }
89     return true;
90 }
91 
AcquireAccess(napi_env env,napi_callback_info info)92 napi_value AcquireAccess(napi_env env, napi_callback_info info)
93 {
94     size_t argc = MAX_PARAM_SIZE;
95     napi_value argv[MAX_PARAM_SIZE] = { nullptr };
96     if (napi_get_cb_info(env, info, &argc, argv, NULL, NULL) != napi_ok) {
97         LOG_ERROR("napi_get_cb_info failed.");
98         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
99         return nullptr;
100     }
101 
102     int32_t dataLockType = static_cast<int32_t>(DataLockType::DEFAULT_DATA);
103     if ((argc == MAX_PARAM_SIZE) && !ParseDataType(env, argv[0], dataLockType)) {
104         return nullptr;
105     }
106 
107     if (!CheckDataType(env, dataLockType)) {
108         LOG_ERROR("Invalid DataType.");
109         return nullptr;
110     }
111 
112     int32_t retCode = El5FilekeyManagerKit::AcquireAccess(static_cast<DataLockType>(dataLockType));
113     if (retCode != EFM_SUCCESS) {
114         ThrowError(env, retCode);
115         retCode = ACCESS_DENIED;
116     }
117 
118     napi_value result = nullptr;
119     NAPI_CALL(env, napi_create_int32(env, retCode, &result));
120     return result;
121 }
122 
ReleaseAccess(napi_env env,napi_callback_info info)123 napi_value ReleaseAccess(napi_env env, napi_callback_info info)
124 {
125     size_t argc = MAX_PARAM_SIZE;
126     napi_value argv[MAX_PARAM_SIZE] = { nullptr };
127     if (napi_get_cb_info(env, info, &argc, argv, NULL, NULL) != napi_ok) {
128         LOG_ERROR("napi_get_cb_info failed.");
129         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
130         return nullptr;
131     }
132 
133     int32_t dataLockType = static_cast<int32_t>(DataLockType::DEFAULT_DATA);
134     if ((argc == MAX_PARAM_SIZE) && !ParseDataType(env, argv[0], dataLockType)) {
135         return nullptr;
136     }
137 
138     if (!CheckDataType(env, dataLockType)) {
139         LOG_ERROR("Invalid DataType.");
140         return nullptr;
141     }
142 
143     int32_t retCode = El5FilekeyManagerKit::ReleaseAccess(static_cast<DataLockType>(dataLockType));
144     if (retCode != EFM_SUCCESS) {
145         ThrowError(env, retCode);
146         retCode = RELEASE_DENIED;
147     }
148 
149     napi_value result = nullptr;
150     NAPI_CALL(env, napi_create_int32(env, retCode, &result));
151     return result;
152 }
153 
QueryAppKeyState(napi_env env,napi_callback_info info)154 napi_value QueryAppKeyState(napi_env env, napi_callback_info info)
155 {
156     size_t argc = MAX_PARAM_SIZE;
157     napi_value argv[MAX_PARAM_SIZE] = { nullptr };
158     if (napi_get_cb_info(env, info, &argc, argv, NULL, NULL) != napi_ok) {
159         LOG_ERROR("napi_get_cb_info failed.");
160         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
161         return nullptr;
162     }
163 
164     int32_t dataLockType = static_cast<int32_t>(DataLockType::DEFAULT_DATA);
165     if ((argc == MAX_PARAM_SIZE) && !ParseDataType(env, argv[0], dataLockType)) {
166         return nullptr;
167     }
168 
169     if (!CheckDataType(env, dataLockType)) {
170         LOG_ERROR("Invalid DataType.");
171         return nullptr;
172     }
173 
174     int32_t retCode = El5FilekeyManagerKit::QueryAppKeyState(static_cast<DataLockType>(dataLockType));
175     switch (retCode) {
176         case EFM_SUCCESS:
177             retCode = KEY_EXIST;
178             break;
179         case EFM_ERR_ACCESS_RELEASED:
180             retCode = KEY_RELEASED;
181             break;
182         case EFM_ERR_FIND_ACCESS_FAILED:
183             retCode = KEY_NOT_EXIST;
184             break;
185         default:
186             ThrowError(env, retCode);
187             retCode = KEY_RELEASED;
188             break;
189     }
190 
191     napi_value result = nullptr;
192     NAPI_CALL(env, napi_create_int32(env, retCode, &result));
193     return result;
194 }
195 
SetNamedProperty(napi_env env,napi_value dstObj,const int32_t objValue,const char * propName)196 static void SetNamedProperty(napi_env env, napi_value dstObj, const int32_t objValue, const char* propName)
197 {
198     napi_value prop = nullptr;
199     napi_create_int32(env, objValue, &prop);
200     napi_set_named_property(env, dstObj, propName, prop);
201 }
202 
203 EXTERN_C_START
204 /*
205  * function for module exports
206  */
Init(napi_env env,napi_value exports)207 static napi_value Init(napi_env env, napi_value exports)
208 {
209     napi_property_descriptor properties[] = {
210         DECLARE_NAPI_FUNCTION("acquireAccess", AcquireAccess),
211         DECLARE_NAPI_FUNCTION("releaseAccess", ReleaseAccess),
212         DECLARE_NAPI_FUNCTION("queryAppKeyState", QueryAppKeyState)
213     };
214 
215     napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties);
216 
217     napi_value dataType = nullptr;
218     napi_create_object(env, &dataType);
219     SetNamedProperty(env, dataType, static_cast<int32_t>(DataLockType::MEDIA_DATA), "MEDIA_DATA");
220     SetNamedProperty(env, dataType, static_cast<int32_t>(DataLockType::ALL_DATA), "ALL_DATA");
221 
222     napi_value accessStatus = nullptr;
223     napi_create_object(env, &accessStatus);
224     SetNamedProperty(env, accessStatus, ACCESS_GRANTED, "ACCESS_GRANTED");
225     SetNamedProperty(env, accessStatus, ACCESS_DENIED, "ACCESS_DENIED");
226 
227     napi_value releaseStatus = nullptr;
228     napi_create_object(env, &releaseStatus);
229     SetNamedProperty(env, releaseStatus, RELEASE_GRANTED, "RELEASE_GRANTED");
230     SetNamedProperty(env, releaseStatus, RELEASE_DENIED, "RELEASE_DENIED");
231 
232     napi_value keyStatus = nullptr;
233     napi_create_object(env, &keyStatus);
234     SetNamedProperty(env, keyStatus, KEY_NOT_EXIST, "KEY_NOT_EXIST");
235     SetNamedProperty(env, keyStatus, KEY_EXIST, "KEY_EXIST");
236     SetNamedProperty(env, keyStatus, KEY_RELEASED, "KEY_RELEASED");
237 
238     napi_property_descriptor exportFuncs[] = {
239         DECLARE_NAPI_PROPERTY("DataType", dataType),
240         DECLARE_NAPI_PROPERTY("AccessStatus", accessStatus),
241         DECLARE_NAPI_PROPERTY("ReleaseStatus", releaseStatus),
242         DECLARE_NAPI_PROPERTY("KeyStatus", keyStatus),
243     };
244     napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(exportFuncs[0]), exportFuncs);
245 
246     return exports;
247 }
248 EXTERN_C_END
249 
250 /*
251  * Module define
252  */
253 static napi_module g_module = {
254     .nm_version = 1,
255     .nm_flags = 0,
256     .nm_filename = nullptr,
257     .nm_register_func = Init,
258     .nm_modname = "ability.screenLockFileManager",
259     .nm_priv = static_cast<void*>(nullptr),
260     .reserved = {nullptr}
261 };
262 
263 /*
264  * Module register function
265  */
RegisterEl5FilekeyManager(void)266 extern "C" __attribute__((constructor)) void RegisterEl5FilekeyManager(void)
267 {
268     napi_module_register(&g_module);
269 }
270 }  // namespace AccessToken
271 }  // namespace Security
272 }  // namespace OHOS
273