public ScramAttributes SetClientProof(byte[] clientProof)
        {
            ScramAttributes next = ScramAttributes.From(this);

            next.ClientProof = Convert.ToBase64String(clientProof);
            return(next);
        }
        public ScramAttributes SetHeaderAndChannelBinding(string hacb)
        {
            ScramAttributes next = ScramAttributes.From(this);

            next.HeaderAndChannelBinding = hacb;
            return(next);
        }
        public ScramAttributes SetNonce(string nonce)
        {
            ScramAttributes next = ScramAttributes.From(this);

            next.Nonce = nonce;
            return(next);
        }
        // Setters with coercion
        public ScramAttributes SetUsername(string username)
        {
            ScramAttributes next = ScramAttributes.From(this);

            next.Username = username.Replace("=", "=3D").Replace(",", "=2C");
            return(next);
        }
示例#5
0
            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());
            }
示例#6
0
            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));
            }