• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
35 static 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 
65 static 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 
85 static bool g_isDebugMode = false;
86 
87 static bool g_isActsMode = false;
88 
SignHeadN2H(HwSignHead * signHead)89 static 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 
BlockHeadN2H(BlockHead * blockHead)99 static 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 
ContentN2H(ContentInfo * content)107 static 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 
GetSignHead(const FileRead * file,SignatureInfo * signInfo)116 static 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 
FindBlockHead(const SignatureInfo * signInfo,int32_t fp,int32_t blockType,BlockHead * block)169 static 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 
GetSignBlockByType(const SignatureInfo * signInfo,int32_t fp,int32_t blockType,int32_t * len,BlockHead * blockHead)195 char *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 
GetHashUnitLen(int32_t hashAlg)245 int32_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 
CalcCmpContHash(const Pkcs7 * pkcs7,const SignerInfo * signer,mbedtls_md_type_t algType,unsigned char * hash,size_t * hashLen)251 static 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 
CalcDigest(const Pkcs7 * pkcs7,const SignerInfo * signer,mbedtls_md_type_t algType,unsigned char * hash,size_t * hashLen)288 static 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 
VerifyRawHash(const SignatureInfo * signInfo,const FileRead * fileRead,const Pkcs7 * pkcs7Handle)316 static 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 
GetCertTypeBySourceName(const TrustAppCert * cert)369 static 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 
GetProfSourceBySigningCert(const SignerResovledInfo * signer,const TrustAppCert * trustList,int32_t num)386 static 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 
GetProfileCertTypeBySignInfo(SignerResovledInfo * signer,int32_t * certType)401 static 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 
GetAppSourceBySigningCert(const SignerResovledInfo * signer,const TrustAppCert * trustList,int32_t num)420 static 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 
GetAppCertTypeBySignInfo(SignerResovledInfo * signer,int32_t * certType)432 static 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 */
GetAppSingerCertType(Pkcs7 * pkcs7Handle,int32_t * certType)451 static 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 */
GetProfileSingerCertType(Pkcs7 * pkcs7Handle,int32_t * certType)470 static 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 */
VerifyProfileSignGetRaw(const char * buf,int32_t len,char ** profileContent,int32_t * contentLen)488 static 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;
544 EXIT:
545     PKCS7_FreeRes(pkcs7);
546     APPV_FREE(pkcs7);
547     APPV_FREE(profileData);
548     return V_ERR;
549 }
GetRsaPk(const mbedtls_pk_context * pk,int32_t * len)550 static 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 
GetEcPk(const mbedtls_pk_context * pk,int32_t * len)593 static 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 
GetPkBuf(const mbedtls_pk_context * pk,int32_t * len)643 static 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 
ParseCertGetPk(const char * certEncoded,AppSignPk * pk)654 static 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 
GetAppSignPublicKey(const ProfileProf * profile,AppSignPk * pk)681 static 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 
FreeAppSignPublicKey(AppSignPk * pk)698 static void FreeAppSignPublicKey(AppSignPk *pk)
699 {
700     if (pk->pk != NULL) {
701         APPV_FREE(pk->pk);
702     }
703     return;
704 }
705 
GetAppid(ProfileProf * profile)706 int32_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 
VerifyProfGetContent(int32_t fp,const SignatureInfo * signInfo,int32_t certType,ProfileProf * pf)754 static 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;
790 EXIT:
791     ProfFreeData(pf);
792     return ret;
793 }
794 
CmpCert(const mbedtls_x509_crt * certA,const CertInfo * binSignCert)795 static 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 
LoadCertAndCmpDest(const unsigned char * certBase64,const CertInfo * binSignCert)837 int32_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 
CheckReleaseAppSign(const CertInfo * binSignCert,const ProfileProf * pf)861 static 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 
CheckDebugAppSign(CertInfo * binSignCert,const ProfileProf * pf)882 static 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 
CheckAppSignCertWithProfile(int32_t appCertType,CertInfo * binSignCert,ProfileProf * pf)904 static 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 
CertInfoInit(CertInfo * certInfo)924 static 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 
FreeCertInfo(CertInfo * certInfo)933 void 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 
GetCertInfo(const mbedtls_x509_crt * ctr,CertInfo ** binSignCert)955 static 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;
1004 EXIT:
1005     FreeCertInfo(certInfo);
1006     APPV_FREE(certInfo);
1007     return ret;
1008 }
1009 
VerfiyAppSourceGetProfile(int32_t fp,const SignatureInfo * signInfo,int32_t certType,CertInfo * binSignCert,ProfileProf * pf)1010 static 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 
VerifyAppSignPkcsData(const FileRead * fileRead,const SignatureInfo * signInfo,const Pkcs7 * pkcs7Handle)1036 static 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 
GetBinSignPkcs(const char * signBuf,int32_t len)1062 static 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 
GetFileRead(int32_t fp,int32_t offset,int32_t size)1079 static 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 }
VerifyBinSign(SignatureInfo * signInfo,int32_t fp,CertInfo ** signCert,int32_t * certType)1092 static 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 
1141 EXIT:
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 
VerifyIntegrity(SignatureInfo * signInfo,int32_t fp,ProfileProf * pf)1151 static 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 
APPVERI_AppVerify(const char * filePath,VerifyResult * verifyRst)1174 int32_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 */
APPVERI_SetDebugMode(bool mode)1225 int32_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 */
APPVERI_SetActsMode(bool mode)1241 void APPVERI_SetActsMode(bool mode)
1242 {
1243     g_isActsMode = mode;
1244 }
1245 
APPVERI_IsActsMode(void)1246 int32_t APPVERI_IsActsMode(void)
1247 {
1248     return g_isActsMode;
1249 }
1250 
APPVERI_FreeVerifyRst(VerifyResult * verifyRst)1251 void 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