1 /*
2  * Copyright (c) 2021-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 "huks_napi_common.h"
17 
18 #include <vector>
19 
20 #include "securec.h"
21 
22 #include "hks_log.h"
23 #include "hks_param.h"
24 #include "hks_type.h"
25 
26 namespace HuksNapi {
27 namespace {
28 constexpr int HKS_MAX_DATA_LEN = 0x6400000; // The maximum length is 100M
29 constexpr size_t ASYNCCALLBACK_ARGC = 2;
30 }  // namespace
31 
ParseKeyAlias(napi_env env,napi_value object,HksBlob * & alias)32 napi_value ParseKeyAlias(napi_env env, napi_value object, HksBlob *&alias)
33 {
34     size_t length = 0;
35     napi_status status = napi_get_value_string_utf8(env, object, nullptr, 0, &length);
36     if (status != napi_ok) {
37         GET_AND_THROW_LAST_ERROR((env));
38         HKS_LOG_E("could not get string length");
39         return nullptr;
40     }
41 
42     if (length > HKS_MAX_DATA_LEN) {
43         HKS_LOG_E("input key alias length too large");
44         return nullptr;
45     }
46 
47     char *data = static_cast<char *>(HksMalloc(length + 1));
48     if (data == nullptr) {
49         napi_throw_error(env, nullptr, "could not alloc memory");
50         HKS_LOG_E("could not alloc memory");
51         return nullptr;
52     }
53     (void)memset_s(data, length + 1, 0, length + 1);
54 
55     size_t result = 0;
56     status = napi_get_value_string_utf8(env, object, data, length + 1, &result);
57     if (status != napi_ok) {
58         HKS_FREE(data);
59         GET_AND_THROW_LAST_ERROR((env));
60         HKS_LOG_E("could not get string");
61         return nullptr;
62     }
63 
64     alias = static_cast<HksBlob *>(HksMalloc(sizeof(HksBlob)));
65     if (alias == nullptr) {
66         HKS_FREE(data);
67         napi_throw_error(env, NULL, "could not alloc memory");
68         HKS_LOG_E("could not alloc memory");
69         return nullptr;
70     }
71     alias->data = reinterpret_cast<uint8_t *>(data);
72     alias->size = static_cast<uint32_t>(length & UINT32_MAX);
73 
74     return GetInt32(env, 0);
75 }
76 
GetUint8Array(napi_env env,napi_value object,HksBlob & arrayBlob)77 napi_value GetUint8Array(napi_env env, napi_value object, HksBlob &arrayBlob)
78 {
79     napi_typedarray_type arrayType;
80     napi_value arrayBuffer = nullptr;
81     size_t length = 0;
82     size_t offset = 0;
83     void *rawData = nullptr;
84 
85     NAPI_CALL(
86         env, napi_get_typedarray_info(env, object, &arrayType, &length, &rawData, &arrayBuffer, &offset));
87     NAPI_ASSERT(env, arrayType == napi_uint8_array, "it's not uint8 array");
88 
89     if (length > HKS_MAX_DATA_LEN) {
90         HKS_LOG_E("data len is too large, len = %" LOG_PUBLIC "zx", length);
91         return nullptr;
92     }
93     if (length == 0) {
94         HKS_LOG_I("the created memory length just 1 Byte");
95         // the created memory length just 1 Byte
96         arrayBlob.data = static_cast<uint8_t *>(HksMalloc(1));
97     } else {
98         arrayBlob.data = static_cast<uint8_t *>(HksMalloc(length));
99     }
100     if (arrayBlob.data == nullptr) {
101         return nullptr;
102     }
103     (void)memcpy_s(arrayBlob.data, length, rawData, length);
104     arrayBlob.size = static_cast<uint32_t>(length);
105 
106     napi_value result = GetInt32(env, 0);
107     if (result == nullptr) {
108         memset_s(arrayBlob.data, length, 0, length);
109         HKS_FREE_BLOB(arrayBlob);
110     }
111     return result;
112 }
113 
GetHksParam(napi_env env,napi_value object,HksParam & param)114 static napi_value GetHksParam(napi_env env, napi_value object, HksParam &param)
115 {
116     napi_value tag = nullptr;
117     NAPI_CALL(env, napi_get_named_property(env, object, HKS_PARAM_PROPERTY_TAG.c_str(), &tag));
118     NAPI_CALL(env, napi_get_value_uint32(env, tag, &param.tag));
119 
120     napi_value value = nullptr;
121     NAPI_CALL(env, napi_get_named_property(env, object, HKS_PARAM_PROPERTY_VALUE.c_str(), &value));
122 
123     napi_value result = nullptr;
124 
125     switch (param.tag & HKS_TAG_TYPE_MASK) {
126         case HKS_TAG_TYPE_INT:
127             NAPI_CALL(env, napi_get_value_int32(env, value, &param.int32Param));
128             result = GetInt32(env, 0);
129             break;
130         case HKS_TAG_TYPE_UINT:
131             NAPI_CALL(env, napi_get_value_uint32(env, value, &param.uint32Param));
132             result = GetInt32(env, 0);
133             break;
134         case HKS_TAG_TYPE_ULONG:
135             NAPI_CALL(env, napi_get_value_int64(env, value, reinterpret_cast<int64_t *>(&param.uint64Param)));
136             result = GetInt32(env, 0);
137             break;
138         case HKS_TAG_TYPE_BOOL:
139             NAPI_CALL(env, napi_get_value_bool(env, value, &param.boolParam));
140             result = GetInt32(env, 0);
141             break;
142         case HKS_TAG_TYPE_BYTES:
143             result = GetUint8Array(env, value, param.blob);
144             if (result == nullptr) {
145                 HKS_LOG_E("get uint8 array fail.");
146             } else {
147                 HKS_LOG_D("tag 0x%" LOG_PUBLIC "x, len 0x%" LOG_PUBLIC "x", param.tag, param.blob.size);
148             }
149             break;
150         default:
151             HKS_LOG_E("invalid tag value 0x%" LOG_PUBLIC "x", param.tag);
152             break;
153     }
154 
155     return result;
156 }
157 
FreeParsedParams(std::vector<HksParam> & params)158 void FreeParsedParams(std::vector<HksParam> &params)
159 {
160     HksParam *param = params.data();
161     size_t paramCount = params.size();
162     if (param == nullptr) {
163         return;
164     }
165     while (paramCount > 0) {
166         paramCount--;
167         if ((param->tag & HKS_TAG_TYPE_MASK) == HKS_TAG_TYPE_BYTES) {
168             HKS_FREE(param->blob.data);
169             param->blob.size = 0;
170         }
171         ++param;
172     }
173 }
174 
ParseParams(napi_env env,napi_value object,std::vector<HksParam> & params)175 napi_value ParseParams(napi_env env, napi_value object, std::vector<HksParam> &params)
176 {
177     bool hasNextElement = false;
178     napi_value result = nullptr;
179     size_t index = 0;
180     while ((napi_has_element(env, object, index, &hasNextElement) == napi_ok) && hasNextElement) {
181         napi_value element = nullptr;
182         NAPI_CALL(env, napi_get_element(env, object, index, &element));
183 
184         HksParam param = { 0 };
185         result = GetHksParam(env, element, param);
186         if (result == nullptr) {
187             HKS_LOG_E("get param failed when parse input params.");
188             return nullptr;
189         }
190 
191         params.push_back(param);
192         index++;
193     }
194     return GetInt32(env, 0);
195 }
196 
ParseHksParamSet(napi_env env,napi_value object,HksParamSet * & paramSet)197 napi_value ParseHksParamSet(napi_env env, napi_value object, HksParamSet *&paramSet)
198 {
199     if (paramSet != nullptr) {
200         HKS_LOG_E("param input invalid");
201         return nullptr;
202     }
203 
204     std::vector<HksParam> params{};
205     HksParamSet *outParamSet = nullptr;
206     do {
207         if (HksInitParamSet(&outParamSet) != HKS_SUCCESS) {
208             napi_throw_error(env, NULL, "native error");
209             HKS_LOG_E("paramset init failed");
210             break;
211         }
212 
213         if (ParseParams(env, object, params) == nullptr) {
214             HKS_LOG_E("parse params failed");
215             break;
216         }
217 
218         if (!params.empty()) {
219             if (HksAddParams(outParamSet, params.data(), params.size()) != HKS_SUCCESS) {
220                 HKS_LOG_E("add params failed");
221                 break;
222             }
223         }
224 
225         if (HksBuildParamSet(&outParamSet) != HKS_SUCCESS) {
226             HKS_LOG_E("HksBuildParamSet failed");
227             break;
228         }
229 
230         FreeParsedParams(params);
231         paramSet = outParamSet;
232         return GetInt32(env, 0);
233     } while (0);
234 
235     HksFreeParamSet(&outParamSet);
236     FreeParsedParams(params);
237     return nullptr;
238 }
239 
GetCallback(napi_env env,napi_value object)240 napi_ref GetCallback(napi_env env, napi_value object)
241 {
242     napi_valuetype valueType = napi_undefined;
243     napi_status status = napi_typeof(env, object, &valueType);
244     if (status != napi_ok) {
245         GET_AND_THROW_LAST_ERROR((env));
246         HKS_LOG_E("could not get object type");
247         return nullptr;
248     }
249 
250     if (valueType != napi_function) {
251         HKS_LOG_E("invalid type");
252         return nullptr;
253     }
254 
255     napi_ref ref = nullptr;
256     status = napi_create_reference(env, object, 1, &ref);
257     if (status != napi_ok) {
258         GET_AND_THROW_LAST_ERROR((env));
259         HKS_LOG_E("could not create reference");
260         return nullptr;
261     }
262     return ref;
263 }
264 
GenerateArrayBuffer(napi_env env,uint8_t * data,uint32_t size)265 static napi_value GenerateArrayBuffer(napi_env env, uint8_t *data, uint32_t size)
266 {
267     uint8_t *buffer = static_cast<uint8_t *>(HksMalloc(size));
268     if (buffer == nullptr) {
269         return nullptr;
270     }
271 
272     napi_value outBuffer = nullptr;
273     (void)memcpy_s(buffer, size, data, size);
274 
275     napi_status status = napi_create_external_arraybuffer(
276         env, buffer, size, [](napi_env env, void *data, void *hint) { HKS_FREE(data); }, nullptr, &outBuffer);
277     if (status == napi_ok) {
278         // free by finalize callback
279         buffer = nullptr;
280     } else {
281         HKS_FREE(buffer);
282         GET_AND_THROW_LAST_ERROR((env));
283     }
284 
285     return outBuffer;
286 }
287 
GenerateHksParam(napi_env env,const HksParam & param)288 static napi_value GenerateHksParam(napi_env env, const HksParam &param)
289 {
290     napi_value hksParam = nullptr;
291     NAPI_CALL(env, napi_create_object(env, &hksParam));
292 
293     napi_value tag = nullptr;
294     NAPI_CALL(env, napi_create_uint32(env, param.tag, &tag));
295     NAPI_CALL(env, napi_set_named_property(env, hksParam, HKS_PARAM_PROPERTY_TAG.c_str(), tag));
296 
297     napi_value value = nullptr;
298     switch (param.tag & HKS_TAG_TYPE_MASK) {
299         case HKS_TAG_TYPE_INT:
300             NAPI_CALL(env, napi_create_int32(env, param.int32Param, &value));
301             break;
302         case HKS_TAG_TYPE_UINT:
303             NAPI_CALL(env, napi_create_uint32(env, param.uint32Param, &value));
304             break;
305         case HKS_TAG_TYPE_ULONG:
306             NAPI_CALL(env, napi_create_int64(env, param.uint64Param, &value));
307             break;
308         case HKS_TAG_TYPE_BOOL:
309             NAPI_CALL(env, napi_get_boolean(env, param.boolParam, &value));
310             break;
311         case HKS_TAG_TYPE_BYTES:
312             value = GenerateArrayBuffer(env, param.blob.data, param.blob.size);
313             break;
314         default:
315             value = GetNull(env);
316             break;
317     }
318     NAPI_CALL(env, napi_set_named_property(env, hksParam, HKS_PARAM_PROPERTY_VALUE.c_str(), value));
319 
320     return hksParam;
321 }
322 
GenerateHksParamArray(napi_env env,const HksParamSet & paramSet)323 static napi_value GenerateHksParamArray(napi_env env, const HksParamSet &paramSet)
324 {
325     napi_value paramArray = nullptr;
326     NAPI_CALL(env, napi_create_array(env, &paramArray));
327 
328     for (uint32_t i = 0; i < paramSet.paramsCnt; i++) {
329         napi_value element = nullptr;
330         element = GenerateHksParam(env, paramSet.params[i]);
331         napi_set_element(env, paramArray, i, element);
332     }
333 
334     return paramArray;
335 }
336 
GenerateResult(napi_env env,int32_t error,uint8_t * data,uint32_t size,const HksParamSet * paramSet)337 static napi_value GenerateResult(napi_env env, int32_t error, uint8_t *data, uint32_t size,
338     const HksParamSet *paramSet)
339 {
340     napi_value result = nullptr;
341     NAPI_CALL(env, napi_create_object(env, &result));
342 
343     napi_value errorCode = nullptr;
344     NAPI_CALL(env, napi_create_int32(env, error, &errorCode));
345     NAPI_CALL(env, napi_set_named_property(env, result, HKS_RESULT_PROPERTY_ERRORCODE.c_str(), errorCode));
346 
347     napi_value outData = nullptr;
348     if (data != nullptr && size != 0) {
349         napi_value outBuffer = GenerateArrayBuffer(env, data, size);
350         if (outBuffer != nullptr) {
351             NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, size, outBuffer, 0, &outData));
352         }
353     } else {
354         outData = GetNull(env);
355     }
356     NAPI_CALL(env, napi_set_named_property(env, result, HKS_RESULT_PROPERTY_OUTDATA.c_str(), outData));
357 
358     napi_value properties = nullptr;
359     if (paramSet == nullptr) {
360         properties = GetNull(env);
361     } else {
362         properties = GenerateHksParamArray(env, *paramSet);
363     }
364     NAPI_CALL(env, napi_set_named_property(env, result, HKS_RESULT_PRPPERTY_PROPERTIES.c_str(), properties));
365 
366     return result;
367 }
368 
GenerateHksResult(napi_env env,int32_t error,uint8_t * data,uint32_t size)369 napi_value GenerateHksResult(napi_env env, int32_t error, uint8_t *data, uint32_t size)
370 {
371     return GenerateResult(env, error, data, size, nullptr);
372 }
373 
GenerateHksResult(napi_env env,int32_t error,uint8_t * data,uint32_t size,const HksParamSet & paramSet)374 napi_value GenerateHksResult(napi_env env, int32_t error, uint8_t *data, uint32_t size, const HksParamSet &paramSet)
375 {
376     return GenerateResult(env, error, data, size, &paramSet);
377 }
378 
GenerateBusinessError(napi_env env,int32_t errorCode)379 static napi_value GenerateBusinessError(napi_env env, int32_t errorCode)
380 {
381     napi_value businessError = nullptr;
382     NAPI_CALL(env, napi_create_object(env, &businessError));
383 
384     napi_value code = nullptr;
385     NAPI_CALL(env, napi_create_int32(env, errorCode, &code));
386     NAPI_CALL(env, napi_set_named_property(env, businessError, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code));
387 
388     return businessError;
389 }
390 
CallAsyncCallback(napi_env env,napi_ref callback,int32_t error,napi_value data)391 void CallAsyncCallback(napi_env env, napi_ref callback, int32_t error, napi_value data)
392 {
393     napi_value businessError = GenerateBusinessError(env, error);
394 
395     napi_value params[ASYNCCALLBACK_ARGC] = { businessError, data };
396 
397     napi_value func = nullptr;
398     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callback, &func));
399 
400     napi_value recv = nullptr;
401     napi_value result = nullptr;
402     NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &recv));
403     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, recv, func, ASYNCCALLBACK_ARGC, params, &result));
404 }
405 
GenerateStringArray(napi_env env,const struct HksBlob * blob,const uint32_t blobCount)406 napi_value GenerateStringArray(napi_env env, const struct HksBlob *blob, const uint32_t blobCount)
407 {
408     if (blobCount == 0 || blob == nullptr) {
409         return nullptr;
410     }
411     napi_value array = nullptr;
412     NAPI_CALL(env, napi_create_array(env, &array));
413     for (uint32_t i = 0; i < blobCount; i++) {
414         napi_value element = nullptr;
415         napi_create_string_latin1(env, reinterpret_cast<const char *>(blob[i].data), blob[i].size, &element);
416         napi_set_element(env, array, i, element);
417     }
418     return array;
419 }
420 
FreeHksCertChain(HksCertChain * & certChain)421 void FreeHksCertChain(HksCertChain *&certChain)
422 {
423     if (certChain == nullptr) {
424         return;
425     }
426 
427     if (certChain->certsCount > 0 && certChain->certs != nullptr) {
428         for (uint32_t i = 0; i < certChain->certsCount; i++) {
429             if (certChain->certs[i].data != nullptr) {
430                 HKS_FREE(certChain->certs[i].data);
431                 certChain->certs[i].data = nullptr;
432             }
433         }
434     }
435 
436     HKS_FREE(certChain);
437     certChain = nullptr;
438 }
439 
GenerateHksHandle(napi_env env,int32_t error,const struct HksBlob * handle,const struct HksBlob * token)440 napi_value GenerateHksHandle(napi_env env, int32_t error, const struct HksBlob *handle,
441     const struct HksBlob *token)
442 {
443     napi_value result = nullptr;
444     NAPI_CALL(env, napi_create_object(env, &result));
445 
446     napi_value errorCode = nullptr;
447     NAPI_CALL(env, napi_create_int32(env, error, &errorCode));
448     NAPI_CALL(env, napi_set_named_property(env, result, HKS_HANDLE_PROPERTY_ERRORCODE.c_str(), errorCode));
449 
450     if (error != HKS_SUCCESS) {
451         HKS_LOG_E("init failed, ret = %" LOG_PUBLIC "d", error);
452         return result;
453     }
454 
455     if ((handle == nullptr) || (handle->data == nullptr) || (handle->size != sizeof(uint64_t))) {
456         HKS_LOG_E("invalid handle");
457         return result;
458     }
459 
460     uint64_t tempHandle = *reinterpret_cast<uint64_t *>(handle->data);
461     uint32_t handleValue = static_cast<uint32_t>(tempHandle); /* Temporarily only use 32 bit handle */
462 
463     napi_value handlejs = nullptr;
464     NAPI_CALL(env, napi_create_uint32(env, handleValue, &handlejs));
465     NAPI_CALL(env, napi_set_named_property(env, result, HKS_HANDLE_PROPERTY_HANDLE.c_str(), handlejs));
466 
467     if (token == nullptr) {
468         HKS_LOG_E("invalid token");
469         return result;
470     }
471 
472     napi_value tokenjs = nullptr;
473     if ((token->size != 0) && (token->data != nullptr)) {
474         napi_value outBuffer = GenerateArrayBuffer(env, token->data, token->size);
475         if (outBuffer != nullptr) {
476             NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, token->size, outBuffer, 0, &tokenjs));
477         } else {
478             tokenjs = GetNull(env);
479         }
480     } else {
481         tokenjs = GetNull(env);
482     }
483     NAPI_CALL(env, napi_set_named_property(env, result, HKS_HANDLE_PROPERTY_TOKEN.c_str(), tokenjs));
484 
485     return result;
486 }
487 
GetHandleValue(napi_env env,napi_value object,struct HksBlob * & handleBlob)488 napi_value GetHandleValue(napi_env env, napi_value object, struct HksBlob *&handleBlob)
489 {
490     if (handleBlob != nullptr) {
491         HKS_LOG_E("param input invalid");
492         return nullptr;
493     }
494 
495     napi_valuetype valueType = napi_valuetype::napi_undefined;
496     napi_typeof(env, object, &valueType);
497     if (valueType != napi_valuetype::napi_number) {
498         napi_throw_type_error(env, nullptr, "Parameter type does not match");
499         return nullptr;
500     }
501 
502     uint32_t handleTmp = 0;
503     napi_status status = napi_get_value_uint32(env, object, &handleTmp);
504     if (status != napi_ok) {
505         HKS_LOG_E("Retrieve field failed");
506         return nullptr;
507     }
508 
509     uint64_t handle = static_cast<uint64_t>(handleTmp);
510 
511     handleBlob = static_cast<struct HksBlob *>(HksMalloc(sizeof(struct HksBlob)));
512     if (handleBlob == nullptr) {
513         HKS_LOG_E("could not alloc memory");
514         return nullptr;
515     }
516 
517     handleBlob->data = static_cast<uint8_t *>(HksMalloc(sizeof(uint64_t)));
518     if (handleBlob->data == nullptr) {
519         HKS_FREE(handleBlob);
520         HKS_LOG_E("could not alloc memory");
521         return nullptr;
522     }
523     handleBlob->size = sizeof(uint64_t);
524     if (memcpy_s(handleBlob->data, sizeof(uint64_t), &handle, sizeof(uint64_t)) != EOK) {
525         // the memory of handleBlob free by finalize callback
526         return nullptr;
527     }
528 
529     return GetInt32(env, 0);
530 }
531 
DeleteCommonAsyncContext(napi_env env,napi_async_work & asyncWork,napi_ref & callback,struct HksBlob * & blob,struct HksParamSet * & paramSet)532 void DeleteCommonAsyncContext(napi_env env, napi_async_work &asyncWork, napi_ref &callback,
533     struct HksBlob *&blob, struct HksParamSet *&paramSet)
534 {
535     if (asyncWork != nullptr) {
536         napi_delete_async_work(env, asyncWork);
537         asyncWork = nullptr;
538     }
539 
540     if (callback != nullptr) {
541         napi_delete_reference(env, callback);
542         callback = nullptr;
543     }
544 
545     if (blob != nullptr) {
546         FreeHksBlob(blob);
547     }
548 
549     if (paramSet != nullptr) {
550         HksFreeParamSet(&paramSet);
551     }
552 }
553 
ParseGetHksParamSet(napi_env env,napi_value value,HksParamSet * & paramSet)554 static napi_value ParseGetHksParamSet(napi_env env, napi_value value, HksParamSet *&paramSet)
555 {
556     napi_value properties = nullptr;
557     napi_status status = napi_get_named_property(env, value,
558         HKS_OPTIONS_PROPERTY_PROPERTIES.c_str(), &properties);
559     if (status != napi_ok || properties == nullptr) {
560         GET_AND_THROW_LAST_ERROR((env));
561         HKS_LOG_E("could not get property %" LOG_PUBLIC "s", HKS_OPTIONS_PROPERTY_PROPERTIES.c_str());
562         return nullptr;
563     }
564     napi_value result = ParseHksParamSet(env, properties, paramSet);
565     if (result == nullptr) {
566         HKS_LOG_E("could not get paramset");
567         return nullptr;
568     }
569 
570     return GetInt32(env, 0);
571 }
572 
ParseHandleAndHksParamSet(napi_env env,napi_value * argv,size_t & index,HksBlob * & handleBlob,HksParamSet * & paramSet)573 napi_value ParseHandleAndHksParamSet(napi_env env, napi_value *argv, size_t &index,
574     HksBlob *&handleBlob, HksParamSet *&paramSet)
575 {
576     // the index is controlled by the caller and needs to ensure that it does not overflow
577     if (argv == nullptr || handleBlob != nullptr || paramSet != nullptr) {
578         HKS_LOG_E("param input invalid");
579         return nullptr;
580     }
581 
582     napi_value result = GetHandleValue(env, argv[index], handleBlob);
583     if (result == nullptr) {
584         HKS_LOG_E("could not get handle value");
585         return nullptr;
586     }
587 
588     index++;
589     result = ParseGetHksParamSet(env, argv[index], paramSet);
590     if (result == nullptr) {
591         HKS_LOG_E("could not get hksParamSet");
592         return nullptr;
593     }
594 
595     return GetInt32(env, 0);
596 }
597 
ParseKeyAliasAndHksParamSet(napi_env env,napi_value * argv,size_t & index,HksBlob * & keyAliasBlob,HksParamSet * & paramSet)598 napi_value ParseKeyAliasAndHksParamSet(napi_env env, napi_value *argv, size_t &index,
599     HksBlob *&keyAliasBlob, HksParamSet *&paramSet)
600 {
601     // the index is controlled by the caller and needs to ensure that it does not overflow
602     if (argv == nullptr || keyAliasBlob != nullptr || paramSet != nullptr) {
603         HKS_LOG_E("param input invalid");
604         return nullptr;
605     }
606 
607     napi_value result = ParseKeyAlias(env, argv[index], keyAliasBlob);
608     if (result == nullptr) {
609         HKS_LOG_E("could not get keyAlias");
610         return nullptr;
611     }
612 
613     index++;
614     result = ParseGetHksParamSet(env, argv[index], paramSet);
615     if (result == nullptr) {
616         HKS_LOG_E("get hksParamSet failed");
617         return nullptr;
618     }
619 
620     return GetInt32(env, 0);
621 }
622 
ParseKeyData(napi_env env,napi_value value,HksBlob * & keyDataBlob)623 napi_value ParseKeyData(napi_env env, napi_value value, HksBlob *&keyDataBlob)
624 {
625     if (keyDataBlob != nullptr) {
626         HKS_LOG_E("param input invalid");
627         return nullptr;
628     }
629 
630     napi_value inData = nullptr;
631     napi_status status = napi_get_named_property(env, value, HKS_OPTIONS_PROPERTY_INDATA.c_str(), &inData);
632     if (status != napi_ok || inData == nullptr) {
633         GET_AND_THROW_LAST_ERROR((env));
634         HKS_LOG_E("could not get property %" LOG_PUBLIC "s", HKS_OPTIONS_PROPERTY_INDATA.c_str());
635         return nullptr;
636     }
637 
638     keyDataBlob = static_cast<HksBlob *>(HksMalloc(sizeof(HksBlob)));
639     if (keyDataBlob == nullptr) {
640         HKS_LOG_E("could not alloc memory");
641         return nullptr;
642     }
643     (void)memset_s(keyDataBlob, sizeof(HksBlob), 0, sizeof(HksBlob));
644 
645     if (GetUint8Array(env, inData, *keyDataBlob) == nullptr) {
646         FreeHksBlob(keyDataBlob);
647         HKS_LOG_E("could not get indata");
648         return nullptr;
649     }
650 
651     return GetInt32(env, 0);
652 }
653 }  // namespace HuksNapi
654