diff options
author | Roman Grundkiewicz <rgrundkiewicz@gmail.com> | 2022-09-02 16:40:36 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-02 16:40:36 +0300 |
commit | 8909c57b5473cb95e197fa7f034edabb474535ba (patch) | |
tree | e43e942078e441b66f0887c7b8dc4eb3c817e25c /crypto.hpp | |
parent | 1d7e84aeb3f1ebdc78f6965d79ad3ca3003789fe (diff) | |
parent | db904bbcb73be90b6e52a212660478ceefe5bb9d (diff) |
Update with newest upstream
Diffstat (limited to 'crypto.hpp')
-rw-r--r-- | crypto.hpp | 157 |
1 files changed, 65 insertions, 92 deletions
@@ -32,7 +32,7 @@ namespace SimpleWeb { std::string base64; BIO *bio, *b64; - BUF_MEM *bptr = BUF_MEM_new(); + auto bptr = BUF_MEM_new(); b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); @@ -62,10 +62,8 @@ namespace SimpleWeb { /// Returns Base64 decoded string from base64 input. static std::string decode(const std::string &base64) noexcept { - std::string ascii; + std::string ascii((6 * base64.size()) / 8, '\0'); // The size is a up to two bytes too large. - // Resize ascii, however, the size is a up to two bytes too large. - ascii.resize((6 * base64.size()) / 8); BIO *b64, *bio; b64 = BIO_new(BIO_f_base64()); @@ -99,133 +97,109 @@ namespace SimpleWeb { return hex_stream.str(); } - /// Returns md5 hash value from input string. - static std::string md5(const std::string &input, std::size_t iterations = 1) noexcept { - std::string hash; + /// Return hash value using specific EVP_MD from input string. + static std::string message_digest(const std::string &str, const EVP_MD *evp_md, std::size_t digest_length) noexcept { + std::string md(digest_length, '\0'); + + auto ctx = EVP_MD_CTX_create(); + EVP_MD_CTX_init(ctx); + EVP_DigestInit_ex(ctx, evp_md, nullptr); + EVP_DigestUpdate(ctx, str.data(), str.size()); + EVP_DigestFinal_ex(ctx, reinterpret_cast<unsigned char *>(&md[0]), nullptr); + EVP_MD_CTX_destroy(ctx); + + return md; + } + + /// Return hash value using specific EVP_MD from input stream. + static std::string stream_digest(std::istream &stream, const EVP_MD *evp_md, std::size_t digest_length) noexcept { + std::string md(digest_length, '\0'); + std::unique_ptr<char[]> buffer(new char[buffer_size]); + std::streamsize read_length; - hash.resize(128 / 8); - MD5(reinterpret_cast<const unsigned char *>(&input[0]), input.size(), reinterpret_cast<unsigned char *>(&hash[0])); + auto ctx = EVP_MD_CTX_create(); + EVP_MD_CTX_init(ctx); + EVP_DigestInit_ex(ctx, evp_md, nullptr); + while((read_length = stream.read(buffer.get(), buffer_size).gcount()) > 0) + EVP_DigestUpdate(ctx, buffer.get(), static_cast<std::size_t>(read_length)); + EVP_DigestFinal_ex(ctx, reinterpret_cast<unsigned char *>(&md[0]), nullptr); + EVP_MD_CTX_destroy(ctx); - for(std::size_t c = 1; c < iterations; ++c) - MD5(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); + return md; + } + /// Returns md5 hash value from input string. + static std::string md5(const std::string &input, std::size_t iterations = 1) noexcept { + auto evp_md = EVP_md5(); + auto hash = message_digest(input, evp_md, MD5_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, MD5_DIGEST_LENGTH); return hash; } /// Returns md5 hash value from input stream. static std::string md5(std::istream &stream, std::size_t iterations = 1) noexcept { - MD5_CTX context; - MD5_Init(&context); - std::streamsize read_length; - std::vector<char> buffer(buffer_size); - while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0) - MD5_Update(&context, buffer.data(), static_cast<std::size_t>(read_length)); - std::string hash; - hash.resize(128 / 8); - MD5_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context); - - for(std::size_t c = 1; c < iterations; ++c) - MD5(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_md5(); + auto hash = stream_digest(stream, evp_md, MD5_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, MD5_DIGEST_LENGTH); return hash; } /// Returns sha1 hash value from input string. static std::string sha1(const std::string &input, std::size_t iterations = 1) noexcept { - std::string hash; - - hash.resize(160 / 8); - SHA1(reinterpret_cast<const unsigned char *>(&input[0]), input.size(), reinterpret_cast<unsigned char *>(&hash[0])); - - for(std::size_t c = 1; c < iterations; ++c) - SHA1(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_sha1(); + auto hash = message_digest(input, evp_md, SHA_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, SHA_DIGEST_LENGTH); return hash; } /// Returns sha1 hash value from input stream. static std::string sha1(std::istream &stream, std::size_t iterations = 1) noexcept { - SHA_CTX context; - SHA1_Init(&context); - std::streamsize read_length; - std::vector<char> buffer(buffer_size); - while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0) - SHA1_Update(&context, buffer.data(), static_cast<std::size_t>(read_length)); - std::string hash; - hash.resize(160 / 8); - SHA1_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context); - - for(std::size_t c = 1; c < iterations; ++c) - SHA1(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_sha1(); + auto hash = stream_digest(stream, evp_md, SHA_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, SHA_DIGEST_LENGTH); return hash; } /// Returns sha256 hash value from input string. static std::string sha256(const std::string &input, std::size_t iterations = 1) noexcept { - std::string hash; - - hash.resize(256 / 8); - SHA256(reinterpret_cast<const unsigned char *>(&input[0]), input.size(), reinterpret_cast<unsigned char *>(&hash[0])); - - for(std::size_t c = 1; c < iterations; ++c) - SHA256(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_sha256(); + auto hash = message_digest(input, evp_md, SHA256_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, SHA256_DIGEST_LENGTH); return hash; } /// Returns sha256 hash value from input stream. static std::string sha256(std::istream &stream, std::size_t iterations = 1) noexcept { - SHA256_CTX context; - SHA256_Init(&context); - std::streamsize read_length; - std::vector<char> buffer(buffer_size); - while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0) - SHA256_Update(&context, buffer.data(), static_cast<std::size_t>(read_length)); - std::string hash; - hash.resize(256 / 8); - SHA256_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context); - - for(std::size_t c = 1; c < iterations; ++c) - SHA256(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_sha256(); + auto hash = stream_digest(stream, evp_md, SHA256_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, SHA256_DIGEST_LENGTH); return hash; } /// Returns sha512 hash value from input string. static std::string sha512(const std::string &input, std::size_t iterations = 1) noexcept { - std::string hash; - - hash.resize(512 / 8); - SHA512(reinterpret_cast<const unsigned char *>(&input[0]), input.size(), reinterpret_cast<unsigned char *>(&hash[0])); - - for(std::size_t c = 1; c < iterations; ++c) - SHA512(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_sha512(); + auto hash = message_digest(input, evp_md, SHA512_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, SHA512_DIGEST_LENGTH); return hash; } /// Returns sha512 hash value from input stream. static std::string sha512(std::istream &stream, std::size_t iterations = 1) noexcept { - SHA512_CTX context; - SHA512_Init(&context); - std::streamsize read_length; - std::vector<char> buffer(buffer_size); - while((read_length = stream.read(&buffer[0], buffer_size).gcount()) > 0) - SHA512_Update(&context, buffer.data(), static_cast<std::size_t>(read_length)); - std::string hash; - hash.resize(512 / 8); - SHA512_Final(reinterpret_cast<unsigned char *>(&hash[0]), &context); - - for(std::size_t c = 1; c < iterations; ++c) - SHA512(reinterpret_cast<const unsigned char *>(&hash[0]), hash.size(), reinterpret_cast<unsigned char *>(&hash[0])); - + auto evp_md = EVP_sha512(); + auto hash = stream_digest(stream, evp_md, SHA512_DIGEST_LENGTH); + for(std::size_t i = 1; i < iterations; ++i) + hash = message_digest(hash, evp_md, SHA512_DIGEST_LENGTH); return hash; } - /// Returns PBKDF2 hash value from the given password - /// Input parameter key_size number of bytes of the returned key. - /** * Returns PBKDF2 derived key from the given password. * @@ -237,8 +211,7 @@ namespace SimpleWeb { * @return The PBKDF2 derived key. */ static std::string pbkdf2(const std::string &password, const std::string &salt, int iterations, int key_size) noexcept { - std::string key; - key.resize(static_cast<std::size_t>(key_size)); + std::string key(static_cast<std::size_t>(key_size), '\0'); PKCS5_PBKDF2_HMAC_SHA1(password.c_str(), password.size(), reinterpret_cast<const unsigned char *>(salt.c_str()), salt.size(), iterations, key_size, reinterpret_cast<unsigned char *>(&key[0])); |