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 "cert_crl_collection.h"
17
18 #include <securec.h>
19
20 #include "cf_blob.h"
21 #include "config.h"
22 #include "cf_result.h"
23 #include "cf_log.h"
24 #include "cf_memory.h"
25 #include "cf_result.h"
26 #include "utils.h"
27 #include "x509_certificate.h"
28 #include "x509_crl.h"
29 #include "cert_crl_common.h"
30
31 typedef struct {
32 HcfCertCrlCollection base;
33 HcfX509CertificateArray certs;
34 HcfX509CrlArray crls;
35 } CertCrlCollectionImpl;
36
GetCertCrlCollectionClass(void)37 static const char *GetCertCrlCollectionClass(void)
38 {
39 return "HcfCertCrlCollection";
40 }
41
DestroyCertCrlCollection(CfObjectBase * self)42 static void DestroyCertCrlCollection(CfObjectBase *self)
43 {
44 if (self == NULL) {
45 LOGE("Invalid input parameter.");
46 return;
47 }
48 if (!IsClassMatch(self, GetCertCrlCollectionClass())) {
49 LOGE("Class is not match.");
50 return;
51 }
52
53 CertCrlCollectionImpl *collectionImpl = (CertCrlCollectionImpl *)self;
54 FreeCertArrayData(&collectionImpl->certs);
55 FreeCrlArrayData(&collectionImpl->crls);
56 CfFree(collectionImpl);
57 }
58
GetMatchCerts(const HcfX509CertificateArray * inCerts,const HcfX509CertMatchParams * matchParams,HcfX509CertificateArray * outCerts)59 static CfResult GetMatchCerts(const HcfX509CertificateArray *inCerts, const HcfX509CertMatchParams *matchParams,
60 HcfX509CertificateArray *outCerts)
61 {
62 HcfX509CertificateArray tmpArr = { NULL, 0 };
63 tmpArr.count = inCerts->count;
64 /* inCerts is inner object, the size has been checked in function HcfCertCrlCollectionCreate */
65 tmpArr.data = (HcfX509Certificate **)HcfMalloc(inCerts->count * sizeof(HcfX509Certificate *), 0);
66 if (tmpArr.data == NULL) {
67 LOGE("Failed to allocate memory!");
68 return CF_ERR_MALLOC;
69 }
70 uint32_t outInd = 0;
71 for (uint32_t i = 0; i < inCerts->count; ++i) {
72 HcfX509Certificate *cert = inCerts->data[i];
73 bool out = false;
74 CfResult res = cert->match(cert, matchParams, &out);
75 if (res != CF_SUCCESS) {
76 LOGE("match failed");
77 FreeCertArrayData(&tmpArr);
78 return res;
79 }
80 if (!out) {
81 continue;
82 }
83 res = CloneCertificateObj(cert, &(tmpArr.data[outInd]));
84 if (res != CF_SUCCESS) {
85 LOGE("cert clone failed");
86 FreeCertArrayData(&tmpArr);
87 return res;
88 }
89 outInd++;
90 }
91 if (outInd == 0) {
92 LOGI("no any match!");
93 FreeCertArrayData(&tmpArr);
94 return CF_SUCCESS;
95 }
96 outCerts->data = (HcfX509Certificate **)HcfMalloc(outInd * sizeof(HcfX509Certificate *), 0);
97 if (outCerts->data == NULL) {
98 LOGE("Failed to allocate memory!");
99 FreeCertArrayData(&tmpArr);
100 return CF_ERR_MALLOC;
101 }
102 outCerts->count = outInd;
103 for (uint32_t i = 0; i < outInd; ++i) {
104 outCerts->data[i] = tmpArr.data[i];
105 }
106 CfFree(tmpArr.data);
107 return CF_SUCCESS;
108 }
109
GetMatchCRLs(const HcfX509CrlArray * inCrls,const HcfX509CrlMatchParams * matchParams,HcfX509CrlArray * outCrls)110 static CfResult GetMatchCRLs(
111 const HcfX509CrlArray *inCrls, const HcfX509CrlMatchParams *matchParams, HcfX509CrlArray *outCrls)
112 {
113 HcfX509CrlArray tmpArr = { NULL, 0 };
114 tmpArr.count = inCrls->count;
115 /* inCrls is inner object, the size has been checked in function HcfCertCrlCollectionCreate */
116 tmpArr.data = (HcfX509Crl **)HcfMalloc(inCrls->count * sizeof(HcfX509Crl *), 0);
117 if (tmpArr.data == NULL) {
118 LOGE("Failed to allocate memory!");
119 return CF_ERR_MALLOC;
120 }
121 uint32_t outInd = 0;
122 for (uint32_t i = 0; i < inCrls->count; ++i) {
123 HcfX509Crl *crl = inCrls->data[i];
124 bool out = false;
125 CfResult res = crl->match(crl, matchParams, &out);
126 if (res != CF_SUCCESS) {
127 LOGE("match failed");
128 FreeCrlArrayData(&tmpArr);
129 return res;
130 }
131 if (!out) {
132 continue;
133 }
134 res = CloneCrlObj(crl, &tmpArr.data[outInd]);
135 if (res != CF_SUCCESS) {
136 LOGE("crl clone failed");
137 FreeCrlArrayData(&tmpArr);
138 return res;
139 }
140 outInd++;
141 }
142 if (outInd == 0) {
143 LOGI("no any match!");
144 FreeCrlArrayData(&tmpArr);
145 return CF_SUCCESS;
146 }
147 outCrls->data = (HcfX509Crl **)HcfMalloc(outInd * sizeof(HcfX509Crl *), 0);
148 if (outCrls->data == NULL) {
149 LOGE("Failed to allocate memory!");
150 FreeCrlArrayData(&tmpArr);
151 return CF_ERR_MALLOC;
152 }
153 outCrls->count = outInd;
154 for (uint32_t i = 0; i < outInd; ++i) {
155 outCrls->data[i] = tmpArr.data[i];
156 }
157 CfFree(tmpArr.data);
158 return CF_SUCCESS;
159 }
160
SelectCerts(HcfCertCrlCollection * self,const HcfX509CertMatchParams * matchParams,HcfX509CertificateArray * retCerts)161 static CfResult SelectCerts(
162 HcfCertCrlCollection *self, const HcfX509CertMatchParams *matchParams, HcfX509CertificateArray *retCerts)
163 {
164 if (self == NULL || matchParams == NULL || retCerts == NULL) {
165 LOGE("Invalid input parameter.");
166 return CF_INVALID_PARAMS;
167 }
168 if (!IsClassMatch((CfObjectBase *)self, GetCertCrlCollectionClass())) {
169 LOGE("Class is not match.");
170 return CF_INVALID_PARAMS;
171 }
172 CertCrlCollectionImpl *collectionImpl = (CertCrlCollectionImpl *)self;
173 if (collectionImpl->certs.count == 0) {
174 LOGE("no any certs for select.");
175 return CF_INVALID_PARAMS;
176 }
177 CfResult res = GetMatchCerts(&collectionImpl->certs, matchParams, retCerts);
178 if (res != CF_SUCCESS) {
179 LOGE("match failed");
180 return res;
181 }
182 return CF_SUCCESS;
183 }
184
SelectCRLs(HcfCertCrlCollection * self,const HcfX509CrlMatchParams * matchParams,HcfX509CrlArray * retCrls)185 static CfResult SelectCRLs(
186 HcfCertCrlCollection *self, const HcfX509CrlMatchParams *matchParams, HcfX509CrlArray *retCrls)
187 {
188 if (self == NULL || matchParams == NULL || retCrls == NULL) {
189 LOGE("Invalid input parameter.");
190 return CF_INVALID_PARAMS;
191 }
192 if (!IsClassMatch((CfObjectBase *)self, GetCertCrlCollectionClass())) {
193 LOGE("Class is not match.");
194 return CF_INVALID_PARAMS;
195 }
196 CertCrlCollectionImpl *collectionImpl = (CertCrlCollectionImpl *)self;
197 if (collectionImpl->crls.count == 0) {
198 LOGE("no any crls for select.");
199 return CF_INVALID_PARAMS;
200 }
201 CfResult res = GetMatchCRLs(&collectionImpl->crls, matchParams, retCrls);
202 if (res != CF_SUCCESS) {
203 LOGE("match failed");
204 return res;
205 }
206 return CF_SUCCESS;
207 }
208
GetCRLs(HcfCertCrlCollection * self,HcfX509CrlArray ** retCrls)209 static CfResult GetCRLs(HcfCertCrlCollection *self, HcfX509CrlArray **retCrls)
210 {
211 if (self == NULL || retCrls == NULL) {
212 LOGE("Invalid input parameter.");
213 return CF_INVALID_PARAMS;
214 }
215 if (!IsClassMatch((CfObjectBase *)self, GetCertCrlCollectionClass())) {
216 LOGE("Class is not match.");
217 return CF_INVALID_PARAMS;
218 }
219 CertCrlCollectionImpl *collectionImpl = (CertCrlCollectionImpl *)self;
220 *retCrls = &(collectionImpl->crls);
221
222 return CF_SUCCESS;
223 }
224
CloneCertArray(const HcfX509CertificateArray * inCerts,HcfX509CertificateArray * certs)225 static CfResult CloneCertArray(const HcfX509CertificateArray *inCerts, HcfX509CertificateArray *certs)
226 {
227 if (inCerts == NULL || inCerts->count == 0) {
228 LOGI("inCerts is null, or count is 0.");
229 return CF_SUCCESS;
230 }
231
232 if (inCerts->count > MAX_LEN_OF_CERT_CRL_ARR || certs == NULL) {
233 LOGE("array count is over limit.");
234 return CF_INVALID_PARAMS;
235 }
236
237 certs->data = (HcfX509Certificate **)HcfMalloc(inCerts->count * sizeof(HcfX509Certificate *), 0);
238 if (certs->data == NULL) {
239 LOGE("Failed to allocate memory!");
240 return CF_ERR_MALLOC;
241 }
242 certs->count = inCerts->count;
243 CfResult res = CF_SUCCESS;
244 for (uint32_t i = 0; i < inCerts->count; ++i) {
245 res = CloneCertificateObj(inCerts->data[i], &(certs->data[i]));
246 if (res != CF_SUCCESS) {
247 break;
248 }
249 }
250 if (res != CF_SUCCESS) {
251 FreeCertArrayData(certs);
252 LOGE("Failed to clone cert!");
253 return res;
254 }
255 return CF_SUCCESS;
256 }
257
CloneCrlArray(const HcfX509CrlArray * inCrls,HcfX509CrlArray * crls)258 static CfResult CloneCrlArray(const HcfX509CrlArray *inCrls, HcfX509CrlArray *crls)
259 {
260 if (inCrls == NULL || inCrls->count == 0) {
261 LOGI("inCrls is null, or count is 0.");
262 return CF_SUCCESS;
263 }
264
265 if (inCrls->count > MAX_LEN_OF_CERT_CRL_ARR || crls == NULL) {
266 LOGE("array count is over limit.");
267 return CF_INVALID_PARAMS;
268 }
269
270 crls->data = (HcfX509Crl **)HcfMalloc(inCrls->count * sizeof(HcfX509Crl *), 0);
271 if (crls->data == NULL) {
272 LOGE("Failed to allocate memory!");
273 return CF_ERR_MALLOC;
274 }
275
276 crls->count = inCrls->count;
277 CfResult res = CF_SUCCESS;
278 for (uint32_t i = 0; i < inCrls->count; ++i) {
279 res = CloneCrlObj(inCrls->data[i], &(crls->data[i]));
280 if (res != CF_SUCCESS) {
281 break;
282 }
283 }
284 if (res != CF_SUCCESS) {
285 FreeCrlArrayData(crls);
286 LOGE("Failed to clone crl!");
287 return res;
288 }
289 return CF_SUCCESS;
290 }
291
HcfCertCrlCollectionCreate(const HcfX509CertificateArray * inCerts,const HcfX509CrlArray * inCrls,HcfCertCrlCollection ** out)292 CfResult HcfCertCrlCollectionCreate(
293 const HcfX509CertificateArray *inCerts, const HcfX509CrlArray *inCrls, HcfCertCrlCollection **out)
294 {
295 CF_LOG_I("enter");
296 if (out == NULL) {
297 LOGE("input params invalid!");
298 return CF_INVALID_PARAMS;
299 }
300
301 CertCrlCollectionImpl *ret = (CertCrlCollectionImpl *)HcfMalloc(sizeof(CertCrlCollectionImpl), 0);
302 if (ret == NULL) {
303 LOGE("Failed to allocate ret memory!");
304 return CF_ERR_MALLOC;
305 }
306
307 ret->base.base.destroy = DestroyCertCrlCollection;
308 ret->base.base.getClass = GetCertCrlCollectionClass;
309 ret->base.selectCerts = SelectCerts;
310 ret->base.selectCRLs = SelectCRLs;
311 ret->base.getCRLs = GetCRLs;
312
313 CfResult res = CloneCertArray(inCerts, &(ret->certs));
314 if (res != CF_SUCCESS) {
315 LOGE("Failed to clone cert array!");
316 CfFree(ret);
317 return res;
318 }
319 res = CloneCrlArray(inCrls, &(ret->crls));
320 if (res != CF_SUCCESS) {
321 LOGE("Failed to clone crl array!");
322 FreeCertArrayData(&ret->certs);
323 CfFree(ret);
324 return res;
325 }
326
327 *out = (HcfCertCrlCollection *)ret;
328 return CF_SUCCESS;
329 }
330