summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Test
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2010-07-21 16:15:28 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2010-07-21 16:15:28 -0700
commitd2350db627b5ef7c9ebe6fd150b3007b0af1e660 (patch)
tree6817d8679ad3efadb78e7c275429fd9372ee4058 /src/DotNetOpenAuth.Test
parentb5c8335f528acbca046ca2844f8e4c12cfa9cba3 (diff)
parent4f2ccab7a53819c7d0c4008626995e95ece4dd34 (diff)
downloadDotNetOpenAuth-d2350db627b5ef7c9ebe6fd150b3007b0af1e660.zip
DotNetOpenAuth-d2350db627b5ef7c9ebe6fd150b3007b0af1e660.tar.gz
DotNetOpenAuth-d2350db627b5ef7c9ebe6fd150b3007b0af1e660.tar.bz2
Merge branch 'v3.4' into oauth2
Conflicts: projecttemplates/RelyingPartyDatabase/RelyingPartyDatabase.dbproj projecttemplates/RelyingPartyLogic/CreateDatabase.sql samples/OAuthConsumerWpf/OAuthConsumerWpf.csproj src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs src/DotNetOpenAuth/Messaging/MessagingStrings.resx src/DotNetOpenAuth/Messaging/MessagingUtilities.cs src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs src/version.txt
Diffstat (limited to 'src/DotNetOpenAuth.Test')
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj2
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs16
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs63
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs2
4 files changed, 81 insertions, 2 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index 596c499..f4d0bb3 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
<PropertyGroup>
<ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\..\..\</ProjectRoot>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -391,4 +392,5 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" />
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
index 9ba433d..e0c2de6 100644
--- a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
@@ -6,6 +6,8 @@
namespace DotNetOpenAuth.Test.Messaging.Bindings {
using System;
+
+ using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.Test.Mocks;
@@ -30,10 +32,22 @@ namespace DotNetOpenAuth.Test.Messaging.Bindings {
this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
}
+ [TestCase]
+ public void VerifyFutureTimestampWithinClockSkewIsAccepted() {
+ this.Channel = CreateChannel(MessageProtections.Expiration);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow + DotNetOpenAuthSection.Configuration.Messaging.MaximumClockSkew - TimeSpan.FromSeconds(1), false);
+ }
+
[TestCase, ExpectedException(typeof(ExpiredMessageException))]
- public void VerifyBadTimestampIsRejected() {
+ public void VerifyOldTimestampIsRejected() {
this.Channel = CreateChannel(MessageProtections.Expiration);
this.ParameterizedReceiveProtectedTest(DateTime.UtcNow - StandardExpirationBindingElement.MaximumMessageAge - TimeSpan.FromSeconds(1), false);
}
+
+ [TestCase, ExpectedException(typeof(ProtocolException))]
+ public void VerifyFutureTimestampIsRejected() {
+ this.Channel = CreateChannel(MessageProtections.Expiration);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow + DotNetOpenAuthSection.Configuration.Messaging.MaximumClockSkew + TimeSpan.FromSeconds(1), false);
+ }
}
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
index 1e0ede5..2c2da64 100644
--- a/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/MessagingUtilitiesTests.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Test.Messaging {
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+ using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
@@ -227,5 +228,67 @@ namespace DotNetOpenAuth.Test.Messaging {
string roundTripped = MessagingUtilities.Decrypt(cipher, key);
Assert.AreEqual(PlainText, roundTripped);
}
+
+ /// <summary>
+ /// Verifies that the time-independent string equality check works accurately.
+ /// </summary>
+ [TestCase]
+ public void EqualsConstantTime() {
+ this.EqualsConstantTimeHelper(null, null);
+ this.EqualsConstantTimeHelper(null, string.Empty);
+ this.EqualsConstantTimeHelper(string.Empty, string.Empty);
+ this.EqualsConstantTimeHelper(string.Empty, "a");
+ this.EqualsConstantTimeHelper(null, "a");
+ this.EqualsConstantTimeHelper("a", "a");
+ this.EqualsConstantTimeHelper("a", "A");
+ this.EqualsConstantTimeHelper("A", "A");
+ this.EqualsConstantTimeHelper("ab", "ab");
+ this.EqualsConstantTimeHelper("ab", "b");
+ }
+
+ /// <summary>
+ /// Verifies that EqualsConstantTime actually has the same execution time regardless of how well a value matches.
+ /// </summary>
+ [TestCase, Category("Performance")]
+ public void EqualsConstantTimeIsActuallyConstantTime() {
+ string expected = new string('A', 5000);
+ string totalmismatch = new string('B', 5000);
+ string almostmatch = new string('A', 4999) + 'B';
+
+ const int Iterations = 4000;
+ var totalMismatchTimer = new Stopwatch();
+ totalMismatchTimer.Start();
+ for (int i = 0; i < Iterations; i++) {
+ MessagingUtilities.EqualsConstantTime(expected, totalmismatch);
+ }
+ totalMismatchTimer.Stop();
+
+ var almostMatchTimer = new Stopwatch();
+ almostMatchTimer.Start();
+ for (int i = 0; i < Iterations; i++) {
+ MessagingUtilities.EqualsConstantTime(expected, almostmatch);
+ }
+ almostMatchTimer.Stop();
+
+ const double ToleranceFactor = 0.06;
+ long averageTimeTicks = (totalMismatchTimer.ElapsedTicks + almostMatchTimer.ElapsedTicks) / 2;
+ var tolerableDifference = TimeSpan.FromTicks((long)(averageTimeTicks * ToleranceFactor));
+ var absoluteDifference = TimeSpan.FromTicks(Math.Abs(totalMismatchTimer.ElapsedTicks - almostMatchTimer.ElapsedTicks));
+ double actualFactor = (double)absoluteDifference.Ticks / averageTimeTicks;
+ Assert.IsTrue(absoluteDifference <= tolerableDifference, "A total mismatch took {0} but a near match took {1}, which is too different to be indistinguishable. The tolerable difference is {2} but the actual difference is {3}. This represents a difference of {4}%, beyond the tolerated {5}%.", totalMismatchTimer.Elapsed, almostMatchTimer.Elapsed, tolerableDifference, absoluteDifference, Math.Round(actualFactor * 100), Math.Round(ToleranceFactor * 100));
+ Console.WriteLine("A total mismatch took {0} and a near match took {1}. The tolerable difference is {2}, and the actual difference is {3}. This represents a difference of {4}%, within the tolerated {5}%.", totalMismatchTimer.Elapsed, almostMatchTimer.Elapsed, tolerableDifference, absoluteDifference, Math.Round(actualFactor * 100), Math.Round(ToleranceFactor * 100));
+ Console.WriteLine("The equality test execution time difference was only {0}%, within the tolerable {1}%", Math.Round(100 * actualFactor), Math.Round(ToleranceFactor * 100));
+ }
+
+ /// <summary>
+ /// Verifies that the time-independent string equality check works for a given pair of strings.
+ /// </summary>
+ /// <param name="value1">The first value.</param>
+ /// <param name="value2">The second value.</param>
+ private void EqualsConstantTimeHelper(string value1, string value2) {
+ bool expected = string.Equals(value1, value2, StringComparison.Ordinal);
+ Assert.AreEqual(expected, MessagingUtilities.EqualsConstantTime(value1, value2));
+ Assert.AreEqual(expected, MessagingUtilities.EqualsConstantTime(value2, value1));
+ }
}
}
diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
index dd6738f..54ed37e 100644
--- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
@@ -359,7 +359,7 @@ namespace DotNetOpenAuth.Test.OAuth.ChannelElements {
{ "Name", "Andrew" },
{ "Location", "http://hostb/pathB" },
{ "Timestamp", XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.Utc) },
- { "realm" , "someValue" },
+ { "realm", "someValue" },
};
IProtocolMessage requestMessage = this.channel.ReadFromRequest(CreateHttpRequestInfo(scheme, fields));
Assert.IsNotNull(requestMessage);