1 // Transport Security Layer (TLS)
2 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
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.
26 using System.Globalization;
29 using Mono.Security.Protocol.Tls.Handshake;
30 using Mono.Security.Protocol.Tls.Handshake.Client;
32 namespace Mono.Security.Protocol.Tls
34 internal class ClientRecordProtocol : RecordProtocol
38 public ClientRecordProtocol(
40 ClientContext context) : base(innerStream, context)
48 public override HandshakeMessage GetMessage(HandshakeType type)
50 HandshakeMessage msg = this.createClientHandshakeMessage(type);
57 #region Handshake Processing Methods
59 protected override void ProcessHandshakeMessage(TlsStream handMsg)
61 HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte();
62 HandshakeMessage message = null;
64 DebugHelper.WriteLine(">>>> Processing Handshake record ({0})", handshakeType);
66 // Read message length
67 int length = handMsg.ReadInt24();
73 data = new byte[length];
74 handMsg.Read (data, 0, length);
77 // Create and process the server message
78 message = this.createServerHandshakeMessage(handshakeType, data);
84 // Update the last handshake message
85 this.Context.LastHandshakeMsg = handshakeType;
91 this.Context.HandshakeMessages.WriteByte ((byte) handshakeType);
92 this.Context.HandshakeMessages.WriteInt24 (length);
95 this.Context.HandshakeMessages.Write (data, 0, data.Length);
102 #region Client Handshake Message Factories
104 private HandshakeMessage createClientHandshakeMessage(HandshakeType type)
108 case HandshakeType.ClientHello:
109 return new TlsClientHello(this.context);
111 case HandshakeType.Certificate:
112 return new TlsClientCertificate(this.context);
114 case HandshakeType.ClientKeyExchange:
115 return new TlsClientKeyExchange(this.context);
117 case HandshakeType.CertificateVerify:
118 return new TlsClientCertificateVerify(this.context);
120 case HandshakeType.Finished:
121 return new TlsClientFinished(this.context);
124 throw new InvalidOperationException("Unknown client handshake message type: " + type.ToString() );
128 private HandshakeMessage createServerHandshakeMessage(
129 HandshakeType type, byte[] buffer)
131 ClientContext context = (ClientContext)this.context;
135 case HandshakeType.HelloRequest:
136 if (context.HandshakeState != HandshakeState.Started)
138 context.HandshakeState = HandshakeState.None;
139 // re-negotiation will occur at next read/write
140 // (i.e. not during an existing encode/decode op)
146 AlertDescription.NoRenegotiation);
150 case HandshakeType.ServerHello:
151 return new TlsServerHello(this.context, buffer);
153 case HandshakeType.Certificate:
154 return new TlsServerCertificate(this.context, buffer);
156 case HandshakeType.ServerKeyExchange:
157 return new TlsServerKeyExchange(this.context, buffer);
159 case HandshakeType.CertificateRequest:
160 return new TlsServerCertificateRequest(this.context, buffer);
162 case HandshakeType.ServerHelloDone:
163 return new TlsServerHelloDone(this.context, buffer);
165 case HandshakeType.Finished:
166 return new TlsServerFinished(this.context, buffer);
169 throw new TlsException(
170 AlertDescription.UnexpectedMessage,
171 String.Format(CultureInfo.CurrentUICulture,
172 "Unknown server handshake message received ({0})",