//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OpenId.Provider { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using Validation; /// /// A signed and encrypted serialization of an association. /// internal class AssociationDataBag : DataBag, IStreamSerializingDataBag { /// /// Initializes a new instance of the class. /// public AssociationDataBag() { } /// /// Gets or sets the association secret. /// [MessagePart(IsRequired = true)] internal byte[] Secret { get; set; } /// /// Gets or sets the UTC time that this association expires. /// [MessagePart(IsRequired = true)] internal DateTime ExpiresUtc { get; set; } /// /// Gets or sets a value indicating whether this instance is for "dumb" mode RPs. /// /// /// true if this instance is private association; otherwise, false. /// [MessagePart(IsRequired = true)] internal bool IsPrivateAssociation { get { return this.AssociationType == AssociationRelyingPartyType.Dumb; } set { this.AssociationType = value ? AssociationRelyingPartyType.Dumb : AssociationRelyingPartyType.Smart; } } /// /// Gets or sets the type of the association (shared or private, a.k.a. smart or dumb). /// internal AssociationRelyingPartyType AssociationType { get; set; } /// /// Serializes the instance to the specified stream. /// /// The stream. public void Serialize(Stream stream) { Requires.NotNull(stream, "stream"); Requires.That(stream.CanWrite, "stream", "requires stream.CanWrite"); var writer = new BinaryWriter(stream); writer.Write(this.IsPrivateAssociation); writer.WriteBuffer(this.Secret); writer.Write((int)(this.ExpiresUtc - TimestampEncoder.Epoch).TotalSeconds); writer.Flush(); } /// /// Initializes the fields on this instance from the specified stream. /// /// The stream. public void Deserialize(Stream stream) { Requires.NotNull(stream, "stream"); Requires.That(stream.CanRead, "stream", "requires stream.CanRead"); var reader = new BinaryReader(stream); this.IsPrivateAssociation = reader.ReadBoolean(); this.Secret = reader.ReadBuffer(256); this.ExpiresUtc = TimestampEncoder.Epoch + TimeSpan.FromSeconds(reader.ReadInt32()); } /// /// Creates the formatter used for serialization of this type. /// /// The crypto key store used when signing or encrypting. /// The bucket in which symmetric keys are stored for signing/encrypting data. /// The minimum age. /// /// A formatter for serialization. /// internal static IDataBagFormatter CreateFormatter(ICryptoKeyStore cryptoKeyStore, string bucket, TimeSpan? minimumAge = null) { Requires.NotNull(cryptoKeyStore, "cryptoKeyStore"); Requires.NotNullOrEmpty(bucket, "bucket"); return new BinaryDataBagFormatter(cryptoKeyStore, bucket, signed: true, encrypted: true, minimumAge: minimumAge); } } }