* Makefile: Added new targets for running the tests. Now the generated
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / TlsStream.cs
1 /* Transport Security Layer (TLS)
2  * Copyright (c) 2003-2004 Carlos Guzman Alvarez
3  * 
4  * Permission is hereby granted, free of charge, to any person 
5  * obtaining a copy of this software and associated documentation 
6  * files (the "Software"), to deal in the Software without restriction, 
7  * including without limitation the rights to use, copy, modify, merge, 
8  * publish, distribute, sublicense, and/or sell copies of the Software, 
9  * and to permit persons to whom the Software is furnished to do so, 
10  * subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be included 
13  * in all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
17  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 using System;
26 using System.IO;
27 using System.Net;
28
29 namespace Mono.Security.Protocol.Tls
30 {
31         internal class TlsStream : Stream
32         {
33                 #region Fields
34
35                 private bool                            canRead;
36                 private bool                            canWrite;
37                 private MemoryStream            buffer;
38
39                 #endregion
40
41                 #region Properties
42
43                 public bool EOF
44                 {
45                         get 
46                         {
47                                 if (this.Position < this.Length)
48                                 {
49                                         return false;
50                                 }
51                                 else
52                                 {
53                                         return true;
54                                 }
55                         }
56                 }
57
58                 #endregion
59
60                 #region Stream Properties
61
62                 public override bool CanWrite
63                 {
64                         get { return this.canWrite; }
65                 }
66
67                 public override bool CanRead
68                 {
69                         get { return this.canRead; }
70                 }
71
72                 public override bool CanSeek
73                 {
74                         get { return this.buffer.CanSeek; }
75                 }
76
77                 public override long Position
78                 {
79                         get { return this.buffer.Position; }
80                         set { this.buffer.Position = value; }
81                 }
82
83                 public override long Length
84                 {
85                         get { return this.buffer.Length; }
86                 }
87
88                 #endregion
89
90                 #region Constructors
91
92                 public TlsStream() : base()
93                 {
94                         this.buffer             = new MemoryStream(0);
95                         this.canRead    = false;
96                         this.canWrite   = true;
97                 }
98
99                 public TlsStream(byte[] data) : base()
100                 {
101                         this.buffer             = new MemoryStream(data);
102                         this.canRead    = true;
103                         this.canWrite   = false;
104                 }
105
106                 #endregion
107
108                 #region Specific Read Methods
109
110                 public new byte ReadByte()
111                 {
112                         return (byte)base.ReadByte();
113                 }
114
115                 public short ReadInt16()
116                 {
117                         byte[] bytes = this.ReadBytes(2);
118
119                         return IPAddress.HostToNetworkOrder(BitConverter.ToInt16(bytes, 0));
120                 }
121
122                 public int ReadInt24()
123                 {
124                         byte[] b = this.ReadBytes(3);
125                         
126                         return ((b[0] & 0xff) << 16) | ((b[1] & 0xff) << 8) | (b[2] & 0xff);
127                 }
128
129                 public int ReadInt32()
130                 {
131                         byte[] bytes = this.ReadBytes(4);
132
133                         return IPAddress.HostToNetworkOrder(BitConverter.ToInt32(bytes, 0));
134                 }
135
136                 public long ReadInt64()
137                 {
138                         byte[] bytes = this.ReadBytes(8);
139                                                 
140                         return IPAddress.HostToNetworkOrder(BitConverter.ToInt64(bytes, 0));
141                 }
142
143                 public byte[] ReadBytes(int count)
144                 {
145                         byte[] bytes = new byte[count];
146                         this.Read(bytes, 0, count);
147
148                         return bytes;
149                 }
150
151                 #endregion
152
153                 #region Specific Write Methods
154
155                 public void Write(byte value)
156                 {
157                         this.WriteByte(value);
158                 }
159
160                 public void Write(short value)
161                 {
162                         byte[] bytes = BitConverter.GetBytes((short)IPAddress.HostToNetworkOrder(value));
163                         this.Write(bytes);
164                 }
165
166                 public void WriteInt24(int value)
167                 {
168                         int int24 = IPAddress.HostToNetworkOrder(value);
169                         byte[] content = new byte[3];
170                                 
171                         Buffer.BlockCopy(BitConverter.GetBytes(int24), 1, content, 0, 3);
172
173                         this.Write(content);
174                 }
175
176                 public void Write(int value)
177                 {
178                         byte[] bytes = BitConverter.GetBytes((int)IPAddress.HostToNetworkOrder(value));
179                         this.Write(bytes);
180                 }
181
182                 public void Write(long value)
183                 {
184                         byte[] bytes = BitConverter.GetBytes((long)IPAddress.HostToNetworkOrder(value));
185                         this.Write(bytes);
186                 }
187
188                 public void Write(byte[] buffer)
189                 {
190                         this.Write(buffer, 0, buffer.Length);
191                 }
192
193                 #endregion
194
195                 #region Methods
196
197                 public void Reset()
198                 {
199                         this.buffer.SetLength(0);
200                         this.buffer.Position = 0;
201                 }
202
203                 public byte[] ToArray()
204                 {
205                         return this.buffer.ToArray();
206                 }
207
208                 #endregion
209
210                 #region Stream Methods
211
212                 public override void Flush()
213                 {
214                         this.buffer.Flush();
215                 }
216
217                 public override void SetLength(long length)
218                 {
219                         this.buffer.SetLength(length);
220                 }
221
222                 public override long Seek(long offset, System.IO.SeekOrigin loc)
223                 {
224                         return this.buffer.Seek(offset, loc);
225                 }
226
227                 public override int Read(byte[] buffer, int offset, int count)
228                 {
229                         if (this.canRead)
230                         {
231                                 return this.buffer.Read(buffer, offset, count);
232                         }
233                         throw new InvalidOperationException("Read operations are not allowed by this stream");
234                 }
235
236                 public override void Write(byte[] buffer, int offset, int count)
237                 {
238                         if (this.canWrite)
239                         {
240                                 this.buffer.Write(buffer, offset, count);
241                         }
242                         else
243                         {
244                                 throw new InvalidOperationException("Write operations are not allowed by this stream");
245                         }
246                 }
247
248                 #endregion
249         }
250 }