mirror of
https://gitee.com/openharmony/global_i18n
synced 2024-11-23 07:00:13 +00:00
libphonenumber upgrade
Signed-off-by: LY <liuyong235@huawei.com>
This commit is contained in:
parent
40aaae3584
commit
77008aa808
@ -67,6 +67,7 @@
|
||||
"libpng",
|
||||
"libxml2",
|
||||
"napi",
|
||||
"openssl",
|
||||
"preferences",
|
||||
"resource_management",
|
||||
"safwk",
|
||||
|
@ -47,16 +47,14 @@ ohos_shared_library("preferred_language") {
|
||||
"-fPIC",
|
||||
]
|
||||
deps = [ "//base/global/i18n/frameworks/intl:intl_util" ]
|
||||
external_deps = [
|
||||
"hilog:libhilog",
|
||||
"init:libbegetutil",
|
||||
]
|
||||
external_deps = [ "init:libbegetutil" ]
|
||||
if (i18n_support_app_preferred_language) {
|
||||
external_deps += [
|
||||
"ability_runtime:app_context",
|
||||
"bundle_framework:appexecfwk_base",
|
||||
"bundle_framework:appexecfwk_core",
|
||||
"c_utils:utils",
|
||||
"hilog:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"preferences:native_preferences",
|
||||
"resource_management:global_resmgr",
|
||||
@ -120,6 +118,7 @@ ohos_shared_library("intl_util") {
|
||||
"src/taboo.cpp",
|
||||
"src/taboo_utils.cpp",
|
||||
"src/utils.cpp",
|
||||
"src/verify_sign_tool.cpp",
|
||||
]
|
||||
version_script = "libintl_util.map"
|
||||
cflags_cc = [
|
||||
@ -162,7 +161,6 @@ ohos_shared_library("intl_util") {
|
||||
"access_token:libaccesstoken_sdk",
|
||||
"access_token:libtokenid_sdk",
|
||||
"c_utils:utils",
|
||||
"config_policy:configpolicy_util",
|
||||
"hilog:libhilog",
|
||||
"icu:icundk",
|
||||
"icu:shared_icui18n",
|
||||
@ -172,6 +170,9 @@ ohos_shared_library("intl_util") {
|
||||
"libphonenumber:phonenumber_standard",
|
||||
"libpng:libpng",
|
||||
"libxml2:libxml2",
|
||||
"openssl:libcrypto_shared",
|
||||
"openssl:libssl_shared",
|
||||
"preferences:native_preferences",
|
||||
]
|
||||
public_external_deps = []
|
||||
defines = []
|
||||
@ -183,6 +184,7 @@ ohos_shared_library("intl_util") {
|
||||
"ability_runtime:ability_manager",
|
||||
"ability_runtime:app_manager",
|
||||
"common_event_service:cesfwk_innerkits",
|
||||
"config_policy:configpolicy_util",
|
||||
]
|
||||
defines += [ "SUPPORT_GRAPHICS" ]
|
||||
}
|
||||
|
84
frameworks/intl/include/verify_sign_tool.h
Normal file
84
frameworks/intl/include/verify_sign_tool.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except", "in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef OHOS_GLOBAL_I18N_VERIFY_SIGN_TOOL_H
|
||||
#define OHOS_GLOBAL_I18N_VERIFY_SIGN_TOOL_H
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "preferences.h"
|
||||
#include "preferences_helper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
enum VerifyStatus {
|
||||
VERIFY_FAILED = 0,
|
||||
VERIFY_START = 1,
|
||||
VERIFY_SUCCESS = 2
|
||||
};
|
||||
|
||||
class VerifySignTool {
|
||||
public:
|
||||
static std::pair<int, int> Parse();
|
||||
|
||||
private:
|
||||
static VerifyStatus Verify();
|
||||
static bool VerifyCertFile();
|
||||
static bool VerifyConfigFiles();
|
||||
static bool VerifyDigest();
|
||||
static std::string VerifyParamFile(const std::string& filePath);
|
||||
static VerifyStatus VerifyCertAndConfig(std::string& version);
|
||||
static VerifyStatus GetVerifyInfo();
|
||||
|
||||
static bool VerifyFileSign(const std::string& pubkeyPath, const std::string& signPath,
|
||||
const std::string& digestPath);
|
||||
static bool VerifyRsa(RSA* pubkey, const std::string& digest, const std::string& sign);
|
||||
static std::string CalcFileSha256Digest(const std::string& path);
|
||||
static void CalcBase64(uint8_t* input, uint32_t inputLen, std::string& encodedStr);
|
||||
static int CalcFileShaOriginal(const std::string& filePath, unsigned char* hash, size_t len);
|
||||
|
||||
static std::string LoadFileVersion(std::string& versionPath);
|
||||
static int CompareVersion(std::string& preVersion, std::string& curVersion);
|
||||
|
||||
static bool IsLegalPath(const std::string& path);
|
||||
static void Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest);
|
||||
static std::string trim(std::string &s);
|
||||
static std::string GetFileStream(const std::string& filePath);
|
||||
static const int HASH_BUFFER_SIZE;
|
||||
static const int MIN_SIZE;
|
||||
static const int VERSION_SIZE;
|
||||
static const std::string VERSION_FILE;
|
||||
static const std::string METADATA_FILE;
|
||||
static const std::string GEOCODING_FILE;
|
||||
static const std::string CERT_FILE;
|
||||
static const std::string VERIFY_FILE;
|
||||
static const std::string MANIFEST_FILE;
|
||||
static const std::string CONFIG_TYPE;
|
||||
static const std::string SUB_TYPE;
|
||||
static const std::string CFG_PATH;
|
||||
static const std::string LOCALE_PATH;
|
||||
static const std::string PUBKEY_NAME;
|
||||
static const std::string PREFERENCE_PATH;
|
||||
static const std::string VERSION_NAME;
|
||||
static const std::string VERIFY_CERT_NAME;
|
||||
static const std::string METADATA_DIGEST_NAME;
|
||||
static const std::string GEOCODING_DIGEST_NAME;
|
||||
static std::shared_ptr<NativePreferences::Preferences> preferences;
|
||||
};
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
} // namespace OHOS
|
||||
#endif
|
473
frameworks/intl/src/verify_sign_tool.cpp
Normal file
473
frameworks/intl/src/verify_sign_tool.cpp
Normal file
@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <fcntl.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
#include "verify_sign_tool.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Global {
|
||||
namespace I18n {
|
||||
namespace {
|
||||
const int32_t BASE64_ENCODE_PACKET_LEN = 3;
|
||||
const int32_t BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA = 4;
|
||||
}
|
||||
|
||||
const int VerifySignTool::HASH_BUFFER_SIZE = 4096;
|
||||
const int VerifySignTool::MIN_SIZE = 2;
|
||||
const int VerifySignTool::VERSION_SIZE = 4;
|
||||
const std::string VerifySignTool::VERSION_FILE = "version.txt";
|
||||
const std::string VerifySignTool::METADATA_FILE = "MetadataInfo";
|
||||
const std::string VerifySignTool::GEOCODING_FILE = "GeocodingInfo";
|
||||
const std::string VerifySignTool::CERT_FILE = "CERT.ENC";
|
||||
const std::string VerifySignTool::VERIFY_FILE = "CERT.SF";
|
||||
const std::string VerifySignTool::MANIFEST_FILE = "MANIFEST.MF";
|
||||
const std::string VerifySignTool::CONFIG_TYPE = "LIBPHONENUMBER";
|
||||
const std::string VerifySignTool::SUB_TYPE = "generic";
|
||||
const std::string VerifySignTool::CFG_PATH =
|
||||
"/data/service/el1/public/update/param_service/install/system/etc/LIBPHONENUMBER/generic/";
|
||||
const std::string VerifySignTool::LOCALE_PATH = "/system/etc/LIBPHONENUMBER/generic/";
|
||||
const std::string VerifySignTool::PUBKEY_NAME = "hota_i18n_upgrade_v1.pem";
|
||||
const std::string VerifySignTool::PREFERENCE_PATH = "/data/service/el1/public/i18n/libphonenumber";
|
||||
const std::string VerifySignTool::VERSION_NAME = "version";
|
||||
const std::string VerifySignTool::VERIFY_CERT_NAME = "verify_cert";
|
||||
const std::string VerifySignTool::METADATA_DIGEST_NAME = "metadata_digest";
|
||||
const std::string VerifySignTool::GEOCODING_DIGEST_NAME = "geocoding_digest";
|
||||
std::shared_ptr<NativePreferences::Preferences> VerifySignTool::preferences = nullptr;
|
||||
|
||||
std::pair<int, int> VerifySignTool::Parse()
|
||||
{
|
||||
std::pair<int, int> fds = {-1, -1};
|
||||
VerifyStatus status = Verify();
|
||||
if (status == VERIFY_FAILED) {
|
||||
return fds;
|
||||
} else if (status == VERIFY_START) {
|
||||
if (!VerifyDigest()) {
|
||||
return fds;
|
||||
}
|
||||
}
|
||||
std::string metadataPath = CFG_PATH + METADATA_FILE;
|
||||
int metadataFd = open(metadataPath.c_str(), O_RDONLY);
|
||||
std::string geocodingPath = CFG_PATH + GEOCODING_FILE;
|
||||
int geocodingFd = open(geocodingPath.c_str(), O_RDONLY);
|
||||
fds.first = metadataFd;
|
||||
fds.second = geocodingFd;
|
||||
return fds;
|
||||
}
|
||||
|
||||
// verify MetadataInfo/GeocodingInfo digest
|
||||
bool VerifySignTool::VerifyDigest()
|
||||
{
|
||||
std::string metadataDigest = preferences->GetString(METADATA_DIGEST_NAME, "");
|
||||
if (metadataDigest.length() != 0) {
|
||||
std::string metadataPath = CFG_PATH + METADATA_FILE;
|
||||
if (CalcFileSha256Digest(metadataPath) != metadataDigest) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string geocodingDigest = preferences->GetString(GEOCODING_DIGEST_NAME, "");
|
||||
if (geocodingDigest.length() != 0) {
|
||||
std::string geocodingPath = CFG_PATH + GEOCODING_FILE;
|
||||
if (CalcFileSha256Digest(geocodingPath) != geocodingDigest) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// verify all update file
|
||||
VerifyStatus VerifySignTool::Verify()
|
||||
{
|
||||
std::string versionUpdatePath = CFG_PATH + VERSION_FILE;
|
||||
std::string versionUpdate = LoadFileVersion(versionUpdatePath);
|
||||
if (versionUpdate.length() == 0) {
|
||||
return VERIFY_FAILED;
|
||||
}
|
||||
std::string versionLocalePath = LOCALE_PATH + VERSION_FILE;
|
||||
std::string versionLocale = LoadFileVersion(versionLocalePath);
|
||||
if (versionLocale.length() == 0) {
|
||||
return VERIFY_FAILED;
|
||||
}
|
||||
int status;
|
||||
if (preferences == nullptr) {
|
||||
OHOS::NativePreferences::Options opt(PREFERENCE_PATH);
|
||||
preferences = NativePreferences::PreferencesHelper::GetPreferences(opt, status);
|
||||
if (status != 0) {
|
||||
preferences = nullptr;
|
||||
}
|
||||
}
|
||||
status = CompareVersion(versionLocale, versionUpdate);
|
||||
if (status <= 0) {
|
||||
return VERIFY_FAILED;
|
||||
} else {
|
||||
std::string versionPrefer = preferences->GetString(VERSION_NAME, "");
|
||||
status = CompareVersion(versionPrefer, versionUpdate);
|
||||
if (versionPrefer == "" || status > 0) {
|
||||
return VerifyCertAndConfig(versionUpdate);
|
||||
} else if (status == 0) {
|
||||
return GetVerifyInfo();
|
||||
}
|
||||
}
|
||||
return VERIFY_FAILED;
|
||||
}
|
||||
|
||||
std::string VerifySignTool::LoadFileVersion(std::string& versionPath)
|
||||
{
|
||||
std::string version;
|
||||
if (!std::filesystem::exists(versionPath.c_str())) {
|
||||
return version;
|
||||
}
|
||||
std::ifstream file(versionPath);
|
||||
std::string line;
|
||||
std::vector<std::string> strs;
|
||||
while (std::getline(file, line)) {
|
||||
Split(line, "=", strs);
|
||||
if (strs.size() < MIN_SIZE) {
|
||||
continue;
|
||||
}
|
||||
if (strs[0] == VERSION_NAME) {
|
||||
version = trim(strs[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return version;
|
||||
}
|
||||
|
||||
// compare version
|
||||
int VerifySignTool::CompareVersion(std::string& preVersion, std::string& curVersion)
|
||||
{
|
||||
std::vector<std::string> preVersionstr;
|
||||
std::vector<std::string> curVersionstr;
|
||||
Split(preVersion, ".", preVersionstr);
|
||||
Split(curVersion, ".", curVersionstr);
|
||||
if (curVersionstr.size() != VERSION_SIZE || preVersionstr.size() != VERSION_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < VERSION_SIZE; i++) {
|
||||
if (atoi(preVersionstr.at(i).c_str()) < atoi(curVersionstr.at(i).c_str())) {
|
||||
return 1;
|
||||
} else if (atoi(preVersionstr.at(i).c_str()) > atoi(curVersionstr.at(i).c_str())) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// determine if the certificate file has been verified
|
||||
VerifyStatus VerifySignTool::GetVerifyInfo()
|
||||
{
|
||||
bool isVerifyCert = false;
|
||||
if (preferences != nullptr) {
|
||||
isVerifyCert = preferences->GetBool(VERIFY_CERT_NAME, false);
|
||||
}
|
||||
return isVerifyCert ? VERIFY_START : VERIFY_FAILED;
|
||||
}
|
||||
|
||||
// verify certificate file and config file
|
||||
VerifyStatus VerifySignTool::VerifyCertAndConfig(std::string& version)
|
||||
{
|
||||
int status;
|
||||
if (VerifyCertFile() && VerifyConfigFiles()) {
|
||||
if (preferences != nullptr) {
|
||||
status = preferences->PutBool(VERIFY_CERT_NAME, true);
|
||||
if (status == 0) {
|
||||
preferences->PutString(VERSION_NAME, version);
|
||||
}
|
||||
preferences->Flush();
|
||||
}
|
||||
return VERIFY_SUCCESS;
|
||||
} else {
|
||||
if (preferences != nullptr) {
|
||||
status = preferences->PutBool(VERIFY_CERT_NAME, false);
|
||||
if (status == 0) {
|
||||
preferences->PutString(VERSION_NAME, version);
|
||||
}
|
||||
preferences->Flush();
|
||||
}
|
||||
return VERIFY_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
// // verify certificate file
|
||||
bool VerifySignTool::VerifyCertFile()
|
||||
{
|
||||
std::string certPath = CFG_PATH + CERT_FILE;
|
||||
std::string verifyPath = CFG_PATH + VERIFY_FILE;
|
||||
std::string pubkeyPath = LOCALE_PATH + PUBKEY_NAME;
|
||||
if (!VerifyFileSign(pubkeyPath, certPath, verifyPath)) {
|
||||
return false;
|
||||
}
|
||||
std::ifstream file(verifyPath);
|
||||
if (!file.good()) {
|
||||
return false;
|
||||
}
|
||||
std::string line;
|
||||
std::string sha256Digest;
|
||||
std::getline(file, line);
|
||||
file.close();
|
||||
std::vector<std::string> strs;
|
||||
Split(line, ":", strs);
|
||||
if (strs.size() < MIN_SIZE) {
|
||||
return false;
|
||||
}
|
||||
sha256Digest = strs[1];
|
||||
sha256Digest = trim(sha256Digest);
|
||||
std::string manifestPath = CFG_PATH + MANIFEST_FILE;
|
||||
std::string manifestDigest = CalcFileSha256Digest(manifestPath);
|
||||
if (sha256Digest == manifestDigest) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify config file
|
||||
bool VerifySignTool::VerifyConfigFiles()
|
||||
{
|
||||
std::string versionPath = CFG_PATH + VERSION_FILE;
|
||||
if (!std::filesystem::exists(versionPath.c_str())) {
|
||||
return false;
|
||||
}
|
||||
if (VerifyParamFile(VERSION_FILE).length() == 0) {
|
||||
return false;
|
||||
}
|
||||
std::string metadataPath = CFG_PATH + METADATA_FILE;
|
||||
std::string metadataDigest = VerifyParamFile(METADATA_FILE);
|
||||
if (std::filesystem::exists(metadataPath.c_str()) && metadataDigest.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
std::string geocodingDigest = VerifyParamFile(GEOCODING_FILE);
|
||||
std::string geocodingPath = CFG_PATH + GEOCODING_FILE;
|
||||
if (std::filesystem::exists(geocodingPath.c_str()) && geocodingDigest.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (preferences != nullptr) {
|
||||
if (metadataDigest.length() != 0) {
|
||||
preferences->PutString(METADATA_DIGEST_NAME, metadataDigest);
|
||||
}
|
||||
if (geocodingDigest.length() != 0) {
|
||||
preferences->PutString(GEOCODING_DIGEST_NAME, geocodingDigest);
|
||||
}
|
||||
preferences->Flush();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// verify param file digest
|
||||
std::string VerifySignTool::VerifyParamFile(const std::string& filePath)
|
||||
{
|
||||
std::string manifestPath = CFG_PATH + MANIFEST_FILE;
|
||||
std::ifstream file(manifestPath);
|
||||
if (!file.good()) {
|
||||
return "";
|
||||
}
|
||||
std::string absFilePath = CFG_PATH + filePath;
|
||||
std::ifstream paramFile(absFilePath);
|
||||
if (!paramFile.good()) {
|
||||
return "";
|
||||
}
|
||||
std::string sha256Digest;
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
std::string nextLine;
|
||||
if (line.find("Name: " + filePath) != std::string::npos) {
|
||||
std::getline(file, nextLine);
|
||||
std::vector<std::string> strs;
|
||||
Split(nextLine, ":", strs);
|
||||
if (strs.size() < MIN_SIZE) {
|
||||
return "";
|
||||
}
|
||||
sha256Digest = strs[1];
|
||||
sha256Digest = trim(sha256Digest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sha256Digest.empty()) {
|
||||
return "";
|
||||
}
|
||||
std::string fileDigest = CalcFileSha256Digest(absFilePath);
|
||||
if (fileDigest == sha256Digest) {
|
||||
return fileDigest;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string VerifySignTool::trim(std::string &s)
|
||||
{
|
||||
if (s.empty()) {
|
||||
return s;
|
||||
}
|
||||
s.erase(0, s.find_first_not_of(" "));
|
||||
s.erase(s.find_last_not_of(" ") + 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
// verify cert file sign
|
||||
bool VerifySignTool::VerifyFileSign(const std::string& pubkeyPath, const std::string& signPath,
|
||||
const std::string& digestPath)
|
||||
{
|
||||
if (!std::filesystem::exists(pubkeyPath.c_str())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(signPath.c_str())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(digestPath.c_str())) {
|
||||
return false;
|
||||
}
|
||||
std::string signStr = GetFileStream(signPath);
|
||||
std::string digestStr = GetFileStream(digestPath);
|
||||
RSA* pubkey = RSA_new();
|
||||
bool verify = false;
|
||||
if (pubkey != nullptr && !signStr.empty() && !digestStr.empty()) {
|
||||
BIO* bio = BIO_new_file(pubkeyPath.c_str(), "r");
|
||||
if (PEM_read_bio_RSA_PUBKEY(bio, &pubkey, nullptr, nullptr) == nullptr) {
|
||||
BIO_free(bio);
|
||||
return false;
|
||||
}
|
||||
verify = VerifyRsa(pubkey, digestStr, signStr);
|
||||
BIO_free(bio);
|
||||
}
|
||||
RSA_free(pubkey);
|
||||
return verify;
|
||||
}
|
||||
|
||||
bool VerifySignTool::VerifyRsa(RSA* pubkey, const std::string& digest, const std::string& sign)
|
||||
{
|
||||
EVP_PKEY* evpKey = EVP_PKEY_new();
|
||||
if (evpKey == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (EVP_PKEY_set1_RSA(evpKey, pubkey) != 1) {
|
||||
return false;
|
||||
}
|
||||
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
|
||||
EVP_MD_CTX_init(ctx);
|
||||
if (ctx == nullptr) {
|
||||
EVP_PKEY_free(evpKey);
|
||||
return false;
|
||||
}
|
||||
if (EVP_VerifyInit_ex(ctx, EVP_sha256(), nullptr) != 1) {
|
||||
EVP_PKEY_free(evpKey);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return false;
|
||||
}
|
||||
if (EVP_VerifyUpdate(ctx, digest.c_str(), digest.size()) != 1) {
|
||||
EVP_PKEY_free(evpKey);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return false;
|
||||
}
|
||||
if (EVP_VerifyFinal(ctx, (unsigned char *)sign.c_str(), sign.size(), evpKey) != 1) {
|
||||
EVP_PKEY_free(evpKey);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return false;
|
||||
}
|
||||
EVP_PKEY_free(evpKey);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string VerifySignTool::CalcFileSha256Digest(const std::string& path)
|
||||
{
|
||||
unsigned char res[SHA256_DIGEST_LENGTH] = {0};
|
||||
CalcFileShaOriginal(path, res, SHA256_DIGEST_LENGTH);
|
||||
std::string dist;
|
||||
CalcBase64(res, SHA256_DIGEST_LENGTH, dist);
|
||||
return dist;
|
||||
}
|
||||
|
||||
void VerifySignTool::CalcBase64(uint8_t* input, uint32_t inputLen, std::string& encodedStr)
|
||||
{
|
||||
size_t base64Len = static_cast<size_t>(ceil(static_cast<long double>(inputLen) / BASE64_ENCODE_PACKET_LEN) *
|
||||
BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA + 1);
|
||||
std::unique_ptr<unsigned char[]> base64Str = std::make_unique<unsigned char[]>(base64Len);
|
||||
size_t outLen = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64Str.get()), input, inputLen);
|
||||
encodedStr = std::string(reinterpret_cast<char*>(base64Str.get()), outLen);
|
||||
}
|
||||
|
||||
int VerifySignTool::CalcFileShaOriginal(const std::string& filePath, unsigned char* hash, size_t len)
|
||||
{
|
||||
if (filePath.empty() || hash == nullptr || !IsLegalPath(filePath) || len < SHA256_DIGEST_LENGTH) {
|
||||
return -1;
|
||||
}
|
||||
FILE* fp = fopen(filePath.c_str(), "rb");
|
||||
if (fp == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
size_t n;
|
||||
char buffer[HASH_BUFFER_SIZE] = {0};
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init(&ctx);
|
||||
while ((n = fread(buffer, 1, sizeof(buffer), fp))) {
|
||||
SHA256_Update(&ctx, (unsigned char*)buffer, n);
|
||||
}
|
||||
SHA256_Final(hash, &ctx);
|
||||
if (fclose(fp) == -1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// load file content
|
||||
std::string VerifySignTool::GetFileStream(const std::string& filePath)
|
||||
{
|
||||
std::ifstream file(filePath, std::ios::in | std::ios::binary);
|
||||
if (!file) {
|
||||
return "";
|
||||
}
|
||||
std::stringstream inFile;
|
||||
inFile << file.rdbuf();
|
||||
return inFile.str();
|
||||
}
|
||||
|
||||
bool VerifySignTool::IsLegalPath(const std::string& path)
|
||||
{
|
||||
if (path.find("./") != std::string::npos ||
|
||||
path.find("../") != std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void VerifySignTool::Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest)
|
||||
{
|
||||
if (src == "") {
|
||||
return;
|
||||
}
|
||||
std::string::size_type begin = 0;
|
||||
std::string::size_type end = src.find(sep);
|
||||
while (end != std::string::npos) {
|
||||
dest.push_back(src.substr(begin, end - begin));
|
||||
begin = end + sep.size();
|
||||
end = src.find(sep, begin);
|
||||
}
|
||||
if (begin != src.size()) {
|
||||
dest.push_back(src.substr(begin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -81,6 +81,9 @@ ohos_shared_library("i18n_sa") {
|
||||
"eventhandler:libeventhandler",
|
||||
"hilog:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"openssl:libcrypto_shared",
|
||||
"openssl:libssl_shared",
|
||||
"preferences:native_preferences",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr:samgr_proxy",
|
||||
]
|
||||
|
@ -1,4 +1,12 @@
|
||||
{
|
||||
"jobs" : [
|
||||
{
|
||||
"name": "boot",
|
||||
"cmds": [
|
||||
"mkdir /data/service/el1/public/i18n/ 0777 i18n_service i18n_service"
|
||||
]
|
||||
}
|
||||
],
|
||||
"services" : [
|
||||
{
|
||||
"name": "i18n_service",
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
I18nErrorCode SetUsingLocalDigit(bool flag) override;
|
||||
I18nErrorCode AddPreferredLanguage(const std::string &language, int32_t index) override;
|
||||
I18nErrorCode RemovePreferredLanguage(int32_t index) override;
|
||||
|
||||
std::pair<int, int> VerifyLibphonenumberUpdate() override;
|
||||
/**
|
||||
* @brief Trigger unload i18n service after one request finished, but service will not unload
|
||||
* until there no request in 10s.
|
||||
|
@ -89,6 +89,13 @@ public:
|
||||
*/
|
||||
static I18nErrorCode RemovePreferredLanguage(int32_t index);
|
||||
|
||||
/**
|
||||
* @brief Verify the libphonenumber upgrade file.
|
||||
*
|
||||
* @return corresponding file descriptor {metadataFd, geocodingFd}.
|
||||
*/
|
||||
static std::pair<int, int> VerifyLibphonenumberUpdate();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Get the proxy of i18n service to access service.
|
||||
|
@ -91,6 +91,13 @@ public:
|
||||
*/
|
||||
I18nErrorCode RemovePreferredLanguage(int32_t index);
|
||||
|
||||
/**
|
||||
* @brief Verify the libphonenumber upgrade file.
|
||||
*
|
||||
* @return corresponding file descriptor {metadataFd, geocodingFd}.
|
||||
*/
|
||||
std::pair<int, int> VerifyLibphonenumberUpdate();
|
||||
|
||||
private:
|
||||
static I18nErrorCode ProcessReply(int32_t reply);
|
||||
static inline BrokerDelegator<I18nServiceAbilityProxy> delegator_;
|
||||
|
@ -73,6 +73,7 @@ private:
|
||||
int32_t SetUsingLocalDigitInner(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t AddPreferredLanguageInner(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t RemovePreferredLanguageInner(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t VerifyLibphonenumberUpdateInner(MessageParcel &data, MessageParcel &reply);
|
||||
};
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
virtual I18nErrorCode SetUsingLocalDigit(bool flag) = 0;
|
||||
virtual I18nErrorCode AddPreferredLanguage(const std::string &language, int32_t index) = 0;
|
||||
virtual I18nErrorCode RemovePreferredLanguage(int32_t index) = 0;
|
||||
virtual std::pair<int, int> VerifyLibphonenumberUpdate() = 0;
|
||||
|
||||
// I18n service request code.
|
||||
enum class ILocaleConfigAbilityCode {
|
||||
@ -43,6 +44,7 @@ public:
|
||||
SET_USING_LOCAL_DIGIT = 4,
|
||||
ADD_PREFERRED_LANGUAGE = 5,
|
||||
REMOVE_PREFERRED_LANGUAGE = 6,
|
||||
VERIFY_LIBPHONENUMBER_UPDATE = 7,
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.global.II18nServiceAbility");
|
||||
|
@ -17,7 +17,10 @@
|
||||
#include "i18n_service_ability_load_manager.h"
|
||||
#include "locale_config.h"
|
||||
#include "preferred_language.h"
|
||||
#include "preferences.h"
|
||||
#include "preferences_helper.h"
|
||||
#include "system_ability_definition.h"
|
||||
#include "verify_sign_tool.h"
|
||||
#include "i18n_service_ability.h"
|
||||
|
||||
namespace OHOS {
|
||||
@ -72,6 +75,11 @@ I18nErrorCode I18nServiceAbility::RemovePreferredLanguage(int32_t index)
|
||||
return PreferredLanguage::RemovePreferredLanguage(index);
|
||||
}
|
||||
|
||||
std::pair<int, int> I18nServiceAbility::VerifyLibphonenumberUpdate()
|
||||
{
|
||||
return VerifySignTool::Parse();
|
||||
}
|
||||
|
||||
void I18nServiceAbility::UnloadI18nServiceAbility()
|
||||
{
|
||||
if (handler != nullptr) {
|
||||
|
@ -106,6 +106,23 @@ I18nErrorCode I18nServiceAbilityClient::RemovePreferredLanguage(int32_t index)
|
||||
}
|
||||
return i18nServiceAbilityObj->RemovePreferredLanguage(index);
|
||||
}
|
||||
|
||||
std::pair<int, int> I18nServiceAbilityClient::VerifyLibphonenumberUpdate()
|
||||
{
|
||||
I18nErrorCode err = I18nErrorCode::SUCCESS;
|
||||
sptr<II18nServiceAbility> i18nServiceAbilityObj = GetProxy(err);
|
||||
if (i18nServiceAbilityObj == nullptr) {
|
||||
return {-1, -1};
|
||||
}
|
||||
return i18nServiceAbilityObj->VerifyLibphonenumberUpdate();
|
||||
}
|
||||
|
||||
extern "C" void VerifyLibphonenumberUpdate(int* metadataFd, int* geocodingFd)
|
||||
{
|
||||
std::pair<int, int> fds = I18nServiceAbilityClient::VerifyLibphonenumberUpdate();
|
||||
*metadataFd = fds.first;
|
||||
*geocodingFd = fds.second;
|
||||
}
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
} // namespace OHOS
|
@ -112,6 +112,20 @@ I18nErrorCode I18nServiceAbilityProxy::RemovePreferredLanguage(int32_t index)
|
||||
return ProcessReply(reply.ReadInt32());
|
||||
}
|
||||
|
||||
std::pair<int, int> I18nServiceAbilityProxy::VerifyLibphonenumberUpdate()
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
data.WriteInterfaceToken(DESCRIPTOR);
|
||||
Remote()->SendRequest(static_cast<uint32_t>(ILocaleConfigAbilityCode::VERIFY_LIBPHONENUMBER_UPDATE),
|
||||
data, reply, option);
|
||||
int metadataFd = reply.ReadFileDescriptor();
|
||||
int geocodingFd = reply.ReadFileDescriptor();
|
||||
std::pair<int, int> fds = {metadataFd, geocodingFd};
|
||||
return fds;
|
||||
}
|
||||
|
||||
I18nErrorCode I18nServiceAbilityProxy::ProcessReply(int32_t reply)
|
||||
{
|
||||
I18nErrorCode err = static_cast<I18nErrorCode>(reply);
|
||||
|
@ -82,6 +82,8 @@ void I18nServiceAbilityStub::InitInnerFuncMap()
|
||||
&I18nServiceAbilityStub::AddPreferredLanguageInner;
|
||||
innerFuncMap[static_cast<uint32_t>(ILocaleConfigAbilityCode::REMOVE_PREFERRED_LANGUAGE)] =
|
||||
&I18nServiceAbilityStub::RemovePreferredLanguageInner;
|
||||
innerFuncMap[static_cast<uint32_t>(ILocaleConfigAbilityCode::VERIFY_LIBPHONENUMBER_UPDATE)] =
|
||||
&I18nServiceAbilityStub::VerifyLibphonenumberUpdateInner;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -228,6 +230,14 @@ int32_t I18nServiceAbilityStub::RemovePreferredLanguageInner(MessageParcel &data
|
||||
reply.WriteInt32(static_cast<int32_t>(err));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t I18nServiceAbilityStub::VerifyLibphonenumberUpdateInner(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
std::pair<int, int> fds = VerifyLibphonenumberUpdate();
|
||||
reply.WriteFileDescriptor(fds.first);
|
||||
reply.WriteFileDescriptor(fds.second);
|
||||
return 0;
|
||||
}
|
||||
} // namespace I18n
|
||||
} // namespace Global
|
||||
} // namespace OHOS
|
Loading…
Reference in New Issue
Block a user