//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.Messaging { using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Web; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; using DotNetOpenAuth.Messaging.Reflection; using Validation; /// /// A serializer for -derived types /// /// The DataBag-derived type that is to be serialized/deserialized. internal class UriStyleMessageFormatter : DataBagFormatterBase where T : DataBag { /// /// 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 UriStyleMessageFormatter(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 UriStyleMessageFormatter(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 && !string.IsNullOrEmpty(bucket)) || (!signed && !encrypted), null, "Signing or encryption requires a cryptoKeyStore and bucket."); } /// /// Serializes the instance to a buffer. /// /// The message. /// The buffer containing the serialized data. protected override byte[] SerializeCore(T message) { var fields = MessageSerializer.Get(message.GetType()).Serialize(MessageDescriptions.GetAccessor(message)); string value = MessagingUtilities.CreateQueryString(fields); return Encoding.UTF8.GetBytes(value); } /// /// Deserializes the instance from a buffer. /// /// The message instance to initialize with data from the buffer. /// The data buffer. protected override void DeserializeCore(T message, byte[] data) { string value = Encoding.UTF8.GetString(data); // Deserialize into message newly created instance. var serializer = MessageSerializer.Get(message.GetType()); var fields = MessageDescriptions.GetAccessor(message); serializer.Deserialize(HttpUtility.ParseQueryString(value).ToDictionary(), fields); } } }