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_x509_certificate.h"
21
FfiCertCjX509CertificateNewInstance(const CfEncodingBlob * blob,CjX509Certificate * returnObj)22 int32_t FfiCertCjX509CertificateNewInstance(const CfEncodingBlob *blob, CjX509Certificate *returnObj)
23 {
24 auto cert = static_cast<HcfX509Certificate *>(malloc(sizeof(HcfX509Certificate)));
25 if (cert == nullptr) {
26 return CF_ERR_MALLOC;
27 }
28 CfResult errCode = HcfX509CertificateCreate(blob, &cert);
29 if (errCode != CF_SUCCESS) {
30 free(cert);
31 return errCode;
32 }
33 auto cfObj = static_cast<CfObject *>(malloc(sizeof(CfObject)));
34 if (cfObj == nullptr) {
35 free(cert);
36 return CF_ERR_MALLOC;
37 }
38 errCode = CfResult(CfCreate(CF_OBJ_TYPE_CERT, blob, &cfObj));
39 if (errCode != CF_SUCCESS) {
40 CfObjDestroy(cert);
41 free(cfObj);
42 return errCode;
43 }
44 returnObj->cert = cert;
45 returnObj->cfObj = cfObj;
46 return CF_SUCCESS;
47 }
48
FfiCertCjX509CertificateDeleteInstance(CjX509Certificate self)49 void FfiCertCjX509CertificateDeleteInstance(CjX509Certificate self)
50 {
51 CfObjDestroy(self.cert);
52 self.cfObj->destroy(&self.cfObj);
53 }
54
FfiCertCjX509CertificateFromHcfCert(HcfX509Certificate * hcfCert,CjX509Certificate * returnObj)55 CfResult FfiCertCjX509CertificateFromHcfCert(HcfX509Certificate *hcfCert, CjX509Certificate *returnObj)
56 {
57 CfEncodingBlob blob = {};
58 CfResult errCode = hcfCert->base.getEncoded(&hcfCert->base, &blob);
59 if (errCode != CF_SUCCESS) {
60 return errCode;
61 }
62 auto cert = static_cast<HcfX509Certificate *>(malloc(sizeof(HcfX509Certificate)));
63 if (cert == nullptr) {
64 free(blob.data);
65 return CF_ERR_MALLOC;
66 }
67 errCode = HcfX509CertificateCreate(&blob, &cert);
68 if (errCode != CF_SUCCESS) {
69 free(blob.data);
70 free(cert);
71 return errCode;
72 }
73 auto cfObj = static_cast<CfObject *>(malloc(sizeof(CfObject)));
74 if (cfObj == nullptr) {
75 free(blob.data);
76 free(cert);
77 return CF_ERR_MALLOC;
78 }
79
80 errCode = CfResult(CfCreate(CF_OBJ_TYPE_CERT, &blob, &cfObj));
81 if (errCode != CF_SUCCESS) {
82 free(blob.data);
83 CfObjDestroy(cert);
84 free(cfObj);
85 return errCode;
86 }
87 returnObj->cert = cert;
88 returnObj->cfObj = cfObj;
89 free(blob.data);
90 return errCode;
91 }
92
FfiCertCjX509CertificateVerify(const CjX509Certificate self,HcfPubKey * pubKey)93 CfResult FfiCertCjX509CertificateVerify(const CjX509Certificate self, HcfPubKey *pubKey)
94 {
95 return self.cert->base.verify(&self.cert->base, pubKey);
96 }
97
FfiCertCjX509CertificateGetEncoded(const CjX509Certificate self,CfEncodingBlob * encodedByte)98 CfResult FfiCertCjX509CertificateGetEncoded(const CjX509Certificate self, CfEncodingBlob *encodedByte)
99 {
100 return self.cert->base.getEncoded(&self.cert->base, encodedByte);
101 }
102
FfiCertCjX509CertificateGetPublicKey(const CjX509Certificate self,HcfPubKey ** retPubKey)103 CfResult FfiCertCjX509CertificateGetPublicKey(const CjX509Certificate self, HcfPubKey **retPubKey)
104 {
105 HcfPubKey *pubKey = nullptr;
106 const CfResult errCode = self.cert->base.getPublicKey(&self.cert->base, (void **) &pubKey);
107 if (errCode == CF_SUCCESS) {
108 *retPubKey = pubKey;
109 }
110 return errCode;
111 }
112
FfiCertCjX509CertificateCheckValidityWithDate(const CjX509Certificate self,const char * date)113 CfResult FfiCertCjX509CertificateCheckValidityWithDate(const CjX509Certificate self, const char *date)
114 {
115 return self.cert->checkValidityWithDate(self.cert, date);
116 }
117
FfiCertCjX509CertificateGetVersion(const CjX509Certificate self)118 long FfiCertCjX509CertificateGetVersion(const CjX509Certificate self)
119 {
120 return self.cert->getVersion(self.cert);
121 }
122
FfiCertCjX509CertificateGetSerialNumber(const CjX509Certificate self,CfBlob * out)123 CfResult FfiCertCjX509CertificateGetSerialNumber(const CjX509Certificate self, CfBlob *out)
124 {
125 return self.cert->getSerialNumber(self.cert, out);
126 }
127
FfiCertCjX509CertificateGetIssuerName(const CjX509Certificate self,CfBlob * out)128 CfResult FfiCertCjX509CertificateGetIssuerName(const CjX509Certificate self, CfBlob *out)
129 {
130 return self.cert->getIssuerName(self.cert, out);
131 }
132
FfiCertCjX509CertificateGetSubjectName(const CjX509Certificate self,CfBlob * out)133 CfResult FfiCertCjX509CertificateGetSubjectName(const CjX509Certificate self, CfBlob *out)
134 {
135 return self.cert->getSubjectName(self.cert, out);
136 }
137
FfiCertCjX509CertificateGetNotBeforeTime(const CjX509Certificate self,CfBlob * outDate)138 CfResult FfiCertCjX509CertificateGetNotBeforeTime(const CjX509Certificate self, CfBlob *outDate)
139 {
140 return self.cert->getNotBeforeTime(self.cert, outDate);
141 }
142
FfiCertCjX509CertificateGetNotAfterTime(const CjX509Certificate self,CfBlob * outDate)143 CfResult FfiCertCjX509CertificateGetNotAfterTime(const CjX509Certificate self, CfBlob *outDate)
144 {
145 return self.cert->getNotAfterTime(self.cert, outDate);
146 }
147
FfiCertCjX509CertificateGetSignature(const CjX509Certificate self,CfBlob * sigOut)148 CfResult FfiCertCjX509CertificateGetSignature(const CjX509Certificate self, CfBlob *sigOut)
149 {
150 return self.cert->getSignature(self.cert, sigOut);
151 }
152
FfiCertCjX509CertificateGetSignatureAlgName(const CjX509Certificate self,CfBlob * outName)153 CfResult FfiCertCjX509CertificateGetSignatureAlgName(const CjX509Certificate self, CfBlob *outName)
154 {
155 return self.cert->getSignatureAlgName(self.cert, outName);
156 }
157
FfiCertCjX509CertificateGetSignatureAlgOid(const CjX509Certificate self,CfBlob * out)158 CfResult FfiCertCjX509CertificateGetSignatureAlgOid(const CjX509Certificate self, CfBlob *out)
159 {
160 return self.cert->getSignatureAlgOid(self.cert, out);
161 }
162
FfiCertCjX509CertificateGetSignatureAlgParams(const CjX509Certificate self,CfBlob * sigAlgParamsOut)163 CfResult FfiCertCjX509CertificateGetSignatureAlgParams(const CjX509Certificate self, CfBlob *sigAlgParamsOut)
164 {
165 return self.cert->getSignatureAlgParams(self.cert, sigAlgParamsOut);
166 }
167
FfiCertCjX509CertificateGetKeyUsage(const CjX509Certificate self,CfBlob * boolArr)168 CfResult FfiCertCjX509CertificateGetKeyUsage(const CjX509Certificate self, CfBlob *boolArr)
169 {
170 return self.cert->getKeyUsage(self.cert, boolArr);
171 }
172
FfiCertCjX509CertificateGetExtKeyUsage(const CjX509Certificate self,CfArray * keyUsageOut)173 CfResult FfiCertCjX509CertificateGetExtKeyUsage(const CjX509Certificate self, CfArray *keyUsageOut)
174 {
175 return self.cert->getExtKeyUsage(self.cert, keyUsageOut);
176 }
177
FfiCertCjX509CertificateGetBasicConstraints(const CjX509Certificate self)178 int32_t FfiCertCjX509CertificateGetBasicConstraints(const CjX509Certificate self)
179 {
180 return self.cert->getBasicConstraints(self.cert);
181 }
182
FfiCertCjX509CertificateGetSubjectAltNames(const CjX509Certificate self,CfArray * outName)183 CfResult FfiCertCjX509CertificateGetSubjectAltNames(const CjX509Certificate self, CfArray *outName)
184 {
185 return self.cert->getSubjectAltNames(self.cert, outName);
186 }
187
FfiCertCjX509CertificateGetIssuerAltNames(const CjX509Certificate self,CfArray * outName)188 CfResult FfiCertCjX509CertificateGetIssuerAltNames(const CjX509Certificate self, CfArray *outName)
189 {
190 return self.cert->getIssuerAltNames(self.cert, outName);
191 }
192
FfiCertCjX509CertificateMatch(const CjX509Certificate self,const CjX509CertMatchParams * matchParams,bool * out)193 CfResult FfiCertCjX509CertificateMatch(const CjX509Certificate self, const CjX509CertMatchParams *matchParams,
194 bool *out)
195 {
196 SubAltNameArray *subjectAlternativeNamesPtr = nullptr;
197 SubAltNameArray subjectAlternativeNames;
198 if (matchParams->subjectAlternativeNameCnt != 0) {
199 subjectAlternativeNames = SubAltNameArray{
200 .data = matchParams->subjectAlternativeNames,
201 .count = matchParams->subjectAlternativeNameCnt
202 };
203 subjectAlternativeNamesPtr = &subjectAlternativeNames;
204 }
205
206 HcfCertificate *certPtr = nullptr;
207 if (matchParams->x509Cert) {
208 certPtr = &matchParams->x509Cert->base;
209 }
210
211 const auto params = HcfX509CertMatchParams{
212 certPtr,
213 matchParams->validDate,
214 matchParams->issuer,
215 matchParams->keyUsage,
216 matchParams->serialNumber,
217 matchParams->subject,
218 matchParams->publicKey,
219 matchParams->publicKeyAlgID,
220 subjectAlternativeNamesPtr,
221 matchParams->matchAllSubjectAltNames,
222 matchParams->authorityKeyIdentifier,
223 matchParams->minPathLenConstraint,
224 matchParams->extendedKeyUsage,
225 matchParams->nameConstraints,
226 matchParams->certPolicy,
227 matchParams->privateKeyValid,
228 matchParams->subjectKeyIdentifier,
229 };
230
231 return self.cert->match(self.cert, ¶ms, out);
232 }
233
FfiCertCjX509CertificateGetCRLDistributionPointsURI(const CjX509Certificate self,CfArray * outURI)234 CfResult FfiCertCjX509CertificateGetCRLDistributionPointsURI(const CjX509Certificate self, CfArray *outURI)
235 {
236 return self.cert->getCRLDistributionPointsURI(self.cert, outURI);
237 }
238
FfiCertCjX509CertificateToString(const CjX509Certificate self,CfBlob * out)239 CfResult FfiCertCjX509CertificateToString(const CjX509Certificate self, CfBlob *out)
240 {
241 return self.cert->toString(self.cert, out);
242 }
243
FfiCertCjX509CertificateHashCode(const CjX509Certificate self,CfBlob * out)244 CfResult FfiCertCjX509CertificateHashCode(const CjX509Certificate self, CfBlob *out)
245 {
246 return self.cert->hashCode(self.cert, out);
247 }
248
FfiCertCjX509CertificateGetExtensionsObject(const CjX509Certificate self,CfBlob * out)249 CfResult FfiCertCjX509CertificateGetExtensionsObject(const CjX509Certificate self, CfBlob *out)
250 {
251 return self.cert->getExtensionsObject(self.cert, out);
252 }
253
FfiCertCjX509CertificateGetSubjectNameEx(const CjX509Certificate self,const CfEncodinigType encodingType,CfBlob * out)254 CfResult FfiCertCjX509CertificateGetSubjectNameEx(const CjX509Certificate self, const CfEncodinigType encodingType,
255 CfBlob *out)
256 {
257 return self.cert->getSubjectNameEx(self.cert, encodingType, out);
258 }
259
FfiCertCjX509CertificateGetItem(const CjX509Certificate self,const int32_t itemType,CfBlob * out)260 CfResult FfiCertCjX509CertificateGetItem(const CjX509Certificate self, const int32_t itemType, CfBlob *out)
261 {
262 CfParamSet *inParamSet = nullptr;
263 int32_t ret;
264 if ((ret = CfInitParamSet(&inParamSet)) != CF_SUCCESS) {
265 return CfResult(ret);
266 }
267
268 const CfParam param[] = {
269 CfParam{.tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_CERT_ITEM},
270 CfParam{.tag = CF_TAG_PARAM0_INT32, .int32Param = itemType}
271 };
272 if ((ret = CfAddParams(inParamSet, param, sizeof(param) / sizeof(CfParam))) != CF_SUCCESS) {
273 CfFreeParamSet(&inParamSet);
274 return CfResult(ret);
275 }
276
277 CfParamSet *outParamSet = nullptr;
278 if ((ret = self.cfObj->get(self.cfObj, inParamSet, &outParamSet)) != CF_SUCCESS) {
279 CfFreeParamSet(&inParamSet);
280 return CfResult(ret);
281 }
282
283 CfParam *resultParam = nullptr;
284 ret = CfGetParam(outParamSet, CF_TAG_RESULT_BYTES, &resultParam);
285 if (ret != CF_SUCCESS) {
286 CfFreeParamSet(&inParamSet);
287 CfFreeParamSet(&outParamSet);
288 return CfResult(ret);
289 }
290 uint32_t blobSize = resultParam->blob.size;
291 uint8_t* buffer = static_cast<uint8_t*>(CfMalloc(blobSize, 0));
292 if (buffer == nullptr) {
293 ret = CF_ERR_MALLOC;
294 CfFreeParamSet(&inParamSet);
295 CfFreeParamSet(&outParamSet);
296 return CfResult(ret);
297 }
298 if ((ret = memcpy_s(buffer, blobSize, resultParam->blob.data, blobSize)) != CF_SUCCESS) {
299 CfFree(buffer);
300 CfFreeParamSet(&inParamSet);
301 CfFreeParamSet(&outParamSet);
302 return CfResult(ret);
303 }
304 CfFreeParamSet(&inParamSet);
305 CfFreeParamSet(&outParamSet);
306 *out = CfBlob { .size = blobSize, .data = buffer };
307 return CfResult(ret);
308 }
309