Before you go and say, use Jon Skeet's answer , I can't. I'm using this thread , which works great in the beginning, but now I am having a little problem. I am now at a point where I do not know how much data I expect, so I thought that I would use the Jon Skeet method, but unfortunately, it waits for packet = mPackets.Take() when all the packets have been read.
I have no idea how to fix this, the thread does what it should do (at the beginning), but, unfortunately, this is the case when I do not want it to do what it was created for ...
Should I try to rewrite the waitingstream or is there another readall method that will work better in my case?
I tried to return 0 when there were no more packages available (when I wanted it to read everything and not wait), but then it throws an IO end of stream exception .
I am really in trouble here, I understand that I dug a deep hole for myself ...
So far, I have not been able to find a better solution than to subtract the TLS and GCM IV and MAC header from the total length (as indicated below). This is great for the 1 package I am using now, but not to boast of future cipher suites.
Some context why I do this:
I use https://github.com/bcgit/bc-csharp to create TLS-based encryption, however due to restrictions I cannot assign a TCP stream to it, all I get is a string from the TCP layer, I cannot provide him with a propper TCP stream.
I use mockPskTlsServer and the client , and I created it like this:
WaitingStream mStdin = new WaitingStream(); WaitingStream mStdout = new WaitingStream(); CryptoPskTlsClient mServer = new CryptoPskTlsClient(null); SecureRandom secureRandom = new SecureRandom(); TlsClientProtocol TlsProtocol = new TlsServerProtocol(Stdin, Stdout, secureRandom); TlsProtocol.Connect(mServer);
This works fine, I also added an event to the wait thread, which fires when it is output to the thread. Thus, I could receive messages with several handshakes when they were created.
All this works great, it can be done better (less ... hacked?), But it does what it should do.
I know how to make it work, but it's HACK, and I'm looking for an elegant way to do it. Here is a sample code for one of these HACKS:
public override string DecryptData(string ciphertext) { byte[] ciphertextBuff = ASCIIEncoding.Default.GetBytes(ciphertext); mStdin.Write(ciphertextBuff, 0, ciphertextBuff.Length); Stream tlsStream = mServerProtocol.Stream; byte[] plaintextBuffer = new byte[ciphertextBuff.Length - 29];
or by adding the length of unencrypted text in x reserved bytes to the TLS packet and receiving these bytes before decryption.
but, as you can clearly see from the code example, the buffer in the read method should completely be the length of the bytes I want to extract, it may be less than the stream, but it cannot be more, because then it will wait indefinitely.
When I talk about methods like readall and ReadFully I mean these methods