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