• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "calc_fingerprint.h"
16 
17 #include <dlfcn.h>
18 #include <securec.h>
19 
20 #include "common_defines.h"
21 #include "file_util.h"
22 
23 using namespace std;
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace {
27 struct DlCloseDeleter {
operator ()OHOS::HiviewDFX::__anon8d0bbd230111::DlCloseDeleter28     void operator()(void* handle)
29     {
30         if (handle) {
31             dlclose(handle);
32         }
33     }
34 };
35 }
36 DEFINE_LOG_TAG("CalcFingerprint");
ConvertToString(const unsigned char hash[SHA256_DIGEST_LENGTH],char * outstr,size_t len)37 int CalcFingerprint::ConvertToString(const unsigned char hash[SHA256_DIGEST_LENGTH], char *outstr, size_t len)
38 {
39     uint32_t i;
40     char *outHash = outstr;
41 
42     if (hash == nullptr || outHash == nullptr) {
43         return EINVAL;
44     }
45     constexpr int charsEachHex = 2;
46     if (len < (SHA256_DIGEST_LENGTH * charsEachHex + 1)) { // 1: add '\0'
47         return ENOMEM;
48     }
49     for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
50         int err = snprintf_s(outHash, charsEachHex + 1, charsEachHex, "%02x", hash[i]);
51         if (err < 0) {
52             return err;
53         }
54         outHash += charsEachHex;
55     }
56     *outHash = '\0';
57     return 0;
58 }
59 
60 /*
61  * API name : calc_file_sha1
62  * Description : calculate a file sha1 hash for given file
63  * Input parameters
64  * filePath : path of the file to be calculated
65  * hash      : buffer to store output sha1 string
66  * Return
67  * 0 : successful
68  * x : fail
69  */
CalcFileSha(const string & filePath,char * hash,size_t len)70 int CalcFingerprint::CalcFileSha(const string& filePath, char *hash, size_t len)
71 {
72     if (filePath.empty() || hash == nullptr || !FileUtil::IsLegalPath(filePath)) {
73         HIVIEW_LOGE("invalid param.");
74         return EINVAL;
75     }
76     unsigned char value[SHA256_DIGEST_LENGTH] = {0};
77     int ret = CalcFileShaOriginal(filePath, value, len);
78     if (ret != 0) {
79         HIVIEW_LOGE("CalcFileShaOriginal failed.");
80         return ret;
81     }
82     return ConvertToString(value, hash, len);
83 }
84 
CalcFileShaOriginal(const string & filePath,unsigned char * hash,size_t len)85 int CalcFingerprint::CalcFileShaOriginal(const string& filePath, unsigned char *hash, size_t len)
86 {
87     if (filePath.empty() || hash == nullptr || !FileUtil::IsLegalPath(filePath)) {
88         HIVIEW_LOGE("file is invalid.");
89         return EINVAL;
90     }
91 
92     if (len < SHA256_DIGEST_LENGTH) {
93         HIVIEW_LOGE("hash buf len error.");
94         return ENOMEM;
95     }
96 
97     FILE *fp = nullptr;
98     fp = fopen(filePath.c_str(), "rb");
99     if (fp == nullptr) {
100         HIVIEW_LOGE("open file failed.");
101         return errno; // if file not exist, errno will be ENOENT
102     }
103 
104     size_t n;
105     char buffer[HASH_BUFFER_SIZE] = {0};
106     SHA256_CTX ctx;
107     SHA256_Init(&ctx);
108     while ((n = fread(buffer, 1, sizeof(buffer), fp))) {
109         SHA256_Update(&ctx, (unsigned char *)buffer, n);
110     }
111     if (fclose(fp)) {
112         HIVIEW_LOGE("fclose is failed");
113     }
114     fp = nullptr;
115     SHA256_Final(hash, &ctx);
116     return 0;
117 }
118 
119 /*
120  * API name : calc_buffer_sha1
121  * Description : calculate a buffer sha1 hash for given buffer
122  * Input parameters
123  * buffer : buffer to store the content which needed to be calculated
124  * hash_str   : buffer to store output sha1 string
125  * Return
126  * 0 : successful
127  * x : fail
128  */
CalcBufferSha(const string & buffer,size_t bufSize,char * hash,size_t len)129 int CalcFingerprint::CalcBufferSha(const string& buffer, size_t bufSize, char *hash, size_t len)
130 {
131     if (buffer.empty()) {
132         return EINVAL;
133     }
134     return CalcBufferSha((unsigned char *)buffer.c_str(), bufSize, hash, len);
135 }
136 
137 /*
138  * API name : calc_buffer_sha1
139  * Description : calculate a buffer sha1 hash for given buffer
140  * Input parameters
141  * source : buffer to store the content which needed to be calculated
142  * sourceLen : input buffer len
143  * hash : buffer to store output sha1 string
144  * hashLen : output buff len
145  * Return
146  * 0 : successful
147  * x : fail
148  */
CalcBufferSha(unsigned char * source,size_t sourceLen,char * hash,size_t hashLen)149 int CalcFingerprint::CalcBufferSha(unsigned char* source, size_t sourceLen, char *hash, size_t hashLen)
150 {
151     if (source == nullptr || hash == nullptr || sourceLen == 0) {
152         return EINVAL;
153     }
154 
155     unsigned char value[SHA256_DIGEST_LENGTH] = {0};
156     SHA256(source, sourceLen, value);
157     return ConvertToString(value, hash, hashLen);
158 }
159 }
160 }
161