1f2d4f7b0Sopenharmony_ci/*
2f2d4f7b0Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
3f2d4f7b0Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f2d4f7b0Sopenharmony_ci * you may not use this file except in compliance with the License.
5f2d4f7b0Sopenharmony_ci * You may obtain a copy of the License at
6f2d4f7b0Sopenharmony_ci *
7f2d4f7b0Sopenharmony_ci *    http://www.apache.org/licenses/LICENSE-2.0
8f2d4f7b0Sopenharmony_ci *
9f2d4f7b0Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f2d4f7b0Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f2d4f7b0Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f2d4f7b0Sopenharmony_ci * See the License for the specific language governing permissions and
13f2d4f7b0Sopenharmony_ci * limitations under the License.
14f2d4f7b0Sopenharmony_ci */
15f2d4f7b0Sopenharmony_ci
16f2d4f7b0Sopenharmony_ci#include "app_verify.h"
17f2d4f7b0Sopenharmony_ci#include <fcntl.h>
18f2d4f7b0Sopenharmony_ci#include <stdbool.h>
19f2d4f7b0Sopenharmony_ci#include <string.h>
20f2d4f7b0Sopenharmony_ci#include <sys/stat.h>
21f2d4f7b0Sopenharmony_ci#include <sys/types.h>
22f2d4f7b0Sopenharmony_ci#include <unistd.h>
23f2d4f7b0Sopenharmony_ci#include "app_centraldirectory.h"
24f2d4f7b0Sopenharmony_ci#include "app_common.h"
25f2d4f7b0Sopenharmony_ci#include "app_file.h"
26f2d4f7b0Sopenharmony_ci#include "app_provision.h"
27f2d4f7b0Sopenharmony_ci#include "app_verify_hap.h"
28f2d4f7b0Sopenharmony_ci#include "mbedtls/base64.h"
29f2d4f7b0Sopenharmony_ci#include "mbedtls/md.h"
30f2d4f7b0Sopenharmony_ci#include "mbedtls/pk.h"
31f2d4f7b0Sopenharmony_ci#include "mbedtls/x509_crt.h"
32f2d4f7b0Sopenharmony_ci#include "mbedtls_pkcs7.h"
33f2d4f7b0Sopenharmony_ci#include "securec.h"
34f2d4f7b0Sopenharmony_ci
35f2d4f7b0Sopenharmony_cistatic const TrustAppCert g_trustAppList[] = {
36f2d4f7b0Sopenharmony_ci    {
37f2d4f7b0Sopenharmony_ci        .maxCertPath = CERT_MAX_DEPTH,
38f2d4f7b0Sopenharmony_ci        .name = "huawei app gallary",
39f2d4f7b0Sopenharmony_ci        .appSignCert = "C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS AppGallery Application Release",
40f2d4f7b0Sopenharmony_ci        .profileSignCert = "C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS Profile Management",
41f2d4f7b0Sopenharmony_ci        .profileDebugSignCert = "C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS Profile Management Debug",
42f2d4f7b0Sopenharmony_ci        .issueCA = "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA",
43f2d4f7b0Sopenharmony_ci    },
44f2d4f7b0Sopenharmony_ci    {
45f2d4f7b0Sopenharmony_ci        .maxCertPath = CERT_MAX_DEPTH,
46f2d4f7b0Sopenharmony_ci        .name = "huawei system apps",
47f2d4f7b0Sopenharmony_ci        .appSignCert = "C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Release",
48f2d4f7b0Sopenharmony_ci        .profileSignCert = "C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Profile Release",
49f2d4f7b0Sopenharmony_ci        .profileDebugSignCert =
50f2d4f7b0Sopenharmony_ci            "C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Profile Release_Debug",
51f2d4f7b0Sopenharmony_ci        .issueCA = "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA",
52f2d4f7b0Sopenharmony_ci    },
53f2d4f7b0Sopenharmony_ci#ifndef OHOS_SIGN_HAPS_BY_SERVER
54f2d4f7b0Sopenharmony_ci    {
55f2d4f7b0Sopenharmony_ci        .maxCertPath = CERT_MAX_DEPTH,
56f2d4f7b0Sopenharmony_ci        .name = "OpenHarmony apps",
57f2d4f7b0Sopenharmony_ci        .appSignCert = "C=CN, O=OpenHarmony, OU=OpenHarmony Team, CN=OpenHarmony Application Release",
58f2d4f7b0Sopenharmony_ci        .profileSignCert = "C=CN, O=OpenHarmony, OU=OpenHarmony Team, CN=OpenHarmony Application Profile Release",
59f2d4f7b0Sopenharmony_ci        .profileDebugSignCert = "C=CN, O=OpenHarmony, OU=OpenHarmony Team, CN=OpenHarmony Application Profile Debug",
60f2d4f7b0Sopenharmony_ci        .issueCA = "C=CN, O=OpenHarmony, OU=OpenHarmony Team, CN=OpenHarmony Application CA",
61f2d4f7b0Sopenharmony_ci    },
62f2d4f7b0Sopenharmony_ci#endif
63f2d4f7b0Sopenharmony_ci};
64f2d4f7b0Sopenharmony_ci
65f2d4f7b0Sopenharmony_cistatic const TrustAppCert g_trustAppListTest[] = {
66f2d4f7b0Sopenharmony_ci    {
67f2d4f7b0Sopenharmony_ci        .maxCertPath = CERT_MAX_DEPTH,
68f2d4f7b0Sopenharmony_ci        .name = "huawei app gallary",
69f2d4f7b0Sopenharmony_ci        .appSignCert = "C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS AppGallery Application Release",
70f2d4f7b0Sopenharmony_ci        .profileSignCert = "C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS Profile Management",
71f2d4f7b0Sopenharmony_ci        .profileDebugSignCert = "C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS Profile Management Debug",
72f2d4f7b0Sopenharmony_ci        .issueCA = "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA Test",
73f2d4f7b0Sopenharmony_ci    },
74f2d4f7b0Sopenharmony_ci    {
75f2d4f7b0Sopenharmony_ci        .maxCertPath = CERT_MAX_DEPTH,
76f2d4f7b0Sopenharmony_ci        .name = "huawei system apps",
77f2d4f7b0Sopenharmony_ci        .appSignCert = "C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Dev",
78f2d4f7b0Sopenharmony_ci        .profileSignCert = "C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Profile Dev",
79f2d4f7b0Sopenharmony_ci        .profileDebugSignCert =
80f2d4f7b0Sopenharmony_ci            "C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Profile Dev_Debug",
81f2d4f7b0Sopenharmony_ci        .issueCA = "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA Test",
82f2d4f7b0Sopenharmony_ci    },
83f2d4f7b0Sopenharmony_ci};
84f2d4f7b0Sopenharmony_ci
85f2d4f7b0Sopenharmony_cistatic bool g_isDebugMode = false;
86f2d4f7b0Sopenharmony_ci
87f2d4f7b0Sopenharmony_cistatic bool g_isActsMode = false;
88f2d4f7b0Sopenharmony_ci
89f2d4f7b0Sopenharmony_cistatic void SignHeadN2H(HwSignHead *signHead)
90f2d4f7b0Sopenharmony_ci{
91f2d4f7b0Sopenharmony_ci    signHead->blockNum = HapGetInt((unsigned char *)&signHead->blockNum, sizeof(signHead->blockNum));
92f2d4f7b0Sopenharmony_ci    signHead->size = HapGetInt64((unsigned char *)&signHead->size, sizeof(signHead->size));
93f2d4f7b0Sopenharmony_ci    signHead->magicLow = HapGetInt64((unsigned char *)&signHead->magicLow, sizeof(signHead->magicLow));
94f2d4f7b0Sopenharmony_ci    signHead->magicHigh = HapGetInt64((unsigned char *)&signHead->magicHigh, sizeof(signHead->magicHigh));
95f2d4f7b0Sopenharmony_ci    signHead->version = HapGetInt((unsigned char *)&signHead->version, sizeof(signHead->version));
96f2d4f7b0Sopenharmony_ci    return;
97f2d4f7b0Sopenharmony_ci}
98f2d4f7b0Sopenharmony_ci
99f2d4f7b0Sopenharmony_cistatic void BlockHeadN2H(BlockHead *blockHead)
100f2d4f7b0Sopenharmony_ci{
101f2d4f7b0Sopenharmony_ci    blockHead->type = HapGetUnsignedInt((unsigned char *)&blockHead->type, sizeof(blockHead->type));
102f2d4f7b0Sopenharmony_ci    blockHead->length = HapGetUnsignedInt((unsigned char *)&blockHead->length, sizeof(blockHead->length));
103f2d4f7b0Sopenharmony_ci    blockHead->offset = HapGetUnsignedInt((unsigned char *)&blockHead->offset, sizeof(blockHead->offset));
104f2d4f7b0Sopenharmony_ci    return;
105f2d4f7b0Sopenharmony_ci}
106f2d4f7b0Sopenharmony_ci
107f2d4f7b0Sopenharmony_cistatic void ContentN2H(ContentInfo *content)
108f2d4f7b0Sopenharmony_ci{
109f2d4f7b0Sopenharmony_ci    content->blockNum = HapGetInt((unsigned char *)&content->blockNum, sizeof(content->blockNum));
110f2d4f7b0Sopenharmony_ci    content->size = HapGetInt((unsigned char *)&content->size, sizeof(content->size));
111f2d4f7b0Sopenharmony_ci    content->algId = HapGetInt((unsigned char *)&content->algId, sizeof(content->algId));
112f2d4f7b0Sopenharmony_ci    content->length = HapGetInt((unsigned char *)&content->length, sizeof(content->length));
113f2d4f7b0Sopenharmony_ci    return;
114f2d4f7b0Sopenharmony_ci}
115f2d4f7b0Sopenharmony_ci
116f2d4f7b0Sopenharmony_cistatic int32_t GetSignHead(const FileRead *file, SignatureInfo *signInfo)
117f2d4f7b0Sopenharmony_ci{
118f2d4f7b0Sopenharmony_ci    struct stat fileSt;
119f2d4f7b0Sopenharmony_ci    int32_t ret = fstat(file->fp, &fileSt);
120f2d4f7b0Sopenharmony_ci    if ((ret != 0) || (fileSt.st_size < sizeof(HwSignHead))) {
121f2d4f7b0Sopenharmony_ci        LOG_ERROR("fstat error, %d, filelen: %d", ret, (int)fileSt.st_size);
122f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
123f2d4f7b0Sopenharmony_ci    }
124f2d4f7b0Sopenharmony_ci    if (!FindSignature(file, signInfo)) {
125f2d4f7b0Sopenharmony_ci        LOG_ERROR("find signature error");
126f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
127f2d4f7b0Sopenharmony_ci    }
128f2d4f7b0Sopenharmony_ci    if (signInfo->hapCoreDirOffset < sizeof(HwSignHead)) {
129f2d4f7b0Sopenharmony_ci        LOG_ERROR("hapCoreDirOffset error, %d", signInfo->hapCoreDirOffset);
130f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
131f2d4f7b0Sopenharmony_ci    }
132f2d4f7b0Sopenharmony_ci    ret = lseek(file->fp, signInfo->hapCoreDirOffset - sizeof(HwSignHead), SEEK_SET);
133f2d4f7b0Sopenharmony_ci    if (ret < 0) {
134f2d4f7b0Sopenharmony_ci        LOG_ERROR("lseek error, %d", ret);
135f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
136f2d4f7b0Sopenharmony_ci    }
137f2d4f7b0Sopenharmony_ci    HwSignHead *signHead = APPV_MALLOC(sizeof(HwSignHead));
138f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_WTTH_LOG(signHead);
139f2d4f7b0Sopenharmony_ci    int32_t readLen = read(file->fp, signHead, sizeof(HwSignHead));
140f2d4f7b0Sopenharmony_ci    if (readLen != sizeof(HwSignHead)) {
141f2d4f7b0Sopenharmony_ci        LOG_ERROR("readLen %d, %d", readLen, (int)sizeof(HwSignHead));
142f2d4f7b0Sopenharmony_ci        APPV_FREE(signHead);
143f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
144f2d4f7b0Sopenharmony_ci    }
145f2d4f7b0Sopenharmony_ci    SignHeadN2H(signHead);
146f2d4f7b0Sopenharmony_ci    unsigned long long magicLow = HAP_SIG_BLOCK_MAGIC_LO;
147f2d4f7b0Sopenharmony_ci    unsigned long long magicHigh = HAP_SIG_BLOCK_MAGIC_HI;
148f2d4f7b0Sopenharmony_ci    if (signHead->version < VERSION_FOR_NEW_MAGIC_NUM) {
149f2d4f7b0Sopenharmony_ci        magicLow = HAP_SIG_BLOCK_MAGIC_LO_OLD;
150f2d4f7b0Sopenharmony_ci        magicHigh = HAP_SIG_BLOCK_MAGIC_HI_OLD;
151f2d4f7b0Sopenharmony_ci    }
152f2d4f7b0Sopenharmony_ci    if (signHead->magicLow != magicLow || signHead->magicHigh != magicHigh) {
153f2d4f7b0Sopenharmony_ci        LOG_ERROR("sign head magic invalid");
154f2d4f7b0Sopenharmony_ci        APPV_FREE(signHead);
155f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
156f2d4f7b0Sopenharmony_ci    }
157f2d4f7b0Sopenharmony_ci    LOG_INFO("sign head: size: %llu, blockNum:0x%x", signHead->size, signHead->blockNum);
158f2d4f7b0Sopenharmony_ci    signInfo->signHead = signHead;
159f2d4f7b0Sopenharmony_ci    signInfo->fullSignBlockOffset = signInfo->hapCoreDirOffset - (int)signHead->size;
160f2d4f7b0Sopenharmony_ci    signInfo->fileSize = fileSt.st_size;
161f2d4f7b0Sopenharmony_ci    if (signInfo->fullSignBlockOffset <= 0 || signInfo->fullSignBlockOffset >= signInfo->hapCoreDirOffset) {
162f2d4f7b0Sopenharmony_ci        LOG_ERROR("fullSignBlockOffset invalid");
163f2d4f7b0Sopenharmony_ci        APPV_FREE(signHead);
164f2d4f7b0Sopenharmony_ci        return V_ERR_GET_SIGNHEAD;
165f2d4f7b0Sopenharmony_ci    }
166f2d4f7b0Sopenharmony_ci    return V_OK;
167f2d4f7b0Sopenharmony_ci}
168f2d4f7b0Sopenharmony_ci
169f2d4f7b0Sopenharmony_cistatic int32_t FindBlockHead(const SignatureInfo *signInfo, int32_t fp, int32_t blockType, BlockHead *block)
170f2d4f7b0Sopenharmony_ci{
171f2d4f7b0Sopenharmony_ci    HwSignHead *signH = signInfo->signHead;
172f2d4f7b0Sopenharmony_ci    /* find signature block */
173f2d4f7b0Sopenharmony_ci    lseek(fp, signInfo->fullSignBlockOffset, SEEK_SET);
174f2d4f7b0Sopenharmony_ci    int32_t num = signH->blockNum;
175f2d4f7b0Sopenharmony_ci    if (num > MAX_BLOCK_NUM) {
176f2d4f7b0Sopenharmony_ci        return V_ERR;
177f2d4f7b0Sopenharmony_ci    }
178f2d4f7b0Sopenharmony_ci    while (num-- > 0) {
179f2d4f7b0Sopenharmony_ci        int32_t readLen = read(fp, block, sizeof(BlockHead));
180f2d4f7b0Sopenharmony_ci        if (readLen != sizeof(BlockHead)) {
181f2d4f7b0Sopenharmony_ci            LOG_ERROR("find block head , read err %d, %d", readLen, (int)sizeof(BlockHead));
182f2d4f7b0Sopenharmony_ci            return V_ERR;
183f2d4f7b0Sopenharmony_ci        }
184f2d4f7b0Sopenharmony_ci        int32_t type = HapGetInt((unsigned char *)&block->type, sizeof(block->type));
185f2d4f7b0Sopenharmony_ci        LOG_ERROR("find block type: %0x", type);
186f2d4f7b0Sopenharmony_ci        if (type == blockType) {
187f2d4f7b0Sopenharmony_ci            BlockHeadN2H(block);
188f2d4f7b0Sopenharmony_ci            return V_OK;
189f2d4f7b0Sopenharmony_ci        }
190f2d4f7b0Sopenharmony_ci    }
191f2d4f7b0Sopenharmony_ci    LOG_ERROR("get sign block by type failed, type: %d", blockType);
192f2d4f7b0Sopenharmony_ci    return V_ERR;
193f2d4f7b0Sopenharmony_ci}
194f2d4f7b0Sopenharmony_ci
195f2d4f7b0Sopenharmony_cichar *GetSignBlockByType(
196f2d4f7b0Sopenharmony_ci    const SignatureInfo *signInfo, int32_t fp, int32_t blockType, int32_t *len, BlockHead *blockHead)
197f2d4f7b0Sopenharmony_ci{
198f2d4f7b0Sopenharmony_ci    if (signInfo == NULL || blockHead == NULL) {
199f2d4f7b0Sopenharmony_ci        return NULL;
200f2d4f7b0Sopenharmony_ci    }
201f2d4f7b0Sopenharmony_ci    int32_t ret = FindBlockHead(signInfo, fp, blockType, blockHead);
202f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
203f2d4f7b0Sopenharmony_ci        LOG_ERROR("find block head error");
204f2d4f7b0Sopenharmony_ci        return NULL;
205f2d4f7b0Sopenharmony_ci    }
206f2d4f7b0Sopenharmony_ci    LOG_INFO("type: %u, len: %u, offset: %u signoffset: %d",
207f2d4f7b0Sopenharmony_ci        blockHead->type, blockHead->length, blockHead->offset, signInfo->fullSignBlockOffset);
208f2d4f7b0Sopenharmony_ci    /* sign block head length always 0
209f2d4f7b0Sopenharmony_ci        rawdata
210f2d4f7b0Sopenharmony_ci        xx block head
211f2d4f7b0Sopenharmony_ci        signdata
212f2d4f7b0Sopenharmony_ci        hwsignhead
213f2d4f7b0Sopenharmony_ci    */
214f2d4f7b0Sopenharmony_ci    if (blockHead->length == 0 || blockHead->length > (signInfo->hapCoreDirOffset - signInfo->fullSignBlockOffset)) {
215f2d4f7b0Sopenharmony_ci        return NULL;
216f2d4f7b0Sopenharmony_ci    }
217f2d4f7b0Sopenharmony_ci    if ((blockHead->length + 1) >= signInfo->fileSize) {
218f2d4f7b0Sopenharmony_ci        return NULL;
219f2d4f7b0Sopenharmony_ci    }
220f2d4f7b0Sopenharmony_ci    char *buf = APPV_MALLOC(blockHead->length + 1);
221f2d4f7b0Sopenharmony_ci    if (buf == NULL) {
222f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
223f2d4f7b0Sopenharmony_ci        return NULL;
224f2d4f7b0Sopenharmony_ci    }
225f2d4f7b0Sopenharmony_ci    buf[blockHead->length] = '\0';
226f2d4f7b0Sopenharmony_ci    struct stat fileSt;
227f2d4f7b0Sopenharmony_ci    ret = fstat(fp, &fileSt);
228f2d4f7b0Sopenharmony_ci    if ((ret != 0) || (fileSt.st_size < signInfo->fullSignBlockOffset + blockHead->offset + blockHead->length)) {
229f2d4f7b0Sopenharmony_ci        LOG_ERROR("fstat error, %d, filelen: %d", ret, (int)fileSt.st_size);
230f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
231f2d4f7b0Sopenharmony_ci        return NULL;
232f2d4f7b0Sopenharmony_ci    }
233f2d4f7b0Sopenharmony_ci    lseek(fp, signInfo->fullSignBlockOffset + blockHead->offset, SEEK_SET);
234f2d4f7b0Sopenharmony_ci    int32_t readLen = read(fp, buf, blockHead->length);
235f2d4f7b0Sopenharmony_ci    if (readLen != blockHead->length) {
236f2d4f7b0Sopenharmony_ci        LOG_ERROR("read error: %d, %d", readLen, blockHead->length);
237f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
238f2d4f7b0Sopenharmony_ci        return NULL;
239f2d4f7b0Sopenharmony_ci    }
240f2d4f7b0Sopenharmony_ci    *len = readLen;
241f2d4f7b0Sopenharmony_ci    LOG_INFO("buf begin");
242f2d4f7b0Sopenharmony_ci    return buf;
243f2d4f7b0Sopenharmony_ci}
244f2d4f7b0Sopenharmony_ci
245f2d4f7b0Sopenharmony_ciint32_t GetHashUnitLen(int32_t hashAlg)
246f2d4f7b0Sopenharmony_ci{
247f2d4f7b0Sopenharmony_ci    LOG_INFO("algId: %d", hashAlg);
248f2d4f7b0Sopenharmony_ci    return mbedtls_md_get_size(mbedtls_md_info_from_type((mbedtls_md_type_t)hashAlg));
249f2d4f7b0Sopenharmony_ci}
250f2d4f7b0Sopenharmony_ci
251f2d4f7b0Sopenharmony_cistatic int32_t CalcCmpContHash(const Pkcs7 *pkcs7, const SignerInfo *signer,
252f2d4f7b0Sopenharmony_ci    mbedtls_md_type_t algType, unsigned char *hash, size_t *hashLen)
253f2d4f7b0Sopenharmony_ci{
254f2d4f7b0Sopenharmony_ci    int32_t rc;
255f2d4f7b0Sopenharmony_ci    unsigned char *input = NULL;
256f2d4f7b0Sopenharmony_ci    size_t inputLen;
257f2d4f7b0Sopenharmony_ci
258f2d4f7b0Sopenharmony_ci    /* calc orinal context hash */
259f2d4f7b0Sopenharmony_ci    rc = PKCS7_GetContentData((Pkcs7 *)pkcs7, &input, &inputLen);
260f2d4f7b0Sopenharmony_ci    P_ERR_RETURN_WTTH_LOG(rc);
261f2d4f7b0Sopenharmony_ci
262f2d4f7b0Sopenharmony_ci    rc = mbedtls_md(mbedtls_md_info_from_type(algType), input, inputLen, hash);
263f2d4f7b0Sopenharmony_ci    if (rc) {
264f2d4f7b0Sopenharmony_ci        LOG_ERROR("Error: calc digest failed");
265f2d4f7b0Sopenharmony_ci        return rc;
266f2d4f7b0Sopenharmony_ci    }
267f2d4f7b0Sopenharmony_ci    *hashLen = mbedtls_md_get_size(mbedtls_md_info_from_type(algType));
268f2d4f7b0Sopenharmony_ci
269f2d4f7b0Sopenharmony_ci    /* compare the calc hash with the attributes hash */
270f2d4f7b0Sopenharmony_ci    unsigned char *digInAttr = NULL;
271f2d4f7b0Sopenharmony_ci    size_t digInAttrLen;
272f2d4f7b0Sopenharmony_ci    rc = PKCS7_GetDigestInSignerAuthAttr((SignerInfo *)signer, &digInAttr, &digInAttrLen);
273f2d4f7b0Sopenharmony_ci    if (rc != V_OK) {
274f2d4f7b0Sopenharmony_ci        LOG_ERROR("PKCS7_GetDigestInSignerAuthAttr error: %d", rc);
275f2d4f7b0Sopenharmony_ci        return rc;
276f2d4f7b0Sopenharmony_ci    }
277f2d4f7b0Sopenharmony_ci    if (digInAttrLen != *hashLen) {
278f2d4f7b0Sopenharmony_ci        LOG_ERROR("Error: content hash len is not equal with attr's hash len");
279f2d4f7b0Sopenharmony_ci        return V_ERR;
280f2d4f7b0Sopenharmony_ci    }
281f2d4f7b0Sopenharmony_ci    if (memcmp(hash, digInAttr, digInAttrLen) != 0) {
282f2d4f7b0Sopenharmony_ci        LOG_ERROR("Error: content hash not equal with attr hash");
283f2d4f7b0Sopenharmony_ci        return V_ERR;
284f2d4f7b0Sopenharmony_ci    }
285f2d4f7b0Sopenharmony_ci    return V_OK;
286f2d4f7b0Sopenharmony_ci}
287f2d4f7b0Sopenharmony_ci
288f2d4f7b0Sopenharmony_cistatic int32_t CalcDigest(const Pkcs7 *pkcs7, const SignerInfo *signer,
289f2d4f7b0Sopenharmony_ci    mbedtls_md_type_t algType, unsigned char *hash, size_t *hashLen)
290f2d4f7b0Sopenharmony_ci{
291f2d4f7b0Sopenharmony_ci    int32_t rc;
292f2d4f7b0Sopenharmony_ci    unsigned char *input = NULL;
293f2d4f7b0Sopenharmony_ci    size_t inputLen;
294f2d4f7b0Sopenharmony_ci    rc = CalcCmpContHash(pkcs7, signer, algType, hash, hashLen);
295f2d4f7b0Sopenharmony_ci    if (rc != V_OK) {
296f2d4f7b0Sopenharmony_ci        LOG_ERROR("Error: content hash not equal with attr hash");
297f2d4f7b0Sopenharmony_ci        return rc;
298f2d4f7b0Sopenharmony_ci    }
299f2d4f7b0Sopenharmony_ci    LOG_INFO("signer context hash equal with attr hash");
300f2d4f7b0Sopenharmony_ci
301f2d4f7b0Sopenharmony_ci    /* calc the attribute hash */
302f2d4f7b0Sopenharmony_ci    rc = PKCS7_GetSignerAuthAttr(signer, &input, &inputLen);
303f2d4f7b0Sopenharmony_ci    if (rc != V_OK) {
304f2d4f7b0Sopenharmony_ci        LOG_ERROR("Error: PKCS7_GetSignerAuthAttr failed ret: %d", rc);
305f2d4f7b0Sopenharmony_ci        return rc;
306f2d4f7b0Sopenharmony_ci    }
307f2d4f7b0Sopenharmony_ci    rc = mbedtls_md(mbedtls_md_info_from_type(algType), input, inputLen, hash);
308f2d4f7b0Sopenharmony_ci    if (rc != V_OK) {
309f2d4f7b0Sopenharmony_ci        LOG_ERROR("Error: calc digest failed ret: %d", rc);
310f2d4f7b0Sopenharmony_ci        return rc;
311f2d4f7b0Sopenharmony_ci    }
312f2d4f7b0Sopenharmony_ci    *hashLen = mbedtls_md_get_size(mbedtls_md_info_from_type(algType));
313f2d4f7b0Sopenharmony_ci    return V_OK;
314f2d4f7b0Sopenharmony_ci}
315f2d4f7b0Sopenharmony_ci
316f2d4f7b0Sopenharmony_cistatic int32_t VerifyRawHash(const SignatureInfo *signInfo, const FileRead *fileRead, const Pkcs7 *pkcs7Handle)
317f2d4f7b0Sopenharmony_ci{
318f2d4f7b0Sopenharmony_ci    /* parse content */
319f2d4f7b0Sopenharmony_ci    unsigned char *input = NULL;
320f2d4f7b0Sopenharmony_ci    size_t inputLen = 0;
321f2d4f7b0Sopenharmony_ci    /* calc orinal context hash */
322f2d4f7b0Sopenharmony_ci    int32_t ret = PKCS7_GetContentData((Pkcs7 *)pkcs7Handle, &input, &inputLen);
323f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
324f2d4f7b0Sopenharmony_ci        LOG_ERROR("get content info error: %d", ret);
325f2d4f7b0Sopenharmony_ci        return ret;
326f2d4f7b0Sopenharmony_ci    }
327f2d4f7b0Sopenharmony_ci    LOG_INFO("content: len: %d", (int)inputLen);
328f2d4f7b0Sopenharmony_ci
329f2d4f7b0Sopenharmony_ci    ContentInfo *content = APPV_MALLOC(sizeof(ContentInfo));
330f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_WTTH_LOG(content);
331f2d4f7b0Sopenharmony_ci
332f2d4f7b0Sopenharmony_ci    ret = memcpy_s(content, sizeof(ContentInfo), input, inputLen);
333f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
334f2d4f7b0Sopenharmony_ci        LOG_ERROR("mem cpy error, ret: %d", ret);
335f2d4f7b0Sopenharmony_ci        APPV_FREE(content);
336f2d4f7b0Sopenharmony_ci        return ret;
337f2d4f7b0Sopenharmony_ci    }
338f2d4f7b0Sopenharmony_ci    ContentN2H(content);
339f2d4f7b0Sopenharmony_ci    content->algId = GetDigestAlgorithmId((unsigned int)content->algId);
340f2d4f7b0Sopenharmony_ci    if (content->algId != HASH_ALG_SHA256 && content->algId != HASH_ALG_SHA384 && content->algId != HASH_ALG_SHA512) {
341f2d4f7b0Sopenharmony_ci        LOG_ERROR("hash alg invalid");
342f2d4f7b0Sopenharmony_ci        APPV_FREE(content);
343f2d4f7b0Sopenharmony_ci        return V_ERR;
344f2d4f7b0Sopenharmony_ci    }
345f2d4f7b0Sopenharmony_ci    HapBuf actualDigest = {0};
346f2d4f7b0Sopenharmony_ci    int32_t rootHashLen = GetHashUnitLen(content->algId);
347f2d4f7b0Sopenharmony_ci    if (!CreateHapBuffer(&actualDigest, rootHashLen)) {
348f2d4f7b0Sopenharmony_ci        LOG_ERROR("create buf fail");
349f2d4f7b0Sopenharmony_ci        APPV_FREE(content);
350f2d4f7b0Sopenharmony_ci        return V_ERR;
351f2d4f7b0Sopenharmony_ci    }
352f2d4f7b0Sopenharmony_ci    if (!VerifyIntegrityChunk(content->algId, fileRead->fp, signInfo, &actualDigest)) {
353f2d4f7b0Sopenharmony_ci        LOG_ERROR("get raw hash failed");
354f2d4f7b0Sopenharmony_ci        ClearHapBuffer(&actualDigest);
355f2d4f7b0Sopenharmony_ci        APPV_FREE(content);
356f2d4f7b0Sopenharmony_ci        return V_ERR;
357f2d4f7b0Sopenharmony_ci    }
358f2d4f7b0Sopenharmony_ci    if ((actualDigest.len != content->length) || (memcmp(actualDigest.buffer, content->hash, actualDigest.len) != 0)) {
359f2d4f7b0Sopenharmony_ci        LOG_ERROR("hash diff");
360f2d4f7b0Sopenharmony_ci        APPV_FREE(content);
361f2d4f7b0Sopenharmony_ci        ClearHapBuffer(&actualDigest);
362f2d4f7b0Sopenharmony_ci        return V_ERR_GET_HASH_DIFF;
363f2d4f7b0Sopenharmony_ci    }
364f2d4f7b0Sopenharmony_ci    APPV_FREE(content);
365f2d4f7b0Sopenharmony_ci    ClearHapBuffer(&actualDigest);
366f2d4f7b0Sopenharmony_ci    return V_OK;
367f2d4f7b0Sopenharmony_ci}
368f2d4f7b0Sopenharmony_ci
369f2d4f7b0Sopenharmony_cistatic int32_t GetCertTypeBySourceName(const TrustAppCert *cert)
370f2d4f7b0Sopenharmony_ci{
371f2d4f7b0Sopenharmony_ci    if (cert == NULL) {
372f2d4f7b0Sopenharmony_ci        return CERT_TYPE_OTHER;
373f2d4f7b0Sopenharmony_ci    } else if (strcmp(cert->name, "huawei app gallary") == 0) {
374f2d4f7b0Sopenharmony_ci        return CERT_TYPE_APPGALLARY;
375f2d4f7b0Sopenharmony_ci    } else if (strcmp(cert->name, "huawei system apps") == 0) {
376f2d4f7b0Sopenharmony_ci        return CERT_TYPE_SYETEM;
377f2d4f7b0Sopenharmony_ci#ifndef OHOS_SIGN_HAPS_BY_SERVER
378f2d4f7b0Sopenharmony_ci    } else if (strcmp(cert->name, "OpenHarmony apps") == 0) {
379f2d4f7b0Sopenharmony_ci        return CERT_TYPE_SYETEM;
380f2d4f7b0Sopenharmony_ci#endif
381f2d4f7b0Sopenharmony_ci    } else {
382f2d4f7b0Sopenharmony_ci        return CERT_TYPE_OTHER;
383f2d4f7b0Sopenharmony_ci    }
384f2d4f7b0Sopenharmony_ci}
385f2d4f7b0Sopenharmony_ci
386f2d4f7b0Sopenharmony_cistatic const TrustAppCert *GetProfSourceBySigningCert(const SignerResovledInfo *signer,
387f2d4f7b0Sopenharmony_ci                                                      const TrustAppCert* trustList, int32_t num)
388f2d4f7b0Sopenharmony_ci{
389f2d4f7b0Sopenharmony_ci    for (int32_t i = 0; i < num; i++) {
390f2d4f7b0Sopenharmony_ci        if (strcmp(trustList[i].issueCA, signer->issuer) == 0) {
391f2d4f7b0Sopenharmony_ci            if (strcmp(trustList[i].profileSignCert, signer->subject) == 0 ||
392f2d4f7b0Sopenharmony_ci                strcmp(trustList[i].profileDebugSignCert, signer->subject) == 0) {
393f2d4f7b0Sopenharmony_ci                LOG_PRINT_STR("profile source name : %s", g_trustAppList[i].name);
394f2d4f7b0Sopenharmony_ci                return  &trustList[i];
395f2d4f7b0Sopenharmony_ci            }
396f2d4f7b0Sopenharmony_ci        }
397f2d4f7b0Sopenharmony_ci    }
398f2d4f7b0Sopenharmony_ci    return NULL;
399f2d4f7b0Sopenharmony_ci}
400f2d4f7b0Sopenharmony_ci
401f2d4f7b0Sopenharmony_cistatic int32_t GetProfileCertTypeBySignInfo(SignerResovledInfo *signer, int32_t *certType)
402f2d4f7b0Sopenharmony_ci{
403f2d4f7b0Sopenharmony_ci    /* only support first signer cert */
404f2d4f7b0Sopenharmony_ci    const TrustAppCert *trustCert = GetProfSourceBySigningCert(signer, g_trustAppList,
405f2d4f7b0Sopenharmony_ci                                                               sizeof(g_trustAppList) / sizeof(TrustAppCert));
406f2d4f7b0Sopenharmony_ci    if (g_isDebugMode && trustCert == NULL) {
407f2d4f7b0Sopenharmony_ci        trustCert = GetProfSourceBySigningCert(signer, g_trustAppListTest,
408f2d4f7b0Sopenharmony_ci                                               sizeof(g_trustAppListTest) / sizeof(TrustAppCert));
409f2d4f7b0Sopenharmony_ci    }
410f2d4f7b0Sopenharmony_ci    /* check level */
411f2d4f7b0Sopenharmony_ci    if (trustCert != NULL && trustCert->maxCertPath < signer->depth) {
412f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert maxdepth error: %d", signer->depth);
413f2d4f7b0Sopenharmony_ci        return V_ERR;
414f2d4f7b0Sopenharmony_ci    }
415f2d4f7b0Sopenharmony_ci    *certType = GetCertTypeBySourceName(trustCert);
416f2d4f7b0Sopenharmony_ci    return V_OK;
417f2d4f7b0Sopenharmony_ci}
418f2d4f7b0Sopenharmony_ci
419f2d4f7b0Sopenharmony_ci
420f2d4f7b0Sopenharmony_cistatic const TrustAppCert *GetAppSourceBySigningCert(const SignerResovledInfo *signer,
421f2d4f7b0Sopenharmony_ci                                                     const TrustAppCert* trustList, int32_t num)
422f2d4f7b0Sopenharmony_ci{
423f2d4f7b0Sopenharmony_ci    for (int32_t i = 0; i < num; i++) {
424f2d4f7b0Sopenharmony_ci        if (strcmp(trustList[i].appSignCert, signer->subject) == 0 &&
425f2d4f7b0Sopenharmony_ci            strcmp(trustList[i].issueCA, signer->issuer) == 0) {
426f2d4f7b0Sopenharmony_ci                return  &trustList[i];
427f2d4f7b0Sopenharmony_ci        }
428f2d4f7b0Sopenharmony_ci    }
429f2d4f7b0Sopenharmony_ci    return NULL;
430f2d4f7b0Sopenharmony_ci}
431f2d4f7b0Sopenharmony_ci
432f2d4f7b0Sopenharmony_cistatic int32_t GetAppCertTypeBySignInfo(SignerResovledInfo *signer, int32_t *certType)
433f2d4f7b0Sopenharmony_ci{
434f2d4f7b0Sopenharmony_ci    /* only support first signer cert */
435f2d4f7b0Sopenharmony_ci    const TrustAppCert *trustCert = GetAppSourceBySigningCert(signer, g_trustAppList,
436f2d4f7b0Sopenharmony_ci                                                              sizeof(g_trustAppList) / sizeof(TrustAppCert));
437f2d4f7b0Sopenharmony_ci    if (g_isDebugMode && trustCert == NULL) {
438f2d4f7b0Sopenharmony_ci        trustCert = GetAppSourceBySigningCert(signer, g_trustAppListTest,
439f2d4f7b0Sopenharmony_ci                                              sizeof(g_trustAppListTest) / sizeof(TrustAppCert));
440f2d4f7b0Sopenharmony_ci    }
441f2d4f7b0Sopenharmony_ci    /* check level */
442f2d4f7b0Sopenharmony_ci    if (trustCert != NULL && trustCert->maxCertPath < signer->depth) {
443f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert maxdepth error: %d %d", trustCert->maxCertPath, signer->depth);
444f2d4f7b0Sopenharmony_ci        return V_ERR;
445f2d4f7b0Sopenharmony_ci    }
446f2d4f7b0Sopenharmony_ci    *certType = GetCertTypeBySourceName(trustCert);
447f2d4f7b0Sopenharmony_ci    return V_OK;
448f2d4f7b0Sopenharmony_ci}
449f2d4f7b0Sopenharmony_ci
450f2d4f7b0Sopenharmony_ci/* get singer cert type by trust list */
451f2d4f7b0Sopenharmony_cistatic int32_t GetAppSingerCertType(Pkcs7 *pkcs7Handle, int32_t *certType)
452f2d4f7b0Sopenharmony_ci{
453f2d4f7b0Sopenharmony_ci    SignersResovedInfo *sri = PKCS7_GetAllSignersResolvedInfo(pkcs7Handle);
454f2d4f7b0Sopenharmony_ci    if (sri == NULL || sri->nrOfSigners == 0) {
455f2d4f7b0Sopenharmony_ci        PKCS7_FreeAllSignersResolvedInfo(sri);
456f2d4f7b0Sopenharmony_ci        LOG_ERROR("Get all signer's resolved info failed");
457f2d4f7b0Sopenharmony_ci        return V_ERR;
458f2d4f7b0Sopenharmony_ci    }
459f2d4f7b0Sopenharmony_ci    int32_t ret = GetAppCertTypeBySignInfo(&sri->signers[0], certType);
460f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
461f2d4f7b0Sopenharmony_ci        LOG_ERROR("get cert type by sign info failed: %d", ret);
462f2d4f7b0Sopenharmony_ci        PKCS7_FreeAllSignersResolvedInfo(sri);
463f2d4f7b0Sopenharmony_ci        return V_ERR;
464f2d4f7b0Sopenharmony_ci    }
465f2d4f7b0Sopenharmony_ci    PKCS7_FreeAllSignersResolvedInfo(sri);
466f2d4f7b0Sopenharmony_ci    return V_OK;
467f2d4f7b0Sopenharmony_ci}
468f2d4f7b0Sopenharmony_ci
469f2d4f7b0Sopenharmony_ci/* get singer cert type by trust list */
470f2d4f7b0Sopenharmony_cistatic int32_t GetProfileSingerCertType(Pkcs7 *pkcs7Handle, int32_t *certType)
471f2d4f7b0Sopenharmony_ci{
472f2d4f7b0Sopenharmony_ci    SignersResovedInfo *sri = PKCS7_GetAllSignersResolvedInfo(pkcs7Handle);
473f2d4f7b0Sopenharmony_ci    if (sri == NULL) {
474f2d4f7b0Sopenharmony_ci        LOG_ERROR("Get all signer's resolved info failed");
475f2d4f7b0Sopenharmony_ci        return V_ERR;
476f2d4f7b0Sopenharmony_ci    }
477f2d4f7b0Sopenharmony_ci    int32_t ret = GetProfileCertTypeBySignInfo(&sri->signers[0], certType);
478f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
479f2d4f7b0Sopenharmony_ci        LOG_ERROR("get cert type by sign info failed: %d", ret);
480f2d4f7b0Sopenharmony_ci        PKCS7_FreeAllSignersResolvedInfo(sri);
481f2d4f7b0Sopenharmony_ci        return V_ERR;
482f2d4f7b0Sopenharmony_ci    }
483f2d4f7b0Sopenharmony_ci    PKCS7_FreeAllSignersResolvedInfo(sri);
484f2d4f7b0Sopenharmony_ci    return V_OK;
485f2d4f7b0Sopenharmony_ci}
486f2d4f7b0Sopenharmony_ci
487f2d4f7b0Sopenharmony_ci/* verfiy profile data integrity with sign */
488f2d4f7b0Sopenharmony_cistatic int32_t VerifyProfileSignGetRaw(const char *buf, int32_t len, char **profileContent, int32_t *contentLen)
489f2d4f7b0Sopenharmony_ci{
490f2d4f7b0Sopenharmony_ci    /* verfiy */
491f2d4f7b0Sopenharmony_ci    char *profileData = NULL;
492f2d4f7b0Sopenharmony_ci    int32_t certType;
493f2d4f7b0Sopenharmony_ci    unsigned char *input = NULL;
494f2d4f7b0Sopenharmony_ci    size_t inputLen;
495f2d4f7b0Sopenharmony_ci    Pkcs7 *pkcs7 = APPV_MALLOC(sizeof(Pkcs7));
496f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_WTTH_LOG(pkcs7);
497f2d4f7b0Sopenharmony_ci
498f2d4f7b0Sopenharmony_ci    int32_t ret = PKCS7_ParseSignedData((unsigned char *)buf, (size_t)len, pkcs7);
499f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
500f2d4f7b0Sopenharmony_ci
501f2d4f7b0Sopenharmony_ci    LOG_INFO("pkcs7 parse message success");
502f2d4f7b0Sopenharmony_ci
503f2d4f7b0Sopenharmony_ci    /* verify sign, rawdata */
504f2d4f7b0Sopenharmony_ci    ret = PKCS7_VerifyCertsChain(pkcs7);
505f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
506f2d4f7b0Sopenharmony_ci
507f2d4f7b0Sopenharmony_ci    LOG_INFO("Verify certs success");
508f2d4f7b0Sopenharmony_ci
509f2d4f7b0Sopenharmony_ci    ret = GetProfileSingerCertType(pkcs7, &certType);
510f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
511f2d4f7b0Sopenharmony_ci
512f2d4f7b0Sopenharmony_ci    if (certType == CERT_TYPE_OTHER) {
513f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert type invalid");
514f2d4f7b0Sopenharmony_ci        ret = V_ERR;
515f2d4f7b0Sopenharmony_ci        goto EXIT;
516f2d4f7b0Sopenharmony_ci    }
517f2d4f7b0Sopenharmony_ci    ret = PKCS7_VerifySignerSignature(pkcs7, CalcDigest);
518f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
519f2d4f7b0Sopenharmony_ci    LOG_INFO("verify profile ok");
520f2d4f7b0Sopenharmony_ci
521f2d4f7b0Sopenharmony_ci    /* raw profile data: content */
522f2d4f7b0Sopenharmony_ci    ret = PKCS7_GetContentData(pkcs7, &input, &inputLen);
523f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
524f2d4f7b0Sopenharmony_ci
525f2d4f7b0Sopenharmony_ci    LOG_INFO("get profile sign content ok");
526f2d4f7b0Sopenharmony_ci
527f2d4f7b0Sopenharmony_ci    if (inputLen > MAX_PROFILE_SIZE || inputLen == 0) {
528f2d4f7b0Sopenharmony_ci        ret = V_ERR;
529f2d4f7b0Sopenharmony_ci        goto EXIT;
530f2d4f7b0Sopenharmony_ci    }
531f2d4f7b0Sopenharmony_ci    profileData = APPV_MALLOC(inputLen + 1);
532f2d4f7b0Sopenharmony_ci    P_NULL_GOTO_WTTH_LOG(profileData);
533f2d4f7b0Sopenharmony_ci
534f2d4f7b0Sopenharmony_ci    ret = memcpy_s(profileData, inputLen, input, inputLen);
535f2d4f7b0Sopenharmony_ci    profileData[inputLen] = '\0';
536f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
537f2d4f7b0Sopenharmony_ci
538f2d4f7b0Sopenharmony_ci    PKCS7_FreeRes(pkcs7);
539f2d4f7b0Sopenharmony_ci    APPV_FREE(pkcs7);
540f2d4f7b0Sopenharmony_ci    *profileContent = profileData;
541f2d4f7b0Sopenharmony_ci    *contentLen = (int)inputLen;
542f2d4f7b0Sopenharmony_ci    LOG_INFO("verify profile get raw data ok");
543f2d4f7b0Sopenharmony_ci    return V_OK;
544f2d4f7b0Sopenharmony_ciEXIT:
545f2d4f7b0Sopenharmony_ci    PKCS7_FreeRes(pkcs7);
546f2d4f7b0Sopenharmony_ci    APPV_FREE(pkcs7);
547f2d4f7b0Sopenharmony_ci    APPV_FREE(profileData);
548f2d4f7b0Sopenharmony_ci    return V_ERR;
549f2d4f7b0Sopenharmony_ci}
550f2d4f7b0Sopenharmony_cistatic unsigned char *GetRsaPk(const mbedtls_pk_context *pk, int32_t *len)
551f2d4f7b0Sopenharmony_ci{
552f2d4f7b0Sopenharmony_ci    unsigned char *buf = APPV_MALLOC(MAX_PK_BUF);
553f2d4f7b0Sopenharmony_ci    if (buf == NULL) {
554f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
555f2d4f7b0Sopenharmony_ci        return NULL;
556f2d4f7b0Sopenharmony_ci    }
557f2d4f7b0Sopenharmony_ci    int32_t ret = memset_s(buf, MAX_PK_BUF, 0, MAX_PK_BUF);
558f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
559f2d4f7b0Sopenharmony_ci        LOG_ERROR("memset error");
560f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
561f2d4f7b0Sopenharmony_ci        return NULL;
562f2d4f7b0Sopenharmony_ci    }
563f2d4f7b0Sopenharmony_ci    unsigned char *c = buf + MAX_PK_BUF;
564f2d4f7b0Sopenharmony_ci    int32_t pkLen = mbedtls_pk_write_pubkey(&c, buf, pk);
565f2d4f7b0Sopenharmony_ci    LOG_INFO("GetRsaPk pkLen %d", pkLen);
566f2d4f7b0Sopenharmony_ci    if (pkLen < 0 || pkLen > MAX_PK_BUF) {
567f2d4f7b0Sopenharmony_ci        LOG_ERROR("get pk buf error");
568f2d4f7b0Sopenharmony_ci        (void)memset_s(buf, MAX_PK_BUF, 0, MAX_PK_BUF);
569f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
570f2d4f7b0Sopenharmony_ci        return NULL;
571f2d4f7b0Sopenharmony_ci    }
572f2d4f7b0Sopenharmony_ci    unsigned char *pkBuf = APPV_MALLOC(pkLen);
573f2d4f7b0Sopenharmony_ci    if (pkBuf == NULL) {
574f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
575f2d4f7b0Sopenharmony_ci        (void)memset_s(buf, MAX_PK_BUF, 0, MAX_PK_BUF);
576f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
577f2d4f7b0Sopenharmony_ci        return NULL;
578f2d4f7b0Sopenharmony_ci    }
579f2d4f7b0Sopenharmony_ci    ret = memcpy_s(pkBuf, pkLen, c, pkLen);
580f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
581f2d4f7b0Sopenharmony_ci        LOG_ERROR("mem copy error: %d", ret);
582f2d4f7b0Sopenharmony_ci        (void)memset_s(buf, MAX_PK_BUF, 0, MAX_PK_BUF);
583f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
584f2d4f7b0Sopenharmony_ci        APPV_FREE(pkBuf);
585f2d4f7b0Sopenharmony_ci        return NULL;
586f2d4f7b0Sopenharmony_ci    }
587f2d4f7b0Sopenharmony_ci    *len = pkLen;
588f2d4f7b0Sopenharmony_ci    (void)memset_s(buf, MAX_PK_BUF, 0, MAX_PK_BUF);
589f2d4f7b0Sopenharmony_ci    APPV_FREE(buf);
590f2d4f7b0Sopenharmony_ci    return pkBuf;
591f2d4f7b0Sopenharmony_ci}
592f2d4f7b0Sopenharmony_ci
593f2d4f7b0Sopenharmony_cistatic unsigned char *GetEcPk(const mbedtls_pk_context *pk, int32_t *len)
594f2d4f7b0Sopenharmony_ci{
595f2d4f7b0Sopenharmony_ci    mbedtls_ecp_keypair *ecCtx = mbedtls_pk_ec(*pk);
596f2d4f7b0Sopenharmony_ci    if (ecCtx == NULL) {
597f2d4f7b0Sopenharmony_ci        LOG_ERROR("get ec pk error");
598f2d4f7b0Sopenharmony_ci        return NULL;
599f2d4f7b0Sopenharmony_ci    }
600f2d4f7b0Sopenharmony_ci    unsigned char *buf = APPV_MALLOC(MBEDTLS_ECP_MAX_PT_LEN);
601f2d4f7b0Sopenharmony_ci    if (buf == NULL) {
602f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
603f2d4f7b0Sopenharmony_ci        return NULL;
604f2d4f7b0Sopenharmony_ci    }
605f2d4f7b0Sopenharmony_ci    int32_t ret = memset_s(buf, MBEDTLS_ECP_MAX_PT_LEN, 0, MBEDTLS_ECP_MAX_PT_LEN);
606f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
607f2d4f7b0Sopenharmony_ci        LOG_ERROR("memset error");
608f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
609f2d4f7b0Sopenharmony_ci        return NULL;
610f2d4f7b0Sopenharmony_ci    }
611f2d4f7b0Sopenharmony_ci    ret = mbedtls_ecp_point_write_binary(&ecCtx->MBEDTLS_PRIVATE(grp), &ecCtx->MBEDTLS_PRIVATE(Q),
612f2d4f7b0Sopenharmony_ci        MBEDTLS_ECP_PF_UNCOMPRESSED, (size_t *)len, buf, MBEDTLS_ECP_MAX_PT_LEN);
613f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
614f2d4f7b0Sopenharmony_ci        LOG_ERROR("get ecc pk key error");
615f2d4f7b0Sopenharmony_ci        (void)memset_s(buf, MBEDTLS_ECP_MAX_PT_LEN, 0, MBEDTLS_ECP_MAX_PT_LEN);
616f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
617f2d4f7b0Sopenharmony_ci        return NULL;
618f2d4f7b0Sopenharmony_ci    }
619f2d4f7b0Sopenharmony_ci    LOG_INFO("GetEcPk *len %d", *len);
620f2d4f7b0Sopenharmony_ci    if (*len <= 0 || *len > MBEDTLS_ECP_MAX_PT_LEN) {
621f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
622f2d4f7b0Sopenharmony_ci        return NULL;
623f2d4f7b0Sopenharmony_ci    }
624f2d4f7b0Sopenharmony_ci    unsigned char *pkBuf = APPV_MALLOC(*len);
625f2d4f7b0Sopenharmony_ci    if (pkBuf == NULL) {
626f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
627f2d4f7b0Sopenharmony_ci        (void)memset_s(buf, MBEDTLS_ECP_MAX_PT_LEN, 0, MBEDTLS_ECP_MAX_PT_LEN);
628f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
629f2d4f7b0Sopenharmony_ci        return NULL;
630f2d4f7b0Sopenharmony_ci    }
631f2d4f7b0Sopenharmony_ci    ret = memcpy_s(pkBuf, *len, buf, *len);
632f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
633f2d4f7b0Sopenharmony_ci        LOG_ERROR("mem copy error: %d", ret);
634f2d4f7b0Sopenharmony_ci        (void)memset_s(buf, MBEDTLS_ECP_MAX_PT_LEN, 0, MBEDTLS_ECP_MAX_PT_LEN);
635f2d4f7b0Sopenharmony_ci        APPV_FREE(buf);
636f2d4f7b0Sopenharmony_ci        APPV_FREE(pkBuf);
637f2d4f7b0Sopenharmony_ci        return NULL;
638f2d4f7b0Sopenharmony_ci    }
639f2d4f7b0Sopenharmony_ci    APPV_FREE(buf);
640f2d4f7b0Sopenharmony_ci    return pkBuf;
641f2d4f7b0Sopenharmony_ci}
642f2d4f7b0Sopenharmony_ci
643f2d4f7b0Sopenharmony_cistatic unsigned char *GetPkBuf(const mbedtls_pk_context *pk, int32_t *len)
644f2d4f7b0Sopenharmony_ci{
645f2d4f7b0Sopenharmony_ci    unsigned char *bufA = NULL;
646f2d4f7b0Sopenharmony_ci    if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSA || mbedtls_pk_get_type(pk) == MBEDTLS_PK_RSASSA_PSS) {
647f2d4f7b0Sopenharmony_ci        bufA = GetRsaPk(pk, len);
648f2d4f7b0Sopenharmony_ci    } else if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECDSA || mbedtls_pk_get_type(pk) == MBEDTLS_PK_ECKEY) {
649f2d4f7b0Sopenharmony_ci        bufA = GetEcPk(pk, len);
650f2d4f7b0Sopenharmony_ci    }
651f2d4f7b0Sopenharmony_ci    return bufA;
652f2d4f7b0Sopenharmony_ci}
653f2d4f7b0Sopenharmony_ci
654f2d4f7b0Sopenharmony_cistatic int32_t ParseCertGetPk(const char *certEncoded, AppSignPk *pk)
655f2d4f7b0Sopenharmony_ci{
656f2d4f7b0Sopenharmony_ci    mbedtls_x509_crt *cert = APPV_MALLOC(sizeof(mbedtls_x509_crt));
657f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_WTTH_LOG(cert);
658f2d4f7b0Sopenharmony_ci
659f2d4f7b0Sopenharmony_ci    mbedtls_x509_crt_init(cert);
660f2d4f7b0Sopenharmony_ci    int32_t ret = mbedtls_x509_crt_parse(cert, (unsigned char *)certEncoded, strlen(certEncoded) + 1);
661f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
662f2d4f7b0Sopenharmony_ci        LOG_ERROR("load cert failed, ret: %d", ret);
663f2d4f7b0Sopenharmony_ci        APPV_FREE(cert);
664f2d4f7b0Sopenharmony_ci        return V_ERR;
665f2d4f7b0Sopenharmony_ci    }
666f2d4f7b0Sopenharmony_ci    int32_t len = 0;
667f2d4f7b0Sopenharmony_ci    unsigned char *pkBuf = GetPkBuf(&cert->pk, &len);
668f2d4f7b0Sopenharmony_ci    if (pkBuf == NULL) {
669f2d4f7b0Sopenharmony_ci        LOG_ERROR("get pk error");
670f2d4f7b0Sopenharmony_ci        mbedtls_x509_crt_free(cert);
671f2d4f7b0Sopenharmony_ci        APPV_FREE(cert);
672f2d4f7b0Sopenharmony_ci        return V_ERR;
673f2d4f7b0Sopenharmony_ci    }
674f2d4f7b0Sopenharmony_ci    pk->pk = (char *)pkBuf;
675f2d4f7b0Sopenharmony_ci    pk->len = len;
676f2d4f7b0Sopenharmony_ci    mbedtls_x509_crt_free(cert);
677f2d4f7b0Sopenharmony_ci    APPV_FREE(cert);
678f2d4f7b0Sopenharmony_ci    return V_OK;
679f2d4f7b0Sopenharmony_ci}
680f2d4f7b0Sopenharmony_ci
681f2d4f7b0Sopenharmony_cistatic int32_t GetAppSignPublicKey(const ProfileProf *profile, AppSignPk *pk)
682f2d4f7b0Sopenharmony_ci{
683f2d4f7b0Sopenharmony_ci    int32_t ret;
684f2d4f7b0Sopenharmony_ci    /* release cert */
685f2d4f7b0Sopenharmony_ci    if (profile->bundleInfo.releaseCert &&
686f2d4f7b0Sopenharmony_ci        strlen((char *)profile->bundleInfo.releaseCert) != 0) {
687f2d4f7b0Sopenharmony_ci        ret = ParseCertGetPk((char *)profile->bundleInfo.releaseCert, pk);
688f2d4f7b0Sopenharmony_ci    } else {
689f2d4f7b0Sopenharmony_ci        ret = ParseCertGetPk((char *)profile->bundleInfo.devCert, pk);
690f2d4f7b0Sopenharmony_ci    }
691f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
692f2d4f7b0Sopenharmony_ci        LOG_ERROR("GetSignCertpk failed, ret: %d", ret);
693f2d4f7b0Sopenharmony_ci        return V_ERR_GET_CERT_PK;
694f2d4f7b0Sopenharmony_ci    }
695f2d4f7b0Sopenharmony_ci    return V_OK;
696f2d4f7b0Sopenharmony_ci}
697f2d4f7b0Sopenharmony_ci
698f2d4f7b0Sopenharmony_cistatic void FreeAppSignPublicKey(AppSignPk *pk)
699f2d4f7b0Sopenharmony_ci{
700f2d4f7b0Sopenharmony_ci    if (pk->pk != NULL) {
701f2d4f7b0Sopenharmony_ci        APPV_FREE(pk->pk);
702f2d4f7b0Sopenharmony_ci    }
703f2d4f7b0Sopenharmony_ci    return;
704f2d4f7b0Sopenharmony_ci}
705f2d4f7b0Sopenharmony_ci
706f2d4f7b0Sopenharmony_ciint32_t GetAppid(ProfileProf *profile)
707f2d4f7b0Sopenharmony_ci{
708f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(profile, V_ERR);
709f2d4f7b0Sopenharmony_ci    AppSignPk pk = {0};
710f2d4f7b0Sopenharmony_ci    int32_t ret = GetAppSignPublicKey(profile, &pk);
711f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
712f2d4f7b0Sopenharmony_ci        LOG_ERROR("get sign pk failed");
713f2d4f7b0Sopenharmony_ci        return ret;
714f2d4f7b0Sopenharmony_ci    }
715f2d4f7b0Sopenharmony_ci    /* base64 */
716f2d4f7b0Sopenharmony_ci    size_t useLen = 0;
717f2d4f7b0Sopenharmony_ci    mbedtls_base64_encode(NULL, 0, &useLen, (unsigned char *)pk.pk, pk.len);
718f2d4f7b0Sopenharmony_ci    int32_t bundleNameLen = strlen(profile->bundleInfo.bundleName);
719f2d4f7b0Sopenharmony_ci    int32_t appidLen = bundleNameLen + useLen + 1 + 1;
720f2d4f7b0Sopenharmony_ci
721f2d4f7b0Sopenharmony_ci    LOG_INFO("GetAppid %d", appidLen);
722f2d4f7b0Sopenharmony_ci    if (useLen > MAX_KEY_PAIR_SIZE) {
723f2d4f7b0Sopenharmony_ci        return V_ERR;
724f2d4f7b0Sopenharmony_ci    }
725f2d4f7b0Sopenharmony_ci    char *appid = APPV_MALLOC(appidLen);
726f2d4f7b0Sopenharmony_ci    if (appid == NULL) {
727f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc failed");
728f2d4f7b0Sopenharmony_ci        FreeAppSignPublicKey(&pk);
729f2d4f7b0Sopenharmony_ci        return V_ERR_MALLOC;
730f2d4f7b0Sopenharmony_ci    }
731f2d4f7b0Sopenharmony_ci    appid[appidLen - 1] = '\0';
732f2d4f7b0Sopenharmony_ci    ret = snprintf_s(appid, appidLen, bundleNameLen + 1, "%s_", profile->bundleInfo.bundleName);
733f2d4f7b0Sopenharmony_ci    if (ret < 0) {
734f2d4f7b0Sopenharmony_ci        LOG_ERROR("snprintf error ret: %d", ret);
735f2d4f7b0Sopenharmony_ci        APPV_FREE(appid);
736f2d4f7b0Sopenharmony_ci        FreeAppSignPublicKey(&pk);
737f2d4f7b0Sopenharmony_ci        return V_ERR_GET_APPID;
738f2d4f7b0Sopenharmony_ci    }
739f2d4f7b0Sopenharmony_ci    ret = mbedtls_base64_encode((unsigned char *)appid + bundleNameLen + 1,
740f2d4f7b0Sopenharmony_ci        appidLen - bundleNameLen - 1, &useLen, (unsigned char *)pk.pk, pk.len);
741f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
742f2d4f7b0Sopenharmony_ci        LOG_ERROR("base 64 encode error");
743f2d4f7b0Sopenharmony_ci        APPV_FREE(appid);
744f2d4f7b0Sopenharmony_ci        FreeAppSignPublicKey(&pk);
745f2d4f7b0Sopenharmony_ci        return V_ERR_GET_APPID;
746f2d4f7b0Sopenharmony_ci    }
747f2d4f7b0Sopenharmony_ci    profile->appid = appid;
748f2d4f7b0Sopenharmony_ci    LOG_INFO("appid len: %d, bL len: %d, base64: %d", appidLen, bundleNameLen, (int)useLen);
749f2d4f7b0Sopenharmony_ci    LOG_PRINT_STR("%s", appid);
750f2d4f7b0Sopenharmony_ci    FreeAppSignPublicKey(&pk);
751f2d4f7b0Sopenharmony_ci    return V_OK;
752f2d4f7b0Sopenharmony_ci}
753f2d4f7b0Sopenharmony_ci
754f2d4f7b0Sopenharmony_cistatic int32_t VerifyProfGetContent(int32_t fp, const SignatureInfo *signInfo, int32_t certType, ProfileProf *pf)
755f2d4f7b0Sopenharmony_ci{
756f2d4f7b0Sopenharmony_ci    char *profBuf = NULL;
757f2d4f7b0Sopenharmony_ci    int32_t len = 0;
758f2d4f7b0Sopenharmony_ci    BlockHead blockHead = {0};
759f2d4f7b0Sopenharmony_ci    int32_t ret;
760f2d4f7b0Sopenharmony_ci    int32_t rawLen = 0;
761f2d4f7b0Sopenharmony_ci    char *rawBuf = GetSignBlockByType(signInfo, fp, PROFILE_BLOCK_WITHSIGN_TYPE, &rawLen, &blockHead);
762f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(rawBuf, V_ERR_GET_PROFILE_DATA);
763f2d4f7b0Sopenharmony_ci    LOG_INFO("certType %d", certType);
764f2d4f7b0Sopenharmony_ci    /* app gallary with no sign */
765f2d4f7b0Sopenharmony_ci    if (certType == CERT_TYPE_APPGALLARY) {
766f2d4f7b0Sopenharmony_ci        profBuf = rawBuf;
767f2d4f7b0Sopenharmony_ci        len = rawLen;
768f2d4f7b0Sopenharmony_ci    } else {
769f2d4f7b0Sopenharmony_ci        /* verify profile */
770f2d4f7b0Sopenharmony_ci        ret = VerifyProfileSignGetRaw(rawBuf, rawLen, &profBuf, &len);
771f2d4f7b0Sopenharmony_ci        APPV_FREE(rawBuf);
772f2d4f7b0Sopenharmony_ci        P_ERR_RETURN_WTTH_LOG(ret);
773f2d4f7b0Sopenharmony_ci    }
774f2d4f7b0Sopenharmony_ci
775f2d4f7b0Sopenharmony_ci    ret = ParseProfile(profBuf, len, pf);
776f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
777f2d4f7b0Sopenharmony_ci        LOG_ERROR("GetSignBlock error");
778f2d4f7b0Sopenharmony_ci        APPV_FREE(profBuf);
779f2d4f7b0Sopenharmony_ci        return V_ERR_GET_PARSE_PROFILE;
780f2d4f7b0Sopenharmony_ci    }
781f2d4f7b0Sopenharmony_ci    APPV_FREE(profBuf);
782f2d4f7b0Sopenharmony_ci
783f2d4f7b0Sopenharmony_ci    ret = VerifyProfileContent(pf);
784f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
785f2d4f7b0Sopenharmony_ci
786f2d4f7b0Sopenharmony_ci    ret = GetAppid(pf);
787f2d4f7b0Sopenharmony_ci    P_ERR_GOTO_WTTH_LOG(ret);
788f2d4f7b0Sopenharmony_ci
789f2d4f7b0Sopenharmony_ci    return V_OK;
790f2d4f7b0Sopenharmony_ciEXIT:
791f2d4f7b0Sopenharmony_ci    ProfFreeData(pf);
792f2d4f7b0Sopenharmony_ci    return ret;
793f2d4f7b0Sopenharmony_ci}
794f2d4f7b0Sopenharmony_ci
795f2d4f7b0Sopenharmony_cistatic int32_t CmpCert(const mbedtls_x509_crt *certA, const CertInfo *binSignCert)
796f2d4f7b0Sopenharmony_ci{
797f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(certA, V_ERR);
798f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(binSignCert, V_ERR);
799f2d4f7b0Sopenharmony_ci    /* cmp subject and issuer */
800f2d4f7b0Sopenharmony_ci    if (certA->subject_raw.len != binSignCert->subjectLen ||
801f2d4f7b0Sopenharmony_ci        memcmp(certA->subject_raw.p, binSignCert->subject, certA->subject_raw.len)) {
802f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert subject diff");
803f2d4f7b0Sopenharmony_ci        return V_ERR;
804f2d4f7b0Sopenharmony_ci    }
805f2d4f7b0Sopenharmony_ci
806f2d4f7b0Sopenharmony_ci    if (certA->issuer_raw.len != binSignCert->issuerLen ||
807f2d4f7b0Sopenharmony_ci        memcmp(certA->issuer_raw.p, binSignCert->issuer, certA->issuer_raw.len)) {
808f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert issuer diff");
809f2d4f7b0Sopenharmony_ci        return V_ERR;
810f2d4f7b0Sopenharmony_ci    }
811f2d4f7b0Sopenharmony_ci
812f2d4f7b0Sopenharmony_ci    /* V_OK means same */
813f2d4f7b0Sopenharmony_ci    if (mbedtls_pk_get_type(&certA->pk) != binSignCert->pkType) {
814f2d4f7b0Sopenharmony_ci        LOG_ERROR("pk type diff");
815f2d4f7b0Sopenharmony_ci        return V_ERR;
816f2d4f7b0Sopenharmony_ci    }
817f2d4f7b0Sopenharmony_ci    int32_t lenA = 0;
818f2d4f7b0Sopenharmony_ci    unsigned char *bufA = GetPkBuf(&certA->pk, &lenA);
819f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(bufA, V_ERR);
820f2d4f7b0Sopenharmony_ci
821f2d4f7b0Sopenharmony_ci    if (lenA != binSignCert->pkLen) {
822f2d4f7b0Sopenharmony_ci        LOG_ERROR("pkA len diff %d, %d", lenA, binSignCert->pkLen);
823f2d4f7b0Sopenharmony_ci        APPV_FREE(bufA);
824f2d4f7b0Sopenharmony_ci        return V_ERR;
825f2d4f7b0Sopenharmony_ci    }
826f2d4f7b0Sopenharmony_ci
827f2d4f7b0Sopenharmony_ci    if (memcmp(bufA, binSignCert->pkBuf, lenA)) {
828f2d4f7b0Sopenharmony_ci        LOG_ERROR("pk content different");
829f2d4f7b0Sopenharmony_ci        APPV_FREE(bufA);
830f2d4f7b0Sopenharmony_ci        return V_ERR;
831f2d4f7b0Sopenharmony_ci    }
832f2d4f7b0Sopenharmony_ci    APPV_FREE(bufA);
833f2d4f7b0Sopenharmony_ci    LOG_INFO("compare cert consistent");
834f2d4f7b0Sopenharmony_ci    return V_OK;
835f2d4f7b0Sopenharmony_ci}
836f2d4f7b0Sopenharmony_ci
837f2d4f7b0Sopenharmony_ciint32_t LoadCertAndCmpDest(const unsigned char *certBase64, const CertInfo *binSignCert)
838f2d4f7b0Sopenharmony_ci{
839f2d4f7b0Sopenharmony_ci    if (certBase64 == NULL || binSignCert == NULL) {
840f2d4f7b0Sopenharmony_ci        return V_ERR;
841f2d4f7b0Sopenharmony_ci    }
842f2d4f7b0Sopenharmony_ci    mbedtls_x509_crt cert;
843f2d4f7b0Sopenharmony_ci    mbedtls_x509_crt_init(&cert);
844f2d4f7b0Sopenharmony_ci    int32_t ret = mbedtls_x509_crt_parse(&cert, certBase64, strlen((char *)certBase64) + 1);
845f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
846f2d4f7b0Sopenharmony_ci        LOG_ERROR("load release cert failed");
847f2d4f7b0Sopenharmony_ci        LOG_PRINT_STR("%s", certBase64);
848f2d4f7b0Sopenharmony_ci        return V_ERR;
849f2d4f7b0Sopenharmony_ci    }
850f2d4f7b0Sopenharmony_ci    /* cmp cert */
851f2d4f7b0Sopenharmony_ci    if (CmpCert(&cert, binSignCert) == V_OK) {
852f2d4f7b0Sopenharmony_ci        LOG_INFO("cert consistent");
853f2d4f7b0Sopenharmony_ci        mbedtls_x509_crt_free(&cert);
854f2d4f7b0Sopenharmony_ci        return V_OK;
855f2d4f7b0Sopenharmony_ci    }
856f2d4f7b0Sopenharmony_ci    LOG_ERROR("cert inconsistent");
857f2d4f7b0Sopenharmony_ci    mbedtls_x509_crt_free(&cert);
858f2d4f7b0Sopenharmony_ci    return V_ERR;
859f2d4f7b0Sopenharmony_ci}
860f2d4f7b0Sopenharmony_ci
861f2d4f7b0Sopenharmony_cistatic int32_t CheckReleaseAppSign(const CertInfo *binSignCert, const ProfileProf *pf)
862f2d4f7b0Sopenharmony_ci{
863f2d4f7b0Sopenharmony_ci    /* if distribution type is app_gallery, return error */
864f2d4f7b0Sopenharmony_ci    if (strcmp(pf->appDistType, "app_gallery") == 0) {
865f2d4f7b0Sopenharmony_ci        LOG_ERROR("app release, distribution type is app_gallery, return error");
866f2d4f7b0Sopenharmony_ci        return V_ERR;
867f2d4f7b0Sopenharmony_ci    }
868f2d4f7b0Sopenharmony_ci
869f2d4f7b0Sopenharmony_ci    if (strlen((char *)pf->bundleInfo.releaseCert) == 0) {
870f2d4f7b0Sopenharmony_ci        LOG_ERROR("release app, release Cert null");
871f2d4f7b0Sopenharmony_ci        return V_ERR;
872f2d4f7b0Sopenharmony_ci    }
873f2d4f7b0Sopenharmony_ci    int32_t ret = LoadCertAndCmpDest(pf->bundleInfo.releaseCert, binSignCert);
874f2d4f7b0Sopenharmony_ci    if (ret == V_OK) {
875f2d4f7b0Sopenharmony_ci        LOG_INFO("dev cert consistent");
876f2d4f7b0Sopenharmony_ci        return V_OK;
877f2d4f7b0Sopenharmony_ci    }
878f2d4f7b0Sopenharmony_ci    LOG_ERROR("app sign cert not consistent with profile cert");
879f2d4f7b0Sopenharmony_ci    return V_ERR;
880f2d4f7b0Sopenharmony_ci}
881f2d4f7b0Sopenharmony_ci
882f2d4f7b0Sopenharmony_cistatic int32_t CheckDebugAppSign(CertInfo *binSignCert, const ProfileProf *pf)
883f2d4f7b0Sopenharmony_ci{
884f2d4f7b0Sopenharmony_ci    if (strlen((char *)pf->bundleInfo.devCert) == 0) {
885f2d4f7b0Sopenharmony_ci        LOG_ERROR("debug app, devCert null");
886f2d4f7b0Sopenharmony_ci        return V_ERR;
887f2d4f7b0Sopenharmony_ci    }
888f2d4f7b0Sopenharmony_ci    int32_t ret = LoadCertAndCmpDest(pf->bundleInfo.devCert, binSignCert);
889f2d4f7b0Sopenharmony_ci    if (ret == V_OK) {
890f2d4f7b0Sopenharmony_ci        LOG_INFO("dev cert consistent");
891f2d4f7b0Sopenharmony_ci        return V_OK;
892f2d4f7b0Sopenharmony_ci    }
893f2d4f7b0Sopenharmony_ci    if (strlen((char *)pf->bundleInfo.releaseCert) != 0) {
894f2d4f7b0Sopenharmony_ci        ret = LoadCertAndCmpDest(pf->bundleInfo.releaseCert, binSignCert);
895f2d4f7b0Sopenharmony_ci        if (ret == V_OK) {
896f2d4f7b0Sopenharmony_ci            LOG_INFO("release cert consistent");
897f2d4f7b0Sopenharmony_ci            return V_OK;
898f2d4f7b0Sopenharmony_ci        }
899f2d4f7b0Sopenharmony_ci    }
900f2d4f7b0Sopenharmony_ci    LOG_ERROR("app sign cert not consistent with profile cert");
901f2d4f7b0Sopenharmony_ci    return V_ERR;
902f2d4f7b0Sopenharmony_ci}
903f2d4f7b0Sopenharmony_ci
904f2d4f7b0Sopenharmony_cistatic int32_t CheckAppSignCertWithProfile(int32_t appCertType, CertInfo *binSignCert, ProfileProf *pf)
905f2d4f7b0Sopenharmony_ci{
906f2d4f7b0Sopenharmony_ci    /* cert type appgallary or system, not check */
907f2d4f7b0Sopenharmony_ci    if (appCertType == CERT_TYPE_APPGALLARY || appCertType == CERT_TYPE_SYETEM) {
908f2d4f7b0Sopenharmony_ci        LOG_INFO("app type : %d, return OK", appCertType);
909f2d4f7b0Sopenharmony_ci        return V_OK;
910f2d4f7b0Sopenharmony_ci    }
911f2d4f7b0Sopenharmony_ci
912f2d4f7b0Sopenharmony_ci    int32_t ret = V_ERR;
913f2d4f7b0Sopenharmony_ci    /* debug app, app cert consistent with profile dev or release cert */
914f2d4f7b0Sopenharmony_ci    if (strcmp(DEBUG_TYPE, (char *)pf->type) == 0) {
915f2d4f7b0Sopenharmony_ci        ret = CheckDebugAppSign(binSignCert, pf);
916f2d4f7b0Sopenharmony_ci    } else if (strcmp(RELEASE_TYPE, pf->type) == 0) {
917f2d4f7b0Sopenharmony_ci        ret = CheckReleaseAppSign(binSignCert, pf);
918f2d4f7b0Sopenharmony_ci    }
919f2d4f7b0Sopenharmony_ci
920f2d4f7b0Sopenharmony_ci    LOG_INFO("check app sign cert ret : %d", ret);
921f2d4f7b0Sopenharmony_ci    return ret;
922f2d4f7b0Sopenharmony_ci}
923f2d4f7b0Sopenharmony_ci
924f2d4f7b0Sopenharmony_cistatic int32_t CertInfoInit(CertInfo *certInfo)
925f2d4f7b0Sopenharmony_ci{
926f2d4f7b0Sopenharmony_ci    int32_t ret = memset_s(certInfo, sizeof(CertInfo), 0, sizeof(CertInfo));
927f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
928f2d4f7b0Sopenharmony_ci        LOG_ERROR("memset error");
929f2d4f7b0Sopenharmony_ci    }
930f2d4f7b0Sopenharmony_ci    return ret;
931f2d4f7b0Sopenharmony_ci}
932f2d4f7b0Sopenharmony_ci
933f2d4f7b0Sopenharmony_civoid FreeCertInfo(CertInfo *certInfo)
934f2d4f7b0Sopenharmony_ci{
935f2d4f7b0Sopenharmony_ci    if (certInfo == NULL) {
936f2d4f7b0Sopenharmony_ci        return;
937f2d4f7b0Sopenharmony_ci    }
938f2d4f7b0Sopenharmony_ci    if (certInfo->issuer != NULL) {
939f2d4f7b0Sopenharmony_ci        APPV_FREE(certInfo->issuer);
940f2d4f7b0Sopenharmony_ci        certInfo->issuerLen = 0;
941f2d4f7b0Sopenharmony_ci    }
942f2d4f7b0Sopenharmony_ci
943f2d4f7b0Sopenharmony_ci    if (certInfo->subject != NULL) {
944f2d4f7b0Sopenharmony_ci        APPV_FREE(certInfo->subject);
945f2d4f7b0Sopenharmony_ci        certInfo->subjectLen = 0;
946f2d4f7b0Sopenharmony_ci    }
947f2d4f7b0Sopenharmony_ci
948f2d4f7b0Sopenharmony_ci    if (certInfo->pkBuf != NULL) {
949f2d4f7b0Sopenharmony_ci        APPV_FREE(certInfo->pkBuf);
950f2d4f7b0Sopenharmony_ci        certInfo->pkLen = 0;
951f2d4f7b0Sopenharmony_ci    }
952f2d4f7b0Sopenharmony_ci    return;
953f2d4f7b0Sopenharmony_ci}
954f2d4f7b0Sopenharmony_ci
955f2d4f7b0Sopenharmony_cistatic int32_t GetCertInfo(const mbedtls_x509_crt *ctr, CertInfo **binSignCert)
956f2d4f7b0Sopenharmony_ci{
957f2d4f7b0Sopenharmony_ci    CertInfo *certInfo = APPV_MALLOC(sizeof(CertInfo));
958f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(certInfo, V_ERR_MALLOC);
959f2d4f7b0Sopenharmony_ci
960f2d4f7b0Sopenharmony_ci    int32_t ret = CertInfoInit(certInfo);
961f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
962f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert info init");
963f2d4f7b0Sopenharmony_ci        ret = V_ERR_MEMSET;
964f2d4f7b0Sopenharmony_ci        goto EXIT;
965f2d4f7b0Sopenharmony_ci    }
966f2d4f7b0Sopenharmony_ci    certInfo->issuerLen = ctr->issuer_raw.len;
967f2d4f7b0Sopenharmony_ci    certInfo->subjectLen = ctr->subject_raw.len;
968f2d4f7b0Sopenharmony_ci    if (certInfo->issuerLen == 0 || certInfo->issuerLen > MAX_PROFILE_SIZE ||
969f2d4f7b0Sopenharmony_ci        certInfo->subjectLen == 0 || certInfo->subjectLen > MAX_PROFILE_SIZE) {
970f2d4f7b0Sopenharmony_ci        ret = V_ERR_MALLOC;
971f2d4f7b0Sopenharmony_ci        goto EXIT;
972f2d4f7b0Sopenharmony_ci    }
973f2d4f7b0Sopenharmony_ci    certInfo->issuer = APPV_MALLOC(certInfo->issuerLen + 1);
974f2d4f7b0Sopenharmony_ci    if (certInfo->issuer == NULL) {
975f2d4f7b0Sopenharmony_ci        ret = V_ERR_MALLOC;
976f2d4f7b0Sopenharmony_ci        goto EXIT;
977f2d4f7b0Sopenharmony_ci    }
978f2d4f7b0Sopenharmony_ci    certInfo->issuer[certInfo->issuerLen] = '\0';
979f2d4f7b0Sopenharmony_ci    ret = memcpy_s(certInfo->issuer, certInfo->issuerLen, ctr->issuer_raw.p, ctr->issuer_raw.len);
980f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
981f2d4f7b0Sopenharmony_ci        ret = V_ERR_MEMCPY;
982f2d4f7b0Sopenharmony_ci        goto EXIT;
983f2d4f7b0Sopenharmony_ci    }
984f2d4f7b0Sopenharmony_ci    certInfo->subject = APPV_MALLOC(certInfo->subjectLen + 1);
985f2d4f7b0Sopenharmony_ci    if (certInfo->subject == NULL) {
986f2d4f7b0Sopenharmony_ci        ret = V_ERR_MALLOC;
987f2d4f7b0Sopenharmony_ci        goto EXIT;
988f2d4f7b0Sopenharmony_ci    }
989f2d4f7b0Sopenharmony_ci    certInfo->subject[certInfo->subjectLen] = '\0';
990f2d4f7b0Sopenharmony_ci    ret = memcpy_s(certInfo->subject, certInfo->subjectLen, ctr->subject_raw.p, ctr->subject_raw.len);
991f2d4f7b0Sopenharmony_ci    if (ret != EOK) {
992f2d4f7b0Sopenharmony_ci        ret = V_ERR_MEMCPY;
993f2d4f7b0Sopenharmony_ci        goto EXIT;
994f2d4f7b0Sopenharmony_ci    }
995f2d4f7b0Sopenharmony_ci    certInfo->pkType = mbedtls_pk_get_type(&ctr->pk);
996f2d4f7b0Sopenharmony_ci    certInfo->pkBuf = (char *)GetPkBuf(&ctr->pk, &certInfo->pkLen);
997f2d4f7b0Sopenharmony_ci    if (certInfo->pkBuf == NULL) {
998f2d4f7b0Sopenharmony_ci        LOG_ERROR("get pk error");
999f2d4f7b0Sopenharmony_ci        ret = V_ERR;
1000f2d4f7b0Sopenharmony_ci        goto EXIT;
1001f2d4f7b0Sopenharmony_ci    }
1002f2d4f7b0Sopenharmony_ci    *binSignCert = certInfo;
1003f2d4f7b0Sopenharmony_ci    return V_OK;
1004f2d4f7b0Sopenharmony_ciEXIT:
1005f2d4f7b0Sopenharmony_ci    FreeCertInfo(certInfo);
1006f2d4f7b0Sopenharmony_ci    APPV_FREE(certInfo);
1007f2d4f7b0Sopenharmony_ci    return ret;
1008f2d4f7b0Sopenharmony_ci}
1009f2d4f7b0Sopenharmony_ci
1010f2d4f7b0Sopenharmony_cistatic int32_t VerfiyAppSourceGetProfile(int32_t fp, const SignatureInfo *signInfo,
1011f2d4f7b0Sopenharmony_ci    int32_t certType, CertInfo *binSignCert, ProfileProf *pf)
1012f2d4f7b0Sopenharmony_ci{
1013f2d4f7b0Sopenharmony_ci    int32_t ret = VerifyProfGetContent(fp, signInfo, certType, pf);
1014f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1015f2d4f7b0Sopenharmony_ci        LOG_ERROR("VerifyProfGetContent error: %d", ret);
1016f2d4f7b0Sopenharmony_ci        return ret;
1017f2d4f7b0Sopenharmony_ci    }
1018f2d4f7b0Sopenharmony_ci    LOG_INFO("verify prof get content success");
1019f2d4f7b0Sopenharmony_ci
1020f2d4f7b0Sopenharmony_ci    /* verfiy profile cert and app sign cert */
1021f2d4f7b0Sopenharmony_ci    ret = CheckAppSignCertWithProfile(certType, binSignCert, pf);
1022f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1023f2d4f7b0Sopenharmony_ci        LOG_ERROR("CheckAppSignCertWithProfile error: %d", ret);
1024f2d4f7b0Sopenharmony_ci        ProfFreeData(pf);
1025f2d4f7b0Sopenharmony_ci        return V_ERR_VERFIY_PROF_CERT;
1026f2d4f7b0Sopenharmony_ci    }
1027f2d4f7b0Sopenharmony_ci
1028f2d4f7b0Sopenharmony_ci    /* free cert */
1029f2d4f7b0Sopenharmony_ci    FREE_IF_NOT_NULL(pf->bundleInfo.devCert);
1030f2d4f7b0Sopenharmony_ci    FREE_IF_NOT_NULL(pf->bundleInfo.releaseCert);
1031f2d4f7b0Sopenharmony_ci
1032f2d4f7b0Sopenharmony_ci    LOG_INFO("verfiy app source success");
1033f2d4f7b0Sopenharmony_ci    return V_OK;
1034f2d4f7b0Sopenharmony_ci}
1035f2d4f7b0Sopenharmony_ci
1036f2d4f7b0Sopenharmony_cistatic int32_t VerifyAppSignPkcsData(const FileRead *fileRead, const SignatureInfo *signInfo, const Pkcs7 *pkcs7Handle)
1037f2d4f7b0Sopenharmony_ci{
1038f2d4f7b0Sopenharmony_ci    /*  verify sign, rawdata */
1039f2d4f7b0Sopenharmony_ci    int32_t ret = PKCS7_VerifyCertsChain(pkcs7Handle);
1040f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1041f2d4f7b0Sopenharmony_ci        LOG_ERROR("Verify certs failed, ret: %d", ret);
1042f2d4f7b0Sopenharmony_ci        return V_ERR_VERIFY_CERT_CHAIN;
1043f2d4f7b0Sopenharmony_ci    }
1044f2d4f7b0Sopenharmony_ci    LOG_INFO("Verify certs success");
1045f2d4f7b0Sopenharmony_ci
1046f2d4f7b0Sopenharmony_ci    ret = VerifyRawHash(signInfo, fileRead, pkcs7Handle);
1047f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1048f2d4f7b0Sopenharmony_ci        LOG_ERROR("VerifyRawHash failed : %d", ret);
1049f2d4f7b0Sopenharmony_ci        return ret;
1050f2d4f7b0Sopenharmony_ci    }
1051f2d4f7b0Sopenharmony_ci    LOG_INFO("VerifyRawHash success");
1052f2d4f7b0Sopenharmony_ci
1053f2d4f7b0Sopenharmony_ci    ret = PKCS7_VerifySignerSignature(pkcs7Handle, CalcDigest);
1054f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1055f2d4f7b0Sopenharmony_ci        LOG_ERROR("pkcs7 verify signer signature failed : %d", ret);
1056f2d4f7b0Sopenharmony_ci        return V_ERR_VERIFY_SIGNATURE;
1057f2d4f7b0Sopenharmony_ci    }
1058f2d4f7b0Sopenharmony_ci
1059f2d4f7b0Sopenharmony_ci    return V_OK;
1060f2d4f7b0Sopenharmony_ci}
1061f2d4f7b0Sopenharmony_ci
1062f2d4f7b0Sopenharmony_cistatic Pkcs7 *GetBinSignPkcs(const char *signBuf, int32_t len)
1063f2d4f7b0Sopenharmony_ci{
1064f2d4f7b0Sopenharmony_ci    Pkcs7 *pkcs7 = APPV_MALLOC(sizeof(Pkcs7));
1065f2d4f7b0Sopenharmony_ci    if (pkcs7 == NULL) {
1066f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
1067f2d4f7b0Sopenharmony_ci        return NULL;
1068f2d4f7b0Sopenharmony_ci    }
1069f2d4f7b0Sopenharmony_ci    int32_t ret = PKCS7_ParseSignedData((unsigned char *)signBuf, (size_t)len, pkcs7);
1070f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1071f2d4f7b0Sopenharmony_ci        LOG_ERROR("pkcs7parse message failed, ret: %d", ret);
1072f2d4f7b0Sopenharmony_ci        PKCS7_FreeRes(pkcs7);
1073f2d4f7b0Sopenharmony_ci        APPV_FREE(pkcs7);
1074f2d4f7b0Sopenharmony_ci        return NULL;
1075f2d4f7b0Sopenharmony_ci    }
1076f2d4f7b0Sopenharmony_ci    return pkcs7;
1077f2d4f7b0Sopenharmony_ci}
1078f2d4f7b0Sopenharmony_ci
1079f2d4f7b0Sopenharmony_cistatic FileRead *GetFileRead(int32_t fp, int32_t offset, int32_t size)
1080f2d4f7b0Sopenharmony_ci{
1081f2d4f7b0Sopenharmony_ci    /* raw buf len = sign block head offset */
1082f2d4f7b0Sopenharmony_ci    FileRead *fileRead = APPV_MALLOC(sizeof(FileRead));
1083f2d4f7b0Sopenharmony_ci    if (fileRead == NULL) {
1084f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
1085f2d4f7b0Sopenharmony_ci        return NULL;
1086f2d4f7b0Sopenharmony_ci    }
1087f2d4f7b0Sopenharmony_ci    fileRead->fp = fp;
1088f2d4f7b0Sopenharmony_ci    fileRead->offset = offset;
1089f2d4f7b0Sopenharmony_ci    fileRead->len = size;
1090f2d4f7b0Sopenharmony_ci    return fileRead;
1091f2d4f7b0Sopenharmony_ci}
1092f2d4f7b0Sopenharmony_cistatic int32_t VerifyBinSign(SignatureInfo *signInfo, int32_t fp, CertInfo **signCert, int32_t *certType)
1093f2d4f7b0Sopenharmony_ci{
1094f2d4f7b0Sopenharmony_ci    int32_t blockLen;
1095f2d4f7b0Sopenharmony_ci    BlockHead blockHead = {0};
1096f2d4f7b0Sopenharmony_ci    FileRead *fileRead = NULL;
1097f2d4f7b0Sopenharmony_ci    int32_t ret;
1098f2d4f7b0Sopenharmony_ci
1099f2d4f7b0Sopenharmony_ci    char *signBuf = GetSignBlockByType(signInfo, fp, SIGNATURE_BLOCK_TYPE, &blockLen, &blockHead);
1100f2d4f7b0Sopenharmony_ci    P_NULL_RETURN_RET_WTTH_LOG(signBuf, V_ERR_GET_SIGN_BLOCK);
1101f2d4f7b0Sopenharmony_ci
1102f2d4f7b0Sopenharmony_ci    Pkcs7 *pkcs7 = GetBinSignPkcs(signBuf, (size_t)blockLen);
1103f2d4f7b0Sopenharmony_ci    if (pkcs7 == NULL) {
1104f2d4f7b0Sopenharmony_ci        LOG_ERROR("GetBinSignPkcs failed");
1105f2d4f7b0Sopenharmony_ci        APPV_FREE(signBuf);
1106f2d4f7b0Sopenharmony_ci        return V_ERR_PARSE_PKC7_DATA;
1107f2d4f7b0Sopenharmony_ci    }
1108f2d4f7b0Sopenharmony_ci    /* pkcs7 handle the content of signBuf, do not free signBuf */
1109f2d4f7b0Sopenharmony_ci    LOG_INFO("pkcs7 parse message success");
1110f2d4f7b0Sopenharmony_ci
1111f2d4f7b0Sopenharmony_ci    /* raw buf len = sign block head offset */
1112f2d4f7b0Sopenharmony_ci    fileRead = GetFileRead(fp, 0, blockHead.offset);
1113f2d4f7b0Sopenharmony_ci    if (fileRead == NULL) {
1114f2d4f7b0Sopenharmony_ci        LOG_ERROR("malloc error");
1115f2d4f7b0Sopenharmony_ci        ret = V_ERR_MALLOC;
1116f2d4f7b0Sopenharmony_ci        goto EXIT;
1117f2d4f7b0Sopenharmony_ci    }
1118f2d4f7b0Sopenharmony_ci    ret = GetAppSingerCertType(pkcs7, certType);
1119f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1120f2d4f7b0Sopenharmony_ci        LOG_ERROR("cert source invalid: %d", ret);
1121f2d4f7b0Sopenharmony_ci        ret = V_ERR_GET_CERT_TYPE;
1122f2d4f7b0Sopenharmony_ci        goto EXIT;
1123f2d4f7b0Sopenharmony_ci    }
1124f2d4f7b0Sopenharmony_ci    LOG_INFO("get cert Type : %d", *certType);
1125f2d4f7b0Sopenharmony_ci    signInfo->certType = *certType;
1126f2d4f7b0Sopenharmony_ci    ret = VerifyAppSignPkcsData(fileRead, signInfo, pkcs7);
1127f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1128f2d4f7b0Sopenharmony_ci        LOG_ERROR("intergrity failed");
1129f2d4f7b0Sopenharmony_ci        ret = V_ERR_VERIFY_CERT_CHAIN;
1130f2d4f7b0Sopenharmony_ci        goto EXIT;
1131f2d4f7b0Sopenharmony_ci    }
1132f2d4f7b0Sopenharmony_ci    LOG_INFO("pkcs7 verify signer signature success");
1133f2d4f7b0Sopenharmony_ci
1134f2d4f7b0Sopenharmony_ci    ret = GetCertInfo(pkcs7->signedData.signers.certPath.crt, signCert);
1135f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1136f2d4f7b0Sopenharmony_ci        LOG_ERROR("get bin cert info  error: %d", ret);
1137f2d4f7b0Sopenharmony_ci        ret = V_ERR_GET_CERT_INFO;
1138f2d4f7b0Sopenharmony_ci        goto EXIT;
1139f2d4f7b0Sopenharmony_ci    }
1140f2d4f7b0Sopenharmony_ci
1141f2d4f7b0Sopenharmony_ciEXIT:
1142f2d4f7b0Sopenharmony_ci    /* free sign */
1143f2d4f7b0Sopenharmony_ci    APPV_FREE(signBuf);
1144f2d4f7b0Sopenharmony_ci    /* free pkcs7Handle */
1145f2d4f7b0Sopenharmony_ci    PKCS7_FreeRes(pkcs7);
1146f2d4f7b0Sopenharmony_ci    APPV_FREE(pkcs7);
1147f2d4f7b0Sopenharmony_ci    APPV_FREE(fileRead);
1148f2d4f7b0Sopenharmony_ci    return ret;
1149f2d4f7b0Sopenharmony_ci}
1150f2d4f7b0Sopenharmony_ci
1151f2d4f7b0Sopenharmony_cistatic int32_t VerifyIntegrity(SignatureInfo *signInfo, int32_t fp, ProfileProf *pf)
1152f2d4f7b0Sopenharmony_ci{
1153f2d4f7b0Sopenharmony_ci    CertInfo *binSignCert = NULL;
1154f2d4f7b0Sopenharmony_ci    int32_t certType = 0;
1155f2d4f7b0Sopenharmony_ci
1156f2d4f7b0Sopenharmony_ci    int32_t ret = VerifyBinSign(signInfo, fp, &binSignCert, &certType);
1157f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1158f2d4f7b0Sopenharmony_ci        LOG_ERROR("verify bin sign error");
1159f2d4f7b0Sopenharmony_ci        return ret;
1160f2d4f7b0Sopenharmony_ci    }
1161f2d4f7b0Sopenharmony_ci
1162f2d4f7b0Sopenharmony_ci    ret = VerfiyAppSourceGetProfile(fp, signInfo, certType, binSignCert, pf);
1163f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1164f2d4f7b0Sopenharmony_ci        LOG_ERROR("verify app source failed : %d", ret);
1165f2d4f7b0Sopenharmony_ci        FreeCertInfo(binSignCert);
1166f2d4f7b0Sopenharmony_ci        APPV_FREE(binSignCert);
1167f2d4f7b0Sopenharmony_ci        return ret;
1168f2d4f7b0Sopenharmony_ci    }
1169f2d4f7b0Sopenharmony_ci    FreeCertInfo(binSignCert);
1170f2d4f7b0Sopenharmony_ci    APPV_FREE(binSignCert);
1171f2d4f7b0Sopenharmony_ci    return V_OK;
1172f2d4f7b0Sopenharmony_ci}
1173f2d4f7b0Sopenharmony_ci
1174f2d4f7b0Sopenharmony_ciint32_t APPVERI_AppVerify(const char *filePath, VerifyResult *verifyRst)
1175f2d4f7b0Sopenharmony_ci{
1176f2d4f7b0Sopenharmony_ci    if (filePath == NULL || verifyRst == NULL) {
1177f2d4f7b0Sopenharmony_ci        return V_ERR_FILE_OPEN;
1178f2d4f7b0Sopenharmony_ci    }
1179f2d4f7b0Sopenharmony_ci    int32_t handle = 0;
1180f2d4f7b0Sopenharmony_ci    FileRead file = {0};
1181f2d4f7b0Sopenharmony_ci    if (InitVerify(&file, filePath, &handle) != V_OK) {
1182f2d4f7b0Sopenharmony_ci        close(handle);
1183f2d4f7b0Sopenharmony_ci        return V_ERR_FILE_OPEN;
1184f2d4f7b0Sopenharmony_ci    }
1185f2d4f7b0Sopenharmony_ci    SignatureInfo signInfo = {0};
1186f2d4f7b0Sopenharmony_ci    int32_t ret = GetSignHead(&file, &signInfo);
1187f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1188f2d4f7b0Sopenharmony_ci        LOG_ERROR("get sign head error");
1189f2d4f7b0Sopenharmony_ci        close(handle);
1190f2d4f7b0Sopenharmony_ci        return ret;
1191f2d4f7b0Sopenharmony_ci    }
1192f2d4f7b0Sopenharmony_ci    HwSignHead *signHead = signInfo.signHead;
1193f2d4f7b0Sopenharmony_ci    ret = VerifyIntegrity(&signInfo, handle, &verifyRst->profile);
1194f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1195f2d4f7b0Sopenharmony_ci        LOG_ERROR("verify integrity failed");
1196f2d4f7b0Sopenharmony_ci        close(handle);
1197f2d4f7b0Sopenharmony_ci        APPV_FREE(signHead);
1198f2d4f7b0Sopenharmony_ci        return ret;
1199f2d4f7b0Sopenharmony_ci    }
1200f2d4f7b0Sopenharmony_ci    struct stat *fileSt = APPV_MALLOC(sizeof(struct stat));
1201f2d4f7b0Sopenharmony_ci    if (fileSt == NULL) {
1202f2d4f7b0Sopenharmony_ci        LOG_PRINT_STR("malloc error");
1203f2d4f7b0Sopenharmony_ci        close(handle);
1204f2d4f7b0Sopenharmony_ci        APPV_FREE(signHead);
1205f2d4f7b0Sopenharmony_ci        ProfFreeData(&verifyRst->profile);
1206f2d4f7b0Sopenharmony_ci        return V_ERR_MALLOC;
1207f2d4f7b0Sopenharmony_ci    }
1208f2d4f7b0Sopenharmony_ci    ret = fstat(handle, fileSt);
1209f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1210f2d4f7b0Sopenharmony_ci        LOG_ERROR("fstat error");
1211f2d4f7b0Sopenharmony_ci        close(handle);
1212f2d4f7b0Sopenharmony_ci        APPV_FREE(signHead);
1213f2d4f7b0Sopenharmony_ci        ProfFreeData(&verifyRst->profile);
1214f2d4f7b0Sopenharmony_ci        APPV_FREE(fileSt);
1215f2d4f7b0Sopenharmony_ci        return V_ERR_FILE_STAT;
1216f2d4f7b0Sopenharmony_ci    }
1217f2d4f7b0Sopenharmony_ci    LOG_INFO("file len: %d", (int)fileSt->st_size);
1218f2d4f7b0Sopenharmony_ci    close(handle);
1219f2d4f7b0Sopenharmony_ci    APPV_FREE(signHead);
1220f2d4f7b0Sopenharmony_ci    APPV_FREE(fileSt);
1221f2d4f7b0Sopenharmony_ci    return ret;
1222f2d4f7b0Sopenharmony_ci}
1223f2d4f7b0Sopenharmony_ci
1224f2d4f7b0Sopenharmony_ci/* set debug mode */
1225f2d4f7b0Sopenharmony_ciint32_t APPVERI_SetDebugMode(bool mode)
1226f2d4f7b0Sopenharmony_ci{
1227f2d4f7b0Sopenharmony_ci    LOG_INFO("set debug mode: %d", mode);
1228f2d4f7b0Sopenharmony_ci    if (g_isDebugMode == mode) {
1229f2d4f7b0Sopenharmony_ci        return V_OK;
1230f2d4f7b0Sopenharmony_ci    }
1231f2d4f7b0Sopenharmony_ci    int32_t ret = PKCS7_EnableDebugMode(mode);
1232f2d4f7b0Sopenharmony_ci    if (ret != V_OK) {
1233f2d4f7b0Sopenharmony_ci        LOG_ERROR("enable pcks7 debug mode failed");
1234f2d4f7b0Sopenharmony_ci        return ret;
1235f2d4f7b0Sopenharmony_ci    }
1236f2d4f7b0Sopenharmony_ci    g_isDebugMode = mode;
1237f2d4f7b0Sopenharmony_ci    return V_OK;
1238f2d4f7b0Sopenharmony_ci}
1239f2d4f7b0Sopenharmony_ci
1240f2d4f7b0Sopenharmony_ci/* set test mode */
1241f2d4f7b0Sopenharmony_civoid APPVERI_SetActsMode(bool mode)
1242f2d4f7b0Sopenharmony_ci{
1243f2d4f7b0Sopenharmony_ci    g_isActsMode = mode;
1244f2d4f7b0Sopenharmony_ci}
1245f2d4f7b0Sopenharmony_ci
1246f2d4f7b0Sopenharmony_ciint32_t APPVERI_IsActsMode(void)
1247f2d4f7b0Sopenharmony_ci{
1248f2d4f7b0Sopenharmony_ci    return g_isActsMode;
1249f2d4f7b0Sopenharmony_ci}
1250f2d4f7b0Sopenharmony_ci
1251f2d4f7b0Sopenharmony_civoid APPVERI_FreeVerifyRst(VerifyResult *verifyRst)
1252f2d4f7b0Sopenharmony_ci{
1253f2d4f7b0Sopenharmony_ci    if (verifyRst == NULL) {
1254f2d4f7b0Sopenharmony_ci        return;
1255f2d4f7b0Sopenharmony_ci    }
1256f2d4f7b0Sopenharmony_ci    LOG_INFO("free verify rst data");
1257f2d4f7b0Sopenharmony_ci    ProfFreeData(&verifyRst->profile);
1258f2d4f7b0Sopenharmony_ci    return;
1259f2d4f7b0Sopenharmony_ci}
1260