• 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 "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