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