1 /*
2 * Copyright (C) 2022-2024 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 "napi_utils.h"
17 #include "params_parser.h"
18 #include "log.h"
19 #include "memory.h"
20 #include "securec.h"
21 #include "napi_crypto_framework_defines.h"
22 #include "detailed_iv_params.h"
23 #include "detailed_gcm_params.h"
24 #include "detailed_ccm_params.h"
25 #include "detailed_dsa_key_params.h"
26 #include "detailed_ecc_key_params.h"
27 #include "detailed_rsa_key_params.h"
28 #include "detailed_alg_25519_key_params.h"
29 #include "detailed_dh_key_params.h"
30 #include "utils.h"
31 #include "pri_key.h"
32 #include "asy_key_generator.h"
33
34 namespace OHOS {
35 namespace CryptoFramework {
36 using namespace std;
37
38 constexpr int PASSWORD_MAX_LENGTH = 4096;
39 struct AsyKeySpecItemRelationT {
40 AsyKeySpecItem item;
41 int32_t itemType;
42 };
43 using AsyKeySpecItemRelation = AsyKeySpecItemRelationT;
44
45 static const AsyKeySpecItemRelation ASY_KEY_SPEC_RELATION_SET[] = {
46 { DSA_P_BN, SPEC_ITEM_TYPE_BIG_INT },
47 { DSA_Q_BN, SPEC_ITEM_TYPE_BIG_INT },
48 { DSA_G_BN, SPEC_ITEM_TYPE_BIG_INT },
49 { DSA_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
50 { DSA_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
51
52 { ECC_FP_P_BN, SPEC_ITEM_TYPE_BIG_INT },
53 { ECC_A_BN, SPEC_ITEM_TYPE_BIG_INT },
54 { ECC_B_BN, SPEC_ITEM_TYPE_BIG_INT },
55 { ECC_G_X_BN, SPEC_ITEM_TYPE_BIG_INT },
56 { ECC_G_Y_BN, SPEC_ITEM_TYPE_BIG_INT },
57 { ECC_N_BN, SPEC_ITEM_TYPE_BIG_INT },
58 { ECC_H_INT, SPEC_ITEM_TYPE_NUM }, // warning: ECC_H_NUM in JS
59 { ECC_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
60 { ECC_PK_X_BN, SPEC_ITEM_TYPE_BIG_INT },
61 { ECC_PK_Y_BN, SPEC_ITEM_TYPE_BIG_INT },
62 { ECC_FIELD_TYPE_STR, SPEC_ITEM_TYPE_STR },
63 { ECC_FIELD_SIZE_INT, SPEC_ITEM_TYPE_NUM }, // warning: ECC_FIELD_SIZE_NUM in JS
64 { ECC_CURVE_NAME_STR, SPEC_ITEM_TYPE_STR },
65
66 { RSA_N_BN, SPEC_ITEM_TYPE_BIG_INT },
67 { RSA_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
68 { RSA_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
69 { DH_P_BN, SPEC_ITEM_TYPE_BIG_INT },
70 { DH_G_BN, SPEC_ITEM_TYPE_BIG_INT },
71 { DH_L_NUM, SPEC_ITEM_TYPE_NUM },
72 { DH_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
73 { DH_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
74 { ED25519_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
75 { ED25519_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
76 { X25519_SK_BN, SPEC_ITEM_TYPE_BIG_INT },
77 { X25519_PK_BN, SPEC_ITEM_TYPE_BIG_INT },
78 };
79
GetAsyKeySpecType(AsyKeySpecItem targetItemType)80 int32_t GetAsyKeySpecType(AsyKeySpecItem targetItemType)
81 {
82 for (uint32_t i = 0; i < sizeof(ASY_KEY_SPEC_RELATION_SET) / sizeof(AsyKeySpecItemRelation); i++) {
83 if (ASY_KEY_SPEC_RELATION_SET[i].item == targetItemType) {
84 return ASY_KEY_SPEC_RELATION_SET[i].itemType;
85 }
86 }
87 LOGE("AsyKeySpecItem not support! ItemType: %d", targetItemType);
88 return -1;
89 }
90
GetSignSpecType(SignSpecItem targetItemType)91 int32_t GetSignSpecType(SignSpecItem targetItemType)
92 {
93 if (targetItemType == PSS_MD_NAME_STR || targetItemType == PSS_MGF_NAME_STR ||
94 targetItemType == PSS_MGF1_MD_STR) {
95 return SPEC_ITEM_TYPE_STR;
96 }
97 if (targetItemType == SM2_USER_ID_UINT8ARR) {
98 return SPEC_ITEM_TYPE_UINT8ARR;
99 }
100 if (targetItemType == PSS_SALT_LEN_INT || targetItemType == PSS_TRAILER_FIELD_INT) {
101 return SPEC_ITEM_TYPE_NUM;
102 }
103 LOGE("SignSpecItem not support! ItemType: %d", targetItemType);
104 return -1;
105 }
106
GetCipherSpecType(CipherSpecItem targetItemType)107 int32_t GetCipherSpecType(CipherSpecItem targetItemType)
108 {
109 if (targetItemType == OAEP_MD_NAME_STR || targetItemType == OAEP_MGF_NAME_STR ||
110 targetItemType == OAEP_MGF1_MD_STR || targetItemType == SM2_MD_NAME_STR) {
111 return SPEC_ITEM_TYPE_STR;
112 }
113 if (targetItemType == OAEP_MGF1_PSRC_UINT8ARR) {
114 return SPEC_ITEM_TYPE_UINT8ARR;
115 }
116 LOGE("CipherSpecItem not support! ItemType: %d", targetItemType);
117 return -1;
118 }
119
NapiGetNull(napi_env env)120 napi_value NapiGetNull(napi_env env)
121 {
122 napi_value result = nullptr;
123 napi_get_null(env, &result);
124 return result;
125 }
126
GetUint8ArrFromNapiDataBlob(napi_env env,napi_value arg)127 static napi_value GetUint8ArrFromNapiDataBlob(napi_env env, napi_value arg)
128 {
129 if ((env == nullptr) || (arg == nullptr)) {
130 LOGE("Invalid params!");
131 return nullptr;
132 }
133 napi_value data = nullptr;
134 napi_valuetype valueType = napi_undefined;
135 napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_DATA.c_str(), &data);
136 napi_typeof(env, data, &valueType);
137 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
138 LOGE("failed to get valid data property!");
139 return nullptr;
140 }
141 return data;
142 }
143
GetBlobFromNapiUint8Arr(napi_env env,napi_value data)144 HcfBlob *GetBlobFromNapiUint8Arr(napi_env env, napi_value data)
145 {
146 size_t length = 0;
147 size_t offset = 0;
148 void *rawData = nullptr;
149 napi_value arrayBuffer = nullptr;
150 napi_typedarray_type arrayType;
151 // Warning: Do not release the rawData returned by this interface because the rawData is managed by VM.
152 napi_status status = napi_get_typedarray_info(env, data, &arrayType, &length,
153 reinterpret_cast<void **>(&rawData), &arrayBuffer, &offset);
154 if ((status != napi_ok)) {
155 LOGE("failed to get valid rawData.");
156 return nullptr;
157 }
158 if (arrayType != napi_uint8_array) {
159 LOGE("input data is not uint8 array.");
160 return nullptr;
161 }
162
163 HcfBlob *newBlob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
164 if (newBlob == nullptr) {
165 LOGE("Failed to allocate newBlob memory!");
166 return nullptr;
167 }
168
169 // input empty uint8Arr, ex: new Uint8Arr(), the length is 0 and rawData is nullptr;
170 if ((length == 0) || (rawData == nullptr)) {
171 newBlob->len = 0;
172 newBlob->data = nullptr;
173 LOGD("napi Uint8Arr is null");
174 return newBlob;
175 }
176 newBlob->len = length;
177 newBlob->data = static_cast<uint8_t *>(HcfMalloc(length, 0));
178 if (newBlob->data == nullptr) {
179 LOGE("malloc blob data failed!");
180 HcfFree(newBlob);
181 return nullptr;
182 }
183 (void)memcpy_s(newBlob->data, length, rawData, length);
184 return newBlob;
185 }
186
GetBlobFromNapiDataBlob(napi_env env,napi_value arg)187 HcfBlob *GetBlobFromNapiDataBlob(napi_env env, napi_value arg)
188 {
189 napi_value data = GetUint8ArrFromNapiDataBlob(env, arg);
190 if (data == nullptr) {
191 LOGE("failed to get data in DataBlob");
192 return nullptr;
193 }
194 return GetBlobFromNapiUint8Arr(env, data);
195 }
196
GetBlobFromNapiValue(napi_env env,napi_value arg,HcfBlob * blob)197 HcfResult GetBlobFromNapiValue(napi_env env, napi_value arg, HcfBlob *blob)
198 {
199 napi_value data = GetUint8ArrFromNapiDataBlob(env, arg);
200 if (data == nullptr) {
201 LOGE("failed to get data in DataBlob");
202 return HCF_INVALID_PARAMS;
203 }
204
205 void *rawData = nullptr;
206 napi_typedarray_type arrayType;
207 napi_status status = napi_get_typedarray_info(env, data, &arrayType, &(blob->len),
208 reinterpret_cast<void **>(&rawData), nullptr, nullptr);
209 if (status != napi_ok) {
210 LOGE("failed to get valid rawData.");
211 return HCF_ERR_NAPI;
212 }
213 if (arrayType != napi_uint8_array) {
214 LOGE("input data is not uint8 array.");
215 return HCF_INVALID_PARAMS;
216 }
217
218 blob->data = nullptr;
219 if (blob->len == 0 || rawData == nullptr) {
220 LOGD("napi Uint8Arr is null");
221 return HCF_SUCCESS;
222 }
223
224 blob->data = static_cast<uint8_t *>(HcfMalloc(blob->len, 0));
225 if (blob->data == nullptr) {
226 LOGE("malloc blob data failed!");
227 return HCF_ERR_MALLOC;
228 }
229 (void)memcpy_s(blob->data, blob->len, rawData, blob->len);
230 return HCF_SUCCESS;
231 }
232
GetAadFromParamsSpec(napi_env env,napi_value arg)233 static HcfBlob *GetAadFromParamsSpec(napi_env env, napi_value arg)
234 {
235 napi_value data = nullptr;
236 HcfBlob *blob = nullptr;
237 napi_valuetype valueType = napi_undefined;
238
239 napi_status status = napi_get_named_property(env, arg, AAD_PARAMS.c_str(), &data);
240 napi_typeof(env, data, &valueType);
241 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
242 LOGE("failed to get valid param property!");
243 return nullptr;
244 }
245 if (valueType == napi_null) {
246 blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
247 if (blob == nullptr) {
248 LOGE("Failed to allocate newBlob memory!");
249 return nullptr;
250 }
251 return blob;
252 }
253 blob = GetBlobFromNapiDataBlob(env, data);
254 if (blob == nullptr) {
255 LOGE("GetBlobFromNapiDataBlob failed!");
256 return nullptr;
257 }
258 return blob;
259 }
260
GetBigIntFromNapiValue(napi_env env,napi_value arg,HcfBigInteger * bigInt)261 bool GetBigIntFromNapiValue(napi_env env, napi_value arg, HcfBigInteger *bigInt)
262 {
263 if ((env == nullptr) || (arg == nullptr) || (bigInt == nullptr)) {
264 LOGE("Invalid params!");
265 return false;
266 }
267
268 int signBit;
269 size_t wordCount;
270
271 napi_get_value_bigint_words(env, arg, nullptr, &wordCount, nullptr);
272 if ((wordCount == 0) || (wordCount > (INT_MAX / sizeof(uint64_t)))) {
273 LOGE("Get big int failed.");
274 return false;
275 }
276 int length = wordCount * sizeof(uint64_t);
277 uint8_t *retArr = reinterpret_cast<uint8_t *>(HcfMalloc(length, 0));
278 if (retArr == nullptr) {
279 LOGE("malloc blob data failed!");
280 return false;
281 }
282 if (napi_get_value_bigint_words(env, arg, &signBit, &wordCount, reinterpret_cast<uint64_t *>(retArr)) != napi_ok) {
283 HcfFree(retArr);
284 LOGE("failed to get valid rawData.");
285 return false;
286 }
287 if (signBit != 0) {
288 HcfFree(retArr);
289 LOGE("failed to get gegative rawData.");
290 return false;
291 }
292 bigInt->data = retArr;
293 bigInt->len = length;
294 return true;
295 }
296
GetPointFromNapiValue(napi_env env,napi_value arg,HcfPoint * point)297 bool GetPointFromNapiValue(napi_env env, napi_value arg, HcfPoint *point)
298 {
299 if ((env == nullptr) || (arg == nullptr) || (point == nullptr)) {
300 LOGE("Invalid params!");
301 return false;
302 }
303 napi_value dataX = nullptr;
304 napi_value dataY = nullptr;
305 napi_valuetype valueType = napi_undefined;
306 napi_status status = napi_get_named_property(env, arg, "x", &dataX);
307 napi_typeof(env, dataX, &valueType);
308 if ((status != napi_ok) || (dataX == nullptr) || (valueType == napi_undefined)) {
309 LOGE("failed to get valid algo name!");
310 return false;
311 }
312 status = napi_get_named_property(env, arg, "y", &dataY);
313 napi_typeof(env, dataY, &valueType);
314 if ((status != napi_ok) || (dataY == nullptr) || (valueType == napi_undefined)) {
315 LOGE("failed to get valid algo name!");
316 return false;
317 }
318
319 bool ret = GetBigIntFromNapiValue(env, dataX, &point->x);
320 if (!ret) {
321 LOGE("get point x failed!");
322 return false;
323 }
324 ret = GetBigIntFromNapiValue(env, dataY, &point->y);
325 if (!ret) {
326 LOGE("get point y failed!");
327 HcfFree((point->x).data);
328 (point->x).data = nullptr;
329 return false;
330 }
331 return true;
332 }
333
GetIvParamsSpecType()334 static const char *GetIvParamsSpecType()
335 {
336 return IV_PARAMS_SPEC.c_str();
337 }
338
GetGcmParamsSpecType()339 static const char *GetGcmParamsSpecType()
340 {
341 return GCM_PARAMS_SPEC.c_str();
342 }
343
GetCcmParamsSpecType()344 static const char *GetCcmParamsSpecType()
345 {
346 return CCM_PARAMS_SPEC.c_str();
347 }
348
GetBlobFromParamsSpec(napi_env env,napi_value arg,const string & type)349 static HcfBlob *GetBlobFromParamsSpec(napi_env env, napi_value arg, const string &type)
350 {
351 napi_value data = nullptr;
352 HcfBlob *blob = nullptr;
353 napi_valuetype valueType = napi_undefined;
354
355 napi_status status = napi_get_named_property(env, arg, type.c_str(), &data);
356 napi_typeof(env, data, &valueType);
357 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
358 LOGE("failed to get valid param property!");
359 return nullptr;
360 }
361 blob = GetBlobFromNapiDataBlob(env, data);
362 if (blob == nullptr) {
363 LOGE("GetBlobFromNapiDataBlob failed!");
364 return nullptr;
365 }
366 return blob;
367 }
368
GetIvParamsSpec(napi_env env,napi_value arg,HcfParamsSpec ** paramsSpec)369 static bool GetIvParamsSpec(napi_env env, napi_value arg, HcfParamsSpec **paramsSpec)
370 {
371 HcfIvParamsSpec *ivParamsSpec = reinterpret_cast<HcfIvParamsSpec *>(HcfMalloc(sizeof(HcfIvParamsSpec), 0));
372 if (ivParamsSpec == nullptr) {
373 LOGE("ivParamsSpec malloc failed!");
374 return false;
375 }
376
377 HcfBlob *iv = GetBlobFromParamsSpec(env, arg, IV_PARAMS);
378 if (iv == nullptr) {
379 LOGE("GetBlobFromNapiDataBlob failed!");
380 HcfFree(ivParamsSpec);
381 return false;
382 }
383 ivParamsSpec->base.getType = GetIvParamsSpecType;
384 ivParamsSpec->iv = *iv;
385 *paramsSpec = reinterpret_cast<HcfParamsSpec *>(ivParamsSpec);
386 HcfFree(iv);
387 return true;
388 }
389
GetIvAndAadBlob(napi_env env,napi_value arg,HcfBlob ** iv,HcfBlob ** aad)390 static bool GetIvAndAadBlob(napi_env env, napi_value arg, HcfBlob **iv, HcfBlob **aad)
391 {
392 *iv = GetBlobFromParamsSpec(env, arg, IV_PARAMS);
393 if (*iv == nullptr) {
394 LOGE("get iv failed!");
395 return false;
396 }
397
398 *aad = GetAadFromParamsSpec(env, arg);
399 // error case free is in get paramspec func.
400 if (*aad == nullptr) {
401 LOGE("get aad failed!");
402 return false;
403 }
404 return true;
405 }
406
GetGcmParamsSpec(napi_env env,napi_value arg,HcfCryptoMode opMode,HcfParamsSpec ** paramsSpec)407 static bool GetGcmParamsSpec(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec)
408 {
409 HcfBlob *iv = nullptr;
410 HcfBlob *aad = nullptr;
411 HcfBlob *tag = nullptr;
412 HcfBlob authTag = {};
413 bool ret = false;
414
415 HcfGcmParamsSpec *gcmParamsSpec = reinterpret_cast<HcfGcmParamsSpec *>(HcfMalloc(sizeof(HcfGcmParamsSpec), 0));
416 if (gcmParamsSpec == nullptr) {
417 LOGE("gcmParamsSpec malloc failed!");
418 return false;
419 }
420
421 if (!GetIvAndAadBlob(env, arg, &iv, &aad)) {
422 LOGE("GetIvAndAadBlob failed!");
423 goto clearup;
424 }
425
426 if (opMode == DECRYPT_MODE) {
427 tag = GetBlobFromParamsSpec(env, arg, AUTHTAG_PARAMS);
428 if (tag == nullptr) {
429 LOGE("get tag failed!");
430 goto clearup;
431 }
432 } else if (opMode == ENCRYPT_MODE) {
433 authTag.data = static_cast<uint8_t *>(HcfMalloc(GCM_AUTH_TAG_LEN, 0));
434 if (authTag.data == nullptr) {
435 LOGE("get tag failed!");
436 goto clearup;
437 }
438 authTag.len = GCM_AUTH_TAG_LEN;
439 } else {
440 goto clearup;
441 }
442
443 gcmParamsSpec->base.getType = GetGcmParamsSpecType;
444 gcmParamsSpec->iv = *iv;
445 gcmParamsSpec->aad = *aad;
446 gcmParamsSpec->tag = opMode == DECRYPT_MODE ? *tag : authTag;
447 *paramsSpec = reinterpret_cast<HcfParamsSpec *>(gcmParamsSpec);
448 ret = true;
449 clearup:
450 if (!ret) {
451 HcfBlobDataFree(iv);
452 HcfBlobDataFree(aad);
453 HcfBlobDataFree(tag);
454 HcfFree(gcmParamsSpec);
455 }
456 HcfFree(iv);
457 HcfFree(aad);
458 HcfFree(tag);
459 return ret;
460 }
461
GetCcmParamsSpec(napi_env env,napi_value arg,HcfCryptoMode opMode,HcfParamsSpec ** paramsSpec)462 static bool GetCcmParamsSpec(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec)
463 {
464 HcfBlob *iv = nullptr;
465 HcfBlob *aad = nullptr;
466 HcfBlob *tag = nullptr;
467 HcfBlob authTag = {};
468 bool ret = false;
469
470 HcfCcmParamsSpec *ccmParamsSpec = reinterpret_cast<HcfCcmParamsSpec *>(HcfMalloc(sizeof(HcfCcmParamsSpec), 0));
471 if (ccmParamsSpec == nullptr) {
472 LOGE("ccmParamsSpec malloc failed!");
473 return ret;
474 }
475
476 if (!GetIvAndAadBlob(env, arg, &iv, &aad)) {
477 LOGE("GetIvAndAadBlob failed!");
478 goto clearup;
479 }
480
481 if (opMode == DECRYPT_MODE) {
482 tag = GetBlobFromParamsSpec(env, arg, AUTHTAG_PARAMS);
483 if (tag == nullptr) {
484 LOGE("get tag failed!");
485 goto clearup;
486 }
487 } else if (opMode == ENCRYPT_MODE) {
488 authTag.data = static_cast<uint8_t *>(HcfMalloc(CCM_AUTH_TAG_LEN, 0));
489 if (authTag.data == nullptr) {
490 LOGE("get tag failed!");
491 goto clearup;
492 }
493 authTag.len = CCM_AUTH_TAG_LEN;
494 } else {
495 goto clearup;
496 }
497 ccmParamsSpec->base.getType = GetCcmParamsSpecType;
498 ccmParamsSpec->iv = *iv;
499 ccmParamsSpec->aad = *aad;
500 ccmParamsSpec->tag = opMode == DECRYPT_MODE ? *tag : authTag;
501 *paramsSpec = reinterpret_cast<HcfParamsSpec *>(ccmParamsSpec);
502 ret = true;
503 clearup:
504 if (!ret) {
505 HcfBlobDataFree(iv);
506 HcfBlobDataFree(aad);
507 HcfBlobDataFree(tag);
508 HcfFree(ccmParamsSpec);
509 }
510 HcfFree(iv);
511 HcfFree(aad);
512 HcfFree(tag);
513 return ret;
514 }
515
GetParamsSpecFromNapiValue(napi_env env,napi_value arg,HcfCryptoMode opMode,HcfParamsSpec ** paramsSpec)516 bool GetParamsSpecFromNapiValue(napi_env env, napi_value arg, HcfCryptoMode opMode, HcfParamsSpec **paramsSpec)
517 {
518 napi_value data = nullptr;
519 napi_valuetype valueType = napi_undefined;
520 if ((env == nullptr) || (arg == nullptr) || (paramsSpec == nullptr)) {
521 LOGE("Invalid params!");
522 return false;
523 }
524
525 napi_status status = napi_get_named_property(env, arg, ALGO_PARAMS.c_str(), &data);
526 napi_typeof(env, data, &valueType);
527 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
528 status = napi_get_named_property(env, arg, ALGO_PARAMS_OLD.c_str(), &data);
529 napi_typeof(env, data, &valueType);
530 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
531 LOGE("failed to get valid algo name!");
532 return false;
533 }
534 }
535 string algoName;
536 if (!GetStringFromJSParams(env, data, algoName)) {
537 LOGE("GetStringFromJSParams failed!");
538 return false;
539 }
540 if (algoName.compare(IV_PARAMS_SPEC) == 0) {
541 return GetIvParamsSpec(env, arg, paramsSpec);
542 } else if (algoName.compare(GCM_PARAMS_SPEC) == 0) {
543 return GetGcmParamsSpec(env, arg, opMode, paramsSpec);
544 } else if (algoName.compare(CCM_PARAMS_SPEC) == 0) {
545 return GetCcmParamsSpec(env, arg, opMode, paramsSpec);
546 } else {
547 return false;
548 }
549 }
550
GetCharArrayFromJsString(napi_env env,napi_value arg,HcfBlob * retBlob)551 static bool GetCharArrayFromJsString(napi_env env, napi_value arg, HcfBlob *retBlob)
552 {
553 size_t length = 0;
554 if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
555 LOGE("can not get char string length");
556 return false;
557 }
558 if (length > PASSWORD_MAX_LENGTH) {
559 LOGE("password length should not exceed 4096");
560 return false;
561 }
562 if (length == 0) {
563 LOGD("empty string");
564 return false;
565 }
566 char *tmpPassword = static_cast<char *>(HcfMalloc(length + 1, 0));
567 if (tmpPassword == nullptr) {
568 LOGE("malloc string failed");
569 return false;
570 }
571 if (napi_get_value_string_utf8(env, arg, tmpPassword, (length + 1), &length) != napi_ok) {
572 LOGE("can not get char string value");
573 HcfFree(tmpPassword);
574 return false;
575 }
576 retBlob->data = reinterpret_cast<uint8_t *>(tmpPassword);
577 retBlob->len = length;
578 return true;
579 }
580
InitEncodingParams(napi_env env,napi_value arg,HcfKeyEncodingParamsSpec * spec,HcfBlob * tmpPw,HcfBlob * tmpCipher)581 static bool InitEncodingParams(napi_env env, napi_value arg, HcfKeyEncodingParamsSpec *spec, HcfBlob *tmpPw,
582 HcfBlob *tmpCipher)
583 {
584 napi_value passWd = GetDetailAsyKeySpecValue(env, arg, PASSWD_PARAMS);
585 napi_value cipher = GetDetailAsyKeySpecValue(env, arg, CIPHER_PARAMS);
586 if ((passWd == nullptr) || (cipher == nullptr)) {
587 LOGE("Invalid params.");
588 return false;
589 }
590
591 if (!GetCharArrayFromJsString(env, passWd, tmpPw)) {
592 LOGE("Failed to get passWord string from napi!");
593 return false;
594 }
595
596 if (!GetCharArrayFromJsString(env, cipher, tmpCipher)) {
597 LOGE("Failed to get cipher string from napi!");
598 HcfBlobDataClearAndFree(tmpPw);
599 return false;
600 }
601
602 spec->cipher = reinterpret_cast<char *>(tmpCipher->data);
603 spec->password = reinterpret_cast<char *>(tmpPw->data);
604 return true;
605 }
606
GetEncodingParamsSpec(napi_env env,napi_value arg,HcfParamsSpec ** returnSpec)607 bool GetEncodingParamsSpec(napi_env env, napi_value arg, HcfParamsSpec **returnSpec)
608 {
609 if ((env == nullptr) || (arg == nullptr) || (returnSpec == nullptr)) {
610 LOGE("Invalid params.");
611 return false;
612 }
613
614 HcfKeyEncodingParamsSpec *encodingParamsSpec =
615 reinterpret_cast<HcfKeyEncodingParamsSpec *>(HcfMalloc(sizeof(HcfKeyEncodingParamsSpec), 0));
616 if (encodingParamsSpec == nullptr) {
617 LOGE("encodingParamsSpec malloc failed!");
618 return false;
619 }
620
621 HcfBlob tmpPw = { .data = nullptr, .len = 0 };
622 HcfBlob tmpCipher = { .data = nullptr, .len = 0 };
623 if (!InitEncodingParams(env, arg, encodingParamsSpec, &tmpPw, &tmpCipher)) {
624 LOGE("Failed to get passWord string from napi!");
625 HcfFree(encodingParamsSpec);
626 return false;
627 }
628 *returnSpec = reinterpret_cast<HcfParamsSpec *>(encodingParamsSpec);
629 return true;
630 }
631
GetBlobFromStringJSParams(napi_env env,napi_value arg)632 static HcfBlob *GetBlobFromStringJSParams(napi_env env, napi_value arg)
633 {
634 napi_valuetype valueType;
635 napi_typeof(env, arg, &valueType);
636 if (valueType != napi_string) {
637 LOGE("wrong argument type. expect string type. [Type]: %d", valueType);
638 return nullptr;
639 }
640
641 size_t length = 0;
642 if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
643 LOGE("can not get string length");
644 return nullptr;
645 }
646
647 if (length == 0) {
648 LOGE("string length is 0");
649 return nullptr;
650 }
651
652 HcfBlob *newBlob = static_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
653 if (newBlob == nullptr) {
654 LOGE("Failed to allocate newBlob memory!");
655 return nullptr;
656 }
657
658 newBlob->len = length + 1;
659 newBlob->data = static_cast<uint8_t *>(HcfMalloc(newBlob->len, 0));
660 if (newBlob->data == nullptr) {
661 LOGE("malloc blob data failed!");
662 HcfFree(newBlob);
663 return nullptr;
664 }
665
666 if (napi_get_value_string_utf8(env, arg, reinterpret_cast<char *>(newBlob->data), newBlob->len, &length) !=
667 napi_ok) {
668 LOGE("can not get string value");
669 HcfBlobDataClearAndFree(newBlob);
670 HcfFree(newBlob);
671 return nullptr;
672 }
673
674 return newBlob;
675 }
676
GetDecodingParamsSpec(napi_env env,napi_value arg,HcfParamsSpec ** returnSpec)677 bool GetDecodingParamsSpec(napi_env env, napi_value arg, HcfParamsSpec **returnSpec)
678 {
679 HcfKeyDecodingParamsSpec *decodingParamsSpec =
680 reinterpret_cast<HcfKeyDecodingParamsSpec *>(HcfMalloc(sizeof(HcfKeyDecodingParamsSpec), 0));
681 if (decodingParamsSpec == nullptr) {
682 LOGE("decodingParamsSpec malloc failed!");
683 return false;
684 }
685
686 HcfBlob *tmpPw = GetBlobFromStringJSParams(env, arg);
687 if (tmpPw == nullptr) {
688 LOGE("Failed to get passWord string from napi!");
689 HcfFree(decodingParamsSpec);
690 return false;
691 }
692 if (tmpPw->len > PASSWORD_MAX_LENGTH) {
693 LOGE("Password length exceeds max length limit of 4096 bytes!");
694 HcfBlobDataClearAndFree(tmpPw);
695 HcfFree(decodingParamsSpec);
696 return false;
697 }
698 decodingParamsSpec->password = reinterpret_cast<char *>(tmpPw->data);
699
700 *returnSpec = reinterpret_cast<HcfParamsSpec *>(decodingParamsSpec);
701 HcfFree(tmpPw);
702 return true;
703 }
704
GetDetailAsyKeySpecValue(napi_env env,napi_value arg,string argName)705 napi_value GetDetailAsyKeySpecValue(napi_env env, napi_value arg, string argName)
706 {
707 napi_value data = nullptr;
708 napi_valuetype valueType = napi_undefined;
709 if ((env == nullptr) || (arg == nullptr)) {
710 LOGE("Invalid params!");
711 return nullptr;
712 }
713 napi_status status = napi_get_named_property(env, arg, argName.c_str(), &data);
714 napi_typeof(env, data, &valueType);
715 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
716 LOGE("failed to get valid algo name!");
717 return nullptr;
718 }
719 return data;
720 }
721
GetCommSpecNapiValue(napi_env env,napi_value arg)722 static napi_value GetCommSpecNapiValue(napi_env env, napi_value arg)
723 {
724 napi_value data = nullptr;
725 napi_valuetype valueType = napi_undefined;
726
727 napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_COMM_PARAMS.c_str(), &data);
728 napi_typeof(env, data, &valueType);
729
730 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
731 LOGE("failed to get valid algo name!");
732 return nullptr;
733 }
734 return data;
735 }
736
InitDsaCommonAsyKeySpec(napi_env env,napi_value arg,HcfDsaCommParamsSpec * spec)737 static bool InitDsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfDsaCommParamsSpec *spec)
738 {
739 size_t algNameLen = DSA_ASY_KEY_SPEC.length();
740 spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
741 if (spec->base.algName == nullptr) {
742 LOGE("malloc DSA algName failed!");
743 return false;
744 }
745 (void)memcpy_s(spec->base.algName, algNameLen+ 1, DSA_ASY_KEY_SPEC.c_str(), algNameLen);
746 spec->base.specType = HCF_COMMON_PARAMS_SPEC;
747
748 napi_value p = GetDetailAsyKeySpecValue(env, arg, "p");
749 napi_value q = GetDetailAsyKeySpecValue(env, arg, "q");
750 napi_value g = GetDetailAsyKeySpecValue(env, arg, "g");
751 bool ret = GetBigIntFromNapiValue(env, p, &spec->p);
752 if (!ret) {
753 HcfFree(spec->base.algName);
754 spec->base.algName = nullptr;
755 return false;
756 }
757 ret = GetBigIntFromNapiValue(env, q, &spec->q);
758 if (!ret) {
759 FreeDsaCommParamsSpec(spec);
760 return false;
761 }
762 ret = GetBigIntFromNapiValue(env, g, &spec->g);
763 if (!ret) {
764 FreeDsaCommParamsSpec(spec);
765 return false;
766 }
767 return true;
768 }
769
GetDsaCommonAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)770 static bool GetDsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
771 {
772 HcfDsaCommParamsSpec *spec = reinterpret_cast<HcfDsaCommParamsSpec *>(HcfMalloc(sizeof(HcfDsaCommParamsSpec), 0));
773 if (spec == nullptr) {
774 LOGE("malloc failed!");
775 return false;
776 }
777 if (!InitDsaCommonAsyKeySpec(env, arg, spec)) {
778 LOGE("InitDsaCommonAsyKeySpec failed!");
779 HcfFree(spec);
780 return false;
781 }
782 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
783 return true;
784 }
785
GetDsaPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)786 static bool GetDsaPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
787 {
788 HcfDsaPubKeyParamsSpec *spec = reinterpret_cast<HcfDsaPubKeyParamsSpec *>(
789 HcfMalloc(sizeof(HcfDsaPubKeyParamsSpec), 0));
790 if (spec == nullptr) {
791 LOGE("malloc failed!");
792 return false;
793 }
794
795 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
796 if (commSpecValue == nullptr) {
797 LOGE("Get comm spec napi value failed.");
798 HcfFree(spec);
799 return false;
800 }
801 if (!InitDsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDsaCommParamsSpec *>(spec))) {
802 LOGE("InitDsaCommonAsyKeySpec failed.");
803 HcfFree(spec);
804 return false;
805 }
806 spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
807
808 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
809 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
810 if (!ret) {
811 DestroyDsaPubKeySpec(spec);
812 return false;
813 }
814 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
815 return true;
816 }
817
GetDsaKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)818 static bool GetDsaKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
819 {
820 HcfDsaKeyPairParamsSpec *spec = reinterpret_cast<HcfDsaKeyPairParamsSpec *>(
821 HcfMalloc(sizeof(HcfDsaKeyPairParamsSpec), 0));
822 if (spec == nullptr) {
823 LOGE("malloc failed!");
824 return false;
825 }
826
827 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
828 if (commSpecValue == nullptr) {
829 LOGE("Get comm spec napi value failed.");
830 HcfFree(spec);
831 return false;
832 }
833 if (!InitDsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDsaCommParamsSpec *>(spec))) {
834 LOGE("InitDsaCommonAsyKeySpec failed!");
835 HcfFree(spec);
836 return false;
837 }
838 spec->base.base.specType = HCF_KEY_PAIR_SPEC;
839
840 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
841 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
842 if (!ret) {
843 FreeDsaCommParamsSpec(reinterpret_cast<HcfDsaCommParamsSpec *>(spec));
844 HcfFree(spec);
845 return false;
846 }
847 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
848 ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
849 if (!ret) {
850 FreeDsaCommParamsSpec(reinterpret_cast<HcfDsaCommParamsSpec *>(spec));
851 HcfFree(spec->pk.data);
852 HcfFree(spec);
853 return false;
854 }
855 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
856 return true;
857 }
858
GetDsaAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)859 static bool GetDsaAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
860 {
861 napi_value data = nullptr;
862 napi_valuetype valueType = napi_undefined;
863
864 napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
865 napi_typeof(env, data, &valueType);
866 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
867 LOGE("failed to get valid algo name!");
868 return false;
869 }
870 HcfAsyKeySpecType asyKeySpecType;
871 status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
872 if (status != napi_ok) {
873 LOGE("failed to get valid asyKeySpecType!");
874 return false;
875 }
876 if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
877 return GetDsaCommonAsyKeySpec(env, arg, asyKeySpec);
878 } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
879 return GetDsaPubKeySpec(env, arg, asyKeySpec);
880 } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
881 return GetDsaKeyPairAsyKeySpec(env, arg, asyKeySpec);
882 } else {
883 return false;
884 }
885 }
886
GetFpField(napi_env env,napi_value arg,HcfECField ** ecField)887 static bool GetFpField(napi_env env, napi_value arg, HcfECField **ecField)
888 {
889 HcfECFieldFp *fp = reinterpret_cast<HcfECFieldFp *>(HcfMalloc(sizeof(HcfECFieldFp), 0));
890 if (fp == nullptr) {
891 LOGE("malloc fp failed!");
892 return false;
893 }
894
895 size_t fieldTpyeLen = ECC_FIELD_TYPE_FP.length();
896 fp->base.fieldType = static_cast<char *>(HcfMalloc(fieldTpyeLen + 1, 0));
897 if (fp->base.fieldType == nullptr) {
898 LOGE("malloc fieldType failed!");
899 HcfFree(fp);
900 return false;
901 }
902 (void)memcpy_s(fp->base.fieldType, fieldTpyeLen+ 1, ECC_FIELD_TYPE_FP.c_str(), fieldTpyeLen);
903
904 napi_value p = GetDetailAsyKeySpecValue(env, arg, "p");
905 bool ret = GetBigIntFromNapiValue(env, p, &fp->p);
906 if (!ret) {
907 HcfFree(fp->base.fieldType);
908 HcfFree(fp);
909 return false;
910 }
911 *ecField = reinterpret_cast<HcfECField *>(fp);
912 return true;
913 }
914
GetField(napi_env env,napi_value arg,HcfECField ** ecField)915 static bool GetField(napi_env env, napi_value arg, HcfECField **ecField)
916 {
917 // get fieldData in { field : fieldData, a : xxx, b : xxx, ... } of ECCCommonParamsSpec first
918 napi_value fieldData = nullptr;
919 napi_valuetype valueType = napi_undefined;
920 napi_status status = napi_get_named_property(env, arg, "field", &fieldData);
921 napi_typeof(env, fieldData, &valueType);
922 if ((status != napi_ok) || (fieldData == nullptr) || (valueType == napi_undefined)) {
923 LOGE("failed to get valid field data!");
924 return false;
925 }
926
927 // get fieldType in { fieldType : fieldTypeData } of ECField
928 napi_value fieldTypeData = nullptr;
929 status = napi_get_named_property(env, fieldData, "fieldType", &fieldTypeData);
930 napi_typeof(env, fieldTypeData, &valueType);
931 if ((status != napi_ok) || (fieldTypeData == nullptr) || (valueType == napi_undefined)) {
932 LOGE("failed to get valid fieldType data!");
933 return false;
934 }
935 string fieldType;
936 if (!GetStringFromJSParams(env, fieldTypeData, fieldType)) {
937 LOGE("GetStringFromJSParams failed when extracting fieldType!");
938 return false;
939 }
940
941 // get p in { p : pData } of ECField, and generateECField
942 if (fieldType.compare("Fp") == 0) {
943 return GetFpField(env, fieldData, ecField);
944 }
945 return false;
946 }
947
InitEccDetailAsyKeySpec(napi_env env,napi_value arg,HcfEccCommParamsSpec * spec)948 static bool InitEccDetailAsyKeySpec(napi_env env, napi_value arg, HcfEccCommParamsSpec *spec)
949 {
950 napi_value a = GetDetailAsyKeySpecValue(env, arg, "a");
951 napi_value b = GetDetailAsyKeySpecValue(env, arg, "b");
952 napi_value n = GetDetailAsyKeySpecValue(env, arg, "n");
953 napi_value g = GetDetailAsyKeySpecValue(env, arg, "g");
954 bool ret = GetBigIntFromNapiValue(env, a, &spec->a);
955 if (!ret) {
956 LOGE("get ecc asyKeySpec a failed!");
957 return false;
958 }
959 ret = GetBigIntFromNapiValue(env, b, &spec->b);
960 if (!ret) {
961 LOGE("get ecc asyKeySpec b failed!");
962 return false;
963 }
964 ret = GetBigIntFromNapiValue(env, n, &spec->n);
965 if (!ret) {
966 LOGE("get ecc asyKeySpec n failed!");
967 return false;
968 }
969 ret = GetPointFromNapiValue(env, g, &spec->g);
970 if (!ret) {
971 LOGE("get ecc asyKeySpec g failed!");
972 return false;
973 }
974 return true;
975 }
976
InitEccCommonAsyKeySpec(napi_env env,napi_value arg,HcfEccCommParamsSpec * spec,const string & algName)977 static bool InitEccCommonAsyKeySpec(napi_env env, napi_value arg, HcfEccCommParamsSpec *spec, const string &algName)
978 {
979 size_t algNameLen = ECC_ASY_KEY_SPEC.length();
980 spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
981 if (spec->base.algName == nullptr) {
982 LOGE("malloc ECC algName failed!");
983 return false;
984 }
985 (void)memcpy_s(spec->base.algName, algNameLen+ 1, algName.c_str(), algNameLen);
986 spec->base.specType = HCF_COMMON_PARAMS_SPEC;
987
988 // get h
989 napi_value hData = nullptr;
990 napi_valuetype valueType = napi_undefined;
991 napi_status status = napi_get_named_property(env, arg, "h", &hData);
992 napi_typeof(env, hData, &valueType);
993 if ((status != napi_ok) || (hData == nullptr) || (valueType == napi_undefined)) {
994 LOGE("failed to get valid h!");
995 HcfFree(spec->base.algName);
996 spec->base.algName = nullptr;
997 return false;
998 }
999 if (!GetInt32FromJSParams(env, hData, spec->h)) {
1000 LOGE("get ecc asyKeySpec h failed!");
1001 HcfFree(spec->base.algName);
1002 spec->base.algName = nullptr;
1003 return false;
1004 }
1005 // get field
1006 if (!GetField(env, arg, &spec->field)) {
1007 LOGE("GetField failed!");
1008 HcfFree(spec->base.algName);
1009 spec->base.algName = nullptr;
1010 return false;
1011 }
1012 bool ret = InitEccDetailAsyKeySpec(env, arg, spec);
1013 if (!ret) {
1014 LOGE("get ecc asyKeySpec g failed!");
1015 FreeEccCommParamsSpec(spec);
1016 return false;
1017 }
1018 return true;
1019 }
1020
GetEccCommonAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1021 static bool GetEccCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec,
1022 const string &algName)
1023 {
1024 HcfEccCommParamsSpec *spec = reinterpret_cast<HcfEccCommParamsSpec *>(HcfMalloc(sizeof(HcfEccCommParamsSpec), 0));
1025 if (spec == nullptr) {
1026 LOGE("malloc failed!");
1027 return false;
1028 }
1029 if (!InitEccCommonAsyKeySpec(env, arg, spec, algName)) {
1030 LOGE("InitEccCommonAsyKeySpec failed!");
1031 HcfFree(spec);
1032 return false;
1033 }
1034 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1035 return true;
1036 }
1037
GetEccPriKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1038 static bool GetEccPriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1039 {
1040 HcfEccPriKeyParamsSpec *spec =
1041 reinterpret_cast<HcfEccPriKeyParamsSpec *>(HcfMalloc(sizeof(HcfEccPriKeyParamsSpec), 0));
1042 if (spec == nullptr) {
1043 LOGE("malloc failed!");
1044 return false;
1045 }
1046
1047 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1048 if (commSpecValue == nullptr) {
1049 LOGE("Get comm spec napi value failed.");
1050 HcfFree(spec);
1051 return false;
1052 }
1053 if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfEccCommParamsSpec *>(spec), algName)) {
1054 LOGE("InitEccCommonAsyKeySpec failed!");
1055 HcfFree(spec);
1056 return false;
1057 }
1058 spec->base.base.specType = HCF_PRIVATE_KEY_SPEC;
1059
1060 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1061 bool ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1062 if (!ret) {
1063 // get big int fail, sk is null
1064 FreeEccCommParamsSpec(reinterpret_cast<HcfEccCommParamsSpec *>(spec));
1065 HcfFree(spec);
1066 return false;
1067 }
1068 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1069 return true;
1070 }
1071
GetEccPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1072 static bool GetEccPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1073 {
1074 HcfEccPubKeyParamsSpec *spec =
1075 reinterpret_cast<HcfEccPubKeyParamsSpec *>(HcfMalloc(sizeof(HcfEccPubKeyParamsSpec), 0));
1076 if (spec == nullptr) {
1077 LOGE("malloc failed!");
1078 return false;
1079 }
1080
1081 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1082 if (commSpecValue == nullptr) {
1083 LOGE("Get comm spec napi value failed.");
1084 HcfFree(spec);
1085 return false;
1086 }
1087 if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfEccCommParamsSpec *>(spec), algName)) {
1088 LOGE("InitEccCommonAsyKeySpec failed!");
1089 HcfFree(spec);
1090 return false;
1091 }
1092 spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
1093
1094 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1095 bool ret = GetPointFromNapiValue(env, pk, &spec->pk);
1096 if (!ret) {
1097 DestroyEccPubKeySpec(spec);
1098 return false;
1099 }
1100 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1101 return true;
1102 }
1103
GetEccKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1104 static bool GetEccKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec,
1105 const string &algName)
1106 {
1107 HcfEccKeyPairParamsSpec *spec =
1108 reinterpret_cast<HcfEccKeyPairParamsSpec *>(HcfMalloc(sizeof(HcfEccKeyPairParamsSpec), 0));
1109 if (spec == nullptr) {
1110 LOGE("malloc failed!");
1111 return false;
1112 }
1113
1114 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1115 if (commSpecValue == nullptr) {
1116 LOGE("Get comm spec napi value failed.");
1117 HcfFree(spec);
1118 return false;
1119 }
1120 if (!InitEccCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfEccCommParamsSpec *>(spec), algName)) {
1121 LOGE("InitEccCommonAsyKeySpec failed!");
1122 HcfFree(spec);
1123 return false;
1124 }
1125 spec->base.base.specType = HCF_KEY_PAIR_SPEC;
1126
1127 // get big int fail, sk is null
1128 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1129 bool ret = GetPointFromNapiValue(env, pk, &spec->pk);
1130 if (!ret) {
1131 FreeEccCommParamsSpec(reinterpret_cast<HcfEccCommParamsSpec *>(spec));
1132 HcfFree(spec);
1133 return false;
1134 }
1135 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1136 ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1137 if (!ret) {
1138 FreeEccCommParamsSpec(reinterpret_cast<HcfEccCommParamsSpec *>(spec));
1139 HcfFree(spec->pk.x.data);
1140 HcfFree(spec->pk.y.data);
1141 HcfFree(spec);
1142 return false;
1143 }
1144 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1145 return true;
1146 }
1147
GetEccAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1148 static bool GetEccAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1149 {
1150 napi_value data = nullptr;
1151 napi_valuetype valueType = napi_undefined;
1152
1153 napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1154 napi_typeof(env, data, &valueType);
1155 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1156 LOGE("failed to get valid algo name!");
1157 return false;
1158 }
1159 HcfAsyKeySpecType asyKeySpecType;
1160 status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1161 if (status != napi_ok) {
1162 LOGE("failed to get valid asyKeySpecType!");
1163 return false;
1164 }
1165 if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
1166 return GetEccCommonAsyKeySpec(env, arg, asyKeySpec, algName);
1167 } else if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) {
1168 return GetEccPriKeySpec(env, arg, asyKeySpec, algName);
1169 } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1170 return GetEccPubKeySpec(env, arg, asyKeySpec, algName);
1171 } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1172 return GetEccKeyPairAsyKeySpec(env, arg, asyKeySpec, algName);
1173 } else {
1174 LOGE("keySpec not support!");
1175 return false;
1176 }
1177 }
1178
InitRsaCommonAsyKeySpec(napi_env env,napi_value arg,HcfRsaCommParamsSpec * spec)1179 static bool InitRsaCommonAsyKeySpec(napi_env env, napi_value arg, HcfRsaCommParamsSpec *spec)
1180 {
1181 size_t algNameLen = RSA_ASY_KEY_SPEC.length();
1182 spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
1183 if (spec->base.algName == nullptr) {
1184 LOGE("malloc RSA algName failed!");
1185 return false;
1186 }
1187 (void)memcpy_s(spec->base.algName, algNameLen+ 1, RSA_ASY_KEY_SPEC.c_str(), algNameLen);
1188 spec->base.specType = HCF_COMMON_PARAMS_SPEC;
1189
1190 napi_value n = GetDetailAsyKeySpecValue(env, arg, "n");
1191
1192 bool ret = GetBigIntFromNapiValue(env, n, &spec->n);
1193 if (!ret) {
1194 LOGE("Rsa asyKeySpec get n failed!");
1195 HcfFree(spec->base.algName);
1196 spec->base.algName = nullptr;
1197 return false;
1198 }
1199 return true;
1200 }
1201
GetRsaPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1202 static bool GetRsaPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1203 {
1204 HcfRsaPubKeyParamsSpec *spec =
1205 reinterpret_cast<HcfRsaPubKeyParamsSpec *>(HcfMalloc(sizeof(HcfRsaPubKeyParamsSpec), 0));
1206 if (spec == nullptr) {
1207 LOGE("malloc failed!");
1208 return false;
1209 }
1210
1211 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1212 if (commSpecValue == nullptr) {
1213 LOGE("Get comm spec napi value failed.");
1214 HcfFree(spec);
1215 return false;
1216 }
1217 if (!InitRsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfRsaCommParamsSpec *>(spec))) {
1218 LOGE("InitRsaCommonAsyKeySpec failed!");
1219 HcfFree(spec);
1220 return false;
1221 }
1222 spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
1223
1224 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1225 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1226 if (!ret) {
1227 DestroyRsaPubKeySpec(spec);
1228 return false;
1229 }
1230 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1231 return true;
1232 }
1233
GetRsaKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1234 static bool GetRsaKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1235 {
1236 HcfRsaKeyPairParamsSpec *spec =
1237 reinterpret_cast<HcfRsaKeyPairParamsSpec *>(HcfMalloc(sizeof(HcfRsaKeyPairParamsSpec), 0));
1238 if (spec == nullptr) {
1239 LOGE("malloc failed!");
1240 return false;
1241 }
1242
1243 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1244 if (commSpecValue == nullptr) {
1245 LOGE("Get comm spec napi value failed.");
1246 HcfFree(spec);
1247 return false;
1248 }
1249 if (!InitRsaCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfRsaCommParamsSpec *>(spec))) {
1250 LOGE("InitRsaCommonAsyKeySpec failed!");
1251 HcfFree(spec);
1252 return false;
1253 }
1254 spec->base.base.specType = HCF_KEY_PAIR_SPEC;
1255
1256 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1257 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1258 if (!ret) {
1259 FreeRsaCommParamsSpec(&(spec->base));
1260 HcfFree(spec);
1261 return false;
1262 }
1263 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1264 ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1265 if (!ret) {
1266 FreeRsaCommParamsSpec(&(spec->base));
1267 HcfFree(spec->pk.data);
1268 HcfFree(spec);
1269 return false;
1270 }
1271 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1272 return true;
1273 }
1274
GetRsaAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1275 static bool GetRsaAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1276 {
1277 napi_value data = nullptr;
1278 napi_valuetype valueType = napi_undefined;
1279
1280 napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1281 napi_typeof(env, data, &valueType);
1282 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1283 LOGE("failed to get valid algo name!");
1284 return false;
1285 }
1286 HcfAsyKeySpecType asyKeySpecType;
1287 status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1288 if (status != napi_ok) {
1289 LOGE("failed to get valid asyKeySpecType!");
1290 return false;
1291 }
1292 if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
1293 LOGE("RSA not support comm key spec");
1294 return false;
1295 } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1296 return GetRsaPubKeySpec(env, arg, asyKeySpec);
1297 } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1298 return GetRsaKeyPairAsyKeySpec(env, arg, asyKeySpec);
1299 } else {
1300 return false;
1301 }
1302 }
1303
InitAlg25519CommonAsyKeySpec(HcfAsyKeyParamsSpec * spec,const string & algName)1304 static bool InitAlg25519CommonAsyKeySpec(HcfAsyKeyParamsSpec *spec, const string &algName)
1305 {
1306 size_t algNameLen = algName.length();
1307 spec->algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
1308 if (spec->algName == nullptr) {
1309 LOGE("malloc alg25519 algName failed!");
1310 return false;
1311 }
1312 (void)memcpy_s(spec->algName, algNameLen + 1, algName.c_str(), algNameLen);
1313 return true;
1314 }
1315
GetAlg25519PriKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1316 static bool GetAlg25519PriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1317 {
1318 HcfAlg25519PriKeyParamsSpec *spec =
1319 reinterpret_cast<HcfAlg25519PriKeyParamsSpec *>(HcfMalloc(sizeof(HcfAlg25519PriKeyParamsSpec), 0));
1320 if (spec == nullptr) {
1321 LOGE("malloc failed!");
1322 return false;
1323 }
1324 if (!InitAlg25519CommonAsyKeySpec(reinterpret_cast<HcfAsyKeyParamsSpec *>(spec), algName)) {
1325 LOGE("InitRsaCommonAsyKeySpec failed!");
1326 DestroyAlg25519PriKeySpec(spec);
1327 return false;
1328 }
1329 spec->base.specType = HCF_PRIVATE_KEY_SPEC;
1330
1331 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1332 bool ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1333 if (!ret) {
1334 // get big int fail, sk is null
1335 DestroyAlg25519PriKeySpec(spec);
1336 return false;
1337 }
1338 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1339 return true;
1340 }
1341
GetAlg25519PubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1342 static bool GetAlg25519PubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1343 {
1344 HcfAlg25519PubKeyParamsSpec *spec =
1345 reinterpret_cast<HcfAlg25519PubKeyParamsSpec *>(HcfMalloc(sizeof(HcfAlg25519PubKeyParamsSpec), 0));
1346 if (spec == nullptr) {
1347 LOGE("malloc failed!");
1348 return false;
1349 }
1350 if (!InitAlg25519CommonAsyKeySpec(reinterpret_cast<HcfAsyKeyParamsSpec *>(spec), algName)) {
1351 LOGE("InitRsaCommonAsyKeySpec failed!");
1352 DestroyAlg25519PubKeySpec(spec);
1353 return false;
1354 }
1355 spec->base.specType = HCF_PUBLIC_KEY_SPEC;
1356
1357 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1358 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1359 if (!ret) {
1360 DestroyAlg25519PubKeySpec(spec);
1361 return false;
1362 }
1363 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1364 return true;
1365 }
1366
GetAlg25519KeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1367 static bool GetAlg25519KeyPairAsyKeySpec(napi_env env, napi_value arg,
1368 HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1369 {
1370 HcfAlg25519KeyPairParamsSpec *spec =
1371 reinterpret_cast<HcfAlg25519KeyPairParamsSpec *>(HcfMalloc(sizeof(HcfAlg25519KeyPairParamsSpec), 0));
1372 if (spec == nullptr) {
1373 LOGE("malloc failed!");
1374 return false;
1375 }
1376 if (!InitAlg25519CommonAsyKeySpec(reinterpret_cast<HcfAsyKeyParamsSpec *>(spec), algName)) {
1377 LOGE("InitRsaCommonAsyKeySpec failed!");
1378 HcfFree(spec);
1379 return false;
1380 }
1381 spec->base.specType = HCF_KEY_PAIR_SPEC;
1382
1383 // get big int fail, sk is null
1384 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1385 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1386 if (!ret) {
1387 DestroyAlg25519KeyPairSpec(spec);
1388 return false;
1389 }
1390 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1391 ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1392 if (!ret) {
1393 DestroyAlg25519KeyPairSpec(spec);
1394 return false;
1395 }
1396 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1397 return true;
1398 }
1399
GetAlg25519AsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec,const string & algName)1400 static bool GetAlg25519AsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec, const string &algName)
1401 {
1402 napi_value data = nullptr;
1403 napi_valuetype valueType = napi_undefined;
1404
1405 napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1406 napi_typeof(env, data, &valueType);
1407 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1408 LOGE("failed to get valid algo name!");
1409 return false;
1410 }
1411 HcfAsyKeySpecType asyKeySpecType;
1412 status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1413 if (status != napi_ok) {
1414 LOGE("failed to get valid asyKeySpecType!");
1415 return false;
1416 }
1417 if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) {
1418 return GetAlg25519PriKeySpec(env, arg, asyKeySpec, algName);
1419 } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1420 return GetAlg25519PubKeySpec(env, arg, asyKeySpec, algName);
1421 } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1422 return GetAlg25519KeyPairAsyKeySpec(env, arg, asyKeySpec, algName);
1423 } else {
1424 LOGE("keySpec not support!");
1425 return false;
1426 }
1427 }
1428
InitDhCommonAsyKeySpec(napi_env env,napi_value arg,HcfDhCommParamsSpec * spec)1429 static bool InitDhCommonAsyKeySpec(napi_env env, napi_value arg, HcfDhCommParamsSpec *spec)
1430 {
1431 size_t algNameLen = DH_ASY_KEY_SPEC.length();
1432 spec->base.algName = static_cast<char *>(HcfMalloc(algNameLen + 1, 0));
1433 if (spec->base.algName == nullptr) {
1434 LOGE("malloc DH algName failed!");
1435 return false;
1436 }
1437 (void)memcpy_s(spec->base.algName, algNameLen+ 1, DH_ASY_KEY_SPEC.c_str(), algNameLen);
1438 spec->base.specType = HCF_COMMON_PARAMS_SPEC;
1439
1440 napi_value length = nullptr;
1441 napi_valuetype valueType = napi_undefined;
1442 napi_status status = napi_get_named_property(env, arg, "l", &length);
1443 napi_typeof(env, length, &valueType);
1444 if ((status != napi_ok) || (length == nullptr) || (valueType == napi_undefined)) {
1445 LOGE("failed to get valid l!");
1446 HcfFree(spec->base.algName);
1447 spec->base.algName = nullptr;
1448 return false;
1449 }
1450 if (!GetInt32FromJSParams(env, length, spec->length)) {
1451 LOGE("get dh asyKeySpec length failed!");
1452 HcfFree(spec->base.algName);
1453 spec->base.algName = nullptr;
1454 return false;
1455 }
1456 napi_value p = GetDetailAsyKeySpecValue(env, arg, "p");
1457 napi_value g = GetDetailAsyKeySpecValue(env, arg, "g");
1458 bool ret = GetBigIntFromNapiValue(env, p, &spec->p);
1459 if (!ret) {
1460 HcfFree(spec->base.algName);
1461 spec->base.algName = nullptr;
1462 return false;
1463 }
1464 ret = GetBigIntFromNapiValue(env, g, &spec->g);
1465 if (!ret) {
1466 FreeDhCommParamsSpec(spec);
1467 return false;
1468 }
1469 return true;
1470 }
1471
GetDhCommonAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1472 static bool GetDhCommonAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1473 {
1474 HcfDhCommParamsSpec *spec = reinterpret_cast<HcfDhCommParamsSpec *>(HcfMalloc(sizeof(HcfDhCommParamsSpec), 0));
1475 if (spec == nullptr) {
1476 LOGE("malloc failed!");
1477 return false;
1478 }
1479 if (!InitDhCommonAsyKeySpec(env, arg, spec)) {
1480 LOGE("InitDhCommonAsyKeySpec failed!");
1481 HcfFree(spec);
1482 return false;
1483 }
1484 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1485 return true;
1486 }
1487
GetDhPubKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1488 static bool GetDhPubKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1489 {
1490 HcfDhPubKeyParamsSpec *spec = reinterpret_cast<HcfDhPubKeyParamsSpec *>(
1491 HcfMalloc(sizeof(HcfDhPubKeyParamsSpec), 0));
1492 if (spec == nullptr) {
1493 LOGE("malloc failed!");
1494 return false;
1495 }
1496
1497 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1498 if (commSpecValue == nullptr) {
1499 LOGE("Get comm spec napi value failed.");
1500 HcfFree(spec);
1501 return false;
1502 }
1503 if (!InitDhCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDhCommParamsSpec *>(spec))) {
1504 LOGE("InitDhCommonAsyKeySpec failed.");
1505 HcfFree(spec);
1506 return false;
1507 }
1508 spec->base.base.specType = HCF_PUBLIC_KEY_SPEC;
1509
1510 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1511 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1512 if (!ret) {
1513 DestroyDhPubKeySpec(spec);
1514 return false;
1515 }
1516 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1517 return true;
1518 }
1519
GetDhPriKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1520 static bool GetDhPriKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1521 {
1522 HcfDhPriKeyParamsSpec *spec = reinterpret_cast<HcfDhPriKeyParamsSpec *>(
1523 HcfMalloc(sizeof(HcfDhPriKeyParamsSpec), 0));
1524 if (spec == nullptr) {
1525 LOGE("malloc failed!");
1526 return false;
1527 }
1528
1529 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1530 if (commSpecValue == nullptr) {
1531 LOGE("Get comm spec napi value failed.");
1532 HcfFree(spec);
1533 return false;
1534 }
1535 if (!InitDhCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDhCommParamsSpec *>(spec))) {
1536 LOGE("InitDhCommonAsyKeySpec failed.");
1537 HcfFree(spec);
1538 return false;
1539 }
1540 spec->base.base.specType = HCF_PRIVATE_KEY_SPEC;
1541
1542 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "sk");
1543 bool ret = GetBigIntFromNapiValue(env, pk, &spec->sk);
1544 if (!ret) {
1545 DestroyDhPriKeySpec(spec);
1546 return false;
1547 }
1548 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1549 return true;
1550 }
1551
GetDhKeyPairAsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1552 static bool GetDhKeyPairAsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1553 {
1554 HcfDhKeyPairParamsSpec *spec = reinterpret_cast<HcfDhKeyPairParamsSpec *>(
1555 HcfMalloc(sizeof(HcfDhKeyPairParamsSpec), 0));
1556 if (spec == nullptr) {
1557 LOGE("malloc failed!");
1558 return false;
1559 }
1560
1561 napi_value commSpecValue = GetCommSpecNapiValue(env, arg);
1562 if (commSpecValue == nullptr) {
1563 LOGE("Get comm spec napi value failed.");
1564 HcfFree(spec);
1565 return false;
1566 }
1567 if (!InitDhCommonAsyKeySpec(env, commSpecValue, reinterpret_cast<HcfDhCommParamsSpec *>(spec))) {
1568 LOGE("InitDhCommonAsyKeySpec failed!");
1569 HcfFree(spec);
1570 return false;
1571 }
1572 spec->base.base.specType = HCF_KEY_PAIR_SPEC;
1573
1574 napi_value pk = GetDetailAsyKeySpecValue(env, arg, "pk");
1575 bool ret = GetBigIntFromNapiValue(env, pk, &spec->pk);
1576 if (!ret) {
1577 FreeDhCommParamsSpec(reinterpret_cast<HcfDhCommParamsSpec *>(spec));
1578 HcfFree(spec);
1579 return false;
1580 }
1581 napi_value sk = GetDetailAsyKeySpecValue(env, arg, "sk");
1582 ret = GetBigIntFromNapiValue(env, sk, &spec->sk);
1583 if (!ret) {
1584 FreeDhCommParamsSpec(reinterpret_cast<HcfDhCommParamsSpec *>(spec));
1585 HcfFree(spec->pk.data);
1586 HcfFree(spec);
1587 return false;
1588 }
1589 *asyKeySpec = reinterpret_cast<HcfAsyKeyParamsSpec *>(spec);
1590 return true;
1591 }
1592
GetDh25519AsyKeySpec(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1593 static bool GetDh25519AsyKeySpec(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1594 {
1595 napi_value data = nullptr;
1596 napi_valuetype valueType = napi_undefined;
1597
1598 napi_status status = napi_get_named_property(env, arg, TAG_SPEC_TYPE.c_str(), &data);
1599 napi_typeof(env, data, &valueType);
1600 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1601 LOGE("failed to get valid algo name!");
1602 return false;
1603 }
1604 HcfAsyKeySpecType asyKeySpecType;
1605 status = napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&asyKeySpecType));
1606 if (status != napi_ok) {
1607 LOGE("failed to get valid asyKeySpecType!");
1608 return false;
1609 }
1610 if (asyKeySpecType == HCF_PRIVATE_KEY_SPEC) {
1611 return GetDhPriKeySpec(env, arg, asyKeySpec);
1612 } else if (asyKeySpecType == HCF_PUBLIC_KEY_SPEC) {
1613 return GetDhPubKeySpec(env, arg, asyKeySpec);
1614 } else if (asyKeySpecType == HCF_KEY_PAIR_SPEC) {
1615 return GetDhKeyPairAsyKeySpec(env, arg, asyKeySpec);
1616 } else if (asyKeySpecType == HCF_COMMON_PARAMS_SPEC) {
1617 return GetDhCommonAsyKeySpec(env, arg, asyKeySpec);
1618 } else {
1619 LOGE("keySpec not support!");
1620 return false;
1621 }
1622 }
1623
GetAsyKeySpecFromNapiValue(napi_env env,napi_value arg,HcfAsyKeyParamsSpec ** asyKeySpec)1624 bool GetAsyKeySpecFromNapiValue(napi_env env, napi_value arg, HcfAsyKeyParamsSpec **asyKeySpec)
1625 {
1626 napi_value data = nullptr;
1627
1628 if ((env == nullptr) || (arg == nullptr) || (asyKeySpec == nullptr)) {
1629 LOGE("Invalid params!");
1630 return false;
1631 }
1632
1633 napi_valuetype valueType = napi_undefined;
1634
1635 napi_status status = napi_get_named_property(env, arg, CRYPTO_TAG_ALG_NAME.c_str(), &data);
1636 napi_typeof(env, data, &valueType);
1637 if ((status != napi_ok) || (data == nullptr) || (valueType == napi_undefined)) {
1638 LOGE("failed to get valid algName!");
1639 return false;
1640 }
1641 string algName;
1642 if (!GetStringFromJSParams(env, data, algName)) {
1643 LOGE("GetStringFromJSParams failed!");
1644 return false;
1645 }
1646 if (algName.compare(DSA_ASY_KEY_SPEC) == 0) {
1647 return GetDsaAsyKeySpec(env, arg, asyKeySpec);
1648 } else if (algName.compare(ECC_ASY_KEY_SPEC) == 0 || algName.compare(SM2_ASY_KEY_SPEC) == 0) {
1649 return GetEccAsyKeySpec(env, arg, asyKeySpec, algName);
1650 } else if (algName.compare(RSA_ASY_KEY_SPEC) == 0) {
1651 return GetRsaAsyKeySpec(env, arg, asyKeySpec);
1652 } else if (algName.compare(ED25519_ASY_KEY_SPEC) == 0 || algName.compare(X25519_ASY_KEY_SPEC) == 0) {
1653 return GetAlg25519AsyKeySpec(env, arg, asyKeySpec, algName);
1654 } else if (algName.compare(DH_ASY_KEY_SPEC) == 0) {
1655 return GetDh25519AsyKeySpec(env, arg, asyKeySpec);
1656 } else {
1657 LOGE("AlgName not support! [AlgName]: %s", algName.c_str());
1658 return false;
1659 }
1660 }
1661
ConvertBlobToNapiValue(napi_env env,HcfBlob * blob)1662 napi_value ConvertBlobToNapiValue(napi_env env, HcfBlob *blob)
1663 {
1664 if (blob == nullptr || blob->data == nullptr || blob->len == 0) {
1665 LOGD("Invalid blob!");
1666 return NapiGetNull(env);
1667 }
1668 uint8_t *buffer = reinterpret_cast<uint8_t *>(HcfMalloc(blob->len, 0));
1669 if (buffer == nullptr) {
1670 LOGE("malloc uint8 array buffer failed!");
1671 return NapiGetNull(env);
1672 }
1673
1674 if (memcpy_s(buffer, blob->len, blob->data, blob->len) != EOK) {
1675 LOGE("memcpy_s data to buffer failed!");
1676 HcfFree(buffer);
1677 return NapiGetNull(env);
1678 }
1679
1680 napi_value outBuffer = nullptr;
1681 napi_status status = napi_create_external_arraybuffer(
1682 env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer);
1683 if (status != napi_ok) {
1684 LOGE("create uint8 array buffer failed!");
1685 (void)memset_s(buffer, blob->len, 0, blob->len);
1686 HcfFree(buffer);
1687 return NapiGetNull(env);
1688 }
1689 buffer = nullptr;
1690
1691 napi_value outData = nullptr;
1692 napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData);
1693 napi_value dataBlob = nullptr;
1694 napi_create_object(env, &dataBlob);
1695 napi_set_named_property(env, dataBlob, CRYPTO_TAG_DATA.c_str(), outData);
1696
1697 return dataBlob;
1698 }
1699
ConvertDataBlobToNapiValue(napi_env env,HcfBlob * blob,napi_value * napiValue)1700 HcfResult ConvertDataBlobToNapiValue(napi_env env, HcfBlob *blob, napi_value *napiValue)
1701 {
1702 if (blob->data == nullptr || blob->len == 0) { // inner api, allow empty data
1703 *napiValue = NapiGetNull(env);
1704 return HCF_SUCCESS;
1705 }
1706
1707 uint8_t *buffer = reinterpret_cast<uint8_t *>(HcfMalloc(blob->len, 0));
1708 if (buffer == nullptr) {
1709 LOGE("malloc uint8 array buffer failed!");
1710 return HCF_ERR_MALLOC;
1711 }
1712 (void)memcpy_s(buffer, blob->len, blob->data, blob->len);
1713
1714 napi_value outBuffer = nullptr;
1715 napi_status status = napi_create_external_arraybuffer(
1716 env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer);
1717 if (status != napi_ok) {
1718 LOGE("create napi uint8 array buffer failed!");
1719 HcfFree(buffer);
1720 return HCF_ERR_NAPI;
1721 }
1722
1723 napi_value outData = nullptr;
1724 napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData);
1725 napi_value dataBlob = nullptr;
1726 napi_create_object(env, &dataBlob);
1727 napi_set_named_property(env, dataBlob, CRYPTO_TAG_DATA.c_str(), outData);
1728 *napiValue = dataBlob;
1729 return HCF_SUCCESS;
1730 }
1731
ConvertObjectBlobToNapiValue(napi_env env,HcfBlob * blob)1732 napi_value ConvertObjectBlobToNapiValue(napi_env env, HcfBlob *blob)
1733 {
1734 if (blob == nullptr || blob->data == nullptr || blob->len == 0) {
1735 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!"));
1736 LOGE("Invalid blob!");
1737 return NapiGetNull(env);
1738 }
1739 uint8_t *buffer = reinterpret_cast<uint8_t *>(HcfMalloc(blob->len, 0));
1740 if (buffer == nullptr) {
1741 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc uint8 array buffer failed!"));
1742 LOGE("malloc uint8 array buffer failed!");
1743 return NapiGetNull(env);
1744 }
1745
1746 if (memcpy_s(buffer, blob->len, blob->data, blob->len) != EOK) {
1747 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "memcpy_s data to buffer failed!"));
1748 LOGE("memcpy_s data to buffer failed!");
1749 HcfFree(buffer);
1750 return NapiGetNull(env);
1751 }
1752
1753 napi_value outBuffer = nullptr;
1754 napi_status status = napi_create_external_arraybuffer(
1755 env, buffer, blob->len, [](napi_env env, void *data, void *hint) { HcfFree(data); }, nullptr, &outBuffer);
1756 if (status != napi_ok) {
1757 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create uint8 array buffer failed!"));
1758 LOGE("create uint8 array buffer failed!");
1759 HcfFree(buffer);
1760 return NapiGetNull(env);
1761 }
1762 buffer = nullptr;
1763
1764 napi_value outData = nullptr;
1765 napi_create_typedarray(env, napi_uint8_array, blob->len, outBuffer, 0, &outData);
1766 return outData;
1767 }
1768
ConvertBigIntToNapiValue(napi_env env,HcfBigInteger * blob)1769 napi_value ConvertBigIntToNapiValue(napi_env env, HcfBigInteger *blob)
1770 {
1771 if (blob == nullptr || blob->data == nullptr || blob->len == 0) {
1772 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Invalid blob!"));
1773 LOGE("Invalid blob!");
1774 return NapiGetNull(env);
1775 }
1776 size_t wordsCount = (blob->len / sizeof(uint64_t)) + ((blob->len % sizeof(uint64_t)) == 0 ? 0 : 1);
1777 uint64_t *words = reinterpret_cast<uint64_t *>(HcfMalloc(wordsCount * sizeof(uint64_t), 0));
1778 if (words == nullptr) {
1779 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc uint8 array buffer failed!"));
1780 LOGE("malloc uint8 array buffer failed!");
1781 return NapiGetNull(env);
1782 }
1783
1784 size_t index = 0;
1785 for (size_t i = 0; index < wordsCount; i += sizeof(uint64_t), index++) {
1786 uint64_t tmp = 0;
1787 for (size_t j = 0; j < sizeof(uint64_t); j++) {
1788 if (i + j < blob->len) {
1789 tmp += ((uint64_t)blob->data[i + j] << (sizeof(uint64_t) * j));
1790 }
1791 }
1792 words[index] = tmp;
1793 }
1794 napi_value bigInt = nullptr;
1795 napi_status status = napi_create_bigint_words(env, 0, wordsCount, words, &bigInt);
1796 if (status != napi_ok) {
1797 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create bigint failed!"));
1798 LOGE("create bigint failed!");
1799 (void)memset_s(words, wordsCount * sizeof(uint64_t), 0, wordsCount * sizeof(uint64_t));
1800 HcfFree(words);
1801 return NapiGetNull(env);
1802 }
1803 if (bigInt == nullptr) {
1804 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "bigInt is null!"));
1805 LOGE("bigInt is null!");
1806 }
1807 (void)memset_s(words, wordsCount * sizeof(uint64_t), 0, wordsCount * sizeof(uint64_t));
1808 HcfFree(words);
1809 words = nullptr;
1810 return bigInt;
1811 }
1812
GetStringFromJSParams(napi_env env,napi_value arg,string & returnStr)1813 bool GetStringFromJSParams(napi_env env, napi_value arg, string &returnStr)
1814 {
1815 napi_valuetype valueType;
1816 napi_typeof(env, arg, &valueType);
1817 if (valueType != napi_string) {
1818 LOGE("wrong argument type. expect string type.");
1819 return false;
1820 }
1821
1822 size_t length = 0;
1823 if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
1824 LOGE("can not get string length");
1825 return false;
1826 }
1827 returnStr.reserve(length + 1);
1828 returnStr.resize(length);
1829 if (napi_get_value_string_utf8(env, arg, returnStr.data(), (length + 1), &length) != napi_ok) {
1830 LOGE("can not get string value");
1831 return false;
1832 }
1833 return true;
1834 }
1835
GetInt32FromJSParams(napi_env env,napi_value arg,int32_t & returnInt)1836 bool GetInt32FromJSParams(napi_env env, napi_value arg, int32_t &returnInt)
1837 {
1838 napi_valuetype valueType;
1839 napi_typeof(env, arg, &valueType);
1840 if (valueType != napi_number) {
1841 LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
1842 return false;
1843 }
1844
1845 if (napi_get_value_int32(env, arg, &returnInt) != napi_ok) {
1846 LOGE("can not get int value");
1847 return false;
1848 }
1849 return true;
1850 }
1851
GetUint32FromJSParams(napi_env env,napi_value arg,uint32_t & returnInt)1852 bool GetUint32FromJSParams(napi_env env, napi_value arg, uint32_t &returnInt)
1853 {
1854 napi_valuetype valueType;
1855 napi_typeof(env, arg, &valueType);
1856 if (valueType != napi_number) {
1857 LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
1858 return false;
1859 }
1860
1861 if (napi_get_value_uint32(env, arg, &returnInt) != napi_ok) {
1862 LOGE("can not get int value");
1863 return false;
1864 }
1865 return true;
1866 }
1867
GetUint64FromJSParams(napi_env env,napi_value arg,uint64_t & returnInt)1868 bool GetUint64FromJSParams(napi_env env, napi_value arg, uint64_t &returnInt)
1869 {
1870 napi_valuetype valueType;
1871 napi_typeof(env, arg, &valueType);
1872 if (valueType != napi_number) {
1873 LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
1874 return false;
1875 }
1876 int64_t int64Value = 0;
1877 if (napi_get_value_int64(env, arg, &int64Value) != napi_ok) {
1878 LOGE("can not get int value");
1879 return false;
1880 }
1881 if (int64Value < 0) {
1882 LOGE("int64Value is less than 0");
1883 return false;
1884 }
1885 returnInt = static_cast<uint64_t>(int64Value);
1886 return true;
1887 }
1888
GetCallbackFromJSParams(napi_env env,napi_value arg,napi_ref * returnCb)1889 bool GetCallbackFromJSParams(napi_env env, napi_value arg, napi_ref *returnCb)
1890 {
1891 napi_valuetype valueType = napi_undefined;
1892 napi_typeof(env, arg, &valueType);
1893 if (valueType != napi_function) {
1894 LOGE("wrong argument type. expect callback type. [Type]: %d", valueType);
1895 return false;
1896 }
1897
1898 napi_create_reference(env, arg, 1, returnCb);
1899 return true;
1900 }
1901
GetJsErrValueByErrCode(HcfResult errCode)1902 static uint32_t GetJsErrValueByErrCode(HcfResult errCode)
1903 {
1904 switch (errCode) {
1905 case HCF_INVALID_PARAMS:
1906 return JS_ERR_INVALID_PARAMS;
1907 case HCF_NOT_SUPPORT:
1908 return JS_ERR_NOT_SUPPORT;
1909 case HCF_ERR_MALLOC:
1910 return JS_ERR_OUT_OF_MEMORY;
1911 case HCF_ERR_NAPI:
1912 return JS_ERR_RUNTIME_ERROR;
1913 case HCF_ERR_CRYPTO_OPERATION:
1914 return JS_ERR_CRYPTO_OPERATION;
1915 default:
1916 return JS_ERR_DEFAULT_ERR;
1917 }
1918 }
1919
GenerateBusinessError(napi_env env,HcfResult errCode,const char * errMsg)1920 napi_value GenerateBusinessError(napi_env env, HcfResult errCode, const char *errMsg)
1921 {
1922 napi_value businessError = nullptr;
1923
1924 napi_value code = nullptr;
1925 napi_create_uint32(env, GetJsErrValueByErrCode(errCode), &code);
1926
1927 napi_value msg = nullptr;
1928 napi_create_string_utf8(env, errMsg, NAPI_AUTO_LENGTH, &msg);
1929
1930 napi_create_error(env, nullptr, msg, &businessError);
1931 napi_set_named_property(env, businessError, CRYPTO_TAG_ERR_CODE.c_str(), code);
1932
1933 return businessError;
1934 }
1935
CheckArgsCount(napi_env env,size_t argc,size_t expectedCount,bool isSync)1936 bool CheckArgsCount(napi_env env, size_t argc, size_t expectedCount, bool isSync)
1937 {
1938 if (isSync) {
1939 if (argc != expectedCount) {
1940 LOGE("invalid params count!");
1941 return false;
1942 }
1943 } else {
1944 if ((argc != expectedCount) && (argc != (expectedCount - ARGS_SIZE_ONE))) {
1945 LOGE("invalid params count!");
1946 return false;
1947 }
1948 }
1949 return true;
1950 }
1951
isCallback(napi_env env,napi_value argv,size_t argc,size_t expectedArgc)1952 bool isCallback(napi_env env, napi_value argv, size_t argc, size_t expectedArgc)
1953 {
1954 if (argc == expectedArgc - 1) {
1955 return false;
1956 }
1957 napi_valuetype valueType = napi_undefined;
1958 napi_typeof(env, argv, &valueType);
1959 if (valueType == napi_undefined || valueType == napi_null) {
1960 return false;
1961 }
1962 return true;
1963 }
1964
GetResourceName(napi_env env,const char * name)1965 napi_value GetResourceName(napi_env env, const char *name)
1966 {
1967 napi_value resourceName = nullptr;
1968 napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resourceName);
1969 return resourceName;
1970 }
1971
BuildSetNamedProperty(napi_env env,HcfBigInteger * number,const char * name,napi_value * instance)1972 bool BuildSetNamedProperty(napi_env env, HcfBigInteger *number, const char *name, napi_value *instance)
1973 {
1974 napi_value value = ConvertBigIntToNapiValue(env, number);
1975 napi_status status = napi_set_named_property(env, *instance, name, value);
1976 if (status != napi_ok) {
1977 LOGE("create value failed!");
1978 return false;
1979 }
1980 return true;
1981 }
1982 } // namespace CryptoFramework
1983 } // namespace OHOS
1984