1 /*
2 * Copyright (c) 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 "camera_rotate_param_reader.h"
17
18 #include <memory>
19 #include <iostream>
20 #include <fstream>
21
22 #include "camera_log.h"
23 #include "camera_util.h"
24 #ifdef CONFIG_POLICY_EXT_ENABLE
25 #include "config_policy_param_upgrade_path.h"
26 #include "config_policy_utils.h"
27 #endif
28 #include "camera_rotate_param_sign_tools.h"
29
30 namespace OHOS {
31 namespace CameraStandard {
32
33 namespace {
34 const std::string PUBKEY_PATH = ABS_CONTENT_FILE_PATH + PUB_KEY_NAME;
35 constexpr int VERSION_LEN = 4;
36 constexpr int DEC = 10;
37 }
38 // LCOV_EXCL_START
39 // 获取高版本配置路径
GetConfigFilePath()40 std::string CameraRoateParamReader::GetConfigFilePath()
41 {
42 #ifdef CONFIG_POLICY_EXT_ENABLE
43 std::lock_guard<std::mutex> lock(custMethodLock);
44 ::HwCustSetDataSourceType(HW_CUST_TYPE_SYSTEM);
45 std::string cfgDir = CAMERA_ROTATE_CFG_DIR;
46 //期望data/service/el1/public/update/param_service/install/system/etc/camera/version.txt
47 ParamVersionFileInfo *paramVersionFileInfo = ::GetDownloadCfgFile(cfgDir.c_str(), cfgDir.c_str());
48 if (paramVersionFileInfo == NULL) {
49 MEDIA_ERR_LOG("NULL ptr, can not found txt in path : %{public}s", cfgDir.c_str());
50 return {};
51 }
52 if (!paramVersionFileInfo->found) {
53 MEDIA_ERR_LOG("not found, can not found version txt in path : %{public}s", cfgDir.c_str());
54 free(paramVersionFileInfo);
55 return {};
56 }
57 std::string path = std::string(paramVersionFileInfo->path);
58 MEDIA_INFO_LOG("GetConfigFilePath path:%{public}s", path.c_str());
59 free(paramVersionFileInfo);
60 return path;
61 #else
62 return PARAM_SERVICE_INSTALL_PATH + CAMERA_ROTATE_CFG_DIR;
63 #endif
64 };
65
66 // 获取路径下版本信息
GetPathVersion()67 std::string CameraRoateParamReader::GetPathVersion()
68 {
69 std::string path = GetConfigFilePath();
70 MEDIA_INFO_LOG("GetPathVersion:%{public}s", path.c_str());
71 return path.find(PARAM_UPDATE_ABS_PATH) != std::string::npos ?
72 GetVersionInfoStr(PARAM_SERVICE_INSTALL_PATH + CAMERA_ROTATE_CFG_DIR + VERSION_FILE_NAME) :
73 GetVersionInfoStr(CAMERA_ROTATE_CFG_DIR + VERSION_FILE_NAME); // 返回本地的默认路径system/etc/camera/
74 };
75
76 // 校验下载的参数文件是否合法
VerifyCertSfFile(const std::string & certFile,const std::string & verifyFile,const std::string & manifestFile)77 bool CameraRoateParamReader::VerifyCertSfFile(
78 const std::string &certFile, const std::string &verifyFile, const std::string &manifestFile)
79 {
80 char *canonicalPath = realpath(verifyFile.c_str(), nullptr);
81 CHECK_RETURN_RET(canonicalPath == nullptr, false);
82 // 验证CERT.SF文件是否合法
83 if (!CameraRoateParamSignTool::VerifyFileSign(PUBKEY_PATH, certFile, canonicalPath)) {
84 MEDIA_ERR_LOG("signToolManager verify failed %{public}s,%{public}s, %{public}s", PUBKEY_PATH.c_str(),
85 certFile.c_str(), canonicalPath);
86 return false;
87 }
88 std::ifstream file(canonicalPath);
89 free(canonicalPath);
90 if (!file.good()) {
91 MEDIA_ERR_LOG("Verify is not good,verifyFile:%{public}s", verifyFile.c_str());
92 return false;
93 };
94 std::string line;
95 std::string sha256Digest;
96 std::getline(file, line);
97 file.close();
98 sha256Digest = SplitStringWithPattern(line, ':')[1];
99 TrimString(sha256Digest);
100 std::tuple<int, std::string> ret = CameraRoateParamSignTool::CalcFileSha256Digest(manifestFile);
101 std::string manifestDigest = std::get<1>(ret);
102 if (sha256Digest == manifestDigest) {
103 return true;
104 }
105 return false;
106 };
107
108 // 校验下载的参数文件的完整性
VerifyParamFile(const std::string & cfgDirPath,const std::string & filePathStr)109 bool CameraRoateParamReader::VerifyParamFile(const std::string& cfgDirPath, const std::string &filePathStr)
110 {
111 char canonicalPath[PATH_MAX + 1] = {0x00};
112 CHECK_RETURN_RET_ELOG(realpath((cfgDirPath + filePathStr).c_str(), canonicalPath) == nullptr, false,
113 "VerifyParamFile filePathStr is irregular");
114 MEDIA_INFO_LOG("VerifyParamFile ,filePathStr:%{public}s", filePathStr.c_str());
115 std::string absFilePath = std::string(canonicalPath);
116 std::string manifestFile = cfgDirPath + "/MANIFEST.MF";
117 char *canonicalPathManifest = realpath(manifestFile.c_str(), nullptr);
118 CHECK_RETURN_RET(canonicalPathManifest == nullptr, false);
119 std::ifstream file(canonicalPathManifest);
120 free(canonicalPathManifest);
121 std::string line;
122 std::string sha256Digest;
123
124 CHECK_RETURN_RET_ELOG(
125 !file.good(), false, "manifestFile is not good,manifestFile:%{public}s", manifestFile.c_str());
126 std::ifstream paramFile(absFilePath);
127 CHECK_RETURN_RET_ELOG(
128 !paramFile.good(), false, "paramFile is not good,paramFile:%{public}s", absFilePath.c_str());
129
130 while (std::getline(file, line)) {
131 std::string nextline;
132 if (line.find("Name: " + filePathStr) != std::string::npos) {
133 std::getline(file, nextline);
134 sha256Digest = SplitStringWithPattern(nextline, ':')[1];
135 TrimString(sha256Digest);
136 break;
137 }
138 }
139 CHECK_RETURN_RET_ELOG(sha256Digest.empty(), false, "VerifyParamFile failed ,sha256Digest is empty");
140 std::tuple<int, std::string> ret = CameraRoateParamSignTool::CalcFileSha256Digest(absFilePath);
141 CHECK_RETURN_RET_ELOG(
142 std::get<0>(ret) != 0, false, "CalcFileSha256Digest failed,error : %{public}d ", std::get<0>(ret));
143 if (sha256Digest == std::get<1>(ret)) {
144 return true;
145 } else {
146 return false;
147 }
148 }
149
GetVersionInfoStr(const std::string & filePathStr)150 std::string CameraRoateParamReader::GetVersionInfoStr(const std::string &filePathStr)
151 {
152 char canonicalPath[PATH_MAX + 1] = {0x00};
153 CHECK_RETURN_RET_ELOG(realpath(filePathStr.c_str(), canonicalPath) == nullptr, DEFAULT_VERSION,
154 "GetVersionInfoStr filepath is irregular");
155 std::ifstream file(canonicalPath);
156 CHECK_RETURN_RET_ELOG(
157 !file.good(), DEFAULT_VERSION, "VersionFilePath is not good,FilePath:%{public}s", filePathStr.c_str());
158 std::string line;
159 std::getline(file, line);
160 std::string versionStr = SplitStringWithPattern(line, '=')[1];
161 TrimString(versionStr);
162 return versionStr;
163 };
164
VersionStrToNumber(const std::string & versionStr,std::vector<std::string> & versionNum)165 bool CameraRoateParamReader::VersionStrToNumber(const std::string &versionStr, std::vector<std::string> &versionNum)
166 {
167 versionNum.clear();
168 versionNum = SplitStringWithPattern(versionStr, '.');
169 return versionNum.size() == VERSION_LEN;
170 }
171
CompareVersion(const std::vector<std::string> & localVersion,const std::vector<std::string> & pathVersion)172 bool CameraRoateParamReader::CompareVersion(
173 const std::vector<std::string> &localVersion, const std::vector<std::string> &pathVersion)
174 {
175 CHECK_RETURN_RET_ELOG(
176 localVersion.size() != VERSION_LEN || pathVersion.size() != VERSION_LEN, false, "Version num not valid");
177 for (int i = 0; i < VERSION_LEN; i++) {
178 if (localVersion[i] != pathVersion[i]) {
179 int ret = strtol(localVersion[i].c_str(), nullptr, DEC) < strtol(pathVersion[i].c_str(), nullptr, DEC);
180 return ret;
181 }
182 }
183 return false;
184 }
185 // LCOV_EXCL_STOP
186 }
187 }
188