Exemple #1
0
        internal protected override bool ProcessHandshake()
        {
            var ret = false;

            // Check to see if we have an exception from the previous call
            //!!if (handshakeException != null)
            //!!{
            //!!    throw handshakeException;
            //!!}

            var nRet = 0;

            if (handShakeState == HandshakeState.InProcess)
            {
                nRet = ssl.Connect();
            }
            else if (handShakeState == HandshakeState.RenegotiateInProcess ||
                     handShakeState == HandshakeState.Renegotiate)
            {
                handShakeState = HandshakeState.RenegotiateInProcess;
                nRet           = ssl.DoHandshake();
            }

            if (nRet <= 0)
            {
                var lastError = ssl.GetError(nRet);
                if (lastError == SslError.SSL_ERROR_WANT_READ)
                {
                    // Do nothing -- the base stream will write the data from the bio
                    // when this call returns
                }
                else if (lastError == SslError.SSL_ERROR_WANT_WRITE)
                {
                    // unexpected error
                    //!!TODO - debug log
                }
                else
                {
                    // We should have alert data in the bio that needs to be written
                    // We'll save the exception, allow the write to start, and then throw the exception
                    // when we come back into the AsyncHandshakeCall
                    if (write_bio.BytesPending > 0)
                    {
                        handshakeException = new OpenSslException();
                    }
                    else
                    {
                        throw new OpenSslException();
                    }
                }
            }
            else
            {
                // Successful handshake
                ret = true;
            }

            return(ret);
        }
        override protected bool HandleIncoming(MemBlock data, out MemBlock app_data)
        {
            app_data = null;
            int count = 0;

            lock (_buffer_sync) {
                if (data != null)
                {
                    data.CopyTo(_buffer, 0);
                    _read.Write(_buffer, data.Length);
                }

                count = _ssl.Read(_buffer, _buffer.Length);
                if (count > 0)
                {
                    app_data = MemBlock.Copy(_buffer, 0, count);
                }
            }

            if (app_data != null)
            {
                // If the read was successful, Dtls has received an incoming data
                // message and decrypted it
                return(true);
            }
            else
            {
                SslError error = _ssl.GetError(count);
                if (error == SslError.SSL_ERROR_WANT_READ)
                {
                    if (SslState == SslState.OK)
                    {
                        UpdateState(States.Active);
                        // In the SslCtx verify, there's no way to get the underlying Sender
                        _ch.Verify(RemoteCertificate, Sender);
                    }
                    HandleWouldBlock();
                }
                else if (error == SslError.SSL_ERROR_SSL)
                {
                    var ose = new OpenSslException();
                    Close("Received unrecoverable error: " + ose.ToString());
                    throw ose;
                }
                else if (error == SslError.SSL_ERROR_ZERO_RETURN)
                {
                    Close("Received clean close notification");
                }
                else
                {
                    ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions,
                                        "Receive other: " + error);
                }
            }
            return(false);
        }
        internal protected override bool ProcessHandshake()
        {
            var bRet = false;
            var nRet = 0;

            if (handShakeState == HandshakeState.InProcess)
            {
                nRet = ssl.Accept();
            }
            else if (handShakeState == HandshakeState.RenegotiateInProcess)
            {
                nRet = ssl.DoHandshake();
            }
            else if (handShakeState == HandshakeState.Renegotiate)
            {
                nRet           = ssl.DoHandshake();
                ssl.State      = Ssl.SSL_ST_ACCEPT;
                handShakeState = HandshakeState.RenegotiateInProcess;
            }

            var lastError = ssl.GetError(nRet);

            if (lastError == SslError.SSL_ERROR_WANT_READ || lastError == SslError.SSL_ERROR_WANT_WRITE || lastError == SslError.SSL_ERROR_NONE)
            {
                if (nRet == 1)                 // success
                {
                    bRet = true;
                }
            }
            else
            {
                // Check to see if we have alert data in the write_bio that needs to be sent
                if (write_bio.BytesPending > 0)
                {
                    // We encountered an error, but need to send the alert
                    // set the handshakeException so that it will be processed
                    // and thrown after the alert is sent
                    handshakeException = new OpenSslException();
                }
                else
                {
                    // No alert to send, throw the exception
                    throw new OpenSslException();
                }
            }
            return(bRet);
        }
        override protected bool HandleOutgoing(ICopyable app_data, out ICopyable data)
        {
            MemBlock buffer = null;

            data = null;
            int written = 1;

            lock (_buffer_sync) {
                if (app_data != null)
                {
                    int count = app_data.CopyTo(_buffer, 0);
                    written = _ssl.Write(_buffer, count);
                }

                if (written > 0)
                {
                    int count = _write.Read(_buffer, _buffer.Length);
                    if (count <= 0)
                    {
                        // This really shouldn't ever happen
                        ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, this + " error");
                        data = null;
                        return(false);
                    }

                    buffer = MemBlock.Copy(_buffer, 0, count);
                }
            }

            if (written > 0)
            {
                // Timer becomes -1 when there are no more control messages
                long to = _ssl.GetTimeout();
                if (to >= 0)
                {
                    HandleWouldBlock();
                }

                if (buffer != null)
                {
                    data = new CopyList(PType, Header, buffer);
                    return(true);
                }
            }

            // If the write failed, then Dtls is either waiting for a control message
            // or has a control message to send
            var error = _ssl.GetError(written);

            if (error == SslError.SSL_ERROR_WANT_READ)
            {
                HandleWouldBlock();
            }
            else if (error == SslError.SSL_ERROR_SSL)
            {
                var ose = new OpenSslException();
                Close("Received unrecoverable error: " + ose.ToString());
                throw ose;
            }
            else
            {
                ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Send other");
            }
            data = null;
            return(false);
        }