Check platform without using #define
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / ServerRecordProtocol.cs
1 // Transport Security Layer (TLS)
2 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
3
4 //
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:
12 // 
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 // 
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.
23 //
24
25 using System;
26 using System.Globalization;
27 using System.IO;
28
29 using Mono.Security.Protocol.Tls.Handshake;
30 using Mono.Security.Protocol.Tls.Handshake.Server;
31
32 namespace Mono.Security.Protocol.Tls
33 {
34         internal class ServerRecordProtocol : RecordProtocol
35         {
36                 #region Constructors
37
38                 public ServerRecordProtocol(
39                         Stream                  innerStream, 
40                         ServerContext   context) : base(innerStream, context)
41                 {
42                 }
43
44                 #endregion
45
46                 #region Send Messages
47
48                 public override void SendRecord(HandshakeType type)
49                 {
50                         // Create the record message
51                         HandshakeMessage msg = this.createServerHandshakeMessage(type);
52                         msg.Process();
53                         
54                         // Write record
55                         this.SendRecord(msg.ContentType, msg.EncodeMessage());
56
57                         // Update session
58                         msg.Update();
59
60                         // Reset message contents
61                         msg.Reset();
62                 }
63
64                 #endregion
65
66                 #region Handshake Processing Methods
67
68                 protected override void ProcessChangeCipherSpec()
69                 {
70                         // Reset sequence numbers
71                         this.context.ReadSequenceNumber = 0;
72
73                         // Make the pending state to be the current state
74                         this.context.IsActual = true;
75                 }
76
77                 protected override void ProcessHandshakeMessage(TlsStream handMsg)
78                 {
79                         HandshakeType           handshakeType   = (HandshakeType)handMsg.ReadByte();
80                         HandshakeMessage        message                 = null;
81
82                         // Read message length
83                         int length = handMsg.ReadInt24();
84
85                         // Read message data
86                         byte[] data = new byte[length];
87                         handMsg.Read(data, 0, length);
88
89                         // Create and process the server message
90                         message = this.createClientHandshakeMessage(handshakeType, data);
91                         message.Process();
92
93                         // Update the last handshake message
94                         this.Context.LastHandshakeMsg = handshakeType;
95
96                         // Update session
97                         if (message != null)
98                         {
99                                 message.Update();
100                         }
101                 }
102
103                 #endregion
104
105                 #region Server Handshake Message Factories
106
107                 private HandshakeMessage createClientHandshakeMessage(
108                         HandshakeType type, byte[] buffer)
109                 {
110                         switch (type)
111                         {
112                                 case HandshakeType.ClientHello:
113                                         return new TlsClientHello(this.context, buffer);
114
115                                 case HandshakeType.Certificate:
116                                         return new TlsClientCertificate(this.context, buffer);
117
118                                 case HandshakeType.ClientKeyExchange:
119                                         return new TlsClientKeyExchange(this.context, buffer);
120
121                                 case HandshakeType.CertificateVerify:
122                                         return new TlsClientCertificateVerify(this.context, buffer);
123
124                                 case HandshakeType.Finished:
125                                         return new TlsClientFinished(this.context, buffer);
126
127                                 default:
128                                         throw new TlsException(
129                                                 AlertDescription.UnexpectedMessage,
130                                                 String.Format(CultureInfo.CurrentUICulture,
131                                                         "Unknown server handshake message received ({0})", 
132                                                         type.ToString()));
133                         }
134                 }
135
136                 private HandshakeMessage createServerHandshakeMessage(
137                         HandshakeType type)
138                 {
139                         switch (type)
140                         {
141                                 case HandshakeType.HelloRequest:
142                                         this.SendRecord(HandshakeType.ClientHello);
143                                         return null;
144
145                                 case HandshakeType.ServerHello:
146                                         return new TlsServerHello(this.context);
147
148                                 case HandshakeType.Certificate:
149                                         return new TlsServerCertificate(this.context);
150
151                                 case HandshakeType.ServerKeyExchange:
152                                         return new TlsServerKeyExchange(this.context);
153
154                                 case HandshakeType.CertificateRequest:
155                                         return new TlsServerCertificateRequest(this.context);
156
157                                 case HandshakeType.ServerHelloDone:
158                                         return new TlsServerHelloDone(this.context);
159
160                                 case HandshakeType.Finished:
161                                         return new TlsServerFinished(this.context);
162
163                                 default:
164                                         throw new InvalidOperationException("Unknown server handshake message type: " + type.ToString() );                                      
165                         }
166                 }
167
168                 #endregion
169         }
170 }