//-----------------------------------------------------------------------
//
// 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;
}
}
}