1 /*
2 * Copyright (c) 2023-2023 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 "log_sign_tools.h"
17
18 #include "calc_fingerprint.h"
19 #include "file_util.h"
20 #include "logger.h"
21
22 namespace OHOS {
23 namespace HiviewDFX {
24 DEFINE_LOG_TAG("Hiview-ParamUpdate");
25
26 namespace {
27 const int32_t BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA = 4;
28 const int32_t BASE64_ENCODE_PACKET_LEN = 3;
29 }
30
VerifyFileSign(const std::string & pubKeyPath,const std::string & signPath,const std::string & digestPath)31 bool LogSignTools::VerifyFileSign(const std::string &pubKeyPath, const std::string &signPath,
32 const std::string &digestPath)
33 {
34 if (!FileUtil::FileExists(pubKeyPath)) {
35 HIVIEW_LOGE("pubKey file not exist");
36 return false;
37 }
38
39 if (!FileUtil::FileExists(signPath)) {
40 HIVIEW_LOGE("sign file not exist");
41 return false;
42 }
43
44 if (!FileUtil::FileExists(digestPath)) {
45 HIVIEW_LOGE("digest file not exist");
46 return false;
47 }
48
49 std::string signStr;
50 FileUtil::LoadStringFromFile(signPath, signStr);
51 std::string digestStr;
52 FileUtil::LoadStringFromFile(digestPath, digestStr);
53 RSA *pubKey = RSA_new();
54 bool verify = false;
55 if (!(pubKey == nullptr || signStr.empty() || digestStr.empty())) {
56 BIO *bio = BIO_new_file(pubKeyPath.c_str(), "r");
57 if (PEM_read_bio_RSA_PUBKEY(bio, &pubKey, nullptr, nullptr) == nullptr) {
58 HIVIEW_LOGE("get pubKey is failed.");
59 BIO_free(bio);
60 return false;
61 }
62 verify = VerifyRsa(pubKey, digestStr, signStr);
63 BIO_free(bio);
64 } else {
65 HIVIEW_LOGE("pubKey or signStr or digestStr is error.");
66 }
67 RSA_free(pubKey);
68 return verify;
69 }
70
CalcFileSha256Digest(const std::string & fpath)71 std::string LogSignTools::CalcFileSha256Digest(const std::string &fpath)
72 {
73 unsigned char res[SHA256_DIGEST_LENGTH] = {0};
74 CalcFingerprint::CalcFileShaOriginal(fpath, res, SHA256_DIGEST_LENGTH);
75 std::string dist;
76 CalcBase64(res, SHA256_DIGEST_LENGTH, dist);
77 return dist;
78 }
79
CalcBase64(uint8_t * input,uint32_t inputLen,std::string & encodedStr)80 void LogSignTools::CalcBase64(uint8_t *input, uint32_t inputLen, std::string &encodedStr)
81 {
82 size_t base64Len = static_cast<size_t>(ceil(static_cast<long double>(inputLen) / BASE64_ENCODE_PACKET_LEN) *
83 BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA + 1);
84 std::unique_ptr<unsigned char[]> base64Str = std::make_unique<unsigned char[]>(base64Len);
85 size_t outLen = static_cast<size_t>(EVP_EncodeBlock(reinterpret_cast<uint8_t *>(base64Str.get()),
86 input, inputLen));
87 encodedStr = std::string(reinterpret_cast<char*>(base64Str.get()), outLen);
88 }
89
VerifyRsa(RSA * pubKey,const std::string & digest,const std::string & sign)90 bool LogSignTools::VerifyRsa(RSA *pubKey, const std::string &digest, const std::string &sign)
91 {
92 EVP_PKEY *evpKey = nullptr;
93 EVP_MD_CTX *ctx = nullptr;
94 evpKey = EVP_PKEY_new();
95 if (evpKey == nullptr) {
96 HIVIEW_LOGE("evpKey is nullptr");
97 return false;
98 }
99
100 if (EVP_PKEY_set1_RSA(evpKey, pubKey) != 1) {
101 HIVIEW_LOGE("set RSA failed.");
102 return false;
103 }
104
105 ctx = EVP_MD_CTX_new();
106 EVP_MD_CTX_init(ctx);
107 if (ctx == nullptr) {
108 HIVIEW_LOGE("ctx is nullptr.");
109 EVP_PKEY_free(evpKey);
110 return false;
111 }
112
113 if (EVP_VerifyInit_ex(ctx, EVP_sha256(), nullptr) != 1) {
114 HIVIEW_LOGE("VerifyInit failed.");
115 EVP_PKEY_free(evpKey);
116 EVP_MD_CTX_free(ctx);
117 return false;
118 }
119
120 if (EVP_VerifyUpdate(ctx, digest.c_str(), digest.size()) != 1) {
121 HIVIEW_LOGE("VerifyUpdate failed.");
122 EVP_PKEY_free(evpKey);
123 EVP_MD_CTX_free(ctx);
124 return false;
125 }
126
127 if (EVP_VerifyFinal(ctx, (unsigned char *)sign.c_str(), sign.size(), evpKey) != 1) {
128 HIVIEW_LOGE("VerifyFinal failed.");
129 EVP_PKEY_free(evpKey);
130 EVP_MD_CTX_free(ctx);
131 return false;
132 }
133 EVP_PKEY_free(evpKey);
134 EVP_MD_CTX_free(ctx);
135 return true;
136 }
137 }
138 }
139