• 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 <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         int rtnErrno = errno;
90         HIVIEW_LOGE("open file failed.");
91         return rtnErrno; // if file not exist, errno will be ENOENT
92     }
93 
94     size_t n;
95     char buffer[HASH_BUFFER_SIZE] = {0};
96     SHA256_CTX ctx;
97     SHA256_Init(&ctx);
98     while ((n = fread(buffer, 1, sizeof(buffer), fp))) {
99         SHA256_Update(&ctx, (unsigned char *)buffer, n);
100     }
101     if (fclose(fp)) {
102         HIVIEW_LOGE("fclose is failed");
103     }
104     fp = nullptr;
105     SHA256_Final(hash, &ctx);
106     return 0;
107 }
108 
109 /*
110  * API name : calc_buffer_sha1
111  * Description : calculate a buffer sha1 hash for given buffer
112  * Input parameters
113  * buffer : buffer to store the content which needed to be calculated
114  * hash_str   : buffer to store output sha1 string
115  * Return
116  * 0 : successful
117  * x : fail
118  */
CalcBufferSha(const string & buffer,size_t bufSize,char * hash,size_t len)119 int CalcFingerprint::CalcBufferSha(const string& buffer, size_t bufSize, char *hash, size_t len)
120 {
121     if (buffer.empty() || hash == nullptr) {
122         return EINVAL;
123     }
124     unsigned char value[SHA256_DIGEST_LENGTH] = {0};
125     SHA256((unsigned char *)buffer.c_str(), bufSize, value);
126     return ConvertToString(value, hash, len);
127 }
128 }
129 }
130