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