protected internal override bool ProcessHandshake() { bool bRet = false; int 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; } SslError 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; }
internal protected override bool ProcessHandshake() { bool ret = false; // Check to see if we have an exception from the previous call //!!if (handshakeException != null) //!!{ //!! throw handshakeException; //!!} int 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) { SslError 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 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; }
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; }