1 /*
2 * Copyright (c) 2025-2025 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 "feature/param_update/param_reader.h"
17
18 #include <memory>
19 #include <iostream>
20 #include <fstream>
21 #include <sstream>
22 #include <cstdlib>
23 #include <climits>
24 #include "common/util/string_utils.h"
25 #include "feature/param_update/sign_tools.h"
26 #include "form_constants.h"
27 #include "fms_log_wrapper.h"
28 #include "json_serializer.h"
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 const std::string CERT_ENC_FILE = "CERT.ENC";
34 const std::string CERT_SF_FILE = "CERT.SF";
35 const std::string MANIFEST_MF_FILE = "MANIFEST.MF";
36 const std::string FILE_SHA_KEY = "Name: ";
37 const std::string PUBKEY_PATH = "/system/etc/update/hwkey_param_upgrade_v1.pem";
38 }
39
ParamReader()40 ParamReader::ParamReader()
41 {
42 HILOG_INFO("init");
43 }
~ParamReader()44 ParamReader::~ParamReader()
45 {
46 HILOG_INFO("destroy");
47 }
48
GetPathVersion(const std::string & path)49 std::string ParamReader::GetPathVersion(const std::string &path)
50 {
51 HILOG_INFO("GetPathVersion:%{public}s", path.c_str());
52 if (path.empty()) {
53 HILOG_ERROR("path is empty, return default version");
54 return Constants::FMC_DEFAULT_VERSION;
55 }
56 char canonicalPath[PATH_MAX] = { '\0' };
57 if (realpath((path + Constants::VERSION_FILE_NAME).c_str(), canonicalPath) == nullptr) {
58 HILOG_ERROR("canonicalPath is null, return default version");
59 return Constants::FMC_DEFAULT_VERSION;
60 }
61 canonicalPath[PATH_MAX - 1] = '\0';
62 std::ifstream file(canonicalPath);
63 if (!file.good()) {
64 HILOG_ERROR("VersionFilePath is not good");
65 return Constants::FMC_DEFAULT_VERSION;
66 }
67 std::string line;
68 std::getline(file, line);
69 std::string versionStr = StringUtils::split(line, '=')[1];
70 StringUtils::trim(versionStr);
71 file.close();
72 return versionStr;
73 }
74
VerifyCertSfFile()75 bool ParamReader::VerifyCertSfFile()
76 {
77 std::string certFile = Constants::FORM_MGR_CONFIG_DIR + CERT_ENC_FILE;
78 std::string verifyFile = Constants::FORM_MGR_CONFIG_DIR + CERT_SF_FILE;
79 if (!SignTools::VerifyFileSign(PUBKEY_PATH, certFile, verifyFile)) {
80 HILOG_ERROR("verify file sign failed");
81 return false;
82 }
83 std::string sha256Digest = GetManifestSha256Digest();
84 HILOG_INFO("sha256Digest:%{public}s", sha256Digest.c_str());
85 if (sha256Digest.empty()) {
86 HILOG_ERROR("sha256Digest is empty");
87 return false;
88 }
89 std::string calSha256Digest = CalcFileSha256Digest(MANIFEST_MF_FILE);
90 HILOG_INFO("calSha256Digest:%{public}s", calSha256Digest.c_str());
91 if (calSha256Digest.empty()) {
92 HILOG_ERROR("calSha256Digest is empty");
93 return false;
94 }
95 return sha256Digest == calSha256Digest;
96 }
97
VerifyParamFile(const std::string & fileName)98 bool ParamReader::VerifyParamFile(const std::string &fileName)
99 {
100 HILOG_INFO("VerifyParamFile ,fileName:%{public}s", fileName.c_str());
101 std::string sha256Digest = GetSha256Digest(fileName);
102 HILOG_INFO("sha256Digest:%{public}s", sha256Digest.c_str());
103 if (sha256Digest.empty()) {
104 HILOG_ERROR("sha256Digest is empty");
105 return false;
106 }
107 std::string calSha256Digest = CalcFileSha256Digest(fileName);
108 HILOG_INFO("calSha256Digest:%{public}s", calSha256Digest.c_str());
109 if (calSha256Digest.empty()) {
110 HILOG_ERROR("calSha256Digest is empty");
111 return false;
112 }
113 return sha256Digest == calSha256Digest;
114 }
115
GetParamInfoStr(const std::string & filePathStr)116 std::string ParamReader::GetParamInfoStr(const std::string &filePathStr)
117 {
118 std::string paramInfo;
119 char canonicalPath[PATH_MAX] = { '\0' };
120 if (realpath(filePathStr.c_str(), canonicalPath) == nullptr) {
121 HILOG_ERROR("canonicalPath is null");
122 return paramInfo;
123 }
124 canonicalPath[PATH_MAX - 1] = '\0';
125 std::ifstream file(canonicalPath, std::ios::in | std::ios::binary);
126 if (!file.good()) {
127 HILOG_ERROR("Failed to open the file!");
128 return paramInfo;
129 }
130 std::stringstream infile;
131 infile << file.rdbuf();
132 paramInfo = infile.str();
133 file.close();
134 return paramInfo;
135 }
136
GetManifestSha256Digest()137 std::string ParamReader::GetManifestSha256Digest()
138 {
139 std::string verifyFile = Constants::FORM_MGR_CONFIG_DIR + CERT_SF_FILE;
140 std::ifstream file(verifyFile);
141 std::string sha256Digest;
142 if (!file.good()) {
143 HILOG_ERROR("Verify file is not good");
144 return sha256Digest;
145 }
146 std::string line;
147 std::getline(file, line);
148 file.close();
149 sha256Digest = StringUtils::split(line, ':')[1];
150 StringUtils::trim(sha256Digest);
151 return sha256Digest;
152 }
153
GetSha256Digest(const std::string & fileName)154 std::string ParamReader::GetSha256Digest(const std::string &fileName)
155 {
156 std::string manifestFile = Constants::FORM_MGR_CONFIG_DIR + MANIFEST_MF_FILE;
157 std::ifstream file(manifestFile);
158 std::string sha256Digest;
159 if (!file.good()) {
160 HILOG_ERROR("manifestFile is not good");
161 return sha256Digest;
162 }
163 std::string line;
164 while (std::getline(file, line)) {
165 std::string nextline;
166 if (line.find(FILE_SHA_KEY + fileName) != std::string::npos) {
167 std::getline(file, nextline);
168 sha256Digest = StringUtils::split(nextline, ':')[1];
169 StringUtils::trim(sha256Digest);
170 break;
171 }
172 }
173 file.close();
174 return sha256Digest;
175 }
176
CalcFileSha256Digest(const std::string & fileName)177 std::string ParamReader::CalcFileSha256Digest(const std::string &fileName)
178 {
179 std::string filePath = Constants::FORM_MGR_CONFIG_DIR + fileName;
180 std::string calSha256Digest;
181 std::tuple<int, std::string> ret = SignTools::CalcFileSha256Digest(filePath);
182 if (std::get<0>(ret) != 0) {
183 HILOG_ERROR("CalcFileSha256Digest failed,error : %{public}d ", std::get<0>(ret));
184 return calSha256Digest;
185 }
186 calSha256Digest = std::get<1>(ret);
187 return calSha256Digest;
188 }
189 } // namespace AppExecFwk
190 } // namespace OHOS