18e920a95Sopenharmony_ci/*
28e920a95Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38e920a95Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48e920a95Sopenharmony_ci * you may not use this file except in compliance with the License.
58e920a95Sopenharmony_ci * You may obtain a copy of the License at
68e920a95Sopenharmony_ci *
78e920a95Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88e920a95Sopenharmony_ci *
98e920a95Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108e920a95Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118e920a95Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128e920a95Sopenharmony_ci * See the License for the specific language governing permissions and
138e920a95Sopenharmony_ci * limitations under the License.
148e920a95Sopenharmony_ci */
158e920a95Sopenharmony_ci
168e920a95Sopenharmony_ci#include "huks_attest_verifier.h"
178e920a95Sopenharmony_ci
188e920a95Sopenharmony_ci#include <openssl/asn1.h>
198e920a95Sopenharmony_ci#include <openssl/obj_mac.h>
208e920a95Sopenharmony_ci#include <openssl/objects.h>
218e920a95Sopenharmony_ci#include <openssl/ossl_typ.h>
228e920a95Sopenharmony_ci#include <openssl/pem.h>
238e920a95Sopenharmony_ci#include <openssl/safestack.h>
248e920a95Sopenharmony_ci#include <openssl/x509.h>
258e920a95Sopenharmony_ci#include <openssl/x509v3.h>
268e920a95Sopenharmony_ci#include <openssl/x509_vfy.h>
278e920a95Sopenharmony_ci#include <string>
288e920a95Sopenharmony_ci#include <vector>
298e920a95Sopenharmony_ci
308e920a95Sopenharmony_ci#include "byte_buffer.h"
318e920a95Sopenharmony_ci#include "cert_utils.h"
328e920a95Sopenharmony_ci#include "log.h"
338e920a95Sopenharmony_ci#include "openssl_utils.h"
348e920a95Sopenharmony_ci
358e920a95Sopenharmony_cinamespace OHOS {
368e920a95Sopenharmony_cinamespace Security {
378e920a95Sopenharmony_cinamespace CodeSign {
388e920a95Sopenharmony_cistatic const std::string ATTEST_ROOT_CA_PATH = "/system/etc/security/trusted_attest_root_ca.cer";
398e920a95Sopenharmony_cistatic const std::vector<std::string> ATTESTTATION_EXTENSION = {
408e920a95Sopenharmony_ci    "1.3.6.1.4.1.2011.2.376.1.3",
418e920a95Sopenharmony_ci    "AttestationInfo",
428e920a95Sopenharmony_ci    "Attestation Information"
438e920a95Sopenharmony_ci};
448e920a95Sopenharmony_ci
458e920a95Sopenharmony_cistatic const std::vector<std::string> SA_INFO_EXTENSION = {
468e920a95Sopenharmony_ci    "1.3.6.1.4.1.2011.2.376.2.1.3.1",
478e920a95Sopenharmony_ci    "SA INFO",
488e920a95Sopenharmony_ci    "SystemAbiliy Information"
498e920a95Sopenharmony_ci};
508e920a95Sopenharmony_ci
518e920a95Sopenharmony_cistatic const std::vector<std::string> CHALLENGE_EXTENSION = {
528e920a95Sopenharmony_ci    "1.3.6.1.4.1.2011.2.376.2.1.4",
538e920a95Sopenharmony_ci    "Challenge",
548e920a95Sopenharmony_ci    "Challenge"
558e920a95Sopenharmony_ci};
568e920a95Sopenharmony_ci
578e920a95Sopenharmony_cistatic const std::string LOCAL_CODE_SIGN_SA_NAME = "local_code_sign";
588e920a95Sopenharmony_ci
598e920a95Sopenharmony_cistatic constexpr uint32_t MIN_VECTOR_SIZE = 3;
608e920a95Sopenharmony_cistatic bool g_verifierInited = false;
618e920a95Sopenharmony_cistatic int g_saNid = 0;
628e920a95Sopenharmony_cistatic int g_challengeNid = 0;
638e920a95Sopenharmony_cistatic int g_attestationNid = 0;
648e920a95Sopenharmony_ci#ifdef VERIFY_KEY_ATTEST_CERTCHAIN
658e920a95Sopenharmony_cistatic constexpr uint32_t COMMON_NAME_BUF_SIZE = 256;
668e920a95Sopenharmony_ci#endif
678e920a95Sopenharmony_ci
688e920a95Sopenharmony_cistatic inline int GetNidFromDefination(const std::vector<std::string> &defVector)
698e920a95Sopenharmony_ci{
708e920a95Sopenharmony_ci    if (defVector.size() < MIN_VECTOR_SIZE) {
718e920a95Sopenharmony_ci        return NID_undef;
728e920a95Sopenharmony_ci    }
738e920a95Sopenharmony_ci    return CreateNIDFromOID(defVector[0], defVector[1], defVector[defVector.size() - 1]);
748e920a95Sopenharmony_ci}
758e920a95Sopenharmony_ci
768e920a95Sopenharmony_cistatic void InitVerifier()
778e920a95Sopenharmony_ci{
788e920a95Sopenharmony_ci    if (g_verifierInited) {
798e920a95Sopenharmony_ci        return;
808e920a95Sopenharmony_ci    }
818e920a95Sopenharmony_ci    g_saNid = GetNidFromDefination(SA_INFO_EXTENSION);
828e920a95Sopenharmony_ci    g_challengeNid = GetNidFromDefination(CHALLENGE_EXTENSION);
838e920a95Sopenharmony_ci    g_attestationNid = GetNidFromDefination(ATTESTTATION_EXTENSION);
848e920a95Sopenharmony_ci    LOG_DEBUG("g_saNid = %{public}d, g_challengeNid = %{public}d, g_attestationNid = %{public}d",
858e920a95Sopenharmony_ci        g_saNid, g_challengeNid, g_attestationNid);
868e920a95Sopenharmony_ci    g_verifierInited = true;
878e920a95Sopenharmony_ci}
888e920a95Sopenharmony_ci
898e920a95Sopenharmony_cistatic bool AddCAToStore(X509_STORE *store)
908e920a95Sopenharmony_ci{
918e920a95Sopenharmony_ci    FILE *fp = fopen(ATTEST_ROOT_CA_PATH.c_str(), "r");
928e920a95Sopenharmony_ci    if (fp == nullptr) {
938e920a95Sopenharmony_ci        LOG_ERROR("Open file failed.");
948e920a95Sopenharmony_ci        return false;
958e920a95Sopenharmony_ci    }
968e920a95Sopenharmony_ci
978e920a95Sopenharmony_ci    X509 *caCert = nullptr;
988e920a95Sopenharmony_ci    do {
998e920a95Sopenharmony_ci        caCert = PEM_read_X509(fp, nullptr, nullptr, nullptr);
1008e920a95Sopenharmony_ci        if (caCert == nullptr) {
1018e920a95Sopenharmony_ci            break;
1028e920a95Sopenharmony_ci        }
1038e920a95Sopenharmony_ci        if (X509_STORE_add_cert(store, caCert) <= 0) {
1048e920a95Sopenharmony_ci            LOG_ERROR("add cert to X509 store failed");
1058e920a95Sopenharmony_ci            GetOpensslErrorMessage();
1068e920a95Sopenharmony_ci        }
1078e920a95Sopenharmony_ci        LOG_INFO("Add root CA successfully");
1088e920a95Sopenharmony_ci    } while (caCert != nullptr);
1098e920a95Sopenharmony_ci    (void) fclose(fp);
1108e920a95Sopenharmony_ci    return true;
1118e920a95Sopenharmony_ci}
1128e920a95Sopenharmony_ci
1138e920a95Sopenharmony_cistatic bool VerifyIssurCert(X509 *cert, STACK_OF(X509) *chain)
1148e920a95Sopenharmony_ci{
1158e920a95Sopenharmony_ci    X509_STORE *store = X509_STORE_new();
1168e920a95Sopenharmony_ci    if (store == nullptr) {
1178e920a95Sopenharmony_ci        return false;
1188e920a95Sopenharmony_ci    }
1198e920a95Sopenharmony_ci
1208e920a95Sopenharmony_ci    bool ret = false;
1218e920a95Sopenharmony_ci    X509_STORE_CTX *storeCtx = nullptr;
1228e920a95Sopenharmony_ci
1238e920a95Sopenharmony_ci    do {
1248e920a95Sopenharmony_ci        if (!AddCAToStore(store)) {
1258e920a95Sopenharmony_ci            break;
1268e920a95Sopenharmony_ci        }
1278e920a95Sopenharmony_ci        storeCtx = X509_STORE_CTX_new();
1288e920a95Sopenharmony_ci        if (storeCtx == nullptr) {
1298e920a95Sopenharmony_ci            break;
1308e920a95Sopenharmony_ci        }
1318e920a95Sopenharmony_ci
1328e920a95Sopenharmony_ci        if (!X509_STORE_CTX_init(storeCtx, store, cert, chain)) {
1338e920a95Sopenharmony_ci            LOG_ERROR("init X509_STORE_CTX failed.");
1348e920a95Sopenharmony_ci            break;
1358e920a95Sopenharmony_ci        }
1368e920a95Sopenharmony_ci        X509_STORE_CTX_set_purpose(storeCtx, X509_PURPOSE_ANY);
1378e920a95Sopenharmony_ci        // because user can set date of device, validation skip time check for fool-proofing
1388e920a95Sopenharmony_ci        X509_STORE_CTX_set_flags(storeCtx, X509_V_FLAG_NO_CHECK_TIME);
1398e920a95Sopenharmony_ci        int index = X509_verify_cert(storeCtx);
1408e920a95Sopenharmony_ci        if (index <= 0) {
1418e920a95Sopenharmony_ci            index = X509_STORE_CTX_get_error(storeCtx);
1428e920a95Sopenharmony_ci            LOG_ERROR("Verify cert failed, msg = %{public}s", X509_verify_cert_error_string(index));
1438e920a95Sopenharmony_ci            break;
1448e920a95Sopenharmony_ci        }
1458e920a95Sopenharmony_ci        ret = true;
1468e920a95Sopenharmony_ci    } while (0);
1478e920a95Sopenharmony_ci    if (!ret) {
1488e920a95Sopenharmony_ci        GetOpensslErrorMessage();
1498e920a95Sopenharmony_ci    }
1508e920a95Sopenharmony_ci    X509_STORE_CTX_free(storeCtx);
1518e920a95Sopenharmony_ci    X509_STORE_free(store);
1528e920a95Sopenharmony_ci    return ret;
1538e920a95Sopenharmony_ci}
1548e920a95Sopenharmony_ci
1558e920a95Sopenharmony_cistatic bool VerifySigningCert(X509 *signCert, X509 *issuerCert)
1568e920a95Sopenharmony_ci{
1578e920a95Sopenharmony_ci    EVP_PKEY *key = X509_get0_pubkey(issuerCert);
1588e920a95Sopenharmony_ci    if (key == nullptr) {
1598e920a95Sopenharmony_ci        LOG_ERROR("get pub key failed.");
1608e920a95Sopenharmony_ci        return false;
1618e920a95Sopenharmony_ci    }
1628e920a95Sopenharmony_ci    if (X509_verify(signCert, key) <= 0) {
1638e920a95Sopenharmony_ci        LOG_ERROR("verify signing cert failed.");
1648e920a95Sopenharmony_ci        GetOpensslErrorMessage();
1658e920a95Sopenharmony_ci        return false;
1668e920a95Sopenharmony_ci    }
1678e920a95Sopenharmony_ci    return true;
1688e920a95Sopenharmony_ci}
1698e920a95Sopenharmony_ci
1708e920a95Sopenharmony_cistatic bool CompareTargetValue(int nid, uint8_t *data, int size, const ByteBuffer &challenge)
1718e920a95Sopenharmony_ci{
1728e920a95Sopenharmony_ci    if (nid == g_saNid) {
1738e920a95Sopenharmony_ci        std::string str(reinterpret_cast<char *>(data), size);
1748e920a95Sopenharmony_ci        LOG_INFO("compare with proc = %{private}s", str.c_str());
1758e920a95Sopenharmony_ci        return str.find(LOCAL_CODE_SIGN_SA_NAME) != std::string::npos;
1768e920a95Sopenharmony_ci    } else if (nid == g_challengeNid) {
1778e920a95Sopenharmony_ci        LOG_INFO("compare with challenge");
1788e920a95Sopenharmony_ci        return (static_cast<uint32_t>(size) == challenge.GetSize())
1798e920a95Sopenharmony_ci                    && (memcmp(data, challenge.GetBuffer(), size) == 0);
1808e920a95Sopenharmony_ci    }
1818e920a95Sopenharmony_ci    return true;
1828e920a95Sopenharmony_ci}
1838e920a95Sopenharmony_ci
1848e920a95Sopenharmony_cistatic bool ParseASN1Sequence(uint8_t *data, int size, const ByteBuffer &challenge)
1858e920a95Sopenharmony_ci{
1868e920a95Sopenharmony_ci    STACK_OF(ASN1_TYPE) *types = d2i_ASN1_SEQUENCE_ANY(
1878e920a95Sopenharmony_ci        nullptr, const_cast<const uint8_t **>(&data), size);
1888e920a95Sopenharmony_ci    if (types == nullptr) {
1898e920a95Sopenharmony_ci        return false;
1908e920a95Sopenharmony_ci    }
1918e920a95Sopenharmony_ci
1928e920a95Sopenharmony_ci    int num = sk_ASN1_TYPE_num(types);
1938e920a95Sopenharmony_ci    int curNid = -1;
1948e920a95Sopenharmony_ci    bool ret = true;
1958e920a95Sopenharmony_ci    for (int i = 0; i < num; i++) {
1968e920a95Sopenharmony_ci        ASN1_TYPE *type = sk_ASN1_TYPE_value(types, i);
1978e920a95Sopenharmony_ci        if (type->type == V_ASN1_SEQUENCE) {
1988e920a95Sopenharmony_ci            ret = ParseASN1Sequence(type->value.sequence->data, type->value.sequence->length,
1998e920a95Sopenharmony_ci                challenge);
2008e920a95Sopenharmony_ci        } else if (type->type == V_ASN1_OBJECT) {
2018e920a95Sopenharmony_ci            ASN1_OBJECT *obj = type->value.object;
2028e920a95Sopenharmony_ci            curNid = OBJ_obj2nid(obj);
2038e920a95Sopenharmony_ci        } else if (type->type == V_ASN1_OCTET_STRING) {
2048e920a95Sopenharmony_ci            ASN1_OCTET_STRING *value = type->value.octet_string;
2058e920a95Sopenharmony_ci            ret = CompareTargetValue(curNid, value->data, value->length, challenge);
2068e920a95Sopenharmony_ci        }
2078e920a95Sopenharmony_ci        if (!ret) {
2088e920a95Sopenharmony_ci            LOG_ERROR("Value is unexpected");
2098e920a95Sopenharmony_ci            break;
2108e920a95Sopenharmony_ci        }
2118e920a95Sopenharmony_ci    }
2128e920a95Sopenharmony_ci    return ret;
2138e920a95Sopenharmony_ci}
2148e920a95Sopenharmony_ci
2158e920a95Sopenharmony_cistatic bool VerifyExtension(X509 *cert, const ByteBuffer &challenge)
2168e920a95Sopenharmony_ci{
2178e920a95Sopenharmony_ci    if (challenge.GetBuffer() == nullptr) {
2188e920a95Sopenharmony_ci        return false;
2198e920a95Sopenharmony_ci    }
2208e920a95Sopenharmony_ci
2218e920a95Sopenharmony_ci    const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(cert);
2228e920a95Sopenharmony_ci    int num;
2238e920a95Sopenharmony_ci
2248e920a95Sopenharmony_ci    if ((num = sk_X509_EXTENSION_num(exts)) <= 0) {
2258e920a95Sopenharmony_ci        LOG_ERROR("Get extension failed.");
2268e920a95Sopenharmony_ci        return false;
2278e920a95Sopenharmony_ci    }
2288e920a95Sopenharmony_ci
2298e920a95Sopenharmony_ci    InitVerifier();
2308e920a95Sopenharmony_ci    for (int i = 0; i < num; i++) {
2318e920a95Sopenharmony_ci        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
2328e920a95Sopenharmony_ci        ASN1_OBJECT *obj = X509_EXTENSION_get_object(ext);
2338e920a95Sopenharmony_ci        if (obj == nullptr) {
2348e920a95Sopenharmony_ci            LOG_ERROR("Get ans1 object faild");
2358e920a95Sopenharmony_ci            continue;
2368e920a95Sopenharmony_ci        }
2378e920a95Sopenharmony_ci        int curNid = OBJ_obj2nid(obj);
2388e920a95Sopenharmony_ci        if (g_attestationNid == curNid) {
2398e920a95Sopenharmony_ci            const ASN1_OCTET_STRING *extData = X509_EXTENSION_get_data(ext);
2408e920a95Sopenharmony_ci            if (!ParseASN1Sequence(extData->data, extData->length, challenge)) {
2418e920a95Sopenharmony_ci                LOG_INFO("extension verify failed.");
2428e920a95Sopenharmony_ci                return false;
2438e920a95Sopenharmony_ci            }
2448e920a95Sopenharmony_ci        }
2458e920a95Sopenharmony_ci    }
2468e920a95Sopenharmony_ci    return true;
2478e920a95Sopenharmony_ci}
2488e920a95Sopenharmony_ci
2498e920a95Sopenharmony_ci#ifdef CODE_SIGNATURE_DEBUGGABLE
2508e920a95Sopenharmony_cistatic void ShowCertInfo(const std::vector<ByteBuffer> &certChainBuffer,
2518e920a95Sopenharmony_ci    const ByteBuffer &issuerBuffer, const ByteBuffer &certBuffer)
2528e920a95Sopenharmony_ci{
2538e920a95Sopenharmony_ci    std::string pem;
2548e920a95Sopenharmony_ci    LOG_INFO("Dump cert chain");
2558e920a95Sopenharmony_ci    for (auto cert: certChainBuffer) {
2568e920a95Sopenharmony_ci        if (ConvertCertToPEMString(cert, pem)) {
2578e920a95Sopenharmony_ci            LOG_INFO("%{private}s", pem.c_str());
2588e920a95Sopenharmony_ci        }
2598e920a95Sopenharmony_ci    }
2608e920a95Sopenharmony_ci    LOG_INFO("Dump issuer cert");
2618e920a95Sopenharmony_ci    if (ConvertCertToPEMString(issuerBuffer, pem)) {
2628e920a95Sopenharmony_ci        LOG_INFO("%{private}s", pem.c_str());
2638e920a95Sopenharmony_ci    }
2648e920a95Sopenharmony_ci    LOG_INFO("Dump signing cert");
2658e920a95Sopenharmony_ci    if (ConvertCertToPEMString(certBuffer, pem)) {
2668e920a95Sopenharmony_ci        LOG_INFO("%{private}s", pem.c_str());
2678e920a95Sopenharmony_ci    }
2688e920a95Sopenharmony_ci}
2698e920a95Sopenharmony_ci#endif
2708e920a95Sopenharmony_ci
2718e920a95Sopenharmony_cibool VerifyCertAndExtension(X509 *signCert, X509 *issuerCert, const ByteBuffer &challenge)
2728e920a95Sopenharmony_ci{
2738e920a95Sopenharmony_ci    if (!VerifySigningCert(signCert, issuerCert)) {
2748e920a95Sopenharmony_ci        return false;
2758e920a95Sopenharmony_ci    }
2768e920a95Sopenharmony_ci    LOG_DEBUG("Verify sign cert pass");
2778e920a95Sopenharmony_ci
2788e920a95Sopenharmony_ci    if (!VerifyExtension(signCert, challenge)) {
2798e920a95Sopenharmony_ci        LOG_ERROR("Verify extension failed.");
2808e920a95Sopenharmony_ci        return false;
2818e920a95Sopenharmony_ci    }
2828e920a95Sopenharmony_ci    LOG_INFO("Verify success");
2838e920a95Sopenharmony_ci    return true;
2848e920a95Sopenharmony_ci}
2858e920a95Sopenharmony_ci
2868e920a95Sopenharmony_cistatic bool VerifyIntermediateCASubject(const std::vector<ByteBuffer> &certChainBuffer)
2878e920a95Sopenharmony_ci{
2888e920a95Sopenharmony_ci#ifndef VERIFY_KEY_ATTEST_CERTCHAIN
2898e920a95Sopenharmony_ci    LOG_INFO("Skip intermediate CA subject verification.");
2908e920a95Sopenharmony_ci    return true;
2918e920a95Sopenharmony_ci#else
2928e920a95Sopenharmony_ci    if (certChainBuffer.empty()) {
2938e920a95Sopenharmony_ci        LOG_ERROR("The vector is empty");
2948e920a95Sopenharmony_ci        return false;
2958e920a95Sopenharmony_ci    }
2968e920a95Sopenharmony_ci
2978e920a95Sopenharmony_ci    auto certBuffer = certChainBuffer.back();
2988e920a95Sopenharmony_ci    X509 *cert = LoadCertFromBuffer(certBuffer.GetBuffer(), certBuffer.GetSize());
2998e920a95Sopenharmony_ci    if (cert == nullptr) {
3008e920a95Sopenharmony_ci        LOG_ERROR("Load intermediate CA cert failed.");
3018e920a95Sopenharmony_ci        return false;
3028e920a95Sopenharmony_ci    }
3038e920a95Sopenharmony_ci
3048e920a95Sopenharmony_ci    bool ret = false;
3058e920a95Sopenharmony_ci    do {
3068e920a95Sopenharmony_ci        X509_NAME *subjectName = X509_get_subject_name(cert);
3078e920a95Sopenharmony_ci        if (subjectName == nullptr) {
3088e920a95Sopenharmony_ci            LOG_ERROR("Get subject name failed.");
3098e920a95Sopenharmony_ci            break;
3108e920a95Sopenharmony_ci        }
3118e920a95Sopenharmony_ci
3128e920a95Sopenharmony_ci        char commonNameBuf[COMMON_NAME_BUF_SIZE] = {0};
3138e920a95Sopenharmony_ci        int len = X509_NAME_get_text_by_NID(subjectName, NID_commonName, commonNameBuf, COMMON_NAME_BUF_SIZE);
3148e920a95Sopenharmony_ci        if (len <= 0) {
3158e920a95Sopenharmony_ci            LOG_ERROR("Get common name failed.");
3168e920a95Sopenharmony_ci            break;
3178e920a95Sopenharmony_ci        }
3188e920a95Sopenharmony_ci
3198e920a95Sopenharmony_ci        if (!strstr(commonNameBuf, "Huawei CBG Mobile Equipment CA") &&
3208e920a95Sopenharmony_ci            !strstr(commonNameBuf, "Huawei CBG Equipment S2 CA") &&
3218e920a95Sopenharmony_ci            !strstr(commonNameBuf, "Huawei CBG Equipment S3 CA")) {
3228e920a95Sopenharmony_ci            LOG_ERROR("Intermediate CA common name not matched, common name:%{private}s", commonNameBuf);
3238e920a95Sopenharmony_ci            break;
3248e920a95Sopenharmony_ci        }
3258e920a95Sopenharmony_ci
3268e920a95Sopenharmony_ci        ret = true;
3278e920a95Sopenharmony_ci    } while (0);
3288e920a95Sopenharmony_ci
3298e920a95Sopenharmony_ci    X509_free(cert);
3308e920a95Sopenharmony_ci    return ret;
3318e920a95Sopenharmony_ci#endif
3328e920a95Sopenharmony_ci}
3338e920a95Sopenharmony_ci
3348e920a95Sopenharmony_cibool GetVerifiedCert(const ByteBuffer &buffer, const ByteBuffer &challenge, ByteBuffer &certBuffer)
3358e920a95Sopenharmony_ci{
3368e920a95Sopenharmony_ci    std::vector<ByteBuffer> certChainBuffer;
3378e920a95Sopenharmony_ci    ByteBuffer issuerBuffer;
3388e920a95Sopenharmony_ci    if (!GetCertChainFormBuffer(buffer, certBuffer, issuerBuffer, certChainBuffer)) {
3398e920a95Sopenharmony_ci        return false;
3408e920a95Sopenharmony_ci    }
3418e920a95Sopenharmony_ci    X509 *issuerCert = LoadCertFromBuffer(issuerBuffer.GetBuffer(), issuerBuffer.GetSize());
3428e920a95Sopenharmony_ci    if (issuerCert == nullptr) {
3438e920a95Sopenharmony_ci        LOG_ERROR("Load issuerCert cert failed.");
3448e920a95Sopenharmony_ci        return false;
3458e920a95Sopenharmony_ci    }
3468e920a95Sopenharmony_ci    bool ret = false;
3478e920a95Sopenharmony_ci    X509 *signCert = nullptr;
3488e920a95Sopenharmony_ci    STACK_OF(X509 *) certChain = nullptr;
3498e920a95Sopenharmony_ci    do {
3508e920a95Sopenharmony_ci        certChain = MakeStackOfCerts(certChainBuffer);
3518e920a95Sopenharmony_ci        if (certChain == nullptr) {
3528e920a95Sopenharmony_ci            LOG_ERROR("Load cert chain failed.");
3538e920a95Sopenharmony_ci            break;
3548e920a95Sopenharmony_ci        }
3558e920a95Sopenharmony_ci        if (!VerifyIntermediateCASubject(certChainBuffer)) {
3568e920a95Sopenharmony_ci            LOG_ERROR("Failed to verify the Intermediate CA subject.");
3578e920a95Sopenharmony_ci            break;
3588e920a95Sopenharmony_ci        }
3598e920a95Sopenharmony_ci        if (!VerifyIssurCert(issuerCert, certChain)) {
3608e920a95Sopenharmony_ci            LOG_ERROR("Verify issuer cert not pass.");
3618e920a95Sopenharmony_ci            break;
3628e920a95Sopenharmony_ci        }
3638e920a95Sopenharmony_ci        LOG_DEBUG("Verify issuer cert pass");
3648e920a95Sopenharmony_ci        signCert = LoadCertFromBuffer(certBuffer.GetBuffer(), certBuffer.GetSize());
3658e920a95Sopenharmony_ci        if (signCert == nullptr) {
3668e920a95Sopenharmony_ci            LOG_ERROR("Load signing cert failed.");
3678e920a95Sopenharmony_ci            break;
3688e920a95Sopenharmony_ci        }
3698e920a95Sopenharmony_ci        if (!VerifyCertAndExtension(signCert, issuerCert, challenge)) {
3708e920a95Sopenharmony_ci            break;
3718e920a95Sopenharmony_ci        }
3728e920a95Sopenharmony_ci        ret = true;
3738e920a95Sopenharmony_ci    } while (0);
3748e920a95Sopenharmony_ci    X509_free(signCert);
3758e920a95Sopenharmony_ci    X509_free(issuerCert);
3768e920a95Sopenharmony_ci    sk_X509_pop_free(certChain, X509_free);
3778e920a95Sopenharmony_ci#ifdef CODE_SIGNATURE_DEBUGGABLE
3788e920a95Sopenharmony_ci    if (!ret) {
3798e920a95Sopenharmony_ci        ShowCertInfo(certChainBuffer, issuerBuffer, certBuffer);
3808e920a95Sopenharmony_ci    }
3818e920a95Sopenharmony_ci#endif
3828e920a95Sopenharmony_ci    LOG_INFO("verify finished, ret = %{public}d.", ret);
3838e920a95Sopenharmony_ci    return ret;
3848e920a95Sopenharmony_ci}
3858e920a95Sopenharmony_ci}
3868e920a95Sopenharmony_ci}
3878e920a95Sopenharmony_ci}
388