//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.RelyingParty { using System; using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging.Bindings; /// /// Wraps a standard so that it behaves as an association store. /// internal class CryptoKeyStoreAsRelyingPartyAssociationStore : IRelyingPartyAssociationStore { /// /// The underlying key store. /// private readonly ICryptoKeyStore keyStore; /// /// Initializes a new instance of the class. /// /// The key store. internal CryptoKeyStoreAsRelyingPartyAssociationStore(ICryptoKeyStore keyStore) { Requires.NotNull(keyStore, "keyStore"); Contract.Ensures(this.keyStore == keyStore); this.keyStore = keyStore; } /// /// Saves an for later recall. /// /// The OP Endpoint with which the association is established. /// The association to store. public void StoreAssociation(Uri providerEndpoint, Association association) { var cryptoKey = new CryptoKey(association.SerializePrivateData(), association.Expires); this.keyStore.StoreKey(providerEndpoint.AbsoluteUri, association.Handle, cryptoKey); } /// /// Gets the best association (the one with the longest remaining life) for a given key. /// /// The OP Endpoint with which the association is established. /// The security requirements that the returned association must meet. /// /// The requested association, or null if no unexpired s exist for the given key. /// public Association GetAssociation(Uri providerEndpoint, SecuritySettings securityRequirements) { var matches = from cryptoKey in this.keyStore.GetKeys(providerEndpoint.AbsoluteUri) where cryptoKey.Value.ExpiresUtc > DateTime.UtcNow orderby cryptoKey.Value.ExpiresUtc descending let assoc = Association.Deserialize(cryptoKey.Key, cryptoKey.Value.ExpiresUtc, cryptoKey.Value.Key) where assoc.HashBitLength >= securityRequirements.MinimumHashBitLength where assoc.HashBitLength <= securityRequirements.MaximumHashBitLength select assoc; return matches.FirstOrDefault(); } /// /// Gets the association for a given key and handle. /// /// The OP Endpoint with which the association is established. /// The handle of the specific association that must be recalled. /// /// The requested association, or null if no unexpired s exist for the given key and handle. /// public Association GetAssociation(Uri providerEndpoint, string handle) { var cryptoKey = this.keyStore.GetKey(providerEndpoint.AbsoluteUri, handle); return cryptoKey != null ? Association.Deserialize(handle, cryptoKey.ExpiresUtc, cryptoKey.Key) : null; } /// /// Removes a specified handle that may exist in the store. /// /// The OP Endpoint with which the association is established. /// The handle of the specific association that must be deleted. /// /// True if the association existed in this store previous to this call. /// public bool RemoveAssociation(Uri providerEndpoint, string handle) { this.keyStore.RemoveKey(providerEndpoint.AbsoluteUri, handle); return true; // return value isn't used by DNOA. } } }