summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs')
-rw-r--r--src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs
new file mode 100644
index 0000000..4739d84
--- /dev/null
+++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/ChannelElements/OpenIdRelyingPartyChannel.cs
@@ -0,0 +1,120 @@
+//-----------------------------------------------------------------------
+// <copyright file="OpenIdRelyingPartyChannel.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.Contracts;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OpenId.Extensions;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ /// <summary>
+ /// The messaging channel for OpenID relying parties.
+ /// </summary>
+ internal class OpenIdRelyingPartyChannel : OpenIdChannel {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OpenIdRelyingPartyChannel"/> class.
+ /// </summary>
+ /// <param name="cryptoKeyStore">The association store to use.</param>
+ /// <param name="nonceStore">The nonce store to use.</param>
+ /// <param name="securitySettings">The security settings to apply.</param>
+ internal OpenIdRelyingPartyChannel(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings)
+ : this(cryptoKeyStore, nonceStore, new OpenIdRelyingPartyMessageFactory(), securitySettings, false) {
+ Requires.NotNull(securitySettings, "securitySettings");
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OpenIdRelyingPartyChannel"/> class.
+ /// </summary>
+ /// <param name="cryptoKeyStore">The association store to use.</param>
+ /// <param name="nonceStore">The nonce store to use.</param>
+ /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param>
+ /// <param name="securitySettings">The security settings to apply.</param>
+ /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param>
+ private OpenIdRelyingPartyChannel(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, RelyingPartySecuritySettings securitySettings, bool nonVerifying) :
+ base(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings, nonVerifying)) {
+ Requires.NotNull(messageTypeProvider, "messageTypeProvider");
+ Requires.NotNull(securitySettings, "securitySettings");
+ Requires.True(!nonVerifying || securitySettings is RelyingPartySecuritySettings);
+ }
+
+ /// <summary>
+ /// A value indicating whether the channel is set up
+ /// with no functional security binding elements.
+ /// </summary>
+ /// <returns>A new <see cref="OpenIdChannel"/> instance that will not perform verification on incoming messages or apply any security to outgoing messages.</returns>
+ /// <remarks>
+ /// <para>A value of <c>true</c> allows the relying party to preview incoming
+ /// messages without invalidating nonces or checking signatures.</para>
+ /// <para>Setting this to <c>true</c> poses a great security risk and is only
+ /// present to support the OpenIdAjaxTextBox which needs to preview
+ /// messages, and will validate them later.</para>
+ /// </remarks>
+ internal static OpenIdChannel CreateNonVerifyingChannel() {
+ Contract.Ensures(Contract.Result<OpenIdChannel>() != null);
+
+ return new OpenIdRelyingPartyChannel(null, null, new OpenIdRelyingPartyMessageFactory(), new RelyingPartySecuritySettings(), true);
+ }
+
+ /// <summary>
+ /// Initializes the binding elements.
+ /// </summary>
+ /// <param name="cryptoKeyStore">The crypto key store.</param>
+ /// <param name="nonceStore">The nonce store to use.</param>
+ /// <param name="securitySettings">The security settings to apply. Must be an instance of either <see cref="RelyingPartySecuritySettings"/> or ProviderSecuritySettings.</param>
+ /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param>
+ /// <returns>
+ /// An array of binding elements which may be used to construct the channel.
+ /// </returns>
+ private static IChannelBindingElement[] InitializeBindingElements(ICryptoKeyStore cryptoKeyStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings, bool nonVerifying) {
+ Requires.NotNull(securitySettings, "securitySettings");
+
+ SigningBindingElement signingElement;
+ signingElement = nonVerifying ? null : new RelyingPartySigningBindingElement(new CryptoKeyStoreAsRelyingPartyAssociationStore(cryptoKeyStore ?? new MemoryCryptoKeyStore()));
+
+ var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration();
+
+ List<IChannelBindingElement> elements = new List<IChannelBindingElement>(8);
+ elements.Add(new ExtensionsBindingElementRelyingParty(extensionFactory, securitySettings));
+ elements.Add(new RelyingPartySecurityOptions(securitySettings));
+ elements.Add(new BackwardCompatibilityBindingElement());
+ ReturnToNonceBindingElement requestNonceElement = null;
+
+ if (cryptoKeyStore != null) {
+ if (nonceStore != null) {
+ // There is no point in having a ReturnToNonceBindingElement without
+ // a ReturnToSignatureBindingElement because the nonce could be
+ // artificially changed without it.
+ requestNonceElement = new ReturnToNonceBindingElement(nonceStore, securitySettings);
+ elements.Add(requestNonceElement);
+ }
+
+ // It is important that the return_to signing element comes last
+ // so that the nonce is included in the signature.
+ elements.Add(new ReturnToSignatureBindingElement(cryptoKeyStore));
+ }
+
+ ErrorUtilities.VerifyOperation(!securitySettings.RejectUnsolicitedAssertions || requestNonceElement != null, OpenIdStrings.UnsolicitedAssertionRejectionRequiresNonceStore);
+
+ if (nonVerifying) {
+ elements.Add(new SkipSecurityBindingElement());
+ } else {
+ if (nonceStore != null) {
+ elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true));
+ }
+
+ elements.Add(new StandardExpirationBindingElement());
+ elements.Add(signingElement);
+ }
+
+ return elements.ToArray();
+ }
+ }
+}