Skip to content

Commit ccb7843

Browse files
committed
Fix for 9cwg-hrvf-rm4j, details after release
1 parent 0193f27 commit ccb7843

4 files changed

Lines changed: 65 additions & 28 deletions

File tree

src/auth/SecureRemotePassword/client/SrpClient.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,12 @@ int SrpClient::authenticate(CheckStatusWrapper* status, IClientBlock* cb)
141141
key.assign(saltAndKey, charSize);
142142
dumpIt("Clnt: key(srvPub)", key);
143143

144+
// validate server pubkey
145+
client->serverPublicKey = client->setKey(key.c_str());
146+
144147
dumpIt("Clnt: login", string(cb->getLogin()));
145148
dumpIt("Clnt: pass", string(cb->getPassword()));
146-
client->clientSessionKey(sessionKey, cb->getLogin(), salt.c_str(), cb->getPassword(), key.c_str());
149+
client->clientSessionKey(sessionKey, cb->getLogin(), salt.c_str(), cb->getPassword());
147150
dumpIt("Clnt: sessionKey", sessionKey);
148151

149152
BigInteger cProof = client->clientProof(cb->getLogin(), salt.c_str(), sessionKey);

src/auth/SecureRemotePassword/server/SrpServer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@ int SrpServer::authenticate(CheckStatusWrapper* status, IServerBlock* sb, IWrite
289289
return AUTH_MORE_DATA;
290290
}
291291

292+
// create SRP-calculating server
293+
server = remotePasswordFactory();
294+
295+
// validate client pubkey
296+
server->clientPublicKey = server->setKey(clientPubKey.c_str());
297+
292298
// load verifier and salt from security database
293299
Metadata messages;
294300
messages.param->login.set(account.c_str());
@@ -319,8 +325,7 @@ int SrpServer::authenticate(CheckStatusWrapper* status, IServerBlock* sb, IWrite
319325
BigInteger(s).getText(salt);
320326
dumpIt("Srv: salt", salt);
321327

322-
// create SRP-calculating server
323-
server = remotePasswordFactory();
328+
// calculate serverPubKey
324329
server->genServerKey(serverPubKey, verifier);
325330

326331
// Ready to prepare data for client and calculate session key
@@ -341,7 +346,7 @@ int SrpServer::authenticate(CheckStatusWrapper* status, IServerBlock* sb, IWrite
341346
return AUTH_FAILED;
342347
}
343348

344-
server->serverSessionKey(sessionKey, clientPubKey.c_str(), verifier);
349+
server->serverSessionKey(sessionKey, verifier);
345350
dumpIt("Srv: sessionKey", sessionKey);
346351
return AUTH_MORE_DATA;
347352
}

src/auth/SecureRemotePassword/srp.cpp

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ string RemotePassword::pluginName(unsigned bits)
6868

