1 // Transport Security Layer (TLS)
2 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
3 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 namespace Mono
.Security
.Protocol
.Tls
30 internal class TlsStream
: Stream
35 private bool canWrite
;
36 private MemoryStream buffer
;
38 private const int temp_size
= 4;
48 if (this.Position
< this.Length
)
61 #region Stream Properties
63 public override bool CanWrite
65 get { return this.canWrite; }
68 public override bool CanRead
70 get { return this.canRead; }
73 public override bool CanSeek
75 get { return this.buffer.CanSeek; }
78 public override long Position
80 get { return this.buffer.Position; }
81 set { this.buffer.Position = value; }
84 public override long Length
86 get { return this.buffer.Length; }
93 public TlsStream() : base()
95 this.buffer
= new MemoryStream(0);
100 public TlsStream(byte[] data
) : base()
103 this.buffer
= new MemoryStream(data
);
105 this.buffer
= new MemoryStream ();
107 this.canWrite
= false;
112 #region Specific Read Methods
114 // hack for reducing memory allocations
115 // returned value is valid only for the length asked *and*
116 // cannot be directly returned outside the class
117 // note: Mono's Stream.ReadByte does a 1 byte array allocation
118 private byte[] ReadSmallValue (int length
)
120 if (length
> temp_size
)
121 throw new ArgumentException ("8 bytes maximum");
123 temp
= new byte[temp_size
];
125 if (this.Read (temp
, 0, length
) != length
)
126 throw new TlsException (String
.Format ("buffer underrun"));
130 public new byte ReadByte()
132 byte[] result
= ReadSmallValue (1);
136 public short ReadInt16()
138 byte[] result
= ReadSmallValue (2);
139 return (short) (result
[0] << 8 | result
[1]);
142 public int ReadInt24()
144 byte[] result
= ReadSmallValue (3);
145 return ((result
[0] << 16) | (result
[1] << 8) | result
[2]);
148 public int ReadInt32()
150 byte[] result
= ReadSmallValue (4);
151 return ((result
[0] << 24) | (result
[1] << 16) | (result
[2] << 8) | result
[3]);
154 public byte[] ReadBytes(int count
)
156 byte[] bytes
= new byte[count
];
157 if (this.Read(bytes
, 0, count
) != count
)
158 throw new TlsException ("buffer underrun");
165 #region Specific Write Methods
167 // note: Mono's Stream.WriteByte does a 1 byte array allocation
168 public void Write(byte value)
171 temp
= new byte[temp_size
];
173 this.Write (temp
, 0, 1);
176 public void Write(short value)
179 temp
= new byte[temp_size
];
180 temp
[0] = ((byte)(value >> 8));
181 temp
[1] = ((byte)value);
182 this.Write (temp
, 0, 2);
185 public void WriteInt24(int value)
188 temp
= new byte[temp_size
];
189 temp
[0] = ((byte)(value >> 16));
190 temp
[1] = ((byte)(value >> 8));
191 temp
[2] = ((byte)value);
192 this.Write (temp
, 0, 3);
195 public void Write(int value)
198 temp
= new byte[temp_size
];
199 temp
[0] = ((byte)(value >> 24));
200 temp
[1] = ((byte)(value >> 16));
201 temp
[2] = ((byte)(value >> 8));
202 temp
[3] = ((byte)value);
203 this.Write (temp
, 0, 4);
206 public void Write(ulong value)
208 Write ((int)(value >> 32));
212 public void Write(byte[] buffer
)
214 this.Write(buffer
, 0, buffer
.Length
);
223 this.buffer
.SetLength(0);
224 this.buffer
.Position
= 0;
227 public byte[] ToArray()
229 return this.buffer
.ToArray();
234 #region Stream Methods
236 public override void Flush()
241 public override void SetLength(long length
)
243 this.buffer
.SetLength(length
);
246 public override long Seek(long offset
, System
.IO
.SeekOrigin loc
)
248 return this.buffer
.Seek(offset
, loc
);
251 public override int Read(byte[] buffer
, int offset
, int count
)
255 return this.buffer
.Read(buffer
, offset
, count
);
257 throw new InvalidOperationException("Read operations are not allowed by this stream");
260 public override void Write(byte[] buffer
, int offset
, int count
)
264 this.buffer
.Write(buffer
, offset
, count
);
268 throw new InvalidOperationException("Write operations are not allowed by this stream");