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 22using namespace std; 23namespace OHOS { 24namespace HiviewDFX { 25DEFINE_LOG_TAG("CalcFingerprint"); 26int 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 */ 59int 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 74int 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 */ 118int 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 */ 138int 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