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, >ype);
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