/// <summary>
		/// Initializes a new instance of the SigningBindingElement class for use by a Provider.
		/// </summary>
		/// <param name="associationStore">The association store used to look up the secrets needed for signing.</param>
		/// <param name="securitySettings">The security settings.</param>
		internal SigningBindingElement(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Contract.Requires<ArgumentNullException>(associationStore != null);
			Contract.Requires<ArgumentNullException>(securitySettings != null);

			this.opAssociations = associationStore;
			this.opSecuritySettings = securitySettings;
		}
		/// <summary>
		/// Creates a new association of a given type at an OpenID Provider.
		/// </summary>
		/// <param name="protocol">The protocol.</param>
		/// <param name="associationType">Type of the association (i.e. HMAC-SHA1 or HMAC-SHA256)</param>
		/// <param name="associationUse">A value indicating whether the new association will be used privately by the Provider for "dumb mode" authentication
		/// or shared with the Relying Party for "smart mode" authentication.</param>
		/// <param name="associationStore">The Provider's association store.</param>
		/// <param name="securitySettings">The security settings of the Provider.</param>
		/// <returns>
		/// The newly created association.
		/// </returns>
		/// <remarks>
		/// The new association is NOT automatically put into an association store.  This must be done by the caller.
		/// </remarks>
		internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Requires.NotNull(protocol, "protocol");
			Requires.NotNullOrEmpty(associationType, "associationType");
			Requires.NotNull(associationStore, "associationStore");
			Requires.NotNull(securitySettings, "securitySettings");
			Contract.Ensures(Contract.Result<HmacShaAssociation>() != null);

			int secretLength = HmacShaAssociation.GetSecretLength(protocol, associationType);

			// Generate the secret that will be used for signing
			byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength);

			TimeSpan lifetime;
			if (associationUse == AssociationRelyingPartyType.Smart) {
				if (!securitySettings.AssociationLifetimes.TryGetValue(associationType, out lifetime)) {
					lifetime = DefaultMaximumLifetime;
				}
			} else {
				lifetime = HmacShaAssociation.DumbSecretLifetime;
			}

			string handle = associationStore.Serialize(secret, DateTime.UtcNow + lifetime, associationUse == AssociationRelyingPartyType.Dumb);

			Contract.Assert(protocol != null); // All the way up to the method call, the condition holds, yet we get a Requires failure next
			Contract.Assert(secret != null);
			Contract.Assert(!string.IsNullOrEmpty(associationType));
			var result = HmacShaAssociation.Create(protocol, associationType, handle, secret, lifetime);
			return result;
		}
        /// <summary>
        /// Creates the association at the provider side after the association request has been received.
        /// </summary>
        /// <param name="request">The association request.</param>
        /// <param name="associationStore">The OpenID Provider's association store or handle encoder.</param>
        /// <param name="securitySettings">The security settings of the Provider.</param>
        /// <returns>
        /// The newly created association.
        /// </returns>
        /// <remarks>
        /// The response message is updated to include the details of the created association by this method,
        /// but the resulting association is <i>not</i> added to the association store and must be done by the caller.
        /// </remarks>
        public Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            var diffieHellmanRequest = request as AssociateDiffieHellmanRequest;

            ErrorUtilities.VerifyInternal(diffieHellmanRequest != null, "Expected a DH request type.");

            this.SessionType = this.SessionType ?? request.SessionType;

            // Go ahead and create the association first, complete with its secret that we're about to share.
            Association association = HmacShaAssociationProvider.Create(this.Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings);

            // We now need to securely communicate the secret to the relying party using Diffie-Hellman.
            // We do this by performing a DH algorithm on the secret and setting a couple of properties
            // that will be transmitted to the Relying Party.  The RP will perform an inverse operation
            // using its part of a DH secret in order to decrypt the shared secret we just invented
            // above when we created the association.
            using (DiffieHellman dh = new DiffieHellmanManaged(
                       diffieHellmanRequest.DiffieHellmanModulus ?? AssociateDiffieHellmanRequest.DefaultMod,
                       diffieHellmanRequest.DiffieHellmanGen ?? AssociateDiffieHellmanRequest.DefaultGen,
                       AssociateDiffieHellmanRequest.DefaultX)) {
                HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(this.Protocol, this.SessionType);
                this.DiffieHellmanServerPublic = DiffieHellmanUtilities.EnsurePositive(dh.CreateKeyExchange());
                this.EncodedMacKey             = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey);
            }
            return(association);
        }
