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