//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.Provider { using System; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using Validation; /// /// An association storage mechanism that stores the association secrets in a private store, /// and returns randomly generated association handles to refer to these secrets. /// internal class ProviderAssociationKeyStorage : IProviderAssociationStore { /// /// The bucket to use when recording shared associations. /// internal const string SharedAssociationBucket = "https://localhost/dnoa/shared_associations"; /// /// The bucket to use when recording private associations. /// internal const string PrivateAssociationBucket = "https://localhost/dnoa/private_associations"; /// /// The backing crypto key store. /// private readonly ICryptoKeyStore cryptoKeyStore; /// /// Initializes a new instance of the class. /// /// The store where association secrets will be recorded. internal ProviderAssociationKeyStorage(ICryptoKeyStore cryptoKeyStore) { Requires.NotNull(cryptoKeyStore, "cryptoKeyStore"); this.cryptoKeyStore = cryptoKeyStore; } /// /// Stores an association and returns a handle for it. /// /// The association secret. /// The UTC time that the association should expire. /// A value indicating whether this is a private association. /// /// The association handle that represents this association. /// public string Serialize(byte[] secret, DateTime expiresUtc, bool privateAssociation) { string handle; this.cryptoKeyStore.StoreKey( privateAssociation ? PrivateAssociationBucket : SharedAssociationBucket, handle = OpenIdUtilities.GenerateRandomAssociationHandle(), new CryptoKey(secret, expiresUtc)); return handle; } /// /// Retrieves an association given an association handle. /// /// The OpenID message that referenced this association handle. /// A value indicating whether a private association is expected. /// The association handle. /// /// An association instance, or null if the association has expired or the signature is incorrect (which may be because the OP's symmetric key has changed). /// /// Thrown if the association is not of the expected type. public Association Deserialize(IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) { var key = this.cryptoKeyStore.GetKey(isPrivateAssociation ? PrivateAssociationBucket : SharedAssociationBucket, handle); if (key != null) { return Association.Deserialize(handle, key.ExpiresUtc, key.Key); } return null; } } }