diff options
Diffstat (limited to 'src')
4 files changed, 213 insertions, 0 deletions
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 216d128..432dad6 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -182,6 +182,9 @@ <AutoGen>True</AutoGen> </Compile> <Compile Include="OpenId\Protocol.cs" /> + <Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" /> + <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" /> + <Compile Include="OpenId\SecuritySettings.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="OAuth\Messages\UnauthorizedTokenRequest.cs" /> <Compile Include="OAuth\ChannelElements\RsaSha1SigningBindingElement.cs" /> diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs new file mode 100644 index 0000000..16f23f9 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------- +// <copyright file="ProviderSecuritySettings.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Provider { + /// <summary> + /// Security settings that are applicable to providers. + /// </summary> + internal sealed class ProviderSecuritySettings : SecuritySettings { + /// <summary> + /// Initializes a new instance of the <see cref="ProviderSecuritySettings"/> class. + /// </summary> + internal ProviderSecuritySettings() + : base(true) { + } + + // This property is a placeholder for a feature that has not been written yet. + ///// <summary> + ///// Gets or sets whether OpenID 1.x relying parties that may not be + ///// protecting their users from replay attacks are protected from + ///// replay attacks by this provider. + ///// </summary> + ///// <remarks> + ///// <para>Nonces for protection against replay attacks were not mandated + ///// by OpenID 1.x, which leaves users open to replay attacks.</para> + ///// <para>This feature works by preventing associations from being formed + ///// with OpenID 1.x relying parties, thereby forcing them into + ///// "dumb" mode and verifying every claim with this provider. + ///// This gives the provider an opportunity to verify its own nonce + ///// to protect against replay attacks.</para> + ///// </remarks> + ////internal bool ProtectDownlevelReplayAttacks { get; set; } + } +} diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs new file mode 100644 index 0000000..c5b6088 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------- +// <copyright file="RelyingPartySecuritySettings.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.RelyingParty { + using System; + + /// <summary> + /// Security settings that are applicable to relying parties. + /// </summary> + public sealed class RelyingPartySecuritySettings : SecuritySettings { + /// <summary> + /// Backing field for the <see cref="RequireSsl"/> property. + /// </summary> + private bool requireSsl; + + /// <summary> + /// Initializes a new instance of the <see cref="RelyingPartySecuritySettings"/> class. + /// </summary> + internal RelyingPartySecuritySettings() + : base(false) { + } + + /// <summary> + /// Fired when the <see cref="RequireSsl"/> property is changed. + /// </summary> + internal event EventHandler RequireSslChanged; + + /// <summary> + /// Gets or sets a value indicating whether the entire pipeline from Identifier discovery to + /// Provider redirect is guaranteed to be encrypted using HTTPS for authentication to succeed. + /// </summary> + /// <remarks> + /// <para>Setting this property to true is appropriate for RPs with highly sensitive + /// personal information behind the authentication (money management, health records, etc.)</para> + /// <para>When set to true, some behavioral changes and additional restrictions are placed:</para> + /// <list> + /// <item>User-supplied identifiers lacking a scheme are prepended with + /// HTTPS:// rather than the standard HTTP:// automatically.</item> + /// <item>User-supplied identifiers are not allowed to use HTTP for the scheme.</item> + /// <item>All redirects during discovery on the user-supplied identifier must be HTTPS.</item> + /// <item>Any XRDS file found by discovery on the User-supplied identifier must be protected using HTTPS.</item> + /// <item>Only Provider endpoints found at HTTPS URLs will be considered.</item> + /// <item>If the discovered identifier is an OP Identifier (directed identity), the + /// Claimed Identifier eventually asserted by the Provider must be an HTTPS identifier.</item> + /// <item>In the case of an unsolicited assertion, the asserted Identifier, discovery on it and + /// the asserting provider endpoint must all be secured by HTTPS.</item> + /// </list> + /// <para>Although the first redirect from this relying party to the Provider is required + /// to use HTTPS, any additional redirects within the Provider cannot be protected and MAY + /// revert the user's connection to HTTP, based on individual Provider implementation. + /// There is nothing that the RP can do to detect or prevent this.</para> + /// <para> + /// A <see cref="ProtocolException"/> is thrown during discovery or authentication when a secure pipeline cannot be established. + /// </para> + /// </remarks> + public bool RequireSsl { + get { + return this.requireSsl; + } + + set { + if (this.requireSsl == value) { + return; + } + this.requireSsl = value; + this.OnRequireSslChanged(); + } + } + + /// <summary> + /// Gets or sets the oldest version of OpenID the remote party is allowed to implement. + /// </summary> + /// <value>Defaults to <see cref="ProtocolVersion.V10"/></value> + public ProtocolVersion MinimumRequiredOpenIdVersion { get; set; } + + /// <summary> + /// Fires the <see cref="RequireSslChanged"/> event. + /// </summary> + private void OnRequireSslChanged() { + EventHandler requireSslChanged = this.RequireSslChanged; + if (requireSslChanged != null) { + requireSslChanged(this, new EventArgs()); + } + } + } +} diff --git a/src/DotNetOpenAuth/OpenId/SecuritySettings.cs b/src/DotNetOpenAuth/OpenId/SecuritySettings.cs new file mode 100644 index 0000000..d3ff934 --- /dev/null +++ b/src/DotNetOpenAuth/OpenId/SecuritySettings.cs @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------- +// <copyright file="SecuritySettings.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId { + /// <summary> + /// Security settings that may be applicable to both relying parties and providers. + /// </summary> + public class SecuritySettings { + /// <summary> + /// Initializes static members of the <see cref="SecuritySettings"/> class. + /// </summary> + static SecuritySettings() { + MinimumHashBitLengthDefault = 160; + MaximumHashBitLengthRPDefault = 256; + MaximumHashBitLengthOPDefault = 512; + } + + /// <summary> + /// Initializes a new instance of the <see cref="SecuritySettings"/> class. + /// </summary> + /// <param name="isProvider">A value indicating whether this class is being instantiated for a Provider.</param> + internal SecuritySettings(bool isProvider) { + this.MaximumHashBitLength = isProvider ? MaximumHashBitLengthOPDefault : MaximumHashBitLengthRPDefault; + this.MinimumHashBitLength = MinimumHashBitLengthDefault; + } + + /// <summary> + /// Gets or sets the minimum hash length (in bits) allowed to be used in an <see cref="Association"/> + /// with the remote party. The default is 160. + /// </summary> + /// <remarks> + /// SHA-1 (160 bits) has been broken. The minimum secure hash length is now 256 bits. + /// The default is still a 160 bit minimum to allow interop with common remote parties, + /// such as Yahoo! that only supports 160 bits. + /// For sites that require high security such as to store bank account information and + /// health records, 256 is the recommended value. + /// </remarks> + public int MinimumHashBitLength { get; set; } + + /// <summary> + /// Gets or sets the maximum hash length (in bits) allowed to be used in an <see cref="Association"/> + /// with the remote party. The default is 256 for relying parties and 512 for providers. + /// </summary> + /// <remarks> + /// The longer the bit length, the more secure the identities of your visitors are. + /// Setting a value higher than 256 on a relying party site may reduce performance + /// as many association requests will be denied, causing secondary requests or even + /// authentication failures. + /// Setting a value higher than 256 on a provider increases security where possible + /// without these side-effects. + /// </remarks> + public int MaximumHashBitLength { get; set; } + + /// <summary> + /// Gets the default minimum hash bit length. + /// </summary> + internal static int MinimumHashBitLengthDefault { get; private set; } + + /// <summary> + /// Gets the maximum hash bit length default for relying parties. + /// </summary> + internal static int MaximumHashBitLengthRPDefault { get; private set; } + + /// <summary> + /// Gets the maximum hash bit length default for providers. + /// </summary> + internal static int MaximumHashBitLengthOPDefault { get; private set; } + + /// <summary> + /// Determines whether a named association fits the security requirements. + /// </summary> + /// <param name="protocol">The protocol carrying the association.</param> + /// <param name="associationType">The value of the openid.assoc_type parameter.</param> + /// <returns> + /// <c>true</c> if the association is permitted given the security requirements; otherwise, <c>false</c>. + /// </returns> + internal bool IsAssociationInPermittedRange(Protocol protocol, string associationType) { + int lengthInBits = HmacShaAssociation.GetSecretLength(protocol, associationType) * 8; + return lengthInBits >= this.MinimumHashBitLength && lengthInBits <= this.MaximumHashBitLength; + } + } +} |