//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.Messaging { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using DotNetOpenAuth.Messaging.Bindings; using Validation; /// /// A compact binary serialization class. /// /// The -derived type to serialize/deserialize. internal class BinaryDataBagFormatter : DataBagFormatterBase where T : DataBag, IStreamSerializingDataBag, new() { /// /// Initializes a new instance of the class. /// /// The crypto service provider with the asymmetric key to use for signing or verifying the token. /// The crypto service provider with the asymmetric key to use for encrypting or decrypting the token. /// A value indicating whether the data in this instance will be GZip'd. /// The maximum age of a token that can be decoded; useful only when is true. /// The nonce store to use to ensure that this instance is only decoded once. protected internal BinaryDataBagFormatter(RSACryptoServiceProvider signingKey = null, RSACryptoServiceProvider encryptingKey = null, bool compressed = false, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) : base(signingKey, encryptingKey, compressed, maximumAge, decodeOnceOnly) { } /// /// Initializes a new instance of the class. /// /// The crypto key store used when signing or encrypting. /// The bucket in which symmetric keys are stored for signing/encrypting data. /// A value indicating whether the data in this instance will be protected against tampering. /// A value indicating whether the data in this instance will be protected against eavesdropping. /// A value indicating whether the data in this instance will be GZip'd. /// The minimum age. /// The maximum age of a token that can be decoded; useful only when is true. /// The nonce store to use to ensure that this instance is only decoded once. protected internal BinaryDataBagFormatter(ICryptoKeyStore cryptoKeyStore = null, string bucket = null, bool signed = false, bool encrypted = false, bool compressed = false, TimeSpan? minimumAge = null, TimeSpan? maximumAge = null, INonceStore decodeOnceOnly = null) : base(cryptoKeyStore, bucket, signed, encrypted, compressed, minimumAge, maximumAge, decodeOnceOnly) { Requires.That((cryptoKeyStore != null && bucket != null) || (!signed && !encrypted), null, "Signing or encryption requires a crypto key store and bucket."); } /// /// Serializes the instance to a buffer. /// /// The message. /// The buffer containing the serialized data. [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "No apparent problem. False positive?")] protected override byte[] SerializeCore(T message) { using (var stream = new MemoryStream()) { message.Serialize(stream); return stream.ToArray(); } } /// /// Deserializes the instance from a buffer. /// /// The message instance to initialize with data from the buffer. /// The data buffer. [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "No apparent problem. False positive?")] protected override void DeserializeCore(T message, byte[] data) { using (var stream = new MemoryStream(data)) { message.Deserialize(stream); } // Perform basic validation on message that the MessageSerializer would have normally performed. var messageDescription = MessageDescriptions.Get(message); var dictionary = messageDescription.GetDictionary(message); messageDescription.EnsureMessagePartsPassBasicValidation(dictionary); IMessage m = message; m.EnsureValidMessage(); } } }