sapling/eden/fs/utils/FileHash.cpp
Chad Austin 91502de90c break privhelper dependency on OpenSSL
Summary:
To avoid any risk of SSLKEYLOGFILE being used to unexpectedly write
files as root, ensure the privhelper does not even link against
OpenSSL.

Reviewed By: fanzeyi

Differential Revision: D31944839

fbshipit-source-id: 3280657a10f4a468ddb63a874d38198bd333e01c
2021-10-27 16:04:36 -07:00

66 lines
1.4 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "eden/fs/utils/FileHash.h"
#include <openssl/sha.h>
#include "eden/fs/utils/WinError.h"
namespace facebook::eden {
#ifdef _WIN32
Hash20 getFileSha1(AbsolutePathPiece filePath) {
auto widePath = filePath.wide();
HANDLE fileHandle = CreateFileW(
widePath.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr);
if (INVALID_HANDLE_VALUE == fileHandle) {
throw makeWin32ErrorExplicit(
GetLastError(), fmt::format(FMT_STRING("couldn't open {}"), filePath));
}
SCOPE_EXIT {
CloseHandle(fileHandle);
};
SHA_CTX ctx;
SHA1_Init(&ctx);
while (true) {
uint8_t buf[8192];
DWORD bytesRead;
if (!ReadFile(fileHandle, buf, sizeof(buf), &bytesRead, nullptr)) {
throw makeWin32ErrorExplicit(
GetLastError(),
fmt::format(
FMT_STRING("Error while computing SHA1 of {}"), filePath));
}
if (bytesRead == 0) {
break;
}
SHA1_Update(&ctx, buf, bytesRead);
}
static_assert(Hash20::RAW_SIZE == SHA_DIGEST_LENGTH);
Hash20 sha1;
SHA1_Final(sha1.mutableBytes().begin(), &ctx);
return sha1;
}
#endif
} // namespace facebook::eden