diff --git a/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA1SASLMechanism.cs b/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA1SASLMechanism.cs
index ace448753..2b744a0be 100644
--- a/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA1SASLMechanism.cs
+++ b/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA1SASLMechanism.cs
@@ -84,10 +84,15 @@ public override AbstractMessage generateResponse(AbstractMessage msg)
// Throw wrong order
}
itersStr = itersStr.Substring(2);
- if (!int.TryParse(itersStr, out int iters))
+ int iters = -1;
+ if (!int.TryParse(itersStr, out iters))
{
// Throw could not pars iterations
}
+ else if (!isValidIterationsCount(iters))
+ {
+ // Throw invalid iterations count
+ }
return new ScramSha1ChallengeSolutionMessage(computeAnswer(iters));
}
@@ -106,7 +111,7 @@ public override SelectSASLMechanismMessage getSelectSASLMechanismMessage()
#endregion
#region --Misc Methods (Private)--
- private string computeAnswer(int iterations)
+ protected string computeAnswer(int iterations)
{
string clientFinalMessageBare = "c=biws,r=" + serverNonce;
byte[] saltBytes = Convert.FromBase64String(saltBase64);
@@ -123,6 +128,11 @@ private string computeAnswer(int iterations)
return encodeStringBase64(clientFinalMessage);
}
+ protected virtual bool isValidIterationsCount(int iters)
+ {
+ return iters > 0;
+ }
+
#endregion
#region --Misc Methods (Protected)--
diff --git a/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA256SASLMechanism.cs b/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA256SASLMechanism.cs
new file mode 100644
index 000000000..601eb08ec
--- /dev/null
+++ b/XMPP_API/Classes/Network/XML/Messages/Features/SASL/SHA1/ScramSHA256SASLMechanism.cs
@@ -0,0 +1,69 @@
+namespace XMPP_API.Classes.Network.XML.Messages.Features.SASL.SHA1
+{
+ public class ScramSHA256SASLMechanism : ScramSHA1SASLMechanism
+ {
+ // https://tools.ietf.org/html/rfc7677
+ //--------------------------------------------------------Attributes:-----------------------------------------------------------------\\
+ #region --Attributes--
+ private const byte CLIENT_NONCE_LENGTH = 32;
+
+ private readonly string CLIENT_NONCE_BASE_64;
+ private readonly string PASSWORD_NORMALIZED;
+ private string serverNonce;
+ private string saltBase64;
+ private string clientFirstMsg;
+ private string serverFirstMsg;
+
+ #endregion
+ //--------------------------------------------------------Constructor:----------------------------------------------------------------\\
+ #region --Constructors--
+ ///
+ /// Basic Constructor
+ ///
+ ///
+ /// 06/01/2019 Created [Fabian Sauter]
+ ///
+ public ScramSHA256SASLMechanism(string id, string password) : base(id, password)
+ {
+ }
+
+ public ScramSHA256SASLMechanism(string id, string password, string clientNonceBase64) : base(id, password, clientNonceBase64)
+ {
+ }
+
+ #endregion
+ //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
+ #region --Set-, Get- Methods--
+
+
+ #endregion
+ //--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\
+ #region --Misc Methods (Public)--
+ public override SelectSASLMechanismMessage getSelectSASLMechanismMessage()
+ {
+ clientFirstMsg = "n=" + ID + ",r=" + CLIENT_NONCE_BASE_64;
+ string encClientFirstMsg = encodeStringBase64("n,," + clientFirstMsg);
+
+ return new SelectSASLMechanismMessage("SCRAM-SHA-256", encClientFirstMsg);
+ }
+
+ #endregion
+
+ #region --Misc Methods (Private)--
+
+ #endregion
+
+ #region --Misc Methods (Protected)--
+ protected override bool isValidIterationsCount(int iters)
+ {
+ return iters >= 4096;
+ }
+
+ #endregion
+ //--------------------------------------------------------Events:---------------------------------------------------------------------\\
+ #region --Events--
+
+
+ #endregion
+ }
+}
diff --git a/XMPP_API/Classes/Network/XML/Messages/Processor/SASLConnection.cs b/XMPP_API/Classes/Network/XML/Messages/Processor/SASLConnection.cs
index 47fc88530..8b1e337cc 100644
--- a/XMPP_API/Classes/Network/XML/Messages/Processor/SASLConnection.cs
+++ b/XMPP_API/Classes/Network/XML/Messages/Processor/SASLConnection.cs
@@ -18,7 +18,7 @@ class SASLConnection : AbstractMessageProcessor
private SASLState state;
private AbstractSASLMechanism selectedMechanism;
// The offered authentication mechanism in preferred order:
- private static readonly ArrayList OFFERED_MECHANISMS = new ArrayList() { "scram-sha-1", "plain" };
+ private static readonly ArrayList OFFERED_MECHANISMS = new ArrayList() { "scram-sha-256", "scram-sha-1", "plain" };
#endregion
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\
@@ -83,6 +83,10 @@ private void selectMechanism(ArrayList mechanisms)
XMPPAccount sCC = XMPP_CONNECTION.account;
switch (selected)
{
+ case "scram-sha-256":
+ selectedMechanism = new ScramSHA256SASLMechanism(sCC.user.userId, sCC.user.userPassword);
+ break;
+
case "scram-sha-1":
selectedMechanism = new ScramSHA1SASLMechanism(sCC.user.userId, sCC.user.userPassword);
break;
diff --git a/XMPP_API/XMPP_API.csproj b/XMPP_API/XMPP_API.csproj
index eaf9d003a..6b8a3f3bc 100644
--- a/XMPP_API/XMPP_API.csproj
+++ b/XMPP_API/XMPP_API.csproj
@@ -159,6 +159,7 @@
+