GetCurrentPrfHash() protected static method

protected static GetCurrentPrfHash ( TlsContext context, TlsHandshakeHash handshakeHash, byte sslSender ) : byte[]
context TlsContext
handshakeHash TlsHandshakeHash
sslSender byte
return byte[]
示例#1
0
        protected virtual byte[] CreateVerifyData(bool isServer)
        {
            TlsContext context    = this.Context;
            string     asciiLabel = isServer ? "server finished" : "client finished";

            byte[] sslSender      = isServer ? TlsUtilities.SSL_SERVER : TlsUtilities.SSL_CLIENT;
            byte[] currentPrfHash = TlsProtocol.GetCurrentPrfHash(context, this.mRecordStream.HandshakeHash, sslSender);
            return(TlsUtilities.CalculateVerifyData(context, asciiLabel, currentPrfHash));
        }
示例#2
0
 protected virtual void ReceiveClientKeyExchangeMessage(MemoryStream buf)
 {
     this.mKeyExchange.ProcessClientKeyExchange(buf);
     TlsProtocol.AssertEmpty(buf);
     this.mPrepareFinishHash = this.mRecordStream.PrepareToFinish();
     this.mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(this.Context, this.mPrepareFinishHash, null);
     TlsProtocol.EstablishMasterSecret(this.Context, this.mKeyExchange);
     this.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher());
     if (!this.mExpectSessionTicket)
     {
         this.SendChangeCipherSpecMessage();
     }
 }
        protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf)
        {
            DigitallySigned clientCertificateVerify = DigitallySigned.Parse(Context, buf);

            AssertEmpty(buf);

            // Verify the CertificateVerify message contains a correct signature.
            try
            {
                byte[] certificateVerifyHash;
                if (TlsUtilities.IsTlsV12(Context))
                {
                    certificateVerifyHash = mPrepareFinishHash.GetFinalHash(clientCertificateVerify.Algorithm.Hash);
                }
                else
                {
                    certificateVerifyHash = TlsProtocol.GetCurrentPrfHash(Context, mPrepareFinishHash, null);
                }

                X509CertificateStructure x509Cert  = mPeerCertificate.GetCertificateAt(0);
                SubjectPublicKeyInfo     keyInfo   = x509Cert.SubjectPublicKeyInfo;
                AsymmetricKeyParameter   publicKey = PublicKeyFactory.CreateKey(keyInfo);

                TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)mClientCertificateType);
                tlsSigner.Init(Context);
                if (!tlsSigner.VerifyRawSignature(clientCertificateVerify.Algorithm,
                                                  clientCertificateVerify.Signature, publicKey, certificateVerifyHash))
                {
                    throw new TlsFatalAlert(AlertDescription.decrypt_error);
                }
            }
            catch (Exception e)
            {
                throw new TlsFatalAlert(AlertDescription.decrypt_error, e);
            }
        }
