From 194eb950ea072ac313635d75dc3913f48e300edf Mon Sep 17 00:00:00 2001 From: wujing Date: Wed, 11 May 2022 18:25:40 +0800 Subject: [PATCH 3/5] adapt to openssl 3.0 SHA512_Init&SHA512_Update&SHA512_Final function have been deprecated since OpenSSL 3.0 Signed-off-by: wujing --- src/daemon/entry/cri/cri_helpers.cc | 45 +++++++--------- src/daemon/entry/cri/cri_helpers.h | 2 - src/utils/sha256/sha256.c | 79 +++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 28 deletions(-) diff --git a/src/daemon/entry/cri/cri_helpers.cc b/src/daemon/entry/cri/cri_helpers.cc index a5bb09a6..04e4f534 100644 --- a/src/daemon/entry/cri/cri_helpers.cc +++ b/src/daemon/entry/cri/cri_helpers.cc @@ -33,6 +33,7 @@ #include "utils.h" #include "service_container_api.h" #include "isulad_config.h" +#include "sha256.h" namespace CRIHelpers { const std::string Constants::POD_NETWORK_ANNOTATION_KEY { "network.alpha.kubernetes.io/network" }; @@ -376,30 +377,6 @@ auto IsImageNotFoundError(const std::string &err) -> bool return err.find("No such image:") != std::string::npos; } -auto sha256(const char *val) -> std::string -{ - if (val == nullptr) { - return ""; - } - - SHA256_CTX ctx; - SHA256_Init(&ctx); - SHA256_Update(&ctx, val, strlen(val)); - unsigned char hash[SHA256_DIGEST_LENGTH] = { 0 }; - SHA256_Final(hash, &ctx); - - char outputBuffer[(SHA256_DIGEST_LENGTH * 2) + 1] { 0 }; - for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { - int ret = snprintf(outputBuffer + (i * 2), 3, "%02x", (unsigned int)hash[i]); - if (ret >= 3 || ret < 0) { - return ""; - } - } - outputBuffer[SHA256_DIGEST_LENGTH * 2] = 0; - - return outputBuffer; -} - auto GetNetworkPlaneFromPodAnno(const std::map &annotations, size_t *len, Errors &error) -> cri_pod_network_element ** { @@ -649,6 +626,7 @@ auto CreateCheckpoint(CRI::PodSandboxCheckpoint &checkpoint, Errors &error) -> s }; parser_error err { nullptr }; char *jsonStr { nullptr }; + char *digest { nullptr }; std::string result; checkpoint.CheckpointToCStruct(&criCheckpoint, error); @@ -662,7 +640,14 @@ auto CreateCheckpoint(CRI::PodSandboxCheckpoint &checkpoint, Errors &error) -> s error.Errorf("Generate cri checkpoint json failed: %s", err); goto out; } - checkpoint.SetCheckSum(CRIHelpers::sha256(jsonStr)); + + digest = sha256_digest_str(jsonStr); + if (digest == nullptr) { + error.Errorf("Failed to calculate digest"); + goto out; + } + + checkpoint.SetCheckSum(digest); if (checkpoint.GetCheckSum().empty()) { error.SetError("checksum is empty"); goto out; @@ -678,6 +663,7 @@ auto CreateCheckpoint(CRI::PodSandboxCheckpoint &checkpoint, Errors &error) -> s result = jsonStr; out: + free(digest); free(err); free(jsonStr); free_cri_checkpoint(criCheckpoint); @@ -694,6 +680,7 @@ void GetCheckpoint(const std::string &jsonCheckPoint, CRI::PodSandboxCheckpoint std::string tmpChecksum; char *jsonStr { nullptr }; char *storeChecksum { nullptr }; + char *digest { nullptr }; criCheckpoint = cri_checkpoint_parse_data(jsonCheckPoint.c_str(), &ctx, &err); if (criCheckpoint == nullptr) { @@ -712,7 +699,12 @@ void GetCheckpoint(const std::string &jsonCheckPoint, CRI::PodSandboxCheckpoint goto out; } - if (tmpChecksum != CRIHelpers::sha256(jsonStr)) { + digest = sha256_digest_str(jsonStr); + if (digest == nullptr) { + error.Errorf("Failed to calculate digest"); + goto out; + } + if (tmpChecksum != digest) { ERROR("Checksum of checkpoint is not valid"); error.SetError("checkpoint is corrupted"); goto out; @@ -720,6 +712,7 @@ void GetCheckpoint(const std::string &jsonCheckPoint, CRI::PodSandboxCheckpoint checkpoint.CStructToCheckpoint(criCheckpoint, error); out: + free(digest); free(jsonStr); free(err); free_cri_checkpoint(criCheckpoint); diff --git a/src/daemon/entry/cri/cri_helpers.h b/src/daemon/entry/cri/cri_helpers.h index 5c2f6517..b3bfafe4 100644 --- a/src/daemon/entry/cri/cri_helpers.h +++ b/src/daemon/entry/cri/cri_helpers.h @@ -101,8 +101,6 @@ auto IsContainerNotFoundError(const std::string &err) -> bool; auto IsImageNotFoundError(const std::string &err) -> bool; -auto sha256(const char *val) -> std::string; - auto GetNetworkPlaneFromPodAnno(const std::map &annotations, size_t *len, Errors &error) -> cri_pod_network_element **; diff --git a/src/utils/sha256/sha256.c b/src/utils/sha256/sha256.c index 7bd60467..938e3692 100644 --- a/src/utils/sha256/sha256.c +++ b/src/utils/sha256/sha256.c @@ -21,6 +21,10 @@ #include #include #include +#if OPENSSL_VERSION_MAJOR >= 3 +#include +#include +#endif #include "isula_libutils/log.h" #include "utils.h" @@ -61,7 +65,9 @@ static bool stream_check_error(void *stream, bool isgzip) char *sha256_digest_str(const char *val) { +#if OPENSSL_VERSION_MAJOR < 3 SHA256_CTX ctx; +#endif unsigned char hash[SHA256_DIGEST_LENGTH] = { 0x00 }; char output_buffer[(SHA256_DIGEST_LENGTH * 2) + 1] = { 0x00 }; int i = 0; @@ -70,9 +76,13 @@ char *sha256_digest_str(const char *val) return NULL; } +#if OPENSSL_VERSION_MAJOR >= 3 + SHA256((const unsigned char *)val, strlen(val), hash); +#else SHA256_Init(&ctx); SHA256_Update(&ctx, val, strlen(val)); SHA256_Final(hash, &ctx); +#endif for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { int ret = snprintf(output_buffer + (i * 2), 3, "%02x", (unsigned int)hash[i]); @@ -87,8 +97,15 @@ char *sha256_digest_str(const char *val) char *sha256_digest_file(const char *filename, bool isgzip) { +#if OPENSSL_VERSION_MAJOR >= 3 + EVP_MD_CTX *ctx = NULL; + EVP_MD *sha256 = NULL; + unsigned char *outdigest = NULL; + unsigned int len = 0; +#else SHA256_CTX ctx; unsigned char hash[SHA256_DIGEST_LENGTH] = { 0x00 }; +#endif char output_buffer[(SHA256_DIGEST_LENGTH * 2) + 1] = { 0x00 }; int i = 0; char *buffer = NULL; @@ -117,7 +134,30 @@ char *sha256_digest_file(const char *filename, bool isgzip) return NULL; } +#if OPENSSL_VERSION_MAJOR >= 3 + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) { + ERROR("Failed to create a context for the digest operation"); + ERR_print_errors_fp(stderr); + ret = -1; + goto out; + } + sha256 = EVP_MD_fetch(NULL, "SHA256", NULL); + if (sha256 == NULL) { + ERROR("Failed to fetch the SHA256 algorithm implementation for doing the digest"); + ERR_print_errors_fp(stderr); + ret = -1; + goto out; + } + if (!EVP_DigestInit_ex(ctx, sha256, NULL)) { + ERROR("Failed to initialise the digest operation"); + ERR_print_errors_fp(stderr); + ret = -1; + goto out; + } +#else SHA256_Init(&ctx); +#endif while (true) { if (isgzip) { @@ -134,7 +174,16 @@ char *sha256_digest_file(const char *filename, bool isgzip) } if (n > 0) { +#if OPENSSL_VERSION_MAJOR >= 3 + if (!EVP_DigestUpdate(ctx, (unsigned char *)buffer, n)) { + ERROR("Failed to pass the message to be digested"); + ERR_print_errors_fp(stderr); + ret = -1; + goto out; + } +#else SHA256_Update(&ctx, buffer, n); +#endif } if (stream_check_eof(stream, isgzip)) { @@ -142,6 +191,30 @@ char *sha256_digest_file(const char *filename, bool isgzip) } } +#if OPENSSL_VERSION_MAJOR >= 3 + outdigest = OPENSSL_malloc(EVP_MD_get_size(sha256)); + if (outdigest == NULL) { + ERROR("Failed to allocate the output buffer"); + ERR_print_errors_fp(stderr); + ret = -1; + goto out; + } + if (!EVP_DigestFinal_ex(ctx, outdigest, &len)) { + ERROR("Failed to calculate the digest itself"); + ERR_print_errors_fp(stderr); + ret = -1; + goto out; + } + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + int sret = snprintf(output_buffer + (i * 2), 3, "%02x", (unsigned int)outdigest[i]); + if (sret >= 3 || sret < 0) { + ERROR("snprintf failed when calc sha256 from file %s, result is %d", filename, sret); + return NULL; + } + } + + output_buffer[SHA256_DIGEST_LENGTH * 2] = '\0'; +#else SHA256_Final(hash, &ctx); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { @@ -152,8 +225,14 @@ char *sha256_digest_file(const char *filename, bool isgzip) } } output_buffer[SHA256_DIGEST_LENGTH * 2] = '\0'; +#endif out: +#if OPENSSL_VERSION_MAJOR >= 3 + OPENSSL_free(outdigest); + EVP_MD_free(sha256); + EVP_MD_CTX_free(ctx); +#endif if (isgzip) { gzclose((gzFile)stream); } else { -- 2.25.1