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