Bug 2986 - CryptographicException if CryptoStream is disposed
Summary: CryptographicException if CryptoStream is disposed
Status: RESOLVED INVALID
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib ()
Version: 2.10.x
Hardware: PC All
: --- normal
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
URL:
Depends on:
Blocks:
 
Reported: 2012-01-20 09:19 UTC by Thomas Klose
Modified: 2012-03-24 08:18 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
DeEncryptExample (3.01 KB, text/x-csharp)
2012-01-20 09:19 UTC, Thomas Klose
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Thomas Klose 2012-01-20 09:19:43 UTC
Created attachment 1243 [details]
DeEncryptExample

If a CryptoStream with a certain minimum length is not read to the end before it is disposed, a CryptographicException is thrown.

This problem occurs with 2.10 versions of Mono (tested under Windows 7 and Ubuntu Oneiric). Mono 2.6 works fine.

Steps to reproduce:
* compile example (DeEncryptExample.cs)
* run example in Mono 2.10 (tested with 2.10.5 and 2.10.8)

Actual results:
* example file can be decrypted: First line of plain text is written on console
* while disposing the CryptoStream, an exception is thrown:

Unhandled Exception: System.Security.Cryptography.CryptographicException: Bad PKCS7 padding. Error found at position 31.
  at Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (PaddingMode padding, Int32 length, Int32 position) [0x0005c] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\Mono.Security.Cryptography\SymmetricTransform.cs:357 
  at Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x001d1] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\Mono.Security.Cryptography\SymmetricTransform.cs:507 
  at Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00034] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\Mono.Security.Cryptography\SymmetricTransform.cs:538 
  at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\RijndaelManagedTransform.cs:94 
  at System.Security.Cryptography.CryptoStream.FlushFinalBlock () [0x0003d] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\CryptoStream.cs:317 
  at System.Security.Cryptography.CryptoStream.Dispose (Boolean disposing) [0x0001c] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\CryptoStream.cs:347 
  at System.IO.Stream.Close () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.IO\Stream.cs:107 
  at System.Security.Cryptography.CryptoStream.Close () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\CryptoStream.cs:112 
  at System.IO.StreamReader.Dispose (Boolean disposing) [0x00011] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.IO\StreamReader.cs:263 
  at System.IO.TextReader.Dispose () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.IO\TextReader.cs:60 
  at Playground.DeEncryptExample.Main () [0x000e8] in /home/klose/src/Playground/Playground/DeEncryptExample.cs:72 
[ERROR] FATAL UNHANDLED EXCEPTION: System.Security.Cryptography.CryptographicException: Bad PKCS7 padding. Error found at position 31.
  at Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (PaddingMode padding, Int32 length, Int32 position) [0x0005c] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\Mono.Security.Cryptography\SymmetricTransform.cs:357 
  at Mono.Security.Cryptography.SymmetricTransform.FinalDecrypt (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x001d1] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\Mono.Security.Cryptography\SymmetricTransform.cs:507 
  at Mono.Security.Cryptography.SymmetricTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00034] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\Mono.Security.Cryptography\SymmetricTransform.cs:538 
  at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (System.Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\RijndaelManagedTransform.cs:94 
  at System.Security.Cryptography.CryptoStream.FlushFinalBlock () [0x0003d] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\CryptoStream.cs:317 
  at System.Security.Cryptography.CryptoStream.Dispose (Boolean disposing) [0x0001c] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\CryptoStream.cs:347 
  at System.IO.Stream.Close () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.IO\Stream.cs:107 
  at System.Security.Cryptography.CryptoStream.Close () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.Security.Cryptography\CryptoStream.cs:112 
  at System.IO.StreamReader.Dispose (Boolean disposing) [0x00011] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.IO\StreamReader.cs:263 
  at System.IO.TextReader.Dispose () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.8\mcs\class\corlib\System.IO\TextReader.cs:60 
  at Playground.DeEncryptExample.Main () [0x000e8] in /home/klose/src/Playground/Playground/DeEncryptExample.cs:72

Expected results:
* example should run without exception



Please note additional comments in the example.
Comment 1 Sebastien Pouliot 2012-01-22 12:06:35 UTC
I'll have to dig a bit into it since not calling FlushFinalBlock is not a solution (it would regress several other test cases in Mono's unit tests).

Thanks for the test case.
Comment 2 kenny goers 2012-03-07 11:04:51 UTC
Is this a verified bug and if so what is it's status?

I've run into a similar exception in a large code base in the latest released version Mono for Android, and this test case fails for me the the same way as mentioned above when running under Mono for Android (trying to be clear).  I'm chasing down the details but it seems like a very similar issue...

Thanks.
Comment 3 Sebastien Pouliot 2012-03-23 09:22:50 UTC
I copied your code, unchanged, inside our unit test suite and executed it in VS2010 (FX4.0) and this is what I get:

This is plain text. This is plain text. This is plain text.
TestCase 'MonoTests.System.Security.Cryptography.CryptoStreamTest.Bug2986'
failed: System.Security.Cryptography.CryptographicException : Padding is invalid and cannot be removed.
	at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
	at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
	at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
	at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
	at System.IO.Stream.Close()
	at System.IO.Stream.Dispose()
	CryptoStreamTest.cs(1666,0): at MonoTests.System.Security.Cryptography.CryptoStreamTest.Bug2986()

AFAICT Mono 2.10 (and master) behavior is correct while the older Mono 2.6 was not (and was fixed).
Comment 4 Thomas Klose 2012-03-23 18:23:01 UTC
Why should it be an error if a encrypted stream is not read to the end? (This is what the original bug was about.)

Maybe this is a missunderstanding, but I cannot *partially* decrypt an encrypted stream with Mono 2.10. Why should this be a feature, not a bug?

Perhaps we need to discuss this a little bit more.
Comment 5 Thomas Klose 2012-03-23 18:25:41 UTC
Typo: "Why shouldn't it be an error if an encrypted..."
Comment 6 Sebastien Pouliot 2012-03-23 20:04:29 UTC
You can - just catch the exception when you close the stream or don't use CryptoStream and work in the buffers yourself. 

That's CryptoStream design to warn you when you're doing an incomplete operation. Remember that the CryptoStream can be used on any ICryptoTransform (not just encryption) and that for *any* case you should be made aware of an incomplete operation.

> Why should this be a feature, not a bug?

Whether you or I (and fwiw I *hate* CryptoStream design) think it's good or bad design does not matter much. People expect Mono to be compatible with Microsoft implementation of .NET and be able to port their code / applications with minimal changes. If Mono behave the same it's a feature, if not it's a bug.
Comment 7 Thomas Klose 2012-03-24 08:18:02 UTC
Thanks for the clarification.