108 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.IO;
 | |
| 
 | |
| namespace Org.BouncyCastle.Crypto.Tls
 | |
| {
 | |
| 	/// <remarks>An implementation of the TLS 1.0 record layer.</remarks>
 | |
| 	public class RecordStream
 | |
| 	{
 | |
| 		private TlsProtocolHandler handler;
 | |
| 		private Stream inStr;
 | |
| 		private Stream outStr;
 | |
| 		internal CombinedHash hash1;
 | |
| 		internal CombinedHash hash2;
 | |
| 		internal TlsCipherSuite readSuite = null;
 | |
| 		internal TlsCipherSuite writeSuite = null;
 | |
| 
 | |
| 		internal RecordStream(
 | |
| 			TlsProtocolHandler	handler,
 | |
| 			Stream				inStr,
 | |
| 			Stream				outStr)
 | |
| 		{
 | |
| 			this.handler = handler;
 | |
| 			this.inStr = inStr;
 | |
| 			this.outStr = outStr;
 | |
| 			hash1 = new CombinedHash();
 | |
| 			hash2 = new CombinedHash();
 | |
| 			this.readSuite = new TlsNullCipherSuite();
 | |
| 			this.writeSuite = this.readSuite;
 | |
| 		}
 | |
| 
 | |
| 		public void ReadData()
 | |
| 		{
 | |
| 			short type = TlsUtilities.ReadUint8(inStr);
 | |
| 			TlsUtilities.CheckVersion(inStr, handler);
 | |
| 			int size = TlsUtilities.ReadUint16(inStr);
 | |
| 			byte[] buf = DecodeAndVerify(type, inStr, size);
 | |
| 			handler.ProcessData(type, buf, 0, buf.Length);
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		internal byte[] DecodeAndVerify(
 | |
| 			short	type,
 | |
| 			Stream	inStr,
 | |
| 			int		len)
 | |
| 		{
 | |
| 			byte[] buf = new byte[len];
 | |
| 			TlsUtilities.ReadFully(buf, inStr);
 | |
| 			byte[] result = readSuite.DecodeCiphertext(type, buf, 0, buf.Length, handler);
 | |
| 			return result;
 | |
| 		}
 | |
| 
 | |
| 		internal void WriteMessage(
 | |
| 			short	type,
 | |
| 			byte[]	message,
 | |
| 			int		offset,
 | |
| 			int		len)
 | |
| 		{
 | |
| 			if (type == 22)
 | |
| 			{
 | |
| 				hash1.BlockUpdate(message, offset, len);
 | |
| 				hash2.BlockUpdate(message, offset, len);
 | |
| 			}
 | |
| 			byte[] ciphertext = writeSuite.EncodePlaintext(type, message, offset, len);
 | |
| 			byte[] writeMessage = new byte[ciphertext.Length + 5];
 | |
| 			TlsUtilities.WriteUint8(type, writeMessage, 0);
 | |
| 			TlsUtilities.WriteUint8((short)3, writeMessage, 1);
 | |
| 			TlsUtilities.WriteUint8((short)1, writeMessage, 2);
 | |
| 			TlsUtilities.WriteUint16(ciphertext.Length, writeMessage, 3);
 | |
| 			Array.Copy(ciphertext, 0, writeMessage, 5, ciphertext.Length);
 | |
| 			outStr.Write(writeMessage, 0, writeMessage.Length);
 | |
| 			outStr.Flush();
 | |
| 		}
 | |
| 
 | |
| 		internal void Close()
 | |
| 		{
 | |
| 			IOException e = null;
 | |
| 			try
 | |
| 			{
 | |
| 				inStr.Close();
 | |
| 			}
 | |
| 			catch (IOException ex)
 | |
| 			{
 | |
| 				e = ex;
 | |
| 			}
 | |
| 
 | |
| 			try
 | |
| 			{
 | |
| 				// NB: This is harmless if outStr == inStr
 | |
| 				outStr.Close();
 | |
| 			}
 | |
| 			catch (IOException ex)
 | |
| 			{
 | |
| 				e = ex;
 | |
| 			}
 | |
| 
 | |
| 			if (e != null)
 | |
| 			{
 | |
| 				throw e;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		internal void Flush()
 | |
| 		{
 | |
| 			outStr.Flush();
 | |
| 		}
 | |
| 	}
 | |
| }
 |