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