示例#1
0
        public bool AuthenticateAsClient(Stream stream, byte[] additionalChallenge = null)
        {
            if (additionalChallenge == null)
            {
                additionalChallenge = new byte[] { }
            }
            ;

            byte[] clientNonce = m_nonce.Next();
            stream.WriteWithLength(m_usernameBytes);
            stream.WriteWithLength(clientNonce);
            stream.Flush();

            HashMethod hashMethod = (HashMethod)stream.ReadByte();

            byte[] serverNonce = stream.ReadBytes();
            byte[] salt        = stream.ReadBytes();
            int    iterations  = stream.ReadInt32();

            SetServerValues(hashMethod, salt, iterations);

            byte[] authMessage     = Scram.ComputeAuthMessage(serverNonce, clientNonce, salt, m_usernameBytes, iterations, additionalChallenge);
            byte[] clientSignature = ComputeClientSignature(authMessage);
            byte[] clientProof     = Scram.XOR(m_clientKey, clientSignature);
            stream.WriteWithLength(clientProof);
            stream.Flush();

            byte[] serverSignature       = ComputeServerSignature(authMessage);
            byte[] serverSignatureVerify = stream.ReadBytes();
            return(serverSignature.SecureEquals(serverSignatureVerify));
        }
    }
示例#2
0
        /// <summary>
        /// Requests that the provided stream be authenticated
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="additionalChallenge">Additional data to include in the challenge. If using SSL certificates,
        /// adding the thumbprint to the challenge will allow detecting man in the middle attacks.</param>
        /// <returns></returns>
        public ScramServerSession AuthenticateAsServer(Stream stream, byte[] additionalChallenge = null)
        {
            if (additionalChallenge == null)
            {
                additionalChallenge = new byte[] { }
            }
            ;

            byte[] usernameBytes = stream.ReadBytes();
            byte[] clientNonce   = stream.ReadBytes();

            ScramUserCredential user;

            if (!Users.TryLookup(usernameBytes, out user))
            {
                return(null);
            }

            byte[] serverNonce = m_nonce.Next();
            stream.WriteByte((byte)user.HashMethod);
            stream.WriteWithLength(serverNonce);
            stream.WriteWithLength(user.Salt);
            stream.Write(user.Iterations);
            stream.Flush();

            byte[] authMessage     = Scram.ComputeAuthMessage(serverNonce, clientNonce, user.Salt, usernameBytes, user.Iterations, additionalChallenge);
            byte[] clientSignature = user.ComputeClientSignature(authMessage);
            byte[] serverSignature = user.ComputeServerSignature(authMessage);
            byte[] clientProof     = stream.ReadBytes();

            byte[] clientKeyVerify = Scram.XOR(clientProof, clientSignature);
            byte[] storedKeyVerify = user.ComputeStoredKey(clientKeyVerify);

            if (storedKeyVerify.SecureEquals(user.StoredKey))
            {
                //Client holds the password
                //Send ServerSignature
                stream.WriteWithLength(serverSignature);
                stream.Flush();
                return(new ScramServerSession(user.UserName));
            }
            return(null);
        }
    }