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