summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-08-13 04:25:00 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2008-08-13 04:25:00 -0700
commitfd6acdc9b14b51fc0bf4c1b4fa815cc1f0d7ce26 (patch)
treea345806393382207e9d75a14f820457906f5878e /src
parentba48275ccaae1218b1e8574029f7e009eb3f8735 (diff)
downloadDotNetOpenAuth-fd6acdc9b14b51fc0bf4c1b4fa815cc1f0d7ce26.zip
DotNetOpenAuth-fd6acdc9b14b51fc0bf4c1b4fa815cc1f0d7ce26.tar.gz
DotNetOpenAuth-fd6acdc9b14b51fc0bf4c1b4fa815cc1f0d7ce26.tar.bz2
Made HMAC-SHA association types a table instead of several classes.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenId.Test/AssociationTestSuite.cs17
-rw-r--r--src/DotNetOpenId.Test/AssociationsTest.cs9
-rw-r--r--src/DotNetOpenId/Association.cs10
-rw-r--r--src/DotNetOpenId/CryptUtil.cs2
-rw-r--r--src/DotNetOpenId/DotNetOpenId.csproj5
-rw-r--r--src/DotNetOpenId/HmacSha1Association.cs22
-rw-r--r--src/DotNetOpenId/HmacSha256Association.cs22
-rw-r--r--src/DotNetOpenId/HmacSha384Association.cs22
-rw-r--r--src/DotNetOpenId/HmacSha512Association.cs22
-rw-r--r--src/DotNetOpenId/HmacShaAssociation.cs85
-rw-r--r--src/DotNetOpenId/Protocol.cs10
-rw-r--r--src/DotNetOpenId/Provider/Signatory.cs19
-rw-r--r--src/DotNetOpenId/RelyingParty/AssociateResponse.cs11
13 files changed, 132 insertions, 124 deletions
diff --git a/src/DotNetOpenId.Test/AssociationTestSuite.cs b/src/DotNetOpenId.Test/AssociationTestSuite.cs
index 327d174..e4fd30a 100644
--- a/src/DotNetOpenId.Test/AssociationTestSuite.cs
+++ b/src/DotNetOpenId.Test/AssociationTestSuite.cs
@@ -3,8 +3,7 @@ using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
-namespace DotNetOpenId.Test
-{
+namespace DotNetOpenId.Test {
[TestFixture]
public class AssociationTestSuite {
static readonly TimeSpan deltaDateTime = TimeSpan.FromSeconds(2);
@@ -24,7 +23,8 @@ namespace DotNetOpenId.Test
public void Properties() {
string handle = "somehandle";
TimeSpan lifetime = TimeSpan.FromMinutes(2);
- Association assoc = new HmacSha1Association(handle, sha1Secret, lifetime);
+ Association assoc = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ handle, sha1Secret, lifetime);
Assert.IsFalse(assoc.IsExpired);
Assert.IsTrue(Math.Abs((DateTime.Now - assoc.Issued.ToLocalTime()).TotalSeconds) < deltaDateTime.TotalSeconds);
Assert.IsTrue(Math.Abs((DateTime.Now.ToLocalTime() + lifetime - assoc.Expires.ToLocalTime()).TotalSeconds) < deltaDateTime.TotalSeconds);
@@ -36,8 +36,10 @@ namespace DotNetOpenId.Test
[Test]
public void Sign() {
- Association assoc1 = new HmacSha1Association("h1", sha1Secret, TimeSpan.FromMinutes(2));
- Association assoc2 = new HmacSha1Association("h2", sha1Secret2, TimeSpan.FromMinutes(2));
+ Association assoc1 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ "h1", sha1Secret, TimeSpan.FromMinutes(2));
+ Association assoc2 = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ "h2", sha1Secret2, TimeSpan.FromMinutes(2));
var dict = new Dictionary<string, string>();
dict.Add("a", "b");
@@ -77,7 +79,8 @@ namespace DotNetOpenId.Test
[Test]
public void SignSome() {
- Association assoc = new HmacSha1Association("h1", sha1Secret, TimeSpan.FromMinutes(2));
+ Association assoc = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ "h1", sha1Secret, TimeSpan.FromMinutes(2));
const string prefix = "q.";
var dict = new Dictionary<string, string>();
@@ -85,7 +88,7 @@ namespace DotNetOpenId.Test
dict.Add("q.c", "d");
dict.Add("q.e", "f");
- var signKeys = new List<string> {"a", "c"}; // don't sign e
+ var signKeys = new List<string> { "a", "c" }; // don't sign e
byte[] sig1 = assoc.Sign(dict, signKeys, prefix);
diff --git a/src/DotNetOpenId.Test/AssociationsTest.cs b/src/DotNetOpenId.Test/AssociationsTest.cs
index 7f4ec26..4d6dcfb 100644
--- a/src/DotNetOpenId.Test/AssociationsTest.cs
+++ b/src/DotNetOpenId.Test/AssociationsTest.cs
@@ -27,7 +27,8 @@ namespace DotNetOpenId.Test {
[Test]
public void HandleLifecycle() {
- Association a = new HmacSha1Association("somehandle", sha1Secret, TimeSpan.FromDays(1));
+ Association a = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ "somehandle", sha1Secret, TimeSpan.FromDays(1));
assocs.Set(a);
Assert.AreSame(a, assocs.Get(a.Handle));
Assert.IsTrue(assocs.Remove(a.Handle));
@@ -37,8 +38,10 @@ namespace DotNetOpenId.Test {
[Test]
public void Best() {
- Association a = new HmacSha1Association("h1", sha1Secret, TimeSpan.FromHours(1));
- Association b = new HmacSha1Association("h2", sha1Secret, TimeSpan.FromHours(1));
+ Association a = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ "h1", sha1Secret, TimeSpan.FromHours(1));
+ Association b = HmacShaAssociation.Create(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.HMAC_SHA1,
+ "h2", sha1Secret, TimeSpan.FromHours(1));
assocs.Set(a);
assocs.Set(b);
diff --git a/src/DotNetOpenId/Association.cs b/src/DotNetOpenId/Association.cs
index 5c9c302..ee3fd70 100644
--- a/src/DotNetOpenId/Association.cs
+++ b/src/DotNetOpenId/Association.cs
@@ -56,11 +56,11 @@ namespace DotNetOpenId {
TimeSpan remainingLifeLength = expires - DateTime.UtcNow;
byte[] secret = privateData; // the whole of privateData is the secret key for now.
// We figure out what derived type to instantiate based on the length of the secret.
- if(secret.Length == CryptUtil.Sha1.HashSize / 8)
- return new HmacSha1Association(handle, secret, remainingLifeLength);
- if (secret.Length == CryptUtil.Sha256.HashSize / 8)
- return new HmacSha256Association(handle, secret, remainingLifeLength);
- throw new ArgumentException(Strings.BadAssociationPrivateData, "privateData");
+ try {
+ return HmacShaAssociation.Create(secret.Length, handle, secret, remainingLifeLength);
+ } catch (ArgumentException ex) {
+ throw new ArgumentException(Strings.BadAssociationPrivateData, "privateData", ex);
+ }
}
static TimeSpan minimumUsefulAssociationLifetime {
diff --git a/src/DotNetOpenId/CryptUtil.cs b/src/DotNetOpenId/CryptUtil.cs
index 19b4266..103c8c3 100644
--- a/src/DotNetOpenId/CryptUtil.cs
+++ b/src/DotNetOpenId/CryptUtil.cs
@@ -19,7 +19,7 @@ namespace DotNetOpenId {
154, 72, 59, 138, 118, 34, 62, 93, 73, 10, 37, 127, 5, 189, 255, 22,
242, 251, 34, 197, 131, 171};
- internal static HashAlgorithm Sha1 = new SHA1CryptoServiceProvider();
+ internal static HashAlgorithm Sha1 = new SHA1Managed();
internal static HashAlgorithm Sha256 = new SHA256Managed();
internal static HashAlgorithm Sha384 = new SHA384Managed();
internal static HashAlgorithm Sha512 = new SHA512Managed();
diff --git a/src/DotNetOpenId/DotNetOpenId.csproj b/src/DotNetOpenId/DotNetOpenId.csproj
index df5a518..dac6c93 100644
--- a/src/DotNetOpenId/DotNetOpenId.csproj
+++ b/src/DotNetOpenId/DotNetOpenId.csproj
@@ -59,8 +59,6 @@
<Compile Include="Association.cs" />
<Compile Include="AssociationMemoryStore.cs" />
<Compile Include="Associations.cs" />
- <Compile Include="HmacSha384Association.cs" />
- <Compile Include="HmacSha512Association.cs" />
<Compile Include="Provider\SigningMessageEncoder.cs" />
<Compile Include="RelyingParty\DirectMessageHttpChannel.cs" />
<Compile Include="RelyingParty\IDirectMessageChannel.cs" />
@@ -82,7 +80,6 @@
<Compile Include="Extensions\AttributeExchange\StoreRequest.cs" />
<Compile Include="Extensions\AttributeExchange\StoreResponse.cs" />
<Compile Include="Extensions\IExtension.cs" />
- <Compile Include="HmacSha256Association.cs" />
<Compile Include="Identifier.cs" />
<Compile Include="IResponse.cs" />
<Compile Include="Loggers\TraceLogger.cs" />
@@ -116,7 +113,7 @@
<Compile Include="RelyingParty\OpenIdRelyingParty.cs" />
<Compile Include="RelyingParty\Token.cs" />
<Compile Include="GlobalSuppressions.cs" />
- <Compile Include="HmacSha1Association.cs" />
+ <Compile Include="HmacShaAssociation.cs" />
<Compile Include="HttpEncoding.cs" />
<Compile Include="IAssociationStore.cs" />
<Compile Include="KeyValueFormEncoding.cs" />
diff --git a/src/DotNetOpenId/HmacSha1Association.cs b/src/DotNetOpenId/HmacSha1Association.cs
deleted file mode 100644
index da344f1..0000000
--- a/src/DotNetOpenId/HmacSha1Association.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Security.Cryptography;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace DotNetOpenId {
- internal class HmacSha1Association : Association {
-
- public HmacSha1Association(string handle, byte[] secret, TimeSpan totalLifeLength)
- : base(handle, secret, totalLifeLength, DateTime.UtcNow) {
- Debug.Assert(secret.Length == CryptUtil.Sha1.HashSize / 8);
- }
-
- internal override string GetAssociationType(Protocol protocol) {
- return protocol.Args.SignatureAlgorithm.HMAC_SHA1;
- }
-
- protected override HashAlgorithm CreateHasher() {
- return new HMACSHA1(SecretKey);
- }
- }
-} \ No newline at end of file
diff --git a/src/DotNetOpenId/HmacSha256Association.cs b/src/DotNetOpenId/HmacSha256Association.cs
deleted file mode 100644
index fddc811..0000000
--- a/src/DotNetOpenId/HmacSha256Association.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Security.Cryptography;
-using System.Diagnostics;
-
-namespace DotNetOpenId {
- class HmacSha256Association : Association {
- public HmacSha256Association(string handle, byte[] secret, TimeSpan totalLifeLength)
- : base(handle, secret, totalLifeLength, DateTime.UtcNow) {
- Debug.Assert(secret.Length == CryptUtil.Sha256.HashSize / 8);
- }
-
- protected override HashAlgorithm CreateHasher() {
- return new HMACSHA256(SecretKey);
- }
-
- internal override string GetAssociationType(Protocol protocol) {
- return protocol.Args.SignatureAlgorithm.HMAC_SHA256;
- }
- }
-}
diff --git a/src/DotNetOpenId/HmacSha384Association.cs b/src/DotNetOpenId/HmacSha384Association.cs
deleted file mode 100644
index 054a0df..0000000
--- a/src/DotNetOpenId/HmacSha384Association.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Security.Cryptography;
-using System.Diagnostics;
-
-namespace DotNetOpenId {
- class HmacSha384Association : Association {
- public HmacSha384Association(string handle, byte[] secret, TimeSpan totalLifeLength)
- : base(handle, secret, totalLifeLength, DateTime.UtcNow) {
- Debug.Assert(secret.Length == CryptUtil.Sha384.HashSize / 8);
- }
-
- protected override HashAlgorithm CreateHasher() {
- return new HMACSHA384(SecretKey);
- }
-
- internal override string GetAssociationType(Protocol protocol) {
- return protocol.Args.SignatureAlgorithm.HMAC_SHA384;
- }
- }
-}
diff --git a/src/DotNetOpenId/HmacSha512Association.cs b/src/DotNetOpenId/HmacSha512Association.cs
deleted file mode 100644
index dcff6b4..0000000
--- a/src/DotNetOpenId/HmacSha512Association.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Security.Cryptography;
-using System.Diagnostics;
-
-namespace DotNetOpenId {
- class HmacSha512Association : Association {
- public HmacSha512Association(string handle, byte[] secret, TimeSpan totalLifeLength)
- : base(handle, secret, totalLifeLength, DateTime.UtcNow) {
- Debug.Assert(secret.Length == CryptUtil.Sha512.HashSize / 8);
- }
-
- protected override HashAlgorithm CreateHasher() {
- return new HMACSHA512(SecretKey);
- }
-
- internal override string GetAssociationType(Protocol protocol) {
- return protocol.Args.SignatureAlgorithm.HMAC_SHA512;
- }
- }
-}
diff --git a/src/DotNetOpenId/HmacShaAssociation.cs b/src/DotNetOpenId/HmacShaAssociation.cs
new file mode 100644
index 0000000..a602909
--- /dev/null
+++ b/src/DotNetOpenId/HmacShaAssociation.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Security.Cryptography;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace DotNetOpenId {
+ internal class HmacShaAssociation : Association {
+
+ class HmacSha {
+ internal Util.Func<Protocol, string> GetAssociationType;
+ internal Util.Func<byte[], HashAlgorithm> CreateHasher;
+ internal HashAlgorithm BaseHashAlgorithm;
+ internal int SecretLength { get { return BaseHashAlgorithm.HashSize / 8; } }
+ }
+ static HmacSha[] HmacShaAssociationTypes = {
+ new HmacSha {
+ CreateHasher = secretKey => new HMACSHA1(secretKey),
+ GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA1,
+ BaseHashAlgorithm = CryptUtil.Sha1,
+ },
+ new HmacSha {
+ CreateHasher = secretKey => new HMACSHA256(secretKey),
+ GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA256,
+ BaseHashAlgorithm = CryptUtil.Sha256,
+ },
+ new HmacSha {
+ CreateHasher = secretKey => new HMACSHA384(secretKey),
+ GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA384,
+ BaseHashAlgorithm = CryptUtil.Sha384,
+ },
+ new HmacSha {
+ CreateHasher = secretKey => new HMACSHA512(secretKey),
+ GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA512,
+ BaseHashAlgorithm = CryptUtil.Sha512,
+ },
+ };
+
+ public static HmacShaAssociation Create(Protocol protocol, string associationType,
+ string handle, byte[] secret, TimeSpan totalLifeLength) {
+ foreach (HmacSha shaType in HmacShaAssociationTypes) {
+ if (String.Equals(shaType.GetAssociationType(protocol), associationType, StringComparison.Ordinal)) {
+ return new HmacShaAssociation(shaType, handle, secret, totalLifeLength);
+ }
+ }
+ throw new ArgumentOutOfRangeException("associationType");
+ }
+
+ public static HmacShaAssociation Create(int secretLength,
+ string handle, byte[] secret, TimeSpan totalLifeLength) {
+ foreach (HmacSha shaType in HmacShaAssociationTypes) {
+ if (shaType.SecretLength == secretLength) {
+ return new HmacShaAssociation(shaType, handle, secret, totalLifeLength);
+ }
+ }
+ throw new ArgumentOutOfRangeException("secretLength");
+ }
+
+ public static int GetSecretLength(Protocol protocol, string associationType) {
+ foreach (HmacSha shaType in HmacShaAssociationTypes) {
+ if (String.Equals(shaType.GetAssociationType(protocol), associationType, StringComparison.Ordinal)) {
+ return shaType.SecretLength;
+ }
+ }
+ throw new ArgumentOutOfRangeException("associationType");
+ }
+
+ HmacShaAssociation(HmacSha typeIdentity, string handle, byte[] secret, TimeSpan totalLifeLength)
+ : base(handle, secret, totalLifeLength, DateTime.UtcNow) {
+ if (typeIdentity == null) throw new ArgumentNullException("typeIdentity");
+
+ Debug.Assert(secret.Length == typeIdentity.SecretLength);
+ this.typeIdentity = typeIdentity;
+ }
+
+ HmacSha typeIdentity;
+
+ internal override string GetAssociationType(Protocol protocol) {
+ return typeIdentity.GetAssociationType(protocol);
+ }
+
+ protected override HashAlgorithm CreateHasher() {
+ return typeIdentity.CreateHasher(SecretKey);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/DotNetOpenId/Protocol.cs b/src/DotNetOpenId/Protocol.cs
index 5d3811c..78ad91b 100644
--- a/src/DotNetOpenId/Protocol.cs
+++ b/src/DotNetOpenId/Protocol.cs
@@ -287,6 +287,16 @@ namespace DotNetOpenId {
public string HMAC_SHA256 = null;
public string HMAC_SHA384 = null;
public string HMAC_SHA512 = null;
+ public string Best {
+ get {
+ foreach (string algorithmName in All) {
+ if (algorithmName != null) {
+ return algorithmName;
+ }
+ }
+ throw new OpenIdException(); // really bad... we have no signing algorithms at all
+ }
+ }
}
internal class Modes {
public string cancel = "cancel";
diff --git a/src/DotNetOpenId/Provider/Signatory.cs b/src/DotNetOpenId/Provider/Signatory.cs
index 53c6139..eaf3d21 100644
--- a/src/DotNetOpenId/Provider/Signatory.cs
+++ b/src/DotNetOpenId/Provider/Signatory.cs
@@ -79,24 +79,25 @@ namespace DotNetOpenId.Provider {
if (provider == null && associationType == AssociationRelyingPartyType.Smart)
throw new ArgumentNullException("provider", "For Smart associations, the provider must be given.");
- bool useSha256;
string assoc_type;
+ Protocol associationProtocol;
if (associationType == AssociationRelyingPartyType.Dumb) {
- useSha256 = true;
- assoc_type = Protocol.v20.Args.SignatureAlgorithm.HMAC_SHA256;
+ // We'll just use the best association available.
+ associationProtocol = Protocol.Default;
+ assoc_type = associationProtocol.Args.SignatureAlgorithm.Best;
} else {
+ associationProtocol = provider.Protocol;
assoc_type = Util.GetRequiredArg(provider.Query, provider.Protocol.openid.assoc_type);
Debug.Assert(Array.IndexOf(provider.Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0, "This should have been checked by our caller.");
- useSha256 = assoc_type.Equals(provider.Protocol.Args.SignatureAlgorithm.HMAC_SHA256, StringComparison.Ordinal);
}
- int hashSize = useSha256 ? CryptUtil.Sha256.HashSize : CryptUtil.Sha1.HashSize;
+ int secretLength = HmacShaAssociation.GetSecretLength(associationProtocol, assoc_type);
RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider();
- byte[] secret = new byte[hashSize / 8];
+ byte[] secret = new byte[secretLength];
byte[] uniq_bytes = new byte[4];
string uniq;
string handle;
- Association assoc;
+ HmacShaAssociation assoc;
generator.GetBytes(secret);
generator.GetBytes(uniq_bytes);
@@ -108,9 +109,7 @@ namespace DotNetOpenId.Provider {
handle = "{{" + assoc_type + "}{" + seconds + "}{" + uniq + "}";
TimeSpan lifeSpan = associationType == AssociationRelyingPartyType.Dumb ? dumbSecretLifetime : smartAssociationLifetime;
- assoc = useSha256 ? (Association)
- new HmacSha256Association(handle, secret, lifeSpan) :
- new HmacSha1Association(handle, secret, lifeSpan);
+ assoc = HmacShaAssociation.Create(secretLength, handle, secret, lifeSpan);
store.StoreAssociation(associationType, assoc);
diff --git a/src/DotNetOpenId/RelyingParty/AssociateResponse.cs b/src/DotNetOpenId/RelyingParty/AssociateResponse.cs
index 3652b1c..d55a64f 100644
--- a/src/DotNetOpenId/RelyingParty/AssociateResponse.cs
+++ b/src/DotNetOpenId/RelyingParty/AssociateResponse.cs
@@ -56,14 +56,13 @@ namespace DotNetOpenId.RelyingParty {
string assocHandle = Util.GetRequiredArg(Args, Protocol.openidnp.assoc_handle);
TimeSpan expiresIn = new TimeSpan(0, 0, Convert.ToInt32(Util.GetRequiredArg(Args, Protocol.openidnp.expires_in), CultureInfo.InvariantCulture));
- if (assoc_type == Protocol.Args.SignatureAlgorithm.HMAC_SHA1) {
- Association = new HmacSha1Association(assocHandle, secret, expiresIn);
- } else if (assoc_type == Protocol.Args.SignatureAlgorithm.HMAC_SHA256) {
- Association = new HmacSha256Association(assocHandle, secret, expiresIn);
- } else {
+ try {
+ Association = HmacShaAssociation.Create(Protocol, assoc_type,
+ assocHandle, secret, expiresIn);
+ } catch (ArgumentException ex) {
throw new OpenIdException(string.Format(CultureInfo.CurrentCulture,
Strings.InvalidOpenIdQueryParameterValue,
- Protocol.openid.assoc_type, assoc_type));
+ Protocol.openid.assoc_type, assoc_type), ex);
}
} else {
throw new OpenIdException(string.Format(CultureInfo.CurrentCulture,