File indexing completed on 2026-08-17 08:51:25
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_MYSQL_IMPL_INTERNAL_SANSIO_MYSQL_NATIVE_PASSWORD_HPP
0009 #define BOOST_MYSQL_IMPL_INTERNAL_SANSIO_MYSQL_NATIVE_PASSWORD_HPP
0010
0011 #include <boost/mysql/client_errc.hpp>
0012 #include <boost/mysql/string_view.hpp>
0013
0014 #include <boost/mysql/impl/internal/protocol/static_buffer.hpp>
0015 #include <boost/mysql/impl/internal/sansio/auth_plugin_common.hpp>
0016
0017 #include <boost/config.hpp>
0018 #include <boost/core/span.hpp>
0019 #include <boost/system/result.hpp>
0020
0021 #include <array>
0022 #include <cstddef>
0023 #include <cstdint>
0024 #include <openssl/sha.h>
0025
0026
0027
0028
0029 namespace boost {
0030 namespace mysql {
0031 namespace detail {
0032
0033
0034 BOOST_INLINE_CONSTEXPR std::size_t mnp_hash_size = 20;
0035 BOOST_INLINE_CONSTEXPR const char* mnp_plugin_name = "mysql_native_password";
0036 static_assert(mnp_hash_size <= max_hash_size, "");
0037 static_assert(mnp_hash_size == SHA_DIGEST_LENGTH, "Buffer size mismatch");
0038
0039
0040 inline void mnp_hash_password_impl(
0041 string_view password,
0042 span<const std::uint8_t, scramble_size> scramble,
0043 span<std::uint8_t, mnp_hash_size> output
0044 )
0045 {
0046
0047 std::array<std::uint8_t, mnp_hash_size> password_sha1;
0048 SHA1(reinterpret_cast<const unsigned char*>(password.data()), password.size(), password_sha1.data());
0049
0050
0051 std::array<std::uint8_t, scramble_size + mnp_hash_size> salted_buffer;
0052 std::memcpy(salted_buffer.data(), scramble.data(), scramble.size());
0053 SHA1(password_sha1.data(), password_sha1.size(), salted_buffer.data() + mnp_hash_size);
0054 std::array<std::uint8_t, mnp_hash_size> salted_sha1;
0055 SHA1(salted_buffer.data(), salted_buffer.size(), salted_sha1.data());
0056
0057
0058 for (std::size_t i = 0; i < mnp_hash_size; ++i)
0059 {
0060 output[i] = password_sha1[i] ^ salted_sha1[i];
0061 }
0062 }
0063
0064
0065 inline static_buffer<max_hash_size> mnp_hash_password(
0066 string_view password,
0067 span<const std::uint8_t, scramble_size> scramble
0068 )
0069 {
0070
0071 if (password.empty())
0072 return {};
0073
0074
0075 static_buffer<max_hash_size> res(mnp_hash_size);
0076 mnp_hash_password_impl(password, scramble, span<std::uint8_t, mnp_hash_size>(res.data(), mnp_hash_size));
0077 return res;
0078 }
0079
0080 }
0081 }
0082 }
0083
0084 #endif