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