25using namespace std::string_literals;
30BigNumber const BnetSRP6v1Base::N =
"86A7F6DEEB306CE519770FE37D556F29944132554DED0BD68205E27F3231FEF5A10108238A3150C59CAF7B0B6478691C13A6ACF5E1B5ADAFD4A943D4A21A142B800E8A55F8BFBAC700EB77A7235EE5A609E350EA9FC19F10D921C2FA832E4461B7125D38D254A0BE873DFC27858ACB3F8B9F258461E4373BC3A6C2A9634324AB"s;
33BigNumber const BnetSRP6v2Base::N =
"AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73"s;
37 : s(salt), I(i), b(CalculatePrivateB(N)), v(verifier), B(CalculatePublicB(N, g, k))
48 ASSERT(!
_used,
"A single SRP6 object must only ever be used to verify ONCE!");
69 return (g.
ModExp(
b, N) + (
v * k)) % N;
82 :
SRP6(
SHA1::GetDigestOf(username), salt, verifier, N, g, 3)
101 if ((A %
N).IsZero())
113 std::transform(NHash.begin(), NHash.end(), gHash.begin(), NgHash.begin(), std::bit_xor<>());
116 if (ourM == clientM1)
126 for (
size_t i = 0; i < S.size() / 2; ++i)
128 buf0[i] = S[2 * i + 0];
129 buf1[i] = S[2 * i + 1];
134 while (p < S.size() && !S[p]) ++p;
146 K[2 * i + 0] = hash0[i];
147 K[2 * i + 1] = hash1[i];
153 :
SRP6(i, salt, verifier, N, g, k)
159 std::array evidenceBns{ &A, &clientM1, &K };
166 if ((A % N).IsZero())
170 if ((u % N).IsZero())
175 std::array evidenceBns{ &A, &
B, &S };
177 if (ourM != clientM1)
210 std::string tmp = username +
":" + password;
211 PKCS5_PBKDF2_HMAC(tmp.c_str(), tmp.length(), salt.data(), salt.size(),
GetXIterations(), EVP_sha512(), xBytes.size(), xBytes.data());
213 if (xBytes[0] & 0x80)
215 std::array<uint8, 65> fix = {};
std::optional< T > Optional
Optional helper class to wrap optional values within.
BigNumber ModExp(BigNumber const &bn1, BigNumber const &bn2) const
std::vector< uint8 > ToByteVector(int32 minSize=0, bool littleEndian=true) const
std::array< uint8, Size > ToByteArray(bool littleEndian=true) const
void SetRand(int32 numbits)
static std::vector< uint8 > GetBrokenEvidenceVector(BigNumber const &bn)
BigNumber CalculateServerEvidence(BigNumber const &A, BigNumber const &clientM1, BigNumber const &K) const final
Optional< BigNumber > DoVerifyClientEvidence(BigNumber const &A, BigNumber const &clientM1) final
BnetSRP6Base(BigNumber const &i, Salt const &salt, Verifier const &verifier, BigNumber const &N, BigNumber const &g, BigNumber const &k)
virtual BigNumber CalculateU(BigNumber const &A) const =0
virtual BigNumber DoCalculateEvidence(std::span< BigNumber const * > bns) const =0
BigNumber CalculateX(std::string const &username, std::string const &password, Salt const &salt) const final
BnetSRP6v1Base(std::string const &username, Salt const &salt, Verifier const &verifier, BigNumber const &k)
BigNumber CalculateX(std::string const &username, std::string const &password, Salt const &salt) const final
BnetSRP6v2Base(std::string const &username, Salt const &salt, Verifier const &verifier, BigNumber const &k)
uint32 GetXIterations() const final
Optional< BigNumber > DoVerifyClientEvidence(BigNumber const &A, BigNumber const &clientM1) override
std::array< uint8, EPHEMERAL_KEY_LENGTH > EphemeralKey
BigNumber CalculateServerEvidence(BigNumber const &A, BigNumber const &clientM1, BigNumber const &K) const override
static SessionKey SHA1Interleave(EphemeralKey const &S)
BigNumber CalculateX(std::string const &username, std::string const &password, Salt const &salt) const override
static constexpr size_t EPHEMERAL_KEY_LENGTH
GruntSRP6(std::string const &username, Salt const &salt, Verifier const &verifier)
std::array< uint8, SHA1::DIGEST_LENGTH *2 > SessionKey
static BigNumber CalculatePrivateB(BigNumber const &N)
Optional< BigNumber > VerifyClientEvidence(BigNumber const &A, BigNumber const &clientM1)
SRP6(BigNumber const &i, Salt const &salt, Verifier const &verifier, BigNumber const &N, BigNumber const &g, BigNumber const &k)
virtual BigNumber const & Getg() const =0
virtual Optional< BigNumber > DoVerifyClientEvidence(BigNumber const &A, BigNumber const &clientM1)=0
virtual BigNumber CalculateX(std::string const &username, std::string const &password, Salt const &salt) const =0
virtual BigNumber const & GetN() const =0
BigNumber CalculatePublicB(BigNumber const &N, BigNumber const &g, BigNumber const &k) const
Verifier CalculateVerifier(std::string const &username, std::string const &password, Salt const &salt) const
bool CheckCredentials(std::string const &username, std::string const &password) const
std::array< uint8, DIGEST_LENGTH > Digest
static constexpr size_t DIGEST_LENGTH
static Digest GetDigestOf(uint8 const *data, size_t len)
std::array< uint8, SALT_LENGTH > Salt
std::vector< uint8 > Verifier
static constexpr size_t SALT_LENGTH
void TC_COMMON_API GetRandomBytes(uint8 *buf, size_t len)