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_cert_chain_openssl.h"
17
18 #include <securec.h>
19 #include <openssl/asn1.h>
20 #include <openssl/bio.h>
21 #include <openssl/crypto.h>
22 #include <openssl/evp.h>
23 #include <openssl/obj_mac.h>
24 #include <openssl/ossl_typ.h>
25 #include <openssl/pem.h>
26 #include <openssl/x509.h>
27 #include <openssl/x509_vfy.h>
28
29 #include "cf_blob.h"
30 #include "cf_log.h"
31 #include "cf_memory.h"
32 #include "cf_result.h"
33 #include "config.h"
34 #include "utils.h"
35 #include "fwk_class.h"
36 #include "certificate_openssl_common.h"
37 #include "certificate_openssl_class.h"
38 #include "x509_cert_chain_spi.h"
39 #include "cert_crl_common.h"
40
41 #define X509_CERT_CHAIN_OPENSSL_CLASS "X509CertChainOpensslClass"
42 #define MAX_CERT_NUM 256 /* max certs number of a certchain */
43 #define TIMET_NUM 6
44 #define TIMET_YEAR_START 1900
45 #define TIMET_YEAR_OFFSET 100 // start time year from 1900 + 100
46
47 typedef struct {
48 HcfX509CertChainSpi base;
49 STACK_OF(X509) * x509CertChain;
50 bool isOrder; // is an order chain
51 } HcfX509CertChainOpensslImpl;
52
53 // helper functions
54 typedef struct {
55 int32_t errCode;
56 CfResult result;
57 } OpensslErrorToResult;
58
59 static const OpensslErrorToResult ERROR_TO_RESULT_MAP[] = {
60 { X509_V_OK, CF_SUCCESS },
61 { X509_V_ERR_CERT_SIGNATURE_FAILURE, CF_ERR_CERT_SIGNATURE_FAILURE },
62 { X509_V_ERR_CERT_NOT_YET_VALID, CF_ERR_CERT_NOT_YET_VALID },
63 { X509_V_ERR_CERT_HAS_EXPIRED, CF_ERR_CERT_HAS_EXPIRED },
64 { X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, CF_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY },
65 { X509_V_ERR_KEYUSAGE_NO_CERTSIGN, CF_ERR_KEYUSAGE_NO_CERTSIGN },
66 { X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, CF_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE },
67 };
68
ConvertOpensslErrorMsg(int32_t errCode)69 static CfResult ConvertOpensslErrorMsg(int32_t errCode)
70 {
71 for (uint32_t i = 0; i < sizeof(ERROR_TO_RESULT_MAP) / sizeof(OpensslErrorToResult); ++i) {
72 if (ERROR_TO_RESULT_MAP[i].errCode == errCode) {
73 return ERROR_TO_RESULT_MAP[i].result;
74 }
75 }
76 return CF_ERR_CRYPTO_OPERATION;
77 }
78
CheckIsSelfSigned(const X509 * cert)79 static bool CheckIsSelfSigned(const X509 *cert)
80 {
81 bool ret = false;
82 X509_NAME *issuer = X509_get_issuer_name(cert);
83 if (issuer == NULL) {
84 LOGE("x509 get issuer name failed !");
85 CfPrintOpensslError();
86 return CF_ERR_CRYPTO_OPERATION;
87 }
88
89 X509_NAME *subject = X509_get_subject_name(cert);
90 if (subject == NULL) {
91 LOGE("x509 get subject name failed !");
92 CfPrintOpensslError();
93 return CF_ERR_CRYPTO_OPERATION;
94 }
95
96 ret = (X509_NAME_cmp(issuer, subject) == 0);
97 LOGI("CheckIsSelfSigned() ret: %d .", ret);
98 return ret;
99 }
100
IsOrderCertChain(STACK_OF (X509)* certsChain,bool * isOrder)101 static CfResult IsOrderCertChain(STACK_OF(X509) * certsChain, bool *isOrder)
102 {
103 int num = sk_X509_num(certsChain);
104 if (num == 1) {
105 LOGI("1 certs is order chain.");
106 return CF_SUCCESS;
107 }
108
109 X509 *cert = NULL;
110 X509 *certNext = NULL;
111 X509_NAME *issuerName = NULL;
112 X509_NAME *subjectName = NULL;
113 for (int i = num - 1; i > 0; --i) {
114 cert = sk_X509_value(certsChain, i);
115 if (cert == NULL) {
116 LOGE("sk X509 value is null, failed !");
117 CfPrintOpensslError();
118 return CF_ERR_CRYPTO_OPERATION;
119 }
120 certNext = sk_X509_value(certsChain, i - 1);
121 if (certNext == NULL) {
122 LOGE("sk X509 value is null, failed !");
123 CfPrintOpensslError();
124 return CF_ERR_CRYPTO_OPERATION;
125 }
126
127 subjectName = X509_get_subject_name(cert);
128 if (subjectName == NULL) {
129 LOGE("x509 get subject name failed !");
130 CfPrintOpensslError();
131 return CF_ERR_CRYPTO_OPERATION;
132 }
133 issuerName = X509_get_issuer_name(certNext);
134 if (issuerName == NULL) {
135 LOGE("x509 get subject name failed !");
136 CfPrintOpensslError();
137 return CF_ERR_CRYPTO_OPERATION;
138 }
139
140 if (!(X509_NAME_cmp(subjectName, issuerName) == 0)) {
141 *isOrder = false;
142 LOGI("is a misOrder chain .");
143 break;
144 }
145 }
146
147 return CF_SUCCESS;
148 }
149
150 // helper functions end
151
GetX509CertChainClass(void)152 static const char *GetX509CertChainClass(void)
153 {
154 return X509_CERT_CHAIN_OPENSSL_CLASS;
155 }
156
DestroyX509CertChain(CfObjectBase * self)157 static void DestroyX509CertChain(CfObjectBase *self)
158 {
159 if (self == NULL || !IsClassMatch(self, GetX509CertChainClass())) {
160 LOGE("Invalid params!");
161 return;
162 }
163 HcfX509CertChainOpensslImpl *impl = (HcfX509CertChainOpensslImpl *)self;
164 if (impl->x509CertChain != NULL) {
165 sk_X509_pop_free(impl->x509CertChain, X509_free);
166 impl->x509CertChain = NULL;
167 }
168
169 CfFree(impl);
170 }
171
X509ToHcfX509Certificate(X509 * cert,HcfX509Certificate ** returnObj)172 static CfResult X509ToHcfX509Certificate(X509 *cert, HcfX509Certificate **returnObj)
173 {
174 if (cert == NULL) {
175 LOGE("X509ToHcfX509Certificate() failed !");
176 return CF_INVALID_PARAMS;
177 }
178
179 int dataLength = 0;
180 uint8_t *certData = GetX509EncodedDataStream(cert, &dataLength);
181 if (certData == NULL) {
182 LOGE("Falied to get certificate data!");
183 return CF_ERR_CRYPTO_OPERATION;
184 }
185
186 HcfX509Certificate *x509cert = NULL;
187 CfEncodingBlob encodingBlob = { certData, dataLength, CF_FORMAT_DER };
188 CfResult res = HcfX509CertificateCreate(&encodingBlob, &x509cert);
189 if (res != CF_SUCCESS) {
190 LOGE("HcfX509CertificateCreate fail, res : %d!", res);
191 CfFree(certData);
192 return CF_ERR_MALLOC;
193 }
194
195 *returnObj = x509cert;
196 CfFree(certData);
197 return res;
198 }
199
GetCertlist(HcfX509CertChainSpi * self,HcfX509CertificateArray * certsList)200 static CfResult GetCertlist(HcfX509CertChainSpi *self, HcfX509CertificateArray *certsList)
201 {
202 if ((self == NULL) || (certsList == NULL)) {
203 LOGE("[GetCertlist openssl] The input data is null!");
204 return CF_INVALID_PARAMS;
205 }
206 if (!IsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
207 LOGE("[GetCertlist openssl] Input wrong class type!");
208 return CF_INVALID_PARAMS;
209 }
210
211 CfResult res = CF_SUCCESS;
212 HcfX509CertChainOpensslImpl *certChain = (HcfX509CertChainOpensslImpl *)self;
213 STACK_OF(X509) *x509CertChain = certChain->x509CertChain;
214
215 int32_t certsNum = sk_X509_num(x509CertChain);
216 if (certsNum == 0) {
217 LOGE("sk X509 num : 0, failed !");
218 CfPrintOpensslError();
219 return CF_ERR_CRYPTO_OPERATION;
220 }
221 /* the list count has checked when create cert chain */
222 certsList->data = (HcfX509Certificate **)HcfMalloc(certsNum * sizeof(HcfX509Certificate *), 0);
223 if (certsList->data == NULL) {
224 LOGE("malloc failed");
225 return CF_ERR_MALLOC;
226 }
227
228 certsList->count = (uint32_t)certsNum;
229 for (int32_t i = 0; i < certsNum; ++i) {
230 X509 *cert = sk_X509_value(x509CertChain, i);
231 if (cert == NULL) {
232 LOGE("sk X509 value is null, failed !");
233 CfPrintOpensslError();
234 return CF_ERR_CRYPTO_OPERATION;
235 }
236 HcfX509Certificate *x509Cert = NULL;
237 res = X509ToHcfX509Certificate(cert, &x509Cert);
238 if (res != CF_SUCCESS) {
239 LOGE("convert x509 to HcfX509Certificate failed !");
240 FreeCertArrayData(certsList);
241 return res;
242 }
243 certsList->data[i] = x509Cert;
244 }
245
246 return res;
247 }
248
GetX509FromHcfX509Certificate(const HcfCertificate * cert)249 static X509 *GetX509FromHcfX509Certificate(const HcfCertificate *cert)
250 {
251 if (!IsClassMatch((CfObjectBase *)cert, HCF_X509_CERTIFICATE_CLASS)) {
252 LOGE("Input wrong openssl class type!");
253 return NULL;
254 }
255 HcfX509CertificateImpl *impl = (HcfX509CertificateImpl *)cert;
256 if (!IsClassMatch((CfObjectBase *)(impl->spiObj), X509_CERT_OPENSSL_CLASS)) {
257 LOGE("Input wrong openssl class type!");
258 return NULL;
259 }
260 HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)(impl->spiObj);
261
262 return realCert->x509;
263 }
264
CheckCertChainIsRevoked(const STACK_OF (X509_CRL)* crlStack,const STACK_OF (X509)* certChain)265 static CfResult CheckCertChainIsRevoked(const STACK_OF(X509_CRL) *crlStack, const STACK_OF(X509) *certChain)
266 {
267 int cerNum = sk_X509_num(certChain);
268 if (cerNum == 0) {
269 LOGE("sk X509 num : 0, failed !");
270 CfPrintOpensslError();
271 return CF_ERR_CRYPTO_OPERATION;
272 }
273
274 int crlNum = sk_X509_CRL_num(crlStack); // allow crlNum : 0, no crl
275 for (int i = 0; i < crlNum; ++i) {
276 X509_CRL *crl = sk_X509_CRL_value(crlStack, i);
277 if (crl == NULL) {
278 LOGE("sk X509 CRL value is null, failed !");
279 CfPrintOpensslError();
280 return CF_ERR_CRYPTO_OPERATION;
281 }
282
283 /* crl in certcrlcollection object is not null. */
284 for (int j = 0; j < cerNum; ++j) {
285 X509 *cert = sk_X509_value(certChain, j);
286 if (cert == NULL) {
287 LOGE("sk X509 value is null, failed !");
288 CfPrintOpensslError();
289 return CF_ERR_CRYPTO_OPERATION;
290 }
291
292 X509_REVOKED *rev = NULL;
293 int32_t res = X509_CRL_get0_by_cert(crl, &rev, cert);
294 if (res != 0) {
295 LOGE("cert is revoked.");
296 return CF_ERR_CRYPTO_OPERATION;
297 }
298 }
299 }
300
301 return CF_SUCCESS;
302 }
303
SetVerifyParams(X509_STORE * store,X509 * mostTrustCert)304 static CfResult SetVerifyParams(X509_STORE *store, X509 *mostTrustCert)
305 {
306 LOGI("add most-trusted cert's to store: ");
307 if (X509_STORE_add_cert(store, mostTrustCert) != CF_OPENSSL_SUCCESS) {
308 LOGE("add cert to store failed !");
309 CfPrintOpensslError();
310 return CF_ERR_CRYPTO_OPERATION;
311 }
312
313 unsigned long flags = 0;
314 if (!CheckIsSelfSigned(mostTrustCert)) {
315 flags |= X509_V_FLAG_PARTIAL_CHAIN; // is not self signed
316 LOGI("SetVerifyFlag() is a partitial chain, not self signed !");
317 }
318
319 /* date has verified before. */
320 flags |= X509_V_FLAG_NO_CHECK_TIME;
321 X509_STORE_set_flags(store, flags);
322
323 return CF_SUCCESS;
324 }
325
VerifyCertChain(X509 * mostTrustCert,STACK_OF (X509)* x509CertChain)326 static CfResult VerifyCertChain(X509 *mostTrustCert, STACK_OF(X509) * x509CertChain)
327 {
328 if (mostTrustCert == NULL || x509CertChain == NULL) {
329 LOGE("invalid params !");
330 return CF_INVALID_PARAMS;
331 }
332
333 X509 *cert = sk_X509_value(x509CertChain, 0); // leaf cert
334 if (cert == NULL) {
335 CfPrintOpensslError();
336 return CF_ERR_CRYPTO_OPERATION;
337 }
338
339 X509_STORE_CTX *ctx = X509_STORE_CTX_new();
340 if (ctx == NULL) {
341 CfPrintOpensslError();
342 return CF_ERR_CRYPTO_OPERATION;
343 }
344
345 X509_STORE *store = X509_STORE_new();
346 if (store == NULL) {
347 LOGE("verify cert chain malloc failed !");
348 X509_STORE_CTX_free(ctx);
349 CfPrintOpensslError();
350 return CF_ERR_CRYPTO_OPERATION;
351 }
352
353 CfResult res = SetVerifyParams(store, mostTrustCert);
354 if (res == CF_SUCCESS) {
355 if (X509_STORE_CTX_init(ctx, store, cert, x509CertChain) != CF_OPENSSL_SUCCESS) {
356 LOGE("init verify ctx failed !");
357 X509_STORE_CTX_free(ctx);
358 X509_STORE_free(store);
359 CfPrintOpensslError();
360 return CF_ERR_CRYPTO_OPERATION;
361 }
362
363 if (X509_verify_cert(ctx) == CF_OPENSSL_SUCCESS) {
364 LOGI("Certificate verification succeeded.");
365 res = CF_SUCCESS;
366 } else {
367 int32_t errCode = X509_STORE_CTX_get_error(ctx);
368 const char *pChError = X509_verify_cert_error_string(errCode);
369 LOGE("Failed to verify cert, openssl openssl error code = %d, error msg:%s.", errCode, pChError);
370 res = ConvertOpensslErrorMsg(errCode);
371 }
372 }
373
374 X509_STORE_CTX_free(ctx); // Cleanup: Free the allocated memory and release resources.
375 X509_STORE_free(store);
376 return res;
377 }
378
ConvertByteArrayToPubKey(const uint8_t * pubKeyBytes,size_t len)379 static EVP_PKEY *ConvertByteArrayToPubKey(const uint8_t *pubKeyBytes, size_t len)
380 {
381 if (pubKeyBytes == NULL) {
382 LOGE("ConvertByteArrayToPubkey invalid params.");
383 return NULL;
384 }
385 LOGI("pubkeyBytes len: %d .", len);
386 EVP_PKEY *pubKey = d2i_PUBKEY(NULL, &pubKeyBytes, len); // pubkey DER format.
387 if (pubKey == NULL) {
388 LOGE("d2i_PUBKEY() failed !");
389 CfPrintOpensslError();
390 return NULL;
391 }
392
393 return pubKey;
394 }
395
CheckSelfPubkey(X509 * cert,const EVP_PKEY * pubKey)396 static CfResult CheckSelfPubkey(X509 *cert, const EVP_PKEY *pubKey)
397 {
398 EVP_PKEY *certPublicKey = X509_get_pubkey(cert);
399 if (certPublicKey == NULL) {
400 LOGE("get cert public key failed !");
401 CfPrintOpensslError();
402 return CF_ERR_CRYPTO_OPERATION;
403 }
404
405 int isMatch = EVP_PKEY_cmp(certPublicKey, pubKey);
406 if (isMatch != CF_OPENSSL_SUCCESS) {
407 LOGE("cmp cert public key failed !");
408 CfPrintOpensslError();
409 EVP_PKEY_free(certPublicKey);
410 return CF_ERR_CRYPTO_OPERATION;
411 }
412
413 EVP_PKEY_free(certPublicKey);
414 return CF_SUCCESS;
415 }
416
CheckOthersInTrustAnchor(const HcfX509TrustAnchor * anchor,X509 * rootCert,bool * checkResult)417 static CfResult CheckOthersInTrustAnchor(const HcfX509TrustAnchor *anchor, X509 *rootCert, bool *checkResult)
418 {
419 *checkResult = false;
420 if (anchor->CAPubKey == NULL) {
421 return CF_SUCCESS;
422 }
423
424 // 1. validate public key of the root CA.
425 EVP_PKEY *pubKey = ConvertByteArrayToPubKey(anchor->CAPubKey->data, anchor->CAPubKey->size);
426 if (pubKey == NULL) {
427 LOGE("ConvertByteArrayToPubKey failed !");
428 return CF_ERR_CRYPTO_OPERATION;
429 }
430 /* pubkey in trust anchor may be the pubkey of self or of its upper level cert. */
431 bool matchUpperPubKey = false;
432 if (CheckSelfPubkey(rootCert, pubKey) != CF_SUCCESS) {
433 matchUpperPubKey = (X509_verify(rootCert, pubKey) == CF_OPENSSL_SUCCESS);
434 if (!matchUpperPubKey) {
435 LOGE("verify pubkey in trust anchor failed!");
436 CfPrintOpensslError();
437 EVP_PKEY_free(pubKey);
438 return CF_SUCCESS;
439 }
440 }
441
442 /* If pubkey is of self cert, the subject should be of self cert.
443 * If pubkey is of upper level cert, the subject should be of uppoer level cert (i.e. the issuer of self cert).
444 */
445 if (anchor->CASubject != NULL) {
446 // 2. compare subject name of root CA.
447 X509NameType nameType = NAME_TYPE_SUBECT;
448 if (matchUpperPubKey) {
449 nameType = NAME_TYPE_ISSUER;
450 }
451 bool compareSubjectFlag = false;
452 CfResult res = CompareNameObject(rootCert, anchor->CASubject, nameType, &compareSubjectFlag);
453 if (res != CF_SUCCESS) {
454 LOGE("verify subject in trust anchor failed!");
455 EVP_PKEY_free(pubKey);
456 return res;
457 }
458 LOGI("verify subject in trust anchor result: %d", compareSubjectFlag);
459 *checkResult = compareSubjectFlag;
460 } else {
461 *checkResult = true;
462 }
463
464 EVP_PKEY_free(pubKey);
465 return CF_SUCCESS;
466 }
467
GetTrustAnchor(const HcfX509TrustAnchor * trustAnchors,X509 * rootCert,X509 ** mostTrustCertOut)468 static CfResult GetTrustAnchor(const HcfX509TrustAnchor *trustAnchors, X509 *rootCert, X509 **mostTrustCertOut)
469 {
470 if (trustAnchors == NULL || rootCert == NULL || mostTrustCertOut == NULL) {
471 LOGE("GetTrustAnchorCert() invalid params !");
472 return CF_INVALID_PARAMS;
473 }
474
475 if (trustAnchors->CACert != NULL) {
476 X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)trustAnchors->CACert);
477 if (cert == NULL) {
478 LOGE("GetTrustAnchorCert() cert is null.");
479 return CF_INVALID_PARAMS;
480 }
481
482 X509_NAME *subjectName = X509_get_subject_name(cert);
483 if (subjectName == NULL) {
484 CfPrintOpensslError();
485 return CF_ERR_CRYPTO_OPERATION;
486 }
487 X509_NAME *subjectRoot = X509_get_subject_name(rootCert);
488 if (subjectRoot == NULL) {
489 CfPrintOpensslError();
490 return CF_ERR_CRYPTO_OPERATION;
491 }
492 EVP_PKEY *pubKey = X509_get_pubkey(cert); // validate public key of the trustAnchor CACert. X509_check_issued
493 if (pubKey == NULL) {
494 LOGE("X509_get_pubkey() failed !");
495 CfPrintOpensslError();
496 return CF_ERR_CRYPTO_OPERATION;
497 }
498 if (X509_verify(rootCert, pubKey) != CF_OPENSSL_SUCCESS && X509_NAME_cmp(subjectName, subjectRoot)) {
499 LOGE("X509_verify() failed! ");
500 CfPrintOpensslError();
501 EVP_PKEY_free(pubKey);
502 return CF_SUCCESS; // continue to try next trustAnchor
503 }
504 EVP_PKEY_free(pubKey);
505 *mostTrustCertOut = cert;
506 LOGI("GetTrustAnchorCert() use trustAnchor->CACert .");
507 return CF_SUCCESS;
508 }
509
510 bool checkResult = false;
511 CfResult res = CheckOthersInTrustAnchor(trustAnchors, rootCert, &checkResult);
512 if (res != CF_SUCCESS) {
513 LOGE("CheckOthersInTrustAnchor failed.");
514 return res;
515 }
516
517 if (checkResult) {
518 *mostTrustCertOut = rootCert;
519 }
520 return CF_SUCCESS;
521 }
522
FreeTrustAnchorData(HcfX509TrustAnchor * trustAnchor)523 static void FreeTrustAnchorData(HcfX509TrustAnchor *trustAnchor)
524 {
525 if (trustAnchor == NULL) {
526 return;
527 }
528 CfBlobFree(&trustAnchor->CAPubKey);
529 CfBlobFree(&trustAnchor->CASubject);
530 CfObjDestroy(trustAnchor->CACert);
531 trustAnchor->CACert = NULL;
532 }
533
CopyHcfX509TrustAnchor(const HcfX509TrustAnchor * inputAnchor,HcfX509TrustAnchor * outAnchor)534 static CfResult CopyHcfX509TrustAnchor(const HcfX509TrustAnchor *inputAnchor, HcfX509TrustAnchor *outAnchor)
535 {
536 HcfX509Certificate *CACert = inputAnchor->CACert;
537 CfBlob *CAPubKey = inputAnchor->CAPubKey;
538 CfBlob *CASubject = inputAnchor->CASubject;
539 CfResult res = CF_SUCCESS;
540 if (CACert != NULL) {
541 CfEncodingBlob encodedByte = { NULL, 0, CF_FORMAT_DER };
542 CACert->base.getEncoded((HcfCertificate *)CACert, &encodedByte);
543 res = HcfX509CertificateCreate(&encodedByte, &outAnchor->CACert);
544 if (res != CF_SUCCESS) {
545 LOGE("HcfX509CertificateCreate fail, res : %d!", res);
546 CfFree(encodedByte.data);
547 return CF_ERR_MALLOC;
548 }
549 CfFree(encodedByte.data);
550 }
551 if (CAPubKey != NULL) {
552 res = DeepCopyBlobToBlob(CAPubKey, &outAnchor->CAPubKey);
553 if (res != CF_SUCCESS) {
554 LOGE("DeepCopyDataToBlob failed");
555 CfObjDestroy(outAnchor->CACert);
556 return res;
557 }
558 }
559 if (CASubject != NULL) {
560 res = DeepCopyBlobToBlob(CASubject, &outAnchor->CASubject);
561 if (res != CF_SUCCESS) {
562 LOGE("DeepCopyDataToBlob failed");
563 CfObjDestroy(outAnchor->CACert);
564 CfBlobFree(&outAnchor->CAPubKey);
565 return res;
566 }
567 }
568
569 return res;
570 }
571
FillValidateResult(HcfX509TrustAnchor * inputAnchor,X509 * cert,HcfX509CertChainValidateResult * result)572 static CfResult FillValidateResult(HcfX509TrustAnchor *inputAnchor, X509 *cert, HcfX509CertChainValidateResult *result)
573 {
574 if (inputAnchor == NULL || cert == NULL) {
575 LOGE("FillValidateResult() invalidate params !");
576 return CF_INVALID_PARAMS;
577 }
578 CfResult res = CF_SUCCESS;
579 HcfX509TrustAnchor *validateTrustAnchors = (HcfX509TrustAnchor *)HcfMalloc(sizeof(HcfX509TrustAnchor), 0);
580 if (validateTrustAnchors == NULL) {
581 LOGE("FillValidateResult() malloc failed");
582 return CF_ERR_MALLOC;
583 }
584 res = CopyHcfX509TrustAnchor(inputAnchor, validateTrustAnchors);
585 if (res != CF_SUCCESS) {
586 LOGE("CopyHcfX509TrustAnchor() failed !");
587 CfFree(validateTrustAnchors);
588 return res;
589 }
590
591 result->trustAnchor = validateTrustAnchors;
592 HcfX509Certificate *entityCert = NULL;
593 res = X509ToHcfX509Certificate(cert, &entityCert);
594 if (res != CF_SUCCESS) {
595 LOGE("X509ToHcfX509Certificate() failed !");
596 FreeTrustAnchorData(result->trustAnchor);
597 CF_FREE_PTR(result->trustAnchor);
598 return res;
599 }
600
601 result->entityCert = entityCert;
602 LOGI("FillValidateResult() success !");
603 return res;
604 }
605
ParseX509CRL(const CfEncodingBlob * inStream)606 static X509_CRL *ParseX509CRL(const CfEncodingBlob *inStream)
607 {
608 if ((inStream->data == NULL) || (inStream->len <= 0)) {
609 LOGE("Invalid Paramas!");
610 return NULL;
611 }
612 BIO *bio = BIO_new_mem_buf(inStream->data, inStream->len);
613 if (bio == NULL) {
614 LOGE("bio get null!");
615 CfPrintOpensslError();
616 return NULL;
617 }
618 X509_CRL *crlOut = NULL;
619 switch (inStream->encodingFormat) {
620 case CF_FORMAT_DER:
621 crlOut = d2i_X509_CRL_bio(bio, NULL);
622 break;
623 case CF_FORMAT_PEM:
624 crlOut = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
625 break;
626 default:
627 LOGE("Not support format!");
628 break;
629 }
630 BIO_free_all(bio);
631 if (crlOut == NULL) {
632 LOGE("Parse X509 CRL fail!");
633 CfPrintOpensslError();
634 return NULL;
635 }
636 return crlOut;
637 }
638
PushCrl2Stack(HcfX509CrlArray * crlArray,STACK_OF (X509_CRL)* outCrls)639 static CfResult PushCrl2Stack(HcfX509CrlArray *crlArray, STACK_OF(X509_CRL) * outCrls)
640 {
641 CfResult res = CF_SUCCESS;
642 HcfX509Crl *x509Crl = NULL;
643 X509_CRL *crl = NULL;
644 STACK_OF(X509_CRL) *stackCrls = sk_X509_CRL_new_null();
645 for (uint32_t i = 0; i < crlArray->count; i++) {
646 CfEncodingBlob encodedBlob = { 0 };
647 x509Crl = crlArray->data[i];
648 res = x509Crl->getEncoded(x509Crl, &encodedBlob);
649 if (res != CF_SUCCESS) {
650 LOGE("Failed to getEncoded of crl !");
651 sk_X509_CRL_pop_free(stackCrls, X509_CRL_free);
652 return res;
653 }
654
655 crl = ParseX509CRL(&encodedBlob);
656 if (crl == NULL) {
657 LOGE("Failed to Parse x509 CRL!");
658 CfFree(encodedBlob.data);
659 sk_X509_CRL_pop_free(stackCrls, X509_CRL_free);
660 return CF_INVALID_PARAMS;
661 }
662 if (sk_X509_CRL_push(stackCrls, crl) == 0) {
663 LOGE("sk_X509_CRL_push failed !");
664 CfFree(encodedBlob.data);
665 sk_X509_CRL_pop_free(stackCrls, X509_CRL_free);
666 X509_CRL_free(crl);
667 return CF_ERR_CRYPTO_OPERATION;
668 }
669 CfFree(encodedBlob.data);
670 }
671
672 /* Move stackCrls elements to outCrls */
673 while (sk_X509_CRL_num(stackCrls) > 0) {
674 crl = sk_X509_CRL_pop(stackCrls);
675 LOGI("push crl to crlStack .");
676 if (sk_X509_CRL_push(outCrls, crl) == 0) {
677 LOGE("sk_X509_CRL_push failed !");
678 sk_X509_CRL_pop_free(stackCrls, X509_CRL_free);
679 X509_CRL_free(crl);
680 return CF_ERR_CRYPTO_OPERATION;
681 }
682 }
683
684 sk_X509_CRL_free(stackCrls); /* Only free the stack, do not free elements */
685 return res;
686 }
687
GetX509Crls(const HcfCertCRLCollectionArray * certCRLCollections,STACK_OF (X509_CRL)* outCrls)688 static CfResult GetX509Crls(const HcfCertCRLCollectionArray *certCRLCollections, STACK_OF(X509_CRL) * outCrls)
689 {
690 if (certCRLCollections == NULL) { // certCRLCollection is not force params for verify certchain
691 LOGI("certcrlcollections is null!");
692 return CF_SUCCESS;
693 }
694
695 CfResult res = CF_SUCCESS;
696 HcfX509CrlArray *crlArray = NULL;
697 HcfCertCrlCollection *crlCollection = NULL;
698 for (uint32_t i = 0; i < certCRLCollections->count; i++) {
699 crlCollection = certCRLCollections->data[i];
700 res = crlCollection->getCRLs(crlCollection, &crlArray);
701 if (res != CF_SUCCESS) {
702 LOGE("getCRLs() from CertCrlCollection failed !");
703 /* Warning: free outCrls in outside */
704 return res;
705 }
706 if (crlArray->count == 0) {
707 LOGI("crls array is empty.");
708 continue;
709 }
710 res = PushCrl2Stack(crlArray, outCrls);
711 if (res != CF_SUCCESS) {
712 LOGE("push crls to stack failed !");
713 /* Warning: free outCrls in outside */
714 return res;
715 }
716 }
717
718 return res;
719 }
720
ValidateCrls(const HcfCertCRLCollectionArray * collectionArr,STACK_OF (X509)* x509CertChain)721 static CfResult ValidateCrls(const HcfCertCRLCollectionArray *collectionArr, STACK_OF(X509) * x509CertChain)
722 {
723 STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
724 if (crlStack == NULL) {
725 LOGE("sk X509 CRL new null failed !");
726 CfPrintOpensslError();
727 return CF_ERR_CRYPTO_OPERATION;
728 }
729
730 CfResult res = GetX509Crls(collectionArr, crlStack);
731 if (res != CF_SUCCESS) {
732 LOGE("GetX509Crls failed");
733 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
734 return res;
735 }
736
737 if (sk_X509_CRL_num(crlStack) == 0) {
738 LOGI("crls count is 0");
739 sk_X509_CRL_free(crlStack);
740 return CF_SUCCESS;
741 }
742 res = CheckCertChainIsRevoked(crlStack, x509CertChain);
743 sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
744 return res;
745 }
746
ValidateTrustAnchor(const HcfX509TrustAnchorArray * trustAnchorsArray,X509 * rootCert,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor ** trustAnchorResult)747 static CfResult ValidateTrustAnchor(const HcfX509TrustAnchorArray *trustAnchorsArray, X509 *rootCert,
748 STACK_OF(X509) * x509CertChain, HcfX509TrustAnchor **trustAnchorResult)
749 {
750 CfResult res = CF_SUCCESS;
751 for (uint32_t i = 0; i < trustAnchorsArray->count; ++i) {
752 X509 *mostTrustAnchorCert = NULL;
753 HcfX509TrustAnchor *trustAnchor = trustAnchorsArray->data[i];
754 res = GetTrustAnchor(trustAnchor, rootCert, &mostTrustAnchorCert);
755 if (res != CF_SUCCESS) {
756 LOGE("GetTrustAnchor() failed ! try next trustAnchor .");
757 return res;
758 }
759 if (mostTrustAnchorCert == NULL) {
760 LOGE("most trust anchor cert is null.");
761 res = CF_INVALID_PARAMS; /* if validate trust anchor list failed, return the last error. */
762 continue;
763 }
764
765 res = VerifyCertChain(mostTrustAnchorCert, x509CertChain);
766 if (res != CF_SUCCESS) { // verify the data & crl list of certchain
767 LOGI("verify one trustanchor failed ! try next trustAnchor .");
768 continue;
769 }
770 *trustAnchorResult = trustAnchor;
771 LOGI("Verify CertChain success !");
772 break;
773 }
774
775 return res;
776 }
777
ValidateDate(const STACK_OF (X509)* x509CertChain,CfBlob * date)778 static CfResult ValidateDate(const STACK_OF(X509) * x509CertChain, CfBlob *date)
779 {
780 if (date == NULL) {
781 LOGI("date is null");
782 return CF_SUCCESS;
783 }
784 if (!CfBlobIsStr(date)) {
785 LOGE("time format is invalid");
786 return CF_INVALID_PARAMS;
787 }
788 ASN1_TIME *asn1InputDate = ASN1_TIME_new();
789 if (asn1InputDate == NULL) {
790 LOGE("Failed to malloc for asn1 time.");
791 return CF_ERR_MALLOC;
792 }
793 if (ASN1_TIME_set_string(asn1InputDate, (const char *)date->data) != CF_OPENSSL_SUCCESS) {
794 LOGE("Failed to set time for asn1 time.");
795 CfPrintOpensslError();
796 ASN1_TIME_free(asn1InputDate);
797 return CF_INVALID_PARAMS;
798 }
799 CfResult res = CF_SUCCESS;
800 int certsNum = sk_X509_num(x509CertChain);
801 for (int i = 0; i < certsNum; ++i) {
802 X509 *cert = sk_X509_value(x509CertChain, i);
803 if (cert == NULL) {
804 LOGE("sk X509 value is null, failed !");
805 CfPrintOpensslError();
806 ASN1_TIME_free(asn1InputDate);
807 return CF_ERR_CRYPTO_OPERATION;
808 }
809 res = CompareDateWithCertTime(cert, asn1InputDate);
810 if (res != CF_SUCCESS) {
811 LOGE("check validate failed.");
812 ASN1_TIME_free(asn1InputDate);
813 return res;
814 }
815 }
816 ASN1_TIME_free(asn1InputDate);
817 return res;
818 }
819
Validate(HcfX509CertChainSpi * self,const HcfX509CertChainValidateParams * params,HcfX509CertChainValidateResult * result)820 static CfResult Validate(
821 HcfX509CertChainSpi *self, const HcfX509CertChainValidateParams *params, HcfX509CertChainValidateResult *result)
822 {
823 if ((self == NULL) || (params == NULL) || (params->trustAnchors == NULL) || (params->trustAnchors->data == NULL) ||
824 (params->trustAnchors->count == 0) || (result == NULL)) {
825 LOGE("[Validate openssl] The input data is null!");
826 return CF_INVALID_PARAMS;
827 }
828 if (!IsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
829 LOGE("[Validate openssl] Input wrong class type!");
830 return CF_INVALID_PARAMS;
831 }
832 if (!((HcfX509CertChainOpensslImpl *)self)->isOrder) {
833 LOGE("misOrder certs chain , verify failed");
834 return CF_INVALID_PARAMS;
835 }
836
837 STACK_OF(X509) *x509CertChain = ((HcfX509CertChainOpensslImpl *)self)->x509CertChain;
838 /* when check time with X509_STORE_CTX_set_time, the noAfter of cert is exclusive, but in RFC5280, it is inclusive,
839 * so check manually here.
840 */
841 CfResult res = ValidateDate(x509CertChain, params->date);
842 if (res != CF_SUCCESS) {
843 LOGE("validate date failed.");
844 return res;
845 }
846
847 X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1); // root CA
848 if (rootCert == NULL) {
849 LOGE("sk X509 value failed !");
850 CfPrintOpensslError();
851 return CF_ERR_CRYPTO_OPERATION;
852 }
853
854 HcfX509TrustAnchor *trustAnchorResult = NULL; // Verify trust anchor
855 res = ValidateTrustAnchor(params->trustAnchors, rootCert, x509CertChain, &trustAnchorResult);
856 if (res == CF_SUCCESS) {
857 res = ValidateCrls(params->certCRLCollections, x509CertChain); // Verify Crls
858 if (res != CF_SUCCESS) {
859 LOGE("Validate Crls failed");
860 return res;
861 }
862 X509 *entityCert = sk_X509_value(x509CertChain, 0); // leaf CA
863 if (entityCert == NULL) {
864 LOGE("sk X509 value failed !");
865 CfPrintOpensslError();
866 return CF_ERR_CRYPTO_OPERATION;
867 }
868 res = FillValidateResult(trustAnchorResult, entityCert, result); // build return result
869 }
870
871 return res;
872 }
873
CreateX509CertChainPEM(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)874 static int32_t CreateX509CertChainPEM(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
875 {
876 STACK_OF(X509) *certsChain = NULL;
877 X509 *cert = NULL;
878
879 BIO *bio = BIO_new_mem_buf(inData->data, inData->len);
880 if (bio == NULL) {
881 LOGE("BIO new mem buf failed !");
882 CfPrintOpensslError();
883 return CF_ERR_CRYPTO_OPERATION;
884 }
885 LOGI("createX509CertChainPEM CfEncodingBlob inData len: %u .", inData->len);
886
887 /* Create cert chain object */
888 certsChain = sk_X509_new_null();
889 if (certsChain == NULL) {
890 BIO_free(bio);
891 LOGE("Error creating certificate chain.");
892 CfPrintOpensslError();
893 return CF_ERR_CRYPTO_OPERATION;
894 }
895
896 /* Add cert to cert chain object */
897 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) && cert != NULL) {
898 if (sk_X509_push(certsChain, cert) <= 0) {
899 LOGE("Memory allocation failure !\n");
900 X509_free(cert);
901 BIO_free(bio);
902 sk_X509_pop_free(certsChain, X509_free);
903 return CF_ERR_CRYPTO_OPERATION;
904 }
905 LOGI("push cert to certsChain.");
906 }
907
908 if (sk_X509_num(certsChain) == 0) {
909 LOGE("cert chain size = 0.");
910 CfPrintOpensslError();
911 BIO_free(bio);
912 sk_X509_free(certsChain);
913 return CF_ERR_CRYPTO_OPERATION;
914 }
915
916 *certchainObj = certsChain;
917 BIO_free(bio);
918 return CF_SUCCESS;
919 }
920
921 /*
922 * create x509 certchain from DER format streams
923 * input params: inData
924 * output params: certchainObj
925 */
CreateX509CertChainDER(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)926 static int32_t CreateX509CertChainDER(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
927 {
928 STACK_OF(X509) *certsChain = NULL;
929 X509 *cert = NULL;
930 const unsigned char *p = inData->data; // DER data
931 size_t length = inData->len;
932
933 LOGI("createX509CertChainDER CfEncodingBlob inData len: %u.", length);
934 certsChain = sk_X509_new_null();
935 if (certsChain == NULL) {
936 LOGE("Error creating certificate chain.");
937 return CF_ERR_MALLOC;
938 }
939
940 while (p < inData->data + length) {
941 size_t lengthLeft = (inData->data + length - p);
942 cert = d2i_X509(NULL, &p, lengthLeft);
943 if (cert == NULL) {
944 LOGE("Failed to parse certificate.");
945 CfPrintOpensslError();
946 sk_X509_pop_free(certsChain, X509_free);
947 return CF_ERR_CRYPTO_OPERATION;
948 }
949 if (sk_X509_push(certsChain, cert) <= 0) {
950 LOGE("Memory allocation failure !\n");
951 X509_free(cert);
952 sk_X509_pop_free(certsChain, X509_free);
953 return CF_ERR_MALLOC;
954 }
955 LOGI("push cert to certsChain.");
956 }
957
958 if (sk_X509_num(certsChain) == 0) {
959 sk_X509_free(certsChain);
960 LOGE("certs chain count = 0.");
961 return CF_INVALID_PARAMS;
962 }
963 *certchainObj = certsChain;
964 return CF_SUCCESS;
965 }
966
967 /*
968 * create x509 certchain from pkcs#7 streams
969 * input params: inData
970 * output params: certchainObj
971 */
CreateX509CertChainPKCS7(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)972 static CfResult CreateX509CertChainPKCS7(const CfEncodingBlob *inData, STACK_OF(X509) * *certchainObj)
973 {
974 size_t dataLength = inData->len;
975 uint8_t *data = inData->data;
976 BIO *bio = BIO_new_mem_buf(data, dataLength);
977 if (bio == NULL) {
978 LOGE("malloc failed");
979 CfPrintOpensslError();
980 return CF_ERR_MALLOC;
981 }
982
983 PKCS7 *pkcs7 = d2i_PKCS7_bio(bio, NULL); // DER format .p7b file
984 if (pkcs7 == NULL) {
985 LOGE("Failed to parse PKCS7 data .");
986 BIO_free(bio);
987 CfPrintOpensslError();
988 return CF_ERR_CRYPTO_OPERATION;
989 }
990
991 /* Get cert chain from pkcs7 object */
992 STACK_OF(X509) *oriCertsChain = NULL;
993 int i = OBJ_obj2nid(pkcs7->type);
994 LOGE("pkcs7->type : %d .", i);
995 if (i == NID_pkcs7_signed && pkcs7->d.sign != NULL) {
996 oriCertsChain = pkcs7->d.sign->cert;
997 } else if (i == NID_pkcs7_signedAndEnveloped && pkcs7->d.signed_and_enveloped != NULL) {
998 oriCertsChain = pkcs7->d.signed_and_enveloped->cert;
999 }
1000
1001 if (oriCertsChain == NULL || sk_X509_num(oriCertsChain) == 0) {
1002 LOGE("Failed to get certchain object.");
1003 PKCS7_free(pkcs7);
1004 BIO_free(bio);
1005 return CF_ERR_CRYPTO_OPERATION;
1006 }
1007
1008 /* Clone a cert chain object for free pkcs7 object */
1009 STACK_OF(X509) *certsChain = sk_X509_deep_copy(oriCertsChain, X509_dup, X509_free);
1010 if (certsChain == NULL) {
1011 PKCS7_free(pkcs7);
1012 BIO_free(bio);
1013 LOGE("deep clone cert chain failed.");
1014 CfPrintOpensslError();
1015 return CF_ERR_CRYPTO_OPERATION;
1016 }
1017 *certchainObj = certsChain;
1018 PKCS7_free(pkcs7);
1019 BIO_free(bio);
1020 return CF_SUCCESS;
1021 }
1022
CreateX509CertChainInner(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1023 static int32_t CreateX509CertChainInner(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1024 {
1025 int32_t ret = CF_SUCCESS;
1026 if (inData->encodingFormat == CF_FORMAT_PKCS7) {
1027 ret = CreateX509CertChainPKCS7(inData, certchainObj);
1028 } else if (inData->encodingFormat == CF_FORMAT_DER) {
1029 // create certchain from CF_FORMAT_DER
1030 ret = CreateX509CertChainDER(inData, certchainObj);
1031 } else if (inData->encodingFormat == CF_FORMAT_PEM) {
1032 // create certchain from CF_FORMAT_PEM
1033 ret = CreateX509CertChainPEM(inData, certchainObj);
1034 } else {
1035 LOGE("invalid input params");
1036 return CF_INVALID_PARAMS;
1037 }
1038
1039 if (ret != CF_SUCCESS) {
1040 LOGE("error happened");
1041 return ret;
1042 }
1043
1044 int num = sk_X509_num(*certchainObj);
1045 if (num > MAX_CERT_NUM || num == 0) {
1046 LOGE("certchain certs number :%u invalid. create certChain failed! ", num);
1047 sk_X509_pop_free(*certchainObj, X509_free);
1048 *certchainObj = NULL;
1049 return CF_INVALID_PARAMS;
1050 }
1051
1052 return CF_SUCCESS;
1053 }
1054
HcfX509CertChainByEncSpiCreate(const CfEncodingBlob * inStream,HcfX509CertChainSpi ** spi)1055 CfResult HcfX509CertChainByEncSpiCreate(const CfEncodingBlob *inStream, HcfX509CertChainSpi **spi)
1056 {
1057 int32_t ret = CF_SUCCESS;
1058 if (inStream == NULL || inStream->data == NULL || inStream->len == 0 || spi == NULL) {
1059 LOGE("HcfX509CertChainByEncSpiCreate(), Invalid params !");
1060 return CF_INVALID_PARAMS;
1061 }
1062 HcfX509CertChainOpensslImpl *certChain =
1063 (HcfX509CertChainOpensslImpl *)HcfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1064 if (certChain == NULL) {
1065 LOGE("Failed to allocate certChain spi object memory!");
1066 return CF_ERR_MALLOC;
1067 }
1068
1069 ret = CreateX509CertChainInner(inStream, &(certChain->x509CertChain));
1070 if (ret != CF_SUCCESS || certChain->x509CertChain == NULL) {
1071 CfFree(certChain);
1072 LOGE("Failed to create x509 cert chain");
1073 return CF_INVALID_PARAMS;
1074 }
1075 bool isOrder = true;
1076 ret = IsOrderCertChain(certChain->x509CertChain, &isOrder);
1077 if (ret != CF_SUCCESS) {
1078 LOGE("cert chain isOrder failed !");
1079 sk_X509_pop_free(certChain->x509CertChain, X509_free);
1080 CfFree(certChain);
1081 return ret;
1082 }
1083
1084 certChain->isOrder = isOrder;
1085 certChain->base.base.getClass = GetX509CertChainClass;
1086 certChain->base.base.destroy = DestroyX509CertChain;
1087 certChain->base.engineGetCertList = GetCertlist;
1088 certChain->base.engineValidate = Validate;
1089
1090 *spi = (HcfX509CertChainSpi *)certChain;
1091 return CF_SUCCESS;
1092 }
1093
GetCertsStack(const HcfX509CertificateArray * inCerts,STACK_OF (X509)* certsStack)1094 static CfResult GetCertsStack(const HcfX509CertificateArray *inCerts, STACK_OF(X509) * certsStack)
1095 {
1096 for (uint32_t i = 0; i < inCerts->count; ++i) {
1097 X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)inCerts->data[i]);
1098 if (cert == NULL) {
1099 LOGE("GetX509Cert from encodedBlob failed!");
1100 return CF_INVALID_PARAMS;
1101 }
1102
1103 X509 *certDup = X509_dup(cert);
1104 if (certDup == NULL) {
1105 LOGE("Memory allocation failure !\n");
1106 return CF_ERR_MALLOC;
1107 }
1108
1109 if (sk_X509_push(certsStack, certDup) <= 0) {
1110 LOGE("Memory allocation failure !\n");
1111 X509_free(certDup);
1112 return CF_ERR_MALLOC;
1113 }
1114 }
1115
1116 return CF_SUCCESS;
1117 }
1118
HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray * inCerts,HcfX509CertChainSpi ** spi)1119 CfResult HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray *inCerts, HcfX509CertChainSpi **spi)
1120 {
1121 if (spi == NULL || inCerts == NULL || inCerts->data == NULL || inCerts->count == 0 ||
1122 inCerts->count > MAX_CERT_NUM) {
1123 LOGE("Invalid params, is null !");
1124 return CF_INVALID_PARAMS;
1125 }
1126
1127 HcfX509CertChainOpensslImpl *certChain =
1128 (HcfX509CertChainOpensslImpl *)HcfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1129 if (certChain == NULL) {
1130 LOGE("Failed to allocate certChain spi object memory!");
1131 return CF_ERR_MALLOC;
1132 }
1133
1134 STACK_OF(X509) *certsStack = sk_X509_new_null();
1135 if (certsStack == NULL) {
1136 LOGE("Error creating certificate chain.");
1137 CfFree(certChain);
1138 return CF_ERR_MALLOC;
1139 }
1140
1141 CfResult res = GetCertsStack(inCerts, certsStack);
1142 if (res != CF_SUCCESS) {
1143 LOGE("Get Certs Stack failed! ");
1144 sk_X509_pop_free(certsStack, X509_free);
1145 CfFree(certChain);
1146 return res;
1147 }
1148
1149 bool isOrder = true;
1150 res = IsOrderCertChain(certsStack, &isOrder);
1151 if (res != CF_SUCCESS) {
1152 LOGE("cert chain isOrder failed !");
1153 sk_X509_pop_free(certsStack, X509_free);
1154 CfFree(certChain);
1155 return res;
1156 }
1157
1158 certChain->isOrder = isOrder;
1159 certChain->x509CertChain = certsStack;
1160 certChain->base.base.getClass = GetX509CertChainClass;
1161 certChain->base.base.destroy = DestroyX509CertChain;
1162 certChain->base.engineGetCertList = GetCertlist;
1163 certChain->base.engineValidate = Validate;
1164 *spi = (HcfX509CertChainSpi *)certChain;
1165
1166 return CF_SUCCESS;
1167 }
1168