• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_ex.h"
17 
18 #include "certificate_openssl_class.h"
19 #include "certificate_openssl_common.h"
20 #include "cf_blob.h"
21 #include "cf_log.h"
22 #include "cf_memory.h"
23 #include "cf_result.h"
24 #include "utils.h"
25 #include <securec.h>
26 #include "x509_cert_chain_spi.h"
27 #include "x509_certificate_create.h"
28 #include <openssl/pem.h>
29 #include <openssl/pkcs12.h>
30 
31 #define X509_CERT_CHAIN_OPENSSL_CLASS "X509CertChainOpensslClass"
32 
GetX509CertChainClass(void)33 const char *GetX509CertChainClass(void)
34 {
35     return X509_CERT_CHAIN_OPENSSL_CLASS;
36 }
37 
CfToString(HcfX509CertChainSpi * self,CfBlob * out)38 CfResult CfToString(HcfX509CertChainSpi *self, CfBlob *out)
39 {
40     if ((self == NULL) || (out == NULL)) {
41         LOGE("The input data is null!");
42         return CF_INVALID_PARAMS;
43     }
44     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
45         LOGE("Input wrong class type!");
46         return CF_INVALID_PARAMS;
47     }
48 
49     HcfX509CertChainOpensslImpl *certChain = (HcfX509CertChainOpensslImpl *)self;
50     STACK_OF(X509) *x509CertChain = certChain->x509CertChain;
51 
52     int32_t certsNum = sk_X509_num(x509CertChain);
53     BIO *bio = BIO_new(BIO_s_mem());
54     if (bio == NULL) {
55         LOGE("BIO_new error");
56         return CF_ERR_MALLOC;
57     }
58     for (int32_t i = 0; i < certsNum; ++i) {
59         X509 *cert = sk_X509_value(x509CertChain, i);
60         int len = X509_print(bio, cert);
61         if (len <= 0) {
62             LOGE("X509_print error");
63             BIO_free(bio);
64             return CF_ERR_CRYPTO_OPERATION;
65         }
66     }
67     BUF_MEM *bufMem = NULL;
68     if (BIO_get_mem_ptr(bio, &bufMem) > 0 && bufMem != NULL) {
69         CfResult res = DeepCopyDataToOut(bufMem->data, bufMem->length, out);
70         BIO_free(bio);
71         return res;
72     }
73 
74     BIO_free(bio);
75     LOGE("BIO_get_mem_ptr error");
76     return CF_ERR_CRYPTO_OPERATION;
77 }
78 
CfHashCode(HcfX509CertChainSpi * self,CfBlob * out)79 CfResult CfHashCode(HcfX509CertChainSpi *self, CfBlob *out)
80 {
81     if ((self == NULL) || (out == NULL)) {
82         LOGE("The input data is null!");
83         return CF_INVALID_PARAMS;
84     }
85     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
86         LOGE("Input wrong class type!");
87         return CF_INVALID_PARAMS;
88     }
89 
90     HcfX509CertChainOpensslImpl *certChain = (HcfX509CertChainOpensslImpl *)self;
91     STACK_OF(X509) *x509CertChain = certChain->x509CertChain;
92     int32_t certsNum = sk_X509_num(x509CertChain);
93     BIO *bio = BIO_new(BIO_s_mem());
94     if (bio == NULL) {
95         LOGE("BIO_new error");
96         return CF_ERR_MALLOC;
97     }
98     for (int32_t i = 0; i < certsNum; ++i) {
99         X509 *cert = sk_X509_value(x509CertChain, i);
100         int len = i2d_X509_bio(bio, cert);
101         if (len < 0) {
102             LOGE("i2d_X509_bio error");
103             BIO_free(bio);
104             return CF_ERR_CRYPTO_OPERATION;
105         }
106     }
107 
108     out->data = (uint8_t *)CfMalloc(SHA256_DIGEST_LENGTH, 0);
109     if (out->data == NULL) {
110         LOGE("CfMalloc error");
111         BIO_free(bio);
112         return CF_ERR_MALLOC;
113     }
114     BUF_MEM *bufMem = NULL;
115     if (BIO_get_mem_ptr(bio, &bufMem) > 0 && bufMem != NULL) {
116         SHA256((unsigned char *)bufMem->data, bufMem->length, out->data);
117         out->size = SHA256_DIGEST_LENGTH;
118         BIO_free(bio);
119         return CF_SUCCESS;
120     }
121 
122     BIO_free(bio);
123     CfBlobDataFree(out);
124     LOGE("BIO_get_mem_ptr error");
125     return CF_ERR_CRYPTO_OPERATION;
126 }
127 
GetX509FromHcfX509Certificate(const HcfCertificate * cert)128 X509 *GetX509FromHcfX509Certificate(const HcfCertificate *cert)
129 {
130     if (!CfIsClassMatch((CfObjectBase *)cert, HCF_X509_CERTIFICATE_CLASS)) {
131         LOGE("Input wrong openssl class type!");
132         return NULL;
133     }
134     HcfX509CertificateImpl *impl = (HcfX509CertificateImpl *)cert;
135     if (!CfIsClassMatch((CfObjectBase *)(impl->spiObj), X509_CERT_OPENSSL_CLASS)) {
136         LOGE("Input wrong openssl class type!");
137         return NULL;
138     }
139     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)(impl->spiObj);
140 
141     return realCert->x509;
142 }
143 
FreeCertificateArray(HcfX509CertificateArray * certs)144 void FreeCertificateArray(HcfX509CertificateArray *certs)
145 {
146     if (certs == NULL || certs->data == NULL) {
147         return;
148     }
149     for (uint32_t i = 0; i < certs->count; ++i) {
150         CfObjDestroy(certs->data[i]);
151     }
152     CF_FREE_PTR(certs->data);
153     certs->count = 0;
154 }
155 
GetCertChainFromCollection(const HcfX509CertChainBuildParameters * inParams,STACK_OF (X509)* certStack)156 static CfResult GetCertChainFromCollection(const HcfX509CertChainBuildParameters *inParams, STACK_OF(X509) *certStack)
157 {
158     if (inParams->validateParameters.certCRLCollections == NULL) {
159         LOGE("The input is NULL!");
160         return CF_INVALID_PARAMS;
161     }
162 
163     for (uint32_t i = 0; i < inParams->validateParameters.certCRLCollections->count; ++i) {
164         HcfX509CertificateArray retCerts = { NULL, 0 };
165         HcfCertCrlCollection *collection = inParams->validateParameters.certCRLCollections->data[i];
166         CfResult res = collection->selectCerts(collection, &(inParams->certMatchParameters), &retCerts);
167         if (res != CF_SUCCESS) {
168             LOGE("Get mached certs failed!");
169             return res;
170         }
171         for (uint32_t j = 0; j < retCerts.count; ++j) {
172             X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)retCerts.data[j]);
173             if (cert == NULL) {
174                 LOGE("GetX509Cert from inParams failed!");
175                 FreeCertificateArray(&retCerts);
176                 return CF_INVALID_PARAMS;
177             }
178 
179             X509 *certDup = X509_dup(cert);
180             if (certDup == NULL) {
181                 LOGE("Memory allocation failure!");
182                 FreeCertificateArray(&retCerts);
183                 return CF_ERR_MALLOC;
184             }
185             if (sk_X509_push(certStack, certDup) <= 0) {
186                 LOGE("Push cert to SK failed!");
187                 X509_free(certDup);
188                 FreeCertificateArray(&retCerts);
189                 return CF_ERR_CRYPTO_OPERATION;
190             }
191         }
192         FreeCertificateArray(&retCerts);
193     }
194     return CF_SUCCESS;
195 }
196 
GetLeafCertsFromCertStack(const HcfX509CertChainBuildParameters * inParams,STACK_OF (X509)* allCerts,STACK_OF (X509)* leafCerts)197 CfResult GetLeafCertsFromCertStack(
198     const HcfX509CertChainBuildParameters *inParams, STACK_OF(X509) *allCerts, STACK_OF(X509) *leafCerts)
199 {
200     CfResult res = GetCertChainFromCollection(inParams, allCerts);
201     if (res != CF_SUCCESS) {
202         LOGE("Error geting certificates from collection.");
203         return res;
204     }
205 
206     int allCertsLen = sk_X509_num(allCerts);
207     if (allCertsLen == 0) {
208         LOGE("The num of all certificate from collection is 0.");
209         return CF_INVALID_PARAMS;
210     }
211     for (int i = 0; i < allCertsLen; ++i) {
212         X509 *x509 = sk_X509_value(allCerts, i);
213         if (!CheckIsLeafCert(x509)) {
214             continue;
215         }
216 
217         X509 *x = X509_dup(x509);
218         if (x == NULL) {
219             LOGE("Dup the cert failed.");
220             return CF_ERR_CRYPTO_OPERATION;
221         }
222         if (!sk_X509_push(leafCerts, x)) {
223             X509_free(x);
224             LOGE("Push the cert into stack failed.");
225             return CF_ERR_CRYPTO_OPERATION;
226         }
227     }
228 
229     if (sk_X509_num(leafCerts) <= 0) {
230         LOGE("The num of leaf certificate is 0.");
231         return CF_INVALID_PARAMS;
232     }
233     return CF_SUCCESS;
234 }
235 
X509ToHcfX509Certificate(X509 * cert,HcfX509Certificate ** returnObj)236 CfResult X509ToHcfX509Certificate(X509 *cert, HcfX509Certificate **returnObj)
237 {
238     if (cert == NULL) {
239         LOGE("The input params invalid.");
240         return CF_INVALID_PARAMS;
241     }
242 
243     HcfX509CertCreateFunc func = GetHcfX509CertCreateFunc();
244     if (func == NULL) {
245         LOGE("HcfX509CertificateCreate is null.");
246         return CF_NULL_POINTER;
247     }
248 
249     int dataLength = 0;
250     uint8_t *certData = GetX509EncodedDataStream(cert, &dataLength);
251     if (certData == NULL) {
252         LOGE("Falied to get certificate data!");
253         return CF_ERR_CRYPTO_OPERATION;
254     }
255 
256     HcfX509Certificate *x509cert = NULL;
257     CfEncodingBlob encodingBlob = { certData, dataLength, CF_FORMAT_DER };
258     CfResult res = func(&encodingBlob, &x509cert);
259     CfFree(certData);
260     certData = NULL;
261     if (res != CF_SUCCESS) {
262         LOGE("HcfX509CertificateCreate fail, res : %{public}d!", res);
263         return CF_ERR_MALLOC;
264     }
265 
266     *returnObj = x509cert;
267     return res;
268 }
269 
FreeResources(X509 * cert,EVP_PKEY * pkey,STACK_OF (X509)* caStack)270 void FreeResources(X509 *cert, EVP_PKEY *pkey, STACK_OF(X509) *caStack)
271 {
272     if (cert != NULL) {
273         X509_free(cert);
274     }
275     if (pkey != NULL) {
276         EVP_PKEY_free(pkey);
277     }
278     if (caStack != NULL) {
279         sk_X509_pop_free(caStack, X509_free);
280     }
281 }
282 
FreeHcfX509P12Collection(HcfX509P12Collection * p12Collection)283 void FreeHcfX509P12Collection(HcfX509P12Collection *p12Collection)
284 {
285     if (p12Collection == NULL) {
286         return;
287     }
288     if (p12Collection->cert != NULL) {
289         CfFree(p12Collection->cert);
290         p12Collection->cert = NULL;
291     }
292     if (p12Collection->prikey != NULL && p12Collection->prikey->data != NULL) {
293         CfBlobFree(&p12Collection->prikey);
294     }
295     if (p12Collection->otherCerts != NULL && p12Collection->otherCertsCount != 0) {
296         for (uint32_t i = 0; i < p12Collection->otherCertsCount; i++) {
297             if (p12Collection->otherCerts[i] != NULL) {
298                 CfFree(p12Collection->otherCerts[i]);
299                 p12Collection->otherCerts[i] = NULL;
300             }
301         }
302         CfFree(p12Collection->otherCerts);
303         p12Collection->otherCerts = NULL;
304     }
305     CfFree(p12Collection);
306 }
307 
AllocateAndConvertCert(X509 * cert,HcfX509P12Collection * collection,bool isGet)308 CfResult AllocateAndConvertCert(X509 *cert, HcfX509P12Collection *collection, bool isGet)
309 {
310     if (!isGet) {
311         LOGI("The certificate for P12 does not need to be parsed!");
312         return CF_SUCCESS;
313     }
314     if (cert == NULL) {
315         LOGI("P12 does not have a cert!");
316         return CF_SUCCESS;
317     }
318     CfResult ret = X509ToHcfX509Certificate(cert, &collection->cert);
319     if (ret != CF_SUCCESS) {
320         LOGE("Failed to convert X509 to HcfX509Certificate!");
321         return ret;
322     }
323     return CF_SUCCESS;
324 }
325 
AllocateAndConvertPkey(EVP_PKEY * pkey,HcfX509P12Collection * collection,bool isGet)326 CfResult AllocateAndConvertPkey(EVP_PKEY *pkey, HcfX509P12Collection *collection, bool isGet)
327 {
328     if ((!isGet) || (pkey == NULL)) {
329         LOGI("The prikey for P12 does not need to be parsed!");
330         return CF_SUCCESS;
331     }
332     collection->prikey = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
333     if (collection->prikey == NULL) {
334         LOGE("Failed to malloc pri key!");
335         return CF_ERR_MALLOC;
336     }
337     BIO *memBio = BIO_new(BIO_s_mem());
338     if (collection->isPem) {
339         if (!PEM_write_bio_PrivateKey(memBio, pkey, NULL, NULL, 0, 0, NULL)) {
340             LOGE("PEM write bio PrivateKey failed");
341             CfPrintOpensslError();
342             CfBlobFree(&collection->prikey);
343             BIO_free_all(memBio);
344             return CF_ERR_CRYPTO_OPERATION;
345         }
346     } else {
347         if (!i2d_PKCS8PrivateKey_bio(memBio, pkey, NULL, NULL, 0, NULL, NULL)) {
348             LOGE("PrivateKey i2d failed");
349             CfPrintOpensslError();
350             CfBlobFree(&collection->prikey);
351             BIO_free_all(memBio);
352             return CF_ERR_CRYPTO_OPERATION;
353         }
354     }
355     BUF_MEM *buf = NULL;
356     if (BIO_get_mem_ptr(memBio, &buf) < 0 || buf == NULL) {
357         LOGE("Failed to get mem ptr!");
358         CfBlobFree(&collection->prikey);
359         BIO_free_all(memBio);
360         return CF_ERR_MALLOC;
361     }
362     collection->prikey->size = buf->length;
363     collection->prikey->data = (uint8_t *)CfMalloc(collection->prikey->size, 0);
364     if (collection->prikey->data == NULL) {
365         LOGE("Failed to malloc pri key data!");
366         CfBlobFree(&collection->prikey);
367         BIO_free_all(memBio);
368         return CF_ERR_MALLOC;
369     }
370     (void)memcpy_s(collection->prikey->data, buf->length, buf->data, buf->length);
371     BIO_free_all(memBio);
372     return CF_SUCCESS;
373 }
374 
AllocateAndConvertCertStack(STACK_OF (X509)* ca,HcfX509P12Collection * collection,bool isGet)375 CfResult AllocateAndConvertCertStack(STACK_OF(X509) *ca, HcfX509P12Collection *collection, bool isGet)
376 {
377     if (!isGet) {
378         LOGI("The other certs for P12 does not need to be parsed!");
379         return CF_SUCCESS;
380     }
381     if (ca == NULL) {
382         LOGI("P12 does not have other certs!");
383         return CF_SUCCESS;
384     }
385     int32_t count = sk_X509_num(ca);
386     if (count <= 0) {
387         LOGI("P12 other certs num is 0!");
388         return CF_SUCCESS;
389     }
390     collection->otherCerts = (HcfX509Certificate **)CfMalloc(sizeof(HcfX509Certificate *) * count, 0);
391     collection->otherCertsCount = (uint32_t)count;
392     if (collection->otherCerts == NULL) {
393         LOGE("Failed to malloc otherCerts!");
394         return CF_ERR_MALLOC;
395     }
396     for (uint32_t i = 0; i < collection->otherCertsCount; i++) {
397         X509 *cert = sk_X509_value(ca, i);
398         CfResult ret = X509ToHcfX509Certificate(cert, &collection->otherCerts[i]);
399         if (ret != CF_SUCCESS) {
400             LOGE("Failed to convert X509 to HcfX509Certificate!");
401             return ret;
402         }
403     }
404     return CF_SUCCESS;
405 }
406 
ProcessP12Data(STACK_OF (X509)* ca,HcfX509TrustAnchorArray * result)407 static void ProcessP12Data(STACK_OF(X509) *ca, HcfX509TrustAnchorArray *result)
408 {
409     for (int i = 0; i < sk_X509_num(ca); i++) {
410         X509 *x509 = sk_X509_value(ca, i);
411         // CACert
412         if (X509ToHcfX509Certificate(x509, &(result->data[i]->CACert)) != CF_SUCCESS) {
413             LOGD("Failed to get %d CACert!", i);
414         }
415 
416         // CAPubKey
417         if (GetPubKeyDataFromX509(x509, &(result->data[i]->CAPubKey)) != CF_SUCCESS) {
418             LOGD("Failed to get %d CAPubKey!", i);
419         }
420 
421         // CASubject
422         if (GetSubjectNameFromX509(x509, &(result->data[i]->CASubject)) != CF_SUCCESS) {
423             LOGD("Failed to get %d CASubject!", i);
424         }
425 
426         // nameConstraints
427         if (GetNameConstraintsFromX509(x509, &(result->data[i]->nameConstraints)) != CF_SUCCESS) {
428             LOGD("Failed to get %d nameConstraints!", i);
429         }
430     }
431 }
432 
FreeHcfX509TrustAnchorArrayInner(HcfX509TrustAnchorArray * trustAnchorArray)433 static void FreeHcfX509TrustAnchorArrayInner(HcfX509TrustAnchorArray *trustAnchorArray)
434 {
435     if (trustAnchorArray == NULL) {
436         return;
437     }
438     if (trustAnchorArray->data != NULL) {
439         for (uint32_t i = 0; i < trustAnchorArray->count; i++) {
440             if (trustAnchorArray->data[i] != NULL) {
441                 CfObjDestroy(trustAnchorArray->data[i]->CACert);
442                 trustAnchorArray->data[i]->CACert = NULL;
443                 CfBlobFree(&trustAnchorArray->data[i]->CAPubKey);
444                 CfBlobFree(&trustAnchorArray->data[i]->CASubject);
445                 CfBlobFree(&trustAnchorArray->data[i]->nameConstraints);
446                 CfFree(trustAnchorArray->data[i]);
447                 trustAnchorArray->data[i] = NULL;
448             }
449         }
450         CfFree(trustAnchorArray->data);
451         trustAnchorArray->data = NULL;
452     }
453 }
454 
STACK_OF(X509)455 static STACK_OF(X509) *GetCaFromP12(const CfBlob *keyStore, const CfBlob *pwd)
456 {
457     X509 *cert = NULL;
458     EVP_PKEY *pkey = NULL;
459     STACK_OF(X509) *caStack = NULL;
460     PKCS12 *p12 = NULL;
461     const unsigned char *in = (const unsigned char *)(keyStore->data);
462 
463     p12 = d2i_PKCS12(NULL, &in, keyStore->size);
464     if (p12 == NULL) {
465         LOGE("Error convert pkcs12 data to inner struct!");
466         CfPrintOpensslError();
467         return NULL;
468     }
469 
470     int ret = PKCS12_parse(p12, (const char *)pwd->data, &pkey, &cert, &caStack);
471     PKCS12_free(p12);
472     if (ret != 1) {
473         LOGE("PKCS12_parse failed!");
474         CfPrintOpensslError();
475         return NULL;
476     }
477 
478     EVP_PKEY_free(pkey);
479     if (cert == NULL) {
480         LOGE("P12 does not have a cert!");
481         sk_X509_pop_free(caStack, X509_free);
482         return NULL;
483     }
484     X509_free(cert);
485 
486     if (caStack == NULL) {
487         LOGE("P12 does not have ca!");
488     }
489     return caStack;
490 }
491 
MallocTrustAnchorArray(int32_t count)492 static HcfX509TrustAnchorArray *MallocTrustAnchorArray(int32_t count)
493 {
494     HcfX509TrustAnchorArray *anchor = (HcfX509TrustAnchorArray *)(CfMalloc(sizeof(HcfX509TrustAnchorArray), 0));
495     if (anchor == NULL) {
496         LOGE("Failed to allocate trustAnchorArray memory!");
497         return NULL;
498     }
499 
500     anchor->count = (uint32_t)count;
501     anchor->data = (HcfX509TrustAnchor **)(CfMalloc(anchor->count * sizeof(HcfX509TrustAnchor *), 0));
502     if (anchor->data == NULL) {
503         LOGE("Failed to allocate data memory!");
504         CfFree(anchor);
505         anchor = NULL;
506         return NULL;
507     }
508 
509     for (uint32_t i = 0; i < anchor->count; i++) {
510         anchor->data[i] = (HcfX509TrustAnchor *)(CfMalloc(sizeof(HcfX509TrustAnchor), 0));
511         if (anchor->data[i] == NULL) {
512             LOGE("Failed to allocate data memory!");
513             FreeHcfX509TrustAnchorArrayInner(anchor);
514             CfFree(anchor);
515             anchor = NULL;
516             return NULL;
517         }
518     }
519     return anchor;
520 }
521 
HcfX509CreateTrustAnchorWithKeyStoreFunc(const CfBlob * keyStore,const CfBlob * pwd,HcfX509TrustAnchorArray ** trustAnchorArray)522 CfResult HcfX509CreateTrustAnchorWithKeyStoreFunc(
523     const CfBlob *keyStore, const CfBlob *pwd, HcfX509TrustAnchorArray **trustAnchorArray)
524 {
525     if (keyStore == NULL || pwd == NULL || trustAnchorArray == NULL) {
526         LOGE("Invalid params!");
527         return CF_INVALID_PARAMS;
528     }
529 
530     STACK_OF(X509) *ca = GetCaFromP12(keyStore, pwd);
531     if (ca == NULL) {
532         return CF_ERR_CRYPTO_OPERATION;
533     }
534 
535     int32_t count = sk_X509_num(ca);
536     if (count <= 0) {
537         LOGE("P12 ca num is 0!");
538         sk_X509_pop_free(ca, X509_free);
539         return CF_ERR_CRYPTO_OPERATION;
540     }
541 
542     HcfX509TrustAnchorArray *anchor = MallocTrustAnchorArray(count);
543     if (anchor == NULL) {
544         sk_X509_pop_free(ca, X509_free);
545         return CF_ERR_MALLOC;
546     }
547 
548     ProcessP12Data(ca, anchor);
549     *trustAnchorArray = anchor;
550     anchor = NULL;
551     sk_X509_pop_free(ca, X509_free);
552     return CF_SUCCESS;
553 }
554 
ParsePkcs12(const CfBlob * keyStore,const CfBlob * pwd,X509 ** cert,EVP_PKEY ** pkey,STACK_OF (X509)** caStack)555 static CfResult ParsePkcs12(const CfBlob *keyStore, const CfBlob *pwd,
556     X509 **cert, EVP_PKEY **pkey, STACK_OF(X509) **caStack)
557 {
558     PKCS12 *p12 = NULL;
559     const unsigned char *in = (const unsigned char *)(keyStore->data);
560 
561     p12 = d2i_PKCS12(NULL, &in, keyStore->size);
562     if (p12 == NULL) {
563         LOGE("Error convert pkcs12 data to inner struct!");
564         CfPrintOpensslError();
565         return CF_ERR_CRYPTO_OPERATION;
566     }
567 
568     int ret = PKCS12_parse(p12, (const char *)pwd->data, pkey, cert, caStack);
569     PKCS12_free(p12);
570     if (ret != 1) {
571         LOGE("PKCS12_parse failed!");
572         CfPrintOpensslError();
573         return CF_ERR_CRYPTO_OPERATION;
574     }
575     return CF_SUCCESS;
576 }
577 
HcfX509ParsePKCS12Func(const CfBlob * keyStore,const HcfParsePKCS12Conf * conf,HcfX509P12Collection ** p12Collection)578 CfResult HcfX509ParsePKCS12Func(
579     const CfBlob *keyStore, const HcfParsePKCS12Conf *conf, HcfX509P12Collection **p12Collection)
580 {
581     X509 *cert = NULL;
582     EVP_PKEY *pkey = NULL;
583     STACK_OF(X509) *caStack = NULL;
584     CfResult ret = ParsePkcs12(keyStore, conf->pwd, &cert, &pkey, &caStack);
585     if (ret != CF_SUCCESS) {
586         LOGE("Failed to parse PKCS12!");
587         return ret;
588     }
589 
590     HcfX509P12Collection *collection = (HcfX509P12Collection *)CfMalloc(sizeof(HcfX509P12Collection), 0);
591     if (collection == NULL) {
592         FreeResources(cert, pkey, caStack);
593         LOGE("Failed to malloc collection!");
594         return CF_ERR_MALLOC;
595     }
596 
597     ret = AllocateAndConvertCert(cert, collection, conf->isGetCert);
598     if (ret != CF_SUCCESS) {
599         FreeResources(cert, pkey, caStack);
600         FreeHcfX509P12Collection(collection);
601         collection = NULL;
602         LOGE("Failed to convert cert!");
603         return ret;
604     }
605 
606     collection->isPem = conf->isPem;
607     ret = AllocateAndConvertPkey(pkey, collection, conf->isGetPriKey);
608     if (ret != CF_SUCCESS) {
609         FreeResources(cert, pkey, caStack);
610         FreeHcfX509P12Collection(collection);
611         collection = NULL;
612         LOGE("Failed to convert pkey!");
613         return ret;
614     }
615 
616     ret = AllocateAndConvertCertStack(caStack, collection, conf->isGetOtherCerts);
617     if (ret != CF_SUCCESS) {
618         FreeResources(cert, pkey, caStack);
619         FreeHcfX509P12Collection(collection);
620         collection = NULL;
621         LOGE("Failed to convert caStack!");
622         return ret;
623     }
624 
625     *p12Collection = collection;
626     FreeResources(cert, pkey, caStack);
627     return CF_SUCCESS;
628 }