2003-11-04 Carlos Guzm�n �lvarez <carlosga@telefonica.net>
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls.Handshake.Client / TlsClientHello.cs
1 /* Transport Security Layer (TLS)\r
2  * Copyright (c) 2003 Carlos Guzmán Álvarez\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.Security.Cryptography;\r
27 \r
28 namespace Mono.Security.Protocol.Tls.Handshake.Client\r
29 {\r
30         internal class TlsClientHello : TlsHandshakeMessage\r
31         {\r
32                 #region FIELDS\r
33 \r
34                 private byte[] random;\r
35 \r
36                 #endregion\r
37 \r
38                 #region CONSTRUCTORS\r
39 \r
40                 public TlsClientHello(TlsSession session) \r
41                         : base(session, TlsHandshakeType.ClientHello, TlsContentType.Handshake)\r
42                 {\r
43                 }\r
44 \r
45                 #endregion\r
46 \r
47                 #region METHODS\r
48 \r
49                 public override void UpdateSession()\r
50                 {\r
51                         base.UpdateSession();\r
52 \r
53                         Session.Context.ClientRandom = random;\r
54 \r
55                         random = null;\r
56                 }\r
57 \r
58                 #endregion\r
59 \r
60                 #region PROTECTED_METHODS\r
61 \r
62                 protected override void ProcessAsSsl3()\r
63                 {\r
64                         this.ProcessAsTls1();\r
65                 }\r
66 \r
67                 protected override void ProcessAsTls1()\r
68                 {\r
69                         // Client Version\r
70                         this.Write((short)this.Session.Context.Protocol);\r
71                                                                 \r
72                         // Random bytes - Unix time + Radom bytes [28]\r
73                         TlsStream clientRandom = new TlsStream();\r
74                         clientRandom.Write(this.Session.Context.GetUnixTime());\r
75                         clientRandom.Write(this.Session.Context.GetSecureRandomBytes(28));\r
76                         this.random = clientRandom.ToArray();\r
77                         clientRandom.Reset();\r
78 \r
79                         this.Write(this.random);\r
80 \r
81                         // Session id\r
82                         // Send the session ID empty\r
83                         if (this.Session.SessionId != null)\r
84                         {\r
85                                 this.Write((byte)this.Session.SessionId.Length);\r
86                                 if (this.Session.SessionId.Length > 0)\r
87                                 {\r
88                                         this.Write(this.Session.SessionId);\r
89                                 }\r
90                         }\r
91                         else\r
92                         {\r
93                                 this.Write((byte)0);\r
94                         }\r
95                         \r
96                         // Write length of Cipher suites                        \r
97                         this.Write((short)(this.Session.Context.SupportedCiphers.Count*2));\r
98 \r
99                         // Write Supported Cipher suites\r
100                         for (int i = 0; i < this.Session.Context.SupportedCiphers.Count; i++)\r
101                         {\r
102                                 this.Write((short)this.Session.Context.SupportedCiphers[i].Code);\r
103                         }\r
104 \r
105                         // Compression methods length\r
106                         this.Write((byte)1);\r
107                         \r
108                         // Compression methods ( 0 = none )\r
109                         this.Write((byte)this.Session.Context.CompressionMethod);\r
110                 }\r
111 \r
112                 #endregion\r
113         }\r
114 }