Exemple #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OpenIdProviderChannel"/> 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.</param>
 private OpenIdProviderChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings)
     : base(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings))
 {
     Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
     Requires.NotNull(messageTypeProvider, "messageTypeProvider");
     Requires.NotNull(securitySettings, "securitySettings");
 }
Exemple #5
0
        /// <summary>
        /// Called to create the Association based on a request previously given by the Relying Party.
        /// </summary>
        /// <param name="request">The prior request for an association.</param>
        /// <param name="associationStore">The Provider's association store.</param>
        /// <param name="securitySettings">The security settings of the Provider.</param>
        /// <returns>
        /// The created association.
        /// </returns>
        /// <remarks>
        ///   <para>The caller will update this message's
        ///   <see cref="AssociateSuccessfulResponse.ExpiresIn"/> and
        ///   <see cref="AssociateSuccessfulResponse.AssociationHandle"/>
        /// properties based on the <see cref="Association"/> returned by this method, but any other
        /// association type specific properties must be set by this method.</para>
        ///   <para>The response message is updated to include the details of the created association by this method,
        /// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para>
        /// </remarks>
        public Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            Association association = HmacShaAssociationProvider.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings);

            this.MacKey = association.SecretKey;
            return(association);
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="ProviderSigningBindingElement"/> class.
		/// </summary>
		/// <param name="associationStore">The association store used to look up the secrets needed for signing.</param>
		/// <param name="securitySettings">The security settings.</param>
		internal ProviderSigningBindingElement(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Requires.NotNull(associationStore, "associationStore");
			Requires.NotNull(securitySettings, "securitySettings");

			this.opAssociations = associationStore;
			this.opSecuritySettings = securitySettings;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderSigningBindingElement"/> class.
        /// </summary>
        /// <param name="associationStore">The association store used to look up the secrets needed for signing.</param>
        /// <param name="securitySettings">The security settings.</param>
        internal ProviderSigningBindingElement(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            Requires.NotNull(associationStore, "associationStore");
            Requires.NotNull(securitySettings, "securitySettings");

            this.opAssociations     = associationStore;
            this.opSecuritySettings = securitySettings;
        }
            /// <summary>
            /// Initializes a new instance of the <see cref="SwitchingAssociationStore"/> class.
            /// </summary>
            /// <param name="cryptoKeyStore">The crypto key store.</param>
            /// <param name="securitySettings">The security settings.</param>
            internal SwitchingAssociationStore(ICryptoKeyStore cryptoKeyStore, ProviderSecuritySettings securitySettings)
            {
                Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
                Requires.NotNull(securitySettings, "securitySettings");
                this.securitySettings = securitySettings;

                this.associationHandleEncoder = new ProviderAssociationHandleEncoder(cryptoKeyStore);
                this.associationSecretStorage = new ProviderAssociationKeyStorage(cryptoKeyStore);
            }
Exemple #9
0
 /// <summary>
 /// Determines whether the association with the specified handle is (still) valid.
 /// </summary>
 /// <param name="associationStore">The association store.</param>
 /// <param name="containingMessage">The OpenID message that referenced this association handle.</param>
 /// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param>
 /// <param name="handle">The association handle.</param>
 /// <returns>
 ///   <c>true</c> if the specified containing message is valid; otherwise, <c>false</c>.
 /// </returns>
 internal static bool IsValid(this IProviderAssociationStore associationStore, IProtocolMessage containingMessage, bool isPrivateAssociation, string handle)
 {
     Requires.NotNull(associationStore, "associationStore");
     Requires.NotNull(containingMessage, "containingMessage");
     Requires.NotNullOrEmpty(handle, "handle");
     try {
         return(associationStore.Deserialize(containingMessage, isPrivateAssociation, handle) != null);
     } catch (ProtocolException) {
         return(false);
     }
 }
		/// <summary>
		/// Called to create the Association based on a request previously given by the Relying Party.
		/// </summary>
		/// <param name="request">The prior request for an association.</param>
		/// <param name="response">The response.</param>
		/// <param name="associationStore">The Provider's association store.</param>
		/// <param name="securitySettings">The security settings for the Provider.  Should be <c>null</c> for Relying Parties.</param>
		/// <returns>
		/// The created association.
		/// </returns>
		/// <remarks>
		/// The response message is updated to include the details of the created association by this method.
		/// This method is called by both the Provider and the Relying Party, but actually performs
		/// quite different operations in either scenario.
		/// </remarks>
		internal static Association CreateAssociation(AssociateRequest request, IAssociateSuccessfulResponseProvider response, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Requires.NotNull(request, "request");
			Requires.NotNull(response, "response");
			Requires.NotNull(securitySettings, "securitySettings");

			// We need to initialize some common properties based on the created association.
			var association = response.CreateAssociationAtProvider(request, associationStore, securitySettings);
			response.ExpiresIn = association.SecondsTillExpiration;
			response.AssociationHandle = association.Handle;

			return association;
		}
		/// <summary>
		/// Initializes the binding elements.
		/// </summary>
		/// <param name="cryptoKeyStore">The OpenID Provider's 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 RelyingPartySecuritySettings or ProviderSecuritySettings.</param>
		/// <returns>
		/// An array of binding elements which may be used to construct the channel.
		/// </returns>
		private static IChannelBindingElement[] InitializeBindingElements(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings) {
			Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
			Requires.NotNull(securitySettings, "securitySettings");
			Requires.NotNull(nonceStore, "nonceStore");

			SigningBindingElement signingElement;
			signingElement = new ProviderSigningBindingElement(cryptoKeyStore, securitySettings);

			var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration();

			List<IChannelBindingElement> elements = new List<IChannelBindingElement>(8);
			elements.Add(new ExtensionsBindingElement(extensionFactory, securitySettings, true));
			elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true));
			elements.Add(new StandardExpirationBindingElement());
			elements.Add(signingElement);

			return elements.ToArray();
		}
