diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/DotNetOpenId.Test/AssociationTestSuite.cs | 17 | ||||
-rw-r--r-- | src/DotNetOpenId.Test/AssociationsTest.cs | 9 | ||||
-rw-r--r-- | src/DotNetOpenId/Association.cs | 10 | ||||
-rw-r--r-- | src/DotNetOpenId/CryptUtil.cs | 2 | ||||
-rw-r--r-- | src/DotNetOpenId/DotNetOpenId.csproj | 5 | ||||
-rw-r--r-- | src/DotNetOpenId/HmacSha1Association.cs | 22 | ||||
-rw-r--r-- | src/DotNetOpenId/HmacSha256Association.cs | 22 | ||||
-rw-r--r-- | src/DotNetOpenId/HmacSha384Association.cs | 22 | ||||
-rw-r--r-- | src/DotNetOpenId/HmacSha512Association.cs | 22 | ||||
-rw-r--r-- | src/DotNetOpenId/HmacShaAssociation.cs | 85 | ||||
-rw-r--r-- | src/DotNetOpenId/Protocol.cs | 10 | ||||
-rw-r--r-- | src/DotNetOpenId/Provider/Signatory.cs | 19 | ||||
-rw-r--r-- | src/DotNetOpenId/RelyingParty/AssociateResponse.cs | 11 |
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,
|