Skip to content

Commit 110aee2

Browse files
committed
CSHARP-1389: use a constant time comparison function for ScramSha1 signature comparisons.
1 parent 16501c0 commit 110aee2

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
@@ -162,7 +162,7 @@ public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedF
162162
var proof = "p=" + Convert.ToBase64String(clientProof);
163163
var clientFinalMessage = clientFinalMessageWithoutProof + "," + proof;
164164

165-
return new ClientLast(encoding.GetBytes(clientFinalMessage), Convert.ToBase64String(serverSignature));
165+
return new ClientLast(encoding.GetBytes(clientFinalMessage), serverSignature);
166166
}
167167

168168
private static byte[] XOR(byte[] a, byte[] b)
@@ -204,9 +204,9 @@ private static byte[] HMAC(UTF8Encoding encoding, byte[] data, string key)
204204
private class ClientLast : ISaslStep
205205
{
206206
private readonly byte[] _bytesToSendToServer;
207-
private readonly string _serverSignature64;
207+
private readonly byte[] _serverSignature64;
208208

209-
public ClientLast(byte[] bytesToSendToServer, string serverSignature64)
209+
public ClientLast(byte[] bytesToSendToServer, byte[] serverSignature64)
210210
{
211211
_bytesToSendToServer = bytesToSendToServer;
212212
_serverSignature64 = serverSignature64;
@@ -226,16 +226,26 @@ public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedF
226226
{
227227
var encoding = Utf8Encodings.Strict;
228228
var map = NVParser.Parse(encoding.GetString(bytesReceivedFromServer));
229+
var serverSignature = Convert.FromBase64String(map['v']);
229230

230-
var serverSignature = map['v'];
231-
232-
if (_serverSignature64 != serverSignature)
231+
if (!ConstantTimeEquals(_serverSignature64, serverSignature))
233232
{
234233
throw new MongoAuthenticationException(conversation.ConnectionId, message: "Server signature was invalid.");
235234
}
236235

237236
return new CompletedStep();
238237
}
238+
239+
private bool ConstantTimeEquals(byte[] a, byte[] b)
240+
{
241+
var diff = a.Length ^ b.Length;
242+
for (var i = 0; i < a.Length && i < b.Length; i++)
243+
{
244+
diff |= a[i] ^ b[i];
245+
}
246+
247+
return diff == 0;
248+
}
239249
}
240250

241251
private class NVParser

0 commit comments

Comments
 (0)