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 23namespace OHOS { 24namespace Global { 25namespace I18n { 26namespace { 27const std::string CUST_GLOBAL_CARRIER_DIR = "/system/etc/LIBPHONENUMBER/mount_dir/"; 28const std::string VERSION_FILE = "version.txt"; 29const std::string CERT_FILE = "CERT.ENC"; 30const std::string VERIFY_FILE = "CERT.SF"; 31const std::string MANIFEST_FILE = "MANIFEST.MF"; 32const std::string SUB_TYPE = "generic"; 33const std::string CFG_PATH = 34 "/data/service/el1/public/update/param_service/install/system/etc/LIBPHONENUMBER/generic/"; 35const std::string LOCALE_PATH = "/system/etc/LIBPHONENUMBER/generic/"; 36const std::string SAFE_PATH = "/data/service/el1/public/i18n/libphonenumber/"; 37const std::string PUBKEY_NAME = "hota_i18n_upgrade_v1.pem"; 38const std::vector<std::string> DATA_FILES = {"GeocodingInfo", "MetadataInfo"}; 39} 40 41bool 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 62void 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 82bool 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 98bool 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 122void 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 147int main(int argc, char *argv[]) 148{ 149 HILOG_INFO_I18N("hmos_libphonenumber_mount: UpdateLibphonenumber start"); 150 OHOS::Global::I18n::UpdateLibphonenumber(); 151 return 0; 152}