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