6969
RemotePassword::RemotePassword()
7070
: group(RemoteGroup::getGroup())
71+
{
72+
makePrivate();
73+
}
74+
75+
void RemotePassword::makePrivate()
7176
{
7277
#if SRP_DEBUG > 1
7378
privateKey = BigInteger("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393");
@@ -103,23 +108,40 @@ BigInteger RemotePassword::computeVerifier(const string& account, const string&
103108

104109
void RemotePassword::genClientKey(string& pubkey)
105110
{
106-
dumpIt("privateKey(C)", privateKey);
107-
clientPublicKey = group->generator.modPow(privateKey, group->prime);
108-
clientPublicKey.getText(pubkey);
109-
dumpIt("clientPublicKey", clientPublicKey);
111+
for(;;)
112+
{
113+
dumpIt("privateKey(C)", privateKey);
114+
clientPublicKey = group->generator.modPow(privateKey, group->prime);
115+
dumpIt("clientPublicKey", clientPublicKey);
116+
if (clientPublicKey > 1)
117+
{
118+
clientPublicKey.getText(pubkey);
119+
break;
120+
}
121+
dumpIt("remake private key", "");
122+
makePrivate();
123+
}
110124
}
111125

112126
void RemotePassword::genServerKey(string& pubkey, const Firebird::UCharBuffer& verifier)
113127
{
114-
dumpIt("privateKey(S)", privateKey);
115-
BigInteger gb(group->generator.modPow(privateKey, group->prime)); // g^b
116-
dumpIt("gb", gb);
117-
BigInteger v(verifier); // v
118-
BigInteger kv = (group->k * v) % group->prime;
119-
dumpIt("kv", kv);
120-
serverPublicKey = (kv + gb) % group->prime;
121-
serverPublicKey.getText(pubkey);
122-
dumpIt("serverPublicKey", serverPublicKey);
128+
for(;;)
129+
{
130+
dumpIt("privateKey(S)", privateKey);
131+
BigInteger gb(group->generator.modPow(privateKey, group->prime)); // g^b
132+
dumpIt("gb", gb);
133+
BigInteger v(verifier); // v
134+
BigInteger kv = (group->k * v) % group->prime;
135+
dumpIt("kv", kv);
136+
serverPublicKey = (kv + gb) % group->prime;
137+
dumpIt("serverPublicKey", serverPublicKey);
138+
if (serverPublicKey > 1)
139+
{
140+
serverPublicKey.getText(pubkey);
141+
break;
142+
}
143+
makePrivate();
144+
}
123145
}
124146

125147
void RemotePassword::computeScramble()
@@ -133,10 +155,8 @@ void RemotePassword::computeScramble()
133155
}
134156

135157
void RemotePassword::clientSessionKey(UCharBuffer& sessionKey, const char* account,
136-
const char* salt, const char* password,
137-
const char* serverPubKey)
158+
const char* salt, const char* password)
138159
{
139-
serverPublicKey = BigInteger(serverPubKey);
140160
computeScramble();
141161
dumpIt("scramble", scramble);
142162
dumpIt("password", password);
@@ -158,10 +178,8 @@ void RemotePassword::clientSessionKey(UCharBuffer& sessionKey, const char* accou
158178
hash.getHash(sessionKey);
159179
}
160180

161-
void RemotePassword::serverSessionKey(UCharBuffer& sessionKey, const char* clientPubKey,
162-
const UCharBuffer& verifier)
181+
void RemotePassword::serverSessionKey(UCharBuffer& sessionKey, const UCharBuffer& verifier)
163182
{
164-
clientPublicKey = BigInteger(clientPubKey);
165183
computeScramble();
166184
dumpIt("scramble", scramble);
167185
BigInteger v = BigInteger(verifier);
@@ -201,6 +219,15 @@ BigInteger RemotePassword::clientProof(const char* account, const char* salt, co
201219
RemotePassword::~RemotePassword()
202220
{ }
203221

222+
BigInteger RemotePassword::setKey(const char* from)
223+
{
224+
BigInteger key(from);
225+
if (key % group->prime < 2)
226+
(Arg::Gds(isc_random) << "Trivial public key").raise();
227+
228+
return key;
229+
}
230+
204231
#if SRP_DEBUG > 0
205232
void dumpIt(const char* name, const Firebird::UCharBuffer& data)
206233
{
@@ -217,7 +244,7 @@ void dumpIt(const char* name, const Firebird::string& str)
217244

218245
void dumpBin(const char* name, const Firebird::string& str)
219246
{
220-
fprintf(stderr, "%s (%ld)\n", name, str.length());
247+
fprintf(stderr, "%s (%ld)\n", name, long(str.length()));
221248
for (size_t x = 0; x < str.length(); ++x)
222249
fprintf(stderr, "%02x ", str[x]);
223250
fprintf(stderr, "\n");

src/auth/SecureRemotePassword/srp.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ template <class SHA> class SecureHash : public SHA
8484

8585
class RemotePassword : public Firebird::GlobalStorage
8686
{
87-
private:
87+
public:
8888
const RemoteGroup* group;
89+
90+
private:
8991
Auth::SecureHash<Firebird::Sha1> hash;
9092
Firebird::BigInteger privateKey;
9193
Firebird::BigInteger scramble;
@@ -118,11 +120,11 @@ class RemotePassword : public Firebird::GlobalStorage
118120
void genClientKey(Firebird::string& clientPubKey);
119121
void genServerKey(Firebird::string& serverPubKey, const Firebird::UCharBuffer& verifier);
120122
void computeScramble();
123+
void makePrivate();
124+
Firebird::BigInteger setKey(const char* from);
121125
void clientSessionKey(Firebird::UCharBuffer& sessionKey, const char* account,
122-
const char* salt, const char* password,
123-
const char* serverPubKey);
126+
const char* salt, const char* password);
124127
void serverSessionKey(Firebird::UCharBuffer& sessionKey,
125-
const char* clientPubKey,
126128
const Firebird::UCharBuffer& verifier);
127129
Firebird::BigInteger clientProof(const char* account,
128130
const char* salt,

0 commit comments

Comments
 (0)