• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "module_file_repository.h"
17 
18 #include "directory_ex.h"
19 #include "log/log.h"
20 #include "module_constants.h"
21 #include "module_utils.h"
22 
23 namespace OHOS {
24 namespace SysInstaller {
25 using namespace Updater;
26 using std::string;
27 
~ModuleFileRepository()28 ModuleFileRepository::~ModuleFileRepository()
29 {
30     Clear();
31 }
32 
GetInstance()33 ModuleFileRepository &ModuleFileRepository::GetInstance()
34 {
35     static ModuleFileRepository instance;
36     return instance;
37 }
38 
InitRepository(const std::unordered_set<int32_t> & saIdSet)39 void ModuleFileRepository::InitRepository(const std::unordered_set<int32_t> &saIdSet)
40 {
41     string allPath[] = {MODULE_PREINSTALL_DIR, UPDATE_INSTALL_DIR, UPDATE_ACTIVE_DIR};
42     for (string &path : allPath) {
43         std::vector<string> files;
44         GetDirFiles(path, files);
45         std::unordered_map<int32_t, ModuleFile> fileMap;
46         for (string &file : files) {
47             ProcessFile(saIdSet, path, file, fileMap);
48         }
49         moduleFileMap_.emplace(path, std::move(fileMap));
50     }
51 }
52 
ProcessFile(const std::unordered_set<int32_t> & saIdSet,const string & path,const string & file,std::unordered_map<int32_t,ModuleFile> & fileMap) const53 void ModuleFileRepository::ProcessFile(const std::unordered_set<int32_t> &saIdSet, const string &path,
54     const string &file, std::unordered_map<int32_t, ModuleFile> &fileMap) const
55 {
56     if (!CheckFileSuffix(file, MODULE_PACKAGE_SUFFIX)) {
57         return;
58     }
59     std::unique_ptr<ModuleFile> moduleFile = ModuleFile::Open(file);
60     if (moduleFile == nullptr || saIdSet.find(moduleFile->GetSaId()) == saIdSet.end()) {
61         return;
62     }
63     string pubkey = moduleFile->GetPublicKey();
64     if (path != MODULE_PREINSTALL_DIR) {
65         pubkey = GetPublicKey(moduleFile->GetSaId());
66         if (!CheckFilePath(*moduleFile, path)) {
67             return;
68         }
69         if (!ModuleFile::VerifyModulePackageSign(file)) {
70             LOG(ERROR) << "verify sign failed of " << file;
71             return;
72         }
73     }
74     if (moduleFile->GetImageStat().has_value() && !moduleFile->VerifyModuleVerity(pubkey)) {
75         LOG(ERROR) << "verify verity failed of " << file;
76         return;
77     }
78     fileMap.emplace(moduleFile->GetSaId(), std::move(*moduleFile));
79 }
80 
GetModuleFile(const std::string & pathPrefix,const int32_t saId) const81 std::unique_ptr<ModuleFile> ModuleFileRepository::GetModuleFile(const std::string &pathPrefix, const int32_t saId) const
82 {
83     auto mapIter = moduleFileMap_.find(pathPrefix);
84     if (mapIter == moduleFileMap_.end()) {
85         LOG(ERROR) << "Invalid path prefix " << pathPrefix;
86         return nullptr;
87     }
88     std::unordered_map<int32_t, ModuleFile> fileMap = mapIter->second;
89     auto fileIter = fileMap.find(saId);
90     if (fileIter == fileMap.end()) {
91         LOG(INFO) << saId << " not found in " << pathPrefix;
92         return nullptr;
93     }
94     ModuleFile file = fileIter->second;
95     return std::make_unique<ModuleFile>(std::move(file));
96 }
97 
IsPreInstalledModule(const ModuleFile & moduleFile) const98 bool ModuleFileRepository::IsPreInstalledModule(const ModuleFile &moduleFile) const
99 {
100     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR, moduleFile.GetSaId());
101     if (preInstalledModule == nullptr) {
102         return false;
103     }
104     return preInstalledModule->GetPath() == moduleFile.GetPath();
105 }
106 
GetPublicKey(const int32_t saId) const107 string ModuleFileRepository::GetPublicKey(const int32_t saId) const
108 {
109     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR, saId);
110     if (preInstalledModule == nullptr) {
111         return "";
112     }
113     return preInstalledModule->GetPublicKey();
114 }
115 
CheckFilePath(const ModuleFile & moduleFile,const string & prefix) const116 bool ModuleFileRepository::CheckFilePath(const ModuleFile &moduleFile, const string &prefix) const
117 {
118     std::unique_ptr<ModuleFile> preInstalledModule = GetModuleFile(MODULE_PREINSTALL_DIR, moduleFile.GetSaId());
119     if (preInstalledModule == nullptr) {
120         return false;
121     }
122     string prePath = preInstalledModule->GetPath();
123     string curPath = moduleFile.GetPath();
124     return prePath.substr(strlen(MODULE_PREINSTALL_DIR), prePath.length()) ==
125         curPath.substr(prefix.length(), curPath.length());
126 }
127 
Clear()128 void ModuleFileRepository::Clear()
129 {
130     for (auto mapIter = moduleFileMap_.begin(); mapIter != moduleFileMap_.end(); ++mapIter) {
131         std::unordered_map<int32_t, ModuleFile> &fileMap = mapIter->second;
132         for (auto fileIter = fileMap.begin(); fileIter != fileMap.end(); ++fileIter) {
133             fileIter->second.ClearVerifiedData();
134         }
135         fileMap.clear();
136     }
137     moduleFileMap_.clear();
138 }
139 } // SysInstaller
140 } // namespace OHOS