• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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