Exemple #12
0
        /// <summary>
        /// Initializes the binding elements.
        /// </summary>
        /// <param name="cryptoKeyStore">The OpenID Provider's 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 RelyingPartySecuritySettings or ProviderSecuritySettings.</param>
        /// <returns>
        /// An array of binding elements which may be used to construct the channel.
        /// </returns>
        private static IChannelBindingElement[] InitializeBindingElements(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings)
        {
            Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
            Requires.NotNull(securitySettings, "securitySettings");
            Requires.NotNull(nonceStore, "nonceStore");

            SigningBindingElement signingElement;

            signingElement = new ProviderSigningBindingElement(cryptoKeyStore, securitySettings);

            var extensionFactory = OpenIdExtensionFactoryAggregator.LoadFromConfiguration();

            List <IChannelBindingElement> elements = new List <IChannelBindingElement>(8);

            elements.Add(new ExtensionsBindingElement(extensionFactory, securitySettings, true));
            elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true));
            elements.Add(new StandardExpirationBindingElement());
            elements.Add(signingElement);

            return(elements.ToArray());
        }
		/// <summary>
		/// Creates a Provider's response to an incoming association request.
		/// </summary>
		/// <param name="requestMessage">The request message.</param>
		/// <param name="associationStore">The association store.</param>
		/// <param name="securitySettings">The security settings on the Provider.</param>
		/// <returns>
		/// The appropriate association response that is ready to be sent back to the Relying Party.
		/// </returns>
		/// <remarks>
		///   <para>If an association is created, it will be automatically be added to the provided
		/// association store.</para>
		///   <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>.
		/// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para>
		/// </remarks>
		internal static IProtocolMessage CreateResponse(IAssociateRequestProvider requestMessage, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Requires.NotNull(requestMessage, "requestMessage");
			Requires.NotNull(associationStore, "associationStore");
			Requires.NotNull(securitySettings, "securitySettings");

			AssociateRequest request = (AssociateRequest)requestMessage;
			IProtocolMessage response;
			var protocol = requestMessage.GetProtocol();
			if (securitySettings.IsAssociationInPermittedRange(protocol, request.AssociationType) &&
				HmacShaAssociation.IsDHSessionCompatible(protocol, request.AssociationType, request.SessionType)) {
				response = requestMessage.CreateResponseCore();

				// Create and store the association if this is a successful response.
				var successResponse = response as IAssociateSuccessfulResponseProvider;
				if (successResponse != null) {
					OpenIdProviderUtilities.CreateAssociation(request, successResponse, associationStore, securitySettings);
				}
			} else {
				response = CreateUnsuccessfulResponse(requestMessage, securitySettings);
			}

			return response;
		}
		/// <summary>
		/// Creates the association at the provider side after the association request has been received.
		/// </summary>
		/// <param name="request">The association request.</param>
		/// <param name="associationStore">The OpenID Provider's association store or handle encoder.</param>
		/// <param name="securitySettings">The security settings of the Provider.</param>
		/// <returns>
		/// The newly created association.
		/// </returns>
		/// <remarks>
		/// The response message is updated to include the details of the created association by this method,
		/// but the resulting association is <i>not</i> added to the association store and must be done by the caller.
		/// </remarks>
		protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			var diffieHellmanRequest = request as AssociateDiffieHellmanRequest;
			ErrorUtilities.VerifyInternal(diffieHellmanRequest != null, "Expected a DH request type.");

			this.SessionType = this.SessionType ?? request.SessionType;

			// Go ahead and create the association first, complete with its secret that we're about to share.
			Association association = HmacShaAssociation.Create(this.Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings);

			// We now need to securely communicate the secret to the relying party using Diffie-Hellman.
			// We do this by performing a DH algorithm on the secret and setting a couple of properties
			// that will be transmitted to the Relying Party.  The RP will perform an inverse operation
			// using its part of a DH secret in order to decrypt the shared secret we just invented 
			// above when we created the association.
			using (DiffieHellman dh = new DiffieHellmanManaged(
				diffieHellmanRequest.DiffieHellmanModulus ?? AssociateDiffieHellmanRequest.DefaultMod,
				diffieHellmanRequest.DiffieHellmanGen ?? AssociateDiffieHellmanRequest.DefaultGen,
				AssociateDiffieHellmanRequest.DefaultX)) {
				HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(this.Protocol, this.SessionType);
				this.DiffieHellmanServerPublic = DiffieHellmanUtilities.EnsurePositive(dh.CreateKeyExchange());
				this.EncodedMacKey = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey);
			}
			return association;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="OpenIdProviderChannel"/> class.
		/// </summary>
		/// <param name="cryptoKeyStore">The OpenID Provider's association store or handle encoder.</param>
		/// <param name="nonceStore">The nonce store to use.</param>
		/// <param name="securitySettings">The security settings.</param>
		internal OpenIdProviderChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings)
			: this(cryptoKeyStore, nonceStore, new OpenIdProviderMessageFactory(), securitySettings) {
			Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
			Requires.NotNull(securitySettings, "securitySettings");
		}
		protected override Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Contract.Requires<ArgumentNullException>(request != null);
			Contract.Requires<ArgumentNullException>(associationStore != null);
			Contract.Requires<ArgumentNullException>(securitySettings != null);
			throw new NotImplementedException();
		}
