//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace System.IdentityModel { using System.Diagnostics; using System.IdentityModel.Diagnostics; using System.IdentityModel.Tokens; using System.IO; using System.IO.Compression; /// /// Provides cookie compression using . /// public sealed class DeflateCookieTransform : CookieTransform { int _maxDecompressedSize = 1024 * 1024; // Default maximum of 1MB /// /// Creates a new instance of . /// public DeflateCookieTransform() { } /// /// Gets or sets the maximum size (in bytes) of a decompressed cookie. /// public int MaxDecompressedSize { get { return _maxDecompressedSize; } set { _maxDecompressedSize = value; } } /// /// Inflates data. /// /// Data previously returned from /// Decoded data. /// The argument 'value' is null. /// The argument 'value' contains zero bytes. /// The decompressed length is larger than MaxDecompressedSize. public override byte[] Decode( byte[] encoded ) { if ( null == encoded ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "encoded" ); } if ( 0 == encoded.Length ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "encoded", SR.GetString( SR.ID6045 ) ); } MemoryStream compressedStream = new MemoryStream( encoded ); using ( DeflateStream deflateStream = new DeflateStream( compressedStream, CompressionMode.Decompress, false ) ) { using ( MemoryStream decompressedStream = new MemoryStream() ) { byte[] buffer = new byte[1024]; int bytesRead; do { bytesRead = deflateStream.Read( buffer, 0, buffer.Length ); decompressedStream.Write( buffer, 0, bytesRead ); // check length against configured maximum to prevevent decompression bomb attacks if ( decompressedStream.Length > MaxDecompressedSize ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException( SR.GetString( SR.ID1068, MaxDecompressedSize ) ) ); } } while ( bytesRead > 0 ); return decompressedStream.ToArray(); } } } /// /// Deflates data. /// /// Data to be compressed. /// Compressed data. /// The argument 'value' is null. /// The argument 'value' contains zero bytes. public override byte[] Encode( byte[] value ) { if ( null == value ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull( "value" ); } if ( 0 == value.Length ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "value", SR.GetString( SR.ID6044 ) ); } using ( MemoryStream compressedStream = new MemoryStream() ) { using ( DeflateStream deflateStream = new DeflateStream( compressedStream, CompressionMode.Compress, true ) ) { deflateStream.Write( value, 0, value.Length ); } byte[] encoded = compressedStream.ToArray(); if ( DiagnosticUtility.ShouldTrace( TraceEventType.Information ) ) { TraceUtility.TraceEvent( TraceEventType.Information, TraceCode.Diagnostics, SR.GetString(SR.TraceDeflateCookieEncode), new DeflateCookieTraceRecord( value.Length, encoded.Length ), null, null ); } return encoded; } } } }