summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj3
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/ProviderSecuritySettings.cs36
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs89
-rw-r--r--src/DotNetOpenAuth/OpenId/SecuritySettings.cs85
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;
+ }
+ }
+}