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