public IProtocolState NextState(string response) { if( response != null ) { throw new ReqlDriverError("Unexpected response"); } // We could use a json serializer, but it's fairly straightforward var clientFirstMessageBare = new ScramAttributes() .SetUsername(username) .SetNonce(nonce); byte[] jsonBytes = Encoding.UTF8.GetBytes( "{" + "\"protocol_version\":" + SubProtocolVersion + "," + "\"authentication_method\":\"SCRAM-SHA-256\"," + "\"authentication\":" + "\"n,," + clientFirstMessageBare + "\"" + "}" ); byte[] msg; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { bw.Write((int)Version); bw.Write(jsonBytes); bw.Write('\0'); bw.Flush(); msg = ms.ToArray(); } return new WaitingForProtocolRange( nonce, password, clientFirstMessageBare, msg); }
public ScramAttributes SetHeaderAndChannelBinding(string hacb) { ScramAttributes next = ScramAttributes.From(this); next.HeaderAndChannelBinding = hacb; return(next); }
public IProtocolState NextState(string response) { if (response != null) { throw new ReqlDriverError("Unexpected response"); } // We could use a json serializer, but it's fairly straightforward var clientFirstMessageBare = new ScramAttributes() .SetUsername(username) .SetNonce(nonce); byte[] jsonBytes = Encoding.UTF8.GetBytes( "{" + "\"protocol_version\":" + SubProtocolVersion + "," + "\"authentication_method\":\"SCRAM-SHA-256\"," + "\"authentication\":" + "\"n,," + clientFirstMessageBare + "\"" + "}" ); byte[] msg; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { bw.Write((int)Version); bw.Write(jsonBytes); bw.Write('\0'); bw.Flush(); msg = ms.ToArray(); } return(new WaitingForProtocolRange( nonce, password, clientFirstMessageBare, msg)); }
public ScramAttributes SetNonce(string nonce) { ScramAttributes next = ScramAttributes.From(this); next.Nonce = nonce; return(next); }
public ScramAttributes SetClientProof(byte[] clientProof) { ScramAttributes next = ScramAttributes.From(this); next.ClientProof = Convert.ToBase64String(clientProof); return(next); }
// Setters with coercion public ScramAttributes SetUsername(string username) { ScramAttributes next = ScramAttributes.From(this); next.Username = username.Replace("=", "=3D").Replace(",", "=2C"); return(next); }
internal WaitingForProtocolRange( string nonce, byte[] password, ScramAttributes clientFirstMessageBare, byte[] message) { this.nonce = nonce; this.password = password; this.clientFirstMessageBare = clientFirstMessageBare; this.message = message; }
public static ScramAttributes From(string input) { var sa = new ScramAttributes { OriginalString = input }; foreach (string section in input.Split(',')) { string[] keyVal = section.Split(new[] { '=' }, 2); sa.SetAttribute(keyVal[0], keyVal[1]); } return(sa); }
public static ScramAttributes From(string input) { var sa = new ScramAttributes { OriginalString = input }; foreach( string section in input.Split(',')) { string[] keyVal = section.Split(new[] {'='}, 2); sa.SetAttribute(keyVal[0], keyVal[1]); } return sa; }
public IProtocolState NextState(string response) { var json = JObject.Parse(response); ThrowIfFailure(json); ScramAttributes auth = ScramAttributes .From(json["authentication"].Value <string>()); if (!auth.ServerSignature.SequenceEqual(serverSignature)) { throw new ReqlAuthError("Invalid server signature"); } return(new HandshakeSuccess()); }
public static ScramAttributes From(ScramAttributes other) { var obj = new ScramAttributes { AuthIdentity = other.AuthIdentity, Username = other.Username, Nonce = other.Nonce, HeaderAndChannelBinding = other.HeaderAndChannelBinding, Salt = other.Salt, IterationCount = other.IterationCount, ClientProof = other.ClientProof, ServerSignature = other.ServerSignature, Error = other.Error }; return obj; }
public static ScramAttributes From(ScramAttributes other) { var obj = new ScramAttributes { AuthIdentity = other.AuthIdentity, Username = other.Username, Nonce = other.Nonce, HeaderAndChannelBinding = other.HeaderAndChannelBinding, Salt = other.Salt, IterationCount = other.IterationCount, ClientProof = other.ClientProof, ServerSignature = other.ServerSignature, Error = other.Error }; return(obj); }
public WaitingForAuthResponse(string nonce, byte[] password, ScramAttributes clientFirstMessageBare) { this.nonce = nonce; this.password = password; this.clientFirstMessageBare = clientFirstMessageBare; }
public IProtocolState NextState(string response) { var json = JObject.Parse(response); ThrowIfFailure(json); string serverFirstMessage = json["authentication"].Value <string>(); ScramAttributes serverAuth = ScramAttributes.From(serverFirstMessage); if (!serverAuth.Nonce.StartsWith(nonce)) { throw new ReqlAuthError("Invalid nonce from server"); } ScramAttributes clientFinalMessageWithoutProof = new ScramAttributes() .SetHeaderAndChannelBinding("biws") .SetNonce(serverAuth.Nonce); // SaltedPassword := Hi(Normalize(password), salt, i) byte[] saltedPassword = Crypto.Pbkdf2( password, serverAuth.Salt, serverAuth.IterationCount); // ClientKey := HMAC(SaltedPassword, "Client Key") byte[] clientKey = Crypto.Hmac(saltedPassword, ClientKey); // StoredKey := H(ClientKey) byte[] storedKey = Crypto.Sha256(clientKey); // AuthMessage := client-first-message-bare + "," + // server-first-message + "," + // client-final-message-without-proof string authMessage = clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof; // ClientSignature := HMAC(StoredKey, AuthMessage) byte[] clientSignature = Crypto.Hmac(storedKey, authMessage); // ClientProof := ClientKey XOR ClientSignature byte[] clientProof = Crypto.Xor(clientKey, clientSignature); // ServerKey := HMAC(SaltedPassword, "Server Key") byte[] serverKey = Crypto.Hmac(saltedPassword, ServerKey); // ServerSignature := HMAC(ServerKey, AuthMessage) byte[] serverSignature = Crypto.Hmac(serverKey, authMessage); ScramAttributes auth = clientFinalMessageWithoutProof .SetClientProof(clientProof); byte[] authJson = Encoding.UTF8.GetBytes("{\"authentication\":\"" + auth + "\"}"); byte[] message; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { bw.Write(authJson); bw.Write('\0'); bw.Flush(); message = ms.ToArray(); } return(new WaitingForAuthSuccess(serverSignature, message)); }
public IProtocolState NextState(string response) { var json = JObject.Parse(response); ThrowIfFailure(json); string serverFirstMessage = json["authentication"].Value<string>(); ScramAttributes serverAuth = ScramAttributes.From(serverFirstMessage); if( !serverAuth.Nonce.StartsWith(nonce) ) { throw new ReqlAuthError("Invalid nonce from server"); } ScramAttributes clientFinalMessageWithoutProof = new ScramAttributes() .SetHeaderAndChannelBinding("biws") .SetNonce(serverAuth.Nonce); // SaltedPassword := Hi(Normalize(password), salt, i) byte[] saltedPassword = Crypto.Pbkdf2( password, serverAuth.Salt, serverAuth.IterationCount); // ClientKey := HMAC(SaltedPassword, "Client Key") byte[] clientKey = Crypto.Hmac(saltedPassword, ClientKey); // StoredKey := H(ClientKey) byte[] storedKey = Crypto.Sha256(clientKey); // AuthMessage := client-first-message-bare + "," + // server-first-message + "," + // client-final-message-without-proof string authMessage = clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof; // ClientSignature := HMAC(StoredKey, AuthMessage) byte[] clientSignature = Crypto.Hmac(storedKey, authMessage); // ClientProof := ClientKey XOR ClientSignature byte[] clientProof = Crypto.Xor(clientKey, clientSignature); // ServerKey := HMAC(SaltedPassword, "Server Key") byte[] serverKey = Crypto.Hmac(saltedPassword, ServerKey); // ServerSignature := HMAC(ServerKey, AuthMessage) byte[] serverSignature = Crypto.Hmac(serverKey, authMessage); ScramAttributes auth = clientFinalMessageWithoutProof .SetClientProof(clientProof); byte[] authJson = Encoding.UTF8.GetBytes("{\"authentication\":\"" + auth + "\"}"); byte[] message; using (var ms = new MemoryStream()) using (var bw = new BinaryWriter(ms)) { bw.Write(authJson); bw.Write('\0'); bw.Flush(); message = ms.ToArray(); } return new WaitingForAuthSuccess(serverSignature, message); }