Skip to content

Commit 922bfbc

Browse files
committed
CSHARP-1389: use a constant time comparison function for ScramSha1 signature comparisons.
1 parent 188c3ed commit 922bfbc

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/MongoDB.Driver.Core/Core/Authentication/ScramSha1Authenticator.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedF
177177
var proof = "p=" + Convert.ToBase64String(clientProof);
178178
var clientFinalMessage = clientFinalMessageWithoutProof + "," + proof;
179179

180-
return new ClientLast(encoding.GetBytes(clientFinalMessage), Convert.ToBase64String(serverSignature));
180+
return new ClientLast(encoding.GetBytes(clientFinalMessage), serverSignature);
181181
}
182182

183183
private static byte[] XOR(byte[] a, byte[] b)
@@ -219,9 +219,9 @@ private static byte[] HMAC(UTF8Encoding encoding, byte[] data, string key)
219219
private class ClientLast : ISaslStep
220220
{
221221
private readonly byte[] _bytesToSendToServer;
222-
private readonly string _serverSignature64;
222+
private readonly byte[] _serverSignature64;
223223

224-
public ClientLast(byte[] bytesToSendToServer, string serverSignature64)
224+
public ClientLast(byte[] bytesToSendToServer, byte[] serverSignature64)
225225
{
226226
_bytesToSendToServer = bytesToSendToServer;
227227
_serverSignature64 = serverSignature64;
@@ -241,16 +241,26 @@ public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedF
241241
{
242242
var encoding = Utf8Encodings.Strict;
243243
var map = NVParser.Parse(encoding.GetString(bytesReceivedFromServer));
244+
var serverSignature = Convert.FromBase64String(map['v']);
244245

245-
var serverSignature = map['v'];
246-
247-
if (_serverSignature64 != serverSignature)
246+
if (!ConstantTimeEquals(_serverSignature64, serverSignature))
248247
{
249248
throw new MongoAuthenticationException(conversation.ConnectionId, message: "Server signature was invalid.");
250249
}
251250

252251
return new CompletedStep();
253252
}
253+
254+
private bool ConstantTimeEquals(byte[] a, byte[] b)
255+
{
256+
var diff = a.Length ^ b.Length;
257+
for (var i = 0; i < a.Length && i < b.Length; i++)
258+
{
259+
diff |= a[i] ^ b[i];
260+
}
261+
262+
return diff == 0;
263+
}
254264
}
255265

256266
private class NVParser

0 commit comments

Comments
 (0)