std::vector hasher::get_hash_binary()

in src/native/hashing/hasher.cpp [310:362]


std::vector<char> hasher::get_hash_binary()
{
#ifdef USE_BCRYPT
	DWORD hash_byte_count;
	DWORD result_byte_count;
	NTSTATUS ntstatus = BCryptGetProperty(
		m_hash_handle.get(),
		BCRYPT_HASH_LENGTH,
		reinterpret_cast<unsigned char *>(&hash_byte_count),
		sizeof(hash_byte_count),
		&result_byte_count,
		0);
	if (ntstatus)
	{
		std::string msg = "BCryptGetProperty() returned: " + std::to_string(ntstatus);
		throw errors::user_exception(errors::error_code::hash_get_value, msg);
	}

	std::vector<unsigned char> hash_result;
	hash_result.reserve(hash_byte_count);
	ntstatus =
		BCryptFinishHash(m_hash_handle.get(), const_cast<unsigned char *>(hash_result.data()), hash_byte_count, 0);
	if (ntstatus)
	{
		std::string msg = "BCryptFinishHash() returned: " + std::to_string(ntstatus);
		throw errors::user_exception(errors::error_code::hash_get_value, msg);
	}

	auto start = reinterpret_cast<char *>(hash_result.data());
	auto end   = &start[hash_byte_count];
	return std::vector<char>{start, end};
#endif

#ifdef USE_LIBGCRYPT
	auto algo         = alg_to_gcrypt_algo(m_alg);
	auto start        = reinterpret_cast<char *>(gcry_md_read(m_hd, algo));
	size_t hash_bytes = gcry_md_get_algo_dlen(algo);
	auto end          = &start[hash_bytes];
	return std::vector<char>{start, end};
#endif

#ifdef USE_OPENSSL
	char hash_value[EVP_MAX_MD_SIZE];
	unsigned int hash_length = sizeof(hash_value);
	if (!EVP_DigestFinal_ex(m_md_ctx, reinterpret_cast<unsigned char *>(hash_value), &hash_length))
	{
		std::string msg = "EVP_DigestFinal_ex() failed with err = " + std::to_string(static_cast<int>(ERR_get_error()));
		throw errors::user_exception(errors::error_code::hash_get_value, msg);
	}

	return std::vector<char>{hash_value, hash_value + hash_length};
#endif
}