1 /*
2 * Copyright (c) 2024 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 #include <filesystem>
16 #include <string>
17 #include <sys/mount.h>
18 #include "i18n_hilog.h"
19 #include "signature_verifier.h"
20 #include "utils.h"
21
22
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 namespace {
27 const std::string CUST_GLOBAL_CARRIER_DIR = "/system/etc/LIBPHONENUMBER/mount_dir/";
28 const std::string VERSION_FILE = "version.txt";
29 const std::string CERT_FILE = "CERT.ENC";
30 const std::string VERIFY_FILE = "CERT.SF";
31 const std::string MANIFEST_FILE = "MANIFEST.MF";
32 const std::string SUB_TYPE = "generic";
33 const std::string CFG_PATH =
34 "/data/service/el1/public/update/param_service/install/system/etc/LIBPHONENUMBER/generic/";
35 const std::string LOCALE_PATH = "/system/etc/LIBPHONENUMBER/generic/";
36 const std::string SAFE_PATH = "/data/service/el1/public/i18n/libphonenumber/";
37 const std::string PUBKEY_NAME = "hota_i18n_upgrade_v1.pem";
38 const std::vector<std::string> DATA_FILES = {"GeocodingInfo", "MetadataInfo"};
39 }
40
Mount()41 bool Mount()
42 {
43 if (!IsDirExist(CUST_GLOBAL_CARRIER_DIR.c_str()) ||
44 !IsDirExist(SAFE_PATH.c_str())) {
45 HILOG_ERROR_I18N("Mount: CUST_GLOBAL_CARRIER_DIR or CFG_PATH not exist");
46 return false;
47 }
48
49 std::string cotaOpkeyVersionDir = SAFE_PATH;
50 std::string custOpkeyVersionDir = CUST_GLOBAL_CARRIER_DIR;
51
52 if (mount(cotaOpkeyVersionDir.c_str(), custOpkeyVersionDir.c_str(), nullptr, MS_BIND, nullptr) != 0) {
53 HILOG_ERROR_I18N("Mount: fail to mount: opkey(%{public}s) errno(%{public}s)",
54 cotaOpkeyVersionDir.c_str(), strerror(errno));
55 return false;
56 } else {
57 HILOG_INFO_I18N("Mount: success to mount cotaDir to custDir: opkey(%{public}s)", cotaOpkeyVersionDir.c_str());
58 }
59 return true;
60 }
61
CopyDataFile()62 void CopyDataFile()
63 {
64 if (!IsDirExist(SAFE_PATH.c_str())) {
65 HILOG_INFO_I18N("CopyDataFile: SAFE_PATH not exist");
66 return;
67 }
68
69 for (size_t i = 0; i < DATA_FILES.size(); i++) {
70 std::string srcPath = CFG_PATH + DATA_FILES[i];
71 std::string dstPath = SAFE_PATH + DATA_FILES[i];
72 if (!FileExist(srcPath)) {
73 HILOG_INFO_I18N("CopyDataFile: %{public}s not exist", DATA_FILES[i].c_str());
74 continue;
75 }
76 if (!FileCopy(srcPath, dstPath)) {
77 HILOG_INFO_I18N("CopyDataFile: copy %{public}s failed", DATA_FILES[i].c_str());
78 }
79 }
80 }
81
CheckIfUpdateNecessary()82 bool CheckIfUpdateNecessary()
83 {
84 std::string versionUpdate = SignatureVerifier::LoadFileVersion(CFG_PATH + VERSION_FILE);
85 std::string versionLocale = SignatureVerifier::LoadFileVersion(LOCALE_PATH + VERSION_FILE);
86 HILOG_INFO_I18N("CheckIfUpdateNecessary: Verify: versionUpdate(%{public}s) versionLocale(%{public}s)",
87 versionUpdate.c_str(), versionLocale.c_str());
88
89 if (versionLocale.length() == 0 || versionUpdate.length() == 0) {
90 return false;
91 }
92 if (SignatureVerifier::CompareVersion(versionLocale, versionUpdate) <= 0) {
93 return false;
94 }
95 return true;
96 }
97
CheckFileIntegrity()98 bool CheckFileIntegrity()
99 {
100 std::string certPath = CFG_PATH + CERT_FILE;
101 std::string verifyPath = CFG_PATH + VERIFY_FILE;
102 std::string pubkeyPath = LOCALE_PATH + PUBKEY_NAME;
103 std::string manifestPath = CFG_PATH + MANIFEST_FILE;
104 if (!SignatureVerifier::VerifyCertFile(certPath, verifyPath, pubkeyPath, manifestPath)) {
105 HILOG_ERROR_I18N("CheckFileIntegrity: VerifyCertFile error");
106 return false;
107 }
108
109 for (size_t i = 0; i < DATA_FILES.size(); i++) {
110 HILOG_ERROR_I18N("CheckFileIntegrity: file to verify (%{public}s)", DATA_FILES[i].c_str());
111 std::string filePath = CFG_PATH + DATA_FILES[i];
112 if (FileExist(filePath.c_str()) &&
113 !SignatureVerifier::VerifyParamFile(DATA_FILES[i], CFG_PATH, manifestPath)) {
114 HILOG_ERROR_I18N("CheckFileIntegrity: VerifyParamFile error");
115 return false;
116 }
117 }
118
119 return true;
120 }
121
UpdateLibphonenumber()122 void UpdateLibphonenumber()
123 {
124 if (!CheckIfUpdateNecessary()) {
125 HILOG_INFO_I18N("UpdateLibphonenumber: CheckIfUpdateNecessary error, no need to update");
126 return;
127 }
128 if (!CheckFileIntegrity()) {
129 HILOG_INFO_I18N("UpdateLibphonenumber: CheckFileIntegrity error, no need to update");
130 return;
131 }
132
133 CopyDataFile();
134
135 if (!Mount()) {
136 HILOG_INFO_I18N("UpdateLibphonenumber: mount error");
137 return;
138 }
139
140 HILOG_INFO_I18N("UpdateLibphonenumber: UpdateLibphonenumber");
141 }
142
143 }
144 }
145 }
146
main(int argc,char * argv[])147 int main(int argc, char *argv[])
148 {
149 HILOG_INFO_I18N("hmos_libphonenumber_mount: UpdateLibphonenumber start");
150 OHOS::Global::I18n::UpdateLibphonenumber();
151 return 0;
152 }