Exemple #1
0
        public void Authenticate()
        {
            var clientFirstMessage = new ClientFirstMessage(_username, _nonce);

            Send(clientFirstMessage.Message);

            var serverFirstMessage = ServerFirstMessage.ParseResponse(Receive());
            var hashedPassword     = Hash.ComputeHash(Encoding.UTF8.GetBytes(_password), serverFirstMessage.Salt.Value,
                                                      serverFirstMessage.Iterations.Value);
            var clientKey = Hash.ComputeHash(Encoding.UTF8.GetBytes("Client Key"), hashedPassword);
            var serverKey = Hash.ComputeHash(Encoding.UTF8.GetBytes("Server Key"), hashedPassword);
            var storedKey = Hash.ComputeHash(clientKey);

            var clientFinalMessage = new ClientFinalMessage(clientFirstMessage, serverFirstMessage);
            var authMessage        =
                $"{clientFirstMessage.BareMessage},{serverFirstMessage},{clientFinalMessage.MessageWithoutProof}";
            var clientSignature = Hash.ComputeHash(Encoding.UTF8.GetBytes(authMessage), storedKey);
            var serverSignature = Hash.ComputeHash(Encoding.UTF8.GetBytes(authMessage), serverKey);
            var clientProof     = clientKey.ExclusiveOr(clientSignature);

            clientFinalMessage.SetProof(clientProof);

            Send(clientFinalMessage.Message);

            var serverFinalMessage = ServerFinalMessage.ParseResponse(Receive());

            if (!serverFinalMessage.ServerSignature.Equals(serverSignature))
            {
                throw new InvalidOperationException();
            }
        }
        public void When_Created_PropertiesShouldBeValid()
        {
            var clientFirst = new ClientFirstMessage("user", "nonce");
            var serverFirst = new ServerFirstMessage(4096, "nonce", "salt");

            var message = new ClientFinalMessage(clientFirst, serverFirst);

            message.Channel.Value.ShouldBe("biws");
            message.Nonce.Value.ShouldBe("nonce");
            message.Proof.ShouldBeNull();
            message.Message.ShouldBe("c=biws,r=nonce,");
            message.MessageWithoutProof.ShouldBe("c=biws,r=nonce");
        }
        public void When_ProofIsSetAsString_PropertiesShouldBeValid()
        {
            var clientFirst = new ClientFirstMessage("user", "nonce");
            var serverFirst = new ServerFirstMessage(4096, "nonce", "salt");

            var message = new ClientFinalMessage(clientFirst, serverFirst);

            message.SetProof("bf45fcbf7073d93d022466c94321745fe1c8e13b");

            message.Channel.Value.ShouldBe("biws");
            message.Nonce.Value.ShouldBe("nonce");
            message.Proof?.ToString().ShouldBe("p=bf45fcbf7073d93d022466c94321745fe1c8e13b");
            message.Message.ShouldBe("c=biws,r=nonce,p=bf45fcbf7073d93d022466c94321745fe1c8e13b");
            message.MessageWithoutProof.ShouldBe("c=biws,r=nonce");
        }
        /// <inheritdoc />
        /// <summary>
        ///     Initializes the SASL processor
        /// </summary>
        /// <param name="id"><see cref="T:Ubiety.Xmpp.Core.Common.Jid" /> of the user for the session</param>
        /// <param name="password">Password of the user</param>
        /// <returns>Next tag to send to the server</returns>
        public override Tag Initialize(Jid id, string password)
        {
            base.Initialize(id, password);

            Logger.Log(LogLevel.Debug, "Initializing SCRAM SASL processor");

            var nonce = CreateNonce();

            _clientFirstMessage = new ClientFirstMessage(_saslprep.Run(Id.User), nonce);
            Logger.Log(LogLevel.Debug, _clientFirstMessage.Message);

            var auth = Client.Registry.GetTag <Auth>(Auth.XmlName);

            auth.MechanismType = _channelBinding ? MechanismTypes.ScramPlus : MechanismTypes.Scram;
            auth.Bytes         = _encoding.GetBytes(_clientFirstMessage.Message);

            return(auth);
        }
        public bool Authenticate(IConnection connection, string username, string password)
        {
            var authenticated = false;

            ClientFirstMessage     = "n,,n=" + username + ",r=" + ClientNonce;
            ClientFirstMessageBare = ClientFirstMessage.Substring(3);

            Log.Debug("Client First Message {0} - {1}: {2} [U:{3}|P:{4}", connection.EndPoint, connection.Identity, ClientFirstMessage, username, password);
            var authOp            = new SaslStart(MechanismType, ClientFirstMessage, _transcoder, SaslFactory.DefaultTimeout);
            var serverFirstResult = Execute(authOp, connection);

            if (serverFirstResult.Status == ResponseStatus.AuthenticationContinue)
            {
                Log.Debug("Server First Message {0} - {1}: {2}", connection.EndPoint, connection.Identity, serverFirstResult.Message);

                //get the server nonce, salt and iterationcount from the server
                var serverFirstMessage = DecodeResponse(serverFirstResult.Value);
                ServerNonce    = serverFirstMessage["r"];
                Salt           = Convert.FromBase64String(serverFirstMessage["s"]);
                IterationCount = Convert.ToInt32(serverFirstMessage["i"]);

                //normalize and salt the password using the salt and iteration count
                var normalizedPassword = password.Normalize(NormalizationForm.FormKC);
                SaltedPassword = GetSaltedPassword(normalizedPassword);

                //build the final client message
                ClientFinalMessageNoProof = "c=biws,r=" + ServerNonce;
                ClientFinalMessage        = ClientFinalMessageNoProof + ",p=" + Convert.ToBase64String(GetClientProof());
                Log.Debug("Client Final Message {0} - {1}: {2}", connection.EndPoint, connection.Identity, ClientFinalMessage);

                //send the final client message
                authOp = new SaslStep(MechanismType, ClientFinalMessage, _transcoder, SaslFactory.DefaultTimeout);
                var serverFinalResult = Execute(authOp, connection);
                Log.Debug("Server Final Message {0} - {1}: {2}", connection.EndPoint, connection.Identity, serverFinalResult.Message);
                authenticated = serverFinalResult.Status == ResponseStatus.Success;
            }
            return(authenticated);
        }
        public void When_NonceIsSet_ExpectNoncePropertyToMatch()
        {
            var message = new ClientFirstMessage("", "fyko+d2lbbFgONRv9qkxdawL");

            message.Nonce?.ToString().ShouldBe("r=fyko+d2lbbFgONRv9qkxdawL");
        }
        public void When_UsernameIsSet_ExpectUsernamePropertyToMatch()
        {
            var message = new ClientFirstMessage("user", "");

            message.Username?.ToString().ShouldBe("n=user");
        }
        public void When_UsernameAndNonceAreSet_ExpectMessageToMatch()
        {
            var message = new ClientFirstMessage("user", "fyko+d2lbbFgONRv9qkxdawL");

            message.Message.ShouldBe("n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL");
        }
Exemple #9
0
 public ClientFinalMessage(ClientFirstMessage clientFirstMessage, ServerFirstMessage serverFirstMessage)
 {
     Channel = new ChannelAttribute(clientFirstMessage.Gs2Header);
     Nonce   = new NonceAttribute(serverFirstMessage.Nonce.Value);
 }