• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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]: %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->asyncType == ASYNC_TYPE_CALLBACK) {
91         ReturnCallbackResult(env, async, result);
92     } else {
93         ReturnPromiseResult(env, async, result);
94     }
95 }
96 
GetResourceName(napi_env env,const char * name)97 napi_value GetResourceName(napi_env env, const char *name)
98 {
99     napi_value resourceName = nullptr;
100     napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resourceName);
101     return resourceName;
102 }
103 
CheckOutParamType(const CfParamSet * paramSet,CfTagType targetType)104 int32_t CheckOutParamType(const CfParamSet *paramSet, CfTagType targetType)
105 {
106     CfParam *resultTypeParam = nullptr;
107     int32_t ret = CfGetParam(paramSet, CF_TAG_RESULT_TYPE, &resultTypeParam);
108     if (ret != CF_SUCCESS) {
109         CF_LOG_E("ext: Failed to get CF_TAG_RESULT_TYPE");
110         return ret;
111     }
112 
113     if (resultTypeParam->int32Param != targetType) {
114         CF_LOG_E("ext: result type is not target type");
115         return CF_NOT_SUPPORT;
116     }
117     return CF_SUCCESS;
118 }
119 
GetBlobArrayFromParamSet(const CfParamSet * paramSet,CfArray * outArray)120 int32_t GetBlobArrayFromParamSet(const CfParamSet *paramSet, CfArray *outArray)
121 {
122     if (paramSet->paramsCnt <= 1) {
123         CF_LOG_E("invalid paramSet for blobArray");
124         return CF_INVALID_PARAMS;
125     }
126 
127     uint32_t oidsCnt = paramSet->paramsCnt - 1;
128     CfBlob *blobs = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob) * oidsCnt));
129     if (blobs == nullptr) {
130         CF_LOG_E("Failed to malloc blobs");
131         return CF_ERR_MALLOC;
132     }
133 
134     for (uint32_t i = 0; i < oidsCnt; ++i) {
135         if (paramSet->params[i + 1].tag != CF_TAG_RESULT_BYTES) { /* index of blob is 1-based */
136             CF_LOG_E("params[%u] is invalid", i);
137             FreeCfBlobArray(blobs, i);
138             return CF_INVALID_PARAMS;
139         }
140 
141         uint32_t size = paramSet->params[i + 1].blob.size;
142         blobs[i].data = static_cast<uint8_t *>(CfMalloc(size));
143         if (blobs[i].data == nullptr) {
144             CF_LOG_E("Failed to malloc blob[%u].data", i);
145             FreeCfBlobArray(blobs, i);
146             return CF_ERR_MALLOC;
147         }
148         (void)memcpy_s(blobs[i].data, size, paramSet->params[i + 1].blob.data, size);
149         blobs[i].size = size;
150     }
151 
152     outArray->data = blobs;
153     outArray->count = oidsCnt;
154     outArray->format = CF_FORMAT_DER;
155     return CF_SUCCESS;
156 }
157 
ConvertBlobArrayToNapiValue(napi_env env,const CfParamSet * paramSet)158 napi_value ConvertBlobArrayToNapiValue(napi_env env,  const CfParamSet *paramSet)
159 {
160     CfArray outArray = { nullptr, CF_FORMAT_DER, 0 };
161     int32_t ret = GetBlobArrayFromParamSet(paramSet, &outArray);
162     if (ret != CF_SUCCESS) {
163         CF_LOG_E("Failed to get out array from paramSet");
164         return nullptr;
165     }
166 
167     napi_value returnValue = ConvertArrayToNapiValue(env, &outArray);
168     CfArrayDataClearAndFree(&outArray);
169     return returnValue;
170 }
171 
FreeAsyncContext(napi_env env,AsyncCtx & async)172 void FreeAsyncContext(napi_env env, AsyncCtx &async)
173 {
174     if (async == nullptr) {
175         return;
176     }
177     if (async->asyncWork != nullptr) {
178         napi_delete_async_work(env, async->asyncWork);
179         async->asyncWork = nullptr;
180     }
181 
182     if (async->callback != nullptr) {
183         napi_delete_reference(env, async->callback);
184         async->callback = nullptr;
185     }
186     CfFree(async);
187     async = nullptr;
188 }
189 
190 } // namespace CertFramework
191 } // namespace OHOS