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