1 /*
2 * Copyright (C) 2021-2022 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 "verify/hap_verify_v2.h"
17
18 #include <climits>
19 #include <cstdlib>
20 #include <regex>
21
22 #include "securec.h"
23
24 #include "common/hap_verify_log.h"
25 #include "init/hap_crl_manager.h"
26 #include "init/trusted_source_manager.h"
27 #include "ticket/ticket_verify.h"
28 #include "util/hap_profile_verify_utils.h"
29 #include "util/hap_signing_block_utils.h"
30 #include "util/signature_info.h"
31
32 namespace OHOS {
33 namespace Security {
34 namespace Verify {
35 const int32_t HapVerifyV2::HEX_PRINT_LENGTH = 3;
36 const int32_t HapVerifyV2::DIGEST_BLOCK_LEN_OFFSET = 8;
37 const int32_t HapVerifyV2::DIGEST_ALGORITHM_OFFSET = 12;
38 const int32_t HapVerifyV2::DIGEST_LEN_OFFSET = 16;
39 const int32_t HapVerifyV2::DIGEST_OFFSET_IN_CONTENT = 20;
40 const std::string HapVerifyV2::HAP_APP_PATTERN = "[^]*.hap$";
41 const std::string HapVerifyV2::HQF_APP_PATTERN = "[^]*.hqf$";
42 const std::string HapVerifyV2::HSP_APP_PATTERN = "[^]*.hsp$";
43 const std::string OPENHARMONY_CERT = "C=CN, O=OpenHarmony, OU=OpenHarmony Team, CN=OpenHarmony Application Root CA";
44
Verify(const std::string & filePath,HapVerifyResult & hapVerifyV1Result,bool readFile)45 int32_t HapVerifyV2::Verify(const std::string& filePath, HapVerifyResult& hapVerifyV1Result, bool readFile)
46 {
47 HAPVERIFY_LOG_DEBUG("Start Verify");
48 std::string standardFilePath;
49 if (!CheckFilePath(filePath, standardFilePath)) {
50 return FILE_PATH_INVALID;
51 }
52
53 RandomAccessFile hapFile;
54 if (!hapFile.Init(standardFilePath, readFile)) {
55 HAPVERIFY_LOG_ERROR("open standard file failed");
56 return OPEN_FILE_ERROR;
57 }
58
59 int32_t resultCode = Verify(hapFile, hapVerifyV1Result);
60 return resultCode;
61 }
62
Verify(const int32_t fileFd,HapVerifyResult & hapVerifyV1Result)63 int32_t HapVerifyV2::Verify(const int32_t fileFd, HapVerifyResult& hapVerifyV1Result)
64 {
65 HAPVERIFY_LOG_INFO("Start Verify with fd");
66 RandomAccessFile hapFile;
67 if (!hapFile.InitWithFd(fileFd)) {
68 HAPVERIFY_LOG_ERROR("init with fd failed");
69 return OPEN_FILE_ERROR;
70 }
71
72 return Verify(hapFile, hapVerifyV1Result);
73 }
74
CheckFilePath(const std::string & filePath,std::string & standardFilePath)75 bool HapVerifyV2::CheckFilePath(const std::string& filePath, std::string& standardFilePath)
76 {
77 char path[PATH_MAX + 1] = { 0x00 };
78 if (filePath.size() > PATH_MAX || realpath(filePath.c_str(), path) == nullptr) {
79 HAPVERIFY_LOG_ERROR("filePath is not a standard path");
80 return false;
81 }
82 standardFilePath = std::string(path);
83 try {
84 if (!std::regex_match(standardFilePath, std::regex(HAP_APP_PATTERN)) &&
85 !std::regex_match(standardFilePath, std::regex(HSP_APP_PATTERN)) &&
86 !std::regex_match(standardFilePath, std::regex(HQF_APP_PATTERN))) {
87 HAPVERIFY_LOG_ERROR("file is not hap, hsp or hqf package");
88 return false;
89 }
90 } catch(const std::regex_error& e) {
91 HAPVERIFY_LOG_ERROR("regex match error");
92 return false;
93 }
94 return true;
95 }
96
Verify(RandomAccessFile & hapFile,HapVerifyResult & hapVerifyV1Result)97 int32_t HapVerifyV2::Verify(RandomAccessFile& hapFile, HapVerifyResult& hapVerifyV1Result)
98 {
99 SignatureInfo hapSignInfo;
100 if (!HapSigningBlockUtils::FindHapSignature(hapFile, hapSignInfo)) {
101 return SIGNATURE_NOT_FOUND;
102 }
103 hapVerifyV1Result.SetVersion(hapSignInfo.version);
104 hapVerifyV1Result.SetPkcs7SignBlock(hapSignInfo.hapSignatureBlock);
105 hapVerifyV1Result.SetPkcs7ProfileBlock(hapSignInfo.hapSignatureBlock);
106 hapVerifyV1Result.SetOptionalBlocks(hapSignInfo.optionBlocks);
107 Pkcs7Context pkcs7Context;
108 if (!VerifyAppPkcs7(pkcs7Context, hapSignInfo.hapSignatureBlock)) {
109 return VERIFY_APP_PKCS7_FAIL;
110 }
111 int32_t profileIndex = 0;
112 if (!HapSigningBlockUtils::GetOptionalBlockIndex(hapSignInfo.optionBlocks, PROFILE_BLOB, profileIndex)) {
113 return NO_PROFILE_BLOCK_FAIL;
114 }
115 bool profileNeedWriteCrl = false;
116 if (!VerifyAppSourceAndParseProfile(pkcs7Context, hapSignInfo.optionBlocks[profileIndex].optionalBlockValue,
117 hapVerifyV1Result, profileNeedWriteCrl)) {
118 HAPVERIFY_LOG_ERROR("APP source is not trusted");
119 return APP_SOURCE_NOT_TRUSTED;
120 }
121 if (!GetDigestAndAlgorithm(pkcs7Context)) {
122 HAPVERIFY_LOG_ERROR("Get digest failed");
123 return GET_DIGEST_FAIL;
124 }
125 std::vector<std::string> publicKeys;
126 if (!HapVerifyOpensslUtils::GetPublickeys(pkcs7Context.certChains[0], publicKeys)) {
127 HAPVERIFY_LOG_ERROR("Get publicKeys failed");
128 return GET_PUBLICKEY_FAIL;
129 }
130 hapVerifyV1Result.SetPublicKey(publicKeys);
131 std::vector<std::string> certSignatures;
132 if (!HapVerifyOpensslUtils::GetSignatures(pkcs7Context.certChains[0], certSignatures)) {
133 HAPVERIFY_LOG_ERROR("Get sianatures failed");
134 return GET_SIGNATURE_FAIL;
135 }
136 hapVerifyV1Result.SetSignature(certSignatures);
137 if (!HapSigningBlockUtils::VerifyHapIntegrity(pkcs7Context, hapFile, hapSignInfo)) {
138 HAPVERIFY_LOG_ERROR("Verify Integrity failed");
139 return VERIFY_INTEGRITY_FAIL;
140 }
141 WriteCrlIfNeed(pkcs7Context, profileNeedWriteCrl);
142 return VERIFY_SUCCESS;
143 }
144
VerifyAppPkcs7(Pkcs7Context & pkcs7Context,const HapByteBuffer & hapSignatureBlock)145 bool HapVerifyV2::VerifyAppPkcs7(Pkcs7Context& pkcs7Context, const HapByteBuffer& hapSignatureBlock)
146 {
147 const unsigned char* pkcs7Block = reinterpret_cast<const unsigned char*>(hapSignatureBlock.GetBufferPtr());
148 uint32_t pkcs7Len = static_cast<unsigned int>(hapSignatureBlock.GetCapacity());
149 if (!HapVerifyOpensslUtils::ParsePkcs7Package(pkcs7Block, pkcs7Len, pkcs7Context)) {
150 HAPVERIFY_LOG_ERROR("parse pkcs7 failed");
151 return false;
152 }
153 if (!HapVerifyOpensslUtils::GetCertChains(pkcs7Context.p7, pkcs7Context)) {
154 HAPVERIFY_LOG_ERROR("GetCertChains from pkcs7 failed");
155 return false;
156 }
157 if (!HapVerifyOpensslUtils::VerifyPkcs7(pkcs7Context)) {
158 HAPVERIFY_LOG_ERROR("verify signature failed");
159 return false;
160 }
161 return true;
162 }
163
VerifyAppSourceAndParseProfile(Pkcs7Context & pkcs7Context,const HapByteBuffer & hapProfileBlock,HapVerifyResult & hapVerifyV1Result,bool & profileNeadWriteCrl)164 bool HapVerifyV2::VerifyAppSourceAndParseProfile(Pkcs7Context& pkcs7Context,
165 const HapByteBuffer& hapProfileBlock, HapVerifyResult& hapVerifyV1Result, bool& profileNeadWriteCrl)
166 {
167 std::string certSubject;
168 if (!HapCertVerifyOpensslUtils::GetSubjectFromX509(pkcs7Context.certChains[0][0], certSubject)) {
169 HAPVERIFY_LOG_ERROR("Get info of sign cert failed");
170 return false;
171 }
172 HAPVERIFY_LOG_DEBUG("App signature subject: %{private}s, issuer: %{public}s",
173 certSubject.c_str(), pkcs7Context.certIssuer.c_str());
174
175 TrustedSourceManager& trustedSourceManager = TrustedSourceManager::GetInstance();
176 pkcs7Context.matchResult = trustedSourceManager.IsTrustedSource(certSubject, pkcs7Context.certIssuer,
177 HAP_SIGN_BLOB, pkcs7Context.certChains[0].size());
178
179 if (pkcs7Context.matchResult.matchState == MATCH_WITH_SIGN &&
180 pkcs7Context.matchResult.rootCa != pkcs7Context.rootCa) {
181 HAPVERIFY_LOG_ERROR("MatchRootCa failed, target rootCa: %{public}s, rootCa in pkcs7: %{public}s",
182 pkcs7Context.matchResult.rootCa.c_str(), pkcs7Context.rootCa.c_str());
183 return false;
184 }
185
186 Pkcs7Context profileContext;
187 std::string profile;
188 if (!HapProfileVerifyUtils::ParseProfile(profileContext, pkcs7Context, hapProfileBlock, profile)) {
189 HAPVERIFY_LOG_ERROR("Parse profile pkcs7 failed");
190 return false;
191 }
192
193 if (!VerifyProfileSignature(pkcs7Context, profileContext)) {
194 HAPVERIFY_LOG_ERROR("VerifyProfileSignature failed");
195 return false;
196 }
197 /*
198 * If app source is not trusted, verify profile.
199 * If profile is debug, check whether app signed cert is same as the debug cert in profile.
200 * If profile is release, do not allow installation of this app.
201 */
202 bool isCallParseAndVerify = false;
203 ProvisionInfo provisionInfo;
204 if (pkcs7Context.matchResult.matchState == DO_NOT_MATCH) {
205 if (!HapProfileVerifyUtils::VerifyProfile(profileContext)) {
206 HAPVERIFY_LOG_ERROR("profile verify failed");
207 return false;
208 }
209 if (profileContext.matchResult.rootCa != pkcs7Context.rootCa) {
210 HAPVERIFY_LOG_ERROR("MatchProfileRootCa failed, target rootCa: %{public}s, rootCa in profile: %{public}s",
211 profileContext.matchResult.rootCa.c_str(), pkcs7Context.rootCa.c_str());
212 return false;
213 }
214 AppProvisionVerifyResult profileRet = ParseAndVerify(profile, provisionInfo);
215 if (profileRet != PROVISION_OK) {
216 HAPVERIFY_LOG_ERROR("profile parsing failed, error: %{public}d", static_cast<int>(profileRet));
217 return false;
218 }
219 if (!VerifyProfileInfo(pkcs7Context, profileContext, provisionInfo)) {
220 HAPVERIFY_LOG_ERROR("VerifyProfileInfo failed");
221 return false;
222 }
223 isCallParseAndVerify = true;
224 }
225
226 if (!ParseAndVerifyProfileIfNeed(profile, provisionInfo, isCallParseAndVerify)) {
227 return false;
228 }
229
230 if (!GenerateAppId(provisionInfo) || !GenerateFingerprint(provisionInfo)) {
231 HAPVERIFY_LOG_ERROR("Generate appId or generate fingerprint failed");
232 return false;
233 }
234 SetOrganization(provisionInfo);
235 SetProfileBlockData(pkcs7Context, hapProfileBlock, provisionInfo);
236 provisionInfo.isOpenHarmony = OPENHARMONY_CERT == pkcs7Context.rootCa;
237
238 hapVerifyV1Result.SetProvisionInfo(provisionInfo);
239 profileNeadWriteCrl = profileContext.needWriteCrl;
240 return true;
241 }
242
VerifyProfileSignature(const Pkcs7Context & pkcs7Context,Pkcs7Context & profileContext)243 bool HapVerifyV2::VerifyProfileSignature(const Pkcs7Context& pkcs7Context, Pkcs7Context& profileContext)
244 {
245 if (pkcs7Context.matchResult.matchState == MATCH_WITH_SIGN &&
246 (pkcs7Context.matchResult.source == APP_THIRD_PARTY_PRELOAD ||
247 pkcs7Context.matchResult.source == APP_SYSTEM)) {
248 if (!HapProfileVerifyUtils::VerifyProfile(profileContext)) {
249 HAPVERIFY_LOG_ERROR("profile verify failed");
250 return false;
251 }
252 }
253 return true;
254 }
255
GenerateAppId(ProvisionInfo & provisionInfo)256 bool HapVerifyV2::GenerateAppId(ProvisionInfo& provisionInfo)
257 {
258 std::string& certInProfile = provisionInfo.bundleInfo.distributionCertificate;
259 if (provisionInfo.bundleInfo.distributionCertificate.empty()) {
260 certInProfile = provisionInfo.bundleInfo.developmentCertificate;
261 HAPVERIFY_LOG_DEBUG("use development Certificate");
262 }
263 std::string publicKey;
264 if (!HapCertVerifyOpensslUtils::GetPublickeyBase64FromPemCert(certInProfile, publicKey)) {
265 return false;
266 }
267 provisionInfo.appId = publicKey;
268 HAPVERIFY_LOG_DEBUG("provisionInfo.appId: %{public}s", provisionInfo.appId.c_str());
269 return true;
270 }
271
GenerateFingerprint(ProvisionInfo & provisionInfo)272 bool HapVerifyV2::GenerateFingerprint(ProvisionInfo& provisionInfo)
273 {
274 std::string& certInProfile = provisionInfo.bundleInfo.distributionCertificate;
275 if (provisionInfo.bundleInfo.distributionCertificate.empty()) {
276 certInProfile = provisionInfo.bundleInfo.developmentCertificate;
277 HAPVERIFY_LOG_DEBUG("use development Certificate");
278 }
279 std::string fingerprint;
280 if (!HapCertVerifyOpensslUtils::GetFingerprintBase64FromPemCert(certInProfile, fingerprint)) {
281 HAPVERIFY_LOG_ERROR("Generate fingerprint from pem certificate failed");
282 return false;
283 }
284 provisionInfo.fingerprint = fingerprint;
285 HAPVERIFY_LOG_DEBUG("fingerprint is : %{private}s", fingerprint.c_str());
286 return true;
287 }
288
SetProfileBlockData(const Pkcs7Context & pkcs7Context,const HapByteBuffer & hapProfileBlock,ProvisionInfo & provisionInfo)289 void HapVerifyV2::SetProfileBlockData(const Pkcs7Context& pkcs7Context, const HapByteBuffer& hapProfileBlock,
290 ProvisionInfo& provisionInfo)
291 {
292 if (pkcs7Context.matchResult.matchState == MATCH_WITH_SIGN &&
293 pkcs7Context.matchResult.source == APP_GALLARY) {
294 HAPVERIFY_LOG_DEBUG("profile is from app gallary and unnecessary to set profile block");
295 return;
296 }
297 provisionInfo.profileBlockLength = hapProfileBlock.GetCapacity();
298 HAPVERIFY_LOG_DEBUG("profile block data length is %{public}d", provisionInfo.profileBlockLength);
299 if (provisionInfo.profileBlockLength == 0) {
300 HAPVERIFY_LOG_ERROR("invalid profile block");
301 return;
302 }
303 provisionInfo.profileBlock = std::make_unique<unsigned char[]>(provisionInfo.profileBlockLength);
304 unsigned char *profileBlockData = provisionInfo.profileBlock.get();
305 const unsigned char *originalProfile = reinterpret_cast<const unsigned char*>(hapProfileBlock.GetBufferPtr());
306 if (profileBlockData == nullptr || originalProfile ==nullptr) {
307 HAPVERIFY_LOG_ERROR("invalid profileBlockData or originalProfile");
308 return;
309 }
310 if (memcpy_s(profileBlockData, provisionInfo.profileBlockLength, originalProfile,
311 provisionInfo.profileBlockLength) != 0) {
312 HAPVERIFY_LOG_ERROR("memcpy failed");
313 }
314 }
315
VerifyProfileInfo(const Pkcs7Context & pkcs7Context,const Pkcs7Context & profileContext,ProvisionInfo & provisionInfo)316 bool HapVerifyV2::VerifyProfileInfo(const Pkcs7Context& pkcs7Context, const Pkcs7Context& profileContext,
317 ProvisionInfo& provisionInfo)
318 {
319 if (!CheckProfileSignatureIsRight(profileContext.matchResult.matchState, provisionInfo.type)) {
320 return false;
321 }
322 std::string& certInProfile = provisionInfo.bundleInfo.developmentCertificate;
323 if (provisionInfo.type == ProvisionType::RELEASE) {
324 if (!IsAppDistributedTypeAllowInstall(provisionInfo.distributionType, provisionInfo)) {
325 HAPVERIFY_LOG_ERROR("untrusted source app with release profile distributionType: %{public}d",
326 static_cast<int>(provisionInfo.distributionType));
327 return false;
328 }
329 certInProfile = provisionInfo.bundleInfo.distributionCertificate;
330 HAPVERIFY_LOG_DEBUG("allow install app with release profile distributionType: %{public}d",
331 static_cast<int>(provisionInfo.distributionType));
332 }
333 HAPVERIFY_LOG_DEBUG("provisionInfo.type: %{public}d", static_cast<int>(provisionInfo.type));
334 if (!HapCertVerifyOpensslUtils::CompareX509Cert(pkcs7Context.certChains[0][0], certInProfile)) {
335 HAPVERIFY_LOG_ERROR("developed cert is not same as signed cert");
336 return false;
337 }
338 return true;
339 }
340
IsAppDistributedTypeAllowInstall(const AppDistType & type,const ProvisionInfo & provisionInfo) const341 bool HapVerifyV2::IsAppDistributedTypeAllowInstall(const AppDistType& type, const ProvisionInfo& provisionInfo) const
342 {
343 switch (type) {
344 case AppDistType::NONE_TYPE:
345 return false;
346 case AppDistType::APP_GALLERY:
347 if (CheckTicketSource(provisionInfo)) {
348 HAPVERIFY_LOG_INFO("current device is allowed to install opentest application");
349 return true;
350 }
351 return false;
352 case AppDistType::ENTERPRISE:
353 case AppDistType::ENTERPRISE_NORMAL:
354 case AppDistType::ENTERPRISE_MDM:
355 case AppDistType::OS_INTEGRATION:
356 case AppDistType::CROWDTESTING:
357 case AppDistType::INTERNALTESTING:
358 return true;
359 default:
360 return false;
361 }
362 }
363
CheckProfileSignatureIsRight(const MatchingStates & matchState,const ProvisionType & type)364 bool HapVerifyV2::CheckProfileSignatureIsRight(const MatchingStates& matchState, const ProvisionType& type)
365 {
366 if (matchState == MATCH_WITH_PROFILE && type == ProvisionType::RELEASE) {
367 return true;
368 } else if (matchState == MATCH_WITH_PROFILE_DEBUG && type == ProvisionType::DEBUG) {
369 return true;
370 }
371 HAPVERIFY_LOG_ERROR("isTrustedSource: %{public}d is not match with profile type: %{public}d",
372 static_cast<int>(matchState), static_cast<int>(type));
373 return false;
374 }
375
WriteCrlIfNeed(const Pkcs7Context & pkcs7Context,const bool & profileNeedWriteCrl)376 void HapVerifyV2::WriteCrlIfNeed(const Pkcs7Context& pkcs7Context, const bool& profileNeedWriteCrl)
377 {
378 if (!pkcs7Context.needWriteCrl && !profileNeedWriteCrl) {
379 return;
380 }
381 HapCrlManager& hapCrlManager = HapCrlManager::GetInstance();
382 hapCrlManager.WriteCrlsToFile();
383 }
384
ParseAndVerifyProfileIfNeed(const std::string & profile,ProvisionInfo & provisionInfo,bool isCallParseAndVerify)385 bool HapVerifyV2::ParseAndVerifyProfileIfNeed(const std::string& profile,
386 ProvisionInfo& provisionInfo, bool isCallParseAndVerify)
387 {
388 if (isCallParseAndVerify) {
389 return isCallParseAndVerify;
390 }
391 AppProvisionVerifyResult profileRet = ParseAndVerify(profile, provisionInfo);
392 if (profileRet != PROVISION_OK) {
393 HAPVERIFY_LOG_ERROR("profile parse failed, error: %{public}d", static_cast<int>(profileRet));
394 return false;
395 }
396 return true;
397 }
398
GetDigestAndAlgorithm(Pkcs7Context & digest)399 bool HapVerifyV2::GetDigestAndAlgorithm(Pkcs7Context& digest)
400 {
401 /*
402 * contentinfo format:
403 * int: version
404 * int: block number
405 * digest blocks:
406 * each digest block format:
407 * int: length of sizeof(digestblock) - 4
408 * int: Algorithm ID
409 * int: length of digest
410 * byte[]: digest
411 */
412 /* length of sizeof(digestblock - 4) */
413 int32_t digestBlockLen;
414 if (!digest.content.GetInt32(DIGEST_BLOCK_LEN_OFFSET, digestBlockLen)) {
415 HAPVERIFY_LOG_ERROR("get digestBlockLen failed");
416 return false;
417 }
418 /* Algorithm ID */
419 if (!digest.content.GetInt32(DIGEST_ALGORITHM_OFFSET, digest.digestAlgorithm)) {
420 HAPVERIFY_LOG_ERROR("get digestAlgorithm failed");
421 return false;
422 }
423 /* length of digest */
424 int32_t digestlen;
425 if (!digest.content.GetInt32(DIGEST_LEN_OFFSET, digestlen)) {
426 HAPVERIFY_LOG_ERROR("get digestlen failed");
427 return false;
428 }
429
430 int32_t sum = sizeof(digestlen) + sizeof(digest.digestAlgorithm) + digestlen;
431 if (sum != digestBlockLen) {
432 HAPVERIFY_LOG_ERROR("digestBlockLen: %{public}d is not equal to sum: %{public}d",
433 digestBlockLen, sum);
434 return false;
435 }
436 /* set position to the digest start point */
437 digest.content.SetPosition(DIGEST_OFFSET_IN_CONTENT);
438 /* set limit to the digest end point */
439 digest.content.SetLimit(DIGEST_OFFSET_IN_CONTENT + digestlen);
440 digest.content.Slice();
441 return true;
442 }
443
ParseHapProfile(const std::string & filePath,HapVerifyResult & hapVerifyV1Result,bool readFile)444 int32_t HapVerifyV2::ParseHapProfile(const std::string& filePath, HapVerifyResult& hapVerifyV1Result, bool readFile)
445 {
446 HAPVERIFY_LOG_INFO("start to ParseHapProfile");
447 std::string standardFilePath;
448 if (!CheckFilePath(filePath, standardFilePath)) {
449 return FILE_PATH_INVALID;
450 }
451
452 RandomAccessFile hapFile;
453 if (!hapFile.Init(standardFilePath, readFile)) {
454 HAPVERIFY_LOG_ERROR("open standard file failed");
455 return OPEN_FILE_ERROR;
456 }
457
458 SignatureInfo hapSignInfo;
459 if (!HapSigningBlockUtils::FindHapSignature(hapFile, hapSignInfo)) {
460 return SIGNATURE_NOT_FOUND;
461 }
462
463 int32_t profileIndex = 0;
464 if (!HapSigningBlockUtils::GetOptionalBlockIndex(hapSignInfo.optionBlocks, PROFILE_BLOB, profileIndex)) {
465 return NO_PROFILE_BLOCK_FAIL;
466 }
467 auto pkcs7ProfileBlock = hapSignInfo.optionBlocks[profileIndex].optionalBlockValue;
468 const unsigned char* pkcs7Block = reinterpret_cast<const unsigned char*>(pkcs7ProfileBlock.GetBufferPtr());
469 uint32_t pkcs7Len = static_cast<unsigned int>(pkcs7ProfileBlock.GetCapacity());
470 Pkcs7Context profileContext;
471 if (!HapVerifyOpensslUtils::ParsePkcs7Package(pkcs7Block, pkcs7Len, profileContext)) {
472 HAPVERIFY_LOG_ERROR("parse pkcs7 failed");
473 return false;
474 }
475 std::string profile = std::string(profileContext.content.GetBufferPtr(), profileContext.content.GetCapacity());
476 HAPVERIFY_LOG_DEBUG("profile is %{public}s", profile.c_str());
477 ProvisionInfo info;
478 auto ret = ParseProfile(profile, info);
479 if (ret != PROVISION_OK) {
480 return PROFILE_PARSE_FAIL;
481 }
482
483 if (!GenerateFingerprint(info)) {
484 HAPVERIFY_LOG_ERROR("Generate appId or generate fingerprint failed");
485 return PROFILE_PARSE_FAIL;
486 }
487 SetOrganization(info);
488 hapVerifyV1Result.SetProvisionInfo(info);
489 return VERIFY_SUCCESS;
490 }
491
ParseHapSignatureInfo(const std::string & filePath,SignatureInfo & hapSignInfo)492 int32_t HapVerifyV2::ParseHapSignatureInfo(const std::string& filePath, SignatureInfo &hapSignInfo)
493 {
494 std::string standardFilePath;
495 if (!CheckFilePath(filePath, standardFilePath)) {
496 return FILE_PATH_INVALID;
497 }
498
499 RandomAccessFile hapFile;
500 if (!hapFile.Init(standardFilePath)) {
501 HAPVERIFY_LOG_ERROR("open standard file failed");
502 return OPEN_FILE_ERROR;
503 }
504
505 if (!HapSigningBlockUtils::FindHapSignature(hapFile, hapSignInfo)) {
506 return SIGNATURE_NOT_FOUND;
507 }
508 return VERIFY_SUCCESS;
509 }
510
SetOrganization(ProvisionInfo & provisionInfo)511 void HapVerifyV2::SetOrganization(ProvisionInfo& provisionInfo)
512 {
513 std::string& certInProfile = provisionInfo.bundleInfo.distributionCertificate;
514 if (provisionInfo.bundleInfo.distributionCertificate.empty()) {
515 HAPVERIFY_LOG_ERROR("distributionCertificate is empty");
516 return;
517 }
518 std::string organization;
519 if (!HapCertVerifyOpensslUtils::GetOrganizationFromPemCert(certInProfile, organization)) {
520 HAPVERIFY_LOG_ERROR("Generate organization from pem certificate failed");
521 return;
522 }
523 provisionInfo.organization = organization;
524 }
525 } // namespace Verify
526 } // namespace Security
527 } // namespace OHOS
528