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 }