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