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 }