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 "x509_certificate.h"
17 
18 #include <securec.h>
19 
20 #include "config.h"
21 #include "fwk_class.h"
22 #include "x509_certificate_openssl.h"
23 #include "cf_log.h"
24 #include "cf_memory.h"
25 #include "utils.h"
26 #include "x509_cert_match_parameters.h"
27 
28 typedef CfResult (*HcfX509CertificateSpiCreateFunc)(const CfEncodingBlob *, HcfX509CertificateSpi **);
29 
30 typedef struct {
31     HcfX509CertificateSpiCreateFunc createFunc;
32 } HcfX509CertificateFuncSet;
33 
34 typedef struct {
35     char *certType;
36     HcfX509CertificateFuncSet funcSet;
37 } HcfCCertFactoryAbility;
38 
GetX509CertificateClass(void)39 static const char *GetX509CertificateClass(void)
40 {
41     return HCF_X509_CERTIFICATE_CLASS;
42 }
43 
44 static const HcfCCertFactoryAbility X509_CERTIFICATE_ABILITY_SET[] = {
45     { "X509", { OpensslX509CertSpiCreate, } }
46 };
47 
FindAbility(const char * certType)48 static const HcfX509CertificateFuncSet *FindAbility(const char *certType)
49 {
50     if (certType == NULL) {
51         LOGE("CertType is null!");
52         return NULL;
53     }
54     for (uint32_t i = 0; i < sizeof(X509_CERTIFICATE_ABILITY_SET) / sizeof(HcfCCertFactoryAbility); i++) {
55         if (strcmp(X509_CERTIFICATE_ABILITY_SET[i].certType, certType) == 0) {
56             return &(X509_CERTIFICATE_ABILITY_SET[i].funcSet);
57         }
58     }
59     LOGE("Cert not support! [cert]: %s", certType);
60     return NULL;
61 }
62 
DestroyX509Certificate(CfObjectBase * self)63 static void DestroyX509Certificate(CfObjectBase *self)
64 {
65     if (self == NULL) {
66         LOGE("Invalid input parameter.");
67         return;
68     }
69     if (!CfIsClassMatch(self, GetX509CertificateClass())) {
70         LOGE("Class is not match.");
71         return;
72     }
73     HcfX509CertificateImpl *impl = (HcfX509CertificateImpl *)self;
74     CfObjDestroy(impl->spiObj);
75     CfFree(impl);
76 }
77 
Verify(HcfCertificate * self,void * key)78 static CfResult Verify(HcfCertificate *self, void *key)
79 {
80     if ((self == NULL) || (key == NULL)) {
81         LOGE("Invalid input parameter.");
82         return CF_INVALID_PARAMS;
83     }
84     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
85         LOGE("Class is not match.");
86         return CF_INVALID_PARAMS;
87     }
88     return ((HcfX509CertificateImpl *)self)->spiObj->engineVerify(
89         ((HcfX509CertificateImpl *)self)->spiObj, (HcfPubKey *)key);
90 }
91 
GetEncoded(HcfCertificate * self,CfEncodingBlob * encodedByte)92 static CfResult GetEncoded(HcfCertificate *self, CfEncodingBlob *encodedByte)
93 {
94     if ((self == NULL) || (encodedByte == NULL)) {
95         LOGE("Invalid input parameter.");
96         return CF_INVALID_PARAMS;
97     }
98     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
99         LOGE("Class is not match.");
100         return CF_INVALID_PARAMS;
101     }
102     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetEncoded(
103         ((HcfX509CertificateImpl *)self)->spiObj, encodedByte);
104 }
105 
GetPublicKey(HcfCertificate * self,void ** keyOut)106 static CfResult GetPublicKey(HcfCertificate *self, void **keyOut)
107 {
108     if ((self == NULL) || (keyOut == NULL)) {
109         LOGE("Invalid input parameter.");
110         return CF_INVALID_PARAMS;
111     }
112     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
113         LOGE("Class is not match.");
114         return CF_INVALID_PARAMS;
115     }
116     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetPublicKey(
117         ((HcfX509CertificateImpl *)self)->spiObj, (HcfPubKey **)keyOut);
118 }
119 
CheckValidityWithDate(HcfX509Certificate * self,const char * date)120 static CfResult CheckValidityWithDate(HcfX509Certificate *self, const char *date)
121 {
122     if ((self == NULL) || (date == NULL)) {
123         LOGE("Invalid input parameter.");
124         return CF_INVALID_PARAMS;
125     }
126     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
127         LOGE("Class is not match.");
128         return CF_INVALID_PARAMS;
129     }
130     return ((HcfX509CertificateImpl *)self)->spiObj->engineCheckValidityWithDate(
131         ((HcfX509CertificateImpl *)self)->spiObj, date);
132 }
133 
GetVersion(HcfX509Certificate * self)134 static long GetVersion(HcfX509Certificate *self)
135 {
136     if (self == NULL) {
137         LOGE("Invalid input parameter.");
138         return INVALID_VERSION;
139     }
140     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
141         LOGE("Class is not match.");
142         return INVALID_VERSION;
143     }
144     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetVersion(
145         ((HcfX509CertificateImpl *)self)->spiObj);
146 }
147 
GetSerialNumber(HcfX509Certificate * self,CfBlob * out)148 static CfResult GetSerialNumber(HcfX509Certificate *self, CfBlob *out)
149 {
150     if (self == NULL) {
151         LOGE("Invalid input parameter.");
152         return CF_INVALID_PARAMS;
153     }
154     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
155         LOGE("Class is not match.");
156         return CF_INVALID_PARAMS;
157     }
158     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSerialNumber(
159         ((HcfX509CertificateImpl *)self)->spiObj, out);
160 }
161 
GetIssuerName(HcfX509Certificate * self,CfBlob * out)162 static CfResult GetIssuerName(HcfX509Certificate *self, CfBlob *out)
163 {
164     if ((self == NULL) || (out == NULL)) {
165         LOGE("Invalid input parameter.");
166         return CF_INVALID_PARAMS;
167     }
168     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
169         LOGE("Class is not match.");
170         return CF_INVALID_PARAMS;
171     }
172     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetIssuerName(
173         ((HcfX509CertificateImpl *)self)->spiObj, out);
174 }
175 
GetSubjectName(HcfX509Certificate * self,CfBlob * out)176 static CfResult GetSubjectName(HcfX509Certificate *self, CfBlob *out)
177 {
178     if ((self == NULL) || (out == NULL)) {
179         LOGE("Invalid input parameter.");
180         return CF_INVALID_PARAMS;
181     }
182     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
183         LOGE("Class is not match.");
184         return CF_INVALID_PARAMS;
185     }
186     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSubjectName(
187         ((HcfX509CertificateImpl *)self)->spiObj, out);
188 }
189 
GetSubjectNameEx(HcfX509Certificate * self,CfEncodinigType encodingType,CfBlob * out)190 static CfResult GetSubjectNameEx(HcfX509Certificate *self, CfEncodinigType encodingType, CfBlob *out)
191 {
192     if ((self == NULL) || (out == NULL) || encodingType != CF_ENCODING_UTF8) {
193         LOGE("Invalid input parameter.");
194         return CF_INVALID_PARAMS;
195     }
196     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
197         LOGE("Class is not match.");
198         return CF_INVALID_PARAMS;
199     }
200     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSubjectNameEx(
201         ((HcfX509CertificateImpl *)self)->spiObj, encodingType, out);
202 }
203 
GetNotBeforeTime(HcfX509Certificate * self,CfBlob * outDate)204 static CfResult GetNotBeforeTime(HcfX509Certificate *self, CfBlob *outDate)
205 {
206     if ((self == NULL) || (outDate == NULL)) {
207         LOGE("Invalid input parameter.");
208         return CF_INVALID_PARAMS;
209     }
210     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
211         LOGE("Class is not match.");
212         return CF_INVALID_PARAMS;
213     }
214     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetNotBeforeTime(
215         ((HcfX509CertificateImpl *)self)->spiObj, outDate);
216 }
217 
GetNotAfterTime(HcfX509Certificate * self,CfBlob * outDate)218 static CfResult GetNotAfterTime(HcfX509Certificate *self, CfBlob *outDate)
219 {
220     if ((self == NULL) || (outDate == NULL)) {
221         LOGE("Invalid input parameter.");
222         return CF_INVALID_PARAMS;
223     }
224     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
225         LOGE("Class is not match.");
226         return CF_INVALID_PARAMS;
227     }
228     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetNotAfterTime(
229         ((HcfX509CertificateImpl *)self)->spiObj, outDate);
230 }
231 
GetSignature(HcfX509Certificate * self,CfBlob * sigOut)232 static CfResult GetSignature(HcfX509Certificate *self, CfBlob *sigOut)
233 {
234     if ((self == NULL) || (sigOut == NULL)) {
235         LOGE("Invalid input parameter.");
236         return CF_INVALID_PARAMS;
237     }
238     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
239         LOGE("Class is not match.");
240         return CF_INVALID_PARAMS;
241     }
242     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignature(
243         ((HcfX509CertificateImpl *)self)->spiObj, sigOut);
244 }
245 
GetSignatureAlgName(HcfX509Certificate * self,CfBlob * outName)246 static CfResult GetSignatureAlgName(HcfX509Certificate *self, CfBlob *outName)
247 {
248     if ((self == NULL) || (outName == NULL)) {
249         LOGE("Invalid input parameter.");
250         return CF_INVALID_PARAMS;
251     }
252     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
253         LOGE("Class is not match.");
254         return CF_INVALID_PARAMS;
255     }
256     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignatureAlgName(
257         ((HcfX509CertificateImpl *)self)->spiObj, outName);
258 }
259 
GetSignatureAlgOid(HcfX509Certificate * self,CfBlob * out)260 static CfResult GetSignatureAlgOid(HcfX509Certificate *self, CfBlob *out)
261 {
262     if ((self == NULL) || (out == NULL)) {
263         LOGE("Invalid input parameter.");
264         return CF_INVALID_PARAMS;
265     }
266     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
267         LOGE("Class is not match.");
268         return CF_INVALID_PARAMS;
269     }
270     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignatureAlgOid(
271         ((HcfX509CertificateImpl *)self)->spiObj, out);
272 }
273 
GetSignatureAlgParams(HcfX509Certificate * self,CfBlob * sigAlgParamsOut)274 static CfResult GetSignatureAlgParams(HcfX509Certificate *self, CfBlob *sigAlgParamsOut)
275 {
276     if ((self == NULL) || (sigAlgParamsOut == NULL)) {
277         LOGE("Invalid input parameter.");
278         return CF_INVALID_PARAMS;
279     }
280     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
281         LOGE("Class is not match.");
282         return CF_INVALID_PARAMS;
283     }
284     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignatureAlgParams(
285         ((HcfX509CertificateImpl *)self)->spiObj, sigAlgParamsOut);
286 }
287 
GetKeyUsage(HcfX509Certificate * self,CfBlob * boolArr)288 static CfResult GetKeyUsage(HcfX509Certificate *self, CfBlob *boolArr)
289 {
290     if ((self == NULL) || (boolArr == NULL)) {
291         LOGE("Invalid input parameter.");
292         return CF_INVALID_PARAMS;
293     }
294     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
295         LOGE("Class is not match.");
296         return CF_INVALID_PARAMS;
297     }
298     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetKeyUsage(
299         ((HcfX509CertificateImpl *)self)->spiObj, boolArr);
300 }
301 
GetExtKeyUsage(HcfX509Certificate * self,CfArray * keyUsageOut)302 static CfResult GetExtKeyUsage(HcfX509Certificate *self, CfArray *keyUsageOut)
303 {
304     if ((self == NULL) || (keyUsageOut == NULL)) {
305         LOGE("Invalid input parameter.");
306         return CF_INVALID_PARAMS;
307     }
308     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
309         LOGE("Class is not match.");
310         return CF_INVALID_PARAMS;
311     }
312     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetExtKeyUsage(
313         ((HcfX509CertificateImpl *)self)->spiObj, keyUsageOut);
314 }
315 
GetBasicConstraints(HcfX509Certificate * self)316 static int32_t GetBasicConstraints(HcfX509Certificate *self)
317 {
318     if (self == NULL) {
319         LOGE("Invalid input parameter.");
320         return INVALID_CONSTRAINTS_LEN;
321     }
322     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
323         LOGE("Class is not match.");
324         return INVALID_CONSTRAINTS_LEN;
325     }
326     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetBasicConstraints(
327         ((HcfX509CertificateImpl *)self)->spiObj);
328 }
329 
GetSubjectAltNames(HcfX509Certificate * self,CfArray * outName)330 static CfResult GetSubjectAltNames(HcfX509Certificate *self, CfArray *outName)
331 {
332     if ((self == NULL) || (outName == NULL)) {
333         LOGE("Invalid input parameter.");
334         return CF_INVALID_PARAMS;
335     }
336     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
337         LOGE("Class is not match.");
338         return CF_INVALID_PARAMS;
339     }
340     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSubjectAltNames(
341         ((HcfX509CertificateImpl *)self)->spiObj, outName);
342 }
343 
GetIssuerAltNames(HcfX509Certificate * self,CfArray * outName)344 static CfResult GetIssuerAltNames(HcfX509Certificate *self, CfArray *outName)
345 {
346     if ((self == NULL) || (outName == NULL)) {
347         LOGE("Invalid input parameter.");
348         return CF_INVALID_PARAMS;
349     }
350     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
351         LOGE("Class is not match.");
352         return CF_INVALID_PARAMS;
353     }
354     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetIssuerAltNames(
355         ((HcfX509CertificateImpl *)self)->spiObj, outName);
356 }
357 
GetCRLDistributionPointsURI(HcfX509Certificate * self,CfArray * outURI)358 static CfResult GetCRLDistributionPointsURI(HcfX509Certificate *self, CfArray *outURI)
359 {
360     if ((self == NULL) || (outURI == NULL)) {
361         LOGE("crl dp invalid input parameter.");
362         return CF_INVALID_PARAMS;
363     }
364     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
365         LOGE("crl dp class is not match.");
366         return CF_INVALID_PARAMS;
367     }
368     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetCRLDistributionPointsURI(
369         ((HcfX509CertificateImpl *)self)->spiObj, outURI);
370 }
371 
Match(HcfX509Certificate * self,const HcfX509CertMatchParams * matchParams,bool * out)372 static CfResult Match(HcfX509Certificate *self, const HcfX509CertMatchParams *matchParams, bool *out)
373 {
374     if ((self == NULL) || (out == NULL) || (matchParams == NULL)) {
375         LOGE("Invalid input parameter.");
376         return CF_INVALID_PARAMS;
377     }
378     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
379         LOGE("Class is not match.");
380         return CF_INVALID_PARAMS;
381     }
382     return ((HcfX509CertificateImpl *)self)->spiObj->engineMatch(
383         ((HcfX509CertificateImpl *)self)->spiObj, matchParams, out);
384 }
385 
ToString(HcfX509Certificate * self,CfBlob * out)386 static CfResult ToString(HcfX509Certificate *self, CfBlob *out)
387 {
388     if (self == NULL || out == NULL) {
389         LOGE("Invalid input parameter.");
390         return CF_INVALID_PARAMS;
391     }
392     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
393         LOGE("Class is not match.");
394         return CF_INVALID_PARAMS;
395     }
396     return ((HcfX509CertificateImpl *)self)->spiObj->engineToString(
397         ((HcfX509CertificateImpl *)self)->spiObj, out);
398 }
399 
HashCode(HcfX509Certificate * self,CfBlob * out)400 static CfResult HashCode(HcfX509Certificate *self, CfBlob *out)
401 {
402     if (self == NULL || out == NULL) {
403         LOGE("Invalid input parameter.");
404         return CF_INVALID_PARAMS;
405     }
406     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
407         LOGE("Class is not match.");
408         return CF_INVALID_PARAMS;
409     }
410     return ((HcfX509CertificateImpl *)self)->spiObj->engineHashCode(
411         ((HcfX509CertificateImpl *)self)->spiObj, out);
412 }
413 
GetExtensionsObject(HcfX509Certificate * self,CfBlob * out)414 static CfResult GetExtensionsObject(HcfX509Certificate *self, CfBlob *out)
415 {
416     if (self == NULL || out == NULL) {
417         LOGE("Invalid input parameter.");
418         return CF_INVALID_PARAMS;
419     }
420     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertificateClass())) {
421         LOGE("Class is not match.");
422         return CF_INVALID_PARAMS;
423     }
424     return ((HcfX509CertificateImpl *)self)->spiObj->engineGetExtensionsObject(
425         ((HcfX509CertificateImpl *)self)->spiObj, out);
426 }
427 
HcfX509CertificateImplPack(HcfX509CertificateImpl * x509CertImpl,HcfX509CertificateSpi * spiObj)428 static void HcfX509CertificateImplPack(HcfX509CertificateImpl *x509CertImpl, HcfX509CertificateSpi *spiObj)
429 {
430     x509CertImpl->base.base.base.getClass = GetX509CertificateClass;
431     x509CertImpl->base.base.base.destroy = DestroyX509Certificate;
432     x509CertImpl->base.base.verify = Verify;
433     x509CertImpl->base.base.getEncoded = GetEncoded;
434     x509CertImpl->base.base.getPublicKey = GetPublicKey;
435     x509CertImpl->base.checkValidityWithDate = CheckValidityWithDate;
436     x509CertImpl->base.getVersion = GetVersion;
437     x509CertImpl->base.getSerialNumber = GetSerialNumber;
438     x509CertImpl->base.getIssuerName = GetIssuerName;
439     x509CertImpl->base.getSubjectName = GetSubjectName;
440     x509CertImpl->base.getSubjectNameEx = GetSubjectNameEx;
441     x509CertImpl->base.getNotBeforeTime = GetNotBeforeTime;
442     x509CertImpl->base.getNotAfterTime = GetNotAfterTime;
443     x509CertImpl->base.getSignature = GetSignature;
444     x509CertImpl->base.getSignatureAlgName = GetSignatureAlgName;
445     x509CertImpl->base.getSignatureAlgOid = GetSignatureAlgOid;
446     x509CertImpl->base.getSignatureAlgParams = GetSignatureAlgParams;
447     x509CertImpl->base.getKeyUsage = GetKeyUsage;
448     x509CertImpl->base.getExtKeyUsage = GetExtKeyUsage;
449     x509CertImpl->base.getBasicConstraints = GetBasicConstraints;
450     x509CertImpl->base.getSubjectAltNames = GetSubjectAltNames;
451     x509CertImpl->base.getIssuerAltNames = GetIssuerAltNames;
452     x509CertImpl->base.getCRLDistributionPointsURI = GetCRLDistributionPointsURI;
453     x509CertImpl->base.match = Match;
454     x509CertImpl->base.toString = ToString;
455     x509CertImpl->base.hashCode = HashCode;
456     x509CertImpl->base.getExtensionsObject = GetExtensionsObject;
457     x509CertImpl->spiObj = spiObj;
458 }
459 
HcfX509CertificateCreate(const CfEncodingBlob * inStream,HcfX509Certificate ** returnObj)460 CfResult HcfX509CertificateCreate(const CfEncodingBlob *inStream, HcfX509Certificate **returnObj)
461 {
462     if ((inStream == NULL) || (inStream->len > HCF_MAX_BUFFER_LEN) || (returnObj == NULL)) {
463         return CF_INVALID_PARAMS;
464     }
465     const HcfX509CertificateFuncSet *funcSet = FindAbility("X509");
466     if (funcSet == NULL) {
467         return CF_NOT_SUPPORT;
468     }
469     HcfX509CertificateSpi *spiObj = NULL;
470     CfResult res = funcSet->createFunc(inStream, &spiObj);
471     if (res != CF_SUCCESS) {
472         LOGE("Failed to create spi object!");
473         return res;
474     }
475     HcfX509CertificateImpl *x509CertImpl = (HcfX509CertificateImpl *)CfMalloc(sizeof(HcfX509CertificateImpl), 0);
476     if (x509CertImpl == NULL) {
477         LOGE("Failed to allocate x509CertImpl memory!");
478         CfObjDestroy(spiObj);
479         return CF_ERR_MALLOC;
480     }
481     HcfX509CertificateImplPack(x509CertImpl, spiObj);
482     *returnObj = (HcfX509Certificate *)x509CertImpl;
483     return CF_SUCCESS;
484 }