1 /*
2 * Copyright (c) 2025 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 "cf_memory.h"
17 #include "cf_param.h"
18 #include "securec.h"
19
20 #include "cj_cf_object.h"
21
FfiCertCjCfObjectNewInstance(const CfEncodingBlob * blob,CjCfObject * returnObj)22 int32_t FfiCertCjCfObjectNewInstance(const CfEncodingBlob *blob, CjCfObject *returnObj)
23 {
24 auto cfObj = static_cast<CfObject *>(malloc(sizeof(CfObject)));
25 if (cfObj == nullptr) {
26 return CF_ERR_MALLOC;
27 }
28 const auto errCode = CfResult(CfCreate(CF_OBJ_TYPE_EXTENSION, blob, &cfObj));
29 if (errCode != CF_SUCCESS) {
30 free(cfObj);
31 return errCode;
32 }
33 returnObj->cfObj = cfObj;
34 return CF_SUCCESS;
35 }
36
FfiCertCjCfObjectDeleteInstance(CjCfObject self)37 void FfiCertCjCfObjectDeleteInstance(CjCfObject self)
38 {
39 self.cfObj->destroy(&self.cfObj);
40 }
41
FfiCertCjCfObjectGetEncoded(const CjCfObject self,CfBlob * out)42 CfResult FfiCertCjCfObjectGetEncoded(const CjCfObject self, CfBlob *out)
43 {
44 CfParamSet *inParamSet = nullptr;
45 int32_t ret;
46 if ((ret = CfInitParamSet(&inParamSet)) != CF_SUCCESS) {
47 return CfResult(ret);
48 }
49
50 const CfParam param[] = {
51 CfParam{.tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_EXT_ITEM},
52 CfParam{.tag = CF_TAG_PARAM0_INT32, .int32Param = CF_ITEM_ENCODED},
53 };
54 if ((ret = CfAddParams(inParamSet, param, sizeof(param) / sizeof(CfParam))) != CF_SUCCESS) {
55 CfFreeParamSet(&inParamSet);
56 return CfResult(ret);
57 }
58
59 CfParamSet *outParamSet = nullptr;
60 if ((ret = self.cfObj->get(self.cfObj, inParamSet, &outParamSet)) != CF_SUCCESS) {
61 CfFreeParamSet(&inParamSet);
62 return CfResult(ret);
63 }
64
65 CfParam *resultParam = nullptr;
66 ret = CfGetParam(outParamSet, CF_TAG_RESULT_BYTES, &resultParam);
67 if (ret != CF_SUCCESS) {
68 CfFreeParamSet(&inParamSet);
69 CfFreeParamSet(&outParamSet);
70 return CfResult(ret);
71 }
72 uint32_t blobSize = resultParam->blob.size;
73 uint8_t* buffer = static_cast<uint8_t*>(CfMalloc(blobSize, 0));
74 if (buffer == nullptr) {
75 ret = CF_ERR_MALLOC;
76 CfFreeParamSet(&inParamSet);
77 CfFreeParamSet(&outParamSet);
78 return CfResult(ret);
79 }
80 if ((ret = memcpy_s(buffer, blobSize, resultParam->blob.data, blobSize)) != CF_SUCCESS) {
81 CfFree(buffer);
82 CfFreeParamSet(&inParamSet);
83 CfFreeParamSet(&outParamSet);
84 return CfResult(ret);
85 }
86 CfFreeParamSet(&inParamSet);
87 CfFreeParamSet(&outParamSet);
88 *out = CfBlob { .size = blobSize, .data = buffer };
89 return CfResult(ret);
90 }
91
FfiCertCjCfObjectGetOidList(const CjCfObject self,int32_t valueType,CfArray * out)92 CfResult FfiCertCjCfObjectGetOidList(const CjCfObject self, int32_t valueType, CfArray *out)
93 {
94 CfParamSet *inParamSet = nullptr;
95 int32_t ret;
96 if ((ret = CfInitParamSet(&inParamSet)) != CF_SUCCESS) {
97 return CfResult(ret);
98 }
99
100 const CfParam param[] = {
101 CfParam{.tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_EXT_OIDS},
102 CfParam{.tag = CF_TAG_PARAM0_INT32, .int32Param = valueType},
103 };
104 if ((ret = CfAddParams(inParamSet, param, sizeof(param) / sizeof(CfParam))) != CF_SUCCESS) {
105 CfFreeParamSet(&inParamSet);
106 return CfResult(ret);
107 }
108
109 CfParamSet *outParamSet = nullptr;
110 if ((ret = self.cfObj->get(self.cfObj, inParamSet, &outParamSet)) != CF_SUCCESS) {
111 CfFreeParamSet(&inParamSet);
112 return CfResult(ret);
113 }
114
115 if (outParamSet->paramsCnt <= 1) {
116 ret = CF_INVALID_PARAMS;
117 } else {
118 out->count = outParamSet->paramsCnt - 1;
119 out->format = CF_FORMAT_DER;
120 out->data = static_cast<CfBlob *>(malloc(sizeof(CfBlob) * out->count));
121 if (out->data == nullptr) {
122 CfFreeParamSet(&inParamSet);
123 CfFreeParamSet(&outParamSet);
124 return CF_ERR_MALLOC;
125 }
126 for (uint32_t i = 0; i < out->count; ++i) {
127 out->data[i] = outParamSet->params[i + 1].blob;
128 }
129 ret = CF_SUCCESS;
130 }
131
132 CfFreeParamSet(&inParamSet);
133 CfFreeParamSet(&outParamSet);
134 return CfResult(ret);
135 }
136
FfiCertCjCfObjectGetEntry(const CjCfObject self,int32_t valueType,CfBlob * oid,CfBlob * out)137 CfResult FfiCertCjCfObjectGetEntry(const CjCfObject self, int32_t valueType, CfBlob *oid, CfBlob *out)
138 {
139 CfParamSet *inParamSet = nullptr;
140 int32_t ret;
141 if ((ret = CfInitParamSet(&inParamSet)) != CF_SUCCESS) {
142 return CfResult(ret);
143 }
144
145 const CfParam param[] = {
146 CfParam{.tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_EXT_ENTRY},
147 CfParam{.tag = CF_TAG_PARAM0_INT32, .int32Param = valueType},
148 CfParam{.tag = CF_TAG_PARAM1_BUFFER, .blob = *oid},
149 };
150 if ((ret = CfAddParams(inParamSet, param, sizeof(param) / sizeof(CfParam))) != CF_SUCCESS) {
151 CfFreeParamSet(&inParamSet);
152 return CfResult(ret);
153 }
154
155 CfParamSet *outParamSet = nullptr;
156 if ((ret = self.cfObj->get(self.cfObj, inParamSet, &outParamSet)) != CF_SUCCESS) {
157 CfFreeParamSet(&inParamSet);
158 return CfResult(ret);
159 }
160 CfParam *resultParam = nullptr;
161 ret = CfGetParam(outParamSet, CF_TAG_RESULT_BYTES, &resultParam);
162 if (ret != CF_SUCCESS) {
163 CfFreeParamSet(&inParamSet);
164 CfFreeParamSet(&outParamSet);
165 return CfResult(ret);
166 }
167 uint32_t blobSize = resultParam->blob.size;
168 uint8_t* buffer = static_cast<uint8_t*>(CfMalloc(blobSize, 0));
169 if (buffer == nullptr) {
170 ret = CF_ERR_MALLOC;
171 CfFreeParamSet(&inParamSet);
172 CfFreeParamSet(&outParamSet);
173 return CfResult(ret);
174 }
175 if ((ret = memcpy_s(buffer, blobSize, resultParam->blob.data, blobSize)) != CF_SUCCESS) {
176 CfFree(buffer);
177 CfFreeParamSet(&inParamSet);
178 CfFreeParamSet(&outParamSet);
179 return CfResult(ret);
180 }
181 CfFreeParamSet(&inParamSet);
182 CfFreeParamSet(&outParamSet);
183 *out = CfBlob { .size = blobSize, .data = buffer };
184 return CfResult(ret);
185 }
186
FfiCertCjCfObjectCheckCA(const CjCfObject self,int32_t * out)187 CfResult FfiCertCjCfObjectCheckCA(const CjCfObject self, int32_t *out)
188 {
189 CfParamSet *inParamSet = nullptr;
190 int32_t ret;
191 if ((ret = CfInitParamSet(&inParamSet)) != CF_SUCCESS) {
192 return CfResult(ret);
193 }
194
195 const CfParam param[] = {
196 CfParam{.tag = CF_TAG_CHECK_TYPE, .int32Param = CF_CHECK_TYPE_EXT_CA},
197 };
198 if ((ret = CfAddParams(inParamSet, param, sizeof(param) / sizeof(CfParam))) != CF_SUCCESS) {
199 CfFreeParamSet(&inParamSet);
200 return CfResult(ret);
201 }
202
203 CfParamSet *outParamSet = nullptr;
204 if ((ret = self.cfObj->check(self.cfObj, inParamSet, &outParamSet)) != CF_SUCCESS) {
205 CfFreeParamSet(&inParamSet);
206 return CfResult(ret);
207 }
208 CfParam *resultParam = nullptr;
209 ret = CfGetParam(outParamSet, CF_TAG_RESULT_INT, &resultParam);
210 if (ret == CF_SUCCESS) {
211 *out = resultParam->int32Param;
212 }
213 CfFreeParamSet(&inParamSet);
214 CfFreeParamSet(&outParamSet);
215 return CfResult(ret);
216 }
217
FfiCertCjCfObjectHasUnsupportedCriticalExtension(const CjCfObject self,bool * out)218 CfResult FfiCertCjCfObjectHasUnsupportedCriticalExtension(const CjCfObject self, bool *out)
219 {
220 CfParamSet *inParamSet = nullptr;
221 int32_t ret;
222 if ((ret = CfInitParamSet(&inParamSet)) != CF_SUCCESS) {
223 return CfResult(ret);
224 }
225
226 const CfParam param[] = {
227 CfParam{.tag = CF_TAG_CHECK_TYPE, .int32Param = CF_CHECK_TYPE_EXT_HAS_UN_SUPPORT},
228 };
229 if ((ret = CfAddParams(inParamSet, param, sizeof(param) / sizeof(CfParam))) != CF_SUCCESS) {
230 CfFreeParamSet(&inParamSet);
231 return CfResult(ret);
232 }
233
234 CfParamSet *outParamSet = nullptr;
235 if ((ret = self.cfObj->check(self.cfObj, inParamSet, &outParamSet)) != CF_SUCCESS) {
236 CfFreeParamSet(&inParamSet);
237 return CfResult(ret);
238 }
239 CfParam *resultParam = nullptr;
240 ret = CfGetParam(outParamSet, CF_TAG_RESULT_BOOL, &resultParam);
241 if (ret == CF_SUCCESS) {
242 *out = resultParam->boolParam;
243 }
244 CfFreeParamSet(&inParamSet);
245 CfFreeParamSet(&outParamSet);
246 return CfResult(ret);
247 }
248