diff options
author | Christoph Enzmann <christoph.enzmann@confer.ch> | 2013-12-05 17:47:33 +0100 |
---|---|---|
committer | Christoph Enzmann <christoph.enzmann@confer.ch> | 2013-12-05 17:47:33 +0100 |
commit | 3e3f949d007812349c623da09f539ab465d46b50 (patch) | |
tree | 99563a436dc76c982acc0cf13fa027a08a5a7f5a | |
parent | 9b8c9cc8bafa315516b6ac704859c6d13ce1b768 (diff) | |
download | TwoStepsAuthenticator-3e3f949d007812349c623da09f539ab465d46b50.zip TwoStepsAuthenticator-3e3f949d007812349c623da09f539ab465d46b50.tar.gz TwoStepsAuthenticator-3e3f949d007812349c623da09f539ab465d46b50.tar.bz2 |
Methods for synchronization
-rw-r--r-- | TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs | 12 | ||||
-rw-r--r-- | TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs | 15 | ||||
-rw-r--r-- | TwoStepsAuthenticator/CounterAuthenticator.cs | 18 | ||||
-rw-r--r-- | TwoStepsAuthenticator/TimeAuthenticator.cs | 16 |
4 files changed, 61 insertions, 0 deletions
diff --git a/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs b/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs index 4738ba1..ecb96c0 100644 --- a/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs +++ b/TwoStepsAuthenticator.UnitTests/CounterAuthenticatorTests.cs @@ -38,5 +38,17 @@ namespace TwoStepsAuthenticator.UnitTests { } + [Test] + public void VerifyUsedCounter() { + var authenticator = new CounterAuthenticator(); + + // Test Values from http://www.ietf.org/rfc/rfc4226.txt - Appendix D + var base32Secret = Base32Encoding.ToString(Encoding.ASCII.GetBytes("12345678901234567890")); + + long usedCounter; + Assert.True(authenticator.CheckCode(base32Secret, "520489", 0L, out usedCounter)); + + Assert.AreEqual(usedCounter, 9L); + } } } diff --git a/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs b/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs index 3d19ea2..3dc6d86 100644 --- a/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs +++ b/TwoStepsAuthenticator.UnitTests/TimeAuthenticatorTests.cs @@ -30,5 +30,20 @@ namespace TwoStepsAuthenticator.UnitTests { Assert.IsTrue(authenticator.CheckCode(secret, code)); } + + [Test] + public void VerifyUsedTime() { + var date = DateTime.Parse("2013-12-05 17:23:50 +0100"); + var authenticator = new TimeAuthenticator(() => date); + + DateTime usedTime; + + Assert.True(authenticator.CheckCode("H22Q7WAMQYFZOJ2Q", "696227", out usedTime)); + + // 17:23:50 - 30s + Assert.AreEqual(usedTime.Hour, 17); + Assert.AreEqual(usedTime.Minute, 23); + Assert.AreEqual(usedTime.Second, 20); + } } } diff --git a/TwoStepsAuthenticator/CounterAuthenticator.cs b/TwoStepsAuthenticator/CounterAuthenticator.cs index 90b0ee4..b9ed5d2 100644 --- a/TwoStepsAuthenticator/CounterAuthenticator.cs +++ b/TwoStepsAuthenticator/CounterAuthenticator.cs @@ -38,13 +38,31 @@ namespace TwoStepsAuthenticator { /// <param name="counter">Current Counter Position</param> /// <returns>true if any code from counter to counter + WindowSize matches</returns> public bool CheckCode(string secret, string code, long counter) { + long successfulSequenceNumber = 0L; + + return CheckCode(secret, code, counter, out successfulSequenceNumber); + } + + /// <summary> + /// Checks if the passed code is valid. + /// </summary> + /// <param name="secret">Shared Secret</param> + /// <param name="code">OTP</param> + /// <param name="counter">Current Counter Position</param> + /// <param name="usedCounter">Matching counter value if successful</param> + /// <returns>true if any code from counter to counter + WindowSize matches</returns> + public bool CheckCode(string secret, string code, long counter, out long usedCounter) { var codeMatch = false; + long successfulSequenceNumber = 0L; + for (int i = 0; i <= WindowSize; i++) { if (ConstantTimeEquals(GetCode(secret, counter + i), code)) { codeMatch = true; + successfulSequenceNumber = counter + i; } } + usedCounter = successfulSequenceNumber; return codeMatch; } } diff --git a/TwoStepsAuthenticator/TimeAuthenticator.cs b/TwoStepsAuthenticator/TimeAuthenticator.cs index a461520..8e8e462 100644 --- a/TwoStepsAuthenticator/TimeAuthenticator.cs +++ b/TwoStepsAuthenticator/TimeAuthenticator.cs @@ -45,7 +45,21 @@ namespace TwoStepsAuthenticator { /// <param name="code">OTP</param> /// <returns>true if code matches</returns> public bool CheckCode(string secret, string code) { + DateTime successfulTime = DateTime.MinValue; + + return CheckCode(secret, code, out successfulTime); + } + + /// <summary> + /// Checks if the passed code is valid. + /// </summary> + /// <param name="secret">Shared Secret</param> + /// <param name="code">OTP</param> + /// <param name="usedDateTime">Matching time if successful</param> + /// <returns>true if code matches</returns> + public bool CheckCode(string secret, string code, out DateTime usedDateTime) { var baseTime = NowFunc(); + DateTime successfulTime = DateTime.MinValue; // We need to do this in constant time var codeMatch = false; @@ -53,9 +67,11 @@ namespace TwoStepsAuthenticator { var checkTime = baseTime.AddSeconds(30 * i); if (ConstantTimeEquals(GetCode(secret, checkTime), code)) { codeMatch = true; + successfulTime = checkTime; } } + usedDateTime = successfulTime; return codeMatch; } } |