Exemple #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OpenIdProviderChannel"/> class.
 /// </summary>
 /// <param name="cryptoKeyStore">The OpenID Provider's association store or handle encoder.</param>
 /// <param name="nonceStore">The nonce store to use.</param>
 /// <param name="securitySettings">The security settings.</param>
 internal OpenIdProviderChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings)
     : this(cryptoKeyStore, nonceStore, new OpenIdProviderMessageFactory(), securitySettings)
 {
     Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
     Requires.NotNull(securitySettings, "securitySettings");
 }
        /// <summary>
        /// Creates a Provider's response to an incoming association request.
        /// </summary>
        /// <param name="requestMessage">The request message.</param>
        /// <param name="associationStore">The association store.</param>
        /// <param name="securitySettings">The security settings on the Provider.</param>
        /// <returns>
        /// The appropriate association response that is ready to be sent back to the Relying Party.
        /// </returns>
        /// <remarks>
        ///   <para>If an association is created, it will be automatically be added to the provided
        /// association store.</para>
        ///   <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>.
        /// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para>
        /// </remarks>
        internal static IProtocolMessage CreateResponse(IAssociateRequestProvider requestMessage, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            Requires.NotNull(requestMessage, "requestMessage");
            Requires.NotNull(associationStore, "associationStore");
            Requires.NotNull(securitySettings, "securitySettings");

            AssociateRequest request = (AssociateRequest)requestMessage;
            IProtocolMessage response;
            var protocol = requestMessage.GetProtocol();

            if (securitySettings.IsAssociationInPermittedRange(protocol, request.AssociationType) &&
                HmacShaAssociation.IsDHSessionCompatible(protocol, request.AssociationType, request.SessionType))
            {
                response = requestMessage.CreateResponseCore();

                // Create and store the association if this is a successful response.
                var successResponse = response as IAssociateSuccessfulResponseProvider;
                if (successResponse != null)
                {
                    OpenIdProviderUtilities.CreateAssociation(request, successResponse, associationStore, securitySettings);
                }
            }
            else
            {
                response = CreateUnsuccessfulResponse(requestMessage, securitySettings);
            }

            return(response);
        }
		/// <summary>
		/// Called to create the Association based on a request previously given by the Relying Party.
		/// </summary>
		/// <param name="request">The prior request for an association.</param>
		/// <param name="associationStore">The Provider's association store.</param>
		/// <param name="securitySettings">The security settings of the Provider.</param>
		/// <returns>
		/// The created association.
		/// </returns>
		/// <remarks>
		///   <para>The caller will update this message's
		///   <see cref="AssociateSuccessfulResponse.ExpiresIn"/> and
		///   <see cref="AssociateSuccessfulResponse.AssociationHandle"/>
		/// properties based on the <see cref="Association"/> returned by this method, but any other
		/// association type specific properties must be set by this method.</para>
		///   <para>The response message is updated to include the details of the created association by this method,
		/// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para>
		/// </remarks>
		public Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Association association = HmacShaAssociationProvider.Create(Protocol, this.AssociationType, AssociationRelyingPartyType.Smart, associationStore, securitySettings);
			this.MacKey = association.SecretKey;
			return association;
		}
			/// <summary>
			/// Initializes a new instance of the <see cref="SwitchingAssociationStore"/> class.
			/// </summary>
			/// <param name="cryptoKeyStore">The crypto key store.</param>
			/// <param name="securitySettings">The security settings.</param>
			internal SwitchingAssociationStore(ICryptoKeyStore cryptoKeyStore, ProviderSecuritySettings securitySettings) {
				Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
				Requires.NotNull(securitySettings, "securitySettings");
				this.securitySettings = securitySettings;

				this.associationHandleEncoder = new ProviderAssociationHandleEncoder(cryptoKeyStore);
				this.associationSecretStorage = new ProviderAssociationKeyStorage(cryptoKeyStore);
			}
		/// <summary>
		/// Initializes a new instance of the <see cref="OpenIdProviderChannel"/> 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.</param>
		private OpenIdProviderChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings)
			: base(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings)) {
			Requires.NotNull(cryptoKeyStore, "cryptoKeyStore");
			Requires.NotNull(messageTypeProvider, "messageTypeProvider");
			Requires.NotNull(securitySettings, "securitySettings");
		}
