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"); }
public ClientFinalMessage(ClientFirstMessage clientFirstMessage, ServerFirstMessage serverFirstMessage) { Channel = new ChannelAttribute(clientFirstMessage.Gs2Header); Nonce = new NonceAttribute(serverFirstMessage.Nonce.Value); }