1 /*
2  * Copyright (C) 2022-2023 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_key_pair.h"
17 
18 #include "securec.h"
19 #include "log.h"
20 #include "napi_crypto_framework_defines.h"
21 #include "napi_pri_key.h"
22 #include "napi_pub_key.h"
23 #include "napi_utils.h"
24 
25 namespace OHOS {
26 namespace CryptoFramework {
27 thread_local napi_ref NapiKeyPair::classRef_ = nullptr;
28 
NapiKeyPair(HcfKeyPair * keyPair)29 NapiKeyPair::NapiKeyPair(HcfKeyPair *keyPair)
30 {
31     this->keyPair_ = keyPair;
32 }
33 
~NapiKeyPair()34 NapiKeyPair::~NapiKeyPair()
35 {
36     HcfObjDestroy(this->keyPair_);
37     this->keyPair_ = nullptr;
38 }
39 
KeyPairConstructor(napi_env env,napi_callback_info info)40 napi_value NapiKeyPair::KeyPairConstructor(napi_env env, napi_callback_info info)
41 {
42     napi_value thisVar = nullptr;
43     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
44     return thisVar;
45 }
46 
WrapPubKey(napi_env env,napi_value instance,HcfPubKey * key)47 static bool WrapPubKey(napi_env env, napi_value instance, HcfPubKey *key)
48 {
49     NapiPubKey *napiPubKey = new (std::nothrow) NapiPubKey(key);
50     if (napiPubKey == nullptr) {
51         LOGE("new napi pub key failed");
52         return false;
53     }
54     napi_value pubKey = napiPubKey->ConvertToJsPubKey(env);
55     napi_status status =  napi_wrap(
56         env, pubKey, napiPubKey,
57         [](napi_env env, void *data, void *hint) {
58             NapiPubKey *napiPubKey = static_cast<NapiPubKey *>(data);
59             HcfObjDestroy(napiPubKey->GetPubKey());
60             delete napiPubKey;
61             return;
62         }, nullptr, nullptr);
63     if (status != napi_ok) {
64         LOGE("failed to wrap napiPubKey obj!");
65         delete napiPubKey;
66         return false;
67     }
68     napi_set_named_property(env, instance, CRYPTO_TAG_PUB_KEY.c_str(), pubKey);
69     return true;
70 }
71 
WrapPriKey(napi_env env,napi_value instance,HcfPriKey * key)72 static bool WrapPriKey(napi_env env, napi_value instance, HcfPriKey *key)
73 {
74     NapiPriKey *napiPriKey = new (std::nothrow) NapiPriKey(key);
75     if (napiPriKey == nullptr) {
76         LOGE("new napi pri key failed");
77         return false;
78     }
79     napi_value priKey = napiPriKey->ConvertToJsPriKey(env);
80     napi_status status =  napi_wrap(
81         env, priKey, napiPriKey,
82         [](napi_env env, void *data, void *hint) {
83             NapiPriKey *napiPriKey = static_cast<NapiPriKey *>(data);
84             HcfObjDestroy(napiPriKey->GetPriKey());
85             delete napiPriKey;
86             return;
87         }, nullptr, nullptr);
88     if (status != napi_ok) {
89         LOGE("failed to wrap napiPriKey obj!");
90         delete napiPriKey;
91         return false;
92     }
93     napi_set_named_property(env, instance, CRYPTO_TAG_PRI_KEY.c_str(), priKey);
94     return true;
95 }
96 
ConvertToJsKeyPair(napi_env env)97 napi_value NapiKeyPair::ConvertToJsKeyPair(napi_env env)
98 {
99     napi_value instance;
100     napi_value constructor = nullptr;
101     napi_get_reference_value(env, classRef_, &constructor);
102     napi_new_instance(env, constructor, 0, nullptr, &instance);
103 
104     if (this->keyPair_->pubKey != nullptr) {
105         if (WrapPubKey(env, instance, this->keyPair_->pubKey) == false) {
106             return nullptr;
107         }
108         this->keyPair_->pubKey = nullptr;
109     }
110 
111     if (this->keyPair_->priKey != nullptr) {
112         if (WrapPriKey(env, instance, this->keyPair_->priKey) == false) {
113             return nullptr;
114         }
115         this->keyPair_->priKey = nullptr;
116     }
117     return instance;
118 }
119 
DefineKeyPairJSClass(napi_env env)120 void NapiKeyPair::DefineKeyPairJSClass(napi_env env)
121 {
122     napi_property_descriptor classDesc[] = {};
123     napi_value constructor = nullptr;
124     napi_define_class(env, "KeyPair", NAPI_AUTO_LENGTH, KeyPairConstructor, nullptr,
125         sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
126     napi_create_reference(env, constructor, 1, &classRef_);
127 }
128 } // CryptoFramework
129 } // OHOS
130