Exemple #22
0
        /// <summary>
        /// Creates a new association of a given type at an OpenID Provider.
        /// </summary>
        /// <param name="protocol">The protocol.</param>
        /// <param name="associationType">Type of the association (i.e. HMAC-SHA1 or HMAC-SHA256)</param>
        /// <param name="associationUse">A value indicating whether the new association will be used privately by the Provider for "dumb mode" authentication
        /// or shared with the Relying Party for "smart mode" authentication.</param>
        /// <param name="associationStore">The Provider's association store.</param>
        /// <param name="securitySettings">The security settings of the Provider.</param>
        /// <returns>
        /// The newly created association.
        /// </returns>
        /// <remarks>
        /// The new association is NOT automatically put into an association store.  This must be done by the caller.
        /// </remarks>
        internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            Requires.NotNull(protocol, "protocol");
            Requires.NotNullOrEmpty(associationType, "associationType");
            Requires.NotNull(associationStore, "associationStore");
            Requires.NotNull(securitySettings, "securitySettings");

            int secretLength = HmacShaAssociation.GetSecretLength(protocol, associationType);

            // Generate the secret that will be used for signing
            byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength);

            TimeSpan lifetime;

            if (associationUse == AssociationRelyingPartyType.Smart)
            {
                if (!securitySettings.AssociationLifetimes.TryGetValue(associationType, out lifetime))
                {
                    lifetime = DefaultMaximumLifetime;
                }
            }
            else
            {
                lifetime = HmacShaAssociation.DumbSecretLifetime;
            }

            string handle = associationStore.Serialize(secret, DateTime.UtcNow + lifetime, associationUse == AssociationRelyingPartyType.Dumb);

            Assumes.True(protocol != null);             // All the way up to the method call, the condition holds, yet we get a Requires failure next
            Assumes.True(secret != null);
            Assumes.True(!string.IsNullOrEmpty(associationType));
            var result = HmacShaAssociation.Create(protocol, associationType, handle, secret, lifetime);

            return(result);
        }
