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