示例#1
0
            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);
        }
示例#3
0
            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);
        }
示例#7
0
 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;
        }
示例#10
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());
            }
 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);
        }
示例#13
0
 public WaitingForAuthResponse(string nonce, byte[] password, ScramAttributes clientFirstMessageBare)
 {
     this.nonce = nonce;
     this.password = password;
     this.clientFirstMessageBare = clientFirstMessageBare;
 }
示例#14
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));
            }
示例#15
0
 public WaitingForAuthResponse(string nonce, byte[] password, ScramAttributes clientFirstMessageBare)
 {
     this.nonce    = nonce;
     this.password = password;
     this.clientFirstMessageBare = clientFirstMessageBare;
 }
示例#16
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);
            }
示例#17
0
 internal WaitingForProtocolRange(
     string nonce,
     byte[] password,
     ScramAttributes clientFirstMessageBare,
     byte[] message)
 {
     this.nonce = nonce;
     this.password = password;
     this.clientFirstMessageBare = clientFirstMessageBare;
     this.message = message;
 }