Convert fixed-size allocations to C++11 std::array (#2242)

This is safer and more efficient.
This commit is contained in:
Andrew Gaul 2023-08-05 09:36:22 +09:00 committed by GitHub
parent b29f8d0f2b
commit b5c3fc0a08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 153 deletions

View File

@ -29,18 +29,16 @@
//-------------------------------------------------------------------
std::string s3fs_get_content_md5(int fd)
{
unsigned char* md5;
md5_t md5;
char* base64;
std::string Signature;
if(nullptr == (md5 = s3fs_md5_fd(fd, 0, -1))){
if(!s3fs_md5_fd(fd, 0, -1, &md5)){
return std::string("");
}
if(nullptr == (base64 = s3fs_base64(md5, get_md5_digest_length()))){
delete[] md5;
if(nullptr == (base64 = s3fs_base64(md5.data(), md5.size()))){
return std::string(""); // ENOMEM
}
delete[] md5;
Signature = base64;
delete[] base64;
@ -50,15 +48,13 @@ std::string s3fs_get_content_md5(int fd)
std::string s3fs_sha256_hex_fd(int fd, off_t start, off_t size)
{
size_t digestlen = get_sha256_digest_length();
unsigned char* sha256;
sha256_t sha256;
if(nullptr == (sha256 = s3fs_sha256_fd(fd, start, size))){
if(!s3fs_sha256_fd(fd, start, size, &sha256)){
return std::string("");
}
std::string sha256hex = s3fs_hex_lower(sha256, digestlen);
delete[] sha256;
std::string sha256hex = s3fs_hex_lower(sha256.data(), sha256.size());
return sha256hex;
}

View File

@ -2808,8 +2808,8 @@ std::string S3fsCurl::CalcSignature(const std::string& method, const std::string
StringCQ += payload_hash;
std::string kSecret = "AWS4" + secret_access_key;
unsigned char *kDate, *kRegion, *kService, *kSigning, *sRequest = nullptr;
unsigned int kDate_len,kRegion_len, kService_len, kSigning_len, sRequest_len = 0;
unsigned char *kDate, *kRegion, *kService, *kSigning = nullptr;
unsigned int kDate_len,kRegion_len, kService_len, kSigning_len = 0;
s3fs_HMAC256(kSecret.c_str(), kSecret.size(), reinterpret_cast<const unsigned char*>(strdate.data()), strdate.size(), &kDate, &kDate_len);
s3fs_HMAC256(kDate, kDate_len, reinterpret_cast<const unsigned char*>(endpoint.c_str()), endpoint.size(), &kRegion, &kRegion_len);
@ -2821,13 +2821,13 @@ std::string S3fsCurl::CalcSignature(const std::string& method, const std::string
const unsigned char* cRequest = reinterpret_cast<const unsigned char*>(StringCQ.c_str());
size_t cRequest_len = StringCQ.size();
s3fs_sha256(cRequest, cRequest_len, &sRequest, &sRequest_len);
sha256_t sRequest;
s3fs_sha256(cRequest, cRequest_len, &sRequest);
StringToSign = "AWS4-HMAC-SHA256\n";
StringToSign += date8601 + "\n";
StringToSign += strdate + "/" + endpoint + "/s3/aws4_request\n";
StringToSign += s3fs_hex_lower(sRequest, sRequest_len);
delete[] sRequest;
StringToSign += s3fs_hex_lower(sRequest.data(), sRequest.size());
const unsigned char* cscope = reinterpret_cast<const unsigned char*>(StringToSign.c_str());
size_t cscope_len = StringToSign.size();
@ -2859,11 +2859,9 @@ void S3fsCurl::insertV4Headers(const std::string& access_key_id, const std::stri
case REQTYPE::COMPLETEMULTIPOST:
{
size_t cRequest_len = strlen(reinterpret_cast<const char *>(b_postdata));
unsigned char* sRequest = nullptr;
unsigned int sRequest_len = 0;
s3fs_sha256(b_postdata, cRequest_len, &sRequest, &sRequest_len);
payload_hash = s3fs_hex_lower(sRequest, sRequest_len);
delete[] sRequest;
sha256_t sRequest;
s3fs_sha256(b_postdata, cRequest_len, &sRequest);
payload_hash = s3fs_hex_lower(sRequest.data(), sRequest.size());
break;
}
@ -4120,16 +4118,15 @@ int S3fsCurl::UploadMultipartPostSetup(const char* tpath, int part_num, const st
// make md5 and file pointer
if(S3fsCurl::is_content_md5){
unsigned char *md5raw = s3fs_md5_fd(partdata.fd, partdata.startpos, partdata.size);
if(md5raw == nullptr){
md5_t md5raw;
if(!s3fs_md5_fd(partdata.fd, partdata.startpos, partdata.size, &md5raw)){
S3FS_PRN_ERR("Could not make md5 for file(part %d)", part_num);
return -EIO;
}
partdata.etag = s3fs_hex_lower(md5raw, get_md5_digest_length());
char* md5base64p = s3fs_base64(md5raw, get_md5_digest_length());
partdata.etag = s3fs_hex_lower(md5raw.data(), md5raw.size());
char* md5base64p = s3fs_base64(md5raw.data(), md5raw.size());
requestHeaders = curl_slist_sort_insert(requestHeaders, "Content-MD5", md5base64p);
delete[] md5base64p;
delete[] md5raw;
}
// make request

View File

@ -183,22 +183,16 @@ bool s3fs_HMAC256(const void* key, size_t keylen, const unsigned char* data, siz
//-------------------------------------------------------------------
// Utility Function for MD5
//-------------------------------------------------------------------
size_t get_md5_digest_length()
{
return 16;
}
#ifdef USE_GNUTLS_NETTLE
unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
bool s3fs_md5_fd(int fd, off_t start, off_t size, md5_t* result)
{
struct md5_ctx ctx_md5;
off_t bytes;
unsigned char* result;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
@ -216,36 +210,34 @@ unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
}else if(-1 == bytes){
// error
S3FS_PRN_ERR("file read error(%d)", errno);
return nullptr;
return false;
}
md5_update(&ctx_md5, bytes, buf);
}
result = new unsigned char[get_md5_digest_length()];
md5_digest(&ctx_md5, get_md5_digest_length(), result);
md5_digest(&ctx_md5, result->size(), result->data());
return result;
return true;
}
#else // USE_GNUTLS_NETTLE
unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
bool s3fs_md5_fd(int fd, off_t start, off_t size, md5_t* result)
{
gcry_md_hd_t ctx_md5;
gcry_error_t err;
off_t bytes;
unsigned char* result;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
if(GPG_ERR_NO_ERROR != (err = gcry_md_open(&ctx_md5, GCRY_MD_MD5, 0))){
S3FS_PRN_ERR("MD5 context creation failure: %s/%s", gcry_strsource(err), gcry_strerror(err));
return nullptr;
return false;
}
for(off_t total = 0; total < size; total += bytes){
@ -260,15 +252,14 @@ unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
// error
S3FS_PRN_ERR("file read error(%d)", errno);
gcry_md_close(ctx_md5);
return nullptr;
return false;
}
gcry_md_write(ctx_md5, buf, bytes);
}
result = new unsigned char[get_md5_digest_length()];
memcpy(result, gcry_md_read(ctx_md5, 0), get_md5_digest_length());
memcpy(result->data(), gcry_md_read(ctx_md5, 0), result->size());
gcry_md_close(ctx_md5);
return result;
return true;
}
#endif // USE_GNUTLS_NETTLE
@ -276,30 +267,21 @@ unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
//-------------------------------------------------------------------
// Utility Function for SHA256
//-------------------------------------------------------------------
size_t get_sha256_digest_length()
{
return 32;
}
#ifdef USE_GNUTLS_NETTLE
bool s3fs_sha256(const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
bool s3fs_sha256(const unsigned char* data, size_t datalen, sha256_t* digest)
{
(*digestlen) = static_cast<unsigned int>(get_sha256_digest_length());
*digest = new unsigned char[*digestlen];
struct sha256_ctx ctx_sha256;
sha256_init(&ctx_sha256);
sha256_update(&ctx_sha256, datalen, data);
sha256_digest(&ctx_sha256, *digestlen, *digest);
sha256_digest(&ctx_sha256, digest->size(), digest->data());
return true;
}
unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
bool s3fs_sha256_fd(int fd, off_t start, off_t size, sha256_t* result)
{
struct sha256_ctx ctx_sha256;
off_t bytes;
unsigned char* result;
sha256_init(&ctx_sha256);
@ -314,55 +296,49 @@ unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
}else if(-1 == bytes){
// error
S3FS_PRN_ERR("file read error(%d)", errno);
return nullptr;
return false;
}
sha256_update(&ctx_sha256, bytes, buf);
}
result = new unsigned char[get_sha256_digest_length()];
sha256_digest(&ctx_sha256, get_sha256_digest_length(), result);
sha256_digest(&ctx_sha256, result->size(), result->data());
return result;
return true;
}
#else // USE_GNUTLS_NETTLE
bool s3fs_sha256(const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
bool s3fs_sha256(const unsigned char* data, size_t datalen, sha256_t* digest)
{
size_t len = (*digestlen) = static_cast<unsigned int>(get_sha256_digest_length());
*digest = new unsigned char[len];
gcry_md_hd_t ctx_sha256;
gcry_error_t err;
if(GPG_ERR_NO_ERROR != (err = gcry_md_open(&ctx_sha256, GCRY_MD_SHA256, 0))){
S3FS_PRN_ERR("SHA256 context creation failure: %s/%s", gcry_strsource(err), gcry_strerror(err));
delete[] *digest;
return false;
}
gcry_md_write(ctx_sha256, data, datalen);
memcpy(*digest, gcry_md_read(ctx_sha256, 0), *digestlen);
memcpy(digest->data(), gcry_md_read(ctx_sha256, 0), digest->size());
gcry_md_close(ctx_sha256);
return true;
}
unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
bool s3fs_sha256_fd(int fd, off_t start, off_t size, sha256_t* result)
{
gcry_md_hd_t ctx_sha256;
gcry_error_t err;
off_t bytes;
unsigned char* result;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
if(GPG_ERR_NO_ERROR != (err = gcry_md_open(&ctx_sha256, GCRY_MD_SHA256, 0))){
S3FS_PRN_ERR("SHA256 context creation failure: %s/%s", gcry_strsource(err), gcry_strerror(err));
return nullptr;
return false;
}
for(off_t total = 0; total < size; total += bytes){
@ -377,15 +353,14 @@ unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
// error
S3FS_PRN_ERR("file read error(%d)", errno);
gcry_md_close(ctx_sha256);
return nullptr;
return false;
}
gcry_md_write(ctx_sha256, buf, bytes);
}
result = new unsigned char[get_sha256_digest_length()];
memcpy(result, gcry_md_read(ctx_sha256, 0), get_sha256_digest_length());
memcpy(result->data(), gcry_md_read(ctx_sha256, 0), result->size());
gcry_md_close(ctx_sha256);
return result;
return true;
}
#endif // USE_GNUTLS_NETTLE

View File

@ -146,22 +146,16 @@ bool s3fs_HMAC256(const void* key, size_t keylen, const unsigned char* data, siz
//-------------------------------------------------------------------
// Utility Function for MD5
//-------------------------------------------------------------------
size_t get_md5_digest_length()
{
return MD5_LENGTH;
}
unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
bool s3fs_md5_fd(int fd, off_t start, off_t size, md5_t* result)
{
PK11Context* md5ctx;
off_t bytes;
unsigned char* result;
unsigned int md5outlen;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
@ -180,53 +174,42 @@ unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
// error
S3FS_PRN_ERR("file read error(%d)", errno);
PK11_DestroyContext(md5ctx, PR_TRUE);
return nullptr;
return false;
}
PK11_DigestOp(md5ctx, buf, bytes);
}
result = new unsigned char[get_md5_digest_length()];
PK11_DigestFinal(md5ctx, result, &md5outlen, get_md5_digest_length());
PK11_DigestFinal(md5ctx, result->data(), &md5outlen, result->size());
PK11_DestroyContext(md5ctx, PR_TRUE);
return result;
return false;
}
//-------------------------------------------------------------------
// Utility Function for SHA256
//-------------------------------------------------------------------
size_t get_sha256_digest_length()
bool s3fs_sha256(const unsigned char* data, size_t datalen, sha256_t* digest)
{
return SHA256_LENGTH;
}
bool s3fs_sha256(const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
{
(*digestlen) = static_cast<unsigned int>(get_sha256_digest_length());
*digest = new unsigned char[*digestlen];
PK11Context* sha256ctx;
unsigned int sha256outlen;
sha256ctx = PK11_CreateDigestContext(SEC_OID_SHA256);
PK11_DigestOp(sha256ctx, data, datalen);
PK11_DigestFinal(sha256ctx, *digest, &sha256outlen, *digestlen);
PK11_DigestFinal(sha256ctx, digest->data(), &sha256outlen, digest->size());
PK11_DestroyContext(sha256ctx, PR_TRUE);
*digestlen = sha256outlen;
return true;
}
unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
bool s3fs_sha256_fd(int fd, off_t start, off_t size, sha256_t* result)
{
PK11Context* sha256ctx;
off_t bytes;
unsigned char* result;
unsigned int sha256outlen;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
@ -245,15 +228,14 @@ unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
// error
S3FS_PRN_ERR("file read error(%d)", errno);
PK11_DestroyContext(sha256ctx, PR_TRUE);
return nullptr;
return false;
}
PK11_DigestOp(sha256ctx, buf, bytes);
}
result = new unsigned char[get_sha256_digest_length()];
PK11_DigestFinal(sha256ctx, result, &sha256outlen, get_sha256_digest_length());
PK11_DigestFinal(sha256ctx, result->data(), &sha256outlen, result->size());
PK11_DestroyContext(sha256ctx, PR_TRUE);
return result;
return true;
}
/*

View File

@ -256,22 +256,16 @@ bool s3fs_HMAC256(const void* key, size_t keylen, const unsigned char* data, siz
// OpenSSL 3.0 deprecated the MD5_*** low-level encryption functions,
// so we should use the high-level EVP API instead.
//
size_t get_md5_digest_length()
{
return EVP_MD_size(EVP_md5());
}
unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
bool s3fs_md5_fd(int fd, off_t start, off_t size, md5_t* result)
{
EVP_MD_CTX* mdctx;
unsigned char* md5_digest;
unsigned int md5_digest_len = static_cast<unsigned int>(get_md5_digest_length());
unsigned int md5_digest_len = result->size();
off_t bytes;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
@ -292,39 +286,32 @@ unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
// error
S3FS_PRN_ERR("file read error(%d)", errno);
EVP_MD_CTX_free(mdctx);
return nullptr;
return false;
}
// instead of MD5_Update
EVP_DigestUpdate(mdctx, buf, bytes);
}
// instead of MD5_Final
md5_digest = new unsigned char[md5_digest_len];
EVP_DigestFinal_ex(mdctx, md5_digest, &md5_digest_len);
EVP_DigestFinal_ex(mdctx, result->data(), &md5_digest_len);
EVP_MD_CTX_free(mdctx);
return md5_digest;
return true;
}
#else
//-------------------------------------------------------------------
// Utility Function for MD5 (OpenSSL < 3.0)
//-------------------------------------------------------------------
size_t get_md5_digest_length()
{
return MD5_DIGEST_LENGTH;
}
unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
bool s3fs_md5_fd(int fd, off_t start, off_t size, md5_t* result)
{
MD5_CTX md5ctx;
off_t bytes;
unsigned char* result;
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
return nullptr;
return false;
}
size = st.st_size;
}
@ -342,56 +329,48 @@ unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size)
}else if(-1 == bytes){
// error
S3FS_PRN_ERR("file read error(%d)", errno);
return nullptr;
return false;
}
MD5_Update(&md5ctx, buf, bytes);
}
result = new unsigned char[get_md5_digest_length()];
MD5_Final(result, &md5ctx);
MD5_Final(result->data(), &md5ctx);
return result;
return true;
}
#endif
//-------------------------------------------------------------------
// Utility Function for SHA256
//-------------------------------------------------------------------
size_t get_sha256_digest_length()
bool s3fs_sha256(const unsigned char* data, size_t datalen, sha256_t* digest)
{
return SHA256_DIGEST_LENGTH;
}
bool s3fs_sha256(const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
{
(*digestlen) = EVP_MAX_MD_SIZE * sizeof(unsigned char);
*digest = new unsigned char[*digestlen];
const EVP_MD* md = EVP_get_digestbyname("sha256");
EVP_MD_CTX* mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, nullptr);
EVP_DigestUpdate(mdctx, data, datalen);
EVP_DigestFinal_ex(mdctx, *digest, digestlen);
// TODO: strange
unsigned int digestlen = digest->size();
EVP_DigestFinal_ex(mdctx, digest->data(), &digestlen);
EVP_MD_CTX_destroy(mdctx);
return true;
}
unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
bool s3fs_sha256_fd(int fd, off_t start, off_t size, sha256_t* result)
{
const EVP_MD* md = EVP_get_digestbyname("sha256");
EVP_MD_CTX* sha256ctx;
off_t bytes;
unsigned char* result;
if(-1 == fd){
return nullptr;
return false;
}
if(-1 == size){
struct stat st;
if(-1 == fstat(fd, &st)){
S3FS_PRN_ERR("fstat error(%d)", errno);
return nullptr;
return false;
}
size = st.st_size;
}
@ -411,15 +390,14 @@ unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size)
// error
S3FS_PRN_ERR("file read error(%d)", errno);
EVP_MD_CTX_destroy(sha256ctx);
return nullptr;
return false;
}
EVP_DigestUpdate(sha256ctx, buf, bytes);
}
result = new unsigned char[get_sha256_digest_length()];
EVP_DigestFinal_ex(sha256ctx, result, nullptr);
EVP_DigestFinal_ex(sha256ctx, result->data(), nullptr);
EVP_MD_CTX_destroy(sha256ctx);
return result;
return true;
}
/*

View File

@ -21,9 +21,13 @@
#ifndef S3FS_AUTH_H_
#define S3FS_AUTH_H_
#include <array>
#include <string>
#include <sys/types.h>
typedef std::array<unsigned char, 16> md5_t;
typedef std::array<unsigned char, 32> sha256_t;
//-------------------------------------------------------------------
// Utility functions for Authentication
//-------------------------------------------------------------------
@ -43,11 +47,9 @@ bool s3fs_init_crypt_mutex();
bool s3fs_destroy_crypt_mutex();
bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen);
bool s3fs_HMAC256(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen);
size_t get_md5_digest_length();
unsigned char* s3fs_md5_fd(int fd, off_t start, off_t size);
bool s3fs_sha256(const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen);
size_t get_sha256_digest_length();
unsigned char* s3fs_sha256_fd(int fd, off_t start, off_t size);
bool s3fs_md5_fd(int fd, off_t start, off_t size, md5_t* result);
bool s3fs_sha256(const unsigned char* data, size_t datalen, sha256_t* digest);
bool s3fs_sha256_fd(int fd, off_t start, off_t size, sha256_t* result);
#endif // S3FS_AUTH_H_