/* In response, the server sends a "server-first-message" containing the * user's iteration count i and the user's salt, and appends its own * nonce to the client-specified one. */ private static string CreateSaslStartReply( string clientSaslStart, string serverNonce, string serverSalt, int iterationCount) { // strip expected GS2 header of "n,," before parsing map var clientNonce = SaslMapParser.Parse(clientSaslStart.Substring(3))['r']; return($"r={clientNonce}{serverNonce},s={serverSalt},i={iterationCount}"); }
public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedFromServer) { var encoding = Utf8Encodings.Strict; var map = SaslMapParser.Parse(encoding.GetString(bytesReceivedFromServer)); var serverSignature = Convert.FromBase64String(map['v']); if (!ConstantTimeEquals(_serverSignature64, serverSignature)) { throw new MongoAuthenticationException(conversation.ConnectionId, message: "Server signature was invalid."); } return(new CompletedStep()); }
public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedFromServer) { var encoding = Utf8Encodings.Strict; var serverFirstMessage = encoding.GetString(bytesReceivedFromServer); var map = SaslMapParser.Parse(serverFirstMessage); var r = map['r']; if (!r.StartsWith(_rPrefix, StringComparison.Ordinal)) { throw new MongoAuthenticationException(conversation.ConnectionId, message: "Server sent an invalid nonce."); } var s = map['s']; var i = map['i']; const string gs2Header = "n,,"; var channelBinding = "c=" + Convert.ToBase64String(encoding.GetBytes(gs2Header)); var nonce = "r=" + r; var clientFinalMessageWithoutProof = channelBinding + "," + nonce; var salt = Convert.FromBase64String(map['s']); var iterations = int.Parse(map['i']); byte[] clientKey; byte[] serverKey; var cacheKey = new ScramCacheKey(_credential.SaslPreppedPassword, salt, iterations); if (_cache.TryGet(cacheKey, out var cacheEntry)) { clientKey = cacheEntry.ClientKey; serverKey = cacheEntry.ServerKey; } else { var saltedPassword = _hi(_credential, salt, iterations); clientKey = _hmac(encoding, saltedPassword, "Client Key"); serverKey = _hmac(encoding, saltedPassword, "Server Key"); _cache.Add(cacheKey, new ScramCacheEntry(clientKey, serverKey)); } var storedKey = _h(clientKey); var authMessage = _clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof; var clientSignature = _hmac(encoding, storedKey, authMessage); var clientProof = XOR(clientKey, clientSignature); var serverSignature = _hmac(encoding, serverKey, authMessage); var proof = "p=" + Convert.ToBase64String(clientProof); var clientFinalMessage = clientFinalMessageWithoutProof + "," + proof; return(new ClientLast(encoding.GetBytes(clientFinalMessage), serverSignature)); }
public ISaslStep Transition(SaslConversation conversation, byte[] bytesReceivedFromServer) { var encoding = Utf8Encodings.Strict; var serverFirstMessage = encoding.GetString(bytesReceivedFromServer); var map = SaslMapParser.Parse(serverFirstMessage); var r = map['r']; if (!r.StartsWith(_rPrefix)) { throw new MongoAuthenticationException(conversation.ConnectionId, message: "Server sent an invalid nonce."); } var s = map['s']; var i = map['i']; const string gs2Header = "n,,"; var channelBinding = "c=" + Convert.ToBase64String(encoding.GetBytes(gs2Header)); var nonce = "r=" + r; var clientFinalMessageWithoutProof = channelBinding + "," + nonce; var saltedPassword = _hi( _credential, Convert.FromBase64String(s), int.Parse(i)); var clientKey = _hmac(encoding, saltedPassword, "Client Key"); var storedKey = _h(clientKey); var authMessage = _clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof; var clientSignature = _hmac(encoding, storedKey, authMessage); var clientProof = XOR(clientKey, clientSignature); var serverKey = _hmac(encoding, saltedPassword, "Server Key"); var serverSignature = _hmac(encoding, serverKey, authMessage); var proof = "p=" + Convert.ToBase64String(clientProof); var clientFinalMessage = clientFinalMessageWithoutProof + "," + proof; return(new ClientLast(encoding.GetBytes(clientFinalMessage), serverSignature)); }