示例#4
0
        internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer)
        {
            SecurityParameters    securityParameters = state.clientContext.SecurityParameters;
            DtlsReliableHandshake handshake          = new DtlsReliableHandshake(state.clientContext, recordLayer);

            byte[] clientHelloBody = GenerateClientHello(state, state.client);
            handshake.SendMessage(HandshakeType.client_hello, clientHelloBody);

            DtlsReliableHandshake.Message serverMessage = handshake.ReceiveMessage();

            while (serverMessage.Type == HandshakeType.hello_verify_request)
            {
                ProtocolVersion recordLayerVersion = recordLayer.ResetDiscoveredPeerVersion();
                ProtocolVersion client_version     = state.clientContext.ClientVersion;

                /*
                 * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of
                 * the version of TLS that is expected to be negotiated. DTLS 1.2 and 1.0 clients MUST use
                 * the version solely to indicate packet formatting (which is the same in both DTLS 1.2 and
                 * 1.0) and not as part of version negotiation.
                 */
                if (!recordLayerVersion.IsEqualOrEarlierVersionOf(client_version))
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                byte[] cookie  = ProcessHelloVerifyRequest(state, serverMessage.Body);
                byte[] patched = PatchClientHelloWithCookie(clientHelloBody, cookie);

                handshake.ResetHandshakeMessagesDigest();
                handshake.SendMessage(HandshakeType.client_hello, patched);

                serverMessage = handshake.ReceiveMessage();
            }

            if (serverMessage.Type == HandshakeType.server_hello)
            {
                ReportServerVersion(state, recordLayer.DiscoveredPeerVersion);

                ProcessServerHello(state, serverMessage.Body);
            }
            else
            {
                throw new TlsFatalAlert(AlertDescription.unexpected_message);
            }

            if (state.maxFragmentLength >= 0)
            {
                int plainTextLimit = 1 << (8 + state.maxFragmentLength);
                recordLayer.SetPlaintextLimit(plainTextLimit);
            }

            securityParameters.cipherSuite          = state.selectedCipherSuite;
            securityParameters.compressionAlgorithm = (byte)state.selectedCompressionMethod;
            securityParameters.prfAlgorithm         = TlsProtocol.GetPrfAlgorithm(state.clientContext, state.selectedCipherSuite);

            /*
             * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has
             * a verify_data_length equal to 12. This includes all existing cipher suites.
             */
            securityParameters.verifyDataLength = 12;

            handshake.NotifyHelloComplete();

            bool resumedSession = state.selectedSessionID.Length > 0 && state.tlsSession != null &&
                                  Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID);

            if (resumedSession)
            {
                if (securityParameters.CipherSuite != state.sessionParameters.CipherSuite ||
                    securityParameters.CompressionAlgorithm != state.sessionParameters.CompressionAlgorithm)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                IDictionary sessionServerExtensions = state.sessionParameters.ReadServerExtensions();

                securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions);

                securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret);
                recordLayer.InitPendingEpoch(state.client.GetCipher());

                // NOTE: Calculated exclusive of the actual Finished message from the server
                byte[] resExpectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished,
                                                                                      TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null));
                ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), resExpectedServerVerifyData);

                // NOTE: Calculated exclusive of the Finished message itself
                byte[] resClientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished,
                                                                              TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null));
                handshake.SendMessage(HandshakeType.finished, resClientVerifyData);

                handshake.Finish();

                state.clientContext.SetResumableSession(state.tlsSession);

                state.client.NotifyHandshakeComplete();

                return(new DtlsTransport(recordLayer));
            }

            InvalidateSession(state);

            if (state.selectedSessionID.Length > 0)
            {
                state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null);
            }

            serverMessage = handshake.ReceiveMessage();

            if (serverMessage.Type == HandshakeType.supplemental_data)
            {
                ProcessServerSupplementalData(state, serverMessage.Body);
                serverMessage = handshake.ReceiveMessage();
            }
            else
            {
                state.client.ProcessServerSupplementalData(null);
            }

            state.keyExchange = state.client.GetKeyExchange();
            state.keyExchange.Init(state.clientContext);

            Certificate serverCertificate = null;

            if (serverMessage.Type == HandshakeType.certificate)
            {
                serverCertificate = ProcessServerCertificate(state, serverMessage.Body);
                serverMessage     = handshake.ReceiveMessage();
            }
            else
            {
                // Okay, Certificate is optional
                state.keyExchange.SkipServerCredentials();
            }

            // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus
            if (serverCertificate == null || serverCertificate.IsEmpty)
            {
                state.allowCertificateStatus = false;
            }

            if (serverMessage.Type == HandshakeType.certificate_status)
            {
                ProcessCertificateStatus(state, serverMessage.Body);
                serverMessage = handshake.ReceiveMessage();
            }
            else
            {
                // Okay, CertificateStatus is optional
            }

            if (serverMessage.Type == HandshakeType.server_key_exchange)
            {
                ProcessServerKeyExchange(state, serverMessage.Body);
                serverMessage = handshake.ReceiveMessage();
            }
            else
            {
                // Okay, ServerKeyExchange is optional
                state.keyExchange.SkipServerKeyExchange();
            }

            if (serverMessage.Type == HandshakeType.certificate_request)
            {
                ProcessCertificateRequest(state, serverMessage.Body);

                /*
                 * TODO Give the client a chance to immediately select the CertificateVerify hash
                 * algorithm here to avoid tracking the other hash algorithms unnecessarily?
                 */
                TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash,
                                                 state.certificateRequest.SupportedSignatureAlgorithms);

                serverMessage = handshake.ReceiveMessage();
            }
            else
            {
                // Okay, CertificateRequest is optional
            }

            if (serverMessage.Type == HandshakeType.server_hello_done)
            {
                if (serverMessage.Body.Length != 0)
                {
                    throw new TlsFatalAlert(AlertDescription.decode_error);
                }
            }
            else
            {
                throw new TlsFatalAlert(AlertDescription.unexpected_message);
            }

            handshake.HandshakeHash.SealHashAlgorithms();

            IList clientSupplementalData = state.client.GetClientSupplementalData();

            if (clientSupplementalData != null)
            {
                byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData);
                handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody);
            }

            if (state.certificateRequest != null)
            {
                state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest);

                /*
                 * 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.
                 */
                Certificate clientCertificate = null;
                if (state.clientCredentials != null)
                {
                    clientCertificate = state.clientCredentials.Certificate;
                }
                if (clientCertificate == null)
                {
                    clientCertificate = Certificate.EmptyChain;
                }

                byte[] certificateBody = GenerateCertificate(clientCertificate);
                handshake.SendMessage(HandshakeType.certificate, certificateBody);
            }

            if (state.clientCredentials != null)
            {
                state.keyExchange.ProcessClientCredentials(state.clientCredentials);
            }
            else
            {
                state.keyExchange.SkipClientCredentials();
            }

            byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state);
            handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody);

            TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish();

            securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, prepareFinishHash, null);

            TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange);
            recordLayer.InitPendingEpoch(state.client.GetCipher());

            if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials)
            {
                TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials;

                /*
                 * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2
                 */
                SignatureAndHashAlgorithm signatureAndHashAlgorithm;
                byte[] hash;

                if (TlsUtilities.IsTlsV12(state.clientContext))
                {
                    signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm;
                    if (signatureAndHashAlgorithm == null)
                    {
                        throw new TlsFatalAlert(AlertDescription.internal_error);
                    }

                    hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
                }
                else
                {
                    signatureAndHashAlgorithm = null;
                    hash = securityParameters.SessionHash;
                }

                byte[]          signature             = signerCredentials.GenerateCertificateSignature(hash);
                DigitallySigned certificateVerify     = new DigitallySigned(signatureAndHashAlgorithm, signature);
                byte[]          certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify);
                handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody);
            }

            // NOTE: Calculated exclusive of the Finished message itself
            byte[] clientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished,
                                                                       TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null));
            handshake.SendMessage(HandshakeType.finished, clientVerifyData);

            if (state.expectSessionTicket)
            {
                serverMessage = handshake.ReceiveMessage();
                if (serverMessage.Type == HandshakeType.session_ticket)
                {
                    ProcessNewSessionTicket(state, serverMessage.Body);
                }
                else
                {
                    throw new TlsFatalAlert(AlertDescription.unexpected_message);
                }
            }

            // NOTE: Calculated exclusive of the actual Finished message from the server
            byte[] expectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished,
                                                                               TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null));
            ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedServerVerifyData);

            handshake.Finish();

            if (state.tlsSession != null)
            {
                state.sessionParameters = new SessionParameters.Builder()
                                          .SetCipherSuite(securityParameters.cipherSuite)
                                          .SetCompressionAlgorithm(securityParameters.compressionAlgorithm)
                                          .SetMasterSecret(securityParameters.masterSecret)
                                          .SetPeerCertificate(serverCertificate)
                                          .SetPskIdentity(securityParameters.pskIdentity)
                                          .Build();

                state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters);

                state.clientContext.SetResumableSession(state.tlsSession);
            }

            state.client.NotifyHandshakeComplete();

            return(new DtlsTransport(recordLayer));
        }
