//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.Provider { using System; using System.Collections.Generic; using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OpenId.Provider; using Validation; /// /// OpenID Provider utility methods for HMAC-SHA* associations. /// internal static class HmacShaAssociationProvider { /// /// The default lifetime of a shared association when no lifetime is given /// for a specific association type. /// private static readonly TimeSpan DefaultMaximumLifetime = TimeSpan.FromDays(14); /// /// Creates a new association of a given type at an OpenID Provider. /// /// The protocol. /// Type of the association (i.e. HMAC-SHA1 or HMAC-SHA256) /// 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. /// The Provider's association store. /// The security settings of the Provider. /// /// The newly created association. /// /// /// The new association is NOT automatically put into an association store. This must be done by the caller. /// 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; } } }