/// <summary> /// Try to get a cached entry. /// </summary> /// <param name="key">The key.</param> /// <param name="entry">The entry.</param> /// <returns>True if the cache contained an entry for the key.</returns> public bool TryGet(ScramCacheKey key, out ScramCacheEntry entry) { if (key.Equals(_cacheKey)) { entry = _cachedEntry; return(true); } else { entry = null; return(false); } }
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 override bool Equals(object obj) { if (this == obj) { return(true); } if (obj == null || obj.GetType() != obj.GetType()) { return(false); } ScramCacheKey other = (ScramCacheKey)obj; return (Equals(_password, other._password) && _iterationCount == other._iterationCount && _salt.SequenceEqual(other._salt)); }
/// <summary> /// Add a cached entry. /// </summary> /// <param name="key">The key.</param> /// <param name="entry">The entry.</param> public void Add(ScramCacheKey key, ScramCacheEntry entry) { _cacheKey = key; _cachedEntry = entry; }