diff options
Diffstat (limited to 'src/DotNetOpenAuth.OpenId')
11 files changed, 120 insertions, 52 deletions
diff --git a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs b/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs index e4e210f..af038f2 100644 --- a/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs +++ b/src/DotNetOpenAuth.OpenId/Configuration/OpenIdElement.cs @@ -6,11 +6,11 @@ namespace DotNetOpenAuth.Configuration { using System; + using System.Collections.Generic; using System.Configuration; using System.Diagnostics.Contracts; using DotNetOpenAuth.OpenId.ChannelElements; using DotNetOpenAuth.OpenId.Messages; - using System.Collections.Generic; /// <summary> /// Represents the <openid> element in the host's .config file. diff --git a/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj b/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj index 74befb7..62fc620 100644 --- a/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj +++ b/src/DotNetOpenAuth.OpenId/DotNetOpenAuth.OpenId.csproj @@ -39,6 +39,7 @@ </Compile> <Compile Include="OpenId\Behaviors\GsaIcamProfile.cs" /> <Compile Include="OpenId\ChannelElements\BackwardCompatibilityBindingElement.cs" /> + <Compile Include="OpenId\ChannelElements\SigningBindingElementContract.cs" /> <Compile Include="OpenId\ChannelElements\ExtensionsBindingElement.cs" /> <Compile Include="OpenId\ChannelElements\IOpenIdExtensionFactory.cs" /> <Compile Include="OpenId\ChannelElements\ITamperResistantOpenIdMessage.cs" /> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Association.cs b/src/DotNetOpenAuth.OpenId/OpenId/Association.cs index dfcc5c4..6e7850a 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Association.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Association.cs @@ -89,6 +89,16 @@ namespace DotNetOpenAuth.OpenId { internal DateTime Issued { get; set; } /// <summary> + /// Gets the duration a secret key used for signing dumb client requests will be good for. + /// </summary> + protected internal static TimeSpan DumbSecretLifetime { + get { + Contract.Ensures(Contract.Result<TimeSpan>() > TimeSpan.Zero); + return OpenIdElement.Configuration.MaxAuthenticationTime; + } + } + + /// <summary> /// Gets the number of seconds until this <see cref="Association"/> expires. /// Never negative (counter runs to zero). /// </summary> @@ -107,16 +117,6 @@ namespace DotNetOpenAuth.OpenId { protected internal byte[] SecretKey { get; private set; } /// <summary> - /// Gets the duration a secret key used for signing dumb client requests will be good for. - /// </summary> - protected internal static TimeSpan DumbSecretLifetime { - get { - Contract.Ensures(Contract.Result<TimeSpan>() > TimeSpan.Zero); - return OpenIdElement.Configuration.MaxAuthenticationTime; - } - } - - /// <summary> /// Gets the lifetime the OpenID provider permits this <see cref="Association"/>. /// </summary> [MessagePart("ttl")] diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs index e7582c2..ace8d69 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ExtensionsBindingElement.cs @@ -21,6 +21,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// their carrying OpenID messages. /// </summary> internal class ExtensionsBindingElement : IChannelBindingElement { + /// <summary> + /// False if unsigned extensions should be dropped. Must always be true on Providers, since RPs never sign extensions. + /// </summary> private readonly bool receiveUnsignedExtensions; /// <summary> diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs index d47ba8b..bc7b2a1 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs @@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.OpenId.Messages; - + /// <summary> /// This binding element signs a Relying Party's openid.return_to parameter /// so that upon return, it can verify that it hasn't been tampered with. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs index 527b180..f186adc 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElement.cs @@ -102,31 +102,16 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { return null; } - protected abstract MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied); - - #endregion - /// <summary> - /// Ensures that all message parameters that must be signed are in fact included - /// in the signature. + /// Verifies the signature by unrecognized handle. /// </summary> + /// <param name="message">The message.</param> /// <param name="signedMessage">The signed message.</param> - private void EnsureParametersRequiringSignatureAreSigned(ITamperResistantOpenIdMessage signedMessage) { - // Verify that the signed parameter order includes the mandated fields. - // We do this in such a way that derived classes that add mandated fields automatically - // get included in the list of checked parameters. - Protocol protocol = Protocol.Lookup(signedMessage.Version); - var partsRequiringProtection = from part in this.Channel.MessageDescriptions.Get(signedMessage).Mapping.Values - where part.RequiredProtection != ProtectionLevel.None - where part.IsRequired || part.IsNondefaultValueSet(signedMessage) - select part.Name; - ErrorUtilities.VerifyInternal(partsRequiringProtection.All(name => name.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal)), "Signing only works when the parameters start with the 'openid.' prefix."); - string[] signedParts = signedMessage.SignedParameterOrder.Split(','); - var unsignedParts = from partName in partsRequiringProtection - where !signedParts.Contains(partName.Substring(protocol.openid.Prefix.Length)) - select partName; - ErrorUtilities.VerifyProtocol(!unsignedParts.Any(), OpenIdStrings.SignatureDoesNotIncludeMandatoryParts, string.Join(", ", unsignedParts.ToArray())); - } + /// <param name="protectionsApplied">The protections applied.</param> + /// <returns>The applied protections.</returns> + protected abstract MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied); + + #endregion /// <summary> /// Calculates the signature for a given message. @@ -188,22 +173,27 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { protected virtual Association GetDumbAssociationForSigning() { throw new NotImplementedException(); } - } - [ContractClassFor(typeof(SigningBindingElement))] - internal abstract class SigningBindingElementContract : SigningBindingElement { - protected override MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied) { - throw new NotImplementedException(); - } - - protected override Association GetAssociation(ITamperResistantOpenIdMessage signedMessage) { - Contract.Requires<ArgumentNullException>(signedMessage != null); - throw new NotImplementedException(); - } - - protected override Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage) { - Contract.Requires<ArgumentNullException>(signedMessage != null); - throw new NotImplementedException(); + /// <summary> + /// Ensures that all message parameters that must be signed are in fact included + /// in the signature. + /// </summary> + /// <param name="signedMessage">The signed message.</param> + private void EnsureParametersRequiringSignatureAreSigned(ITamperResistantOpenIdMessage signedMessage) { + // Verify that the signed parameter order includes the mandated fields. + // We do this in such a way that derived classes that add mandated fields automatically + // get included in the list of checked parameters. + Protocol protocol = Protocol.Lookup(signedMessage.Version); + var partsRequiringProtection = from part in this.Channel.MessageDescriptions.Get(signedMessage).Mapping.Values + where part.RequiredProtection != ProtectionLevel.None + where part.IsRequired || part.IsNondefaultValueSet(signedMessage) + select part.Name; + ErrorUtilities.VerifyInternal(partsRequiringProtection.All(name => name.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal)), "Signing only works when the parameters start with the 'openid.' prefix."); + string[] signedParts = signedMessage.SignedParameterOrder.Split(','); + var unsignedParts = from partName in partsRequiringProtection + where !signedParts.Contains(partName.Substring(protocol.openid.Prefix.Length)) + select partName; + ErrorUtilities.VerifyProtocol(!unsignedParts.Any(), OpenIdStrings.SignatureDoesNotIncludeMandatoryParts, string.Join(", ", unsignedParts.ToArray())); } } } diff --git a/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElementContract.cs b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElementContract.cs new file mode 100644 index 0000000..c46cd12 --- /dev/null +++ b/src/DotNetOpenAuth.OpenId/OpenId/ChannelElements/SigningBindingElementContract.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------- +// <copyright file="SigningBindingElementContract.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.Linq; + using System.Net.Security; + using System.Web; + using DotNetOpenAuth.Loggers; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.OpenId.Messages; + + /// <summary> + /// Code contract for the <see cref="SigningBindingElement"/> class. + /// </summary> + [ContractClassFor(typeof(SigningBindingElement))] + internal abstract class SigningBindingElementContract : SigningBindingElement { + /// <summary> + /// Verifies the signature by unrecognized handle. + /// </summary> + /// <param name="message">The message.</param> + /// <param name="signedMessage">The signed message.</param> + /// <param name="protectionsApplied">The protections applied.</param> + /// <returns> + /// The applied protections. + /// </returns> + protected override MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied) { + throw new NotImplementedException(); + } + + /// <summary> + /// Gets the association to use to sign or verify a message. + /// </summary> + /// <param name="signedMessage">The message to sign or verify.</param> + /// <returns> + /// The association to use to sign or verify the message. + /// </returns> + protected override Association GetAssociation(ITamperResistantOpenIdMessage signedMessage) { + Contract.Requires<ArgumentNullException>(signedMessage != null); + throw new NotImplementedException(); + } + + /// <summary> + /// Gets a specific association referenced in a given message's association handle. + /// </summary> + /// <param name="signedMessage">The signed message whose association handle should be used to lookup the association to return.</param> + /// <returns> + /// The referenced association; or <c>null</c> if such an association cannot be found. + /// </returns> + protected override Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage) { + Contract.Requires<ArgumentNullException>(signedMessage != null); + throw new NotImplementedException(); + } + } +} diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs index bd8117d..13da4f3 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/ExtensionsInteropHelper.cs @@ -23,7 +23,14 @@ namespace DotNetOpenAuth.OpenId.Extensions { /// <summary> /// The gender decoder to translate AX genders to Sreg. /// </summary> - internal static GenderEncoder genderEncoder = new GenderEncoder(); + private static GenderEncoder genderEncoder = new GenderEncoder(); + + /// <summary> + /// Gets the gender decoder to translate AX genders to Sreg. + /// </summary> + internal static GenderEncoder GenderEncoder { + get { return genderEncoder; } + } /// <summary> /// Splits the AX attribute format flags into individual values for processing. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs index 38c1360..b44f797 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Extensions/IClientScriptExtensionResponse.cs @@ -8,7 +8,7 @@ namespace DotNetOpenAuth.OpenId.Extensions { using System.Collections.Generic; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Messages; - + /// <summary> /// An interface that OpenID extensions can implement to allow authentication response /// messages with included extensions to be processed by Javascript on the user agent. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs index 41a4adf..9f1e0d7 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/OpenIdXrdsHelper.cs @@ -12,6 +12,9 @@ namespace DotNetOpenAuth.OpenId { using System.Text; using DotNetOpenAuth.Xrds; + /// <summary> + /// Utility methods for working with XRDS documents. + /// </summary> internal static class OpenIdXrdsHelper { /// <summary> /// Finds the Relying Party return_to receiving endpoints. diff --git a/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs b/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs index a2d6b07..c00653b 100644 --- a/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs +++ b/src/DotNetOpenAuth.OpenId/OpenId/Realm.cs @@ -16,9 +16,9 @@ namespace DotNetOpenAuth.OpenId { using System.Web; using System.Xml; using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Reflection; using DotNetOpenAuth.Xrds; using DotNetOpenAuth.Yadis; - using DotNetOpenAuth.Messaging.Reflection; /// <summary> /// A trust root to validate requests and match return URLs against. |