protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream buf = new MemoryStream(data); switch (type) { case HandshakeType.client_hello: { switch (this.mConnectionState) { case CS_START: { ReceiveClientHelloMessage(buf); this.mConnectionState = CS_CLIENT_HELLO; SendServerHelloMessage(); this.mConnectionState = CS_SERVER_HELLO; mRecordStream.NotifyHelloComplete(); IList serverSupplementalData = mTlsServer.GetServerSupplementalData(); if (serverSupplementalData != null) { SendSupplementalDataMessage(serverSupplementalData); } this.mConnectionState = CS_SERVER_SUPPLEMENTAL_DATA; this.mKeyExchange = mTlsServer.GetKeyExchange(); this.mKeyExchange.Init(Context); this.mServerCredentials = mTlsServer.GetCredentials(); Certificate serverCertificate = null; if (this.mServerCredentials == null) { this.mKeyExchange.SkipServerCredentials(); } else { this.mKeyExchange.ProcessServerCredentials(this.mServerCredentials); serverCertificate = this.mServerCredentials.Certificate; SendCertificateMessage(serverCertificate); } this.mConnectionState = CS_SERVER_CERTIFICATE; // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { this.mAllowCertificateStatus = false; } if (this.mAllowCertificateStatus) { CertificateStatus certificateStatus = mTlsServer.GetCertificateStatus(); if (certificateStatus != null) { SendCertificateStatusMessage(certificateStatus); } } this.mConnectionState = CS_CERTIFICATE_STATUS; byte[] serverKeyExchange = this.mKeyExchange.GenerateServerKeyExchange(); if (serverKeyExchange != null) { SendServerKeyExchangeMessage(serverKeyExchange); } this.mConnectionState = CS_SERVER_KEY_EXCHANGE; if (this.mServerCredentials != null) { this.mCertificateRequest = mTlsServer.GetCertificateRequest(); if (this.mCertificateRequest != null) { this.mKeyExchange.ValidateCertificateRequest(mCertificateRequest); SendCertificateRequestMessage(mCertificateRequest); TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms); } } this.mConnectionState = CS_CERTIFICATE_REQUEST; SendServerHelloDoneMessage(); this.mConnectionState = CS_SERVER_HELLO_DONE; this.mRecordStream.HandshakeHash.SealHashAlgorithms(); break; } case CS_END: { RefuseRenegotiation(); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.supplemental_data: { switch (this.mConnectionState) { case CS_SERVER_HELLO_DONE: { mTlsServer.ProcessClientSupplementalData(ReadSupplementalDataMessage(buf)); this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.certificate: { switch (this.mConnectionState) { case CS_SERVER_HELLO_DONE: case CS_CLIENT_SUPPLEMENTAL_DATA: { if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) { mTlsServer.ProcessClientSupplementalData(null); } if (this.mCertificateRequest == null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ReceiveCertificateMessage(buf); this.mConnectionState = CS_CLIENT_CERTIFICATE; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.client_key_exchange: { switch (this.mConnectionState) { case CS_SERVER_HELLO_DONE: case CS_CLIENT_SUPPLEMENTAL_DATA: case CS_CLIENT_CERTIFICATE: { if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) { mTlsServer.ProcessClientSupplementalData(null); } if (mConnectionState < CS_CLIENT_CERTIFICATE) { if (this.mCertificateRequest == null) { this.mKeyExchange.SkipClientCredentials(); } else { if (TlsUtilities.IsTlsV12(Context)) { /* * RFC 5246 If no suitable certificate is available, the client MUST Send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } else if (TlsUtilities.IsSsl(Context)) { if (this.mPeerCertificate == null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } else { NotifyClientCertificate(Certificate.EmptyChain); } } } ReceiveClientKeyExchangeMessage(buf); this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.certificate_verify: { switch (this.mConnectionState) { case CS_CLIENT_KEY_EXCHANGE: { /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has * signing capability (i.e., all certificates except those containing fixed * Diffie-Hellman parameters). */ if (!ExpectCertificateVerifyMessage()) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ReceiveCertificateVerifyMessage(buf); this.mConnectionState = CS_CERTIFICATE_VERIFY; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.finished: { switch (this.mConnectionState) { case CS_CLIENT_KEY_EXCHANGE: case CS_CERTIFICATE_VERIFY: { if (mConnectionState < CS_CERTIFICATE_VERIFY && ExpectCertificateVerifyMessage()) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ProcessFinishedMessage(buf); this.mConnectionState = CS_CLIENT_FINISHED; if (this.mExpectSessionTicket) { SendNewSessionTicketMessage(mTlsServer.GetNewSessionTicket()); SendChangeCipherSpecMessage(); } this.mConnectionState = CS_SERVER_SESSION_TICKET; SendFinishedMessage(); this.mConnectionState = CS_SERVER_FINISHED; this.mConnectionState = CS_END; CompleteHandshake(); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.hello_request: case HandshakeType.hello_verify_request: case HandshakeType.server_hello: case HandshakeType.server_key_exchange: case HandshakeType.certificate_request: case HandshakeType.server_hello_done: case HandshakeType.session_ticket: default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } }
protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream memoryStream = new MemoryStream(data); switch (type) { case 1: switch (base.mConnectionState) { case 0: { ReceiveClientHelloMessage(memoryStream); base.mConnectionState = 1; SendServerHelloMessage(); base.mConnectionState = 2; mRecordStream.NotifyHelloComplete(); IList serverSupplementalData = mTlsServer.GetServerSupplementalData(); if (serverSupplementalData != null) { SendSupplementalDataMessage(serverSupplementalData); } base.mConnectionState = 3; mKeyExchange = mTlsServer.GetKeyExchange(); mKeyExchange.Init(Context); mServerCredentials = mTlsServer.GetCredentials(); Certificate certificate = null; if (mServerCredentials == null) { mKeyExchange.SkipServerCredentials(); } else { mKeyExchange.ProcessServerCredentials(mServerCredentials); certificate = mServerCredentials.Certificate; SendCertificateMessage(certificate); } base.mConnectionState = 4; if (certificate == null || certificate.IsEmpty) { mAllowCertificateStatus = false; } if (mAllowCertificateStatus) { CertificateStatus certificateStatus = mTlsServer.GetCertificateStatus(); if (certificateStatus != null) { SendCertificateStatusMessage(certificateStatus); } } base.mConnectionState = 5; byte[] array = mKeyExchange.GenerateServerKeyExchange(); if (array != null) { SendServerKeyExchangeMessage(array); } base.mConnectionState = 6; if (mServerCredentials != null) { mCertificateRequest = mTlsServer.GetCertificateRequest(); if (mCertificateRequest != null) { if (TlsUtilities.IsTlsV12(Context) != (mCertificateRequest.SupportedSignatureAlgorithms != null)) { throw new TlsFatalAlert(80); } mKeyExchange.ValidateCertificateRequest(mCertificateRequest); SendCertificateRequestMessage(mCertificateRequest); TlsUtilities.TrackHashAlgorithms(mRecordStream.HandshakeHash, mCertificateRequest.SupportedSignatureAlgorithms); } } base.mConnectionState = 7; SendServerHelloDoneMessage(); base.mConnectionState = 8; mRecordStream.HandshakeHash.SealHashAlgorithms(); break; } case 16: RefuseRenegotiation(); break; default: throw new TlsFatalAlert(10); } break; case 23: { short mConnectionState = base.mConnectionState; if (mConnectionState == 8) { mTlsServer.ProcessClientSupplementalData(TlsProtocol.ReadSupplementalDataMessage(memoryStream)); base.mConnectionState = 9; break; } throw new TlsFatalAlert(10); } case 11: switch (base.mConnectionState) { case 8: case 9: if (base.mConnectionState < 9) { mTlsServer.ProcessClientSupplementalData(null); } if (mCertificateRequest == null) { throw new TlsFatalAlert(10); } ReceiveCertificateMessage(memoryStream); base.mConnectionState = 10; break; default: throw new TlsFatalAlert(10); } break; case 16: switch (base.mConnectionState) { case 8: case 9: case 10: if (base.mConnectionState < 9) { mTlsServer.ProcessClientSupplementalData(null); } if (base.mConnectionState < 10) { if (mCertificateRequest == null) { mKeyExchange.SkipClientCredentials(); } else { if (TlsUtilities.IsTlsV12(Context)) { throw new TlsFatalAlert(10); } if (TlsUtilities.IsSsl(Context)) { if (mPeerCertificate == null) { throw new TlsFatalAlert(10); } } else { NotifyClientCertificate(Certificate.EmptyChain); } } } ReceiveClientKeyExchangeMessage(memoryStream); base.mConnectionState = 11; break; default: throw new TlsFatalAlert(10); } break; case 15: { short mConnectionState = base.mConnectionState; if (mConnectionState == 11) { if (!ExpectCertificateVerifyMessage()) { throw new TlsFatalAlert(10); } ReceiveCertificateVerifyMessage(memoryStream); base.mConnectionState = 12; break; } throw new TlsFatalAlert(10); } case 20: switch (base.mConnectionState) { case 11: case 12: if (base.mConnectionState < 12 && ExpectCertificateVerifyMessage()) { throw new TlsFatalAlert(10); } ProcessFinishedMessage(memoryStream); base.mConnectionState = 13; if (mExpectSessionTicket) { SendNewSessionTicketMessage(mTlsServer.GetNewSessionTicket()); SendChangeCipherSpecMessage(); } base.mConnectionState = 14; SendFinishedMessage(); base.mConnectionState = 15; base.mConnectionState = 16; CompleteHandshake(); break; default: throw new TlsFatalAlert(10); } break; default: throw new TlsFatalAlert(10); } }