Exemple #23
0
		/// <summary>
		/// Initializes a new instance of the <see cref="OpenIdChannel"/> class
		/// for use by a Provider.
		/// </summary>
		/// <param name="cryptoKeyStore">The OpenID Provider's association store or handle encoder.</param>
		/// <param name="nonceStore">The nonce store to use.</param>
		/// <param name="securitySettings">The security settings.</param>
		internal OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings)
			: this(cryptoKeyStore, nonceStore, new OpenIdMessageFactory(), securitySettings) {
			Contract.Requires<ArgumentNullException>(cryptoKeyStore != null);
			Contract.Requires<ArgumentNullException>(securitySettings != null);
		}
Exemple #24
0
		/// <summary>
		/// Initializes a new instance of the <see cref="OpenIdChannel"/> class
		/// for use by a Provider.
		/// </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.</param>
		private OpenIdChannel(IProviderAssociationStore cryptoKeyStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings) :
			this(messageTypeProvider, InitializeBindingElements(cryptoKeyStore, nonceStore, securitySettings)) {
				Contract.Requires<ArgumentNullException>(cryptoKeyStore != null);
			Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
			Contract.Requires<ArgumentNullException>(securitySettings != null);
		}
		/// <summary>
		/// Called to create the Association based on a request previously given by the Relying Party.
		/// </summary>
		/// <param name="request">The prior request for an association.</param>
		/// <param name="associationStore">The Provider's association store.</param>
		/// <param name="securitySettings">The security settings of the Provider.</param>
		/// <returns>
		/// The created association.
		/// </returns>
		/// <remarks>
		///   <para>The caller will update this message's <see cref="ExpiresIn"/> and <see cref="AssociationHandle"/>
		/// properties based on the <see cref="Association"/> returned by this method, but any other
		/// association type specific properties must be set by this method.</para>
		///   <para>The response message is updated to include the details of the created association by this method,
		/// but the resulting association is <i>not</i> added to the association store and must be done by the caller.</para>
		/// </remarks>
		protected abstract Association CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings);
		/// <summary>
		/// Called to create the Association based on a request previously given by the Relying Party.
		/// </summary>
		/// <param name="request">The prior request for an association.</param>
		/// <param name="associationStore">The Provider's association store.</param>
		/// <param name="securitySettings">The security settings of the Provider.</param>
		/// <returns>
		/// The created association.
		/// </returns>
		Association IAssociateSuccessfulResponseProvider.CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Requires.NotNull(request, "request");
			Requires.NotNull(associationStore, "associationStore");
			Requires.NotNull(securitySettings, "securitySettings");
			throw new NotImplementedException();
		}
