#pragma once #include #include #include #include #include namespace rublon { struct EVP_MD_CTX_deleter{ void operator()(EVP_MD_CTX *ctx)const{ EVP_MD_CTX_free(ctx); } }; inline StaticString< SHA256_DIGEST_LENGTH * 2 > fileSHA256(const char * const path) { std::string fileContent; readFile(path, fileContent); StaticString< SHA256_DIGEST_LENGTH * 2 > xRublon{}; std::array< unsigned char, SHA256_DIGEST_LENGTH + 1 > hash{}; auto ctx = std::unique_ptr{EVP_MD_CTX_new()}; if(not ctx) goto out; // EVP_X methods return 1 on success, so does this function // Any values other than 1 denote error if(not EVP_DigestInit(ctx.get(), EVP_sha256())) goto out; if(not EVP_DigestUpdate(ctx.get(), fileContent.data(), fileContent.size())) goto out; // Provide uint* instead of NULL to get nBytes written, 32 for SHA256 if(not EVP_DigestFinal(ctx.get(), hash.data(), NULL)) goto out; out: for(unsigned int i = 0; i < SHA256_DIGEST_LENGTH; i++) sprintf(&xRublon[i * 2], "%02x", ( unsigned int ) hash[i]); return xRublon; } // +1 for \0 inline StaticString< SHA256_DIGEST_LENGTH * 2 > signData(std::string_view data, std::string_view secretKey) { StaticString< SHA256_DIGEST_LENGTH * 2 > xRublon; std::array< unsigned char, EVP_MAX_MD_SIZE > md{}; unsigned int md_len{}; HMAC(EVP_sha256(), secretKey.data(), secretKey.size(), ( unsigned const char * ) data.data(), data.size(), md.data(), &md_len); for(unsigned int i = 0; i < md_len; i++) sprintf(&xRublon[i * 2], "%02x", ( unsigned int ) md[i]); return xRublon; } } // namespace rublon