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