1 /* Transport Security Layer (TLS)
2 * Copyright (c) 2003-2004 Carlos Guzman Alvarez
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:
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
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.
28 using Mono.Security.Protocol.Tls.Handshake;
29 using Mono.Security.Protocol.Tls.Handshake.Client;
31 namespace Mono.Security.Protocol.Tls
33 internal class ClientRecordProtocol : RecordProtocol
37 public ClientRecordProtocol(
39 ClientContext context) : base(innerStream, context)
47 public override void SendRecord(HandshakeType type)
49 // Create the record message
50 HandshakeMessage msg = this.createClientHandshakeMessage(type);
53 this.SendRecord(msg.ContentType, msg.EncodeMessage());
58 // Reset message contents
64 #region Handshake Processing Methods
66 protected override void ProcessChangeCipherSpec()
68 // Reset sequence numbers
69 this.context.ReadSequenceNumber = 0;
72 protected override void ProcessHandshakeMessage(TlsStream handMsg)
74 HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte();
75 HandshakeMessage message = null;
77 // Read message length
78 int length = handMsg.ReadInt24();
81 byte[] data = new byte[length];
82 handMsg.Read(data, 0, length);
84 // Create and process the server message
85 message = this.createServerHandshakeMessage(handshakeType, data);
87 // Update the last handshake message
88 this.Context.LastHandshakeMsg = handshakeType;
99 #region Client Handshake Message Factories
101 private HandshakeMessage createClientHandshakeMessage(
106 case HandshakeType.ClientHello:
107 return new TlsClientHello(this.context);
109 case HandshakeType.Certificate:
110 return new TlsClientCertificate(this.context);
112 case HandshakeType.ClientKeyExchange:
113 return new TlsClientKeyExchange(this.context);
115 case HandshakeType.CertificateVerify:
116 return new TlsClientCertificateVerify(this.context);
118 case HandshakeType.Finished:
119 return new TlsClientFinished(this.context);
122 throw new InvalidOperationException("Unknown client handshake message type: " + type.ToString() );
126 private HandshakeMessage createServerHandshakeMessage(
127 HandshakeType type, byte[] buffer)
129 ClientContext context = (ClientContext)this.context;
133 case HandshakeType.HelloRequest:
134 if (context.HandshakeState != HandshakeState.Started)
136 context.SslStream.NegotiateHandshake();
142 AlertDescription.NoRenegotiation);
146 case HandshakeType.ServerHello:
147 return new TlsServerHello(this.context, buffer);
149 case HandshakeType.Certificate:
150 return new TlsServerCertificate(this.context, buffer);
152 case HandshakeType.ServerKeyExchange:
153 return new TlsServerKeyExchange(this.context, buffer);
155 case HandshakeType.CertificateRequest:
156 return new TlsServerCertificateRequest(this.context, buffer);
158 case HandshakeType.ServerHelloDone:
159 return new TlsServerHelloDone(this.context, buffer);
161 case HandshakeType.Finished:
162 return new TlsServerFinished(this.context, buffer);
165 throw this.context.CreateException("Unknown server handshake message received ({0})", type.ToString());