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