diff --git a/BUILD.gn b/BUILD.gn index 32a18e7..e4c60a2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -31,6 +31,7 @@ group("certificate_framework_fuzztest") { deps += [ "test/fuzztest/cfcreate_fuzzer:fuzztest", "test/fuzztest/cfgetandcheck_fuzzer:fuzztest", + "test/fuzztest/v1.0/x509certchain_fuzzer:fuzztest", "test/fuzztest/v1.0/x509certificate_fuzzer:fuzztest", "test/fuzztest/v1.0/x509crl_fuzzer:fuzztest", ] diff --git a/frameworks/adapter/v1.0/BUILD.gn b/frameworks/adapter/v1.0/BUILD.gn index 9699182..db54dda 100644 --- a/frameworks/adapter/v1.0/BUILD.gn +++ b/frameworks/adapter/v1.0/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Huawei Device Co., Ltd. +# Copyright (c) 2023-2024 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -54,5 +54,6 @@ ohos_static_library("certificate_openssl_plugin_lib") { "crypto_framework:crypto_framework_lib", "hilog:libhilog", "openssl:libcrypto_shared", + "openssl:libssl_shared", ] } diff --git a/frameworks/adapter/v1.0/inc/certificate_openssl_common.h b/frameworks/adapter/v1.0/inc/certificate_openssl_common.h index 004cbfd..6bcf1d4 100644 --- a/frameworks/adapter/v1.0/inc/certificate_openssl_common.h +++ b/frameworks/adapter/v1.0/inc/certificate_openssl_common.h @@ -51,6 +51,11 @@ char *Asn1TimeToStr(const ASN1_GENERALIZEDTIME *time); bool CfArrayContains(const CfArray *self, const CfArray *sub); CfResult DeepCopyDataToOut(const char *data, uint32_t len, CfBlob *out); void SubAltNameArrayDataClearAndFree(SubAltNameArray *array); +bool CheckIsSelfSigned(const X509 *cert); +bool CheckIsLeafCert(X509 *cert); +CfResult IsOrderCertChain(STACK_OF(X509) * certsChain, bool *isOrder); +CfResult CheckSelfPubkey(X509 *cert, const EVP_PKEY *pubKey); +X509 *FindCertificateBySubject(STACK_OF(X509) * certs, X509_NAME *subjectName); #ifdef __cplusplus } #endif diff --git a/frameworks/adapter/v1.0/src/certificate_openssl_common.c b/frameworks/adapter/v1.0/src/certificate_openssl_common.c index 780a7e5..228d4e7 100644 --- a/frameworks/adapter/v1.0/src/certificate_openssl_common.c +++ b/frameworks/adapter/v1.0/src/certificate_openssl_common.c @@ -15,6 +15,8 @@ #include "certificate_openssl_common.h" +#include +#include #include #include @@ -23,8 +25,6 @@ #include "cf_result.h" #include "config.h" -#include - #define TIME_MON_LEN 2 #define TIME_HOUR_LEN 8 #define TIME_MIN_LEN 10 @@ -332,4 +332,164 @@ CfResult DeepCopyDataToOut(const char *data, uint32_t len, CfBlob *out) (void)memcpy_s(out->data, len, data, len); out->size = len; return CF_SUCCESS; +} + +bool CheckIsSelfSigned(const X509 *cert) +{ + bool ret = false; + X509_NAME *issuer = X509_get_issuer_name(cert); + if (issuer == NULL) { + LOGE("x509 get issuer name failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + + X509_NAME *subject = X509_get_subject_name(cert); + if (subject == NULL) { + LOGE("x509 get subject name failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + + ret = (X509_NAME_cmp(issuer, subject) == 0); + LOGI("CheckIsSelfSigned() ret: %d .", ret); + return ret; +} + +bool CheckIsLeafCert(X509 *cert) +{ + if (cert == NULL) { + return false; + } + + bool ret = true; + if (X509_check_ca(cert)) { + return false; + } + + return ret; +} + +CfResult IsOrderCertChain(STACK_OF(X509) * certsChain, bool *isOrder) +{ + int num = sk_X509_num(certsChain); + if (num == 1) { + LOGI("1 certs is order chain."); + return CF_SUCCESS; + } + + X509 *cert = NULL; + X509 *certNext = NULL; + X509_NAME *issuerName = NULL; + X509_NAME *subjectName = NULL; + for (int i = num - 1; i > 0; --i) { + cert = sk_X509_value(certsChain, i); + if (cert == NULL) { + LOGE("sk X509 value is null, failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + certNext = sk_X509_value(certsChain, i - 1); + if (certNext == NULL) { + LOGE("sk X509 value is null, failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + + subjectName = X509_get_subject_name(cert); + if (subjectName == NULL) { + LOGE("x509 get subject name failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + issuerName = X509_get_issuer_name(certNext); + if (issuerName == NULL) { + LOGE("x509 get subject name failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + + if (X509_NAME_cmp(subjectName, issuerName) != 0) { + *isOrder = false; + LOGI("is a misOrder chain."); + break; + } + } + + return CF_SUCCESS; +} + +CfResult CheckSelfPubkey(X509 *cert, const EVP_PKEY *pubKey) +{ + EVP_PKEY *certPublicKey = X509_get_pubkey(cert); + if (certPublicKey == NULL) { + LOGE("get cert public key failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + + int isMatch = EVP_PKEY_cmp(certPublicKey, pubKey); + if (isMatch != CF_OPENSSL_SUCCESS) { + LOGE("cmp cert public key failed!"); + CfPrintOpensslError(); + EVP_PKEY_free(certPublicKey); + return CF_ERR_CRYPTO_OPERATION; + } + + EVP_PKEY_free(certPublicKey); + return CF_SUCCESS; +} + +X509 *FindCertificateBySubject(STACK_OF(X509) * certs, X509_NAME *subjectName) +{ + X509_STORE_CTX *ctx = NULL; + X509 *cert = NULL; + X509_OBJECT *obj; + + X509_STORE *store = X509_STORE_new(); + if (store == NULL) { + return NULL; + } + for (int i = 0; i < sk_X509_num(certs); i++) { + cert = sk_X509_value(certs, i); + X509_STORE_add_cert(store, cert); + } + + if (!(ctx = X509_STORE_CTX_new())) { + X509_STORE_free(store); + return NULL; + } + if (X509_STORE_CTX_init(ctx, store, NULL, NULL) != 1) { + X509_STORE_free(store); + X509_STORE_CTX_free(ctx); + return NULL; + } + obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, subjectName); + if (obj == NULL) { + X509_STORE_free(store); + X509_STORE_CTX_free(ctx); + return NULL; + } + cert = X509_OBJECT_get0_X509(obj); + X509_STORE_free(store); + X509_OBJECT_free(obj); + X509_STORE_CTX_free(ctx); + + return cert; +} + +void SubAltNameArrayDataClearAndFree(SubAltNameArray *array) +{ + if (array == NULL) { + LOGD("The input array is null, no need to free."); + return; + } + if (array->data != NULL) { + for (uint32_t i = 0; i < array->count; ++i) { + CF_FREE_BLOB(array->data[i].name); + } + CfFree(array->data); + array->data = NULL; + array->count = 0; + } } \ No newline at end of file diff --git a/frameworks/adapter/v1.0/src/x509_cert_chain_openssl.c b/frameworks/adapter/v1.0/src/x509_cert_chain_openssl.c index eafd9fe..3f48e79 100644 --- a/frameworks/adapter/v1.0/src/x509_cert_chain_openssl.c +++ b/frameworks/adapter/v1.0/src/x509_cert_chain_openssl.c @@ -15,14 +15,15 @@ #include "x509_cert_chain_openssl.h" -#include -#include #include +#include #include #include +#include #include #include #include +#include #include #include #include @@ -45,6 +46,12 @@ #define TIMET_NUM 6 #define TIMET_YEAR_START 1900 #define TIMET_YEAR_OFFSET 100 // start time year from 1900 + 100 +#define HTTP_TIMEOUT 10 +#define TRY_CONNECT_TIMES 3 +#define OCSP_CONN_MILLISECOND 5000 // millisecond +#define OCSP_CONN_TIMEOUT (-1) // timeout == 0 means no timeout, < 0 means exactly one try. +#define HTTP_PORT "80" +#define HTTPS_PORT "443" typedef struct { HcfX509CertChainSpi base; @@ -58,6 +65,21 @@ typedef struct { CfResult result; } OpensslErrorToResult; +typedef struct { + OCSP_REQUEST *req; + OCSP_RESPONSE *resp; + OCSP_CERTID *certid; +} OcspLocalParam; + +typedef struct { + X509 *leafCert; + HcfRevocationCheckParam *revo; + char **host; + char **port; + char **path; + int *ssl; +} GetOcspUrlParams; + static const OpensslErrorToResult ERROR_TO_RESULT_MAP[] = { { X509_V_OK, CF_SUCCESS }, { X509_V_ERR_CERT_SIGNATURE_FAILURE, CF_ERR_CERT_SIGNATURE_FAILURE }, @@ -78,93 +100,6 @@ static CfResult ConvertOpensslErrorMsg(int32_t errCode) return CF_ERR_CRYPTO_OPERATION; } -static bool CheckIsSelfSigned(const X509 *cert) -{ - bool ret = false; - X509_NAME *issuer = X509_get_issuer_name(cert); - if (issuer == NULL) { - LOGE("x509 get issuer name failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - - X509_NAME *subject = X509_get_subject_name(cert); - if (subject == NULL) { - LOGE("x509 get subject name failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - - ret = (X509_NAME_cmp(issuer, subject) == 0); - LOGI("CheckIsSelfSigned() ret: %d .", ret); - return ret; -} - -static bool CheckIsLeafCert(X509 *cert) -{ - if (cert == NULL) { - return false; - } - - bool ret = true; - if (X509_check_ca(cert)) { - return false; - } - - return ret; -} - -static CfResult IsOrderCertChain(STACK_OF(X509) * certsChain, bool *isOrder) -{ - int num = sk_X509_num(certsChain); - if (num == 1) { - LOGI("1 certs is order chain."); - return CF_SUCCESS; - } - - X509 *cert = NULL; - X509 *certNext = NULL; - X509_NAME *issuerName = NULL; - X509_NAME *subjectName = NULL; - for (int i = num - 1; i > 0; --i) { - cert = sk_X509_value(certsChain, i); - if (cert == NULL) { - LOGE("sk X509 value is null, failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - certNext = sk_X509_value(certsChain, i - 1); - if (certNext == NULL) { - LOGE("sk X509 value is null, failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - - subjectName = X509_get_subject_name(cert); - if (subjectName == NULL) { - LOGE("x509 get subject name failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - issuerName = X509_get_issuer_name(certNext); - if (issuerName == NULL) { - LOGE("x509 get subject name failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - - if (!(X509_NAME_cmp(subjectName, issuerName) == 0)) { - *isOrder = false; - LOGI("is a misOrder chain."); - break; - } - } - - return CF_SUCCESS; -} - -// helper functions end - static const char *GetX509CertChainClass(void) { return X509_CERT_CHAIN_OPENSSL_CLASS; @@ -409,27 +344,6 @@ static EVP_PKEY *ConvertByteArrayToPubKey(const uint8_t *pubKeyBytes, size_t len return pubKey; } -static CfResult CheckSelfPubkey(X509 *cert, const EVP_PKEY *pubKey) -{ - EVP_PKEY *certPublicKey = X509_get_pubkey(cert); - if (certPublicKey == NULL) { - LOGE("get cert public key failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - - int isMatch = EVP_PKEY_cmp(certPublicKey, pubKey); - if (isMatch != CF_OPENSSL_SUCCESS) { - LOGE("cmp cert public key failed!"); - CfPrintOpensslError(); - EVP_PKEY_free(certPublicKey); - return CF_ERR_CRYPTO_OPERATION; - } - - EVP_PKEY_free(certPublicKey); - return CF_SUCCESS; -} - static CfResult CheckOthersInTrustAnchor(const HcfX509TrustAnchor *anchor, X509 *rootCert, bool *checkResult) { *checkResult = false; @@ -744,7 +658,7 @@ static CfResult GetX509Crls(const HcfCertCRLCollectionArray *certCRLCollections, return res; } -static CfResult ValidateCrls(const HcfCertCRLCollectionArray *collectionArr, STACK_OF(X509) * x509CertChain) +static CfResult ValidateCrlLocal(const HcfCertCRLCollectionArray *collectionArr, STACK_OF(X509) * x509CertChain) { STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null(); if (crlStack == NULL) { @@ -843,6 +757,594 @@ static CfResult ValidateTrustAnchor(const HcfX509TrustAnchorArray *trustAnchorsA return res; } +static const char *GetDpUrl(DIST_POINT *dp) +{ + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_STRING *url = NULL; + + if (dp == NULL || dp->distpoint == NULL || dp->distpoint->type != 0) { + return NULL; + } + gens = dp->distpoint->name.fullname; + if (gens == NULL) { + return NULL; + } + for (uint32_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen == NULL) { + continue; + } + int gtype; + url = GENERAL_NAME_get0_value(gen, >ype); + if (url == NULL) { + continue; + } + if (gtype == GEN_URI && ASN1_STRING_length(url) > GEN_URI) { + const char *uptr = (const char *)ASN1_STRING_get0_data(url); + if (IsHttp(uptr)) { + // can/should not use HTTPS here + return uptr; + } + } + } + return NULL; +} + +static X509_CRL *LoadCrlDp(STACK_OF(DIST_POINT) * crldp) +{ + const char *urlptr = NULL; + for (int i = 0; i < sk_DIST_POINT_num(crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(crldp, i); + urlptr = GetDpUrl(dp); + if (urlptr != NULL) { + return X509_CRL_load_http(urlptr, NULL, NULL, HTTP_TIMEOUT); + } + } + return NULL; +} + +static X509_CRL *GetCrlFromCert(const HcfX509CertChainValidateParams *params, X509 *x509) +{ + STACK_OF(DIST_POINT) *crlStack = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL); + if (crlStack != NULL) { + X509_CRL *crl = LoadCrlDp(crlStack); + sk_DIST_POINT_pop_free(crlStack, DIST_POINT_free); + if (crl != NULL) { + return crl; + } + } + + if (params->revocationCheckParam->crlDownloadURI != NULL && + params->revocationCheckParam->crlDownloadURI->data != NULL) { + char *url = (char *)params->revocationCheckParam->crlDownloadURI->data; + if (IsUrlValid(url)) { + return X509_CRL_load_http(url, NULL, NULL, HTTP_TIMEOUT); + } + } + + return NULL; +} + +static CfResult ValidateCrlOnline(const HcfX509CertChainValidateParams *params, STACK_OF(X509) * x509CertChain) +{ + X509 *x509 = sk_X509_value(x509CertChain, 0); + if (x509 == NULL) { + LOGE("Get leaf cert failed!"); + return CF_INVALID_PARAMS; + } + X509_CRL *crl = GetCrlFromCert(params, x509); + if (crl == NULL) { + LOGE("Get crl online is null!"); + return CF_ERR_CRYPTO_OPERATION; + } + + STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null(); + if (crlStack == NULL) { + LOGE("Create crl stack failed!"); + return CF_ERR_CRYPTO_OPERATION; + } + if (sk_X509_CRL_push(crlStack, crl) == 0) { + LOGE("Push crl stack failed!"); + sk_X509_CRL_pop_free(crlStack, X509_CRL_free); + return CF_ERR_CRYPTO_OPERATION; + } + if (CheckCertChainIsRevoked(crlStack, x509CertChain) != CF_SUCCESS) { + LOGE("Certchain is revoked, verify failed!"); + sk_X509_CRL_pop_free(crlStack, X509_CRL_free); + return CF_ERR_CRYPTO_OPERATION; + } + + sk_X509_CRL_pop_free(crlStack, X509_CRL_free); + return CF_SUCCESS; +} + +static bool ContainsOption(HcfRevChkOpArray *options, HcfRevChkOption op) +{ + if (options == NULL || options->data == NULL) { + return false; + } + + for (uint32_t i = 0; i < options->count; i++) { + if (options->data[i] == op) { + return true; + } + } + return false; +} + +static CfResult VerifyOcspSinger(OCSP_BASICRESP *bs, STACK_OF(X509) * certChain, X509 *cert) +{ + if (cert == NULL) { + LOGE("Input data cert is null!"); + return CF_INVALID_PARAMS; + } + X509_STORE *store = X509_STORE_new(); + if (store == NULL) { + LOGE("New x509 store failed!"); + return CF_ERR_CRYPTO_OPERATION; + } + CfResult res = SetVerifyParams(store, cert); + if (res != CF_SUCCESS) { + LOGE("Set verify params failed!"); + X509_STORE_free(store); + return res; + } + + if (OCSP_basic_verify(bs, certChain, store, 0) != 1) { + LOGE("OCSP basic verify failed!"); + res = CF_ERR_CERT_SIGNATURE_FAILURE; + } + X509_STORE_free(store); + + return res; +} + +static CfResult ParseResp(OCSP_BASICRESP *bs, OCSP_CERTID *certid) +{ + int ocspStatus; + ASN1_GENERALIZEDTIME *thisUpdate = NULL; + ASN1_GENERALIZEDTIME *nextUpdate = NULL; + CfResult res = CF_ERR_CRYPTO_OPERATION; + if (certid != NULL && OCSP_resp_find_status(bs, certid, &ocspStatus, NULL, NULL, &thisUpdate, &nextUpdate)) { + LOGI("OCSP_resp_find_status success!"); + switch (ocspStatus) { + case V_OCSP_CERTSTATUS_GOOD: + LOGI("The OCSP status is [V_OCSP_CERTSTATUS_GOOD]!"); + res = CF_SUCCESS; + break; + case V_OCSP_CERTSTATUS_REVOKED: + LOGE("The OCSP status is [V_OCSP_CERTSTATUS_REVOKED]!"); + break; + case V_OCSP_CERTSTATUS_UNKNOWN: + default: + LOGE("!The OCSP status is [UNKNOWN]!"); + break; + } + } + return res; +} + +static CfResult ValidateOcspLocal(OcspLocalParam localParam, STACK_OF(X509) * x509CertChain, + HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params) +{ + int i; + OCSP_BASICRESP *bs = NULL; + X509 *trustCert = NULL; + + HcfRevocationCheckParam *revo = params->revocationCheckParam; + if (localParam.resp == NULL && revo->ocspResponses != NULL) { + localParam.resp = + d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&(revo->ocspResponses->data), revo->ocspResponses->size); + } + if (localParam.resp == NULL || localParam.certid == NULL) { + LOGE("The input data is null!"); + return CF_ERR_CRYPTO_OPERATION; + } + if (OCSP_response_status(localParam.resp) != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + LOGE("The resp status is not success!"); + return CF_ERR_CRYPTO_OPERATION; + } + bs = OCSP_response_get1_basic(localParam.resp); + if (bs == NULL) { + LOGE("Error parsing response!"); + return CF_ERR_CRYPTO_OPERATION; + } + if (localParam.req != NULL && ((i = OCSP_check_nonce(localParam.req, bs)) <= 0)) { + if (i == -1) { + LOGW("No nonce in response!"); + } else { + LOGE("Nonce Verify error!"); + OCSP_BASICRESP_free(bs); + return CF_ERR_CRYPTO_OPERATION; + } + } + if (revo->ocspResponderCert != NULL) { + trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(params->revocationCheckParam->ocspResponderCert)); + } else if (trustAnchor->CACert != NULL) { + trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(trustAnchor->CACert)); + } else { + trustCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1); + } + + CfResult res = VerifyOcspSinger(bs, x509CertChain, trustCert); + if (res != CF_SUCCESS) { + LOGE("VerifySinger failed!"); + OCSP_BASICRESP_free(bs); + return res; + } + res = ParseResp(bs, localParam.certid); + OCSP_BASICRESP_free(bs); + return res; +} + +static OCSP_RESPONSE *SendReqBioCustom(BIO *bio, const char *host, const char *path, OCSP_REQUEST *req) +{ + OCSP_RESPONSE *resp = NULL; + OCSP_REQ_CTX *ctx; + + ctx = OCSP_sendreq_new(bio, path, NULL, -1); + if (ctx == NULL) { + LOGE("Create ocsp req ctx failed!"); + return NULL; + } + if (!OCSP_REQ_CTX_add1_header(ctx, "Accept", "application/ocsp-response")) { + return NULL; + } + if (!OCSP_REQ_CTX_add1_header(ctx, "Host", host)) { + return NULL; + } + if (!OCSP_REQ_CTX_set1_req(ctx, req)) { + return NULL; + } + if (ctx == NULL) { + return NULL; + } + int ret; + int tryNum = TRY_CONNECT_TIMES; + do { + ret = OCSP_sendreq_nbio(&resp, ctx); + tryNum--; + } while ((ret == -1) && BIO_should_retry(bio) && tryNum != 0); + OCSP_REQ_CTX_free(ctx); + if (ret) { + return resp; + } + return NULL; +} + +static bool ConnectToServer(BIO *bio, int tryNum) +{ + int ret = 0; + do { + ret = BIO_do_connect_retry(bio, OCSP_CONN_TIMEOUT, OCSP_CONN_MILLISECOND); + if (ret == 1) { + LOGI("OCSP connecte service successfully."); + break; + } else if (ret <= 0) { + LOGE("OCSP connecte service failed."); + CfPrintOpensslError(); + if (BIO_should_retry(bio)) { + LOGI("Try to connect service again, [%d]st.", tryNum); + tryNum--; + } else { + break; + } + } + } while (ret <= 0 && tryNum != 0); + return (ret == 1 ? true : false); +} + +static CfResult GetOcspUrl(GetOcspUrlParams *params) +{ + char *url = NULL; + + if (params->leafCert == NULL) { + LOGE("Unable to get leafCert."); + return CF_INVALID_PARAMS; + } + STACK_OF(OPENSSL_STRING) *ocspList = X509_get1_ocsp(params->leafCert); + if (ocspList != NULL && sk_OPENSSL_STRING_num(ocspList) > 0) { + url = sk_OPENSSL_STRING_value(ocspList, 0); + } + + if (url == NULL) { + if (params->revo->ocspResponderURI == NULL || params->revo->ocspResponderURI->data == NULL) { + LOGE("Unable to get url."); + return CF_ERR_CRYPTO_OPERATION; + } + } + char *urlValiable = (url == NULL) ? (char *)(params->revo->ocspResponderURI->data) : url; + if (!IsUrlValid(urlValiable)) { + LOGE("Invalid url."); + return CF_INVALID_PARAMS; + } + if (!OCSP_parse_url(urlValiable, params->host, params->port, params->path, params->ssl)) { + LOGE("Unable to parse url."); + return CF_ERR_CRYPTO_OPERATION; + } + return CF_SUCCESS; +} + +static CfResult SetRequestData(HcfRevocationCheckParam *revo, OCSP_REQUEST *req, OCSP_CERTID *certId) +{ + if (OCSP_request_add0_id(req, certId) == NULL) { + LOGE("Unable to add certId to req."); + return CF_INVALID_PARAMS; + } + + if (revo->ocspRequestExtension != NULL) { + for (size_t i = 0; i < revo->ocspRequestExtension->count; i++) { + X509_EXTENSION *ext = + d2i_X509_EXTENSION(NULL, (const unsigned char **)&(revo->ocspRequestExtension->data[i].data), + revo->ocspRequestExtension->data[i].size); + if (ext == NULL) { + return CF_INVALID_PARAMS; + } + if (!OCSP_REQUEST_add_ext(req, ext, -1)) { + X509_EXTENSION_free(ext); + return CF_ERR_CRYPTO_OPERATION; + } + X509_EXTENSION_free(ext); + ext = NULL; + } + } + + return CF_SUCCESS; +} + +static BIO *CreateConnectBio(char *host, char *port, int ssl) +{ + BIO *bio = NULL; + if (ssl == 1) { + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); + + SSL_CTX *sslCtx = SSL_CTX_new(TLS_client_method()); + if (sslCtx == NULL) { + LOGE("Create ssl context failed."); + return NULL; + } + bio = BIO_new_ssl_connect(sslCtx); + if (BIO_set_conn_hostname(bio, host) != 1) { + LOGE("Set host name %s failed.", host); + return NULL; + } + } else { + bio = BIO_new_connect(host); + } + + if (bio == NULL) { + LOGE("Create connect bio failed."); + return bio; + } + + if (port != NULL) { + if (BIO_set_conn_port(bio, port) != 1) { + LOGE("Set port %s failed.", port); + return NULL; + } + } else if (ssl) { + if (BIO_set_conn_port(bio, HTTPS_PORT) != 1) { + LOGE("Set port %s failed.", HTTPS_PORT); + return NULL; + } + } else { + if (BIO_set_conn_port(bio, HTTP_PORT) != 1) { + LOGE("Set port %s failed.", HTTP_PORT); + return NULL; + } + } + return bio; +} + +static CfResult ValidateOcspOnline(STACK_OF(X509) * x509CertChain, OCSP_CERTID *certId, HcfX509TrustAnchor *trustAnchor, + const HcfX509CertChainValidateParams *params) +{ + char *host = NULL; + char *port = NULL; + char *path = NULL; + int ssl = 0; + + HcfRevocationCheckParam *revo = params->revocationCheckParam; + + CfResult res = GetOcspUrl(&(GetOcspUrlParams) { .leafCert = sk_X509_value(x509CertChain, 0), + .revo = revo, .host = &host, .port = &port, .path = &path, .ssl = &ssl }); + if (res != CF_SUCCESS) { + LOGE("Unable to get ocps url."); + return res; + } + + BIO *cbio = CreateConnectBio(host, port, ssl); + if (cbio == NULL) { + LOGE("Unable to create connection."); + return CF_ERR_CRYPTO_OPERATION; + } + if (!ConnectToServer(cbio, TRY_CONNECT_TIMES)) { + LOGE("Unable to connect service."); + BIO_free_all(cbio); + return CF_ERR_CRYPTO_OPERATION; + } + OCSP_REQUEST *req = OCSP_REQUEST_new(); + if (req == NULL) { + LOGE("Unable to create req."); + BIO_free_all(cbio); + return CF_ERR_CRYPTO_OPERATION; + } + res = SetRequestData(revo, req, certId); + if (res != CF_SUCCESS) { + LOGE("Unable to set request data."); + OCSP_REQUEST_free(req); + BIO_free_all(cbio); + return res; + } + + /* Send OCSP request and wait for response */ + OCSP_RESPONSE *resp = SendReqBioCustom(cbio, host, path, req); + if (resp == NULL) { + LOGE("Unable to Send request."); + OCSP_REQUEST_free(req); + BIO_free_all(cbio); + return CF_ERR_CRYPTO_OPERATION; + } + res = ValidateOcspLocal( + (OcspLocalParam) { .req = req, .resp = resp, .certid = certId }, x509CertChain, trustAnchor, params); + OCSP_REQUEST_free(req); + BIO_free_all(cbio); + OCSP_RESPONSE_free(resp); + return res; +} + +static OCSP_CERTID *GetCertId(STACK_OF(X509) * x509CertChain) +{ + X509 *issuerCert = NULL; + X509 *leafCert = NULL; + X509_STORE *store = NULL; + X509_STORE_CTX *storeCtx = NULL; + OCSP_CERTID* ret = NULL; + do + { + store = X509_STORE_new(); + if (store == NULL) { + LOGE("Unable to create store."); + break; + } + leafCert = sk_X509_value(x509CertChain, 0); + if (leafCert == NULL) { + LOGE("Get the leaf cert is null."); + break; + } + for (int i = 1; i < sk_X509_num(x509CertChain); i++) { + X509 *tmpCert = sk_X509_value(x509CertChain, i); + if ((X509_cmp(leafCert, tmpCert) != 0) && (!X509_STORE_add_cert(store, tmpCert))) { + LOGE("Add cert to store failed."); + break; + } + } + storeCtx = X509_STORE_CTX_new(); + if (storeCtx == NULL) { + LOGE("Unable to create storeCtx."); + break; + } + if (X509_STORE_CTX_init(storeCtx, store, NULL, NULL) == 0) { + LOGE("Unable to init STORE_CTX."); + break; + } + + if ((X509_STORE_CTX_get1_issuer(&issuerCert, storeCtx, leafCert) != 1) || (issuerCert == NULL)) { + LOGE("Unable to get issuer."); + break; + } + ret = OCSP_cert_to_id(EVP_sha1(), leafCert, issuerCert); + } while (0); + + if (store != NULL) { + X509_STORE_free(store); + } + if (storeCtx != NULL) { + X509_STORE_CTX_free(storeCtx); + } + + return ret; +} + +static CfResult ValidateRevocationOnLine(const HcfX509CertChainValidateParams *params, STACK_OF(X509) * x509CertChain, + HcfX509TrustAnchor *trustAnchor, OCSP_CERTID *certId) +{ + CfResult res = CF_INVALID_PARAMS; + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) { + if ((res = ValidateOcspOnline(x509CertChain, certId, trustAnchor, params)) == CF_SUCCESS) { + LOGI("Excute validate ocsp online success."); + return res; + } + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER) && + (res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) { + LOGI("Excute validateCRLOnline success."); + return res; + } + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) { + if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certid = certId }, + x509CertChain, trustAnchor, params)) == CF_SUCCESS) { + LOGI("Excute validate ocsp local success."); + return res; + } + LOGI("Try to run CRLLocal."); + return ValidateCrlLocal(params->certCRLCollections, x509CertChain); + } + } else { + if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) { + LOGI("Excute validateCRLOnline success."); + return res; + } + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER) && + (res = ValidateOcspOnline(x509CertChain, certId, trustAnchor, params)) == CF_SUCCESS) { + LOGI("Excute validate ocsp online success."); + return res; + } + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) { + if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) { + LOGI("Excute validateCRLLocal success."); + return res; + } + LOGI("Try to ValidateOcspLocal."); + return ValidateOcspLocal( + (OcspLocalParam) { .req = NULL, .resp = NULL, .certid = certId }, x509CertChain, trustAnchor, params); + } + } + return res; +} + +static CfResult ValidateRevocationLocal(const HcfX509CertChainValidateParams *params, STACK_OF(X509) * x509CertChain, + HcfX509TrustAnchor *trustAnchor, OCSP_CERTID *certId) +{ + CfResult res = CF_INVALID_PARAMS; + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) { + if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certid = certId }, x509CertChain, + trustAnchor, params)) == CF_SUCCESS) { + LOGI("Excute validate ocsp local success."); + return res; + } + } else { + if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) { + LOGI("Excute validate crl local success."); + return res; + } + } + return CF_INVALID_PARAMS; +} + +static CfResult ValidateRevocation( + STACK_OF(X509) * x509CertChain, HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params) +{ + if (x509CertChain == NULL || params == NULL) { + LOGE("The input data is null!"); + return CF_INVALID_PARAMS; + } + + CfResult res = CF_INVALID_PARAMS; + if (params->revocationCheckParam && params->revocationCheckParam->options) { + OCSP_CERTID *certId = GetCertId(x509CertChain); + if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_ACCESS_NETWORK)) { + res = ValidateRevocationOnLine(params, x509CertChain, trustAnchor, certId); + if (res != CF_SUCCESS) { + LOGI("Try to validate revocation online failed."); + return res; + } + } else { + res = ValidateRevocationLocal(params, x509CertChain, trustAnchor, certId); + if (res != CF_SUCCESS) { + LOGI("Try to validate revocation local failed."); + return res; + } + } + return res; + } else { + LOGI("Try to ValidateCrlLocal."); + return ValidateCrlLocal(params->certCRLCollections, x509CertChain); + } +} + static CfResult ValidateDate(const STACK_OF(X509) * x509CertChain, CfBlob *date) { if (date == NULL) { @@ -885,20 +1387,143 @@ static CfResult ValidateDate(const STACK_OF(X509) * x509CertChain, CfBlob *date) return res; } +static CfResult ValidatePolicy(const STACK_OF(X509) * x509CertChain, HcfValPolicyType policy, CfBlob *sslHostname) +{ + CfResult res = CF_SUCCESS; + switch (policy) { + case VALIDATION_POLICY_TYPE_SSL: + if (sslHostname == NULL) { + LOGE("The specified policy is SSL, but sslHostname is null!"); + return CF_INVALID_PARAMS; + } + if (!X509_check_host( + sk_X509_value(x509CertChain, 0), (const char *)(sslHostname->data), sslHostname->size, 0, NULL)) { + LOGE("Validate SSL policy failed!"); + return CF_ERR_CRYPTO_OPERATION; + } + case VALIDATION_POLICY_TYPE_X509: + res = CF_SUCCESS; + break; + default: + LOGE("Unknown policy type!"); + res = CF_INVALID_PARAMS; + break; + } + return res; +} + +static CfResult ValidateUseage(const STACK_OF(X509) * x509CertChain, HcfKuArray *keyUsage) +{ + CfResult res = CF_SUCCESS; + if (keyUsage != NULL) { + X509 *cert = sk_X509_value(x509CertChain, 0); + if (cert == NULL) { + return CF_INVALID_PARAMS; + } + uint32_t count = 0; + for (size_t i = 0; i < keyUsage->count; i++) { + HcfKeyUsageType kuType = keyUsage->data[i]; + int usageFlag = 0; + switch (kuType) { + case KEYUSAGE_DIGITAL_SIGNATURE: + usageFlag = X509v3_KU_DIGITAL_SIGNATURE; + break; + case KEYUSAGE_NON_REPUDIATION: + usageFlag = X509v3_KU_NON_REPUDIATION; + break; + case KEYUSAGE_KEY_ENCIPHERMENT: + usageFlag = X509v3_KU_KEY_ENCIPHERMENT; + break; + case KEYUSAGE_DATA_ENCIPHERMENT: + usageFlag = X509v3_KU_DATA_ENCIPHERMENT; + break; + case KEYUSAGE_KEY_AGREEMENT: + usageFlag = X509v3_KU_KEY_AGREEMENT; + break; + case KEYUSAGE_KEY_CERT_SIGN: + usageFlag = X509v3_KU_KEY_CERT_SIGN; + break; + case KEYUSAGE_CRL_SIGN: + usageFlag = X509v3_KU_CRL_SIGN; + break; + case KEYUSAGE_ENCIPHER_ONLY: + usageFlag = X509v3_KU_ENCIPHER_ONLY; + break; + case KEYUSAGE_DECIPHER_ONLY: + usageFlag = X509v3_KU_DECIPHER_ONLY; + break; + default: + return CF_INVALID_PARAMS; + } + if ((X509_get_key_usage(cert) & usageFlag)) { + count++; + } + } + res = (count == keyUsage->count) ? CF_SUCCESS : CF_ERR_CRYPTO_OPERATION; + } + return res; +} + +static CfResult ValidateStrategies(const HcfX509CertChainValidateParams *params, STACK_OF(X509) * x509CertChain) +{ + CfResult res = ValidateDate(x509CertChain, params->date); + if (res != CF_SUCCESS) { + LOGE("Validate date failed."); + return res; + } + res = ValidatePolicy(x509CertChain, params->policy, params->sslHostname); + if (res != CF_SUCCESS) { + LOGE("Validate policy failed."); + return res; + } + res = ValidateUseage(x509CertChain, params->keyUsage); + if (res != CF_SUCCESS) { + LOGE("Validate usage failed."); + return res; + } + return res; +} + +static CfResult ValidateOther(const HcfX509CertChainValidateParams *params, STACK_OF(X509) * x509CertChain, + HcfX509TrustAnchor **trustAnchorResult) +{ + if (sk_X509_num(x509CertChain) < 1) { + LOGE("No cert in the certchain!"); + return CF_INVALID_PARAMS; + } + X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1); + if (rootCert == NULL) { + LOGE("Sk X509 value failed!"); + CfPrintOpensslError(); + return CF_ERR_CRYPTO_OPERATION; + } + + CfResult res = ValidateTrustAnchor(params->trustAnchors, rootCert, x509CertChain, trustAnchorResult); + if (res != CF_SUCCESS) { + LOGE("ValidateTrustAnchor failed!"); + return CF_INVALID_PARAMS; + } + res = ValidateRevocation(x509CertChain, *trustAnchorResult, params); + if (res != CF_SUCCESS) { + return res; + } + return res; +} + static CfResult Validate( HcfX509CertChainSpi *self, const HcfX509CertChainValidateParams *params, HcfX509CertChainValidateResult *result) { if ((self == NULL) || (params == NULL) || (params->trustAnchors == NULL) || (params->trustAnchors->data == NULL) || (params->trustAnchors->count == 0) || (result == NULL)) { - LOGE("[Validate openssl] The input data is null!"); + LOGE("The input data is null!"); return CF_INVALID_PARAMS; } if (!IsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) { - LOGE("[Validate openssl] Input wrong class type!"); + LOGE("Input wrong class type!"); return CF_INVALID_PARAMS; } if (!((HcfX509CertChainOpensslImpl *)self)->isOrder) { - LOGE("misOrder certs chain , verify failed"); + LOGE("MisOrder certs chain, verify failed!"); return CF_INVALID_PARAMS; } @@ -906,37 +1531,25 @@ static CfResult Validate( /* when check time with X509_STORE_CTX_set_time, the noAfter of cert is exclusive, but in RFC5280, it is inclusive, * so check manually here. */ - CfResult res = ValidateDate(x509CertChain, params->date); + CfResult res = ValidateStrategies(params, x509CertChain); if (res != CF_SUCCESS) { - LOGE("validate date failed."); + LOGE("Validate part1 failed!"); return res; } - X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1); // root CA - if (rootCert == NULL) { - LOGE("sk X509 value failed!"); + HcfX509TrustAnchor *trustAnchorResult = NULL; + res = ValidateOther(params, x509CertChain, &trustAnchorResult); + if (res != CF_SUCCESS) { + LOGE("Validate part2 failed!"); + return res; + } + X509 *entityCert = sk_X509_value(x509CertChain, 0); + if (entityCert == NULL) { CfPrintOpensslError(); return CF_ERR_CRYPTO_OPERATION; } - HcfX509TrustAnchor *trustAnchorResult = NULL; // Verify trust anchor - res = ValidateTrustAnchor(params->trustAnchors, rootCert, x509CertChain, &trustAnchorResult); - if (res == CF_SUCCESS) { - res = ValidateCrls(params->certCRLCollections, x509CertChain); // Verify Crls - if (res != CF_SUCCESS) { - LOGE("Validate Crls failed"); - return res; - } - X509 *entityCert = sk_X509_value(x509CertChain, 0); // leaf CA - if (entityCert == NULL) { - LOGE("sk X509 value failed!"); - CfPrintOpensslError(); - return CF_ERR_CRYPTO_OPERATION; - } - res = FillValidateResult(trustAnchorResult, entityCert, result); // build return result - } - - return res; + return FillValidateResult(trustAnchorResult, entityCert, result); } static int32_t CreateX509CertChainPEM(const CfEncodingBlob *inData, STACK_OF(X509) * *certchainObj) @@ -1271,44 +1884,6 @@ static CfResult GetCertChainFromCollection(const HcfX509CertChainBuildParameters return CF_SUCCESS; } -X509 *FindCertificateBySubject(STACK_OF(X509) * certs, X509_NAME *subjectName) -{ - X509_STORE_CTX *ctx = NULL; - X509 *cert = NULL; - X509_OBJECT *obj; - - X509_STORE *store = X509_STORE_new(); - if (store == NULL) { - return NULL; - } - for (int i = 0; i < sk_X509_num(certs); i++) { - cert = sk_X509_value(certs, i); - X509_STORE_add_cert(store, cert); - } - - if (!(ctx = X509_STORE_CTX_new())) { - X509_STORE_free(store); - return NULL; - } - if (X509_STORE_CTX_init(ctx, store, NULL, NULL) != 1) { - X509_STORE_free(store); - X509_STORE_CTX_free(ctx); - return NULL; - } - obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, subjectName); - if (obj == NULL) { - X509_STORE_free(store); - X509_STORE_CTX_free(ctx); - return NULL; - } - cert = X509_OBJECT_get0_X509(obj); - X509_STORE_free(store); - X509_OBJECT_free(obj); - X509_STORE_CTX_free(ctx); - - return cert; -} - bool ValidatCertChainX509(STACK_OF(X509) * x509CertChain, HcfX509CertChainValidateParams params) { CfResult res = ValidateDate(x509CertChain, params.date); @@ -1323,7 +1898,7 @@ bool ValidatCertChainX509(STACK_OF(X509) * x509CertChain, HcfX509CertChainValida if (ValidateTrustAnchor(params.trustAnchors, rootCert, x509CertChain, &trustAnchorResult) != CF_SUCCESS) { return false; } - if (ValidateCrls(params.certCRLCollections, x509CertChain) != CF_SUCCESS) { + if (ValidateCrlLocal(params.certCRLCollections, x509CertChain) != CF_SUCCESS) { return false; } return true; diff --git a/frameworks/adapter/v1.0/src/x509_crl_openssl.c b/frameworks/adapter/v1.0/src/x509_crl_openssl.c index 27f96eb..0c7a2c7 100644 --- a/frameworks/adapter/v1.0/src/x509_crl_openssl.c +++ b/frameworks/adapter/v1.0/src/x509_crl_openssl.c @@ -15,7 +15,6 @@ #include "x509_crl_openssl.h" -#include #include #include #include diff --git a/frameworks/common/v1.0/inc/utils.h b/frameworks/common/v1.0/inc/utils.h index 4333141..d06053a 100644 --- a/frameworks/common/v1.0/inc/utils.h +++ b/frameworks/common/v1.0/inc/utils.h @@ -22,7 +22,6 @@ #include "cf_blob.h" #include "cf_object_base.h" #include "object_base.h" -#include "x509_cert_match_parameters.h" #ifdef __cplusplus extern "C" { @@ -32,7 +31,8 @@ bool IsStrValid(const char *str, uint32_t maxLen); bool IsBlobValid(const CfBlob *blob); bool IsClassMatch(const CfObjectBase *obj, const char *className); bool IsPubKeyClassMatch(const HcfObjectBase *obj, const char *className); -void SubAltNameArrayDataClearAndFree(SubAltNameArray *array); +bool IsUrlValid(const char *url); +bool IsHttp(const char *url); #ifdef __cplusplus } diff --git a/frameworks/common/v1.0/src/utils.c b/frameworks/common/v1.0/src/utils.c index 6f493ff..a3a37f5 100644 --- a/frameworks/common/v1.0/src/utils.c +++ b/frameworks/common/v1.0/src/utils.c @@ -20,6 +20,10 @@ #include "cf_log.h" #include "cf_memory.h" +#define MIN_URL_LEN 5 +#define HTTP_URL_LEN 7 +#define HTTPS_URL_LEN 8 + bool IsStrValid(const char *str, uint32_t maxLen) { if (str == NULL) { @@ -65,18 +69,49 @@ bool IsPubKeyClassMatch(const HcfObjectBase *obj, const char *className) } } -void SubAltNameArrayDataClearAndFree(SubAltNameArray *array) +bool IsUrlValid(const char *url) { - if (array == NULL) { - LOGD("The input array is null, no need to free."); - return; + if (url == NULL) { + return false; } - if (array->data != NULL) { - for (uint32_t i = 0; i < array->count; ++i) { - CF_FREE_BLOB(array->data[i].name); + if (strlen(url) < MIN_URL_LEN) { + return false; + } + if (strncmp(url, "http://", HTTP_URL_LEN) != 0 && strncmp(url, "https://", HTTPS_URL_LEN) != 0) { + return false; + } + + int httpHeaderLen = (strncmp(url, "http://", HTTP_URL_LEN) == 0) ? HTTP_URL_LEN : HTTPS_URL_LEN; + const char *startDomain = url + httpHeaderLen; + const char *endDomain = startDomain; + while (*endDomain != '\0' && *endDomain != '/') { + endDomain++; + } + if (endDomain == startDomain) { + return false; + } + + if (*endDomain == '\0') { + return true; + } else { + const char *startPath = endDomain; + while (*startPath == '/') { + startPath++; } - CfFree(array->data); - array->data = NULL; - array->count = 0; + if (*startPath == '\0') { + return false; + } else { + return true; + } + } + return false; +} + +bool IsHttp(const char *url) +{ + if (url != NULL && strncmp(url, "http://", strlen("http://")) == 0) { + return true; + } else { + return false; } } \ No newline at end of file diff --git a/frameworks/js/napi/certificate/inc/napi_cert_defines.h b/frameworks/js/napi/certificate/inc/napi_cert_defines.h index 2520627..70e2e60 100644 --- a/frameworks/js/napi/certificate/inc/napi_cert_defines.h +++ b/frameworks/js/napi/certificate/inc/napi_cert_defines.h @@ -100,6 +100,16 @@ const std::string CERT_CHAIN_TRUSTANCHOR_TAG_CASUBJECT = "CASubject"; const std::string CERT_CHAIN_VALIDATE_TAG_DATE = "date"; const std::string CERT_CHAIN_VALIDATE_TAG_TRUSTANCHORS = "trustAnchors"; const std::string CERT_CHAIN_VALIDATE_TAG_CERTCRLS = "certCRLs"; +const std::string CERT_CHAIN_VALIDATE_TAG_REVOCATIONCHECKPARAM = "revocationCheckParam"; +const std::string CERT_CHAIN_VALIDATE_TAG_OCSP_REQ_EXTENSION = "ocspRequestExtension"; +const std::string CERT_CHAIN_VALIDATE_TAG_OCSP_RESP_URI = "ocspResponderURI"; +const std::string CERT_CHAIN_VALIDATE_TAG_OCSP_RESP_CERT = "ocspResponderCert"; +const std::string CERT_CHAIN_VALIDATE_TAG_OCSP_RESPS = "ocspResponses"; +const std::string CERT_CHAIN_VALIDATE_TAG_CRL_DOWNLOAD_URI = "crlDownloadURI"; +const std::string CERT_CHAIN_VALIDATE_TAG_OPTIONS = "options"; +const std::string CERT_CHAIN_VALIDATE_TAG_POLICY = "policy"; +const std::string CERT_CHAIN_VALIDATE_TAG_SSLHOSTNAME = "sslHostname"; +const std::string CERT_CHAIN_VALIDATE_TAG_KEYUSAGE = "keyUsage"; // CertChainValidateResult const std::string CERT_CHAIN_VALIDATE_RESULLT_TAG_TRUSTANCHOR = "trustAnchor"; const std::string CERT_CHAIN_VALIDATE_RESULLT_TAG_X509CERT = "entityCert"; diff --git a/frameworks/js/napi/certificate/src/napi_cert_utils.cpp b/frameworks/js/napi/certificate/src/napi_cert_utils.cpp index f8465c0..6d427fc 100644 --- a/frameworks/js/napi/certificate/src/napi_cert_utils.cpp +++ b/frameworks/js/napi/certificate/src/napi_cert_utils.cpp @@ -628,6 +628,22 @@ bool ParserArray(napi_env env, napi_value arg, uint32_t &arrayLen) return true; } +void SubAltNameArrayDataClearAndFree(SubAltNameArray *array) +{ + if (array == NULL) { + LOGD("The input array is null, no need to free."); + return; + } + if (array->data != NULL) { + for (uint32_t i = 0; i < array->count; ++i) { + CF_FREE_BLOB(array->data[i].name); + } + CfFree(array->data); + array->data = NULL; + array->count = 0; + } +} + SubAltNameArray *CertGetSANArrFromArrUarrJSParams(napi_env env, napi_value arg) { uint32_t length = 0; diff --git a/frameworks/js/napi/certificate/src/napi_certificate_init.cpp b/frameworks/js/napi/certificate/src/napi_certificate_init.cpp index 69e8f0a..9abf88e 100644 --- a/frameworks/js/napi/certificate/src/napi_certificate_init.cpp +++ b/frameworks/js/napi/certificate/src/napi_certificate_init.cpp @@ -170,6 +170,76 @@ static void DefineGeneralNameTypeProperties(napi_env env, napi_value exports) napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); } +static napi_value CreateRevocationCheckOptions(napi_env env) +{ + napi_value revocationCheckOptions = nullptr; + napi_create_object(env, &revocationCheckOptions); + + CertAddUint32Property( + env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_PREFER_OCSP", CF_REVOCATION_CHECK_OPTION_PREFER_OCSP); + CertAddUint32Property(env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_ACCESS_NETWORK", + CF_REVOCATION_CHECK_OPTION_ACCESS_NETWORK); + CertAddUint32Property(env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER", + CF_REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER); + CertAddUint32Property(env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_FALLBACK_LOCAL", + CF_REVOCATION_CHECK_OPTION_FALLBACK_LOCAL); + + return revocationCheckOptions; +} + +static napi_value CreateValidationPolicyType(napi_env env) +{ + napi_value ValidationPolicyType = nullptr; + napi_create_object(env, &ValidationPolicyType); + + CertAddUint32Property(env, ValidationPolicyType, "VALIDATION_POLICY_TYPE_X509", CF_VALIDATION_POLICY_TYPE_X509); + CertAddUint32Property(env, ValidationPolicyType, "VALIDATION_POLICY_TYPE_SSL", CF_VALIDATION_POLICY_TYPE_SSL); + + return ValidationPolicyType; +} + +static napi_value CreateValidationKeyUsageType(napi_env env) +{ + napi_value ValidationKeyUsageType = nullptr; + napi_create_object(env, &ValidationKeyUsageType); + + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_DIGITAL_SIGNATURE", CF_KEYUSAGE_DIGITAL_SIGNATURE); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_NON_REPUDIATION", CF_KEYUSAGE_NON_REPUDIATION); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_KEY_ENCIPHERMENT", CF_KEYUSAGE_KEY_ENCIPHERMENT); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_DATA_ENCIPHERMENT", CF_KEYUSAGE_DATA_ENCIPHERMENT); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_KEY_AGREEMENT", CF_KEYUSAGE_KEY_AGREEMENT); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_KEY_CERT_SIGN", CF_KEYUSAGE_KEY_CERT_SIGN); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_CRL_SIGN", CF_KEYUSAGE_CRL_SIGN); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_ENCIPHER_ONLY", CF_KEYUSAGE_ENCIPHER_ONLY); + CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_DECIPHER_ONLY", CF_KEYUSAGE_DECIPHER_ONLY); + + return ValidationKeyUsageType; +} + +static void DefineOcspCheckOptionTypeProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("RevocationCheckOptions", CreateRevocationCheckOptions(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + +static void DefineValidationPolicyTypeProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("ValidationPolicyType", CreateValidationPolicyType(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + +static void DefineValidationKeyUsageTypeProperties(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_PROPERTY("KeyUsageType", CreateValidationKeyUsageType(env)), + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); +} + /*********************************************** * Module export and register ***********************************************/ @@ -182,6 +252,9 @@ static napi_value CertModuleExport(napi_env env, napi_value exports) DefineExtensionOidTypeProperties(env, exports); DefineExtensionEntryTypeProperties(env, exports); DefineGeneralNameTypeProperties(env, exports); + DefineOcspCheckOptionTypeProperties(env, exports); + DefineValidationPolicyTypeProperties(env, exports); + DefineValidationKeyUsageTypeProperties(env, exports); NapiKey::DefineHcfKeyJSClass(env); NapiPubKey::DefinePubKeyJSClass(env); diff --git a/frameworks/js/napi/certificate/src/napi_x509_cert_chain_validate_params.cpp b/frameworks/js/napi/certificate/src/napi_x509_cert_chain_validate_params.cpp index ea56350..e22fbb8 100644 --- a/frameworks/js/napi/certificate/src/napi_x509_cert_chain_validate_params.cpp +++ b/frameworks/js/napi/certificate/src/napi_x509_cert_chain_validate_params.cpp @@ -163,6 +163,186 @@ static bool GetCertCRLCollectionArray(napi_env env, napi_value arg, HcfCertCRLCo return true; } +static bool GetRevocationOptions(napi_env env, napi_value rckObj, HcfRevocationCheckParam *&out) +{ + napi_value obj = GetProp(env, rckObj, CERT_CHAIN_VALIDATE_TAG_OPTIONS.c_str()); + if (obj == nullptr) { + return true; + } + bool flag = false; + napi_status status = napi_is_array(env, obj, &flag); + if (status != napi_ok || !flag) { + return false; + } + + uint32_t length = 0; + status = napi_get_array_length(env, obj, &length); + if (status != napi_ok || length == 0 || length > MAX_NAPI_ARRAY_OF_U8ARR) { + return false; + } + out->options = static_cast(HcfMalloc(sizeof(HcfRevChkOpArray), 0)); + out->options->count = length; + out->options->data = static_cast(HcfMalloc(length * sizeof(HcfRevChkOption), 0)); + for (uint32_t i = 0; i < length; i++) { + napi_value element; + if (napi_get_element(env, obj, i, &element) != napi_ok || + napi_get_value_int32(env, element, (int32_t *)&(out->options->data[i])) != napi_ok) { + return false; + } + switch (out->options->data[i]) { + case REVOCATION_CHECK_OPTION_PREFER_OCSP: + case REVOCATION_CHECK_OPTION_ACCESS_NETWORK: + case REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER: + case REVOCATION_CHECK_OPTION_FALLBACK_LOCAL: + break; + default: + return false; + } + } + return true; +} + +static bool GetRevocationDetail(napi_env env, napi_value rckObj, HcfRevocationCheckParam *&out) +{ + napi_value obj = GetProp(env, rckObj, CERT_CHAIN_VALIDATE_TAG_OCSP_REQ_EXTENSION.c_str()); + if (obj != nullptr) { + out->ocspRequestExtension = CertGetBlobArrFromArrUarrJSParams(env, obj); + if (out->ocspRequestExtension == nullptr) { + return false; + } + } + obj = GetProp(env, rckObj, CERT_CHAIN_VALIDATE_TAG_OCSP_RESP_URI.c_str()); + if (obj != nullptr) { + out->ocspResponderURI = CertGetBlobFromStringJSParams(env, obj); + if (out->ocspResponderURI == nullptr) { + return false; + } + } + obj = GetProp(env, rckObj, CERT_CHAIN_VALIDATE_TAG_OCSP_RESP_CERT.c_str()); + if (obj != nullptr) { + NapiX509Certificate *napiX509Cert = nullptr; + napi_unwrap(env, obj, reinterpret_cast(&napiX509Cert)); + if (napiX509Cert != nullptr) { + out->ocspResponderCert = napiX509Cert->GetX509Cert(); + if (out->ocspResponderCert == nullptr) { + return false; + } + } else { + return false; + } + } + obj = GetProp(env, rckObj, CERT_CHAIN_VALIDATE_TAG_OCSP_RESPS.c_str()); + if (obj != nullptr) { + out->ocspResponses = CertGetBlobFromUint8ArrJSParams(env, obj); + if (out->ocspResponses == nullptr) { + return false; + } + } + obj = GetProp(env, rckObj, CERT_CHAIN_VALIDATE_TAG_CRL_DOWNLOAD_URI.c_str()); + if (obj != nullptr) { + out->crlDownloadURI = CertGetBlobFromStringJSParams(env, obj); + if (out->crlDownloadURI == nullptr) { + return false; + } + } + return GetRevocationOptions(env, rckObj, out); +} + +static bool GetRevocationCheckParam(napi_env env, napi_value arg, HcfRevocationCheckParam *&out) +{ + napi_value rckObj = GetProp(env, arg, CERT_CHAIN_VALIDATE_TAG_REVOCATIONCHECKPARAM.c_str()); + if (rckObj == nullptr) { + LOGI("RevocationCheckParam do not exist!"); + return true; + } + napi_valuetype valueType; + napi_typeof(env, rckObj, &valueType); + if (valueType == napi_null || valueType != napi_object) { + LOGE("Failed to check input param!"); + return false; + } + + out = static_cast(HcfMalloc(sizeof(HcfRevocationCheckParam), 0)); + if (out == nullptr) { + LOGE("Failed to allocate out memory!"); + return false; + } + if (!GetRevocationDetail(env, rckObj, out)) { + LOGE("Failed to get revocation detail!"); + CfFree(out); + return false; + } + + return true; +} + +static bool GetValidationPolicyType(napi_env env, napi_value arg, HcfValPolicyType &out) +{ + napi_value obj = GetProp(env, arg, CERT_CHAIN_VALIDATE_TAG_POLICY.c_str()); + if (obj != nullptr) { + napi_status status = napi_get_value_int32(env, obj, (int32_t *)&out); + if (status != napi_ok) { + return false; + } + } + return true; +} + +static bool GetSSLHostname(napi_env env, napi_value arg, CfBlob *&out) +{ + napi_value obj = GetProp(env, arg, CERT_CHAIN_VALIDATE_TAG_SSLHOSTNAME.c_str()); + if (obj == nullptr) { + LOGI("Param type not SSLHostname!"); + return true; + } + out = CertGetBlobFromStringJSParams(env, obj); + if (out == nullptr) { + LOGE("SSLHostname is nullptr"); + return false; + } + return true; +} + +static bool GetKeyUsage(napi_env env, napi_value arg, HcfKuArray *&out) +{ + out = nullptr; + napi_value obj = GetProp(env, arg, CERT_CHAIN_VALIDATE_TAG_KEYUSAGE.c_str()); + if (obj == nullptr) { + return true; + } + bool flag = false; + napi_status status = napi_is_array(env, obj, &flag); + if (status != napi_ok || !flag) { + return false; + } + uint32_t length = 0; + status = napi_get_array_length(env, obj, &length); + if (status != napi_ok || length == 0 || length > MAX_NAPI_ARRAY_OF_U8ARR) { + return false; + } + out = static_cast(HcfMalloc(sizeof(HcfKuArray), 0)); + if (out == nullptr) { + return false; + } + out->count = length; + out->data = static_cast(HcfMalloc(length * sizeof(HcfKeyUsageType), 0)); + if (out->data == nullptr) { + CfFree(out); + out = nullptr; + return false; + } + for (uint32_t i = 0; i < length; i++) { + napi_value element; + if (napi_get_element(env, obj, i, &element) != napi_ok || + napi_get_value_int32(env, element, (int32_t *)&(out->data[i])) != napi_ok) { + CfFree(out); + out = nullptr; + return false; + } + } + return true; +} + void FreeX509CertChainValidateParams(HcfX509CertChainValidateParams ¶m) { CfBlobFree(¶m.date); @@ -223,6 +403,22 @@ bool BuildX509CertChainValidateParams(napi_env env, napi_value arg, HcfX509CertC LOGE("GetCertCRLCollectionArray failed"); return false; } + if (!GetRevocationCheckParam(env, arg, param.revocationCheckParam)) { + LOGE("Get revocation check param failed!"); + return false; + } + if (!GetValidationPolicyType(env, arg, param.policy)) { + LOGE("Get validation policy type failed!"); + return false; + } + if (!GetSSLHostname(env, arg, param.sslHostname)) { + LOGE("Get SSLHostname failed!"); + return false; + } + if (!GetKeyUsage(env, arg, param.keyUsage)) { + LOGE("Get key usage failed!"); + return false; + } return true; } diff --git a/interfaces/innerkits/certificate/x509_cert_chain_validate_params.h b/interfaces/innerkits/certificate/x509_cert_chain_validate_params.h index 0fa59bb..9172ec0 100644 --- a/interfaces/innerkits/certificate/x509_cert_chain_validate_params.h +++ b/interfaces/innerkits/certificate/x509_cert_chain_validate_params.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -24,11 +24,59 @@ #include "cf_blob.h" #include "x509_trust_anchor.h" +typedef enum { + VALIDATION_POLICY_TYPE_X509 = 0, + VALIDATION_POLICY_TYPE_SSL = 1, +} HcfValPolicyType; + +typedef enum { + REVOCATION_CHECK_OPTION_PREFER_OCSP = 0, + REVOCATION_CHECK_OPTION_ACCESS_NETWORK = 1, + REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER = 2, + REVOCATION_CHECK_OPTION_FALLBACK_LOCAL = 3, +} HcfRevChkOption; + +typedef enum { + KEYUSAGE_DIGITAL_SIGNATURE = 0, + KEYUSAGE_NON_REPUDIATION = 1, + KEYUSAGE_KEY_ENCIPHERMENT = 2, + KEYUSAGE_DATA_ENCIPHERMENT = 3, + KEYUSAGE_KEY_AGREEMENT = 4, + KEYUSAGE_KEY_CERT_SIGN = 5, + KEYUSAGE_CRL_SIGN = 6, + KEYUSAGE_ENCIPHER_ONLY = 7, + KEYUSAGE_DECIPHER_ONLY = 8, +} HcfKeyUsageType; + +typedef struct { + HcfKeyUsageType *data; + uint32_t count; +} HcfKuArray; + +typedef struct { + HcfRevChkOption *data; + uint32_t count; +} HcfRevChkOpArray; + +typedef struct HcfRevocationCheckParam HcfRevocationCheckParam; +struct HcfRevocationCheckParam { + CfBlobArray *ocspRequestExtension; + CfBlob *ocspResponderURI; + HcfX509Certificate *ocspResponderCert; + CfBlob *ocspResponses; + CfBlob *crlDownloadURI; + HcfRevChkOpArray *options; +}; + typedef struct HcfX509CertChainValidateParams HcfX509CertChainValidateParams; struct HcfX509CertChainValidateParams { CfBlob *date; // string HcfX509TrustAnchorArray *trustAnchors; // Array HcfCertCRLCollectionArray *certCRLCollections; // Array; + HcfRevocationCheckParam *revocationCheckParam; + HcfValPolicyType policy; + CfBlob *sslHostname; + HcfKuArray *keyUsage; }; #endif // X509_CERT_CHAIN_VALIDATE_PARAMETERS_H diff --git a/interfaces/innerkits/include/cf_type.h b/interfaces/innerkits/include/cf_type.h index 4b71312..8d20516 100644 --- a/interfaces/innerkits/include/cf_type.h +++ b/interfaces/innerkits/include/cf_type.h @@ -79,6 +79,30 @@ typedef enum { CF_GENERAL_NAME_TYPE_REGISTERED_ID } CfGeneralNameType; +typedef enum { + CF_REVOCATION_CHECK_OPTION_PREFER_OCSP, + CF_REVOCATION_CHECK_OPTION_ACCESS_NETWORK, + CF_REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER, + CF_REVOCATION_CHECK_OPTION_FALLBACK_LOCAL, +} CfRevocationCheckOptionsType; + +typedef enum { + CF_VALIDATION_POLICY_TYPE_X509, + CF_VALIDATION_POLICY_TYPE_SSL, +} CfValidationPolicyType; + +typedef enum { + CF_KEYUSAGE_DIGITAL_SIGNATURE, + CF_KEYUSAGE_NON_REPUDIATION, + CF_KEYUSAGE_KEY_ENCIPHERMENT, + CF_KEYUSAGE_DATA_ENCIPHERMENT, + CF_KEYUSAGE_KEY_AGREEMENT, + CF_KEYUSAGE_KEY_CERT_SIGN, + CF_KEYUSAGE_CRL_SIGN, + CF_KEYUSAGE_ENCIPHER_ONLY, + CF_KEYUSAGE_DECIPHER_ONLY, +} CfValidationKeyUsageType; + typedef enum { CF_GET_TYPE_CERT_ITEM, CF_GET_TYPE_EXT_ITEM, diff --git a/test/fuzztest/v1.0/x509certchain_fuzzer/BUILD.gn b/test/fuzztest/v1.0/x509certchain_fuzzer/BUILD.gn new file mode 100644 index 0000000..1cd0471 --- /dev/null +++ b/test/fuzztest/v1.0/x509certchain_fuzzer/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#####################hydra-fuzz################### +import("//build/config/features.gni") +import("//build/test.gni") +module_output_path = "certificate_framework/certificate_framework" + +##############################fuzztest########################################## +ohos_fuzztest("X509CertChainFuzzTest") { + module_out_path = module_output_path + fuzz_config_file = "../x509certchain_fuzzer" + configs = [ "../../../../config/build:coverage_flag_cc" ] + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + sources = [ "x509cert_chain_fuzzer.cpp" ] + + external_deps = [ + "c_utils:utils", + "certificate_framework:certificate_framework_core", + "crypto_framework:crypto_framework_lib", + "hilog:libhilog", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + deps = [] + deps += [ + # deps file + ":X509CertChainFuzzTest", + ] +} +############################################################################### diff --git a/test/fuzztest/v1.0/x509certchain_fuzzer/corpus/init b/test/fuzztest/v1.0/x509certchain_fuzzer/corpus/init new file mode 100644 index 0000000..7e96755 --- /dev/null +++ b/test/fuzztest/v1.0/x509certchain_fuzzer/corpus/init @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FUZZ \ No newline at end of file diff --git a/test/fuzztest/v1.0/x509certchain_fuzzer/project.xml b/test/fuzztest/v1.0/x509certchain_fuzzer/project.xml new file mode 100644 index 0000000..7133b2b --- /dev/null +++ b/test/fuzztest/v1.0/x509certchain_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + diff --git a/test/fuzztest/v1.0/x509certchain_fuzzer/x509cert_chain_fuzzer.cpp b/test/fuzztest/v1.0/x509certchain_fuzzer/x509cert_chain_fuzzer.cpp new file mode 100644 index 0000000..8cedd83 --- /dev/null +++ b/test/fuzztest/v1.0/x509certchain_fuzzer/x509cert_chain_fuzzer.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "x509cert_chain_fuzzer.h" + +#include +#include +#include "securec.h" + +#include "cf_blob.h" +#include "cf_result.h" +#include "x509_cert_chain.h" + +namespace OHOS { + static char g_fuzzCert[] = + "-----BEGIN CERTIFICATE-----\r\n" + "MIIEMjCCAxqgAwIBAgICARAwDQYJKoZIhvcNAQELBQAwdjELMAkGA1UEBhMCQ04x\r\n" + "CzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjELMAkGA1UECgwCSEQxDDAKBgNVBAsM\r\n" + "A2RldjELMAkGA1UEAwwCY2ExJTAjBgkqhkiG9w0BCQEWFmNhQGNyeXB0b2ZyYW1l\r\n" + "d29yay5jb20wHhcNMjIwODE5MTI0OTA2WhcNMzIwODE2MTI0OTA2WjB2MQswCQYD\r\n" + "VQQGEwJDTjELMAkGA1UECAwCQkoxCzAJBgNVBAcMAkJKMQswCQYDVQQKDAJIRDEM\r\n" + "MAoGA1UECwwDZGV2MQswCQYDVQQDDAJjYTElMCMGCSqGSIb3DQEJARYWY2FAY3J5\r\n" + "cHRvZnJhbWV3b3JrLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\r\n" + "AJ8p0IWE7WwwbtATg+AbYQj33WNBBktU+/AVf+Tl1aAa4TOeW2/ZARc4sdwLVTxd\r\n" + "XCipFseuiGN30hwXrXFUHrcMf0w2sCkznJVZ/rQcfEO5Kb1vBz6DEEcgISYEhhqO\r\n" + "BfYBit5qfpq5R2+2R/Th/ybV+kBrUl+GssXbDAe6oZCy56lGphDvmHMUO7a13j+S\r\n" + "FmThMbI2yeyua1LagSoaBJfY1J+i7jWPmmEFR0dQ2p0EGjHTgQGhRo5VuwDHipNS\r\n" + "v0XP8OUA/PYbL/SBj1Fq4C3gtfvjeswUbzVaMoq/wCuy1qcXI80ZLe3whR24c0cX\r\n" + "YFO0uGi9egPp24fw7yYGqgECAwEAAaOByTCBxjAdBgNVHQ4EFgQUjKM7QmMBs01R\r\n" + "9uQttYN/GDkvt7UwHwYDVR0jBBgwFoAUjKM7QmMBs01R9uQttYN/GDkvt7UwEgYD\r\n" + "VR0TAQH/BAgwBgEB/wIBAjALBgNVHQ8EBAMCAQYwHQYDVR0lBBYwFAYIKwYBBQUH\r\n" + "AwEGCCsGAQUFBwMCMCEGA1UdEQQaMBiBFmNhQGNyeXB0b2ZyYW1ld29yay5jb20w\r\n" + "IQYDVR0SBBowGIEWY2FAY3J5cHRvZnJhbWV3b3JrLmNvbTANBgkqhkiG9w0BAQsF\r\n" + "AAOCAQEAh+4RE6cJ62/gLYssLkc7ESg7exKwZlmisHyBicuy/+XagOZ3cTbgQNXl\r\n" + "QoZKbw/ks/B/cInbQGYbpAm47Sudo+I/G9xj0X7gQB9wtSrbStOs6SjnLiYU0xFc\r\n" + "Fsc0j6k2SrlyiwRQcjS4POKiUS0Cm3F3DHGdj55PlBkXxudXCq2V3J3VwKf2bVjQ\r\n" + "bzz2+M/Q1m+P7FhB+JmeO8eemkqMQ0tFMU3EM441NpejC5iFVAGgownC8S0B+fxH\r\n" + "9dBJuHM6vpxEWw3ckZFDZQ1kd91YRgr7jY8fc0v/T0tzHWbOEVzklEIBWL1mompL\r\n" + "BCwe0/Gw+BO60bfi2MoJw8t2IcB1Qw==\r\n" + "-----END CERTIFICATE-----\r\n"; + + static char g_fuzzDate[] = "20231212080000Z"; + static uint8_t g_fuzzPubKey[] = { + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd0, 0x35, 0x39, 0x92, 0x49, 0xb5, + 0x95, 0x08, 0xef, 0x38, 0xf8, 0xa8, 0x51, 0xd3, 0xef, 0xd8, 0x3e, 0x3a, 0xd9, + 0x2c, 0xe1, 0x31, 0x1f, 0x99, 0x41, 0x03, 0x86, 0xb3, 0x4a, 0x04, 0x41, 0x23, + 0x6f, 0xf8, 0xb6, 0xf4, 0x60, 0x5f, 0x9e, 0x9b, 0xc5, 0x75, 0x3d, 0xfa, 0x6b, + 0x30, 0xa0, 0xd9, 0x53, 0x83, 0x25, 0x14, 0xa3, 0x23, 0x31, 0x67, 0xe2, 0xa0, + 0x03, 0x71, 0xcf, 0x38, 0x12, 0x67, 0xca, 0x88, 0x31, 0x0c, 0xf7, 0xb1, 0xc5, + 0xb1, 0x03, 0xe9, 0xf5, 0x14, 0x64, 0xab, 0x11, 0xf9, 0x70, 0x1e, 0x75, 0x11, + 0x4d, 0x9e, 0x04, 0x4f, 0x54, 0x6b, 0xde, 0x71, 0xfb, 0x04, 0x29, 0xfc, 0xa4, + 0x9d, 0x0a, 0xa2, 0x13, 0x09, 0x0f, 0xef, 0xca, 0xf9, 0xb7, 0x27, 0x85, 0x29, + 0x8e, 0x5d, 0x30, 0x95, 0x6f, 0x30, 0x44, 0x23, 0xc2, 0x59, 0xc6, 0x30, 0xde, + 0x92, 0x82, 0x94, 0x64, 0x64, 0x37, 0x35, 0x6d, 0x23, 0x52, 0x97, 0x9d, 0xfa, + 0x67, 0xed, 0xf1, 0xb7, 0x37, 0xce, 0x27, 0xef, 0x09, 0x41, 0x6f, 0xd2, 0x06, + 0x28, 0x91, 0x5a, 0x73, 0xfe, 0xbe, 0x87, 0x1b, 0xd9, 0xc7, 0x6a, 0xa7, 0x7c, + 0xbb, 0x31, 0x74, 0x82, 0x91, 0xd1, 0x0f, 0xdb, 0x88, 0x6a, 0x14, 0xe9, 0x9f, + 0x08, 0xcb, 0xf4, 0x7f, 0xa7, 0xb1, 0xa8, 0x3c, 0xef, 0x2f, 0x6a, 0x65, 0x74, + 0xf7, 0x4f, 0x90, 0x1c, 0x42, 0xf9, 0x01, 0xd4, 0xb3, 0x2a, 0xd1, 0x21, 0x53, + 0xdb, 0xdd, 0xbd, 0xcb, 0x96, 0x8e, 0x32, 0xf1, 0x56, 0x76, 0x89, 0x2d, 0xf8, + 0xff, 0xe9, 0x6a, 0x06, 0x66, 0x3f, 0x14, 0x5a, 0x7d, 0xf3, 0x15, 0xb1, 0x28, + 0x4d, 0x56, 0x80, 0x7e, 0x9d, 0xb1, 0xa9, 0xdc, 0xd6, 0xef, 0x24, 0x6f, 0x8b, + 0x6a, 0xf5, 0xe3, 0xc9, 0xbd, 0x7a, 0xfe, 0xe5, 0x8c, 0x3a, 0x87, 0xa3, 0xc5, + 0x17, 0xeb, 0xdb, 0x02, 0x03, 0x01, 0x00, 0x01 + }; + static uint8_t g_fuzzSubject[] = { + 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, + 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x47, 0x65, 0x6f, + 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x4e, 0x20, + 0x43, 0x41, 0x20, 0x47, 0x32 + }; + static char g_fuzzSslHostName[] = "*.163.com"; + constexpr int TEST_DATA_LEN = 1; + static bool g_testFlag = true; + + static void FreeTrustAnchor(HcfX509TrustAnchor *trustAnchor) + { + if (trustAnchor == nullptr) { + return; + } + CfBlobFree(&trustAnchor->CAPubKey); + CfBlobFree(&trustAnchor->CASubject); + CfObjDestroy(trustAnchor->CACert); + trustAnchor->CACert = nullptr; + free(trustAnchor); + trustAnchor = nullptr; + } + + static void FreeValidateResult(HcfX509CertChainValidateResult *result) + { + if (result->entityCert != nullptr) { + CfObjDestroy(result->entityCert); + result->entityCert = nullptr; + } + + if (result->trustAnchor != nullptr) { + FreeTrustAnchor(result->trustAnchor); + } + } + + static void TestValidateParam(HcfX509CertChainValidateParams ¶ms, HcfCertChain *x509CertChainObj) + { + CfBlob date = { 0 }; + date.data = reinterpret_cast(g_fuzzDate); + date.size = strlen(g_fuzzDate) + 1; + HcfX509TrustAnchorArray trustAnchors = { 0 }; + HcfX509TrustAnchor anchor = { 0 }; + CfBlob caPubKey = { 0 }; + caPubKey.data = g_fuzzPubKey; + caPubKey.size = strlen(reinterpret_cast(g_fuzzPubKey)) + 1; + anchor.CAPubKey = &caPubKey; + CfBlob caSubject = { 0 }; + caSubject.data = g_fuzzSubject; + caSubject.size = strlen(reinterpret_cast(g_fuzzSubject)) + 1; + anchor.CASubject = &caSubject; + trustAnchors.data = static_cast( + calloc(TEST_DATA_LEN * sizeof(HcfX509TrustAnchor *), 0)); + if (trustAnchors.data == nullptr) { + return; + } + trustAnchors.data[0] = &anchor; + trustAnchors.count = TEST_DATA_LEN; + + HcfRevocationCheckParam revocationCheckParam = { 0 }; + HcfRevChkOpArray optionData = { 0 }; + HcfRevChkOption option[TEST_DATA_LEN] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + optionData.data = option; + optionData.count = TEST_DATA_LEN; + revocationCheckParam.options = &optionData; + + CfBlob sslHostname = { 0 }; + sslHostname.data = reinterpret_cast(g_fuzzSslHostName); + sslHostname.size = strlen(g_fuzzSslHostName) + 1; + HcfKuArray keyUsage = { 0 }; + HcfKeyUsageType type[TEST_DATA_LEN] = { KEYUSAGE_DIGITAL_SIGNATURE }; + keyUsage.data = type; + keyUsage.count = TEST_DATA_LEN; + + params.date = &date; + params.trustAnchors = &trustAnchors; + params.sslHostname = &sslHostname; + params.policy = HcfValPolicyType::VALIDATION_POLICY_TYPE_SSL; + params.keyUsage = &keyUsage; + params.revocationCheckParam = &revocationCheckParam; + HcfX509CertChainValidateResult result = { 0 }; + (void)x509CertChainObj->validate(x509CertChainObj, ¶ms, &result); + FreeValidateResult(&result); + free(params.trustAnchors->data); + } + + static void TestQuery(HcfCertChain *x509CertChainObj) + { + HcfX509CertChainValidateParams params = { 0 }; + TestValidateParam(params, x509CertChainObj); + } + + static void CreateOneCert(void) + { + CfEncodingBlob inStream = { 0 }; + inStream.data = reinterpret_cast(g_fuzzCert); + inStream.encodingFormat = CF_FORMAT_PEM; + inStream.len = strlen(g_fuzzCert) + 1; + HcfCertChain *x509CertChainObj = nullptr; + CfResult res = HcfCertChainCreate(&inStream, nullptr, &x509CertChainObj); + if (res != CF_SUCCESS) { + return; + } + TestQuery(x509CertChainObj); + CfObjDestroy(x509CertChainObj); + } + + bool X509CertChainFuzzTest(const uint8_t* data, size_t size) + { + if (g_testFlag) { + CreateOneCert(); + g_testFlag = false; + } + if (data == nullptr) { + return false; + } + CfEncodingBlob inStream = { 0 }; + inStream.data = const_cast(data); + inStream.encodingFormat = CF_FORMAT_PEM; + inStream.len = size; + HcfCertChain *x509CertChainObj = nullptr; + CfResult res = HcfCertChainCreate(&inStream, nullptr, &x509CertChainObj); + if (res != CF_SUCCESS) { + return false; + } + CfObjDestroy(x509CertChainObj); + + return true; + } +} + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + /* Run your code on data */ + OHOS::X509CertChainFuzzTest(data, size); + return 0; +} diff --git a/test/fuzztest/v1.0/x509certchain_fuzzer/x509cert_chain_fuzzer.h b/test/fuzztest/v1.0/x509certchain_fuzzer/x509cert_chain_fuzzer.h new file mode 100644 index 0000000..dd2f8bf --- /dev/null +++ b/test/fuzztest/v1.0/x509certchain_fuzzer/x509cert_chain_fuzzer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef X509_CERT_CHAIN_FUZZER_H +#define X509_CERT_CHAIN_FUZZER_H + +#define FUZZ_PROJECT_NAME "x509cert_chain_fuzzer" + +#endif \ No newline at end of file diff --git a/test/unittest/v1.0/BUILD.gn b/test/unittest/v1.0/BUILD.gn index 565d8d8..6bae064 100644 --- a/test/unittest/v1.0/BUILD.gn +++ b/test/unittest/v1.0/BUILD.gn @@ -36,6 +36,7 @@ ohos_unittest("cf_version1_test") { sources = [ "src/cf_mock.cpp", "src/crypto_x509_cert_chain_test.cpp", + "src/crypto_x509_cert_chain_test_part2.cpp", "src/crypto_x509_cert_chain_validator_test.cpp", "src/crypto_x509_cert_crl_collection_test.cpp", "src/crypto_x509_certificate_test.cpp", @@ -102,17 +103,22 @@ ohos_unittest("cf_version1_test") { "-Wl,--wrap=OBJ_obj2nid", "-Wl,--wrap=OBJ_nid2obj", "-Wl,--wrap=OBJ_obj2txt", + "-Wl,--wrap=OCSP_REQUEST_new", + "-Wl,--wrap=OSSL_HTTP_parse_url", "-Wl,--wrap=OPENSSL_sk_deep_copy", "-Wl,--wrap=OPENSSL_sk_num", "-Wl,--wrap=OPENSSL_sk_value", "-Wl,--wrap=OPENSSL_sk_new_null", "-Wl,--wrap=OPENSSL_sk_push", "-Wl,--wrap=X509_ALGOR_get0", + "-Wl,--wrap=X509_check_host", + "-Wl,--wrap=X509_CRL_load_http", "-Wl,--wrap=X509_dup", "-Wl,--wrap=X509_get_pubkey", "-Wl,--wrap=X509_get_ext", "-Wl,--wrap=X509_get_ext_d2i", "-Wl,--wrap=X509_get0_serialNumber", + "-Wl,--wrap=X509_get1_ocsp", "-Wl,--wrap=X509_getm_notBefore", "-Wl,--wrap=X509_getm_notAfter", "-Wl,--wrap=X509_NAME_oneline", @@ -139,5 +145,6 @@ ohos_unittest("cf_version1_test") { "googletest:gmock", "hilog:libhilog", "openssl:libcrypto_shared", + "openssl:libssl_shared", ] } diff --git a/test/unittest/v1.0/include/cf_mock.h b/test/unittest/v1.0/include/cf_mock.h index f52e94e..ebd2351 100644 --- a/test/unittest/v1.0/include/cf_mock.h +++ b/test/unittest/v1.0/include/cf_mock.h @@ -18,72 +18,83 @@ #include #include #include +#include #include #include "certificate_openssl_common.h" #include "x509_certificate.h" #include "x509_certificate_openssl.h" +using ::testing::NiceMock; + namespace CFMock { class X509OpensslMock { public: - MOCK_METHOD2(i2d_X509_EXTENSIONS, int(X509_EXTENSIONS *a, unsigned char **out)); - MOCK_METHOD1(OPENSSL_sk_num, int(const OPENSSL_STACK *st)); - MOCK_METHOD1(X509_getm_notBefore, ASN1_TIME *(const X509 *x)); - MOCK_METHOD1(X509_getm_notAfter, ASN1_TIME *(const X509 *x)); - MOCK_METHOD3(X509_NAME_oneline, char *(const X509_NAME *a, char *buf, int size)); - MOCK_METHOD2(i2d_X509, int(X509 *a, unsigned char **out)); - MOCK_METHOD2(BIO_new_mem_buf, BIO *(const void *buf, int len)); - MOCK_METHOD2(OPENSSL_sk_value, void *(const OPENSSL_STACK *st, int i)); - MOCK_METHOD2(HcfX509CertificateCreate, CfResult(const CfEncodingBlob *inStream, HcfX509Certificate **returnObj)); - MOCK_METHOD0(OPENSSL_sk_new_null, OPENSSL_STACK *(void)); - MOCK_METHOD2(X509_STORE_add_cert, int(X509_STORE *ctx, X509 *x)); - MOCK_METHOD0(X509_STORE_CTX_new, X509_STORE_CTX *(void)); - MOCK_METHOD0(X509_STORE_new, X509_STORE *(void)); - MOCK_METHOD4(X509_STORE_CTX_init, int(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) * chain)); - MOCK_METHOD1(X509_verify_cert, int(X509_STORE_CTX *ctx)); - MOCK_METHOD2(i2d_PUBKEY, int(EVP_PKEY *a, unsigned char **pp)); - MOCK_METHOD4(X509_get_ext_d2i, void *(const X509 *x, int nid, int *crit, int *idx)); - MOCK_METHOD2(i2d_ASN1_OCTET_STRING, int(ASN1_OCTET_STRING *a, unsigned char **out)); - MOCK_METHOD2(i2d_AUTHORITY_KEYID, int(AUTHORITY_KEYID *a, unsigned char **out)); - MOCK_METHOD3(DeepCopyDataToBlob, CfResult(const unsigned char *data, uint32_t len, CfBlob *outBlob)); - MOCK_METHOD0(ASN1_TIME_new, ASN1_TIME *(void)); - MOCK_METHOD1(X509_get0_serialNumber, const ASN1_INTEGER *(const X509 *x)); - MOCK_METHOD2(i2d_ASN1_INTEGER, int(ASN1_INTEGER *a, unsigned char **out)); - MOCK_METHOD1(X509_get_pubkey, EVP_PKEY *(X509 *x)); - MOCK_METHOD1(OBJ_nid2obj, ASN1_OBJECT *(int n)); - MOCK_METHOD4(OBJ_obj2txt, int(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)); - MOCK_METHOD3(BN_bin2bn, BIGNUM *(const unsigned char *s, int len, BIGNUM *ret)); - MOCK_METHOD1(ASN1_TIME_normalize, int(ASN1_TIME *s)); - MOCK_METHOD4( - X509_ALGOR_get0, void(const ASN1_OBJECT **paobj, int *pptype, const void **ppval, const X509_ALGOR *algor)); - MOCK_METHOD0(ASN1_TYPE_new, ASN1_TYPE *(void)); - MOCK_METHOD3(ASN1_TYPE_set1, int(ASN1_TYPE *a, int type, const void *value)); - MOCK_METHOD2(i2d_ASN1_TYPE, int(ASN1_TYPE *a, unsigned char **out)); - MOCK_METHOD1(ASN1_INTEGER_get, long(const ASN1_INTEGER *a)); - MOCK_METHOD1(ASN1_STRING_get0_data, const unsigned char *(const ASN1_STRING *x)); - MOCK_METHOD2(i2d_GENERAL_NAME, int(GENERAL_NAME *a, unsigned char **out)); - MOCK_METHOD2(X509_get_ext, X509_EXTENSION *(const X509 *x, X509_EXTENSION *loc)); - MOCK_METHOD1(X509V3_EXT_d2i, void *(X509_EXTENSION *ext)); - MOCK_METHOD2(GENERAL_NAME_get0_value, void *(const GENERAL_NAME *a, int *ptype)); - MOCK_METHOD2(X509_verify, int(X509 *a, EVP_PKEY *r)); - MOCK_METHOD2(DeepCopyBlobToBlob, CfResult(const CfBlob *inBlob, CfBlob **outBlob)); - MOCK_METHOD2(OPENSSL_sk_push, int(OPENSSL_STACK *st, const int data)); - MOCK_METHOD2(i2d_X509_REVOKED, int(X509_REVOKED *a, unsigned char **out)); - MOCK_METHOD2(i2d_X509_CRL, int(X509_CRL *a, unsigned char **out)); - MOCK_METHOD3( - OPENSSL_sk_deep_copy, OPENSSL_STACK *(const OPENSSL_STACK *, OPENSSL_sk_copyfunc c, OPENSSL_sk_freefunc f)); - MOCK_METHOD1(OBJ_obj2nid, int(const ASN1_OBJECT *o)); - MOCK_METHOD1(X509_dup, X509 *(X509 *x509)); + MOCK_METHOD(int, i2d_X509_EXTENSIONS, (X509_EXTENSIONS * a, unsigned char **out)); + MOCK_METHOD(int, OPENSSL_sk_num, (const OPENSSL_STACK *st)); + MOCK_METHOD(ASN1_TIME *, X509_getm_notBefore, (const X509 *x)); + MOCK_METHOD(ASN1_TIME *, X509_getm_notAfter, (const X509 *x)); + MOCK_METHOD(char *, X509_NAME_oneline, (const X509_NAME *a, char *buf, int size)); + MOCK_METHOD(int, i2d_X509, (X509 * a, unsigned char **out)); + MOCK_METHOD(BIO *, BIO_new_mem_buf, (const void *buf, int len)); + MOCK_METHOD(void *, OPENSSL_sk_value, (const OPENSSL_STACK *st, int i)); + MOCK_METHOD(CfResult, HcfX509CertificateCreate, (const CfEncodingBlob *inStream, HcfX509Certificate **returnObj)); + MOCK_METHOD(OPENSSL_STACK *, OPENSSL_sk_new_null, ()); + MOCK_METHOD(int, X509_STORE_add_cert, (X509_STORE * ctx, X509 *x)); + MOCK_METHOD(X509_STORE_CTX *, X509_STORE_CTX_new, ()); + MOCK_METHOD(X509_STORE *, X509_STORE_new, ()); + MOCK_METHOD( + int, X509_STORE_CTX_init, (X509_STORE_CTX * ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) * chain)); + MOCK_METHOD(int, X509_verify_cert, (X509_STORE_CTX * ctx)); + MOCK_METHOD(int, i2d_PUBKEY, (EVP_PKEY * a, unsigned char **pp)); + MOCK_METHOD(void *, X509_get_ext_d2i, (const X509 *x, int nid, int *crit, int *idx)); + MOCK_METHOD(int, i2d_ASN1_OCTET_STRING, (ASN1_OCTET_STRING * a, unsigned char **out)); + MOCK_METHOD(int, i2d_AUTHORITY_KEYID, (AUTHORITY_KEYID * a, unsigned char **out)); + MOCK_METHOD(CfResult, DeepCopyDataToBlob, (const unsigned char *data, uint32_t len, CfBlob *outBlob)); + MOCK_METHOD(ASN1_TIME *, ASN1_TIME_new, ()); + MOCK_METHOD(const ASN1_INTEGER *, X509_get0_serialNumber, (const X509 *x)); + MOCK_METHOD(int, i2d_ASN1_INTEGER, (ASN1_INTEGER * a, unsigned char **out)); + MOCK_METHOD(EVP_PKEY *, X509_get_pubkey, (X509 * x)); + MOCK_METHOD(ASN1_OBJECT *, OBJ_nid2obj, (int n)); + MOCK_METHOD(int, OBJ_obj2txt, (char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)); + MOCK_METHOD(BIGNUM *, BN_bin2bn, (const unsigned char *s, int len, BIGNUM *ret)); + MOCK_METHOD(int, ASN1_TIME_normalize, (ASN1_TIME * s)); + MOCK_METHOD( + void, X509_ALGOR_get0, (const ASN1_OBJECT **paobj, int *pptype, const void **ppval, const X509_ALGOR *algor)); + MOCK_METHOD(ASN1_TYPE *, ASN1_TYPE_new, ()); + MOCK_METHOD(int, ASN1_TYPE_set1, (ASN1_TYPE * a, int type, const void *value)); + MOCK_METHOD(int, i2d_ASN1_TYPE, (ASN1_TYPE * a, unsigned char **out)); + MOCK_METHOD(long, ASN1_INTEGER_get, (const ASN1_INTEGER *a)); + MOCK_METHOD(const unsigned char *, ASN1_STRING_get0_data, (const ASN1_STRING *x)); + MOCK_METHOD(int, i2d_GENERAL_NAME, (GENERAL_NAME * a, unsigned char **out)); + MOCK_METHOD(X509_EXTENSION *, X509_get_ext, (const X509 *x, X509_EXTENSION *loc)); + MOCK_METHOD(void *, X509V3_EXT_d2i, (X509_EXTENSION * ext)); + MOCK_METHOD(void *, GENERAL_NAME_get0_value, (const GENERAL_NAME *a, int *ptype)); + MOCK_METHOD(int, X509_verify, (X509 * a, EVP_PKEY *r)); + MOCK_METHOD(CfResult, DeepCopyBlobToBlob, (const CfBlob *inBlob, CfBlob **outBlob)); + MOCK_METHOD(int, OPENSSL_sk_push, (OPENSSL_STACK * st, const int data)); + MOCK_METHOD(int, i2d_X509_REVOKED, (X509_REVOKED * a, unsigned char **out)); + MOCK_METHOD(int, i2d_X509_CRL, (X509_CRL * a, unsigned char **out)); + MOCK_METHOD( + OPENSSL_STACK *, OPENSSL_sk_deep_copy, (const OPENSSL_STACK *, OPENSSL_sk_copyfunc c, OPENSSL_sk_freefunc f)); + MOCK_METHOD(int, OBJ_obj2nid, (const ASN1_OBJECT *o)); + MOCK_METHOD(X509 *, X509_dup, (X509 * x509)); + MOCK_METHOD(int, X509_check_host, (X509 * x, const char *chk, size_t chklen, unsigned int flags, char **peername)); + MOCK_METHOD(OCSP_REQUEST *, OCSP_REQUEST_new, ()); + MOCK_METHOD(X509_CRL *, X509_CRL_load_http, (const char *url, BIO *bio, BIO *rbio, int timeout)); + MOCK_METHOD(struct stack_st_OPENSSL_STRING *, X509_get1_ocsp, (X509 * x)); + MOCK_METHOD(int, OSSL_HTTP_parse_url, + (const char *url, int *pssl, char **puser, char **phost, char **pport, int *pport_num, char **ppath, + char **pquery, char **pfrag)); - static X509OpensslMock &GetInstance(void); + static NiceMock &GetInstance(void); static void SetMockFlag(bool flag); static bool GetMockFlag(void); -private: X509OpensslMock(); - virtual ~X509OpensslMock(); + ~X509OpensslMock(); +private: void SetMockFunDefaultBehaviorPartOne(void); void SetMockFunDefaultBehaviorPartTwo(void); void SetMockFunDefaultBehaviorPartThree(void); diff --git a/test/unittest/v1.0/include/crypto_x509_cert_chain_data_pem_ex.h b/test/unittest/v1.0/include/crypto_x509_cert_chain_data_pem_ex.h index 1c32ba2..e282ba4 100644 --- a/test/unittest/v1.0/include/crypto_x509_cert_chain_data_pem_ex.h +++ b/test/unittest/v1.0/include/crypto_x509_cert_chain_data_pem_ex.h @@ -22,6 +22,138 @@ extern "C" { #endif +static const char g_testCertChainPem163[] = + "-----BEGIN CERTIFICATE-----\r\n" + "MIIGVjCCBT6gAwIBAgIQBMO0W3CU9LWVw1bE/jqYojANBgkqhkiG9w0BAQsFADBE\r\n" + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMR4wHAYDVQQDExVH\r\n" + "ZW9UcnVzdCBSU0EgQ04gQ0EgRzIwHhcNMjMwMzIzMDAwMDAwWhcNMjQwNDIyMjM1\r\n" + "OTU5WjB1MQswCQYDVQQGEwJDTjERMA8GA1UECBMIemhlamlhbmcxETAPBgNVBAcT\r\n" + "CGhhbmd6aG91MSwwKgYDVQQKEyNOZXRFYXNlIChIYW5nemhvdSkgTmV0d29yayBD\r\n" + "by4sIEx0ZDESMBAGA1UEAwwJKi4xNjMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC\r\n" + "AQ8AMIIBCgKCAQEAwELks0Q1Z81u1OpbGdEFE2Snm/WpLfmiC5YFj5nFrinSX+UZ\r\n" + "MIk42euBdjYSsWFxbljmWDdUCjstMhG8vRAjz3Nt1QniMCunHHFGujR5rSNLWYHE\r\n" + "vCPhfptIhqOaE/rvkWGZZr2KjTQQN0dRf8dm9Oewy8DHu95c9jW6c9AVgKWUVOni\r\n" + "tTOcJCnrndWjgCIPfKmKgrwaNaMnuQyy5nPIUHl/5EGzuGHrwjwlF+w+cT+Fwdix\r\n" + "C3msEOCwX6wzo6baDs4og2EzuPNyTp4n4UqH5aHhLePgBFboOAyJwWp3+XJNpNGw\r\n" + "GkU56cUUy7+AAn268EVvUNr7uQ65t2t+Ys32bQIDAQABo4IDETCCAw0wHwYDVR0j\r\n" + "BBgwFoAUJG+RP4mHhw4ywkAY38VM60/ISTIwHQYDVR0OBBYEFD1HyRYJ5jqkvYL7\r\n" + "C6TSt8/y3e7hMB0GA1UdEQQWMBSCCSouMTYzLmNvbYIHMTYzLmNvbTAOBgNVHQ8B\r\n" + "Af8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMD0GA1UdHwQ2\r\n" + "MDQwMqAwoC6GLGh0dHA6Ly9jcmwuZGlnaWNlcnQuY24vR2VvVHJ1c3RSU0FDTkNB\r\n" + "RzIuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQICMCkwJwYIKwYBBQUHAgEWG2h0dHA6\r\n" + "Ly93d3cuZGlnaWNlcnQuY29tL0NQUzBxBggrBgEFBQcBAQRlMGMwIwYIKwYBBQUH\r\n" + "MAGGF2h0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNuMDwGCCsGAQUFBzAChjBodHRwOi8v\r\n" + "Y2FjZXJ0cy5kaWdpY2VydC5jbi9HZW9UcnVzdFJTQUNOQ0FHMi5jcnQwCQYDVR0T\r\n" + "BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHUA7s3QZNXbGs7FXLedtM0T\r\n" + "ojKHRny87N7DUUhZRnEftZsAAAGHDSE15QAABAMARjBEAiBRpmsJ3F9AI8wFxqOQ\r\n" + "bHp+RL6F8cvNydajQ0Bqxjvd3AIgefAU/po3jBm+96dFVdbX+AG1uss67DL3VL5I\r\n" + "nUmVva8AdgBz2Z6JG0yWeKAgfUed5rLGHNBRXnEZKoxrgBB6wXdytQAAAYcNITZS\r\n" + "AAAEAwBHMEUCID/sUP12odF7uTTEyE0PjCpKo3nF7A3ba3b5wJJsZrDrAiEAxrat\r\n" + "W2eeZTD458LPSPrMMBb1/o6zibWXqJCQye+bVFwAdwBIsONr2qZHNA/lagL6nTDr\r\n" + "HFIBy1bdLIHZu7+rOdiEcwAAAYcNITYeAAAEAwBIMEYCIQCCJ2ktM1F+d1I5mQju\r\n" + "Tn7oDYxy3GCGyG3u/yhu8k7EaAIhANSP8cAaMQFV6y8B2tubKY5eSQtgkF3a6NNq\r\n" + "QJjtPnoHMA0GCSqGSIb3DQEBCwUAA4IBAQC8dK/G4nvs/SyQe/mnK+rUYIdSFs+4\r\n" + "lgzatmq8V/I1tBly+Sv/FPhnn4F3iCrqy9j8y202FP51ev95DGbjlJRTIFPqVAO8\r\n" + "ywYrLhvl1SJhV0b/8NF0Pr3dZVnK5Vfn11+LSBUg0cBB2hcVV30nv3IuVhz3d12n\r\n" + "P+VseYQgMpQf7ad+ttpZtA7yqHzrUm4fzr03G7q88GztACRSHoYiPbOlz99SeTgW\r\n" + "7bzZl1I4taxy2Q3b0ZBGfUt/kPY05tpKzKwDTbbqSErYszCt5X1RfVvf3coxF8Mo\r\n" + "9bHbs2wYIzQBdujDQ/hU0u6ItERer3SUItZoxaSIxdrZ9eXFwVvXsT/g\r\n" + "-----END CERTIFICATE-----\r\n" + "-----BEGIN CERTIFICATE-----\r\n" + "MIIFDzCCA/egAwIBAgIQCxNitu5qnT6WiTDxbiB9OTANBgkqhkiG9w0BAQsFADBh\r\n" + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n" + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\r\n" + "QTAeFw0yMDAzMDQxMjA0NDBaFw0zMDAzMDQxMjA0NDBaMEQxCzAJBgNVBAYTAlVT\r\n" + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxHjAcBgNVBAMTFUdlb1RydXN0IFJTQSBD\r\n" + "TiBDQSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANA1OZJJtZUI\r\n" + "7zj4qFHT79g+Otks4TEfmUEDhrNKBEEjb/i29GBfnpvFdT36azCg2VODJRSjIzFn\r\n" + "4qADcc84EmfKiDEM97HFsQPp9RRkqxH5cB51EU2eBE9Ua95x+wQp/KSdCqITCQ/v\r\n" + "yvm3J4Upjl0wlW8wRCPCWcYw3pKClGRkNzVtI1KXnfpn7fG3N84n7wlBb9IGKJFa\r\n" + "c/6+hxvZx2qnfLsxdIKR0Q/biGoU6Z8Iy/R/p7GoPO8vamV090+QHEL5AdSzKtEh\r\n" + "U9vdvcuWjjLxVnaJLfj/6WoGZj8UWn3zFbEoTVaAfp2xqdzW7yRvi2r148m9ev7l\r\n" + "jDqHo8UX69sCAwEAAaOCAd4wggHaMB0GA1UdDgQWBBQkb5E/iYeHDjLCQBjfxUzr\r\n" + "T8hJMjAfBgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8E\r\n" + "BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQI\r\n" + "MAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz\r\n" + "cC5kaWdpY2VydC5jbjBABgNVHR8EOTA3MDWgM6Axhi9odHRwOi8vY3JsLmRpZ2lj\r\n" + "ZXJ0LmNuL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDCB3QYDVR0gBIHVMIHSMIHF\r\n" + "BglghkgBhv1sAQEwgbcwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0\r\n" + "LmNvbS9DUFMwgYoGCCsGAQUFBwICMH4MfEFueSB1c2Ugb2YgdGhpcyBDZXJ0aWZp\r\n" + "Y2F0ZSBjb25zdGl0dXRlcyBhY2NlcHRhbmNlIG9mIHRoZSBSZWx5aW5nIFBhcnR5\r\n" + "IEFncmVlbWVudCBsb2NhdGVkIGF0IGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9y\r\n" + "cGEtdWEwCAYGZ4EMAQICMA0GCSqGSIb3DQEBCwUAA4IBAQCzkcXq0TN0oSn4UeXp\r\n" + "FBW7U8zrHBIhH9MXHNBp+Yy/yN19133UY05uuHXHaU2Uv0hxefckjPdkaX7ARso+\r\n" + "O3Ar6nf7YfBwCqSpqsNckKT7KKtf3Ot95wYFpKDa64jcRUfxzRWnmq12IVzczqHI\r\n" + "sIvUZQINw/UHSQcWekdUnMg58bQSHyTjwkj9jcX2RURxaVZkr15wxo/Z3Ydo2PVK\r\n" + "3afEr0/vcuFvE7QeGXiI2DJdVt3JefatZ3rj4VTW2aUZwHGUiWWIUudBfQKR0JEp\r\n" + "lJ8MFaKDh4/A2VEJnXILu1iwvc1m3jCaPuzZKdoHM/1234bznJI2aAfhfIhoHw90\r\n" + "tPO+\r\n" + "-----END CERTIFICATE-----\r\n"; + +static const char g_testOcspResponderCert[] = + "-----BEGIN CERTIFICATE-----\r\n" + "MIIFDzCCA/egAwIBAgIQCxNitu5qnT6WiTDxbiB9OTANBgkqhkiG9w0BAQsFADBh\r\n" + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n" + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\r\n" + "QTAeFw0yMDAzMDQxMjA0NDBaFw0zMDAzMDQxMjA0NDBaMEQxCzAJBgNVBAYTAlVT\r\n" + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxHjAcBgNVBAMTFUdlb1RydXN0IFJTQSBD\r\n" + "TiBDQSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANA1OZJJtZUI\r\n" + "7zj4qFHT79g+Otks4TEfmUEDhrNKBEEjb/i29GBfnpvFdT36azCg2VODJRSjIzFn\r\n" + "4qADcc84EmfKiDEM97HFsQPp9RRkqxH5cB51EU2eBE9Ua95x+wQp/KSdCqITCQ/v\r\n" + "yvm3J4Upjl0wlW8wRCPCWcYw3pKClGRkNzVtI1KXnfpn7fG3N84n7wlBb9IGKJFa\r\n" + "c/6+hxvZx2qnfLsxdIKR0Q/biGoU6Z8Iy/R/p7GoPO8vamV090+QHEL5AdSzKtEh\r\n" + "U9vdvcuWjjLxVnaJLfj/6WoGZj8UWn3zFbEoTVaAfp2xqdzW7yRvi2r148m9ev7l\r\n" + "jDqHo8UX69sCAwEAAaOCAd4wggHaMB0GA1UdDgQWBBQkb5E/iYeHDjLCQBjfxUzr\r\n" + "T8hJMjAfBgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8E\r\n" + "BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQI\r\n" + "MAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz\r\n" + "cC5kaWdpY2VydC5jbjBABgNVHR8EOTA3MDWgM6Axhi9odHRwOi8vY3JsLmRpZ2lj\r\n" + "ZXJ0LmNuL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDCB3QYDVR0gBIHVMIHSMIHF\r\n" + "BglghkgBhv1sAQEwgbcwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0\r\n" + "LmNvbS9DUFMwgYoGCCsGAQUFBwICMH4MfEFueSB1c2Ugb2YgdGhpcyBDZXJ0aWZp\r\n" + "Y2F0ZSBjb25zdGl0dXRlcyBhY2NlcHRhbmNlIG9mIHRoZSBSZWx5aW5nIFBhcnR5\r\n" + "IEFncmVlbWVudCBsb2NhdGVkIGF0IGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9y\r\n" + "cGEtdWEwCAYGZ4EMAQICMA0GCSqGSIb3DQEBCwUAA4IBAQCzkcXq0TN0oSn4UeXp\r\n" + "FBW7U8zrHBIhH9MXHNBp+Yy/yN19133UY05uuHXHaU2Uv0hxefckjPdkaX7ARso+\r\n" + "O3Ar6nf7YfBwCqSpqsNckKT7KKtf3Ot95wYFpKDa64jcRUfxzRWnmq12IVzczqHI\r\n" + "sIvUZQINw/UHSQcWekdUnMg58bQSHyTjwkj9jcX2RURxaVZkr15wxo/Z3Ydo2PVK\r\n" + "3afEr0/vcuFvE7QeGXiI2DJdVt3JefatZ3rj4VTW2aUZwHGUiWWIUudBfQKR0JEp\r\n" + "lJ8MFaKDh4/A2VEJnXILu1iwvc1m3jCaPuzZKdoHM/1234bznJI2aAfhfIhoHw90\r\n" + "tPO+\r\n" + "-----END CERTIFICATE-----\r\n"; + +static const char g_testCertChainPemRoot163[] = + "-----BEGIN CERTIFICATE-----\r\n" + "MIIFDzCCA/egAwIBAgIQCxNitu5qnT6WiTDxbiB9OTANBgkqhkiG9w0BAQsFADBh\r\n" + "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n" + "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\r\n" + "QTAeFw0yMDAzMDQxMjA0NDBaFw0zMDAzMDQxMjA0NDBaMEQxCzAJBgNVBAYTAlVT\r\n" + "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxHjAcBgNVBAMTFUdlb1RydXN0IFJTQSBD\r\n" + "TiBDQSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANA1OZJJtZUI\r\n" + "7zj4qFHT79g+Otks4TEfmUEDhrNKBEEjb/i29GBfnpvFdT36azCg2VODJRSjIzFn\r\n" + "4qADcc84EmfKiDEM97HFsQPp9RRkqxH5cB51EU2eBE9Ua95x+wQp/KSdCqITCQ/v\r\n" + "yvm3J4Upjl0wlW8wRCPCWcYw3pKClGRkNzVtI1KXnfpn7fG3N84n7wlBb9IGKJFa\r\n" + "c/6+hxvZx2qnfLsxdIKR0Q/biGoU6Z8Iy/R/p7GoPO8vamV090+QHEL5AdSzKtEh\r\n" + "U9vdvcuWjjLxVnaJLfj/6WoGZj8UWn3zFbEoTVaAfp2xqdzW7yRvi2r148m9ev7l\r\n" + "jDqHo8UX69sCAwEAAaOCAd4wggHaMB0GA1UdDgQWBBQkb5E/iYeHDjLCQBjfxUzr\r\n" + "T8hJMjAfBgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8E\r\n" + "BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQI\r\n" + "MAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz\r\n" + "cC5kaWdpY2VydC5jbjBABgNVHR8EOTA3MDWgM6Axhi9odHRwOi8vY3JsLmRpZ2lj\r\n" + "ZXJ0LmNuL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDCB3QYDVR0gBIHVMIHSMIHF\r\n" + "BglghkgBhv1sAQEwgbcwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0\r\n" + "LmNvbS9DUFMwgYoGCCsGAQUFBwICMH4MfEFueSB1c2Ugb2YgdGhpcyBDZXJ0aWZp\r\n" + "Y2F0ZSBjb25zdGl0dXRlcyBhY2NlcHRhbmNlIG9mIHRoZSBSZWx5aW5nIFBhcnR5\r\n" + "IEFncmVlbWVudCBsb2NhdGVkIGF0IGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9y\r\n" + "cGEtdWEwCAYGZ4EMAQICMA0GCSqGSIb3DQEBCwUAA4IBAQCzkcXq0TN0oSn4UeXp\r\n" + "FBW7U8zrHBIhH9MXHNBp+Yy/yN19133UY05uuHXHaU2Uv0hxefckjPdkaX7ARso+\r\n" + "O3Ar6nf7YfBwCqSpqsNckKT7KKtf3Ot95wYFpKDa64jcRUfxzRWnmq12IVzczqHI\r\n" + "sIvUZQINw/UHSQcWekdUnMg58bQSHyTjwkj9jcX2RURxaVZkr15wxo/Z3Ydo2PVK\r\n" + "3afEr0/vcuFvE7QeGXiI2DJdVt3JefatZ3rj4VTW2aUZwHGUiWWIUudBfQKR0JEp\r\n" + "lJ8MFaKDh4/A2VEJnXILu1iwvc1m3jCaPuzZKdoHM/1234bznJI2aAfhfIhoHw90\r\n" + "tPO+\r\n" + "-----END CERTIFICATE-----\r\n"; + const uint8_t g_testChainKeystore[] = { 0x30, 0x82, 0x0D, 0xF1, 0x02, 0x01, 0x03, 0x30, 0x82, 0x0D, 0xB7, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x0D, 0xA8, 0x04, 0x82, 0x0D, 0xA4, 0x30, 0x82, 0x0D, 0xA0, 0x30, 0x82, 0x08, 0x57, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06, 0xA0, 0x82, @@ -217,6 +349,39 @@ static const char g_testKeystorePwd[] = "123456"; const uint8_t g_testIssuerValid[] = { 0x30, 0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0C, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4E, 0x43, 0x20, 0x43, 0x41, 0x20, 0x31 }; +static const uint8_t g_testOcspResponses[] = { 0x30, 0x82, 0x01, 0xd3, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x01, 0xcc, 0x30, + 0x82, 0x01, 0xc8, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01, 0x04, 0x82, 0x01, 0xb9, 0x30, + 0x82, 0x01, 0xb5, 0x30, 0x81, 0x9e, 0xa2, 0x16, 0x04, 0x14, 0x24, 0x6f, 0x91, 0x3f, 0x89, 0x87, 0x87, 0x0e, 0x32, + 0xc2, 0x40, 0x18, 0xdf, 0xc5, 0x4c, 0xeb, 0x4f, 0xc8, 0x49, 0x32, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30, 0x32, + 0x32, 0x31, 0x31, 0x33, 0x30, 0x30, 0x33, 0x31, 0x5a, 0x30, 0x73, 0x30, 0x71, 0x30, 0x49, 0x30, 0x09, 0x06, 0x05, + 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0xd1, 0x5d, 0xff, 0xaa, 0x00, 0x86, 0xa3, 0x32, 0x76, 0x5e, + 0x89, 0x07, 0x31, 0xdb, 0xba, 0x75, 0x0b, 0x31, 0x13, 0xdb, 0x04, 0x14, 0x24, 0x6f, 0x91, 0x3f, 0x89, 0x87, 0x87, + 0x0e, 0x32, 0xc2, 0x40, 0x18, 0xdf, 0xc5, 0x4c, 0xeb, 0x4f, 0xc8, 0x49, 0x32, 0x02, 0x10, 0x04, 0xc3, 0xb4, 0x5b, + 0x70, 0x94, 0xf4, 0xb5, 0x95, 0xc3, 0x56, 0xc4, 0xfe, 0x3a, 0x98, 0xa2, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, + 0x34, 0x30, 0x32, 0x32, 0x31, 0x31, 0x32, 0x34, 0x35, 0x30, 0x31, 0x5a, 0xa0, 0x11, 0x18, 0x0f, 0x32, 0x30, 0x32, + 0x34, 0x30, 0x32, 0x32, 0x38, 0x31, 0x31, 0x34, 0x35, 0x30, 0x31, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb0, 0xdf, 0x0f, 0x94, 0x4f, 0x25, + 0x05, 0xec, 0x59, 0x65, 0x15, 0xb7, 0x04, 0x91, 0x10, 0x45, 0xf5, 0xbd, 0x26, 0x16, 0xd1, 0x7d, 0x4e, 0x69, 0x2f, + 0xb3, 0xb2, 0xb5, 0x1c, 0xaa, 0x1d, 0xe5, 0xe9, 0x2a, 0x52, 0xdb, 0xde, 0x69, 0xed, 0xa0, 0x2e, 0x84, 0x18, 0x88, + 0xfd, 0x26, 0x9f, 0xe7, 0x1c, 0x09, 0xba, 0xe8, 0x18, 0x7c, 0x17, 0x5e, 0xfd, 0x1f, 0x52, 0x75, 0x7e, 0xec, 0x3c, + 0xf2, 0x1d, 0x55, 0xa4, 0xf7, 0x2c, 0xdf, 0x40, 0x06, 0x8c, 0x19, 0xc2, 0xbc, 0x72, 0xbb, 0xc2, 0xa1, 0xbb, 0xd7, + 0xd3, 0x79, 0xb3, 0x70, 0xcb, 0x4c, 0x07, 0x18, 0xbc, 0xd1, 0x4e, 0xe2, 0x3e, 0x18, 0xca, 0x08, 0x3d, 0x7f, 0xbc, + 0xf2, 0x0c, 0x1a, 0x2c, 0x10, 0x83, 0x59, 0xa0, 0xfb, 0x1f, 0xc2, 0x0e, 0x26, 0x17, 0x27, 0xa3, 0xba, 0x49, 0x9b, + 0x13, 0xdd, 0x55, 0xeb, 0xc8, 0xa2, 0x49, 0x76, 0xcd, 0x46, 0x5a, 0x78, 0x19, 0x26, 0xde, 0xff, 0x66, 0xac, 0x13, + 0x42, 0x89, 0x86, 0x7e, 0x5c, 0xa4, 0x67, 0xd7, 0x0d, 0xbb, 0x5f, 0xf4, 0x38, 0x91, 0x87, 0x99, 0xeb, 0xd3, 0x99, + 0x97, 0xd8, 0x0c, 0xae, 0xfa, 0x23, 0x2c, 0x4a, 0xbd, 0xd1, 0xe6, 0xa5, 0x31, 0xee, 0x8a, 0x88, 0xc2, 0x5d, 0x61, + 0x2c, 0x43, 0x04, 0x33, 0x57, 0x16, 0x98, 0xc2, 0x9a, 0x01, 0xd1, 0xad, 0x8b, 0xa5, 0x56, 0x0b, 0xd9, 0x4c, 0x81, + 0x88, 0x90, 0x92, 0x07, 0x38, 0xf3, 0xab, 0x38, 0xf8, 0xbc, 0x97, 0x59, 0xae, 0x71, 0xea, 0x25, 0x05, 0x75, 0x3f, + 0x35, 0x0b, 0x00, 0xcc, 0x1b, 0xe3, 0x32, 0x46, 0x01, 0x72, 0x4c, 0x46, 0x1a, 0x72, 0xd4, 0x7f, 0x4a, 0x94, 0x4f, + 0x82, 0xf8, 0x69, 0x86, 0x40, 0x32, 0x69, 0x79, 0xbd, 0x09, 0x16, 0x2b, 0xbb, 0x9a, 0x0a, 0x11, 0xa9, 0x65, 0xf0, + 0xac, 0xbe, 0xd8 }; + +static const char g_crlDownloadURI[] = "http://crl.digicert.cn/GeoTrustRSACNCAG2.crl"; + +static const char g_crlDownloadURIHttps[] = "https://ocsp.digicert.cn"; + +static const char g_crlDownloadURIHttpsInvalid[] = "https://www.123.com"; + #ifdef __cplusplus } #endif diff --git a/test/unittest/v1.0/include/crypto_x509_test_common.h b/test/unittest/v1.0/include/crypto_x509_test_common.h index 00f5cdf..48c8147 100644 --- a/test/unittest/v1.0/include/crypto_x509_test_common.h +++ b/test/unittest/v1.0/include/crypto_x509_test_common.h @@ -31,6 +31,7 @@ #include "key_pair.h" #include "memory_mock.h" #include "securec.h" +#include "x509_cert_chain.h" #include "x509_crl.h" #ifdef __cplusplus @@ -503,12 +504,23 @@ extern const CfEncodingBlob g_inStreamChainDataPemMidCRL; extern const CfEncodingBlob g_inStreamChainPemNoRootHasPubKey; extern const CfEncodingBlob g_inStreamChainPemNoRootLast; extern const CfEncodingBlob g_inStreamChainDataPemDisorder; +extern const CfEncodingBlob g_inStreamChainDataPem163; +extern const CfEncodingBlob g_inStreamChainDataPemRoot163; +extern const CfEncodingBlob g_inStreamOcspResponderCert; + const char *GetInvalidCertClass(void); const char *GetInvalidCrlClass(void); SubAltNameArray *ConstructSubAltNameArrayData(); CfArray *ConstructCertPolicyData(); const char *GetValidCrlClass(void); const char *GetValidX509CertificateClass(void); +void FreeTrustAnchor(HcfX509TrustAnchor *&trustAnchor); +void BuildAnchorArr(const CfEncodingBlob &certInStream, HcfX509TrustAnchorArray &trustAnchorArray); +void FreeTrustAnchorArr(HcfX509TrustAnchorArray &trustAnchorArray); +void BuildCollectionArr(const CfEncodingBlob *certInStream, const CfEncodingBlob *crlInStream, + HcfCertCRLCollectionArray &certCRLCollections); +void FreeCertCrlCollectionArr(HcfCertCRLCollectionArray &certCRLCollections); +void FreeValidateResult(HcfX509CertChainValidateResult &result); #ifdef __cplusplus } diff --git a/test/unittest/v1.0/src/cf_mock.cpp b/test/unittest/v1.0/src/cf_mock.cpp index 151c1e1..911318d 100644 --- a/test/unittest/v1.0/src/cf_mock.cpp +++ b/test/unittest/v1.0/src/cf_mock.cpp @@ -70,6 +70,12 @@ OPENSSL_STACK *__real_OPENSSL_sk_deep_copy(const OPENSSL_STACK *, OPENSSL_sk_cop int __real_OBJ_obj2nid(const ASN1_OBJECT *o); X509 *__real_X509_dup(X509 *x509); int __real_i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out); +int __real_X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername); +OCSP_REQUEST *__real_OCSP_REQUEST_new(void); +X509_CRL *__real_X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); +struct stack_st_OPENSSL_STRING *__real_X509_get1_ocsp(X509 *x); +int __real_OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost, char **pport, int *pport_num, + char **ppath, char **pquery, char **pfrag); #ifdef __cplusplus } @@ -77,9 +83,9 @@ int __real_i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out); static bool g_mockTagX509Openssl = false; -X509OpensslMock &X509OpensslMock::GetInstance(void) +NiceMock &X509OpensslMock::GetInstance(void) { - static X509OpensslMock gX509OpensslMock; + static NiceMock gX509OpensslMock; return gX509OpensslMock; } @@ -233,6 +239,25 @@ void X509OpensslMock::SetMockFunDefaultBehaviorPartThree(void) ON_CALL(*this, i2d_ASN1_INTEGER).WillByDefault([this](ASN1_INTEGER *a, unsigned char **out) { return __real_i2d_ASN1_INTEGER(a, out); }); + + ON_CALL(*this, X509_check_host) + .WillByDefault([this](X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername) { + return __real_X509_check_host(x, chk, chklen, flags, peername); + }); + + ON_CALL(*this, OCSP_REQUEST_new).WillByDefault([this](void) { return __real_OCSP_REQUEST_new(); }); + + ON_CALL(*this, X509_CRL_load_http).WillByDefault([this](const char *url, BIO *bio, BIO *rbio, int timeout) { + return __real_X509_CRL_load_http(url, bio, rbio, timeout); + }); + + ON_CALL(*this, X509_get1_ocsp).WillByDefault([this](X509 *x) { return __real_X509_get1_ocsp(x); }); + + ON_CALL(*this, OSSL_HTTP_parse_url) + .WillByDefault([this](const char *url, int *pssl, char **puser, char **phost, char **pport, int *pport_num, + char **ppath, char **pquery, char **pfrag) { + return __real_OSSL_HTTP_parse_url(url, pssl, puser, phost, pport, pport_num, ppath, pquery, pfrag); + }); } X509OpensslMock::X509OpensslMock() @@ -672,6 +697,53 @@ X509 *__wrap_X509_dup(X509 *x509) } } +int __wrap_X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername) +{ + if (g_mockTagX509Openssl) { + return X509OpensslMock::GetInstance().X509_check_host(x, chk, chklen, flags, peername); + } else { + return __real_X509_check_host(x, chk, chklen, flags, peername); + } +} + +OCSP_REQUEST *__wrap_OCSP_REQUEST_new(void) +{ + if (g_mockTagX509Openssl) { + return X509OpensslMock::GetInstance().OCSP_REQUEST_new(); + } else { + return __real_OCSP_REQUEST_new(); + } +} + +X509_CRL *__wrap_X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) +{ + if (g_mockTagX509Openssl) { + return X509OpensslMock::GetInstance().X509_CRL_load_http(url, bio, rbio, timeout); + } else { + return __real_X509_CRL_load_http(url, bio, rbio, timeout); + } +} + +struct stack_st_OPENSSL_STRING *__wrap_X509_get1_ocsp(X509 *x) +{ + if (g_mockTagX509Openssl) { + return X509OpensslMock::GetInstance().X509_get1_ocsp(x); + } else { + return __real_X509_get1_ocsp(x); + } +} + +int __wrap_OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost, char **pport, int *pport_num, + char **ppath, char **pquery, char **pfrag) +{ + if (g_mockTagX509Openssl) { + return X509OpensslMock::GetInstance().OSSL_HTTP_parse_url( + url, pssl, puser, phost, pport, pport_num, ppath, pquery, pfrag); + } else { + return __real_OSSL_HTTP_parse_url(url, pssl, puser, phost, pport, pport_num, ppath, pquery, pfrag); + } +} + #ifdef __cplusplus } #endif diff --git a/test/unittest/v1.0/src/crypto_x509_cert_chain_test.cpp b/test/unittest/v1.0/src/crypto_x509_cert_chain_test.cpp index 42175f5..03f8f4c 100644 --- a/test/unittest/v1.0/src/crypto_x509_cert_chain_test.cpp +++ b/test/unittest/v1.0/src/crypto_x509_cert_chain_test.cpp @@ -53,6 +53,9 @@ void *__real_OPENSSL_sk_value(const OPENSSL_STACK *st, int i); CfResult __real_DeepCopyBlobToBlob(const CfBlob *inBlob, CfBlob **outBlob); CfResult __real_HcfX509CertificateCreate(const CfEncodingBlob *inStream, HcfX509Certificate **returnObj); int __real_OPENSSL_sk_push(OPENSSL_STACK *st, const int data); +OPENSSL_STACK *__real_OPENSSL_sk_new_null(void); +int __real_OPENSSL_sk_push(OPENSSL_STACK *st, const int data); +X509 *__real_X509_dup(X509 *x509); #ifdef __cplusplus } @@ -100,93 +103,6 @@ static const char *GetInvalidCertChainClass(void) return "HcfInvalidCertChain"; } -static void FreeTrustAnchor(HcfX509TrustAnchor *&trustAnchor) -{ - if (trustAnchor == nullptr) { - return; - } - CfBlobFree(&trustAnchor->CAPubKey); - CfBlobFree(&trustAnchor->CASubject); - CfObjDestroy(trustAnchor->CACert); - trustAnchor->CACert = nullptr; - CfFree(trustAnchor); - trustAnchor = nullptr; -} - -static void BuildAnchorArr(const CfEncodingBlob &certInStream, HcfX509TrustAnchorArray &trustAnchorArray) -{ - HcfX509TrustAnchor *anchor = static_cast(HcfMalloc(sizeof(HcfX509TrustAnchor), 0)); - ASSERT_NE(anchor, nullptr); - - (void)HcfX509CertificateCreate(&certInStream, &anchor->CACert); - trustAnchorArray.data = static_cast(HcfMalloc(1 * sizeof(HcfX509TrustAnchor *), 0)); - ASSERT_NE(trustAnchorArray.data, nullptr); - trustAnchorArray.data[0] = anchor; - trustAnchorArray.count = 1; -} - -static void FreeTrustAnchorArr(HcfX509TrustAnchorArray &trustAnchorArray) -{ - for (uint32_t i = 0; i < trustAnchorArray.count; ++i) { - HcfX509TrustAnchor *anchor = trustAnchorArray.data[i]; - FreeTrustAnchor(anchor); - } - CfFree(trustAnchorArray.data); - trustAnchorArray.data = nullptr; - trustAnchorArray.count = 0; -} - -static void BuildCollectionArr(const CfEncodingBlob *certInStream, const CfEncodingBlob *crlInStream, - HcfCertCRLCollectionArray &certCRLCollections) -{ - CfResult ret = CF_SUCCESS; - HcfX509CertificateArray *certArray = nullptr; - if (certInStream != nullptr) { - certArray = static_cast(HcfMalloc(sizeof(HcfX509CertificateArray), 0)); - ASSERT_NE(certArray, nullptr); - - HcfX509Certificate *x509CertObj = nullptr; - (void)HcfX509CertificateCreate(certInStream, &x509CertObj); - ASSERT_NE(x509CertObj, nullptr); - - certArray->data = static_cast(HcfMalloc(1 * sizeof(HcfX509Certificate *), 0)); - ASSERT_NE(certArray->data, nullptr); - certArray->data[0] = x509CertObj; - certArray->count = 1; - } - - HcfX509CrlArray *crlArray = nullptr; - if (crlInStream != nullptr) { - crlArray = static_cast(HcfMalloc(sizeof(HcfX509CrlArray), 0)); - ASSERT_NE(crlArray, nullptr); - - HcfX509Crl *x509Crl = nullptr; - ret = HcfX509CrlCreate(crlInStream, &x509Crl); - ASSERT_EQ(ret, CF_SUCCESS); - ASSERT_NE(x509Crl, nullptr); - - crlArray->data = static_cast(HcfMalloc(1 * sizeof(HcfX509Crl *), 0)); - ASSERT_NE(crlArray->data, nullptr); - crlArray->data[0] = x509Crl; - crlArray->count = 1; - } - - HcfCertCrlCollection *x509CertCrlCollection = nullptr; - ret = HcfCertCrlCollectionCreate(certArray, crlArray, &x509CertCrlCollection); - ASSERT_EQ(ret, CF_SUCCESS); - ASSERT_NE(x509CertCrlCollection, nullptr); - - certCRLCollections.data = static_cast(HcfMalloc(1 * sizeof(HcfCertCrlCollection *), 0)); - ASSERT_NE(certCRLCollections.data, nullptr); - certCRLCollections.data[0] = x509CertCrlCollection; - certCRLCollections.count = 1; - - FreeCertArrayData(certArray); - CfFree(certArray); - FreeCrlArrayData(crlArray); - CfFree(crlArray); -} - void CryptoX509CertChainTest::SetUpTestCase() { CfResult ret = HcfCertChainCreate(&g_inStreamChainDataP7b, nullptr, &g_certChainP7b); @@ -234,29 +150,6 @@ void CryptoX509CertChainTest::SetUp() {} void CryptoX509CertChainTest::TearDown() {} -static void FreeCertCrlCollectionArr(HcfCertCRLCollectionArray &certCRLCollections) -{ - for (uint32_t i = 0; i < certCRLCollections.count; ++i) { - HcfCertCrlCollection *collection = certCRLCollections.data[i]; - CfObjDestroy(collection); - } - CfFree(certCRLCollections.data); - certCRLCollections.data = nullptr; - certCRLCollections.count = 0; -} - -static void FreeValidateResult(HcfX509CertChainValidateResult &result) -{ - if (result.entityCert != nullptr) { - CfObjDestroy(result.entityCert); - result.entityCert = nullptr; - } - - if (result.trustAnchor != nullptr) { - FreeTrustAnchor(result.trustAnchor); - } -} - /* invalid encodingBlob. */ HWTEST_F(CryptoX509CertChainTest, CertChainByEncSpiCreateTest001, TestSize.Level0) { @@ -694,6 +587,7 @@ HWTEST_F(CryptoX509CertChainTest, GetCertListCoreTest004, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest001, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest001"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainDataP7b, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -707,6 +601,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest001, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest002, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest002"); ASSERT_NE(g_certChainP7bSpi, nullptr); CfResult ret = g_certChainP7bSpi->engineValidate(g_certChainP7bSpi, nullptr, nullptr); ASSERT_EQ(ret, CF_INVALID_PARAMS); @@ -714,6 +609,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest002, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest003, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest003"); ASSERT_NE(g_certChainP7bSpi, nullptr); HcfX509TrustAnchor anchor = { 0 }; CfEncodingBlob inStream = { 0 }; @@ -742,6 +638,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest003, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest004, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest004"); ASSERT_NE(g_certChainP7bSpi, nullptr); HcfX509CertChainSpi *certChainSpi = nullptr; @@ -767,6 +664,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest004, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest005, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest005"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -787,6 +685,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest005, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest006, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest006"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -804,6 +703,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest006, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest007, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest007"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchor anchor = { 0 }; @@ -826,6 +726,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest007, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest008, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest008"); ASSERT_NE(g_certChainPemSpi, nullptr); CfBlob pubkey = { 0, nullptr }; @@ -857,6 +758,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest008, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest009, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest009"); ASSERT_NE(g_certChainPemSpi, nullptr); CfBlob pubkey = { 0, nullptr }; @@ -877,13 +779,14 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest009, TestSize.Level0) HcfX509CertChainValidateResult result = { 0 }; CfResult ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, &pCertChainValidateParams, &result); - ASSERT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + ASSERT_EQ(ret, CF_INVALID_PARAMS); CfFree(trustAnchorArray.data); } HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest010, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest010"); ASSERT_NE(g_certChainPemSpi, nullptr); CfBlob pubkey = { 0, nullptr }; @@ -919,6 +822,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest010, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest011, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest011"); ASSERT_NE(g_certChainPemSpi, nullptr); CfBlob pubkey = { 0, nullptr }; @@ -952,6 +856,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest011, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest012, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest012"); ASSERT_NE(g_certChainPemSpi, nullptr); CfBlob pubkey = { 0, nullptr }; @@ -973,13 +878,14 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest012, TestSize.Level0) HcfX509CertChainValidateResult result = { 0 }; CfResult ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, &pCertChainValidateParams, &result); - ASSERT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + ASSERT_EQ(ret, CF_INVALID_PARAMS); CfFree(trustAnchorArray.data); } HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest013, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest013"); ASSERT_NE(g_certChainPemSpi, nullptr); CfBlob pubkey = { 0, nullptr }; @@ -1002,13 +908,14 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest013, TestSize.Level0) HcfX509CertChainValidateResult result = { 0 }; CfResult ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, &pCertChainValidateParams, &result); - ASSERT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + ASSERT_EQ(ret, CF_INVALID_PARAMS); CfFree(trustAnchorArray.data); } HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest014, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest014"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainDataPemNoRoot, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1033,6 +940,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest014, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest015, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest015"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainPemNoRootHasPubKey, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1067,6 +975,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest015, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest016, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest016"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1085,6 +994,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest016, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest017, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest017"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainDataPemRoot, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1121,6 +1031,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest017, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest018, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest018"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1148,6 +1059,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest018, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest019, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest019"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1175,6 +1087,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest019, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest020, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest020"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1202,6 +1115,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest020, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest021, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest021"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1226,6 +1140,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest021, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest022, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest022"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1250,6 +1165,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest022, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest023, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest023"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1275,6 +1191,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest023, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest024, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest024"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1299,6 +1216,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest024, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest025, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest025"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1324,6 +1242,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest025, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest026, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest026"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1346,6 +1265,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest026, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest027, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest027"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1378,6 +1298,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest027, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest028, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest028"); for (unsigned int i = 0; i < 1000; i++) { HcfX509TrustAnchorArray trustAnchorArray = { 0 }; BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); @@ -1398,6 +1319,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest028, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest029, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest029"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainPemNoRootHasPubKey, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1422,6 +1344,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest029, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest030, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest030"); ASSERT_NE(g_certChainPemSpi, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1447,6 +1370,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest030, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest031, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest031"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainDataPemDisorder, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1468,6 +1392,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest031, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest032, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest032"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainPemNoRootHasPubKey, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1502,6 +1427,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest032, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest033, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest033"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainPemNoRootHasPubKey, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1538,6 +1464,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest033, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest034, TestSize.Level0) { + CF_LOG_I("ValidateOpensslTest034"); HcfX509CertChainSpi *certChainSpi = nullptr; CfResult ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainPemNoRootHasPubKey, &certChainSpi); ASSERT_EQ(ret, CF_SUCCESS); @@ -1574,6 +1501,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateOpensslTest034, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest001, TestSize.Level0) { + CF_LOG_I("ValidateCoreTest001"); HcfCertChain *pCertChain = nullptr; CfResult ret = HcfCertChainCreate(&g_inStreamChainDataP7b, nullptr, &pCertChain); ASSERT_EQ(ret, CF_SUCCESS); @@ -1587,6 +1515,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest001, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest002, TestSize.Level0) { + CF_LOG_I("ValidateCoreTest002"); HcfCertChain *pCertChain = nullptr; CfResult ret = HcfCertChainCreate(&g_inStreamChainDataP7b, nullptr, &pCertChain); ASSERT_EQ(ret, CF_SUCCESS); @@ -1600,6 +1529,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest002, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest003, TestSize.Level0) { + CF_LOG_I("ValidateCoreTest003"); ASSERT_NE(g_certChainP7b, nullptr); HcfX509TrustAnchorArray trustAnchorArray = { 0 }; @@ -1616,6 +1546,7 @@ HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest003, TestSize.Level0) HWTEST_F(CryptoX509CertChainTest, ValidateCoreTest004, TestSize.Level0) { + CF_LOG_I("ValidateCoreTest004"); HcfCertChain *pCertChain = nullptr; CfResult ret = HcfCertChainCreate(&g_inStreamChainDataPem, nullptr, &pCertChain); ASSERT_EQ(ret, CF_SUCCESS); @@ -1780,19 +1711,25 @@ HWTEST_F(CryptoX509CertChainTest, HcfX509CertChainByParamsSpiCreateTest002, Test // test HcfX509CertChainByParamsSpiCreate failed case X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_new_null()).Times(AnyNumber()).WillOnce(Return(NULL)); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_new_null()) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_new_null)); CfResult result = HcfX509CertChainByParamsSpiCreate(&inParams, &spi); EXPECT_EQ(result, CF_ERR_MALLOC); X509OpensslMock::SetMockFlag(false); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), X509_dup(_)).Times(AnyNumber()).WillOnce(Return(NULL)); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_dup(_)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509_dup)); result = HcfX509CertChainByParamsSpiCreate(&inParams, &spi); EXPECT_EQ(result, CF_ERR_MALLOC); X509OpensslMock::SetMockFlag(false); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_push(_, _)).Times(AnyNumber()).WillOnce(Return(-1)); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_push(_, _)) + .WillOnce(Return(-1)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_push)); result = HcfX509CertChainByParamsSpiCreate(&inParams, &spi); EXPECT_EQ(result, CF_ERR_CRYPTO_OPERATION); X509OpensslMock::SetMockFlag(false); diff --git a/test/unittest/v1.0/src/crypto_x509_cert_chain_test_part2.cpp b/test/unittest/v1.0/src/crypto_x509_cert_chain_test_part2.cpp new file mode 100644 index 0000000..d64c31f --- /dev/null +++ b/test/unittest/v1.0/src/crypto_x509_cert_chain_test_part2.cpp @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "cert_crl_common.h" +#include "cf_blob.h" +#include "cf_log.h" +#include "cf_mock.h" +#include "cf_object_base.h" +#include "cf_result.h" +#include "crypto_x509_test_common.h" +#include "memory_mock.h" +#include "securec.h" +#include "string" +#include "x509_cert_chain.h" +#include "x509_cert_chain_openssl.h" +#include "x509_certificate_openssl.h" + +using namespace std; +using namespace testing::ext; +using namespace CFMock; + +using ::testing::_; +using ::testing::AnyNumber; +using ::testing::Invoke; +using ::testing::Return; + +#ifdef __cplusplus +extern "C" { +#endif + +int __real_OPENSSL_sk_num(const OPENSSL_STACK *st); +void *__real_OPENSSL_sk_value(const OPENSSL_STACK *st, int i); +int __real_OPENSSL_sk_push(OPENSSL_STACK *st, const int data); +OPENSSL_STACK *__real_OPENSSL_sk_new_null(void); +void *__real_X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +X509_CRL *__real_X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); +OCSP_REQUEST *__real_OCSP_REQUEST_new(void); +struct stack_st_OPENSSL_STRING *__real_X509_get1_ocsp(X509 *x); +int __real_OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost, char **pport, int *pport_num, + char **ppath, char **pquery, char **pfrag); + +#ifdef __cplusplus +} +#endif + +namespace { +class CryptoX509CertChainTestPart2 : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +static HcfX509CertChainSpi *g_certChainPemSpi = nullptr; +static HcfX509CertChainSpi *g_certChainPemSpi163 = nullptr; + +static CfBlob g_blobDownloadURI = { .data = reinterpret_cast(const_cast(g_crlDownloadURI)), + .size = strlen(g_crlDownloadURI) + 1 }; + +static CfBlob g_blobDownloadURIHttps = { .data = reinterpret_cast(const_cast(g_crlDownloadURIHttps)), + .size = strlen(g_crlDownloadURIHttps) + 1 }; + +static CfBlob g_blobDownloadURIHttpsInvalid = { .data = + reinterpret_cast(const_cast(g_testKeystorePwd)), + .size = strlen(g_testKeystorePwd) + 1 }; + +static CfBlob g_blobDownloadURIHttpsInvalid2 = { .data = reinterpret_cast( + const_cast(g_crlDownloadURIHttpsInvalid)), + .size = strlen(g_crlDownloadURIHttpsInvalid) + 1 }; + +static void FreeHcfRevocationCheckParam(HcfRevocationCheckParam *param) +{ + if (param == nullptr) { + return; + } + + if (param->options != nullptr) { + if (param->options->data != nullptr) { + CfFree(param->options->data); + } + + CfFree(param->options); + } + + if (param->ocspResponses != nullptr) { + CfFree(param->ocspResponses); + } + + if (param->ocspResponderCert != nullptr) { + CfObjDestroy(param->ocspResponderCert); + } + + CfFree(param); +} + +static HcfRevocationCheckParam *ConstructHcfRevocationCheckParam(HcfRevChkOption *data, size_t size, + CfBlob *ocspResponderURI = NULL, CfBlob *crlDownloadURI = NULL, + const CfEncodingBlob *ocspResponderCertStream = NULL) +{ + HcfRevChkOpArray *revChkOpArray = (HcfRevChkOpArray *)HcfMalloc(sizeof(HcfRevChkOpArray), 0); + if (revChkOpArray == nullptr) { + return nullptr; + } + + revChkOpArray->count = size; + revChkOpArray->data = (HcfRevChkOption *)HcfMalloc(revChkOpArray->count * sizeof(HcfRevChkOption), 0); + if (revChkOpArray->data == nullptr) { + CfFree(revChkOpArray); + return nullptr; + } + + for (size_t i = 0; i < revChkOpArray->count; i++) { + revChkOpArray->data[i] = data[i]; + } + + CfBlob *resp = (CfBlob *)HcfMalloc(sizeof(CfBlob), 0); + if (resp == nullptr) { + CfFree(revChkOpArray->data); + CfFree(revChkOpArray); + return nullptr; + } + resp->data = (uint8_t *)(&g_testOcspResponses[0]); + resp->size = sizeof(g_testOcspResponses); + + HcfRevocationCheckParam *param = (HcfRevocationCheckParam *)HcfMalloc(sizeof(HcfRevocationCheckParam), 0); + if (param == nullptr) { + CfFree(revChkOpArray->data); + CfFree(revChkOpArray); + return nullptr; + } + + param->options = revChkOpArray; + param->ocspResponses = resp; + param->ocspResponderURI = ocspResponderURI; + param->crlDownloadURI = crlDownloadURI; + + if (ocspResponderCertStream != NULL) { + (void)HcfX509CertificateCreate(&g_inStreamOcspResponderCert, &(param->ocspResponderCert)); + if (param->ocspResponderCert == nullptr) { + FreeHcfRevocationCheckParam(param); + return nullptr; + } + } + + return param; +} + +void CryptoX509CertChainTestPart2::SetUpTestCase() +{ + CfResult ret; + + HcfX509CertChainSpi *certChainSpi = nullptr; + ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainDataPem, &certChainSpi); + ASSERT_EQ(ret, CF_SUCCESS); + ASSERT_NE(certChainSpi, nullptr); + g_certChainPemSpi = certChainSpi; + + certChainSpi = nullptr; + ret = HcfX509CertChainByEncSpiCreate(&g_inStreamChainDataPem163, &certChainSpi); + ASSERT_EQ(ret, CF_SUCCESS); + ASSERT_NE(certChainSpi, nullptr); + g_certChainPemSpi163 = certChainSpi; +} + +void CryptoX509CertChainTestPart2::TearDownTestCase() +{ + CfObjDestroy(g_certChainPemSpi); + CfObjDestroy(g_certChainPemSpi163); +} + +void CryptoX509CertChainTestPart2::SetUp() {} + +void CryptoX509CertChainTestPart2::TearDown() {} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslBranchTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslBranchTest001"); + ASSERT_NE(g_certChainPemSpi, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); + + HcfCertCRLCollectionArray certCRLCollections = { 0 }; + BuildCollectionArr(&g_inStreamChainDataPemRoot, &g_crlDerInStream, certCRLCollections); + + const char *date = "20231212080000Z"; + CfBlob validDate = { 0 }; + validDate.data = reinterpret_cast(const_cast(date)); + validDate.size = strlen(date) + 1; + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + params.date = &validDate; + params.certCRLCollections = &certCRLCollections; + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test PushCrl2Stack failed case + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_push(_, _)) + .Times(AnyNumber()) + .WillOnce(Invoke(__real_OPENSSL_sk_push)) + .WillOnce(Return(0)); + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_push(_, _)) + .WillOnce(Return(0)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_push)); + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeCertCrlCollectionArr(certCRLCollections); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslPolicyTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslPolicyTest001"); + ASSERT_NE(g_certChainPemSpi, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test ValidatePolicy failed case + params.policy = (HcfValPolicyType)-1; + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + + params.policy = VALIDATION_POLICY_TYPE_SSL; + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + + CfBlob sslHostname = { 0 }; + params.sslHostname = &sslHostname; + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_check_host(_, _, _, _, _)).Times(AnyNumber()).WillOnce(Return(0)); + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslUseageTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslUseageTest001"); + ASSERT_NE(g_certChainPemSpi, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfKuArray kuArray = { 0 }; + kuArray.count = 9; + kuArray.data = (HcfKeyUsageType *)HcfMalloc(kuArray.count * sizeof(HcfKeyUsageType), 0); + kuArray.data[0] = KEYUSAGE_DIGITAL_SIGNATURE; + kuArray.data[1] = KEYUSAGE_NON_REPUDIATION; + kuArray.data[2] = KEYUSAGE_KEY_ENCIPHERMENT; + kuArray.data[3] = KEYUSAGE_DATA_ENCIPHERMENT; + kuArray.data[4] = KEYUSAGE_KEY_AGREEMENT; + kuArray.data[5] = KEYUSAGE_KEY_CERT_SIGN; + kuArray.data[6] = KEYUSAGE_CRL_SIGN; + kuArray.data[7] = KEYUSAGE_ENCIPHER_ONLY; + kuArray.data[8] = KEYUSAGE_DECIPHER_ONLY; + + params.keyUsage = &kuArray; + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + + kuArray.data[8] = (HcfKeyUsageType)-1; + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + + // test ValidatePolicy failed case + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + X509OpensslMock::SetMockFlag(false); + + CfFree(kuArray.data); + FreeTrustAnchorArr(trustAnchorArray); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslPart2Test001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslPart2Test001"); + ASSERT_NE(g_certChainPemSpi, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslCRLLocalTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslCRLLocalTest001"); + ASSERT_NE(g_certChainPemSpi, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_new_null()) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_new_null)); + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslInvaidCertId, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslInvaidCertId"); + ASSERT_NE(g_certChainPemSpi, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOpArray revChkOpArray = { 0 }; + revChkOpArray.count = 1; + revChkOpArray.data = (HcfRevChkOption *)HcfMalloc(revChkOpArray.count * sizeof(HcfRevChkOption), 0); + ASSERT_NE(revChkOpArray.data, nullptr); + revChkOpArray.data[0] = REVOCATION_CHECK_OPTION_PREFER_OCSP; + + HcfRevocationCheckParam rcp; + rcp.options = &revChkOpArray; + params.revocationCheckParam = &rcp; + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test ValidateOcspLocal failed case + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + FreeValidateResult(result); + + // test VerifyOcspSinger failed case + CfBlob resp; + resp.data = (uint8_t *)(&g_testOcspResponses[0]); + resp.size = sizeof(g_testOcspResponses); + rcp.ocspResponses = &resp; + + ret = g_certChainPemSpi->engineValidate(g_certChainPemSpi, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + FreeValidateResult(result); + + FreeTrustAnchorArr(trustAnchorArray); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationLocalTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationLocalTest001"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_PREFER_OCSP }; + params.revocationCheckParam = ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0])); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + + // test ValidateOcspLocal failed case + CfResult ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest001"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, &g_blobDownloadURI); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test ValidateOcspLocal failed case + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest002, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest002"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, NULL); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test CheckCertChainIsRevoked failed case + CF_LOG_I("ValidateOpensslRevocationOnLineTest002 - 01"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_num(_)) + .WillOnce(Invoke(__real_OPENSSL_sk_num)) + .WillOnce(Invoke(__real_OPENSSL_sk_num)) + .WillOnce(Invoke(__real_OPENSSL_sk_num)) + .WillOnce(Invoke(__real_OPENSSL_sk_num)) + .WillOnce(Invoke(__real_OPENSSL_sk_num)) + .WillOnce(Return(0)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_num)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + CF_LOG_I("ValidateOpensslRevocationOnLineTest002 - 02"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest003, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest003"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, NULL); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test CheckCertChainIsRevoked failed case + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest004, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest004"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, NULL); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test ValidateCrlOnline failed case + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_CRL_load_http(_, _, _, _)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509_CRL_load_http)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_push(_, _)) + .WillOnce(Return(0)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_push)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_new_null()) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_new_null)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest005, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest005"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, &g_blobDownloadURI); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test CheckCertChainIsRevoked failed case + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 1"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + X509OpensslMock::SetMockFlag(false); + + params.revocationCheckParam->crlDownloadURI = NULL; + + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 2"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest006, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest006"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, NULL); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test GetDpUrl failed case + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 3"); + DIST_POINT dp = { 0 }; + X509OpensslMock::SetMockFlag(true); + dp.distpoint = NULL; + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(&dp)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 4"); + DIST_POINT_NAME dpn; + dpn.type = GEN_URI; + dp.distpoint = &dpn; + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(&dp)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest007, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest007"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, NULL); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + + // test GetDpUrl failed case + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 5"); + DIST_POINT dp = { 0 }; + + DIST_POINT_NAME dpn; + dpn.type = GEN_URI; + + dp.distpoint = &dpn; + dp.distpoint->type = 0; + dp.distpoint->name.fullname = nullptr; + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(&dp)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + CfResult ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 6"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), GENERAL_NAME_get0_value(_, _)) + .Times(AnyNumber()) + .WillOnce(Return(NULL)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + CF_LOG_I("ValidateOpensslRevocationOnLineTest - 7"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext_d2i(_, _, _, _)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509_get_ext_d2i)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest008, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest008"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_PREFER_OCSP, REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = ConstructHcfRevocationCheckParam( + data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI, &g_blobDownloadURI, &g_inStreamOcspResponderCert); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test ValidateOcspLocal failed case + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OCSP_REQUEST_new()) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OCSP_REQUEST_new)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineHttpsTest001, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineHttpsTest001"); + + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_PREFER_OCSP, REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), + &g_blobDownloadURIHttps, &g_blobDownloadURI, &g_inStreamOcspResponderCert); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get1_ocsp(_)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509_get1_ocsp)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + // test Unable to parse url. + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OSSL_HTTP_parse_url(_, _, _, _, _, _, _, _, _)) + .WillOnce(Return(0)) + .WillRepeatedly(Invoke(__real_OSSL_HTTP_parse_url)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + // test Unable to get leafCert. + CF_LOG_I("ValidateOpensslRevocationOnLineHttpsTest001 - 1"); + X509OpensslMock::SetMockFlag(true); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Invoke(__real_OPENSSL_sk_value)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineHttpsTest002, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineHttpsTest002"); + + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_PREFER_OCSP, REVOCATION_CHECK_OPTION_ACCESS_NETWORK }; + params.revocationCheckParam = ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), + &g_blobDownloadURIHttps, &g_blobDownloadURI, &g_inStreamOcspResponderCert); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + // test GetOCSPUrl failed case + X509OpensslMock::SetMockFlag(true); + params.revocationCheckParam->ocspResponderURI->data = NULL; + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get1_ocsp(_)).Times(AnyNumber()).WillOnce(Return(NULL)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + params.revocationCheckParam->ocspResponderURI = NULL; + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get1_ocsp(_)).Times(AnyNumber()).WillOnce(Return(NULL)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + params.revocationCheckParam->ocspResponderURI = &g_blobDownloadURIHttpsInvalid; + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get1_ocsp(_)).Times(AnyNumber()).WillOnce(Return(NULL)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + X509OpensslMock::SetMockFlag(true); + params.revocationCheckParam->ocspResponderURI = &g_blobDownloadURIHttpsInvalid2; + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get1_ocsp(_)).Times(AnyNumber()).WillOnce(Return(NULL)); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); + FreeValidateResult(result); + X509OpensslMock::SetMockFlag(false); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest009, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest009"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_PREFER_OCSP, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER, + REVOCATION_CHECK_OPTION_FALLBACK_LOCAL }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + CF_LOG_I("ValidateOpensslRevocationOnLineTest009 - 1"); + // test ValidateOcspLocal failed case + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + + CF_LOG_I("ValidateOpensslRevocationOnLineTest009 - 2"); + (void)HcfX509CertificateCreate(&g_inStreamOcspResponderCert, &(params.revocationCheckParam->ocspResponderCert)); + ASSERT_NE(params.revocationCheckParam->ocspResponderCert, nullptr); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_INVALID_PARAMS); + FreeValidateResult(result); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); + CF_LOG_I("ValidateOpensslRevocationOnLineTest009 - ok"); +} + +HWTEST_F(CryptoX509CertChainTestPart2, ValidateOpensslRevocationOnLineTest010, TestSize.Level0) +{ + CF_LOG_I("ValidateOpensslRevocationOnLineTest010"); + ASSERT_NE(g_certChainPemSpi163, nullptr); + + HcfX509TrustAnchorArray trustAnchorArray = { 0 }; + BuildAnchorArr(g_inStreamChainDataPemRoot163, trustAnchorArray); + + HcfX509CertChainValidateParams params = { 0 }; + params.trustAnchors = &trustAnchorArray; + + HcfRevChkOption data[] = { REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL }; + params.revocationCheckParam = + ConstructHcfRevocationCheckParam(data, sizeof(data) / sizeof(data[0]), &g_blobDownloadURI); + ASSERT_NE(params.revocationCheckParam, nullptr); + + HcfX509CertChainValidateResult result = { 0 }; + CfResult ret; + + CF_LOG_I("ValidateOpensslRevocationOnLineTest010 - 1"); + // test ValidateOcspLocal failed case + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + + CF_LOG_I("ValidateOpensslRevocationOnLineTest010 - 2"); + (void)HcfX509CertificateCreate(&g_inStreamOcspResponderCert, &(params.revocationCheckParam->ocspResponderCert)); + ASSERT_NE(params.revocationCheckParam->ocspResponderCert, nullptr); + ret = g_certChainPemSpi163->engineValidate(g_certChainPemSpi163, ¶ms, &result); + EXPECT_EQ(ret, CF_SUCCESS); + FreeValidateResult(result); + + FreeTrustAnchorArr(trustAnchorArray); + FreeHcfRevocationCheckParam(params.revocationCheckParam); + CF_LOG_I("ValidateOpensslRevocationOnLineTest010 - ok"); +} +} // namespace diff --git a/test/unittest/v1.0/src/crypto_x509_certificate_test_part3.cpp b/test/unittest/v1.0/src/crypto_x509_certificate_test_part3.cpp index ea5ce87..2e1d97e 100644 --- a/test/unittest/v1.0/src/crypto_x509_certificate_test_part3.cpp +++ b/test/unittest/v1.0/src/crypto_x509_certificate_test_part3.cpp @@ -40,6 +40,22 @@ using ::testing::AnyNumber; using ::testing::Invoke; using ::testing::Return; +#ifdef __cplusplus +extern "C" { +#endif + +int __real_OPENSSL_sk_num(const OPENSSL_STACK *st); +void *__real_OPENSSL_sk_value(const OPENSSL_STACK *st, int i); +long __real_ASN1_INTEGER_get(const ASN1_INTEGER *a); +void *__real_X509V3_EXT_d2i(X509_EXTENSION *ext); +X509_EXTENSION *__real_X509_get_ext(const X509 *x, X509_EXTENSION *loc); +void *__real_X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +CfResult __real_DeepCopyDataToBlob(const unsigned char *data, uint32_t len, CfBlob *outBlob); + +#ifdef __cplusplus +} +#endif + namespace { class CryptoX509CertificateTestPart3 : public testing::Test { public: @@ -140,7 +156,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareSubjectAlternativeNamesTest002, // test CompareSubAltNameX509Openssl failed case X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext_d2i(_, _, _, _)).Times(AnyNumber()).WillOnce(Return(NULL)); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext_d2i(_, _, _, _)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509_get_ext_d2i)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &matchParams, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); @@ -182,7 +200,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareMatchAllSubjectAltNamesTest001, // add failed case ret != CF_SUCCESS X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_num(_)).Times(AnyNumber()).WillOnce(Return(-1)); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_num(_)) + .WillOnce(Return(-1)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_num)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_ERR_CRYPTO_OPERATION); X509OpensslMock::SetMockFlag(false); @@ -225,8 +245,8 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareAuthorityKeyIdentifierTest001, T X509OpensslMock::SetMockFlag(true); EXPECT_CALL(X509OpensslMock::GetInstance(), DeepCopyDataToBlob(_, _, _)) - .Times(AnyNumber()) - .WillOnce(Return(CF_INVALID_PARAMS)); + .WillOnce(Return(CF_INVALID_PARAMS)) + .WillRepeatedly(Invoke(__real_DeepCopyDataToBlob)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_INVALID_PARAMS); X509OpensslMock::SetMockFlag(false); @@ -280,14 +300,18 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareMinPathLenConstraintTest002, Tes constraints->pathlen = pathlen; X509OpensslMock::SetMockFlag(true); EXPECT_CALL(X509OpensslMock::GetInstance(), X509V3_EXT_d2i(_)).Times(AnyNumber()).WillOnce(Return(constraints)); - EXPECT_CALL(X509OpensslMock::GetInstance(), ASN1_INTEGER_get(_)).Times(AnyNumber()).WillOnce(Return(10)); + EXPECT_CALL(X509OpensslMock::GetInstance(), ASN1_INTEGER_get(_)) + .WillOnce(Return(10)) + .WillRepeatedly(Invoke(__real_ASN1_INTEGER_get)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); X509OpensslMock::SetMockFlag(false); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), X509V3_EXT_d2i(_)).Times(AnyNumber()).WillOnce(Return(NULL)); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509V3_EXT_d2i(_)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509V3_EXT_d2i)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); @@ -302,7 +326,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareMinPathLenConstraintTest002, Tes X509OpensslMock::SetMockFlag(true); certMatchParameters.minPathLenConstraint = 2; - EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext(_, _)).Times(AnyNumber()).WillOnce(Return(NULL)); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext(_, _)) + .WillOnce(Return(NULL)) + .WillRepeatedly(Invoke(__real_X509_get_ext)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); @@ -374,7 +400,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareNameConstraintsTest001, TestSize tree->base->d.otherName = OTHERNAME_new(); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)).Times(AnyNumber()).WillOnce(Return(tree)); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Return(tree)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); ret = g_testCertWithPrivateKeyValidObj->match(g_testCertWithPrivateKeyValidObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); @@ -389,7 +417,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareNameConstraintsTest001, TestSize tree->base->d.x400Address = ASN1_STRING_new(); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)).Times(AnyNumber()).WillOnce(Return(tree)); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Return(tree)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); ret = g_testCertWithPrivateKeyValidObj->match(g_testCertWithPrivateKeyValidObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); @@ -508,7 +538,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareNameConstraintsTest004, TestSize tree->base->d.registeredID = ASN1_OBJECT_new(); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)).Times(AnyNumber()).WillOnce(Return(tree)); + EXPECT_CALL(X509OpensslMock::GetInstance(), OPENSSL_sk_value(_, _)) + .WillOnce(Return(tree)) + .WillRepeatedly(Invoke(__real_OPENSSL_sk_value)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); @@ -550,7 +582,9 @@ HWTEST_F(CryptoX509CertificateTestPart3, CompareNameConstraintsTest005, TestSize nc->permittedSubtrees = sk_GENERAL_SUBTREE_new_null(); EXPECT_NE(nc, nullptr); X509OpensslMock::SetMockFlag(true); - EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext_d2i(_, _, _, _)).Times(AnyNumber()).WillOnce(Return(nc)); + EXPECT_CALL(X509OpensslMock::GetInstance(), X509_get_ext_d2i(_, _, _, _)) + .WillOnce(Return(nc)) + .WillRepeatedly(Invoke(__real_X509_get_ext_d2i)); ret = g_x509CertExtAttrObj->match(g_x509CertExtAttrObj, &certMatchParameters, &bResult); EXPECT_EQ(ret, CF_SUCCESS); EXPECT_EQ(bResult, false); diff --git a/test/unittest/v1.0/src/crypto_x509_test_common.cpp b/test/unittest/v1.0/src/crypto_x509_test_common.cpp index 1868a2c..eac1a9c 100644 --- a/test/unittest/v1.0/src/crypto_x509_test_common.cpp +++ b/test/unittest/v1.0/src/crypto_x509_test_common.cpp @@ -16,16 +16,17 @@ #include "crypto_x509_test_common.h" #include +#include +#include "cert_crl_common.h" #include "certificate_openssl_common.h" #include "cf_blob.h" #include "cf_log.h" +#include "fwk_class.h" #include "memory_mock.h" #include "securec.h" #include "x509_certificate.h" #include "x509_certificate_openssl.h" -#include "fwk_class.h" -#include #define CONSTRUCT_CERTPOLICY_DATA_SIZE 1 @@ -132,12 +133,18 @@ const int g_testCrlWhichEntryWithExtSize = sizeof(g_testCrlWhichEntryWithExt); const int g_testCertChainPemSize = sizeof(g_testCertChainPem) / sizeof(char); +const int g_testCertChainPem163Size = sizeof(g_testCertChainPem163) / sizeof(char); + +const int g_testOcspResponderCertSize = sizeof(g_testOcspResponderCert) / sizeof(char); + const int g_testCertChainPemMidSize = sizeof(g_testCertChainPemMid) / sizeof(char); const int g_testCertChainPemMidCRLSize = sizeof(g_testCertChainPemMidCRL) / sizeof(char); const int g_testCertChainPemRootSize = sizeof(g_testCertChainPemRoot) / sizeof(char); +const int g_testCertChainPemRoot163Size = sizeof(g_testCertChainPemRoot163) / sizeof(char); + const int g_testCertChainPemNoRootSize = sizeof(g_testCertChainPemNoRoot) / sizeof(char); const int g_testCertChainPemNoRootHasPubKeySize = sizeof(g_testCertChainPemNoRootHasPubKey) / sizeof(char); @@ -215,6 +222,14 @@ const CfEncodingBlob g_inStreamChainDataDer = { const_cast(g_testChai const CfEncodingBlob g_inStreamChainDataPem = { reinterpret_cast(const_cast(g_testCertChainPem)), g_testCertChainPemSize, CF_FORMAT_PEM }; +const CfEncodingBlob g_inStreamChainDataPem163 = { + reinterpret_cast(const_cast(g_testCertChainPem163)), g_testCertChainPem163Size, CF_FORMAT_PEM +}; + +const CfEncodingBlob g_inStreamOcspResponderCert = { + reinterpret_cast(const_cast(g_testOcspResponderCert)), g_testOcspResponderCertSize, CF_FORMAT_PEM +}; + const CfEncodingBlob g_inStreamChainDataPemMid = { reinterpret_cast(const_cast(g_testCertChainPemMid)), g_testCertChainPemMidSize, CF_FORMAT_PEM }; @@ -223,6 +238,10 @@ const CfEncodingBlob g_inStreamChainDataPemRoot = { reinterpret_cast(const_cast(g_testCertChainPemRoot)), g_testCertChainPemRootSize, CF_FORMAT_PEM }; +const CfEncodingBlob g_inStreamChainDataPemRoot163 = { reinterpret_cast( + const_cast(g_testCertChainPemRoot163)), + g_testCertChainPemRoot163Size, CF_FORMAT_PEM }; + const CfEncodingBlob g_inStreamChainDataPemNoRoot = { reinterpret_cast( const_cast(g_testCertChainPemNoRoot)), g_testCertChainPemNoRootSize, CF_FORMAT_PEM }; @@ -311,3 +330,113 @@ const char *GetValidX509CertificateClass(void) { return HCF_X509_CERTIFICATE_CLASS; } + +void FreeTrustAnchor(HcfX509TrustAnchor *&trustAnchor) +{ + if (trustAnchor == nullptr) { + return; + } + CfBlobFree(&trustAnchor->CAPubKey); + CfBlobFree(&trustAnchor->CASubject); + CfObjDestroy(trustAnchor->CACert); + trustAnchor->CACert = nullptr; + CfFree(trustAnchor); + trustAnchor = nullptr; +} + +void BuildAnchorArr(const CfEncodingBlob &certInStream, HcfX509TrustAnchorArray &trustAnchorArray) +{ + HcfX509TrustAnchor *anchor = static_cast(HcfMalloc(sizeof(HcfX509TrustAnchor), 0)); + ASSERT_NE(anchor, nullptr); + + (void)HcfX509CertificateCreate(&certInStream, &anchor->CACert); + trustAnchorArray.data = static_cast(HcfMalloc(1 * sizeof(HcfX509TrustAnchor *), 0)); + ASSERT_NE(trustAnchorArray.data, nullptr); + trustAnchorArray.data[0] = anchor; + trustAnchorArray.count = 1; +} + +void FreeTrustAnchorArr(HcfX509TrustAnchorArray &trustAnchorArray) +{ + for (uint32_t i = 0; i < trustAnchorArray.count; ++i) { + HcfX509TrustAnchor *anchor = trustAnchorArray.data[i]; + FreeTrustAnchor(anchor); + } + CfFree(trustAnchorArray.data); + trustAnchorArray.data = nullptr; + trustAnchorArray.count = 0; +} + +void BuildCollectionArr(const CfEncodingBlob *certInStream, const CfEncodingBlob *crlInStream, + HcfCertCRLCollectionArray &certCRLCollections) +{ + CfResult ret = CF_SUCCESS; + HcfX509CertificateArray *certArray = nullptr; + if (certInStream != nullptr) { + certArray = static_cast(HcfMalloc(sizeof(HcfX509CertificateArray), 0)); + ASSERT_NE(certArray, nullptr); + + HcfX509Certificate *x509CertObj = nullptr; + (void)HcfX509CertificateCreate(certInStream, &x509CertObj); + ASSERT_NE(x509CertObj, nullptr); + + certArray->data = static_cast(HcfMalloc(1 * sizeof(HcfX509Certificate *), 0)); + ASSERT_NE(certArray->data, nullptr); + certArray->data[0] = x509CertObj; + certArray->count = 1; + } + + HcfX509CrlArray *crlArray = nullptr; + if (crlInStream != nullptr) { + crlArray = static_cast(HcfMalloc(sizeof(HcfX509CrlArray), 0)); + ASSERT_NE(crlArray, nullptr); + + HcfX509Crl *x509Crl = nullptr; + ret = HcfX509CrlCreate(crlInStream, &x509Crl); + ASSERT_EQ(ret, CF_SUCCESS); + ASSERT_NE(x509Crl, nullptr); + + crlArray->data = static_cast(HcfMalloc(1 * sizeof(HcfX509Crl *), 0)); + ASSERT_NE(crlArray->data, nullptr); + crlArray->data[0] = x509Crl; + crlArray->count = 1; + } + + HcfCertCrlCollection *x509CertCrlCollection = nullptr; + ret = HcfCertCrlCollectionCreate(certArray, crlArray, &x509CertCrlCollection); + ASSERT_EQ(ret, CF_SUCCESS); + ASSERT_NE(x509CertCrlCollection, nullptr); + + certCRLCollections.data = static_cast(HcfMalloc(1 * sizeof(HcfCertCrlCollection *), 0)); + ASSERT_NE(certCRLCollections.data, nullptr); + certCRLCollections.data[0] = x509CertCrlCollection; + certCRLCollections.count = 1; + + FreeCertArrayData(certArray); + CfFree(certArray); + FreeCrlArrayData(crlArray); + CfFree(crlArray); +} + +void FreeCertCrlCollectionArr(HcfCertCRLCollectionArray &certCRLCollections) +{ + for (uint32_t i = 0; i < certCRLCollections.count; ++i) { + HcfCertCrlCollection *collection = certCRLCollections.data[i]; + CfObjDestroy(collection); + } + CfFree(certCRLCollections.data); + certCRLCollections.data = nullptr; + certCRLCollections.count = 0; +} + +void FreeValidateResult(HcfX509CertChainValidateResult &result) +{ + if (result.entityCert != nullptr) { + CfObjDestroy(result.entityCert); + result.entityCert = nullptr; + } + + if (result.trustAnchor != nullptr) { + FreeTrustAnchor(result.trustAnchor); + } +}