		private HandshakeMessage createClientHandshakeMessage(
			HandshakeType type, byte[] buffer)
		{
			var last = context.LastHandshakeMsg;
			switch (type)
			{
				case HandshakeType.ClientHello:
					return new TlsClientHello(this.context, buffer);

				case HandshakeType.Certificate:
					if (last != HandshakeType.ClientHello)
						break;
					cert = new TlsClientCertificate(this.context, buffer);
					return cert;

				case HandshakeType.ClientKeyExchange:
					if (last == HandshakeType.ClientHello || last == HandshakeType.Certificate)
						return new TlsClientKeyExchange(this.context, buffer);
					break;

				case HandshakeType.CertificateVerify:
					if (last == HandshakeType.ClientKeyExchange && cert != null)
						return new TlsClientCertificateVerify(this.context, buffer);
					break;

				case HandshakeType.Finished:
					// Certificates are optional, but if provided, they should send a CertificateVerify
					bool check = (cert == null) ? (last == HandshakeType.ClientKeyExchange) : (last == HandshakeType.CertificateVerify);
					// ChangeCipherSpecDone is not an handshake message (it's a content type) but still needs to be happens before finished
					if (check && context.ChangeCipherSpecDone) {
						context.ChangeCipherSpecDone = false;
						return new TlsClientFinished(this.context, buffer);
					}
					break;
					
				default:
					throw new TlsException(AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture,
														 "Unknown server handshake message received ({0})", 
														 type.ToString()));
					break;
			}
			throw new TlsException (AlertDescription.HandshakeFailiure, String.Format ("Protocol error, unexpected protocol transition from {0} to {1}", last, type));
		}
The software does not validate, or incorrectly validates, a certificate.