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