Exemplo n.º 1
0
        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);
        }
    }