1 /*
2 * Copyright (c) 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_common.h"
17
18 #include "securec.h"
19
20 #include "cf_log.h"
21 #include "cf_memory.h"
22 #include "cf_param.h"
23 #include "cf_result.h"
24 #include "napi_cert_defines.h"
25 #include "napi_cert_utils.h"
26
27 namespace OHOS {
28 namespace CertFramework {
GetCallback(napi_env env,napi_value object,napi_ref * callBack)29 static bool GetCallback(napi_env env, napi_value object, napi_ref *callBack)
30 {
31 napi_valuetype valueType = napi_undefined;
32 napi_status status = napi_typeof(env, object, &valueType);
33 if (status != napi_ok) {
34 CF_LOG_E("Failed to get object type");
35 return false;
36 }
37
38 if (valueType != napi_function) {
39 CF_LOG_E("wrong argument type. expect callback type. [Type]: %{public}d", valueType);
40 return false;
41 }
42
43 napi_create_reference(env, object, 1, callBack);
44 return true;
45 }
46
GetCallbackAndPromise(napi_env env,AsyncCtx async,napi_value arg)47 bool GetCallbackAndPromise(napi_env env, AsyncCtx async, napi_value arg)
48 {
49 if (async->asyncType == ASYNC_TYPE_CALLBACK) {
50 if (!GetCallback(env, arg, &async->callback)) {
51 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get callback type error"));
52 CF_LOG_E("get callback failed!");
53 return false;
54 }
55 } else {
56 napi_create_promise(env, &async->deferred, &async->promise);
57 }
58 return true;
59 }
60
ReturnCallbackResult(napi_env env,AsyncCtx async,napi_value result)61 static void ReturnCallbackResult(napi_env env, AsyncCtx async, napi_value result)
62 {
63 napi_value businessError = nullptr;
64 if (async->errCode != CF_SUCCESS) {
65 businessError = CertGenerateBusinessError(env, async->errCode, async->errMsg);
66 }
67 napi_value params[CALLBACK_NUM] = { businessError, result };
68
69 napi_value func = nullptr;
70 napi_get_reference_value(env, async->callback, &func);
71
72 napi_value recv = nullptr;
73 napi_value callFuncRet = nullptr;
74 napi_get_undefined(env, &recv);
75 napi_call_function(env, recv, func, CALLBACK_NUM, params, &callFuncRet);
76 }
77
ReturnPromiseResult(napi_env env,AsyncCtx async,napi_value result)78 static void ReturnPromiseResult(napi_env env, AsyncCtx async, napi_value result)
79 {
80 if (async->errCode == CF_SUCCESS) {
81 napi_resolve_deferred(env, async->deferred, result);
82 } else {
83 napi_reject_deferred(env, async->deferred,
84 CertGenerateBusinessError(env, async->errCode, async->errMsg));
85 }
86 }
87
ReturnJSResult(napi_env env,AsyncCtx async,napi_value result)88 void ReturnJSResult(napi_env env, AsyncCtx async, napi_value result)
89 {
90 if (async == nullptr) {
91 return;
92 }
93 if (async->asyncType == ASYNC_TYPE_CALLBACK) {
94 ReturnCallbackResult(env, async, result);
95 } else {
96 ReturnPromiseResult(env, async, result);
97 }
98 }
99
GetResourceName(napi_env env,const char * name)100 napi_value GetResourceName(napi_env env, const char *name)
101 {
102 napi_value resourceName = nullptr;
103 napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resourceName);
104 return resourceName;
105 }
106
GetBlobArrayFromParamSet(const CfParamSet * paramSet,CfArray * outArray)107 int32_t GetBlobArrayFromParamSet(const CfParamSet *paramSet, CfArray *outArray)
108 {
109 if (paramSet->paramsCnt <= 1) {
110 CF_LOG_E("invalid paramSet for blobArray");
111 return CF_INVALID_PARAMS;
112 }
113
114 uint32_t oidsCnt = paramSet->paramsCnt - 1;
115 CfBlob *blobs = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob) * oidsCnt, 0));
116 if (blobs == nullptr) {
117 CF_LOG_E("Failed to malloc blobs");
118 return CF_ERR_MALLOC;
119 }
120
121 for (uint32_t i = 0; i < oidsCnt; ++i) {
122 if (paramSet->params[i + 1].tag != CF_TAG_RESULT_BYTES) { /* index of blob is 1-based */
123 CF_LOG_E("params[%{public}u] is invalid", i);
124 FreeCfBlobArray(blobs, i);
125 blobs = nullptr;
126 return CF_INVALID_PARAMS;
127 }
128
129 uint32_t size = paramSet->params[i + 1].blob.size;
130 blobs[i].data = static_cast<uint8_t *>(CfMalloc(size, 0));
131 if (blobs[i].data == nullptr) {
132 CF_LOG_E("Failed to malloc blob[%{public}u].data", i);
133 FreeCfBlobArray(blobs, i);
134 blobs = nullptr;
135 return CF_ERR_MALLOC;
136 }
137 (void)memcpy_s(blobs[i].data, size, paramSet->params[i + 1].blob.data, size);
138 blobs[i].size = size;
139 }
140
141 outArray->data = blobs;
142 outArray->count = oidsCnt;
143 outArray->format = CF_FORMAT_DER;
144 return CF_SUCCESS;
145 }
146
ConvertBlobArrayToNapiValue(napi_env env,const CfParamSet * paramSet)147 napi_value ConvertBlobArrayToNapiValue(napi_env env, const CfParamSet *paramSet)
148 {
149 CfArray outArray = { nullptr, CF_FORMAT_DER, 0 };
150 int32_t ret = GetBlobArrayFromParamSet(paramSet, &outArray);
151 if (ret != CF_SUCCESS) {
152 CF_LOG_E("Failed to get out array from paramSet");
153 return nullptr;
154 }
155
156 napi_value returnValue = ConvertArrayToNapiValue(env, &outArray);
157 CfArrayDataClearAndFree(&outArray);
158 return returnValue;
159 }
160
FreeAsyncContext(napi_env env,AsyncCtx & async)161 void FreeAsyncContext(napi_env env, AsyncCtx &async)
162 {
163 if (async == nullptr) {
164 return;
165 }
166 if (async->asyncWork != nullptr) {
167 napi_delete_async_work(env, async->asyncWork);
168 async->asyncWork = nullptr;
169 }
170
171 if (async->callback != nullptr) {
172 napi_delete_reference(env, async->callback);
173 async->callback = nullptr;
174 }
175 if (async->paramRef != nullptr) {
176 napi_delete_reference(env, async->paramRef);
177 async->paramRef = nullptr;
178 }
179 CfFree(async);
180 async = nullptr;
181 }
182
183 } // namespace CertFramework
184 } // namespace OHOS