From 4f3685c1fead397ce6be586f92f12e81540eaa04 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Sat, 29 Jul 2023 09:26:30 +0900 Subject: [PATCH] Convert fixed-size allocations to C++11 std::array This is safer and more efficient. --- src/common_auth.cpp | 16 ++++------ src/curl.cpp | 27 +++++++--------- src/gnutls_auth.cpp | 75 +++++++++++++++----------------------------- src/nss_auth.cpp | 42 +++++++------------------ src/openssl_auth.cpp | 64 +++++++++++++------------------------ src/s3fs_auth.h | 12 ++++--- 6 files changed, 83 insertions(+), 153 deletions(-) diff --git a/src/common_auth.cpp b/src/common_auth.cpp index 0902245..64336b0 100644 --- a/src/common_auth.cpp +++ b/src/common_auth.cpp @@ -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; } diff --git a/src/curl.cpp b/src/curl.cpp index f9f004a..959a92b 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -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(strdate.data()), strdate.size(), &kDate, &kDate_len); s3fs_HMAC256(kDate, kDate_len, reinterpret_cast(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(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(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(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 diff --git a/src/gnutls_auth.cpp b/src/gnutls_auth.cpp index 1e8325e..3223488 100644 --- a/src/gnutls_auth.cpp +++ b/src/gnutls_auth.cpp @@ -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(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(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 diff --git a/src/nss_auth.cpp b/src/nss_auth.cpp index b84f85e..13309ff 100644 --- a/src/nss_auth.cpp +++ b/src/nss_auth.cpp @@ -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(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; } /* diff --git a/src/openssl_auth.cpp b/src/openssl_auth.cpp index d6f6cf0..34acaa9 100644 --- a/src/openssl_auth.cpp +++ b/src/openssl_auth.cpp @@ -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(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; } /* diff --git a/src/s3fs_auth.h b/src/s3fs_auth.h index f6c96a3..5fd7b82 100644 --- a/src/s3fs_auth.h +++ b/src/s3fs_auth.h @@ -21,9 +21,13 @@ #ifndef S3FS_AUTH_H_ #define S3FS_AUTH_H_ +#include #include #include +typedef std::array md5_t; +typedef std::array 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_