示例#5
0
        internal virtual DtlsTransport ServerHandshake(DtlsServerProtocol.ServerHandshakeState state, DtlsRecordLayer recordLayer)
        {
            SecurityParameters    securityParameters    = state.serverContext.SecurityParameters;
            DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.serverContext, recordLayer);

            DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage();
            ProtocolVersion discoveredPeerVersion = recordLayer.DiscoveredPeerVersion;

            state.serverContext.SetClientVersion(discoveredPeerVersion);
            if (message.Type != 1)
            {
                throw new TlsFatalAlert(10);
            }
            this.ProcessClientHello(state, message.Body);
            byte[] body = this.GenerateServerHello(state);
            DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);
            dtlsReliableHandshake.SendMessage(2, body);
            dtlsReliableHandshake.NotifyHelloComplete();
            IList serverSupplementalData = state.server.GetServerSupplementalData();

            if (serverSupplementalData != null)
            {
                byte[] body2 = DtlsProtocol.GenerateSupplementalData(serverSupplementalData);
                dtlsReliableHandshake.SendMessage(23, body2);
            }
            state.keyExchange = state.server.GetKeyExchange();
            state.keyExchange.Init(state.serverContext);
            state.serverCredentials = state.server.GetCredentials();
            Certificate certificate = null;

            if (state.serverCredentials == null)
            {
                state.keyExchange.SkipServerCredentials();
            }
            else
            {
                state.keyExchange.ProcessServerCredentials(state.serverCredentials);
                certificate = state.serverCredentials.Certificate;
                byte[] body3 = DtlsProtocol.GenerateCertificate(certificate);
                dtlsReliableHandshake.SendMessage(11, body3);
            }
            if (certificate == null || certificate.IsEmpty)
            {
                state.allowCertificateStatus = false;
            }
            if (state.allowCertificateStatus)
            {
                CertificateStatus certificateStatus = state.server.GetCertificateStatus();
                if (certificateStatus != null)
                {
                    byte[] body4 = this.GenerateCertificateStatus(state, certificateStatus);
                    dtlsReliableHandshake.SendMessage(22, body4);
                }
            }
            byte[] array = state.keyExchange.GenerateServerKeyExchange();
            if (array != null)
            {
                dtlsReliableHandshake.SendMessage(12, array);
            }
            if (state.serverCredentials != null)
            {
                state.certificateRequest = state.server.GetCertificateRequest();
                if (state.certificateRequest != null)
                {
                    state.keyExchange.ValidateCertificateRequest(state.certificateRequest);
                    byte[] body5 = this.GenerateCertificateRequest(state, state.certificateRequest);
                    dtlsReliableHandshake.SendMessage(13, body5);
                    TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms);
                }
            }
            dtlsReliableHandshake.SendMessage(14, TlsUtilities.EmptyBytes);
            dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms();
            message = dtlsReliableHandshake.ReceiveMessage();
            if (message.Type == 23)
            {
                this.ProcessClientSupplementalData(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                state.server.ProcessClientSupplementalData(null);
            }
            if (state.certificateRequest == null)
            {
                state.keyExchange.SkipClientCredentials();
            }
            else if (message.Type == 11)
            {
                this.ProcessClientCertificate(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                if (TlsUtilities.IsTlsV12(state.serverContext))
                {
                    throw new TlsFatalAlert(10);
                }
                this.NotifyClientCertificate(state, Certificate.EmptyChain);
            }
            if (message.Type == 16)
            {
                this.ProcessClientKeyExchange(state, message.Body);
                TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish();
                securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, tlsHandshakeHash, null);
                TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange);
                recordLayer.InitPendingEpoch(state.server.GetCipher());
                if (this.ExpectCertificateVerifyMessage(state))
                {
                    byte[] body6 = dtlsReliableHandshake.ReceiveMessageBody(15);
                    this.ProcessCertificateVerify(state, body6, tlsHandshakeHash);
                }
                byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.serverContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null));
                this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data);
                if (state.expectSessionTicket)
                {
                    NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket();
                    byte[]           body7            = this.GenerateNewSessionTicket(state, newSessionTicket);
                    dtlsReliableHandshake.SendMessage(4, body7);
                }
                byte[] body8 = TlsUtilities.CalculateVerifyData(state.serverContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null));
                dtlsReliableHandshake.SendMessage(20, body8);
                dtlsReliableHandshake.Finish();
                state.server.NotifyHandshakeComplete();
                return(new DtlsTransport(recordLayer));
            }
            throw new TlsFatalAlert(10);
        }
        internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer)
        {
            SecurityParameters    securityParameters = state.serverContext.SecurityParameters;
            DtlsReliableHandshake handshake          = new DtlsReliableHandshake(state.serverContext, recordLayer);

            DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage();

            // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this
            //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion;

            if (clientMessage.Type == HandshakeType.client_hello)
            {
                ProcessClientHello(state, clientMessage.Body);
            }
            else
            {
                throw new TlsFatalAlert(AlertDescription.unexpected_message);
            }

            {
                byte[] serverHelloBody = GenerateServerHello(state);

                ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);

                ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion;
                recordLayer.ReadVersion = recordLayerVersion;
                recordLayer.SetWriteVersion(recordLayerVersion);

                handshake.SendMessage(HandshakeType.server_hello, serverHelloBody);
            }

            handshake.NotifyHelloComplete();

            IList serverSupplementalData = state.server.GetServerSupplementalData();

            if (serverSupplementalData != null)
            {
                byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData);
                handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody);
            }

            state.keyExchange = state.server.GetKeyExchange();
            state.keyExchange.Init(state.serverContext);

            state.serverCredentials = state.server.GetCredentials();

            Certificate serverCertificate = null;

            if (state.serverCredentials == null)
            {
                state.keyExchange.SkipServerCredentials();
            }
            else
            {
                state.keyExchange.ProcessServerCredentials(state.serverCredentials);

                serverCertificate = state.serverCredentials.Certificate;
                byte[] certificateBody = GenerateCertificate(serverCertificate);
                handshake.SendMessage(HandshakeType.certificate, certificateBody);
            }

            // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus
            if (serverCertificate == null || serverCertificate.IsEmpty)
            {
                state.allowCertificateStatus = false;
            }

            if (state.allowCertificateStatus)
            {
                CertificateStatus certificateStatus = state.server.GetCertificateStatus();
                if (certificateStatus != null)
                {
                    byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus);
                    handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody);
                }
            }

            byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange();
            if (serverKeyExchange != null)
            {
                handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange);
            }

            if (state.serverCredentials != null)
            {
                state.certificateRequest = state.server.GetCertificateRequest();
                if (state.certificateRequest != null)
                {
                    if (TlsUtilities.IsTlsV12(state.serverContext) != (state.certificateRequest.SupportedSignatureAlgorithms != null))
                    {
                        throw new TlsFatalAlert(AlertDescription.internal_error);
                    }

                    state.keyExchange.ValidateCertificateRequest(state.certificateRequest);

                    byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest);
                    handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody);

                    TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash,
                                                     state.certificateRequest.SupportedSignatureAlgorithms);
                }
            }

            handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes);

            handshake.HandshakeHash.SealHashAlgorithms();

            clientMessage = handshake.ReceiveMessage();

            if (clientMessage.Type == HandshakeType.supplemental_data)
            {
                ProcessClientSupplementalData(state, clientMessage.Body);
                clientMessage = handshake.ReceiveMessage();
            }
            else
            {
                state.server.ProcessClientSupplementalData(null);
            }

            if (state.certificateRequest == null)
            {
                state.keyExchange.SkipClientCredentials();
            }
            else
            {
                if (clientMessage.Type == HandshakeType.certificate)
                {
                    ProcessClientCertificate(state, clientMessage.Body);
                    clientMessage = handshake.ReceiveMessage();
                }
                else
                {
                    if (TlsUtilities.IsTlsV12(state.serverContext))
                    {
                        /*
                         * 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);
                    }

                    NotifyClientCertificate(state, Certificate.EmptyChain);
                }
            }

            if (clientMessage.Type == HandshakeType.client_key_exchange)
            {
                ProcessClientKeyExchange(state, clientMessage.Body);
            }
            else
            {
                throw new TlsFatalAlert(AlertDescription.unexpected_message);
            }

            TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish();

            securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null);

            TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange);
            recordLayer.InitPendingEpoch(state.server.GetCipher());

            /*
             * 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(state))
            {
                byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify);
                ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash);
            }

            // NOTE: Calculated exclusive of the actual Finished message from the client
            byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished,
                                                                               TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null));
            ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData);

            if (state.expectSessionTicket)
            {
                NewSessionTicket newSessionTicket     = state.server.GetNewSessionTicket();
                byte[]           newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket);
                handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody);
            }

            // NOTE: Calculated exclusive of the Finished message itself
            byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished,
                                                                       TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null));
            handshake.SendMessage(HandshakeType.finished, serverVerifyData);

            handshake.Finish();

            state.server.NotifyHandshakeComplete();

            return(new DtlsTransport(recordLayer));
        }
示例#7
0
        internal virtual DtlsTransport ClientHandshake(DtlsClientProtocol.ClientHandshakeState state, DtlsRecordLayer recordLayer)
        {
            SecurityParameters    securityParameters    = state.clientContext.SecurityParameters;
            DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.clientContext, recordLayer);

            byte[] array = this.GenerateClientHello(state, state.client);
            dtlsReliableHandshake.SendMessage(1, array);
            DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage();
            while (message.Type == 3)
            {
                ProtocolVersion protocolVersion = recordLayer.ResetDiscoveredPeerVersion();
                ProtocolVersion clientVersion   = state.clientContext.ClientVersion;
                if (!protocolVersion.IsEqualOrEarlierVersionOf(clientVersion))
                {
                    throw new TlsFatalAlert(47);
                }
                byte[] cookie = this.ProcessHelloVerifyRequest(state, message.Body);
                byte[] body   = DtlsClientProtocol.PatchClientHelloWithCookie(array, cookie);
                dtlsReliableHandshake.ResetHandshakeMessagesDigest();
                dtlsReliableHandshake.SendMessage(1, body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            if (message.Type != 2)
            {
                throw new TlsFatalAlert(10);
            }
            this.ReportServerVersion(state, recordLayer.DiscoveredPeerVersion);
            this.ProcessServerHello(state, message.Body);
            dtlsReliableHandshake.NotifyHelloComplete();
            DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);
            if (state.resumedSession)
            {
                securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret);
                recordLayer.InitPendingEpoch(state.client.GetCipher());
                byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.clientContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
                this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data);
                byte[] body2 = TlsUtilities.CalculateVerifyData(state.clientContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
                dtlsReliableHandshake.SendMessage(20, body2);
                dtlsReliableHandshake.Finish();
                state.clientContext.SetResumableSession(state.tlsSession);
                state.client.NotifyHandshakeComplete();
                return(new DtlsTransport(recordLayer));
            }
            this.InvalidateSession(state);
            if (state.selectedSessionID.Length > 0)
            {
                state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null);
            }
            message = dtlsReliableHandshake.ReceiveMessage();
            if (message.Type == 23)
            {
                this.ProcessServerSupplementalData(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                state.client.ProcessServerSupplementalData(null);
            }
            state.keyExchange = state.client.GetKeyExchange();
            state.keyExchange.Init(state.clientContext);
            Certificate certificate = null;

            if (message.Type == 11)
            {
                certificate = this.ProcessServerCertificate(state, message.Body);
                message     = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                state.keyExchange.SkipServerCredentials();
            }
            if (certificate == null || certificate.IsEmpty)
            {
                state.allowCertificateStatus = false;
            }
            if (message.Type == 22)
            {
                this.ProcessCertificateStatus(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            if (message.Type == 12)
            {
                this.ProcessServerKeyExchange(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                state.keyExchange.SkipServerKeyExchange();
            }
            if (message.Type == 13)
            {
                this.ProcessCertificateRequest(state, message.Body);
                TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            if (message.Type != 14)
            {
                throw new TlsFatalAlert(10);
            }
            if (message.Body.Length != 0)
            {
                throw new TlsFatalAlert(50);
            }
            dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms();
            IList clientSupplementalData = state.client.GetClientSupplementalData();

            if (clientSupplementalData != null)
            {
                byte[] body3 = DtlsProtocol.GenerateSupplementalData(clientSupplementalData);
                dtlsReliableHandshake.SendMessage(23, body3);
            }
            if (state.certificateRequest != null)
            {
                state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest);
                Certificate certificate2 = null;
                if (state.clientCredentials != null)
                {
                    certificate2 = state.clientCredentials.Certificate;
                }
                if (certificate2 == null)
                {
                    certificate2 = Certificate.EmptyChain;
                }
                byte[] body4 = DtlsProtocol.GenerateCertificate(certificate2);
                dtlsReliableHandshake.SendMessage(11, body4);
            }
            if (state.clientCredentials != null)
            {
                state.keyExchange.ProcessClientCredentials(state.clientCredentials);
            }
            else
            {
                state.keyExchange.SkipClientCredentials();
            }
            byte[] body5 = this.GenerateClientKeyExchange(state);
            dtlsReliableHandshake.SendMessage(16, body5);
            TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish();

            securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, tlsHandshakeHash, null);
            TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange);
            recordLayer.InitPendingEpoch(state.client.GetCipher());
            if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials)
            {
                TlsSignerCredentials      tlsSignerCredentials      = (TlsSignerCredentials)state.clientCredentials;
                SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(state.clientContext, tlsSignerCredentials);
                byte[] hash;
                if (signatureAndHashAlgorithm == null)
                {
                    hash = securityParameters.SessionHash;
                }
                else
                {
                    hash = tlsHandshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
                }
                byte[]          signature         = tlsSignerCredentials.GenerateCertificateSignature(hash);
                DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature);
                byte[]          body6             = this.GenerateCertificateVerify(state, certificateVerify);
                dtlsReliableHandshake.SendMessage(15, body6);
            }
            byte[] body7 = TlsUtilities.CalculateVerifyData(state.clientContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
            dtlsReliableHandshake.SendMessage(20, body7);
            if (state.expectSessionTicket)
            {
                message = dtlsReliableHandshake.ReceiveMessage();
                if (message.Type != 4)
                {
                    throw new TlsFatalAlert(10);
                }
                this.ProcessNewSessionTicket(state, message.Body);
            }
            byte[] expected_verify_data2 = TlsUtilities.CalculateVerifyData(state.clientContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null));
            this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data2);
            dtlsReliableHandshake.Finish();
            if (state.tlsSession != null)
            {
                state.sessionParameters = new SessionParameters.Builder().SetCipherSuite(securityParameters.CipherSuite).SetCompressionAlgorithm(securityParameters.CompressionAlgorithm).SetMasterSecret(securityParameters.MasterSecret).SetPeerCertificate(certificate).SetPskIdentity(securityParameters.PskIdentity).SetSrpIdentity(securityParameters.SrpIdentity).SetServerExtensions(state.serverExtensions).Build();
                state.tlsSession        = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters);
                state.clientContext.SetResumableSession(state.tlsSession);
            }
            state.client.NotifyHandshakeComplete();
            return(new DtlsTransport(recordLayer));
        }
        protected override void HandleHandshakeMessage(byte type, byte[] data)
        {
            //IL_0002: Unknown result type (might be due to invalid IL or missing references)
            //IL_0008: Expected O, but got Unknown
            MemoryStream val = new MemoryStream(data, false);

            if (mResumedSession)
            {
                if (type != 20 || mConnectionState != 2)
                {
                    throw new TlsFatalAlert(10);
                }
                ProcessFinishedMessage(val);
                mConnectionState = 15;
                SendFinishedMessage();
                mConnectionState = 13;
                mConnectionState = 16;
                CompleteHandshake();
                return;
            }
            switch (type)
            {
            case 11:
                switch (mConnectionState)
                {
                case 2:
                case 3:
                    if (mConnectionState == 2)
                    {
                        HandleSupplementalData(null);
                    }
                    mPeerCertificate = Certificate.Parse((Stream)(object)val);
                    TlsProtocol.AssertEmpty(val);
                    if (mPeerCertificate == null || mPeerCertificate.IsEmpty)
                    {
                        mAllowCertificateStatus = false;
                    }
                    mKeyExchange.ProcessServerCertificate(mPeerCertificate);
                    mAuthentication = mTlsClient.GetAuthentication();
                    mAuthentication.NotifyServerCertificate(mPeerCertificate);
                    mConnectionState = 4;
                    break;

                default:
                    throw new TlsFatalAlert(10);
                }
                break;

            case 22:
            {
                short num = mConnectionState;
                if (num == 4)
                {
                    if (!mAllowCertificateStatus)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    mCertificateStatus = CertificateStatus.Parse((Stream)(object)val);
                    TlsProtocol.AssertEmpty(val);
                    mConnectionState = 5;
                    break;
                }
                throw new TlsFatalAlert(10);
            }

            case 20:
                switch (mConnectionState)
                {
                case 13:
                case 14:
                    if (mConnectionState == 13 && mExpectSessionTicket)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    ProcessFinishedMessage(val);
                    mConnectionState = 15;
                    mConnectionState = 16;
                    CompleteHandshake();
                    break;

                default:
                    throw new TlsFatalAlert(10);
                }
                break;

            case 2:
            {
                short num = mConnectionState;
                if (num == 1)
                {
                    ReceiveServerHelloMessage(val);
                    mConnectionState = 2;
                    mRecordStream.NotifyHelloComplete();
                    ApplyMaxFragmentLengthExtension();
                    if (mResumedSession)
                    {
                        mSecurityParameters.masterSecret = Arrays.Clone(mSessionParameters.MasterSecret);
                        mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher());
                        SendChangeCipherSpecMessage();
                        break;
                    }
                    InvalidateSession();
                    if (mSelectedSessionID.Length > 0)
                    {
                        mTlsSession = new TlsSessionImpl(mSelectedSessionID, null);
                    }
                    break;
                }
                throw new TlsFatalAlert(10);
            }

            case 23:
            {
                short num = mConnectionState;
                if (num == 2)
                {
                    HandleSupplementalData(TlsProtocol.ReadSupplementalDataMessage(val));
                    break;
                }
                throw new TlsFatalAlert(10);
            }

            case 14:
                switch (mConnectionState)
                {
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                {
                    if (mConnectionState < 3)
                    {
                        HandleSupplementalData(null);
                    }
                    if (mConnectionState < 4)
                    {
                        mKeyExchange.SkipServerCredentials();
                        mAuthentication = null;
                    }
                    if (mConnectionState < 6)
                    {
                        mKeyExchange.SkipServerKeyExchange();
                    }
                    TlsProtocol.AssertEmpty(val);
                    mConnectionState = 8;
                    mRecordStream.HandshakeHash.SealHashAlgorithms();
                    global::System.Collections.IList clientSupplementalData = mTlsClient.GetClientSupplementalData();
                    if (clientSupplementalData != null)
                    {
                        SendSupplementalDataMessage(clientSupplementalData);
                    }
                    mConnectionState = 9;
                    TlsCredentials tlsCredentials = null;
                    if (mCertificateRequest == null)
                    {
                        mKeyExchange.SkipClientCredentials();
                    }
                    else
                    {
                        tlsCredentials = mAuthentication.GetClientCredentials(mCertificateRequest);
                        if (tlsCredentials == null)
                        {
                            mKeyExchange.SkipClientCredentials();
                            SendCertificateMessage(Certificate.EmptyChain);
                        }
                        else
                        {
                            mKeyExchange.ProcessClientCredentials(tlsCredentials);
                            SendCertificateMessage(tlsCredentials.Certificate);
                        }
                    }
                    mConnectionState = 10;
                    SendClientKeyExchangeMessage();
                    mConnectionState = 11;
                    TlsHandshakeHash tlsHandshakeHash = mRecordStream.PrepareToFinish();
                    mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(Context, tlsHandshakeHash, null);
                    TlsProtocol.EstablishMasterSecret(Context, mKeyExchange);
                    mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher());
                    if (tlsCredentials != null && tlsCredentials is TlsSignerCredentials)
                    {
                        TlsSignerCredentials      tlsSignerCredentials      = (TlsSignerCredentials)tlsCredentials;
                        SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(Context, tlsSignerCredentials);
                        byte[]          hash              = ((signatureAndHashAlgorithm != null) ? tlsHandshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash) : mSecurityParameters.SessionHash);
                        byte[]          signature         = tlsSignerCredentials.GenerateCertificateSignature(hash);
                        DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature);
                        SendCertificateVerifyMessage(certificateVerify);
                        mConnectionState = 12;
                    }
                    SendChangeCipherSpecMessage();
                    SendFinishedMessage();
                    mConnectionState = 13;
                    break;
                }

                default:
                    throw new TlsFatalAlert(40);
                }
                break;

            case 12:
                switch (mConnectionState)
                {
                case 2:
                case 3:
                case 4:
                case 5:
                    if (mConnectionState < 3)
                    {
                        HandleSupplementalData(null);
                    }
                    if (mConnectionState < 4)
                    {
                        mKeyExchange.SkipServerCredentials();
                        mAuthentication = null;
                    }
                    mKeyExchange.ProcessServerKeyExchange((Stream)(object)val);
                    TlsProtocol.AssertEmpty(val);
                    mConnectionState = 6;
                    break;

                default:
                    throw new TlsFatalAlert(10);
                }
                break;

            case 13:
                switch (mConnectionState)
                {
                case 4:
                case 5:
                case 6:
                    if (mConnectionState != 6)
                    {
                        mKeyExchange.SkipServerKeyExchange();
                    }
                    if (mAuthentication == null)
                    {
                        throw new TlsFatalAlert(40);
                    }
                    mCertificateRequest = CertificateRequest.Parse(Context, (Stream)(object)val);
                    TlsProtocol.AssertEmpty(val);
                    mKeyExchange.ValidateCertificateRequest(mCertificateRequest);
                    TlsUtilities.TrackHashAlgorithms(mRecordStream.HandshakeHash, mCertificateRequest.SupportedSignatureAlgorithms);
                    mConnectionState = 7;
                    break;

                default:
                    throw new TlsFatalAlert(10);
                }
                break;

            case 4:
            {
                short num = mConnectionState;
                if (num == 13)
                {
                    if (!mExpectSessionTicket)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    InvalidateSession();
                    ReceiveNewSessionTicketMessage(val);
                    mConnectionState = 14;
                    break;
                }
                throw new TlsFatalAlert(10);
            }

            case 0:
                TlsProtocol.AssertEmpty(val);
                if (mConnectionState == 16)
                {
                    RefuseRenegotiation();
                }
                break;

            default:
                throw new TlsFatalAlert(10);
            }
        }
        protected override void HandleHandshakeMessage(byte type, byte[] data)
        {
            MemoryStream buf = new MemoryStream(data, false);

            if (base.mResumedSession)
            {
                if ((type != 20) || (base.mConnectionState != 2))
                {
                    throw new TlsFatalAlert(10);
                }
                this.ProcessFinishedMessage(buf);
                base.mConnectionState = 15;
                this.SendFinishedMessage();
                base.mConnectionState = 13;
                base.mConnectionState = 0x10;
                this.CompleteHandshake();
            }
            else
            {
                switch (type)
                {
                case 0:
                    TlsProtocol.AssertEmpty(buf);
                    if (base.mConnectionState == 0x10)
                    {
                        this.RefuseRenegotiation();
                    }
                    return;

                case 2:
                    if (base.mConnectionState != 1)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    this.ReceiveServerHelloMessage(buf);
                    base.mConnectionState = 2;
                    base.mRecordStream.NotifyHelloComplete();
                    this.ApplyMaxFragmentLengthExtension();
                    if (base.mResumedSession)
                    {
                        base.mSecurityParameters.masterSecret = Arrays.Clone(base.mSessionParameters.MasterSecret);
                        base.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher());
                        this.SendChangeCipherSpecMessage();
                    }
                    else
                    {
                        this.InvalidateSession();
                        if (this.mSelectedSessionID.Length > 0)
                        {
                            base.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null);
                        }
                    }
                    return;

                case 4:
                    if (base.mConnectionState != 13)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    if (!base.mExpectSessionTicket)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    this.InvalidateSession();
                    this.ReceiveNewSessionTicketMessage(buf);
                    base.mConnectionState = 14;
                    return;

                case 11:
                    switch (base.mConnectionState)
                    {
                    case 2:
                    case 3:
                        if (base.mConnectionState == 2)
                        {
                            this.HandleSupplementalData(null);
                        }
                        base.mPeerCertificate = Certificate.Parse(buf);
                        TlsProtocol.AssertEmpty(buf);
                        if ((base.mPeerCertificate == null) || base.mPeerCertificate.IsEmpty)
                        {
                            base.mAllowCertificateStatus = false;
                        }
                        this.mKeyExchange.ProcessServerCertificate(base.mPeerCertificate);
                        this.mAuthentication = this.mTlsClient.GetAuthentication();
                        this.mAuthentication.NotifyServerCertificate(base.mPeerCertificate);
                        base.mConnectionState = 4;
                        return;
                    }
                    throw new TlsFatalAlert(10);

                case 12:
                    switch (base.mConnectionState)
                    {
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                        if (base.mConnectionState < 3)
                        {
                            this.HandleSupplementalData(null);
                        }
                        if (base.mConnectionState < 4)
                        {
                            this.mKeyExchange.SkipServerCredentials();
                            this.mAuthentication = null;
                        }
                        this.mKeyExchange.ProcessServerKeyExchange(buf);
                        TlsProtocol.AssertEmpty(buf);
                        base.mConnectionState = 6;
                        return;
                    }
                    throw new TlsFatalAlert(10);

                case 13:
                    switch (base.mConnectionState)
                    {
                    case 4:
                    case 5:
                    case 6:
                        if (base.mConnectionState != 6)
                        {
                            this.mKeyExchange.SkipServerKeyExchange();
                        }
                        if (this.mAuthentication == null)
                        {
                            throw new TlsFatalAlert(40);
                        }
                        this.mCertificateRequest = CertificateRequest.Parse(this.Context, buf);
                        TlsProtocol.AssertEmpty(buf);
                        this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest);
                        TlsUtilities.TrackHashAlgorithms(base.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms);
                        base.mConnectionState = 7;
                        return;
                    }
                    throw new TlsFatalAlert(10);

                case 14:
                    switch (base.mConnectionState)
                    {
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    {
                        if (base.mConnectionState < 3)
                        {
                            this.HandleSupplementalData(null);
                        }
                        if (base.mConnectionState < 4)
                        {
                            this.mKeyExchange.SkipServerCredentials();
                            this.mAuthentication = null;
                        }
                        if (base.mConnectionState < 6)
                        {
                            this.mKeyExchange.SkipServerKeyExchange();
                        }
                        TlsProtocol.AssertEmpty(buf);
                        base.mConnectionState = 8;
                        base.mRecordStream.HandshakeHash.SealHashAlgorithms();
                        IList clientSupplementalData = this.mTlsClient.GetClientSupplementalData();
                        if (clientSupplementalData != null)
                        {
                            this.SendSupplementalDataMessage(clientSupplementalData);
                        }
                        base.mConnectionState = 9;
                        TlsCredentials clientCredentials = null;
                        if (this.mCertificateRequest == null)
                        {
                            this.mKeyExchange.SkipClientCredentials();
                        }
                        else
                        {
                            clientCredentials = this.mAuthentication.GetClientCredentials(this.Context, this.mCertificateRequest);
                            if (clientCredentials == null)
                            {
                                this.mKeyExchange.SkipClientCredentials();
                                this.SendCertificateMessage(Certificate.EmptyChain);
                            }
                            else
                            {
                                this.mKeyExchange.ProcessClientCredentials(clientCredentials);
                                this.SendCertificateMessage(clientCredentials.Certificate);
                            }
                        }
                        base.mConnectionState = 10;
                        this.SendClientKeyExchangeMessage();
                        base.mConnectionState = 11;
                        TlsHandshakeHash handshakeHash = base.mRecordStream.PrepareToFinish();
                        base.mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(this.Context, handshakeHash, null);
                        TlsProtocol.EstablishMasterSecret(this.Context, this.mKeyExchange);
                        base.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher());
                        if ((clientCredentials != null) && (clientCredentials is TlsSignerCredentials))
                        {
                            byte[] sessionHash;
                            TlsSignerCredentials      signerCredentials         = (TlsSignerCredentials)clientCredentials;
                            SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(this.Context, signerCredentials);
                            if (signatureAndHashAlgorithm == null)
                            {
                                sessionHash = base.mSecurityParameters.SessionHash;
                            }
                            else
                            {
                                sessionHash = handshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash);
                            }
                            byte[]          signature         = signerCredentials.GenerateCertificateSignature(sessionHash);
                            DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature);
                            this.SendCertificateVerifyMessage(certificateVerify);
                            base.mConnectionState = 12;
                        }
                        this.SendChangeCipherSpecMessage();
                        this.SendFinishedMessage();
                        base.mConnectionState = 13;
                        return;
                    }
                    }
                    throw new TlsFatalAlert(40);

                case 20:
                    switch (base.mConnectionState)
                    {
                    case 13:
                    case 14:
                        if ((base.mConnectionState == 13) && base.mExpectSessionTicket)
                        {
                            throw new TlsFatalAlert(10);
                        }
                        this.ProcessFinishedMessage(buf);
                        base.mConnectionState = 15;
                        base.mConnectionState = 0x10;
                        this.CompleteHandshake();
                        return;
                    }
                    throw new TlsFatalAlert(10);

                case 0x16:
                    if (base.mConnectionState != 4)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    if (!base.mAllowCertificateStatus)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    this.mCertificateStatus = CertificateStatus.Parse(buf);
                    TlsProtocol.AssertEmpty(buf);
                    base.mConnectionState = 5;
                    return;

                case 0x17:
                    if (base.mConnectionState != 2)
                    {
                        throw new TlsFatalAlert(10);
                    }
                    this.HandleSupplementalData(TlsProtocol.ReadSupplementalDataMessage(buf));
                    return;
                }
                throw new TlsFatalAlert(10);
            }
        }