/// <summary> /// Gets a specific association referenced in a given message's association handle. /// </summary> /// <param name="signedMessage">The signed message whose association handle should be used to lookup the association to return.</param> /// <returns>The referenced association; or <c>null</c> if such an association cannot be found.</returns> /// <remarks> /// If the association handle set in the message does not match any valid association, /// the association handle property is cleared, and the /// <see cref="ITamperResistantOpenIdMessage.InvalidateHandle"/> property is set to the /// handle that could not be found. /// </remarks> private Association GetSpecificAssociation(ITamperResistantOpenIdMessage signedMessage) { Association association = null; if (!string.IsNullOrEmpty(signedMessage.AssociationHandle)) { IndirectSignedResponse indirectSignedMessage = signedMessage as IndirectSignedResponse; if (this.IsOnProvider) { // Since we have an association handle, we're either signing with a smart association, // or verifying a dumb one. bool signing = string.IsNullOrEmpty(signedMessage.Signature); AssociationRelyingPartyType type = signing ? AssociationRelyingPartyType.Smart : AssociationRelyingPartyType.Dumb; association = this.opAssociations.GetAssociation(type, signedMessage.AssociationHandle); if (association == null) { // There was no valid association with the requested handle. // Let's tell the RP to forget about that association. signedMessage.InvalidateHandle = signedMessage.AssociationHandle; signedMessage.AssociationHandle = null; } } else if (this.rpAssociations != null) // if on a smart RP { Uri providerEndpoint = indirectSignedMessage.ProviderEndpoint; association = this.rpAssociations.GetAssociation(providerEndpoint, signedMessage.AssociationHandle); } } return(association); }
/// <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; }
public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var keyWithoutHandle = "assoc-" + distinguishingFactor.ToString(); var keyWithHandle = keyWithoutHandle + "-" + handle; // lack of short-circuit here is important, both these calls need to run return(Current.RemoveFromCache(keyWithoutHandle) | Current.RemoveFromCache(keyWithHandle)); }
public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association assoc) { var assocRow = dataSet.Association.NewAssociationRow(); assocRow.DistinguishingFactor = distinguishingFactor.ToString(); assocRow.Handle = assoc.Handle; assocRow.Expires = assoc.Expires.ToLocalTime(); assocRow.PrivateData = assoc.SerializePrivateData(); dataSet.Association.AddAssociationRow(assocRow); }
public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var row = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle); if (row != null) { dataSet.Association.RemoveAssociationRow(row); return true; } else { return false; } }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var keyWithHandle = "assoc-" + distinguishingFactor.ToString() + "-" + handle; var wrapper = Current.GetFromCache<Wrapper>(keyWithHandle); if (wrapper == null) return null; return Association.Deserialize(wrapper.Handle, wrapper.Expires, wrapper.PrivateData); }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, SecuritySettings securityRequirements) { var keyWithoutHandle = "assoc-" + distinguishingFactor.ToString(); var wrapper = Current.GetFromCache<Wrapper>(keyWithoutHandle); if(wrapper == null) return null; return Association.Deserialize(wrapper.Handle, wrapper.Expires, wrapper.PrivateData); }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor) { // properly escape the URL to prevent injection attacks. string value = distinguishingFactor.ToString(); string filter = string.Format(CultureInfo.InvariantCulture, "{0} = '{1}'", dataSet.Association.DistinguishingFactorColumn.ColumnName, value); string sort = dataSet.Association.ExpiresColumn.ColumnName + " DESC"; DataView view = new DataView(dataSet.Association, filter, sort, DataViewRowState.CurrentRows); if (view.Count == 0) return null; var row = (CustomStoreDataSet.AssociationRow)view[0].Row; return Association.Deserialize(row.Handle, row.Expires.ToUniversalTime(), row.PrivateData); }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var keyWithHandle = "assoc-" + distinguishingFactor.ToString() + "-" + handle; var wrapper = Current.GetFromCache <Wrapper>(keyWithHandle); if (wrapper == null) { return(null); } return(Association.Deserialize(wrapper.Handle, wrapper.Expires, wrapper.PrivateData)); }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, SecuritySettings securityRequirements) { var keyWithoutHandle = "assoc-" + distinguishingFactor.ToString(); var wrapper = Current.GetFromCache <Wrapper>(keyWithoutHandle); if (wrapper == null) { return(null); } return(Association.Deserialize(wrapper.Handle, wrapper.Expires, wrapper.PrivateData)); }
public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var row = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle); if (row != null) { dataSet.Association.RemoveAssociationRow(row); return(true); } else { return(false); } }
public virtual Association CreateAssociation(AssociationRelyingPartyType associationType, OpenIdProvider provider) { if (provider == null && associationType == AssociationRelyingPartyType.Smart) { throw new ArgumentNullException("provider", "For Smart associations, the provider must be given."); } string assoc_type; Protocol associationProtocol; if (associationType == AssociationRelyingPartyType.Dumb) { // We'll just use the best association available. associationProtocol = Protocol.Default; assoc_type = associationProtocol.Args.SignatureAlgorithm.Best; } else { associationProtocol = provider.Protocol; assoc_type = Util.GetRequiredArg(provider.Query, provider.Protocol.openid.assoc_type); Debug.Assert(Array.IndexOf(provider.Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0, "This should have been checked by our caller."); } int secretLength = HmacShaAssociation.GetSecretLength(associationProtocol, assoc_type); RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider(); byte[] secret = new byte[secretLength]; byte[] uniq_bytes = new byte[4]; string uniq; string handle; HmacShaAssociation assoc; generator.GetBytes(secret); generator.GetBytes(uniq_bytes); uniq = Convert.ToBase64String(uniq_bytes); double seconds = DateTime.UtcNow.Subtract(Association.UnixEpoch).TotalSeconds; handle = "{{" + assoc_type + "}{" + seconds + "}{" + uniq + "}"; TimeSpan lifeSpan = associationType == AssociationRelyingPartyType.Dumb ? dumbSecretLifetime : smartAssociationLifetime; assoc = HmacShaAssociation.Create(secretLength, handle, secret, lifeSpan); store.StoreAssociation(associationType, assoc); return(assoc); }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor) { // properly escape the URL to prevent injection attacks. string value = distinguishingFactor.ToString(); string filter = string.Format(CultureInfo.InvariantCulture, "{0} = '{1}'", dataSet.Association.DistinguishingFactorColumn.ColumnName, value); string sort = dataSet.Association.ExpiresColumn.ColumnName + " DESC"; DataView view = new DataView(dataSet.Association, filter, sort, DataViewRowState.CurrentRows); if (view.Count == 0) { return(null); } var row = (CustomStoreDataSet.AssociationRow)view[0].Row; return(Association.Deserialize(row.Handle, row.Expires.ToUniversalTime(), row.PrivateData)); }
public virtual Association GetAssociation(string assoc_handle, AssociationRelyingPartyType associationType) { if (assoc_handle == null) { throw new ArgumentNullException("assoc_handle"); } Association assoc = store.GetAssociation(associationType, assoc_handle); if (assoc == null || assoc.IsExpired) { Logger.ErrorFormat("Association {0} expired or not in store.", assoc_handle); store.RemoveAssociation(associationType, assoc_handle); assoc = null; } return(assoc); }
public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association association) { var keyWithoutHandle = "assoc-" + distinguishingFactor.ToString(); var keyWithHandle = keyWithoutHandle + "-" + association.Handle; var expireIn = association.Expires - Current.Now; var @private = association.SerializePrivateData(); var newRecord = new Wrapper { Expires = association.Expires, PrivateData = @private, Handle = association.Handle }; Current.AddToCache(keyWithoutHandle, newRecord, expireIn); Current.AddToCache(keyWithHandle, newRecord, expireIn); }
public virtual Association CreateAssociation(AssociationRelyingPartyType associationType, OpenIdProvider provider) { if (provider == null && associationType == AssociationRelyingPartyType.Smart) throw new ArgumentNullException("provider", "For Smart associations, the provider must be given."); string assoc_type; Protocol associationProtocol; if (associationType == AssociationRelyingPartyType.Dumb) { // We'll just use the best association available. associationProtocol = Protocol.Default; assoc_type = associationProtocol.Args.SignatureAlgorithm.Best; } else { associationProtocol = provider.Protocol; assoc_type = Util.GetRequiredArg(provider.Query, provider.Protocol.openid.assoc_type); Debug.Assert(Array.IndexOf(provider.Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0, "This should have been checked by our caller."); } int secretLength = HmacShaAssociation.GetSecretLength(associationProtocol, assoc_type); RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider(); byte[] secret = new byte[secretLength]; byte[] uniq_bytes = new byte[4]; string uniq; string handle; HmacShaAssociation assoc; generator.GetBytes(secret); generator.GetBytes(uniq_bytes); uniq = Convert.ToBase64String(uniq_bytes); double seconds = DateTime.UtcNow.Subtract(Association.UnixEpoch).TotalSeconds; handle = "{{" + assoc_type + "}{" + seconds + "}{" + uniq + "}"; TimeSpan lifeSpan = associationType == AssociationRelyingPartyType.Dumb ? dumbSecretLifetime : smartAssociationLifetime; assoc = HmacShaAssociation.Create(secretLength, handle, secret, lifeSpan); store.StoreAssociation(associationType, assoc); return assoc; }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var assocRow = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle); return Association.Deserialize(assocRow.Handle, assocRow.Expires, assocRow.PrivateData); }
public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var keyWithoutHandle = "assoc-" + distinguishingFactor.ToString(); var keyWithHandle = keyWithoutHandle + "-" + handle; // lack of short-circuit here is important, both these calls need to run return Current.RemoveFromCache(keyWithoutHandle) | Current.RemoveFromCache(keyWithHandle); }
/// <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); }
/// <summary> /// Creates a new association of a given type. /// </summary> /// <param name="protocol">The protocol.</param> /// <param name="associationType">Type of the association.</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="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, ProviderSecuritySettings securitySettings) { ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol"); ErrorUtilities.VerifyNonZeroLength(associationType, "associationType"); ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings"); int secretLength = GetSecretLength(protocol, associationType); // Generate the handle. It must be unique, and preferably unpredictable, // so we use a time element and a random data element to generate it. string uniq = MessagingUtilities.GetCryptoRandomDataAsBase64(4); string handle = string.Format( CultureInfo.InvariantCulture, "{{{0}}}{{{1}}}{{{2}}}", DateTime.UtcNow.Ticks, uniq, secretLength); // 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 = DumbSecretLifetime; } return Create(protocol, associationType, handle, secret, lifetime); }
/// <summary> /// Gets the association for a given key and handle. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="handle">The handle of the specific association that must be recalled.</param> /// <returns> /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key and handle. /// </returns> public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { return this.associationStore.GetAssociation(distinguishingFactor, handle); }
/// <summary> /// Saves an <see cref="Association"/> for later recall. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for providers).</param> /// <param name="association">The association to store.</param> public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association association) { this.associationStore.StoreAssociation(distinguishingFactor, association); }
/// <summary> /// Creates a new association of a given type. /// </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="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, ProviderSecuritySettings securitySettings) { Contract.Requires <ArgumentNullException>(protocol != null); Contract.Requires <ArgumentException>(!String.IsNullOrEmpty(associationType)); Contract.Requires <ArgumentNullException>(securitySettings != null); Contract.Ensures(Contract.Result <HmacShaAssociation>() != null); int secretLength = GetSecretLength(protocol, associationType); // Generate the handle. It must be unique, and preferably unpredictable, // so we use a time element and a random data element to generate it. string uniq = MessagingUtilities.GetCryptoRandomDataAsBase64(4); string handle = string.Format( CultureInfo.InvariantCulture, "{{{0}}}{{{1}}}{{{2}}}", DateTime.UtcNow.Ticks, uniq, secretLength); // 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 = DumbSecretLifetime; } 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)); return(Create(protocol, associationType, handle, secret, lifetime)); }
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { var assocRow = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle); return(Association.Deserialize(assocRow.Handle, assocRow.Expires, assocRow.PrivateData)); }
/// <summary> /// Removes a specified handle that may exist in the store. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="handle">The handle of the specific association that must be deleted.</param> /// <returns> /// True if the association existed in this store previous to this call. /// </returns> /// <remarks> /// No exception should be thrown if the association does not exist in the store /// before this call. /// </remarks> public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { return(this.associationStore.RemoveAssociation(distinguishingFactor, handle)); }
public virtual void Invalidate(string assoc_handle, AssociationRelyingPartyType associationType) { Logger.DebugFormat("Invalidating association '{0}'.", assoc_handle); store.RemoveAssociation(associationType, assoc_handle); }
/// <summary> /// Gets the best association (the one with the longest remaining life) for a given key. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="securityRequirements">The security requirements that the returned association must meet.</param> /// <returns> /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key. /// </returns> /// <remarks> /// In the event that multiple associations exist for the given /// <paramref name="distinguishingFactor"/>, it is important for the /// implementation for this method to use the <paramref name="securityRequirements"/> /// to pick the best (highest grade or longest living as the host's policy may dictate) /// association that fits the security requirements. /// Associations that are returned that do not meet the security requirements will be /// ignored and a new association created. /// </remarks> public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, SecuritySettings securityRequirements) { return(this.associationStore.GetAssociation(distinguishingFactor, securityRequirements)); }
/// <summary> /// Creates a new association of a given type. /// </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="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, ProviderSecuritySettings securitySettings) { Contract.Requires<ArgumentNullException>(protocol != null); Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType)); Contract.Requires<ArgumentNullException>(securitySettings != null); Contract.Ensures(Contract.Result<HmacShaAssociation>() != null); int secretLength = GetSecretLength(protocol, associationType); // Generate the handle. It must be unique, and preferably unpredictable, // so we use a time element and a random data element to generate it. string uniq = MessagingUtilities.GetCryptoRandomDataAsBase64(4); string handle = string.Format( CultureInfo.InvariantCulture, "{{{0}}}{{{1}}}{{{2}}}", DateTime.UtcNow.Ticks, uniq, secretLength); // 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 = DumbSecretLifetime; } 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)); return Create(protocol, associationType, handle, secret, lifetime); }
/// <summary> /// Removes a specified handle that may exist in the store. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="handle">The handle of the specific association that must be deleted.</param> /// <returns> /// True if the association existed in this store previous to this call. /// </returns> /// <remarks> /// No exception should be thrown if the association does not exist in the store /// before this call. /// </remarks> public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { return this.associationStore.RemoveAssociation(distinguishingFactor, handle); }
public virtual Association GetAssociation(string assoc_handle, AssociationRelyingPartyType associationType) { if (assoc_handle == null) throw new ArgumentNullException("assoc_handle"); Association assoc = store.GetAssociation(associationType, assoc_handle); if (assoc == null || assoc.IsExpired) { Logger.ErrorFormat("Association {0} expired or not in store.", assoc_handle); store.RemoveAssociation(associationType, assoc_handle); assoc = null; } return assoc; }
/// <summary> /// Gets the best association (the one with the longest remaining life) for a given key. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="securityRequirements">The security requirements that the returned association must meet.</param> /// <returns> /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key. /// </returns> /// <remarks> /// In the event that multiple associations exist for the given /// <paramref name="distinguishingFactor"/>, it is important for the /// implementation for this method to use the <paramref name="securityRequirements"/> /// to pick the best (highest grade or longest living as the host's policy may dictate) /// association that fits the security requirements. /// Associations that are returned that do not meet the security requirements will be /// ignored and a new association created. /// </remarks> public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, SecuritySettings securityRequirements) { return this.associationStore.GetAssociation(distinguishingFactor, securityRequirements); }
/// <summary> /// Creates a new association of a given type. /// </summary> /// <param name="protocol">The protocol.</param> /// <param name="associationType">Type of the association.</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="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, ProviderSecuritySettings securitySettings) { ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol"); ErrorUtilities.VerifyNonZeroLength(associationType, "associationType"); ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings"); // Generate the handle. It must be unique, and preferably unpredictable, // so we use a time element and a random data element to generate it. string uniq = MessagingUtilities.GetCryptoRandomDataAsBase64(4); string handle = "{" + associationType + "}{" + DateTime.UtcNow.Ticks + "}{" + uniq + "}"; // Generate the secret that will be used for signing int secretLength = GetSecretLength(protocol, associationType); byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength); TimeSpan lifetime; if (associationUse == AssociationRelyingPartyType.Smart) { if (!securitySettings.AssociationLifetimes.TryGetValue(associationType, out lifetime)) { lifetime = DefaultMaximumLifetime; } } else { lifetime = DumbSecretLifetime; } return(Create(protocol, associationType, handle, secret, lifetime)); }
/// <summary> /// Gets the association for a given key and handle. /// </summary> /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param> /// <param name="handle">The handle of the specific association that must be recalled.</param> /// <returns> /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key and handle. /// </returns> public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) { return(this.associationStore.GetAssociation(distinguishingFactor, handle)); }