TrinityCore
SRP6.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITY_SRP6_H
19#define TRINITY_SRP6_H
20
21#include "BigNumber.h"
22#include "CryptoHash.h"
23#include "Define.h"
24#include "Optional.h"
25#include <array>
26#include <span>
27
28namespace Trinity::Crypto
29{
30namespace SRP
31{
32 static constexpr size_t SALT_LENGTH = 32;
33 using Salt = std::array<uint8, SALT_LENGTH>;
34
35 using Verifier = std::vector<uint8>;
36
38 {
39 protected:
41
42 public:
43 explicit SRP6(BigNumber const& i, Salt const& salt, Verifier const& verifier, BigNumber const& N, BigNumber const& g, BigNumber const& k);
44 explicit SRP6(ForRegistrationTag);
45
46 SRP6(SRP6 const&) = delete;
47 SRP6(SRP6&&) = delete;
48 SRP6& operator=(SRP6 const&) = delete;
49 SRP6& operator=(SRP6&&) = delete;
50
51 virtual ~SRP6() = default;
52
53 virtual BigNumber const& GetN() const = 0;
54 virtual BigNumber const& Getg() const = 0;
55
56 Optional<BigNumber> VerifyClientEvidence(BigNumber const& A, BigNumber const& clientM1);
57
58 virtual BigNumber CalculateServerEvidence(BigNumber const& A, BigNumber const& clientM1, BigNumber const& K) const = 0;
59
60 template<typename Impl>
61 static std::pair<Salt, Verifier> MakeRegistrationData(std::string const& username, std::string const& password)
62 {
63 Impl impl(ForRegistrationTag{});
64 return { impl.s, impl.CalculateVerifier(username, password, impl.s) };
65 }
66
67 bool CheckCredentials(std::string const& username, std::string const& password) const;
68
69 Salt const s; // s - the user's password salt, random, used to calculate v on registration
70
71 protected:
72 static BigNumber CalculatePrivateB(BigNumber const& N);
73
74 BigNumber CalculatePublicB(BigNumber const& N, BigNumber const& g, BigNumber const& k) const;
75
76 virtual BigNumber CalculateX(std::string const& username, std::string const& password, Salt const& salt) const = 0;
77
78 Verifier CalculateVerifier(std::string const& username, std::string const& password, Salt const& salt) const;
79
80 virtual Optional<BigNumber> DoVerifyClientEvidence(BigNumber const& A, BigNumber const& clientM1) = 0;
81
82 BigNumber const I; // H(I) - the username, all uppercase
83 BigNumber const b; // b - randomly chosen by the server, same length as N, never given out
84 BigNumber const v; // v - the user's password verifier, derived from s + H(USERNAME || ":" || PASSWORD)
85
86 public:
87 BigNumber const B; // B = k*v + g^b
88
89 private:
90 bool _used = false; // a single instance can only be used to verify once
91 };
92
93 class TC_COMMON_API GruntSRP6 final : public SRP6
94 {
95 public:
96 static constexpr size_t EPHEMERAL_KEY_LENGTH = 32;
97
98 using EphemeralKey = std::array<uint8, EPHEMERAL_KEY_LENGTH>;
99
100 using SessionKey = std::array<uint8, SHA1::DIGEST_LENGTH * 2>;
101
102 static BigNumber const N; // the modulus, an algorithm parameter; all operations are mod this
103 static BigNumber const g; // a [g]enerator for the ring of integers mod N, algorithm parameter
104
105 explicit GruntSRP6(std::string const& username, Salt const& salt, Verifier const& verifier);
106 explicit GruntSRP6(ForRegistrationTag t) : SRP6(t) { }
107
108 BigNumber const& GetN() const override { return N; }
109 BigNumber const& Getg() const override { return g; }
110
111 BigNumber CalculateServerEvidence(BigNumber const& A, BigNumber const& clientM1, BigNumber const& K) const override;
112
113 protected:
114 BigNumber CalculateX(std::string const& username, std::string const& password, Salt const& salt) const override;
115
116 Optional<BigNumber> DoVerifyClientEvidence(BigNumber const& A, BigNumber const& clientM1) override;
117
118 static SessionKey SHA1Interleave(EphemeralKey const& S);
119 };
120
122 {
123 public:
124 explicit BnetSRP6Base(BigNumber const& i, Salt const& salt, Verifier const& verifier, BigNumber const& N, BigNumber const& g, BigNumber const& k);
126
127 BigNumber CalculateServerEvidence(BigNumber const& A, BigNumber const& clientM1, BigNumber const& K) const final;
128
129 virtual uint8 GetVersion() const = 0;
130 virtual uint32 GetXIterations() const = 0;
131
132 protected:
133 Optional<BigNumber> DoVerifyClientEvidence(BigNumber const& A, BigNumber const& clientM1) final;
134
135 virtual BigNumber CalculateU(BigNumber const& A) const = 0;
136
137 virtual BigNumber DoCalculateEvidence(std::span<BigNumber const*> bns) const = 0;
138
139 template<typename CryptoHash>
140 BigNumber DoCalculateEvidence(std::span<BigNumber const*> bns) const
141 {
142 CryptoHash hash;
143 for (BigNumber const* bn : bns)
144 hash.UpdateData(GetBrokenEvidenceVector(*bn));
145
146 hash.Finalize();
147 return BigNumber(hash.GetDigest(), false);
148 }
149
150 static std::vector<uint8> GetBrokenEvidenceVector(BigNumber const& bn);
151 };
152
154 {
155 public:
156 static BigNumber const N; // the modulus, an algorithm parameter; all operations are mod this
157 static BigNumber const g; // a [g]enerator for the ring of integers mod N, algorithm parameter
158
159 explicit BnetSRP6v1Base(std::string const& username, Salt const& salt, Verifier const& verifier, BigNumber const& k);
161
162 BigNumber const& GetN() const final { return N; }
163 BigNumber const& Getg() const final { return g; }
164
165 uint8 GetVersion() const final { return 1; }
166 uint32 GetXIterations() const final { return 1; }
167
168 protected:
169 BigNumber CalculateX(std::string const& username, std::string const& password, Salt const& salt) const final;
170 };
171
173 {
174 public:
175 static BigNumber const N; // the modulus, an algorithm parameter; all operations are mod this
176 static BigNumber const g; // a [g]enerator for the ring of integers mod N, algorithm parameter
177
178 explicit BnetSRP6v2Base(std::string const& username, Salt const& salt, Verifier const& verifier, BigNumber const& k);
180
181 BigNumber const& GetN() const final { return N; }
182 BigNumber const& Getg() const final { return g; }
183
184 uint8 GetVersion() const final { return 2; }
185 uint32 GetXIterations() const final { return 15000; }
186
187 protected:
188 BigNumber CalculateX(std::string const& username, std::string const& password, Salt const& salt) const final;
189 };
190
191 template<typename CryptoHash>
192 class BnetSRP6v1 final : public BnetSRP6v1Base
193 {
194 public:
195 BnetSRP6v1(std::string const& username, Salt const& salt, Verifier const& verifier)
196 : BnetSRP6v1Base(username, salt, verifier, BigNumber(CryptoHash::GetDigestOf(N.ToByteArray<128>(false), g.ToByteArray<128>(false)), false))
197 {
198 }
199
201
202 protected:
203 BigNumber CalculateU(BigNumber const& A) const override
204 {
205 return BigNumber(CryptoHash::GetDigestOf(A.ToByteArray<128>(false), B.ToByteArray<128>(false)), false);
206 }
207
208 BigNumber DoCalculateEvidence(std::span<BigNumber const*> bns) const override
209 {
210 return BnetSRP6Base::DoCalculateEvidence<CryptoHash>(bns);
211 }
212 };
213
214 template<typename CryptoHash>
215 class BnetSRP6v2 final : public BnetSRP6v2Base
216 {
217 public:
218 BnetSRP6v2(std::string const& username, Salt const& salt, Verifier const& verifier)
219 : BnetSRP6v2Base(username, salt, verifier, BigNumber(CryptoHash::GetDigestOf(N.ToByteArray<256>(false), g.ToByteArray<256>(false)), false))
220 {
221 }
222
224
225 protected:
226 BigNumber CalculateU(BigNumber const& A) const override
227 {
228 return BigNumber(CryptoHash::GetDigestOf(A.ToByteArray<256>(false), B.ToByteArray<256>(false)), false);
229 }
230
231 BigNumber DoCalculateEvidence(std::span<BigNumber const*> bns) const override
232 {
233 return BnetSRP6Base::DoCalculateEvidence<CryptoHash>(bns);
234 }
235 };
236}
237
238using SRP::SRP6;
239}
240
241#endif
std::array< uint8, SESSION_KEY_LENGTH > SessionKey
Definition: AuthDefines.h:25
uint8_t uint8
Definition: Define.h:144
#define TC_COMMON_API
Definition: Define.h:99
uint32_t uint32
Definition: Define.h:142
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
std::array< uint8, Size > ToByteArray(bool littleEndian=true) const
Definition: BigNumber.h:128
virtual uint8 GetVersion() const =0
BnetSRP6Base(ForRegistrationTag t)
Definition: SRP6.h:125
BigNumber DoCalculateEvidence(std::span< BigNumber const * > bns) const
Definition: SRP6.h:140
virtual uint32 GetXIterations() const =0
virtual BigNumber CalculateU(BigNumber const &A) const =0
virtual BigNumber DoCalculateEvidence(std::span< BigNumber const * > bns) const =0
uint32 GetXIterations() const final
Definition: SRP6.h:166
static BigNumber const g
Definition: SRP6.h:157
BigNumber const & GetN() const final
Definition: SRP6.h:162
BnetSRP6v1Base(ForRegistrationTag t)
Definition: SRP6.h:160
uint8 GetVersion() const final
Definition: SRP6.h:165
BigNumber const & Getg() const final
Definition: SRP6.h:163
static BigNumber const N
Definition: SRP6.h:156
BnetSRP6v1(ForRegistrationTag t)
Definition: SRP6.h:200
BnetSRP6v1(std::string const &username, Salt const &salt, Verifier const &verifier)
Definition: SRP6.h:195
BigNumber CalculateU(BigNumber const &A) const override
Definition: SRP6.h:203
BigNumber DoCalculateEvidence(std::span< BigNumber const * > bns) const override
Definition: SRP6.h:208
static BigNumber const N
Definition: SRP6.h:175
BigNumber const & Getg() const final
Definition: SRP6.h:182
uint8 GetVersion() const final
Definition: SRP6.h:184
static BigNumber const g
Definition: SRP6.h:176
uint32 GetXIterations() const final
Definition: SRP6.h:185
BnetSRP6v2Base(ForRegistrationTag t)
Definition: SRP6.h:179
BigNumber const & GetN() const final
Definition: SRP6.h:181
BnetSRP6v2(std::string const &username, Salt const &salt, Verifier const &verifier)
Definition: SRP6.h:218
BigNumber DoCalculateEvidence(std::span< BigNumber const * > bns) const override
Definition: SRP6.h:231
BnetSRP6v2(ForRegistrationTag t)
Definition: SRP6.h:223
BigNumber CalculateU(BigNumber const &A) const override
Definition: SRP6.h:226
static BigNumber const g
Definition: SRP6.h:103
std::array< uint8, EPHEMERAL_KEY_LENGTH > EphemeralKey
Definition: SRP6.h:98
GruntSRP6(ForRegistrationTag t)
Definition: SRP6.h:106
static BigNumber const N
Definition: SRP6.h:102
BigNumber const & Getg() const override
Definition: SRP6.h:109
BigNumber const & GetN() const override
Definition: SRP6.h:108
std::array< uint8, SHA1::DIGEST_LENGTH *2 > SessionKey
Definition: SRP6.h:100
BigNumber const I
Definition: SRP6.h:82
virtual ~SRP6()=default
SRP6 & operator=(SRP6 const &)=delete
virtual BigNumber const & Getg() const =0
virtual Optional< BigNumber > DoVerifyClientEvidence(BigNumber const &A, BigNumber const &clientM1)=0
SRP6 & operator=(SRP6 &&)=delete
virtual BigNumber CalculateX(std::string const &username, std::string const &password, Salt const &salt) const =0
static std::pair< Salt, Verifier > MakeRegistrationData(std::string const &username, std::string const &password)
Definition: SRP6.h:61
virtual BigNumber const & GetN() const =0
BigNumber const v
Definition: SRP6.h:84
SRP6(SRP6 const &)=delete
virtual BigNumber CalculateServerEvidence(BigNumber const &A, BigNumber const &clientM1, BigNumber const &K) const =0
BigNumber const b
Definition: SRP6.h:83
BigNumber const B
Definition: SRP6.h:87
std::array< uint8, SALT_LENGTH > Salt
Definition: SRP6.h:33
std::vector< uint8 > Verifier
Definition: SRP6.h:35
static constexpr size_t SALT_LENGTH
Definition: SRP6.h:32