Exemple #27
0
        /// <summary>
        /// Called to create the Association based on a request previously given by the Relying Party.
        /// </summary>
        /// <param name="request">The prior request for an association.</param>
        /// <param name="response">The response.</param>
        /// <param name="associationStore">The Provider's association store.</param>
        /// <param name="securitySettings">The security settings for the Provider.  Should be <c>null</c> for Relying Parties.</param>
        /// <returns>
        /// The created association.
        /// </returns>
        /// <remarks>
        /// The response message is updated to include the details of the created association by this method.
        /// This method is called by both the Provider and the Relying Party, but actually performs
        /// quite different operations in either scenario.
        /// </remarks>
        internal static Association CreateAssociation(AssociateRequest request, IAssociateSuccessfulResponseProvider response, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            Requires.NotNull(request, "request");
            Requires.NotNull(response, "response");
            Requires.NotNull(securitySettings, "securitySettings");

            // We need to initialize some common properties based on the created association.
            var association = response.CreateAssociationAtProvider(request, associationStore, securitySettings);

            response.ExpiresIn         = association.SecondsTillExpiration;
            response.AssociationHandle = association.Handle;

            return(association);
        }
		/// <summary>
		/// Creates a Provider's response to an incoming association request.
		/// </summary>
		/// <param name="associationStore">The association store.</param>
		/// <param name="securitySettings">The security settings on the Provider.</param>
		/// <returns>
		/// The appropriate association response that is ready to be sent back to the Relying Party.
		/// </returns>
		/// <remarks>
		///   <para>If an association is created, it will be automatically be added to the provided
		/// association store.</para>
		///   <para>Successful association response messages will derive from <see cref="AssociateSuccessfulResponse"/>.
		/// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para>
		/// </remarks>
		internal IProtocolMessage CreateResponse(IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Contract.Requires<ArgumentNullException>(associationStore != null);
			Contract.Requires<ArgumentNullException>(securitySettings != null);

			IProtocolMessage response;
			if (securitySettings.IsAssociationInPermittedRange(Protocol, this.AssociationType) &&
				HmacShaAssociation.IsDHSessionCompatible(Protocol, this.AssociationType, this.SessionType)) {
				response = this.CreateResponseCore();

				// Create and store the association if this is a successful response.
				var successResponse = response as AssociateSuccessfulResponse;
				if (successResponse != null) {
					successResponse.CreateAssociation(this, associationStore, securitySettings);
				}
			} else {
				response = this.CreateUnsuccessfulResponse(securitySettings);
			}

			return response;
		}
Exemple #29
0
 /// <summary>
 /// Called to create the Association based on a request previously given by the Relying Party.
 /// </summary>
 /// <param name="request">The prior request for an association.</param>
 /// <param name="associationStore">The Provider's association store.</param>
 /// <param name="securitySettings">The security settings of the Provider.</param>
 /// <returns>
 /// The created association.
 /// </returns>
 Association IAssociateSuccessfulResponseProvider.CreateAssociationAtProvider(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
 {
     Requires.NotNull(request, "request");
     Requires.NotNull(associationStore, "associationStore");
     Requires.NotNull(securitySettings, "securitySettings");
     throw new NotImplementedException();
 }
			/// <summary>
			/// Initializes a new instance of the <see cref="SwitchingAssociationStore"/> class.
			/// </summary>
			/// <param name="cryptoKeyStore">The crypto key store.</param>
			/// <param name="securitySettings">The security settings.</param>
			internal SwitchingAssociationStore(ICryptoKeyStore cryptoKeyStore, ProviderSecuritySettings securitySettings) {
				Contract.Requires<ArgumentNullException>(cryptoKeyStore != null);
				Contract.Requires<ArgumentNullException>(securitySettings != null);
				this.securitySettings = securitySettings;

				this.associationHandleEncoder = new ProviderAssociationHandleEncoder(cryptoKeyStore);
				this.associationSecretStorage = new ProviderAssociationKeyStorage(cryptoKeyStore);
			}
		/// <summary>
		/// Called to create the Association based on a request previously given by the Relying Party.
		/// </summary>
		/// <param name="request">The prior request for an association.</param>
		/// <param name="associationStore">The Provider's association store.</param>
		/// <param name="securitySettings">The security settings for the Provider.  Should be <c>null</c> for Relying Parties.</param>
		/// <returns>
		/// The created association.
		/// </returns>
		/// <remarks>
		/// The response message is updated to include the details of the created association by this method.
		/// This method is called by both the Provider and the Relying Party, but actually performs
		/// quite different operations in either scenario.
		/// </remarks>
		internal Association CreateAssociation(AssociateRequest request, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings) {
			Contract.Requires<ArgumentNullException>(request != null);
			ErrorUtilities.VerifyInternal(!this.associationCreated, "The association has already been created.");

			Association association;

			// If this message is outgoing, then we need to initialize some common
			// properties based on the created association.
			if (this.Incoming) {
				association = this.CreateAssociationAtRelyingParty(request);
			} else {
				ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
				association = this.CreateAssociationAtProvider(request, associationStore, securitySettings);
				this.ExpiresIn = association.SecondsTillExpiration;
				this.AssociationHandle = association.Handle;
			}

			this.associationCreated = true;

			return association;
		}