• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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