• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 #include "x509_cert_chain_openssl_ex.h"
18 
19 #include <openssl/crypto.h>
20 #include <openssl/err.h>
21 #include <openssl/evp.h>
22 #include <openssl/obj_mac.h>
23 #include <openssl/ocsp.h>
24 #include <openssl/ossl_typ.h>
25 #include <openssl/pem.h>
26 #include <openssl/pkcs12.h>
27 #include <openssl/ssl.h>
28 #include <openssl/x509.h>
29 #include <openssl/x509_vfy.h>
30 #include <openssl/x509v3.h>
31 #include <securec.h>
32 
33 #include "x509_certificate_create.h"
34 #include "certificate_openssl_class.h"
35 #include "certificate_openssl_common.h"
36 #include "cf_blob.h"
37 #include "cf_log.h"
38 #include "cf_memory.h"
39 #include "cf_result.h"
40 #include "config.h"
41 #include "fwk_class.h"
42 #include "utils.h"
43 #include "x509_cert_chain_spi.h"
44 
45 #define MAX_CERT_NUM 256 /* max certs number of a certchain */
46 #define TIMET_NUM 6
47 #define TIMET_YEAR_START 1900
48 #define TIMET_YEAR_OFFSET 100 // start time year from 1900 + 100
49 #define HTTP_TIMEOUT 10
50 #define TRY_CONNECT_TIMES 3
51 #define OCSP_CONN_MILLISECOND 5000 // millisecond
52 #define OCSP_CONN_TIMEOUT (-1)     // timeout == 0 means no timeout, < 0 means exactly one try.
53 #define HTTP_PORT "80"
54 #define HTTPS_PORT "443"
55 #define CERT_VERIFY_DIR "/etc/security/certificates"
56 
57 // helper functions
58 typedef struct {
59     int32_t errCode;
60     CfResult result;
61 } OpensslErrorToResult;
62 
63 typedef struct {
64     const EVP_MD *md;
65     X509 *subjectCert;
66     X509 *issuerCert;
67 } OcspCertIdInfo;
68 
69 typedef struct {
70     OCSP_REQUEST *req;
71     OCSP_RESPONSE *resp;
72     OcspCertIdInfo *certIdInfo;
73 } OcspLocalParam;
74 
75 typedef struct {
76     X509 *leafCert;
77     HcfRevocationCheckParam *revo;
78     char **host;
79     char **port;
80     char **path;
81     int *ssl;
82 } GetOcspUrlParams;
83 
84 static const OpensslErrorToResult ERROR_TO_RESULT_MAP[] = {
85     { X509_V_OK, CF_SUCCESS },
86     { X509_V_ERR_CERT_SIGNATURE_FAILURE, CF_ERR_CERT_SIGNATURE_FAILURE },
87     { X509_V_ERR_CERT_NOT_YET_VALID, CF_ERR_CERT_NOT_YET_VALID },
88     { X509_V_ERR_CERT_HAS_EXPIRED, CF_ERR_CERT_HAS_EXPIRED },
89     { X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, CF_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY },
90     { X509_V_ERR_KEYUSAGE_NO_CERTSIGN, CF_ERR_KEYUSAGE_NO_CERTSIGN },
91     { X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, CF_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE },
92 };
93 
ConvertOpensslErrorMsg(int32_t errCode)94 static CfResult ConvertOpensslErrorMsg(int32_t errCode)
95 {
96     for (uint32_t i = 0; i < sizeof(ERROR_TO_RESULT_MAP) / sizeof(OpensslErrorToResult); ++i) {
97         if (ERROR_TO_RESULT_MAP[i].errCode == errCode) {
98             return ERROR_TO_RESULT_MAP[i].result;
99         }
100     }
101     return CF_ERR_CRYPTO_OPERATION;
102 }
103 
DestroyX509CertChain(CfObjectBase * self)104 static void DestroyX509CertChain(CfObjectBase *self)
105 {
106     if (self == NULL || !CfIsClassMatch(self, GetX509CertChainClass())) {
107         LOGE("Invalid params!");
108         return;
109     }
110     HcfX509CertChainOpensslImpl *impl = (HcfX509CertChainOpensslImpl *)self;
111     if (impl->x509CertChain != NULL) {
112         sk_X509_pop_free(impl->x509CertChain, X509_free);
113         impl->x509CertChain = NULL;
114     }
115 
116     CfFree(impl);
117 }
118 
GetCertlist(HcfX509CertChainSpi * self,HcfX509CertificateArray * certsList)119 static CfResult GetCertlist(HcfX509CertChainSpi *self, HcfX509CertificateArray *certsList)
120 {
121     if ((self == NULL) || (certsList == NULL)) {
122         LOGE("[GetCertlist openssl] The input data is null!");
123         return CF_INVALID_PARAMS;
124     }
125     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
126         LOGE("[GetCertlist openssl] Input wrong class type!");
127         return CF_INVALID_PARAMS;
128     }
129 
130     CfResult res = CF_SUCCESS;
131     HcfX509CertChainOpensslImpl *certChain = (HcfX509CertChainOpensslImpl *)self;
132     STACK_OF(X509) *x509CertChain = certChain->x509CertChain;
133 
134     int32_t certsNum = sk_X509_num(x509CertChain);
135     if (certsNum <= 0) {
136         LOGE("sk X509 num : 0, failed!");
137         CfPrintOpensslError();
138         return CF_ERR_CRYPTO_OPERATION;
139     }
140     /* the list count has checked when create cert chain */
141     certsList->data = (HcfX509Certificate **)CfMalloc(certsNum * sizeof(HcfX509Certificate *), 0);
142     if (certsList->data == NULL) {
143         LOGE("malloc failed");
144         return CF_ERR_MALLOC;
145     }
146 
147     certsList->count = (uint32_t)certsNum;
148     for (int32_t i = 0; i < certsNum; ++i) {
149         X509 *cert = sk_X509_value(x509CertChain, i);
150         if (cert == NULL) {
151             LOGE("sk X509 value is null, failed!");
152             CfPrintOpensslError();
153             FreeCertificateArray(certsList);
154             return CF_ERR_CRYPTO_OPERATION;
155         }
156         HcfX509Certificate *x509Cert = NULL;
157         res = X509ToHcfX509Certificate(cert, &x509Cert);
158         if (res != CF_SUCCESS) {
159             LOGE("convert x509 to HcfX509Certificate failed!");
160             FreeCertificateArray(certsList);
161             return res;
162         }
163         certsList->data[i] = x509Cert;
164     }
165 
166     return res;
167 }
168 
CheckCertChainIsRevoked(const STACK_OF (X509_CRL)* crlStack,const STACK_OF (X509)* certChain)169 static CfResult CheckCertChainIsRevoked(const STACK_OF(X509_CRL) *crlStack, const STACK_OF(X509) *certChain)
170 {
171     int cerNum = sk_X509_num(certChain);
172     if (cerNum == 0) {
173         LOGE("sk X509 num : 0, failed!");
174         CfPrintOpensslError();
175         return CF_ERR_CRYPTO_OPERATION;
176     }
177 
178     int crlNum = sk_X509_CRL_num(crlStack); // allow crlNum : 0, no crl
179     for (int i = 0; i < crlNum; ++i) {
180         X509_CRL *crl = sk_X509_CRL_value(crlStack, i);
181         if (crl == NULL) {
182             LOGE("sk X509 CRL value is null, failed!");
183             CfPrintOpensslError();
184             return CF_ERR_CRYPTO_OPERATION;
185         }
186 
187         /* crl in certcrlcollection object is not null. */
188         for (int j = 0; j < cerNum; ++j) {
189             X509 *cert = sk_X509_value(certChain, j);
190             if (cert == NULL) {
191                 LOGE("sk X509 value is null, failed!");
192                 CfPrintOpensslError();
193                 return CF_ERR_CRYPTO_OPERATION;
194             }
195 
196             X509_REVOKED *rev = NULL;
197             int32_t res = X509_CRL_get0_by_cert(crl, &rev, cert);
198             if (res != 0) {
199                 LOGE("cert is revoked.");
200                 return CF_ERR_CRYPTO_OPERATION;
201             }
202         }
203     }
204 
205     return CF_SUCCESS;
206 }
207 
SetVerifyParams(X509_STORE * store,X509 * mostTrustCert)208 static CfResult SetVerifyParams(X509_STORE *store, X509 *mostTrustCert)
209 {
210     if (X509_STORE_add_cert(store, mostTrustCert) != CF_OPENSSL_SUCCESS) {
211         LOGE("add cert to store failed!");
212         CfPrintOpensslError();
213         return CF_ERR_CRYPTO_OPERATION;
214     }
215 
216     unsigned long flags = 0;
217     if (!CheckIsSelfSigned(mostTrustCert)) {
218         flags |= X509_V_FLAG_PARTIAL_CHAIN; // is not self signed
219         LOGI("SetVerifyFlag() is a partitial chain, not self signed!");
220     }
221 
222     /* date has verified before. */
223     flags |= X509_V_FLAG_NO_CHECK_TIME;
224     X509_STORE_set_flags(store, flags);
225 
226     return CF_SUCCESS;
227 }
228 
VerifyCertChain(X509 * mostTrustCert,STACK_OF (X509)* x509CertChain)229 static CfResult VerifyCertChain(X509 *mostTrustCert, STACK_OF(X509) *x509CertChain)
230 {
231     if (mostTrustCert == NULL || x509CertChain == NULL) {
232         LOGE("invalid params!");
233         return CF_INVALID_PARAMS;
234     }
235 
236     X509 *cert = sk_X509_value(x509CertChain, 0); // leaf cert
237     if (cert == NULL) {
238         CfPrintOpensslError();
239         return CF_ERR_CRYPTO_OPERATION;
240     }
241 
242     X509_STORE_CTX *ctx = X509_STORE_CTX_new();
243     if (ctx == NULL) {
244         CfPrintOpensslError();
245         return CF_ERR_CRYPTO_OPERATION;
246     }
247 
248     X509_STORE *store = X509_STORE_new();
249     if (store == NULL) {
250         LOGE("verify cert chain malloc failed!");
251         X509_STORE_CTX_free(ctx);
252         CfPrintOpensslError();
253         return CF_ERR_CRYPTO_OPERATION;
254     }
255 
256     CfResult res = SetVerifyParams(store, mostTrustCert);
257     if (res == CF_SUCCESS) {
258         if (X509_STORE_CTX_init(ctx, store, cert, x509CertChain) != CF_OPENSSL_SUCCESS) {
259             LOGE("init verify ctx failed!");
260             X509_STORE_CTX_free(ctx);
261             X509_STORE_free(store);
262             CfPrintOpensslError();
263             return CF_ERR_CRYPTO_OPERATION;
264         }
265 
266         if (X509_verify_cert(ctx) == CF_OPENSSL_SUCCESS) {
267             res = CF_SUCCESS;
268         } else {
269             int32_t errCode = X509_STORE_CTX_get_error(ctx);
270             const char *pChError = X509_verify_cert_error_string(errCode);
271             LOGE("Failed to verify cert, openssl openssl error code = %{public}d, error msg:%{public}s.",
272                 errCode, pChError);
273             res = ConvertOpensslErrorMsg(errCode);
274         }
275     }
276 
277     X509_STORE_CTX_free(ctx); // Cleanup: Free the allocated memory and release resources.
278     X509_STORE_free(store);
279     return res;
280 }
281 
ConvertByteArrayToPubKey(const uint8_t * pubKeyBytes,size_t len)282 static EVP_PKEY *ConvertByteArrayToPubKey(const uint8_t *pubKeyBytes, size_t len)
283 {
284     if (pubKeyBytes == NULL) {
285         LOGE("ConvertByteArrayToPubkey invalid params.");
286         return NULL;
287     }
288     EVP_PKEY *pubKey = d2i_PUBKEY(NULL, &pubKeyBytes, len); // pubkey DER format.
289     if (pubKey == NULL) {
290         LOGE("d2i_PUBKEY() failed!");
291         CfPrintOpensslError();
292         return NULL;
293     }
294 
295     return pubKey;
296 }
297 
CheckOthersInTrustAnchor(const HcfX509TrustAnchor * anchor,X509 * rootCert,bool * checkResult)298 static CfResult CheckOthersInTrustAnchor(const HcfX509TrustAnchor *anchor, X509 *rootCert, bool *checkResult)
299 {
300     *checkResult = false;
301     if (anchor->CAPubKey == NULL) {
302         return CF_SUCCESS;
303     }
304 
305     // 1. validate public key of the root CA.
306     EVP_PKEY *pubKey = ConvertByteArrayToPubKey(anchor->CAPubKey->data, anchor->CAPubKey->size);
307     if (pubKey == NULL) {
308         LOGE("ConvertByteArrayToPubKey failed!");
309         return CF_ERR_CRYPTO_OPERATION;
310     }
311     /* pubkey in trust anchor may be the pubkey of self or of its upper level cert. */
312     bool matchUpperPubKey = false;
313     if (CheckSelfPubkey(rootCert, pubKey) != CF_SUCCESS) {
314         matchUpperPubKey = (X509_verify(rootCert, pubKey) == CF_OPENSSL_SUCCESS);
315         if (!matchUpperPubKey) {
316             LOGE("verify pubkey in trust anchor failed!");
317             CfPrintOpensslError();
318             EVP_PKEY_free(pubKey);
319             return CF_SUCCESS;
320         }
321     }
322 
323     /* If pubkey is of self cert, the subject should be of self cert.
324      * If pubkey is of upper level cert, the subject should be of uppoer level cert (i.e. the issuer of self cert).
325      */
326     if (anchor->CASubject != NULL) {
327         // 2. compare subject name of root CA.
328         X509NameType nameType = NAME_TYPE_SUBJECT;
329         if (matchUpperPubKey) {
330             nameType = NAME_TYPE_ISSUER;
331         }
332         bool compareSubjectFlag = false;
333         CfResult res = CompareNameObject(rootCert, anchor->CASubject, nameType, &compareSubjectFlag);
334         if (res != CF_SUCCESS) {
335             LOGE("verify subject in trust anchor failed!");
336             EVP_PKEY_free(pubKey);
337             return res;
338         }
339         LOGI("verify subject in trust anchor result: %{public}d", compareSubjectFlag);
340         *checkResult = compareSubjectFlag;
341     } else {
342         *checkResult = true;
343     }
344     EVP_PKEY_free(pubKey);
345     return CF_SUCCESS;
346 }
347 
GetTrustAnchor(const HcfX509TrustAnchor * trustAnchors,X509 * rootCert,X509 ** mostTrustCertOut)348 static CfResult GetTrustAnchor(const HcfX509TrustAnchor *trustAnchors, X509 *rootCert, X509 **mostTrustCertOut)
349 {
350     if (trustAnchors == NULL || rootCert == NULL || mostTrustCertOut == NULL) {
351         LOGE("GetTrustAnchorCert() invalid params!");
352         return CF_INVALID_PARAMS;
353     }
354 
355     if (trustAnchors->CACert != NULL) {
356         X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)trustAnchors->CACert);
357         if (cert == NULL) {
358             LOGE("GetTrustAnchorCert() cert is null.");
359             return CF_INVALID_PARAMS;
360         }
361 
362         X509_NAME *subjectName = X509_get_subject_name(cert);
363         if (subjectName == NULL) {
364             CfPrintOpensslError();
365             return CF_ERR_CRYPTO_OPERATION;
366         }
367         X509_NAME *subjectRoot = X509_get_subject_name(rootCert);
368         if (subjectRoot == NULL) {
369             CfPrintOpensslError();
370             return CF_ERR_CRYPTO_OPERATION;
371         }
372         EVP_PKEY *pubKey = X509_get_pubkey(cert); // validate public key of the trustAnchor CACert. X509_check_issued
373         if (pubKey == NULL) {
374             LOGE("X509_get_pubkey() failed!");
375             CfPrintOpensslError();
376             return CF_ERR_CRYPTO_OPERATION;
377         }
378         if (X509_verify(rootCert, pubKey) != CF_OPENSSL_SUCCESS && X509_NAME_cmp(subjectName, subjectRoot)) {
379             LOGE("X509_verify() failed!");
380             CfPrintOpensslError();
381             EVP_PKEY_free(pubKey);
382             return CF_SUCCESS; // continue to try next trustAnchor
383         }
384         EVP_PKEY_free(pubKey);
385         *mostTrustCertOut = cert;
386         return CF_SUCCESS;
387     }
388 
389     bool checkResult = false;
390     CfResult res = CheckOthersInTrustAnchor(trustAnchors, rootCert, &checkResult);
391     if (res != CF_SUCCESS) {
392         LOGE("CheckOthersInTrustAnchor failed.");
393         return res;
394     }
395 
396     if (checkResult) {
397         *mostTrustCertOut = rootCert;
398     }
399     return CF_SUCCESS;
400 }
401 
FreeTrustAnchorData(HcfX509TrustAnchor * trustAnchor)402 static void FreeTrustAnchorData(HcfX509TrustAnchor *trustAnchor)
403 {
404     if (trustAnchor == NULL) {
405         return;
406     }
407     CfBlobFree(&trustAnchor->CAPubKey);
408     CfBlobFree(&trustAnchor->CASubject);
409     CfObjDestroy(trustAnchor->CACert);
410     trustAnchor->CACert = NULL;
411 }
412 
CopyHcfX509TrustAnchor(const HcfX509TrustAnchor * inputAnchor,HcfX509TrustAnchor * outAnchor)413 static CfResult CopyHcfX509TrustAnchor(const HcfX509TrustAnchor *inputAnchor, HcfX509TrustAnchor *outAnchor)
414 {
415     HcfX509Certificate *CACert = inputAnchor->CACert;
416     CfBlob *CAPubKey = inputAnchor->CAPubKey;
417     CfBlob *CASubject = inputAnchor->CASubject;
418     CfBlob *nameConstraints = inputAnchor->nameConstraints;
419     CfResult res = CF_SUCCESS;
420     if (CACert != NULL) {
421         HcfX509CertCreateFunc func = GetHcfX509CertCreateFunc();
422         if (func == NULL) {
423             LOGE("HcfX509CertificateCreate is null.");
424             return CF_NULL_POINTER;
425         }
426         CfEncodingBlob encodedByte = { NULL, 0, CF_FORMAT_DER };
427         CACert->base.getEncoded((HcfCertificate *)CACert, &encodedByte);
428         res = func(&encodedByte, &outAnchor->CACert);
429         CF_FREE_PTR(encodedByte.data);
430         if (res != CF_SUCCESS) {
431             LOGE("HcfX509CertificateCreate fail, res : %{public}d!", res);
432             return CF_ERR_MALLOC;
433         }
434     }
435     if (CAPubKey != NULL) {
436         res = DeepCopyBlobToBlob(CAPubKey, &outAnchor->CAPubKey);
437         if (res != CF_SUCCESS) {
438             LOGE("DeepCopyDataToBlob failed");
439             FreeTrustAnchorData(outAnchor);
440             return res;
441         }
442     }
443     if (CASubject != NULL) {
444         res = DeepCopyBlobToBlob(CASubject, &outAnchor->CASubject);
445         if (res != CF_SUCCESS) {
446             LOGE("DeepCopyDataToBlob failed");
447             FreeTrustAnchorData(outAnchor);
448             return res;
449         }
450     }
451     if (nameConstraints != NULL) {
452         res = DeepCopyBlobToBlob(nameConstraints, &outAnchor->nameConstraints);
453         if (res != CF_SUCCESS) {
454             LOGE("DeepCopyDataToBlob failed");
455             FreeTrustAnchorData(outAnchor);
456             return res;
457         }
458     }
459 
460     return res;
461 }
462 
FillValidateResult(HcfX509TrustAnchor * inputAnchor,X509 * cert,HcfX509CertChainValidateResult * result)463 static CfResult FillValidateResult(HcfX509TrustAnchor *inputAnchor, X509 *cert, HcfX509CertChainValidateResult *result)
464 {
465     if (inputAnchor == NULL || cert == NULL) {
466         LOGE("FillValidateResult() invalidate params!");
467         return CF_INVALID_PARAMS;
468     }
469     CfResult res = CF_SUCCESS;
470     HcfX509Certificate *entityCert = NULL;
471     res = X509ToHcfX509Certificate(cert, &entityCert);
472     if (res != CF_SUCCESS) {
473         LOGE("X509ToHcfX509Certificate() failed!");
474         return res;
475     }
476 
477     result->trustAnchor = inputAnchor;
478     result->entityCert = entityCert;
479     return res;
480 }
481 
ParseX509CRL(const CfEncodingBlob * inStream)482 static X509_CRL *ParseX509CRL(const CfEncodingBlob *inStream)
483 {
484     if ((inStream->data == NULL) || (inStream->len <= 0)) {
485         LOGE("Invalid params!");
486         return NULL;
487     }
488     BIO *bio = BIO_new_mem_buf(inStream->data, inStream->len);
489     if (bio == NULL) {
490         LOGE("bio get null!");
491         CfPrintOpensslError();
492         return NULL;
493     }
494     X509_CRL *crlOut = NULL;
495     switch (inStream->encodingFormat) {
496         case CF_FORMAT_DER:
497             crlOut = d2i_X509_CRL_bio(bio, NULL);
498             break;
499         case CF_FORMAT_PEM:
500             crlOut = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
501             break;
502         default:
503             LOGE("Not support format!");
504             break;
505     }
506     BIO_free_all(bio);
507     if (crlOut == NULL) {
508         LOGE("Parse X509 CRL fail!");
509         CfPrintOpensslError();
510         return NULL;
511     }
512     return crlOut;
513 }
514 
PushCrl2Stack(HcfX509CrlArray * crlArray,STACK_OF (X509_CRL)* outCrls)515 static CfResult PushCrl2Stack(HcfX509CrlArray *crlArray, STACK_OF(X509_CRL) *outCrls)
516 {
517     CfResult res = CF_SUCCESS;
518     HcfX509Crl *x509Crl = NULL;
519     X509_CRL *crl = NULL;
520     for (uint32_t i = 0; i < crlArray->count; i++) {
521         CfEncodingBlob encodedBlob = { 0 };
522         x509Crl = crlArray->data[i];
523         res = x509Crl->getEncoded(x509Crl, &encodedBlob);
524         if (res != CF_SUCCESS) {
525             LOGE("Failed to getEncoded of crl!");
526             return res;
527         }
528 
529         crl = ParseX509CRL(&encodedBlob);
530         CfFree(encodedBlob.data);
531         encodedBlob.data = NULL;
532         if (crl == NULL) {
533             LOGE("Failed to Parse x509 CRL!");
534             return CF_INVALID_PARAMS;
535         }
536         if (sk_X509_CRL_push(outCrls, crl) == 0) {
537             LOGE("sk_X509_CRL_push failed!");
538             X509_CRL_free(crl);
539             return CF_ERR_CRYPTO_OPERATION;
540         }
541     }
542     return res;
543 }
544 
GetX509Crls(const HcfCertCRLCollectionArray * certCRLCollections,STACK_OF (X509_CRL)* outCrls)545 static CfResult GetX509Crls(const HcfCertCRLCollectionArray *certCRLCollections, STACK_OF(X509_CRL) *outCrls)
546 {
547     if (certCRLCollections == NULL) { // certCRLCollection is not force params for verify certchain
548         LOGI("certcrlcollections is null!");
549         return CF_SUCCESS;
550     }
551 
552     CfResult res = CF_SUCCESS;
553     HcfX509CrlArray *crlArray = NULL;
554     HcfCertCrlCollection *crlCollection = NULL;
555     for (uint32_t i = 0; i < certCRLCollections->count; i++) {
556         crlCollection = certCRLCollections->data[i];
557         res = crlCollection->getCRLs(crlCollection, &crlArray);
558         if (res != CF_SUCCESS) {
559             LOGE("getCRLs() from CertCrlCollection failed!");
560             /* Warning: free outCrls in outside */
561             return res;
562         }
563         if (crlArray->count == 0) {
564             LOGI("crls array is empty.");
565             continue;
566         }
567         res = PushCrl2Stack(crlArray, outCrls);
568         if (res != CF_SUCCESS) {
569             LOGE("push crls to stack failed!");
570             /* Warning: free outCrls in outside */
571             return res;
572         }
573     }
574 
575     return res;
576 }
577 
ValidateCrlLocal(const HcfCertCRLCollectionArray * collectionArr,STACK_OF (X509)* x509CertChain)578 static CfResult ValidateCrlLocal(const HcfCertCRLCollectionArray *collectionArr, STACK_OF(X509) *x509CertChain)
579 {
580     STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
581     if (crlStack == NULL) {
582         LOGE("sk X509 CRL new null failed!");
583         CfPrintOpensslError();
584         return CF_ERR_CRYPTO_OPERATION;
585     }
586 
587     CfResult res = GetX509Crls(collectionArr, crlStack);
588     if (res != CF_SUCCESS) {
589         LOGE("GetX509Crls failed");
590         sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
591         return res;
592     }
593 
594     if (sk_X509_CRL_num(crlStack) == 0) {
595         LOGI("crls count is 0");
596         sk_X509_CRL_free(crlStack);
597         return CF_SUCCESS;
598     }
599     res = CheckCertChainIsRevoked(crlStack, x509CertChain);
600     sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
601     return res;
602 }
603 
ValidateNC(STACK_OF (X509)* x509CertChain,CfBlob * nameConstraints)604 static CfResult ValidateNC(STACK_OF(X509) *x509CertChain, CfBlob *nameConstraints)
605 {
606     if (nameConstraints == NULL) {
607         LOGI("NameConstraints from js is null!");
608         return CF_SUCCESS;
609     }
610 
611     const unsigned char *p = nameConstraints->data;
612     NAME_CONSTRAINTS *nc =
613         (NAME_CONSTRAINTS *)ASN1_item_d2i(NULL, &p, nameConstraints->size, ASN1_ITEM_rptr(NAME_CONSTRAINTS));
614     if (nc == NULL) {
615         LOGE("Get nameConstraints from js failed!");
616         return CF_INVALID_PARAMS;
617     }
618 
619     CfResult res = CF_SUCCESS;
620     for (int i = 0; i < sk_X509_num(x509CertChain); i++) {
621         X509 *cert = sk_X509_value(x509CertChain, i);
622         if (cert == NULL) {
623             LOGE("Get cert from stack to check nameConstraints failed!");
624             res = CF_INVALID_PARAMS;
625             break;
626         }
627         if (CheckIsLeafCert(cert) && !CheckIsSelfSigned(cert)) {
628             if (NAME_CONSTRAINTS_check(cert, nc) != X509_V_OK) {
629                 LOGE("Check nameConstraints failed!");
630                 res = CF_INVALID_PARAMS;
631                 break;
632             }
633         }
634     }
635 
636     NAME_CONSTRAINTS_free(nc);
637     return res;
638 }
639 
ValidateTrustAnchor(const HcfX509TrustAnchorArray * trustAnchorsArray,X509 * rootCert,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchorResult)640 static CfResult ValidateTrustAnchor(const HcfX509TrustAnchorArray *trustAnchorsArray, X509 *rootCert,
641     STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchorResult)
642 {
643     CfResult res = CF_SUCCESS;
644     for (uint32_t i = 0; i < trustAnchorsArray->count; ++i) {
645         X509 *mostTrustAnchorCert = NULL;
646         HcfX509TrustAnchor *trustAnchor = trustAnchorsArray->data[i];
647         res = GetTrustAnchor(trustAnchor, rootCert, &mostTrustAnchorCert);
648         if (res != CF_SUCCESS) {
649             LOGE("Get trust anchor cert failed, try next trustAnchor.");
650             return res;
651         }
652         if (mostTrustAnchorCert == NULL) {
653             LOGE("most trust anchor cert is null.");
654             res = CF_INVALID_PARAMS; /* if validate trust anchor list failed, return the last error. */
655             continue;
656         }
657 
658         res = VerifyCertChain(mostTrustAnchorCert, x509CertChain);
659         if (res != CF_SUCCESS) { // verify the data & crl list of certchain
660             LOGI("verify one trustanchor failed, try next trustAnchor.");
661             continue;
662         }
663 
664         res = ValidateNC(x509CertChain, trustAnchor->nameConstraints);
665         if (res != CF_SUCCESS) {
666             LOGI("verify nameConstraints failed, try next trustAnchor.");
667             continue;
668         }
669         res = CopyHcfX509TrustAnchor(trustAnchor, trustAnchorResult);
670         if (res != CF_SUCCESS) {
671             LOGE("CopyHcfX509TrustAnchor() failed!");
672             return res;
673         }
674         break;
675     }
676 
677     return res;
678 }
679 
GetDpUrl(DIST_POINT * dp)680 static const char *GetDpUrl(DIST_POINT *dp)
681 {
682     GENERAL_NAMES *gens = NULL;
683     GENERAL_NAME *gen = NULL;
684     ASN1_STRING *url = NULL;
685 
686     if (dp == NULL || dp->distpoint == NULL || dp->distpoint->type != 0) {
687         return NULL;
688     }
689     gens = dp->distpoint->name.fullname;
690     if (gens == NULL) {
691         return NULL;
692     }
693     for (int32_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
694         gen = sk_GENERAL_NAME_value(gens, i);
695         if (gen == NULL) {
696             continue;
697         }
698         int gtype;
699         url = GENERAL_NAME_get0_value(gen, &gtype);
700         if (url == NULL) {
701             continue;
702         }
703         if (gtype == GEN_URI && ASN1_STRING_length(url) > GEN_URI) {
704             const char *uptr = (const char *)ASN1_STRING_get0_data(url);
705             if (CfIsHttp(uptr)) {
706                 // can/should not use HTTPS here
707                 return uptr;
708             }
709         }
710     }
711     return NULL;
712 }
713 
LoadCrlDp(STACK_OF (DIST_POINT)* crldp)714 static X509_CRL *LoadCrlDp(STACK_OF(DIST_POINT) *crldp)
715 {
716     const char *urlptr = NULL;
717     for (int i = 0; i < sk_DIST_POINT_num(crldp); i++) {
718         DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
719         urlptr = GetDpUrl(dp);
720         if (urlptr != NULL) {
721             return X509_CRL_load_http(urlptr, NULL, NULL, HTTP_TIMEOUT);
722         }
723     }
724     return NULL;
725 }
726 
GetCrlFromCert(const HcfX509CertChainValidateParams * params,X509 * x509)727 static X509_CRL *GetCrlFromCert(const HcfX509CertChainValidateParams *params, X509 *x509)
728 {
729     STACK_OF(DIST_POINT) *crlStack = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL);
730     if (crlStack != NULL) {
731         X509_CRL *crl = LoadCrlDp(crlStack);
732         sk_DIST_POINT_pop_free(crlStack, DIST_POINT_free);
733         if (crl != NULL) {
734             return crl;
735         }
736     }
737 
738     if (params->revocationCheckParam->crlDownloadURI != NULL &&
739         params->revocationCheckParam->crlDownloadURI->data != NULL) {
740         char *url = (char *)params->revocationCheckParam->crlDownloadURI->data;
741         if (CfIsUrlValid(url)) {
742             return X509_CRL_load_http(url, NULL, NULL, HTTP_TIMEOUT);
743         }
744     }
745 
746     return NULL;
747 }
748 
ValidateCrlOnline(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain)749 static CfResult ValidateCrlOnline(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain)
750 {
751     X509 *x509 = sk_X509_value(x509CertChain, 0);
752     if (x509 == NULL) {
753         LOGE("Get leaf cert failed!");
754         return CF_INVALID_PARAMS;
755     }
756     X509_CRL *crl = GetCrlFromCert(params, x509);
757     if (crl == NULL) {
758         LOGE("Get crl online is null!");
759         return CF_ERR_CRYPTO_OPERATION;
760     }
761 
762     STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
763     if (crlStack == NULL) {
764         LOGE("Create crl stack failed!");
765         X509_CRL_free(crl);
766         CfPrintOpensslError();
767         return CF_ERR_CRYPTO_OPERATION;
768     }
769     if (sk_X509_CRL_push(crlStack, crl) == 0) {
770         LOGE("Push crl stack failed!");
771         X509_CRL_free(crl);
772         CfPrintOpensslError();
773         sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
774         return CF_ERR_CRYPTO_OPERATION;
775     }
776     if (CheckCertChainIsRevoked(crlStack, x509CertChain) != CF_SUCCESS) {
777         LOGE("Certchain is revoked, verify failed!");
778         sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
779         return CF_ERR_CRYPTO_OPERATION;
780     }
781 
782     sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
783     return CF_SUCCESS;
784 }
785 
ContainsOption(HcfRevChkOpArray * options,HcfRevChkOption op)786 static bool ContainsOption(HcfRevChkOpArray *options, HcfRevChkOption op)
787 {
788     if (options == NULL || options->data == NULL) {
789         return false;
790     }
791 
792     for (uint32_t i = 0; i < options->count; i++) {
793         if (options->data[i] == op) {
794             return true;
795         }
796     }
797     return false;
798 }
799 
VerifyOcspSigner(OCSP_BASICRESP * bs,STACK_OF (X509)* certChain,X509 * cert)800 static CfResult VerifyOcspSigner(OCSP_BASICRESP *bs, STACK_OF(X509) *certChain, X509 *cert)
801 {
802     if (cert == NULL) {
803         LOGE("Input data cert is null!");
804         return CF_INVALID_PARAMS;
805     }
806     X509_STORE *store = X509_STORE_new();
807     if (store == NULL) {
808         LOGE("New x509 store failed!");
809         return CF_ERR_CRYPTO_OPERATION;
810     }
811     CfResult res = SetVerifyParams(store, cert);
812     if (res != CF_SUCCESS) {
813         LOGE("Set verify params failed!");
814         X509_STORE_free(store);
815         return res;
816     }
817 
818     if (OCSP_basic_verify(bs, certChain, store, 0) != 1) {
819         LOGE("OCSP basic verify failed!");
820         res = CF_ERR_CERT_SIGNATURE_FAILURE;
821     }
822     X509_STORE_free(store);
823 
824     return res;
825 }
826 
ParseResp(OCSP_BASICRESP * bs,OcspCertIdInfo * certIdInfo)827 static CfResult ParseResp(OCSP_BASICRESP *bs, OcspCertIdInfo *certIdInfo)
828 {
829     int ocspStatus;
830     ASN1_GENERALIZEDTIME *thisUpdate = NULL;
831     ASN1_GENERALIZEDTIME *nextUpdate = NULL;
832     CfResult res = CF_ERR_CRYPTO_OPERATION;
833 
834     OCSP_CERTID *certId = OCSP_cert_to_id(certIdInfo->md, certIdInfo->subjectCert, certIdInfo->issuerCert);
835     if (certId == NULL) {
836         LOGE("Unable to create certId.");
837         return CF_ERR_CRYPTO_OPERATION;
838     }
839 
840     if (OCSP_resp_find_status(bs, certId, &ocspStatus, NULL, NULL, &thisUpdate, &nextUpdate) == 1) {
841         switch (ocspStatus) {
842             case V_OCSP_CERTSTATUS_GOOD:
843                 LOGI("The OCSP status is [V_OCSP_CERTSTATUS_GOOD]!");
844                 res = CF_SUCCESS;
845                 break;
846             case V_OCSP_CERTSTATUS_REVOKED:
847                 LOGE("The OCSP status is [V_OCSP_CERTSTATUS_REVOKED]!");
848                 break;
849             case V_OCSP_CERTSTATUS_UNKNOWN:
850             default:
851                 LOGE("!The OCSP status is [UNKNOWN]!");
852                 break;
853         }
854     }
855     OCSP_CERTID_free(certId);
856     return res;
857 }
858 
ValidateOcspLocalGetTrustCert(STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params,HcfRevocationCheckParam * revo,X509 ** trustCert)859 static void ValidateOcspLocalGetTrustCert(STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchor,
860     const HcfX509CertChainValidateParams *params, HcfRevocationCheckParam *revo, X509 **trustCert)
861 {
862     if (revo->ocspResponderCert != NULL) {
863         *trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(params->revocationCheckParam->ocspResponderCert));
864     } else if (trustAnchor->CACert != NULL) {
865         *trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(trustAnchor->CACert));
866     } else {
867         *trustCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
868     }
869 }
870 
ValidateOcspLocal(OcspLocalParam localParam,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)871 static CfResult ValidateOcspLocal(OcspLocalParam localParam, STACK_OF(X509) *x509CertChain,
872     HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
873 {
874     int i;
875     X509 *trustCert = NULL;
876     OCSP_RESPONSE *rsp = NULL;
877     if (localParam.certIdInfo == NULL) {
878         LOGE("The input data is null!");
879         return CF_INVALID_PARAMS;
880     }
881     HcfRevocationCheckParam *revo = params->revocationCheckParam;
882     if (localParam.resp == NULL && revo->ocspResponses != NULL) {
883         const unsigned char *p = revo->ocspResponses->data;
884         rsp = d2i_OCSP_RESPONSE(NULL, &p, revo->ocspResponses->size);
885         localParam.resp = rsp;
886     }
887     if (localParam.resp == NULL) {
888         LOGE("The input data is null!");
889         return CF_ERR_CRYPTO_OPERATION;
890     }
891     if (OCSP_response_status(localParam.resp) != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
892         LOGE("The resp status is not success!");
893         OCSP_RESPONSE_free(rsp);
894         return CF_ERR_CRYPTO_OPERATION;
895     }
896     OCSP_BASICRESP *bs = OCSP_response_get1_basic(localParam.resp);
897     OCSP_RESPONSE_free(rsp);
898     if (bs == NULL) {
899         LOGE("Error parsing response!");
900         return CF_ERR_CRYPTO_OPERATION;
901     }
902     if (localParam.req != NULL && ((i = OCSP_check_nonce(localParam.req, bs)) <= 0)) {
903         if (i == -1) {
904             LOGW("No nonce in response!");
905         } else {
906             LOGE("Nonce Verify error!");
907             OCSP_BASICRESP_free(bs);
908             return CF_ERR_CRYPTO_OPERATION;
909         }
910     }
911 
912     ValidateOcspLocalGetTrustCert(x509CertChain, trustAnchor, params, revo, &trustCert);
913     CfResult res = VerifyOcspSigner(bs, x509CertChain, trustCert);
914     if (res != CF_SUCCESS) {
915         LOGE("VerifySinger failed!");
916         OCSP_BASICRESP_free(bs);
917         return res;
918     }
919     res = ParseResp(bs, localParam.certIdInfo);
920     OCSP_BASICRESP_free(bs);
921     return res;
922 }
923 
SendReqBioCustom(BIO * bio,const char * host,const char * path,OCSP_REQUEST * req)924 static OCSP_RESPONSE *SendReqBioCustom(BIO *bio, const char *host, const char *path, OCSP_REQUEST *req)
925 {
926     OCSP_RESPONSE *resp = NULL;
927     OCSP_REQ_CTX *ctx;
928 
929     ctx = OCSP_sendreq_new(bio, path, NULL, -1);
930     if (ctx == NULL) {
931         LOGE("Create ocsp req ctx failed!");
932         return NULL;
933     }
934     if (!OCSP_REQ_CTX_add1_header(ctx, "Accept", "application/ocsp-response")) {
935         OCSP_REQ_CTX_free(ctx);
936         return NULL;
937     }
938     if (!OCSP_REQ_CTX_add1_header(ctx, "Host", host)) {
939         OCSP_REQ_CTX_free(ctx);
940         return NULL;
941     }
942     if (!OCSP_REQ_CTX_set1_req(ctx, req)) {
943         OCSP_REQ_CTX_free(ctx);
944         return NULL;
945     }
946     int ret;
947     int tryNum = TRY_CONNECT_TIMES;
948     do {
949         ret = OCSP_sendreq_nbio(&resp, ctx);
950         tryNum--;
951     } while ((ret == -1) && BIO_should_retry(bio) && tryNum != 0);
952     OCSP_REQ_CTX_free(ctx);
953     if (ret) {
954         return resp;
955     }
956     return NULL;
957 }
958 
ConnectToServer(BIO * bio,int tryNum)959 static bool ConnectToServer(BIO *bio, int tryNum)
960 {
961     int ret = 0;
962     int num = tryNum;
963     do {
964         ret = BIO_do_connect_retry(bio, OCSP_CONN_TIMEOUT, OCSP_CONN_MILLISECOND);
965         if (ret == 1) {
966             break;
967         } else if (ret <= 0) {
968             LOGE("OCSP connecte service failed.");
969             CfPrintOpensslError();
970             if (BIO_should_retry(bio)) {
971                 LOGI("Try to connect service again, [%{public}d]st.", num);
972                 num--;
973             } else {
974                 break;
975             }
976         }
977     } while (ret <= 0 && num != 0);
978     return (ret == 1 ? true : false);
979 }
980 
GetOcspUrl(GetOcspUrlParams * params)981 static CfResult GetOcspUrl(GetOcspUrlParams *params)
982 {
983     char *url = NULL;
984 
985     if (params->leafCert == NULL) {
986         LOGE("The input param invalid.");
987         return CF_INVALID_PARAMS;
988     }
989     STACK_OF(OPENSSL_STRING) *ocspList = X509_get1_ocsp(params->leafCert);
990     if (ocspList != NULL && sk_OPENSSL_STRING_num(ocspList) > 0) {
991         url = sk_OPENSSL_STRING_value(ocspList, 0);
992     }
993 
994     if (url == NULL) {
995         if (params->revo->ocspResponderURI == NULL || params->revo->ocspResponderURI->data == NULL) {
996             LOGE("Unable to get url.");
997             return CF_ERR_CRYPTO_OPERATION;
998         }
999     }
1000     char *urlValiable = (url == NULL) ? (char *)(params->revo->ocspResponderURI->data) : url;
1001     if (!CfIsUrlValid(urlValiable)) {
1002         LOGE("Invalid url.");
1003         return CF_INVALID_PARAMS;
1004     }
1005     if (!OCSP_parse_url(urlValiable, params->host, params->port, params->path, params->ssl)) {
1006         LOGE("Unable to parse url.");
1007         return CF_ERR_CRYPTO_OPERATION;
1008     }
1009     return CF_SUCCESS;
1010 }
1011 
SetRequestData(HcfRevocationCheckParam * revo,OCSP_REQUEST * req,OcspCertIdInfo * certIdInfo)1012 static CfResult SetRequestData(HcfRevocationCheckParam *revo, OCSP_REQUEST *req, OcspCertIdInfo *certIdInfo)
1013 {
1014     OCSP_CERTID *certId = OCSP_cert_to_id(certIdInfo->md, certIdInfo->subjectCert, certIdInfo->issuerCert);
1015     if (certId == NULL) {
1016         LOGE("Unable to create certId.");
1017         return CF_ERR_CRYPTO_OPERATION;
1018     }
1019 
1020     if (OCSP_request_add0_id(req, certId) == NULL) {
1021         LOGE("Unable to add certId to req.");
1022         OCSP_CERTID_free(certId);
1023         return CF_INVALID_PARAMS;
1024     }
1025 
1026     if (revo->ocspRequestExtension != NULL) {
1027         for (size_t i = 0; i < revo->ocspRequestExtension->count; i++) {
1028             const unsigned char *p = revo->ocspRequestExtension->data[i].data;
1029             X509_EXTENSION *ext = d2i_X509_EXTENSION(NULL, &p, revo->ocspRequestExtension->data[i].size);
1030             if (ext == NULL) {
1031                 return CF_INVALID_PARAMS;
1032             }
1033             if (!OCSP_REQUEST_add_ext(req, ext, -1)) {
1034                 X509_EXTENSION_free(ext);
1035                 return CF_ERR_CRYPTO_OPERATION;
1036             }
1037             X509_EXTENSION_free(ext);
1038             ext = NULL;
1039         }
1040     }
1041 
1042     return CF_SUCCESS;
1043 }
1044 
CreateConnectBio(char * host,char * port,int ssl)1045 static BIO *CreateConnectBio(char *host, char *port, int ssl)
1046 {
1047     BIO *bio = NULL;
1048     if (ssl == 1) {
1049         SSL_library_init();
1050         SSL_load_error_strings();
1051         OpenSSL_add_all_algorithms();
1052 
1053         SSL_CTX *sslCtx = SSL_CTX_new(TLS_client_method());
1054         if (sslCtx == NULL) {
1055             return NULL;
1056         }
1057         bio = BIO_new_ssl_connect(sslCtx);
1058         if (bio == NULL) {
1059             LOGE("bio is null.");
1060             SSL_CTX_free(sslCtx);
1061             return NULL;
1062         }
1063         if (BIO_set_conn_hostname(bio, host) != 1) {
1064             LOGE("Set host name failed.");
1065             BIO_free_all(bio);
1066             SSL_CTX_free(sslCtx);
1067             return NULL;
1068         }
1069     } else {
1070         bio = BIO_new_connect(host);
1071     }
1072 
1073     if (bio == NULL) {
1074         LOGE("Create connect bio failed.");
1075         return bio;
1076     }
1077 
1078     if (port != NULL) {
1079         if (BIO_set_conn_port(bio, port) != 1) {
1080             LOGE("Set port failed.");
1081             BIO_free_all(bio);
1082             return NULL;
1083         }
1084     } else if (ssl) {
1085         if (BIO_set_conn_port(bio, HTTPS_PORT) != 1) {
1086             LOGE("Set port failed.");
1087             BIO_free_all(bio);
1088             return NULL;
1089         }
1090     } else {
1091         if (BIO_set_conn_port(bio, HTTP_PORT) != 1) {
1092             LOGE("Set port failed.");
1093             BIO_free_all(bio);
1094             return NULL;
1095         }
1096     }
1097     return bio;
1098 }
1099 
ValidateOcspOnline(STACK_OF (X509)* x509CertChain,OcspCertIdInfo * certIdInfo,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)1100 static CfResult ValidateOcspOnline(STACK_OF(X509) *x509CertChain, OcspCertIdInfo *certIdInfo,
1101     HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
1102 {
1103     char *host = NULL;
1104     char *port = NULL;
1105     char *path = NULL;
1106     int ssl = 0;
1107 
1108     HcfRevocationCheckParam *revo = params->revocationCheckParam;
1109 
1110     CfResult res = GetOcspUrl(&(GetOcspUrlParams) { .leafCert = sk_X509_value(x509CertChain, 0),
1111         .revo = revo, .host = &host, .port = &port, .path = &path, .ssl = &ssl });
1112     if (res != CF_SUCCESS) {
1113         LOGE("Unable to get ocps url.");
1114         return res;
1115     }
1116 
1117     BIO *cbio = CreateConnectBio(host, port, ssl);
1118     if (cbio == NULL) {
1119         LOGE("Unable to create connection.");
1120         return CF_ERR_CRYPTO_OPERATION;
1121     }
1122     if (!ConnectToServer(cbio, TRY_CONNECT_TIMES)) {
1123         LOGE("Unable to connect service.");
1124         BIO_free_all(cbio);
1125         return CF_ERR_CRYPTO_OPERATION;
1126     }
1127     OCSP_REQUEST *req = OCSP_REQUEST_new();
1128     if (req == NULL) {
1129         LOGE("Unable to create req.");
1130         BIO_free_all(cbio);
1131         return CF_ERR_CRYPTO_OPERATION;
1132     }
1133     res = SetRequestData(revo, req, certIdInfo);
1134     if (res != CF_SUCCESS) {
1135         LOGE("Unable to set request data.");
1136         OCSP_REQUEST_free(req);
1137         BIO_free_all(cbio);
1138         return res;
1139     }
1140 
1141     /* Send OCSP request and wait for response */
1142     OCSP_RESPONSE *resp = SendReqBioCustom(cbio, host, path, req);
1143     if (resp == NULL) {
1144         LOGE("Unable to send request.");
1145         OCSP_REQUEST_free(req);
1146         BIO_free_all(cbio);
1147         return CF_ERR_CRYPTO_OPERATION;
1148     }
1149     res = ValidateOcspLocal(
1150         (OcspLocalParam) { .req = req, .resp = resp, .certIdInfo = certIdInfo }, x509CertChain, trustAnchor, params);
1151     OCSP_REQUEST_free(req);
1152     BIO_free_all(cbio);
1153     OCSP_RESPONSE_free(resp);
1154     return res;
1155 }
1156 
GetHashDigest(const CfBlob * ocspDigest)1157 static const EVP_MD *GetHashDigest(const CfBlob *ocspDigest)
1158 {
1159     if (ocspDigest == NULL || ocspDigest->data == NULL) {
1160         return EVP_sha256();
1161     }
1162     char *mdName = (char *)ocspDigest->data;
1163     if (strcmp(mdName, "SHA1") == 0) {
1164         return EVP_sha1();
1165     } else if (strcmp(mdName, "SHA224") == 0) {
1166         return EVP_sha224();
1167     } else if (strcmp(mdName, "SHA256") == 0) {
1168         return EVP_sha256();
1169     } else if (strcmp(mdName, "SHA384") == 0) {
1170         return EVP_sha384();
1171     } else if (strcmp(mdName, "SHA512") == 0) {
1172         return EVP_sha512();
1173     } else if (strcmp(mdName, "MD5") == 0) {
1174         return EVP_md5();
1175     }
1176     return EVP_sha256();
1177 }
1178 
GetCertIssuerFromChain(STACK_OF (X509)* x509CertChain,X509 * leafCert,X509 ** issuerCert)1179 static CfResult GetCertIssuerFromChain(STACK_OF(X509) *x509CertChain, X509 *leafCert, X509 **issuerCert)
1180 {
1181     X509_STORE *store = NULL;
1182     X509_STORE_CTX *storeCtx = NULL;
1183     CfResult ret = CF_SUCCESS;
1184 
1185     store = X509_STORE_new();
1186     if (store == NULL) {
1187         LOGE("Unable to create store.");
1188         return CF_ERR_MALLOC;
1189     }
1190 
1191     for (int i = 1; i < sk_X509_num(x509CertChain); i++) {
1192         X509 *tmpCert = sk_X509_value(x509CertChain, i);
1193         if (X509_STORE_add_cert(store, tmpCert) != 1) {
1194             LOGE("Add cert to store failed.");
1195             X509_STORE_free(store);
1196             return CF_ERR_CRYPTO_OPERATION;
1197         }
1198     }
1199 
1200     storeCtx = X509_STORE_CTX_new();
1201     if (storeCtx == NULL) {
1202         LOGE("Unable to create storeCtx.");
1203         X509_STORE_free(store);
1204         return CF_ERR_MALLOC;
1205     }
1206 
1207     if (X509_STORE_CTX_init(storeCtx, store, NULL, NULL) == 0) {
1208         LOGE("Unable to init STORE_CTX.");
1209         ret = CF_ERR_CRYPTO_OPERATION;
1210         goto end;
1211     }
1212 
1213     if (X509_STORE_CTX_get1_issuer(issuerCert, storeCtx, leafCert) == -1) {
1214         LOGE("Some other error occurred when getting issuer.");
1215         ret = CF_ERR_CRYPTO_OPERATION;
1216         goto end;
1217     }
1218 
1219 end:
1220     X509_STORE_free(store);
1221     X509_STORE_CTX_free(storeCtx);
1222     return ret;
1223 }
1224 
GetCertIdInfo(STACK_OF (X509)* x509CertChain,const CfBlob * ocspDigest,OcspCertIdInfo * certIdInfo)1225 static CfResult GetCertIdInfo(STACK_OF(X509) *x509CertChain, const CfBlob *ocspDigest, OcspCertIdInfo *certIdInfo)
1226 {
1227     X509 *issuerCert = NULL;
1228     X509 *leafCert = NULL;
1229     CfResult ret = CF_INVALID_PARAMS;
1230 
1231     leafCert = sk_X509_value(x509CertChain, 0);
1232     if (leafCert == NULL) {
1233         LOGE("Get the leaf cert is null.");
1234         return CF_INVALID_PARAMS;
1235     }
1236 
1237     ret = GetCertIssuerFromChain(x509CertChain, leafCert, &issuerCert);
1238     if (ret != CF_SUCCESS) {
1239         LOGE("Get cert issuer from chain failed.");
1240         return ret;
1241     }
1242 
1243     if (X509_up_ref(leafCert) != 1) {
1244         LOGE("Unable to up ref leaf cert.");
1245         X509_free(issuerCert);
1246         return CF_ERR_CRYPTO_OPERATION;
1247     }
1248 
1249     certIdInfo->md = GetHashDigest(ocspDigest);
1250     certIdInfo->subjectCert = leafCert;
1251     certIdInfo->issuerCert = issuerCert;
1252     return CF_SUCCESS;
1253 }
1254 
ValidateRevocationOnLine(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,OcspCertIdInfo * certIdInfo)1255 static CfResult ValidateRevocationOnLine(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1256     HcfX509TrustAnchor *trustAnchor, OcspCertIdInfo *certIdInfo)
1257 {
1258     CfResult res = CF_INVALID_PARAMS;
1259     if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) {
1260         if ((res = ValidateOcspOnline(x509CertChain, certIdInfo, trustAnchor, params)) == CF_SUCCESS) {
1261             return res;
1262         }
1263         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER)) {
1264             if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) {
1265                 return res;
1266             }
1267         }
1268         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) {
1269             if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1270                                          x509CertChain, trustAnchor, params)) == CF_SUCCESS) {
1271                 return res;
1272             }
1273             return ValidateCrlLocal(params->certCRLCollections, x509CertChain);
1274         }
1275     } else {
1276         if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) {
1277             return res;
1278         }
1279         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER)) {
1280             if ((res = ValidateOcspOnline(x509CertChain, certIdInfo, trustAnchor, params)) == CF_SUCCESS) {
1281                 return res;
1282             }
1283         }
1284         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) {
1285             if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) {
1286                 return res;
1287             }
1288             return ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1289                                                         x509CertChain, trustAnchor, params);
1290         }
1291     }
1292     return res;
1293 }
1294 
ValidateRevocationLocal(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,OcspCertIdInfo * certIdInfo)1295 static CfResult ValidateRevocationLocal(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1296     HcfX509TrustAnchor *trustAnchor, OcspCertIdInfo *certIdInfo)
1297 {
1298     CfResult res = CF_INVALID_PARAMS;
1299     if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) {
1300         if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1301                                      x509CertChain, trustAnchor, params)) == CF_SUCCESS) {
1302             return res;
1303         }
1304     } else {
1305         if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) {
1306             return res;
1307         }
1308     }
1309     return CF_INVALID_PARAMS;
1310 }
1311 
FreeCertIdInfo(OcspCertIdInfo * certIdInfo)1312 static void FreeCertIdInfo(OcspCertIdInfo *certIdInfo)
1313 {
1314     if (certIdInfo->subjectCert != NULL) {
1315         X509_free(certIdInfo->subjectCert);
1316     }
1317     if (certIdInfo->issuerCert != NULL) {
1318         X509_free(certIdInfo->issuerCert);
1319     }
1320 }
1321 
ValidateRevocation(STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)1322 static CfResult ValidateRevocation(
1323     STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
1324 {
1325     if (x509CertChain == NULL || params == NULL) {
1326         LOGE("The input data is null!");
1327         return CF_INVALID_PARAMS;
1328     }
1329 
1330     if (params->revocationCheckParam && params->revocationCheckParam->options) {
1331         CfResult res = CF_INVALID_PARAMS;
1332         OcspCertIdInfo certIdInfo = {0};
1333         res = GetCertIdInfo(x509CertChain, params->revocationCheckParam->ocspDigest, &certIdInfo);
1334         if (res != CF_SUCCESS) {
1335             LOGE("Get cert id info failed.");
1336             return res;
1337         }
1338         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_ACCESS_NETWORK)) {
1339             res = ValidateRevocationOnLine(params, x509CertChain, trustAnchor, &certIdInfo);
1340             if (res != CF_SUCCESS) {
1341                 LOGE("Try to validate revocation online failed.");
1342             }
1343         } else {
1344             res = ValidateRevocationLocal(params, x509CertChain, trustAnchor, &certIdInfo);
1345             if (res != CF_SUCCESS) {
1346                 LOGE("Try to validate revocation local failed.");
1347             }
1348         }
1349         FreeCertIdInfo(&certIdInfo);
1350         return res;
1351     } else {
1352         return ValidateCrlLocal(params->certCRLCollections, x509CertChain);
1353     }
1354 }
1355 
ValidateDate(const STACK_OF (X509)* x509CertChain,CfBlob * date)1356 static CfResult ValidateDate(const STACK_OF(X509) *x509CertChain, CfBlob *date)
1357 {
1358     if (date == NULL) {
1359         LOGI("date is null");
1360         return CF_SUCCESS;
1361     }
1362     if (!CfBlobIsStr(date)) {
1363         LOGE("time format is invalid");
1364         return CF_INVALID_PARAMS;
1365     }
1366     ASN1_TIME *asn1InputDate = ASN1_TIME_new();
1367     if (asn1InputDate == NULL) {
1368         LOGE("Failed to malloc for asn1 time.");
1369         return CF_ERR_MALLOC;
1370     }
1371     if (ASN1_TIME_set_string(asn1InputDate, (const char *)date->data) != CF_OPENSSL_SUCCESS) {
1372         LOGE("Failed to set time for asn1 time.");
1373         CfPrintOpensslError();
1374         ASN1_TIME_free(asn1InputDate);
1375         return CF_INVALID_PARAMS;
1376     }
1377     CfResult res = CF_SUCCESS;
1378     int certsNum = sk_X509_num(x509CertChain);
1379     for (int i = 0; i < certsNum; ++i) {
1380         X509 *cert = sk_X509_value(x509CertChain, i);
1381         if (cert == NULL) {
1382             LOGE("sk X509 value is null, failed!");
1383             CfPrintOpensslError();
1384             ASN1_TIME_free(asn1InputDate);
1385             return CF_ERR_CRYPTO_OPERATION;
1386         }
1387         res = CompareDateWithCertTime(cert, asn1InputDate);
1388         if (res != CF_SUCCESS) {
1389             LOGE("check validate failed.");
1390             ASN1_TIME_free(asn1InputDate);
1391             return res;
1392         }
1393     }
1394     ASN1_TIME_free(asn1InputDate);
1395     return res;
1396 }
1397 
ValidateCertDate(X509 * cert,CfBlob * date)1398 static CfResult ValidateCertDate(X509 *cert, CfBlob *date)
1399 {
1400     STACK_OF(X509) *x509CertChain = sk_X509_new_null();
1401     if (sk_X509_push(x509CertChain, cert) <= 0) {
1402         LOGE("Push cert to chain failed!");
1403         sk_X509_free(x509CertChain);
1404         return CF_ERR_CRYPTO_OPERATION;
1405     }
1406     CfResult res = ValidateDate(x509CertChain, date);
1407     sk_X509_free(x509CertChain);
1408     return res;
1409 }
1410 
ValidatePolicy(const STACK_OF (X509)* x509CertChain,HcfValPolicyType policy,CfBlob * sslHostname)1411 static CfResult ValidatePolicy(const STACK_OF(X509) *x509CertChain, HcfValPolicyType policy, CfBlob *sslHostname)
1412 {
1413     CfResult res = CF_SUCCESS;
1414     switch (policy) {
1415         case VALIDATION_POLICY_TYPE_SSL:
1416             if (sslHostname == NULL) {
1417                 LOGE("The specified policy is SSL, but sslHostname is null!");
1418                 return CF_INVALID_PARAMS;
1419             }
1420             if (!X509_check_host(
1421                     sk_X509_value(x509CertChain, 0), (const char *)(sslHostname->data), sslHostname->size, 0, NULL)) {
1422                 LOGE("Validate SSL policy failed!");
1423                 return CF_ERR_CRYPTO_OPERATION;
1424             }
1425             break;
1426         case VALIDATION_POLICY_TYPE_X509:
1427             res = CF_SUCCESS;
1428             break;
1429         default:
1430             LOGE("Unknown policy type!");
1431             res = CF_INVALID_PARAMS;
1432             break;
1433     }
1434     return res;
1435 }
1436 
ValidateUseage(const STACK_OF (X509)* x509CertChain,HcfKuArray * keyUsage)1437 static CfResult ValidateUseage(const STACK_OF(X509) *x509CertChain, HcfKuArray *keyUsage)
1438 {
1439     CfResult res = CF_SUCCESS;
1440     if (keyUsage != NULL) {
1441         X509 *cert = sk_X509_value(x509CertChain, 0);
1442         if (cert == NULL) {
1443             return CF_INVALID_PARAMS;
1444         }
1445         uint32_t count = 0;
1446         for (size_t i = 0; i < keyUsage->count; i++) {
1447             HcfKeyUsageType kuType = keyUsage->data[i];
1448             uint32_t usageFlag = 0;
1449             switch (kuType) {
1450                 case KEYUSAGE_DIGITAL_SIGNATURE:
1451                     usageFlag = X509v3_KU_DIGITAL_SIGNATURE;
1452                     break;
1453                 case KEYUSAGE_NON_REPUDIATION:
1454                     usageFlag = X509v3_KU_NON_REPUDIATION;
1455                     break;
1456                 case KEYUSAGE_KEY_ENCIPHERMENT:
1457                     usageFlag = X509v3_KU_KEY_ENCIPHERMENT;
1458                     break;
1459                 case KEYUSAGE_DATA_ENCIPHERMENT:
1460                     usageFlag = X509v3_KU_DATA_ENCIPHERMENT;
1461                     break;
1462                 case KEYUSAGE_KEY_AGREEMENT:
1463                     usageFlag = X509v3_KU_KEY_AGREEMENT;
1464                     break;
1465                 case KEYUSAGE_KEY_CERT_SIGN:
1466                     usageFlag = X509v3_KU_KEY_CERT_SIGN;
1467                     break;
1468                 case KEYUSAGE_CRL_SIGN:
1469                     usageFlag = X509v3_KU_CRL_SIGN;
1470                     break;
1471                 case KEYUSAGE_ENCIPHER_ONLY:
1472                     usageFlag = X509v3_KU_ENCIPHER_ONLY;
1473                     break;
1474                 case KEYUSAGE_DECIPHER_ONLY:
1475                     usageFlag = X509v3_KU_DECIPHER_ONLY;
1476                     break;
1477                 default:
1478                     return CF_INVALID_PARAMS;
1479             }
1480             if ((X509_get_key_usage(cert) & usageFlag)) {
1481                 count++;
1482             }
1483         }
1484         res = (count == keyUsage->count) ? CF_SUCCESS : CF_ERR_CRYPTO_OPERATION;
1485     }
1486     return res;
1487 }
1488 
ValidateStrategies(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain)1489 static CfResult ValidateStrategies(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain)
1490 {
1491     CfResult res = ValidateDate(x509CertChain, params->date);
1492     if (res != CF_SUCCESS) {
1493         LOGE("Validate date failed.");
1494         return res;
1495     }
1496     res = ValidatePolicy(x509CertChain, params->policy, params->sslHostname);
1497     if (res != CF_SUCCESS) {
1498         LOGE("Validate policy failed.");
1499         return res;
1500     }
1501     res = ValidateUseage(x509CertChain, params->keyUsage);
1502     if (res != CF_SUCCESS) {
1503         LOGE("Validate usage failed.");
1504         return res;
1505     }
1506     return res;
1507 }
1508 
CreateStoreAndLoadCerts(X509_STORE ** store)1509 static CfResult CreateStoreAndLoadCerts(X509_STORE **store)
1510 {
1511     *store = X509_STORE_new();
1512     if (*store == NULL) {
1513         LOGE("Failed to new store");
1514         return CF_ERR_CRYPTO_OPERATION;
1515     }
1516 
1517     if (X509_STORE_load_path(*store, CERT_VERIFY_DIR) != CF_OPENSSL_SUCCESS) {
1518         LOGE("Failed to load system certificates");
1519         X509_STORE_free(*store);
1520         *store = NULL;
1521         return CF_ERR_CRYPTO_OPERATION;
1522     }
1523 
1524     return CF_SUCCESS;
1525 }
1526 
IsCertInStore(X509_STORE_CTX * storeCtx,X509 * cert)1527 static bool IsCertInStore(X509_STORE_CTX *storeCtx, X509 *cert)
1528 {
1529     if (storeCtx == NULL || cert == NULL) {
1530         return false;
1531     }
1532 
1533     X509_OBJECT *obj = X509_OBJECT_new();
1534     if (obj == NULL) {
1535         LOGE("x509Cert new object failed!");
1536         return false;
1537     }
1538 
1539     bool found = false;
1540     X509_NAME *subjectName = X509_get_subject_name(cert);
1541     if (subjectName == NULL) {
1542         X509_OBJECT_free(obj);
1543         LOGE("x509Cert get subject name failed!");
1544         return found;
1545     }
1546 
1547     if (X509_STORE_get_by_subject(storeCtx, X509_LU_X509, subjectName, obj) <= 0) {
1548         X509_OBJECT_free(obj);
1549         LOGE("x509Cert get subject failed!");
1550         return found;
1551     }
1552 
1553     X509 *storeCert = X509_OBJECT_get0_X509(obj);
1554     if (storeCert != NULL && X509_cmp(storeCert, cert) == 0) {
1555         found = true;
1556     }
1557 
1558     X509_OBJECT_free(obj);
1559     return found;
1560 }
1561 
TryGetIssuerFromStore(X509_STORE_CTX * storeCtx,X509 * rootCert,X509 ** mostTrustCert)1562 static CfResult TryGetIssuerFromStore(X509_STORE_CTX *storeCtx, X509 *rootCert, X509 **mostTrustCert)
1563 {
1564     if (X509_STORE_CTX_get1_issuer(mostTrustCert, storeCtx, rootCert) == CF_OPENSSL_SUCCESS) {
1565         return CF_SUCCESS;
1566     }
1567     return CF_ERR_CRYPTO_OPERATION;
1568 }
1569 
TryUseRootCertAsTrust(X509_STORE_CTX * storeCtx,X509 * rootCert,X509 ** mostTrustCert)1570 static CfResult TryUseRootCertAsTrust(X509_STORE_CTX *storeCtx, X509 *rootCert, X509 **mostTrustCert)
1571 {
1572     if (!IsCertInStore(storeCtx, rootCert)) {
1573         LOGE("root cert not in store");
1574         return CF_ERR_CRYPTO_OPERATION;
1575     }
1576 
1577     *mostTrustCert = X509_dup(rootCert);
1578     if (*mostTrustCert == NULL) {
1579         LOGE("Failed to duplicate root certificate");
1580         return CF_ERR_CRYPTO_OPERATION;
1581     }
1582 
1583     return CF_SUCCESS;
1584 }
1585 
GetMostTrustCert(const HcfX509CertChainValidateParams * params,X509_STORE * store,X509 * rootCert,STACK_OF (X509)* x509CertChain,X509 ** mostTrustCert)1586 static CfResult GetMostTrustCert(const HcfX509CertChainValidateParams *params, X509_STORE *store, X509 *rootCert,
1587     STACK_OF(X509) *x509CertChain, X509 **mostTrustCert)
1588 {
1589     if (store == NULL || rootCert == NULL || mostTrustCert == NULL) {
1590         return CF_INVALID_PARAMS;
1591     }
1592 
1593     X509_STORE_CTX *storeCtx = X509_STORE_CTX_new();
1594     if (storeCtx == NULL) {
1595         LOGE("Failed to create store context");
1596         return CF_ERR_CRYPTO_OPERATION;
1597     }
1598 
1599     CfResult res = CF_ERR_CRYPTO_OPERATION;
1600     if (X509_STORE_CTX_init(storeCtx, store, rootCert, x509CertChain) != CF_OPENSSL_SUCCESS) {
1601         LOGE("Failed to initialize verify context");
1602         goto cleanup;
1603     }
1604 
1605     /* Try to get issuer certificate from store */
1606     res = TryGetIssuerFromStore(storeCtx, rootCert, mostTrustCert);
1607     if (res == CF_SUCCESS) {
1608         res = ValidateCertDate(*mostTrustCert, params->date);
1609         if (res != CF_SUCCESS) {
1610             LOGE("Validate date failed.");
1611             goto cleanup;
1612         }
1613         goto cleanup;
1614     }
1615 
1616     /* If failed to get issuer certificate, try to use root certificate as trust anchor */
1617     LOGW("Failed to get issuer certificate, trying root cert");
1618     res = TryUseRootCertAsTrust(storeCtx, rootCert, mostTrustCert);
1619 
1620 cleanup:
1621     X509_STORE_CTX_free(storeCtx);
1622     return res;
1623 }
1624 
CreateTrustAnchorFromMostTrustCert(X509 * mostTrustCert,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor)1625 static CfResult CreateTrustAnchorFromMostTrustCert(X509 *mostTrustCert, STACK_OF(X509) *x509CertChain,
1626     HcfX509TrustAnchor *trustAnchor)
1627 {
1628     CfResult res = X509ToHcfX509Certificate(mostTrustCert, &(trustAnchor->CACert));
1629     if (res != CF_SUCCESS) {
1630         LOGE("Failed to convert X509 to HcfX509Certificate");
1631         return res;
1632     }
1633 
1634     res = GetPubKeyDataFromX509(mostTrustCert, &(trustAnchor->CAPubKey));
1635     if (res != CF_SUCCESS) {
1636         LOGE("Failed to get public key data");
1637         return res;
1638     }
1639 
1640     res = GetSubjectNameFromX509(mostTrustCert, &(trustAnchor->CASubject));
1641     if (res != CF_SUCCESS) {
1642         LOGE("Failed to get subject name");
1643         return res;
1644     }
1645 
1646     (void)GetNameConstraintsFromX509(mostTrustCert, &(trustAnchor->nameConstraints));
1647     res = ValidateNC(x509CertChain, trustAnchor->nameConstraints);
1648     if (res != CF_SUCCESS) {
1649         LOGI("verify nameConstraints failed, try next trustAnchor.");
1650         return res;
1651     }
1652 
1653     return CF_SUCCESS;
1654 }
1655 
ValidateTrustCertDir(const HcfX509CertChainValidateParams * params,X509 * rootCert,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchorResult)1656 static CfResult ValidateTrustCertDir(const HcfX509CertChainValidateParams *params, X509 *rootCert,
1657     STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchorResult)
1658 {
1659     X509_STORE *store = NULL;
1660     X509 *mostTrustCert = NULL;
1661 
1662     CfResult res = CreateStoreAndLoadCerts(&store);
1663     if (res != CF_SUCCESS) {
1664         return res;
1665     }
1666 
1667     res = GetMostTrustCert(params, store, rootCert, x509CertChain, &mostTrustCert);
1668     X509_STORE_free(store);
1669     if (res != CF_SUCCESS) {
1670         return res;
1671     }
1672 
1673     res = VerifyCertChain(mostTrustCert, x509CertChain);
1674     if (res != CF_SUCCESS) {
1675         LOGE("verify cert chain failed.");
1676         X509_free(mostTrustCert);
1677         return res;
1678     }
1679 
1680     res = CreateTrustAnchorFromMostTrustCert(mostTrustCert, x509CertChain, trustAnchorResult);
1681     if (res != CF_SUCCESS) {
1682         X509_free(mostTrustCert);
1683         return res;
1684     }
1685 
1686     X509_free(mostTrustCert);
1687     return CF_SUCCESS;
1688 }
1689 
ValidateOther(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor ** trustAnchorResult)1690 static CfResult ValidateOther(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1691     HcfX509TrustAnchor **trustAnchorResult)
1692 {
1693     if (sk_X509_num(x509CertChain) < 1) {
1694         LOGE("No cert in the certchain!");
1695         return CF_INVALID_PARAMS;
1696     }
1697     X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
1698     if (rootCert == NULL) {
1699         LOGE("Sk X509 value failed!");
1700         CfPrintOpensslError();
1701         return CF_ERR_CRYPTO_OPERATION;
1702     }
1703     HcfX509TrustAnchor *anchorResult = (HcfX509TrustAnchor *)CfMalloc(sizeof(HcfX509TrustAnchor), 0);
1704     if (anchorResult == NULL) {
1705         LOGE("Failed to allocate anchor result");
1706         return CF_ERR_MALLOC;
1707     }
1708 
1709     CfResult res = CF_INVALID_PARAMS;
1710     if ((params->trustAnchors != NULL) && (params->trustAnchors->data != NULL) && (params->trustAnchors->count != 0)) {
1711         res = ValidateTrustAnchor(params->trustAnchors, rootCert, x509CertChain, anchorResult);
1712     }
1713     if ((res != CF_SUCCESS) && (params->trustSystemCa)) {
1714         res = ValidateTrustCertDir(params, rootCert, x509CertChain, anchorResult);
1715     }
1716     if (res != CF_SUCCESS) {
1717         LOGE("ValidateTrust failed!");
1718         FreeTrustAnchorData(anchorResult);
1719         CfFree(anchorResult);
1720         return res;
1721     }
1722     res = ValidateRevocation(x509CertChain, anchorResult, params);
1723     if (res != CF_SUCCESS) {
1724         FreeTrustAnchorData(anchorResult);
1725         CfFree(anchorResult);
1726         return res;
1727     }
1728     *trustAnchorResult = anchorResult;
1729     return res;
1730 }
1731 
Validate(HcfX509CertChainSpi * self,const HcfX509CertChainValidateParams * params,HcfX509CertChainValidateResult * result)1732 static CfResult Validate(
1733     HcfX509CertChainSpi *self, const HcfX509CertChainValidateParams *params, HcfX509CertChainValidateResult *result)
1734 {
1735     if ((self == NULL) || (params == NULL) || (!(params->trustSystemCa) && ((params->trustAnchors == NULL) ||
1736         (params->trustAnchors->data == NULL) || (params->trustAnchors->count == 0))) || (result == NULL)) {
1737         LOGE("The input data is null!");
1738         return CF_INVALID_PARAMS;
1739     }
1740     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
1741         LOGE("Input wrong class type!");
1742         return CF_INVALID_PARAMS;
1743     }
1744     if (!((HcfX509CertChainOpensslImpl *)self)->isOrder) {
1745         LOGE("MisOrder certs chain, verify failed!");
1746         return CF_INVALID_PARAMS;
1747     }
1748 
1749     STACK_OF(X509) *x509CertChain = ((HcfX509CertChainOpensslImpl *)self)->x509CertChain;
1750     /* when check time with X509_STORE_CTX_set_time, the noAfter of cert is exclusive, but in RFC5280, it is inclusive,
1751      * so check manually here.
1752      */
1753     CfResult res = ValidateStrategies(params, x509CertChain);
1754     if (res != CF_SUCCESS) {
1755         LOGE("Validate part1 failed!");
1756         return res;
1757     }
1758 
1759     HcfX509TrustAnchor *trustAnchorResult = NULL;
1760     res = ValidateOther(params, x509CertChain, &trustAnchorResult);
1761     if (res != CF_SUCCESS) {
1762         LOGE("Validate part2 failed!");
1763         return res;
1764     }
1765 
1766     X509 *entityCert = sk_X509_value(x509CertChain, 0);
1767     if (entityCert == NULL) {
1768         CfPrintOpensslError();
1769         FreeTrustAnchorData(trustAnchorResult);
1770         CF_FREE_PTR(trustAnchorResult);
1771         return CF_ERR_CRYPTO_OPERATION;
1772     }
1773 
1774     res = FillValidateResult(trustAnchorResult, entityCert, result);
1775     if (res != CF_SUCCESS) {
1776         FreeTrustAnchorData(trustAnchorResult);
1777         CF_FREE_PTR(trustAnchorResult);
1778     }
1779     return res;
1780 }
1781 
CreateX509CertChainPEM(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1782 static int32_t CreateX509CertChainPEM(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1783 {
1784     STACK_OF(X509) *certsChain = NULL;
1785     X509 *cert = NULL;
1786 
1787     BIO *bio = BIO_new_mem_buf(inData->data, inData->len);
1788     if (bio == NULL) {
1789         LOGE("BIO new mem buf failed!");
1790         CfPrintOpensslError();
1791         return CF_ERR_CRYPTO_OPERATION;
1792     }
1793 
1794     /* Create cert chain object */
1795     certsChain = sk_X509_new_null();
1796     if (certsChain == NULL) {
1797         BIO_free(bio);
1798         LOGE("Error creating certificate chain.");
1799         CfPrintOpensslError();
1800         return CF_ERR_CRYPTO_OPERATION;
1801     }
1802 
1803     /* Add cert to cert chain object */
1804     while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) && cert != NULL) {
1805         if (sk_X509_push(certsChain, cert) <= 0) {
1806             LOGE("Memory allocation failure!");
1807             X509_free(cert);
1808             BIO_free(bio);
1809             sk_X509_pop_free(certsChain, X509_free);
1810             return CF_ERR_CRYPTO_OPERATION;
1811         }
1812         LOGI("push cert to certsChain.");
1813     }
1814 
1815     if (sk_X509_num(certsChain) == 0) {
1816         LOGE("cert chain size = 0.");
1817         CfPrintOpensslError();
1818         BIO_free(bio);
1819         sk_X509_free(certsChain);
1820         return CF_ERR_CRYPTO_OPERATION;
1821     }
1822 
1823     *certchainObj = certsChain;
1824     BIO_free(bio);
1825     return CF_SUCCESS;
1826 }
1827 
1828 /*
1829  * create x509 certchain from DER format streams
1830  * input params: inData
1831  * output params: certchainObj
1832  */
CreateX509CertChainDER(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1833 static int32_t CreateX509CertChainDER(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1834 {
1835     STACK_OF(X509) *certsChain = NULL;
1836     X509 *cert = NULL;
1837     const unsigned char *p = inData->data; // DER data
1838     size_t length = inData->len;
1839 
1840     certsChain = sk_X509_new_null();
1841     if (certsChain == NULL) {
1842         LOGE("Error creating certificate chain.");
1843         return CF_ERR_MALLOC;
1844     }
1845 
1846     while (p < inData->data + length) {
1847         size_t lengthLeft = (inData->data + length - p);
1848         cert = d2i_X509(NULL, &p, lengthLeft);
1849         if (cert == NULL) {
1850             LOGE("Failed to parse certificate.");
1851             CfPrintOpensslError();
1852             sk_X509_pop_free(certsChain, X509_free);
1853             return CF_ERR_CRYPTO_OPERATION;
1854         }
1855         if (sk_X509_push(certsChain, cert) <= 0) {
1856             LOGE("Memory allocation failure!");
1857             X509_free(cert);
1858             sk_X509_pop_free(certsChain, X509_free);
1859             return CF_ERR_MALLOC;
1860         }
1861         LOGI("push cert to certsChain.");
1862     }
1863 
1864     if (sk_X509_num(certsChain) == 0) {
1865         sk_X509_free(certsChain);
1866         LOGE("sk_X509_num failed.");
1867         return CF_INVALID_PARAMS;
1868     }
1869     *certchainObj = certsChain;
1870     return CF_SUCCESS;
1871 }
1872 
1873 /*
1874  * create x509 certchain from pkcs#7 streams
1875  * input params: inData
1876  * output params: certchainObj
1877  */
CreateX509CertChainPKCS7(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1878 static CfResult CreateX509CertChainPKCS7(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1879 {
1880     size_t dataLength = inData->len;
1881     uint8_t *data = inData->data;
1882     BIO *bio = BIO_new_mem_buf(data, dataLength);
1883     if (bio == NULL) {
1884         LOGE("malloc failed");
1885         CfPrintOpensslError();
1886         return CF_ERR_MALLOC;
1887     }
1888 
1889     PKCS7 *pkcs7 = d2i_PKCS7_bio(bio, NULL); // DER format .p7b file
1890     if (pkcs7 == NULL) {
1891         LOGE("Failed to parse PKCS7 data.");
1892         BIO_free(bio);
1893         CfPrintOpensslError();
1894         return CF_ERR_CRYPTO_OPERATION;
1895     }
1896 
1897     /* Get cert chain from pkcs7 object */
1898     STACK_OF(X509) *oriCertsChain = NULL;
1899     int i = OBJ_obj2nid(pkcs7->type);
1900     if (i == NID_pkcs7_signed && pkcs7->d.sign != NULL) {
1901         oriCertsChain = pkcs7->d.sign->cert;
1902     } else if (i == NID_pkcs7_signedAndEnveloped && pkcs7->d.signed_and_enveloped != NULL) {
1903         oriCertsChain = pkcs7->d.signed_and_enveloped->cert;
1904     }
1905 
1906     if (oriCertsChain == NULL || sk_X509_num(oriCertsChain) == 0) {
1907         LOGE("Failed to get certchain object.");
1908         PKCS7_free(pkcs7);
1909         BIO_free(bio);
1910         return CF_ERR_CRYPTO_OPERATION;
1911     }
1912 
1913     /* Clone a cert chain object for free pkcs7 object */
1914     STACK_OF(X509) *certsChain = sk_X509_deep_copy(oriCertsChain, X509_dup, X509_free);
1915     if (certsChain == NULL) {
1916         PKCS7_free(pkcs7);
1917         BIO_free(bio);
1918         LOGE("deep clone cert chain failed.");
1919         CfPrintOpensslError();
1920         return CF_ERR_CRYPTO_OPERATION;
1921     }
1922     *certchainObj = certsChain;
1923     PKCS7_free(pkcs7);
1924     BIO_free(bio);
1925     return CF_SUCCESS;
1926 }
1927 
CreateX509CertChainInner(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1928 static int32_t CreateX509CertChainInner(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1929 {
1930     int32_t ret = CF_SUCCESS;
1931     if (inData->encodingFormat == CF_FORMAT_PKCS7) {
1932         ret = CreateX509CertChainPKCS7(inData, certchainObj);
1933     } else if (inData->encodingFormat == CF_FORMAT_DER) {
1934         // create certchain from CF_FORMAT_DER
1935         ret = CreateX509CertChainDER(inData, certchainObj);
1936     } else if (inData->encodingFormat == CF_FORMAT_PEM) {
1937         // create certchain from CF_FORMAT_PEM
1938         ret = CreateX509CertChainPEM(inData, certchainObj);
1939     } else {
1940         LOGE("invalid input params");
1941         return CF_INVALID_PARAMS;
1942     }
1943 
1944     if (ret != CF_SUCCESS) {
1945         LOGE("error happened");
1946         return ret;
1947     }
1948 
1949     int num = sk_X509_num(*certchainObj);
1950     if (num > MAX_CERT_NUM || num == 0) {
1951         LOGE("certchain certs number :%{public}d invalid. create certChain failed! ", num);
1952         sk_X509_pop_free(*certchainObj, X509_free);
1953         *certchainObj = NULL;
1954         return CF_INVALID_PARAMS;
1955     }
1956 
1957     return CF_SUCCESS;
1958 }
1959 
HcfX509CertChainByEncSpiCreate(const CfEncodingBlob * inStream,HcfX509CertChainSpi ** spi)1960 CfResult HcfX509CertChainByEncSpiCreate(const CfEncodingBlob *inStream, HcfX509CertChainSpi **spi)
1961 {
1962     int32_t ret = CF_SUCCESS;
1963     if (inStream == NULL || inStream->data == NULL || inStream->len == 0 || spi == NULL) {
1964         LOGE("HcfX509CertChainByEncSpiCreate(), Invalid params!");
1965         return CF_INVALID_PARAMS;
1966     }
1967     HcfX509CertChainOpensslImpl *certChain =
1968         (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1969     if (certChain == NULL) {
1970         LOGE("Failed to allocate certChain spi object memory!");
1971         return CF_ERR_MALLOC;
1972     }
1973 
1974     ret = CreateX509CertChainInner(inStream, &(certChain->x509CertChain));
1975     if (ret != CF_SUCCESS || certChain->x509CertChain == NULL) {
1976         CfFree(certChain);
1977         certChain = NULL;
1978         LOGE("Failed to create x509 cert chain");
1979         return CF_INVALID_PARAMS;
1980     }
1981     bool isOrder = true;
1982     ret = IsOrderCertChain(certChain->x509CertChain, &isOrder);
1983     if (ret != CF_SUCCESS) {
1984         LOGE("cert chain isOrder failed!");
1985         sk_X509_pop_free(certChain->x509CertChain, X509_free);
1986         CfFree(certChain);
1987         certChain = NULL;
1988         return ret;
1989     }
1990 
1991     certChain->isOrder = isOrder;
1992     certChain->base.base.getClass = GetX509CertChainClass;
1993     certChain->base.base.destroy = DestroyX509CertChain;
1994     certChain->base.engineGetCertList = GetCertlist;
1995     certChain->base.engineValidate = Validate;
1996     certChain->base.engineToString = CfToString;
1997     certChain->base.engineHashCode = CfHashCode;
1998     *spi = (HcfX509CertChainSpi *)certChain;
1999     return CF_SUCCESS;
2000 }
2001 
GetCertsStack(const HcfX509CertificateArray * inCerts,STACK_OF (X509)* certsStack)2002 static CfResult GetCertsStack(const HcfX509CertificateArray *inCerts, STACK_OF(X509) *certsStack)
2003 {
2004     for (uint32_t i = 0; i < inCerts->count; ++i) {
2005         X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)inCerts->data[i]);
2006         if (cert == NULL) {
2007             LOGE("GetX509Cert from encodedBlob failed!");
2008             return CF_INVALID_PARAMS;
2009         }
2010 
2011         X509 *certDup = X509_dup(cert);
2012         if (certDup == NULL) {
2013             LOGE("Memory allocation failure!");
2014             return CF_ERR_MALLOC;
2015         }
2016 
2017         if (sk_X509_push(certsStack, certDup) <= 0) {
2018             LOGE("Memory allocation failure!");
2019             X509_free(certDup);
2020             return CF_ERR_MALLOC;
2021         }
2022     }
2023 
2024     return CF_SUCCESS;
2025 }
2026 
HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray * inCerts,HcfX509CertChainSpi ** spi)2027 CfResult HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray *inCerts, HcfX509CertChainSpi **spi)
2028 {
2029     if (spi == NULL || inCerts == NULL || inCerts->data == NULL || inCerts->count == 0 ||
2030         inCerts->count > MAX_CERT_NUM) {
2031         LOGE("Invalid params, is null!");
2032         return CF_INVALID_PARAMS;
2033     }
2034 
2035     HcfX509CertChainOpensslImpl *certChain =
2036         (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
2037     if (certChain == NULL) {
2038         LOGE("Failed to allocate certChain spi object memory!");
2039         return CF_ERR_MALLOC;
2040     }
2041 
2042     STACK_OF(X509) *certsStack = sk_X509_new_null();
2043     if (certsStack == NULL) {
2044         LOGE("Error creating certificate chain.");
2045         CfFree(certChain);
2046         certChain = NULL;
2047         return CF_ERR_MALLOC;
2048     }
2049 
2050     CfResult res = GetCertsStack(inCerts, certsStack);
2051     if (res != CF_SUCCESS) {
2052         LOGE("Get Certs Stack failed!");
2053         sk_X509_pop_free(certsStack, X509_free);
2054         CfFree(certChain);
2055         certChain = NULL;
2056         return res;
2057     }
2058 
2059     bool isOrder = true;
2060     res = IsOrderCertChain(certsStack, &isOrder);
2061     if (res != CF_SUCCESS) {
2062         LOGE("cert chain isOrder failed!");
2063         sk_X509_pop_free(certsStack, X509_free);
2064         CfFree(certChain);
2065         certChain = NULL;
2066         return res;
2067     }
2068 
2069     certChain->isOrder = isOrder;
2070     certChain->x509CertChain = certsStack;
2071     certChain->base.base.getClass = GetX509CertChainClass;
2072     certChain->base.base.destroy = DestroyX509CertChain;
2073     certChain->base.engineGetCertList = GetCertlist;
2074     certChain->base.engineValidate = Validate;
2075     certChain->base.engineToString = CfToString;
2076     certChain->base.engineHashCode = CfHashCode;
2077     *spi = (HcfX509CertChainSpi *)certChain;
2078 
2079     return CF_SUCCESS;
2080 }
2081 
ValidatCertChainX509(STACK_OF (X509)* x509CertChain,HcfX509CertChainValidateParams params)2082 bool ValidatCertChainX509(STACK_OF(X509) * x509CertChain, HcfX509CertChainValidateParams params)
2083 {
2084     CfResult res = ValidateDate(x509CertChain, params.date);
2085     if (res != CF_SUCCESS) {
2086         return false;
2087     }
2088     X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
2089     if (rootCert == NULL) {
2090         return false;
2091     }
2092 
2093     res = CF_INVALID_PARAMS;
2094     HcfX509TrustAnchor trustAnchorResult = {};
2095     if ((params.trustAnchors != NULL) && (params.trustAnchors->data != NULL) && (params.trustAnchors->count != 0)) {
2096         res = ValidateTrustAnchor(params.trustAnchors, rootCert, x509CertChain, &trustAnchorResult);
2097     }
2098     if ((res != CF_SUCCESS) && (params.trustSystemCa)) {
2099         res = ValidateTrustCertDir(&params, rootCert, x509CertChain, &trustAnchorResult);
2100     }
2101     FreeTrustAnchorData(&trustAnchorResult);
2102     if (res != CF_SUCCESS) {
2103         return false;
2104     }
2105 
2106     if (ValidateCrlLocal(params.certCRLCollections, x509CertChain) != CF_SUCCESS) {
2107         return false;
2108     }
2109     return true;
2110 }
2111 
PopFreeCerts(STACK_OF (X509)* allCerts,STACK_OF (X509)* leafCerts)2112 static void PopFreeCerts(STACK_OF(X509) *allCerts, STACK_OF(X509) *leafCerts)
2113 {
2114     sk_X509_pop_free(allCerts, X509_free);
2115     sk_X509_pop_free(leafCerts, X509_free);
2116 }
2117 
PackCertChain(const HcfX509CertChainBuildParameters * inParams,STACK_OF (X509)* out)2118 static CfResult PackCertChain(const HcfX509CertChainBuildParameters *inParams, STACK_OF(X509) * out)
2119 {
2120     STACK_OF(X509) *allCerts = sk_X509_new_null();
2121     STACK_OF(X509) *leafCerts = sk_X509_new_null();
2122     if (allCerts == NULL || leafCerts == NULL) {
2123         sk_X509_free(allCerts);
2124         sk_X509_free(leafCerts);
2125         return CF_ERR_CRYPTO_OPERATION;
2126     }
2127     CfResult res = GetLeafCertsFromCertStack(inParams, allCerts, leafCerts);
2128     if (res != CF_SUCCESS) {
2129         PopFreeCerts(allCerts, leafCerts);
2130         return res;
2131     }
2132 
2133     int allCertsLen = sk_X509_num(allCerts);
2134     int leafCertsLen = sk_X509_num(leafCerts);
2135 
2136     for (int i = 0; i < leafCertsLen; i++) {
2137         X509 *leafCert = sk_X509_value(leafCerts, i);
2138         if (CheckIsSelfSigned(leafCert)) {
2139             sk_X509_push(out, X509_dup(leafCert));
2140             if (ValidatCertChainX509(out, inParams->validateParameters)) {
2141                 PopFreeCerts(allCerts, leafCerts);
2142                 return CF_SUCCESS;
2143             }
2144         } else {
2145             sk_X509_push(out, X509_dup(leafCert));
2146             X509_NAME *issuerName = X509_get_issuer_name(leafCert);
2147             X509 *ca = FindCertificateBySubject(allCerts, issuerName);
2148 
2149             int depth = 0;
2150             int maxdepth = inParams->maxlength < 0 ? allCertsLen : inParams->maxlength;
2151             while (ca && (depth < maxdepth)) {
2152                 sk_X509_push(out, X509_dup(ca));
2153                 issuerName = X509_get_issuer_name(ca);
2154                 ca = FindCertificateBySubject(allCerts, issuerName);
2155                 depth++;
2156             }
2157             if (ValidatCertChainX509(out, inParams->validateParameters)) {
2158                 PopFreeCerts(allCerts, leafCerts);
2159                 return CF_SUCCESS;
2160             }
2161         }
2162 
2163         while (sk_X509_num(out) > 0) {
2164             X509_free(sk_X509_pop(out));
2165         }
2166     }
2167     PopFreeCerts(allCerts, leafCerts);
2168     return CF_INVALID_PARAMS;
2169 }
2170 
HcfX509CertChainByParamsSpiCreate(const HcfX509CertChainBuildParameters * inParams,HcfX509CertChainSpi ** spi)2171 CfResult HcfX509CertChainByParamsSpiCreate(const HcfX509CertChainBuildParameters *inParams, HcfX509CertChainSpi **spi)
2172 {
2173     if (inParams == NULL || spi == NULL) {
2174         LOGE("Get certchain from js error, the input is null!");
2175         return CF_INVALID_PARAMS;
2176     }
2177 
2178     STACK_OF(X509) *certStack = sk_X509_new_null();
2179     if (certStack == NULL) {
2180         LOGE("Failed to new certificate stack.");
2181         return CF_ERR_MALLOC;
2182     }
2183 
2184     CfResult res = PackCertChain(inParams, certStack);
2185     if (res != CF_SUCCESS) {
2186         LOGE("Failed to pack certificate chain.");
2187         sk_X509_pop_free(certStack, X509_free);
2188         return res;
2189     }
2190 
2191     if (sk_X509_num(certStack) == 0) {
2192         sk_X509_free(certStack);
2193         LOGE("certs chain count = 0.");
2194         return CF_ERR_CERT_HAS_EXPIRED;
2195     }
2196 
2197     bool isOrder = true;
2198     res = IsOrderCertChain(certStack, &isOrder);
2199     if (res != CF_SUCCESS) {
2200         LOGE("cert chain isOrder failed!");
2201         sk_X509_pop_free(certStack, X509_free);
2202         return res;
2203     }
2204 
2205     HcfX509CertChainOpensslImpl *certChain =
2206         (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
2207     if (certChain == NULL) {
2208         LOGE("Failed to allocate certChain spi object memory!");
2209         return CF_ERR_MALLOC;
2210     }
2211     certChain->isOrder = isOrder;
2212     certChain->x509CertChain = certStack;
2213     certChain->base.base.getClass = GetX509CertChainClass;
2214     certChain->base.base.destroy = DestroyX509CertChain;
2215     certChain->base.engineGetCertList = GetCertlist;
2216     certChain->base.engineValidate = Validate;
2217     certChain->base.engineToString = CfToString;
2218     certChain->base.engineHashCode = CfHashCode;
2219     *spi = (HcfX509CertChainSpi *)certChain;
2220 
2221     return res;
2222 }