Ejemplo n.º 1
0
        public override IAsyncResult BeginRead(
            byte[] buffer,
            int offset,
            int count,
            AsyncCallback asyncCallback,
            object asyncState)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer", "buffer can't be null");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", "offset less than 0");
            }
            if (offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset", "offset must be less than buffer length");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", "count less than 0");
            }
            if (count > (buffer.Length - offset))
            {
                throw new ArgumentOutOfRangeException("count", "count is greater than buffer length - offset");
            }

            var proceedAfterHandshake = count != 0;

            var internalAsyncResult = new InternalAsyncResult(
                asyncCallback,
                asyncState,
                buffer,
                offset,
                count,
                false,
                proceedAfterHandshake);

            if (NeedHandshake)
            {
                BeginHandshake(internalAsyncResult);
            }
            else
            {
                InternalBeginRead(internalAsyncResult);
            }

            return(internalAsyncResult);
        }
Ejemplo n.º 2
0
        private void InternalWriteCallback(IAsyncResult asyncResult)
        {
            InternalAsyncResult internalAsyncResult = (InternalAsyncResult)asyncResult.AsyncState;

            try
            {
                innerStream.EndWrite(asyncResult);
                internalAsyncResult.SetComplete();
            }
            catch (Exception ex)
            {
                internalAsyncResult.SetComplete(ex);
            }
        }
Ejemplo n.º 3
0
        public override IAsyncResult BeginWrite(
            byte[] buffer,
            int offset,
            int count,
            AsyncCallback asyncCallback,
            object asyncState)
        {
            if (disposed)
            {
                return(null);
            }

            if (buffer == null)
            {
                throw new ArgumentNullException("buffer", "buffer can't be null");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", "offset less than 0");
            }
            if (offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset", "offset must be less than buffer length");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count", "count less than 0");
            }
            if (count > (buffer.Length - offset))
            {
                throw new ArgumentOutOfRangeException("count", "count is greater than buffer length - offset");
            }

            bool proceedAfterHandshake = count != 0;

            InternalAsyncResult asyncResult = new InternalAsyncResult(asyncCallback, asyncState, buffer, offset, count, true, proceedAfterHandshake);

            if (NeedHandshake)
            {
                //inHandshakeLoop = true;
                // Start the handshake
                BeginHandshake(asyncResult);
            }
            else
            {
                InternalBeginWrite(asyncResult);
            }

            return(asyncResult);
        }
Ejemplo n.º 4
0
        private IAsyncResult BeginHandshake(InternalAsyncResult readwriteAsyncResult)
        {
            if (disposed)
            {
                return(null);
            }
            //!!
            // Move the handshake state to the next state
            //if (handShakeState == HandshakeState.Renegotiate)
            //{
            //    handShakeState = HandshakeState.RenegotiateInProcess;
            //}
            //else
            if (handShakeState != HandshakeState.Renegotiate)
            {
                handShakeState = HandshakeState.InProcess;
            }

            // Wrap the read/write InternalAsyncResult in the Handshake InternalAsyncResult instance
            var handshakeAsyncResult = new InternalAsyncResult(
                AsyncHandshakeComplete,
                readwriteAsyncResult,
                null,
                0,
                0,
                readwriteAsyncResult.IsWriteOperation,
                readwriteAsyncResult.ContinueAfterHandshake);

            if (ProcessHandshake())
            {
                handShakeState = HandshakeState.Complete;
                handshakeAsyncResult.SetComplete();
            }
            else
            {
                //!! if (readwriteAsyncResult.IsWriteOperation)
                if (write_bio.BytesPending > 0)
                {
                    handshakeAsyncResult.IsWriteOperation = true;
                    BeginWrite(new byte[0], 0, 0, AsyncHandshakeCallback, handshakeAsyncResult);
                }
                else
                {
                    handshakeAsyncResult.IsWriteOperation = false;
                    BeginRead(new byte[0], 0, 0, AsyncHandshakeCallback, handshakeAsyncResult);
                }
            }
            return(handshakeAsyncResult);
        }
        private void InternalWriteCallback(IAsyncResult ar)
        {
            InternalAsyncResult internalResult = (InternalAsyncResult)ar.AsyncState;

            try
            {
                this.checkDisposed();
                this.innerStream.EndWrite(ar);
                internalResult.SetComplete();
            }
            catch (Exception ex)
            {
                internalResult.SetComplete(ex);
            }
        }
Ejemplo n.º 6
0
 internal void NegotiateHandshake()
 {
     if (MightNeedHandshake)
     {
         InternalAsyncResult asyncResult = new InternalAsyncResult(null, null, null, 0, 0, fromWrite: false, proceedAfterHandshake: false);
         if (!BeginNegotiateHandshake(asyncResult))
         {
             negotiationComplete.WaitOne();
         }
         else
         {
             EndNegotiateHandshake(asyncResult);
         }
     }
 }
        private void AsyncHandshakeCallback(IAsyncResult asyncResult)
        {
            InternalAsyncResult internalResult = asyncResult.AsyncState as InternalAsyncResult;

            try
            {
                try
                {
                    this.OnNegotiateHandshakeCallback(asyncResult);
                }
                catch (TlsException ex)
                {
                    this.protocol.SendAlert(ex.Alert);

                    throw new IOException("The authentication or decryption has failed.", ex);
                }
                catch (Exception ex)
                {
                    this.protocol.SendAlert(AlertDescription.InternalError);

                    throw new IOException("The authentication or decryption has failed.", ex);
                }

                if (internalResult.ProceedAfterHandshake)
                {
                    //kick off the read or write process (whichever called us) after the handshake is complete
                    if (internalResult.FromWrite)
                    {
                        InternalBeginWrite(internalResult);
                    }
                    else
                    {
                        InternalBeginRead(internalResult);
                    }
                    negotiationComplete.Set();
                }
                else
                {
                    negotiationComplete.Set();
                    internalResult.SetComplete();
                }
            }
            catch (Exception ex)
            {
                negotiationComplete.Set();
                internalResult.SetComplete(ex);
            }
        }
Ejemplo n.º 8
0
 private void InternalWriteCallback(IAsyncResult ar)
 {
     if (!disposed)
     {
         InternalAsyncResult internalAsyncResult = (InternalAsyncResult)ar.AsyncState;
         try
         {
             innerStream.EndWrite(ar);
             internalAsyncResult.SetComplete();
         }
         catch (Exception complete)
         {
             internalAsyncResult.SetComplete(complete);
         }
     }
 }
Ejemplo n.º 9
0
 private void InternalBeginRead(InternalAsyncResult asyncResult)
 {
     try
     {
         int num = 0;
         lock (read)
         {
             bool flag  = inputBuffer.Position == inputBuffer.Length && inputBuffer.Length > 0;
             bool flag2 = inputBuffer.Length > 0 && asyncResult.Count > 0;
             if (flag)
             {
                 resetBuffer();
             }
             else if (flag2)
             {
                 num = inputBuffer.Read(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
             }
         }
         if (0 < num)
         {
             asyncResult.SetComplete(num);
         }
         else if (!context.ReceivedConnectionEnd)
         {
             innerStream.BeginRead(recbuf, 0, recbuf.Length, InternalReadCallback, new object[2]
             {
                 recbuf,
                 asyncResult
             });
         }
         else
         {
             asyncResult.SetComplete(0);
         }
     }
     catch (TlsException ex)
     {
         protocol.SendAlert(ex.Alert);
         throw new IOException("The authentication or decryption has failed.", ex);
         IL_012c :;
     }
     catch (Exception innerException)
     {
         throw new IOException("IO exception during read.", innerException);
         IL_0140 :;
     }
 }
Ejemplo n.º 10
0
        private void AsyncHandshakeCallback(IAsyncResult asyncResult)
        {
            InternalAsyncResult internalAsyncResult = asyncResult.AsyncState as InternalAsyncResult;

            try
            {
                try
                {
                    OnNegotiateHandshakeCallback(asyncResult);
                }
                catch (TlsException ex)
                {
                    protocol.SendAlert(ex.Alert);
                    throw new IOException("The authentication or decryption has failed.", ex);
                    IL_0036 :;
                }
                catch (Exception innerException)
                {
                    protocol.SendAlert(AlertDescription.InternalError);
                    throw new IOException("The authentication or decryption has failed.", innerException);
                    IL_0055 :;
                }
                if (internalAsyncResult.ProceedAfterHandshake)
                {
                    if (internalAsyncResult.FromWrite)
                    {
                        InternalBeginWrite(internalAsyncResult);
                    }
                    else
                    {
                        InternalBeginRead(internalAsyncResult);
                    }
                    negotiationComplete.Set();
                }
                else
                {
                    negotiationComplete.Set();
                    internalAsyncResult.SetComplete();
                }
            }
            catch (Exception complete)
            {
                negotiationComplete.Set();
                internalAsyncResult.SetComplete(complete);
            }
        }
Ejemplo n.º 11
0
        private void InternalBeginWrite(InternalAsyncResult asyncResult)
        {
            if (disposed)
            {
                return;
            }

            var new_buffer = asyncResult.Buffer;

            if (asyncResult.Offset != 0 && asyncResult.Count != 0)
            {
                new_buffer = new byte[asyncResult.Count];
                Array.Copy(asyncResult.Buffer, asyncResult.Offset, new_buffer, 0, asyncResult.Count);
            }

            // Only write to the SSL object if we have data
            if (asyncResult.Count != 0)
            {
                var bytesWritten = ssl.Write(new_buffer, asyncResult.Count);
                if (bytesWritten < 0)
                {
                    var lastError = ssl.GetError(bytesWritten);
                    if (lastError == SslError.SSL_ERROR_WANT_READ)
                    {
                        //!!TODO - Log - unexpected renogiation request
                    }
                    throw new OpenSslException();
                }
            }

            var bytesPending = write_bio.BytesPending;

            if (bytesPending > 0)
            {
                var buf = write_bio.ReadBytes((int)bytesPending);
                if (buf.Count > 0)
                {
                    innerStream.BeginWrite(
                        buf.Array, 0, buf.Count,
                        InternalWriteCallback,
                        asyncResult
                        );
                }
            }
        }
Ejemplo n.º 12
0
        internal void NegotiateHandshake()
        {
            if (this.MightNeedHandshake)
            {
                InternalAsyncResult ar = new InternalAsyncResult(null, null, null, 0, 0, false, false);

                //if something already started negotiation, wait for it.
                //otherwise end it ourselves.
                if (!BeginNegotiateHandshake(ar))
                {
                    this.negotiationComplete.WaitOne();
                }
                else
                {
                    this.EndNegotiateHandshake(ar);
                }
            }
        }
Ejemplo n.º 13
0
        public override void EndWrite(IAsyncResult asyncResult)
        {
            checkDisposed();
            InternalAsyncResult internalAsyncResult = asyncResult as InternalAsyncResult;

            if (internalAsyncResult == null)
            {
                throw new ArgumentNullException("asyncResult is null or was not obtained by calling BeginWrite.");
            }
            if (!asyncResult.IsCompleted && !internalAsyncResult.AsyncWaitHandle.WaitOne(300000, exitContext: false))
            {
                throw new TlsException(AlertDescription.InternalError, "Couldn't complete EndWrite");
            }
            if (internalAsyncResult.CompletedWithError)
            {
                throw internalAsyncResult.AsyncException;
            }
        }
Ejemplo n.º 14
0
 private void InternalBeginRead(InternalAsyncResult asyncResult)
 {
     // Check to see if the decrypted data stream should be reset
     if (decrypted_data_stream.Position == decrypted_data_stream.Length)
     {
         decrypted_data_stream.Seek(0, SeekOrigin.Begin);
         decrypted_data_stream.SetLength(0);
     }
     // Check to see if we have data waiting in the decrypted data stream
     if (decrypted_data_stream.Length > 0 && (decrypted_data_stream.Position != decrypted_data_stream.Length))
     {
         // Process the pre-existing data
         int bytesRead = decrypted_data_stream.Read(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
         asyncResult.SetComplete(bytesRead);
         return;
     }
     // Start the async read from the inner stream
     innerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(InternalReadCallback), asyncResult);
 }
Ejemplo n.º 15
0
        private void InternalBeginWrite(InternalAsyncResult asyncResult)
        {
            byte[] new_buffer = asyncResult.Buffer;

            if (asyncResult.Offset != 0 && asyncResult.Count != 0)
            {
                new_buffer = new byte[asyncResult.Count];
                Array.Copy(asyncResult.Buffer, asyncResult.Offset, new_buffer, 0, asyncResult.Count);
            }

            // Only write to the SSL object if we have data
            if (asyncResult.Count != 0)
            {
                int bytesWritten = ssl.Write(new_buffer, asyncResult.Count);
                if (bytesWritten < 0)
                {
                    SslError lastError = ssl.GetError(bytesWritten);
                    if (lastError == SslError.SSL_ERROR_WANT_READ)
                    {
                        //!!TODO - Log - unexpected renogiation request
                    }
                    throw new OpenSslException();
                }
            }
            uint bytesPending = write_bio.BytesPending;
            //!!while (bytesPending > 0)
            {
                if (bytesPending > 0)
                {
                    ArraySegment <byte> buf = write_bio.ReadBytes((int)bytesPending);
                    innerStream.BeginWrite(buf.Array, 0, buf.Count, new AsyncCallback(InternalWriteCallback), asyncResult);
                }
                else
                {
                    innerStream.BeginWrite(new byte[0], 0, 0, new AsyncCallback(InternalWriteCallback), asyncResult);
                }
                //!!bytesPending = write_bio.BytesPending;
            }
        }
Ejemplo n.º 16
0
        public override void EndWrite(IAsyncResult asyncResult)
        {
            InternalAsyncResult internalAsyncResult = asyncResult as InternalAsyncResult;

            if (internalAsyncResult == null)
            {
                throw new ArgumentException("AsyncResult object was not obtained from SslStream.BeginWrite", "asyncResult");
            }

            if (!internalAsyncResult.IsCompleted)
            {
                if (!internalAsyncResult.AsyncWaitHandle.WaitOne(WaitTimeOut, false))
                {
                    throw new IOException("Failed to complete the Write operation");
                }
            }

            if (internalAsyncResult.CompletedWithError)
            {
                throw internalAsyncResult.AsyncException;
            }
        }
Ejemplo n.º 17
0
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            checkDisposed();
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer is a null reference.");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset is less than 0.");
            }
            if (offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("offset is greater than the length of buffer.");
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException("count is less than 0.");
            }
            if (count > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException("count is less than the length of buffer minus the value of the offset parameter.");
            }
            InternalAsyncResult internalAsyncResult = new InternalAsyncResult(callback, state, buffer, offset, count, fromWrite: true, proceedAfterHandshake: true);

            if (MightNeedHandshake)
            {
                if (!BeginNegotiateHandshake(internalAsyncResult))
                {
                    negotiationComplete.WaitOne();
                    InternalBeginWrite(internalAsyncResult);
                }
            }
            else
            {
                InternalBeginWrite(internalAsyncResult);
            }
            return(internalAsyncResult);
        }
Ejemplo n.º 18
0
        private void EndHandshake(IAsyncResult asyncResult)
        {
            if (disposed)
            {
                return;
            }

            InternalAsyncResult handshakeAsyncResult = asyncResult as InternalAsyncResult;
            InternalAsyncResult readwriteAsyncResult = asyncResult.AsyncState as InternalAsyncResult;

            if (!handshakeAsyncResult.IsCompleted)
            {
                handshakeAsyncResult.AsyncWaitHandle.WaitOne(WaitTimeOut, false);
            }
            if (handshakeAsyncResult.CompletedWithError)
            {
                // if there's a handshake error, pass it to the read asyncresult instance
                readwriteAsyncResult.SetComplete(handshakeAsyncResult.AsyncException);
                return;
            }
            if (readwriteAsyncResult.ContinueAfterHandshake)
            {
                // We should continue the read/write operation since the handshake is complete
                if (readwriteAsyncResult.IsWriteOperation)
                {
                    InternalBeginWrite(readwriteAsyncResult);
                }
                else
                {
                    InternalBeginRead(readwriteAsyncResult);
                }
            }
            else
            {
                // If we aren't continuing, we're done
                readwriteAsyncResult.SetComplete();
            }
        }
Ejemplo n.º 19
0
 private void InternalBeginWrite(InternalAsyncResult asyncResult)
 {
     try
     {
         lock (write)
         {
             byte[] array = protocol.EncodeRecord(ContentType.ApplicationData, asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
             innerStream.BeginWrite(array, 0, array.Length, InternalWriteCallback, asyncResult);
         }
     }
     catch (TlsException ex)
     {
         protocol.SendAlert(ex.Alert);
         Close();
         throw new IOException("The authentication or decryption has failed.", ex);
         IL_0080 :;
     }
     catch (Exception innerException)
     {
         throw new IOException("IO exception during Write.", innerException);
         IL_0092 :;
     }
 }
Ejemplo n.º 20
0
        private void InternalBeginWrite(InternalAsyncResult asyncResult)
        {
            try
            {
                // Send the buffer as a TLS record

                lock (this.write)
                {
                    byte[] record = this.protocol.EncodeRecord(
                        ContentType.ApplicationData, asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);

                    this.innerStream.BeginWrite(
                        record, 0, record.Length, new AsyncCallback(InternalWriteCallback), asyncResult);
                }
            }
            catch (Exception ex)
            {
                this.protocol.SendAlert(ref ex);
                this.Close();

                throw new IOException("The authentication or decryption has failed.", ex);
            }
        }
Ejemplo n.º 21
0
        private bool BeginNegotiateHandshake(InternalAsyncResult asyncResult)
        {
            try
            {
                lock (negotiate)
                {
                    if (context.HandshakeState == HandshakeState.None)
                    {
                        OnBeginNegotiateHandshake(AsyncHandshakeCallback, asyncResult);
                        return(true);
                    }
                    return(false);

IL_003f:
                    bool result;
                    return(result);
                }
            }
            catch (TlsException ex)
            {
                negotiationComplete.Set();
                protocol.SendAlert(ex.Alert);
                throw new IOException("The authentication or decryption has failed.", ex);
IL_007a:
                bool result;
                return(result);
            }
            catch (Exception innerException)
            {
                negotiationComplete.Set();
                protocol.SendAlert(AlertDescription.InternalError);
                throw new IOException("The authentication or decryption has failed.", innerException);
IL_00a5:
                bool result;
                return(result);
            }
        }
Ejemplo n.º 22
0
        private void InternalBeginRead(InternalAsyncResult asyncResult)
        {
            if (disposed)
            {
                return;
            }

            // Check to see if the decrypted data stream should be reset
            if (cleartext.Position == cleartext.Length)
            {
                cleartext.Seek(0, SeekOrigin.Begin);
                cleartext.SetLength(0);
            }
            // Check to see if we have data waiting in the decrypted data stream
            if (cleartext.Length > 0 && (cleartext.Position != cleartext.Length))
            {
                // Process the pre-existing data
                var bytesRead = cleartext.Read(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
                asyncResult.SetComplete(bytesRead);
                return;
            }
            // Start the async read from the inner stream
            innerStream.BeginRead(read_buffer, 0, read_buffer.Length, InternalReadCallback, asyncResult);
        }
Ejemplo n.º 23
0
        private bool BeginNegotiateHandshake(InternalAsyncResult asyncResult)
        {
            try
            {
                lock (negotiate)
                {
                    if (context.HandshakeState == HandshakeState.None)
                    {
                        BeginNegotiateHandshake(AsyncHandshakeCallback, asyncResult);

                        return(true);
                    }

                    return(false);
                }
            }
            catch (Exception ex)
            {
                negotiationComplete.Set();
                protocol.SendAlert(ref ex);

                throw new IOException("The authentication or decryption has failed.", ex);
            }
        }
Ejemplo n.º 24
0
		public override IAsyncResult BeginWrite(
			byte[] buffer,
			int offset,
			int count,
			AsyncCallback callback,
			object state)
		{
			this.checkDisposed();

			if (buffer == null)
			{
				throw new ArgumentNullException("buffer is a null reference.");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset is less than 0.");
			}
			if (offset > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("offset is greater than the length of buffer.");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count is less than 0.");
			}
			if (count > (buffer.Length - offset))
			{
				throw new ArgumentOutOfRangeException("count is less than the length of buffer minus the value of the offset parameter.");
			}


			InternalAsyncResult asyncResult = new InternalAsyncResult(callback, state, buffer, offset, count, true, true);

			if (this.MightNeedHandshake)
			{
				if (! BeginNegotiateHandshake(asyncResult))
				{
					//we made it down here so the handshake was not started.
					//another thread must have started it in the mean time.
					//wait for it to complete and then perform our original operation
					this.negotiationComplete.WaitOne();

					InternalBeginWrite(asyncResult);
				}
			}
			else
			{
				InternalBeginWrite(asyncResult);
			}

			return asyncResult;
		}
Ejemplo n.º 25
0
		private void InternalBeginWrite(InternalAsyncResult asyncResult)
		{
			try
			{
				// Send the buffer as a TLS record

				lock (this.write)
				{
					byte[] record = this.protocol.EncodeRecord(
						ContentType.ApplicationData, asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);

					this.innerStream.BeginWrite(
						record, 0, record.Length, new AsyncCallback(InternalWriteCallback), asyncResult);
				}
			}
			catch (TlsException ex)
			{
				this.protocol.SendAlert(ex.Alert);
				this.Close();

				throw new IOException("The authentication or decryption has failed.", ex);
			}
			catch (Exception ex)
			{
				throw new IOException("IO exception during Write.", ex);
			}
		}
Ejemplo n.º 26
0
		private void InternalBeginRead(InternalAsyncResult asyncResult)
		{
			try
			{
				int preReadSize = 0;

				lock (this.read)
				{
					// If actual buffer is fully read, reset it
					bool shouldReset = this.inputBuffer.Position == this.inputBuffer.Length && this.inputBuffer.Length > 0;

					// If the buffer isn't fully read, but does have data, we need to immediately
					// read the info from the buffer and let the user know that they have more data.
					bool shouldReadImmediately = (this.inputBuffer.Length > 0) && (asyncResult.Count > 0);

					if (shouldReset)
					{
						this.resetBuffer();
					}
					else if (shouldReadImmediately)
					{
						preReadSize = this.inputBuffer.Read(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
					}
				}

				// This is explicitly done outside the synclock to avoid 
				// any potential deadlocks in the delegate call.
				if (0 < preReadSize)
				{
					asyncResult.SetComplete(preReadSize);
				}
				else if (!this.context.ReceivedConnectionEnd)
				{
					// this will read data from the network until we have (at least) one
					// record to send back to the caller
					this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
						new AsyncCallback(InternalReadCallback), new object[] { recbuf, asyncResult });
				}
				else
				{
					// We're done with the connection so we need to let the caller know with 0 bytes read
					asyncResult.SetComplete(0);
				}
			}
			catch (TlsException ex)
			{
				this.protocol.SendAlert(ex.Alert);

				throw new IOException("The authentication or decryption has failed.", ex);
			}
			catch (Exception ex)
			{
				throw new IOException("IO exception during read.", ex);
			}
		}
Ejemplo n.º 27
0
		private void EndNegotiateHandshake(InternalAsyncResult asyncResult)
		{
			if (asyncResult.IsCompleted == false)
				asyncResult.AsyncWaitHandle.WaitOne();

			if (asyncResult.CompletedWithError)
			{
				throw asyncResult.AsyncException;
			}
		}
Ejemplo n.º 28
0
		private bool BeginNegotiateHandshake(InternalAsyncResult asyncResult)
		{
			try
			{
				lock (this.negotiate)
				{
					if (this.context.HandshakeState == HandshakeState.None)
					{
						this.OnBeginNegotiateHandshake(new AsyncCallback(AsyncHandshakeCallback), asyncResult);

						return true;
					}
					else
					{
						return false;
					}
				}
			}
			catch (TlsException ex)
			{
				this.negotiationComplete.Set();
				this.protocol.SendAlert(ex.Alert);

				throw new IOException("The authentication or decryption has failed.", ex);
			}
			catch (Exception ex)
			{
				this.negotiationComplete.Set();
				this.protocol.SendAlert(AlertDescription.InternalError);

				throw new IOException("The authentication or decryption has failed.", ex);
			}
		}
Ejemplo n.º 29
0
		internal void NegotiateHandshake()
		{
			if (this.MightNeedHandshake)
			{
				InternalAsyncResult ar = new InternalAsyncResult(null, null, null, 0, 0, false, false);

				//if something already started negotiation, wait for it.
				//otherwise end it ourselves.
				if (!BeginNegotiateHandshake(ar))
				{
					this.negotiationComplete.WaitOne();
				}
				else
				{
					this.EndNegotiateHandshake(ar);
				}
			}
		}
Ejemplo n.º 30
0
        // read encrypted data until we have enough to decrypt (at least) one
        // record and return are the records (may be more than one) we have
        private void InternalReadCallback_inner(InternalAsyncResult internalResult, byte[] recbuf, object[] state,
                                                bool didRead, int n)
        {
            if (disposed)
            {
                return;
            }

            try
            {
                var dataToReturn = false;
                var pos          = recordStream.Position;

                recordStream.Position = 0;
                byte[] record = null;

                // don't try to decode record unless we have at least 5 bytes
                // i.e. type (1), protocol (2) and length (2)
                if (recordStream.Length >= 5)
                {
                    record = protocol.ReceiveRecord(recordStream);
                }

                // a record of 0 length is valid (and there may be more record after it)
                while (record != null)
                {
                    // we probably received more stuff after the record, and we must keep it!
                    var    remainder   = recordStream.Length - recordStream.Position;
                    byte[] outofrecord = null;
                    if (remainder > 0)
                    {
                        outofrecord = new byte[remainder];
                        recordStream.Read(outofrecord, 0, outofrecord.Length);
                    }

                    lock (read)
                    {
                        var position = inputBuffer.Position;

                        if (record.Length > 0)
                        {
                            // Write new data to the inputBuffer
                            inputBuffer.Seek(0, SeekOrigin.End);
                            inputBuffer.Write(record, 0, record.Length);

                            // Restore buffer position
                            inputBuffer.Seek(position, SeekOrigin.Begin);
                            dataToReturn = true;
                        }
                    }

                    recordStream.SetLength(0);
                    record = null;

                    if (remainder > 0)
                    {
                        recordStream.Write(outofrecord, 0, outofrecord.Length);
                        // type (1), protocol (2) and length (2)
                        if (recordStream.Length >= 5)
                        {
                            // try to see if another record is available
                            recordStream.Position = 0;
                            record = protocol.ReceiveRecord(recordStream);
                            if (record == null)
                            {
                                pos = recordStream.Length;
                            }
                        }
                        else
                        {
                            pos = remainder;
                        }
                    }
                    else
                    {
                        pos = 0;
                    }
                }

                if (!dataToReturn && (!didRead || n > 0))
                {
                    if (context.ReceivedConnectionEnd)
                    {
                        internalResult.SetComplete(0);
                    }
                    else
                    {
                        // there is no record to return to caller and (possibly) more data waiting
                        // so continue reading from network (and appending to stream)
                        recordStream.Position = recordStream.Length;
                        innerStream.BeginRead(recbuf, 0, recbuf.Length,
                                              InternalReadCallback, state);
                    }
                }
                else
                {
                    // we have record(s) to return -or- no more available to read from network
                    // reset position for further reading
                    recordStream.Position = pos;

                    var bytesRead = 0;
                    lock (read)
                    {
                        bytesRead = inputBuffer.Read(internalResult.Buffer, internalResult.Offset,
                                                     internalResult.Count);
                    }

                    internalResult.SetComplete(bytesRead);
                }
            }
            catch (Exception ex)
            {
                internalResult.SetComplete(ex);
            }
        }
Ejemplo n.º 31
0
        // read encrypted data until we have enough to decrypt (at least) one
        // record and return are the records (may be more than one) we have
        private void InternalReadCallback(IAsyncResult result)
        {
            if (this.disposed)
            {
                return;
            }

            object[]            state          = (object[])result.AsyncState;
            byte[]              recbuf         = (byte[])state[0];
            InternalAsyncResult internalResult = (InternalAsyncResult)state[1];

            try
            {
                int n = innerStream.EndRead(result);
                if (n > 0)
                {
                    // Add the just received data to the waiting data
                    recordStream.Write(recbuf, 0, n);
                }
                else
                {
                    // 0 length data means this read operation is done (lost connection in the case of a network stream).
                    internalResult.SetComplete(0);
                    return;
                }

                bool dataToReturn = false;
                long pos          = recordStream.Position;

                recordStream.Position = 0;
                byte[] record = null;

                // don't try to decode record unless we have at least 5 bytes
                // i.e. type (1), protocol (2) and length (2)
                if (recordStream.Length >= 5)
                {
                    record = this.protocol.ReceiveRecord(recordStream);
                }

                // a record of 0 length is valid (and there may be more record after it)
                while (record != null)
                {
                    // we probably received more stuff after the record, and we must keep it!
                    long   remainder   = recordStream.Length - recordStream.Position;
                    byte[] outofrecord = null;
                    if (remainder > 0)
                    {
                        outofrecord = new byte[remainder];
                        recordStream.Read(outofrecord, 0, outofrecord.Length);
                    }

                    lock (this.read)
                    {
                        long position = this.inputBuffer.Position;

                        if (record.Length > 0)
                        {
                            // Write new data to the inputBuffer
                            this.inputBuffer.Seek(0, SeekOrigin.End);
                            this.inputBuffer.Write(record, 0, record.Length);

                            // Restore buffer position
                            this.inputBuffer.Seek(position, SeekOrigin.Begin);
                            dataToReturn = true;
                        }
                    }

                    recordStream.SetLength(0);
                    record = null;

                    if (remainder > 0)
                    {
                        recordStream.Write(outofrecord, 0, outofrecord.Length);
                        // type (1), protocol (2) and length (2)
                        if (recordStream.Length >= 5)
                        {
                            // try to see if another record is available
                            recordStream.Position = 0;
                            record = this.protocol.ReceiveRecord(recordStream);
                            if (record == null)
                            {
                                pos = recordStream.Length;
                            }
                        }
                        else
                        {
                            pos = remainder;
                        }
                    }
                    else
                    {
                        pos = 0;
                    }
                }

                if (!dataToReturn && (n > 0))
                {
                    if (context.ReceivedConnectionEnd)
                    {
                        internalResult.SetComplete(0);
                    }
                    else
                    {
                        // there is no record to return to caller and (possibly) more data waiting
                        // so continue reading from network (and appending to stream)
                        recordStream.Position = recordStream.Length;
                        this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
                                                   new AsyncCallback(InternalReadCallback), state);
                    }
                }
                else
                {
                    // we have record(s) to return -or- no more available to read from network
                    // reset position for further reading
                    recordStream.Position = pos;

                    int bytesRead = 0;
                    lock (this.read)
                    {
                        bytesRead = this.inputBuffer.Read(internalResult.Buffer, internalResult.Offset, internalResult.Count);
                    }

                    internalResult.SetComplete(bytesRead);
                }
            }
            catch (Exception ex)
            {
                internalResult.SetComplete(ex);
            }
        }
Ejemplo n.º 32
0
		/*
		public override void Write(byte[] buffer, int offset, int count)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "Offset must be greater than or equal to 0");
			}
			if (offset > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("offset", "Offset is greater than length of the buffer");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", "Count must be greater than 0");    
			}
			if (count > (buffer.Length - offset))
			{
				throw new ArgumentOutOfRangeException("count", "Count is greater than buffer length - offset");
			}

			byte[] new_buffer = buffer;
			if (offset != 0)
			{
				byte[] temp = new byte[count];
				Array.Copy(buffer, offset, temp, 0, count);
				new_buffer = temp;
			}

			int bytesWritten = ssl.Write(new_buffer, count);
			if (bytesWritten <= 0)
			{
				SslError lastError = ssl.GetError(bytesWritten);
				if (lastError == SslError.SSL_ERROR_WANT_READ)
				{
					//!!TODO - Log - unexpected renogiation request
				}
				throw new OpenSslException((uint)lastError);
			}
			uint bytesPending = write_bio.BytesPending;
			while (bytesPending > 0)
			{
				ArraySegment<byte> buf = write_bio.ReadBytes((int)bytesPending);
				innerStream.Write(buf.Array, 0, buf.Count);
				bytesPending = write_bio.BytesPending;
			}
		}
		*/

		public override IAsyncResult BeginWrite(
			byte[] buffer,
			int offset,
			int count,
			AsyncCallback asyncCallback,
			object asyncState)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer", "buffer can't be null");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "offset less than 0");
			}
			if (offset > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("offset", "offset must be less than buffer length");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", "count less than 0");
			}
			if (count > (buffer.Length - offset))
			{
				throw new ArgumentOutOfRangeException("count", "count is greater than buffer length - offset");
			}

			bool proceedAfterHandshake = true;
			if (count == 0) proceedAfterHandshake = false;

			InternalAsyncResult asyncResult = new InternalAsyncResult(asyncCallback, asyncState, buffer, offset, count, true, proceedAfterHandshake);

			if (NeedHandshake)
			{
				//inHandshakeLoop = true;
				// Start the handshake
				BeginHandshake(asyncResult);
			}
			else
			{
				InternalBeginWrite(asyncResult);
			}

			return asyncResult;
		}
Ejemplo n.º 33
0
		private void InternalBeginRead(InternalAsyncResult asyncResult)
		{
			// Check to see if the decrypted data stream should be reset
			if (decrypted_data_stream.Position == decrypted_data_stream.Length)
			{
				decrypted_data_stream.Seek(0, SeekOrigin.Begin);
				decrypted_data_stream.SetLength(0);
			}
			// Check to see if we have data waiting in the decrypted data stream
			if (decrypted_data_stream.Length > 0 && (decrypted_data_stream.Position != decrypted_data_stream.Length))
			{
				// Process the pre-existing data
				int bytesRead = decrypted_data_stream.Read(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
				asyncResult.SetComplete(bytesRead);
				return;
			}
			// Start the async read from the inner stream
			innerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(InternalReadCallback), asyncResult);
		}
Ejemplo n.º 34
0
		private void InternalBeginRead(InternalAsyncResult asyncResult)
		{
			if (disposed)
				return;

			// Check to see if the decrypted data stream should be reset
			if (cleartext.Position == cleartext.Length)
			{
				cleartext.Seek(0, SeekOrigin.Begin);
				cleartext.SetLength(0);
			}
			// Check to see if we have data waiting in the decrypted data stream
			if (cleartext.Length > 0 && (cleartext.Position != cleartext.Length))
			{
				// Process the pre-existing data
				var bytesRead = cleartext.Read(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count);
				asyncResult.SetComplete(bytesRead);
				return;
			}
			// Start the async read from the inner stream
			innerStream.BeginRead(read_buffer, 0, read_buffer.Length, InternalReadCallback, asyncResult);
		}
Ejemplo n.º 35
0
		public override IAsyncResult BeginRead(
			byte[] buffer,
			int offset,
			int count,
			AsyncCallback asyncCallback,
			object asyncState)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer", "buffer can't be null");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "offset less than 0");
			}
			if (offset > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("offset", "offset must be less than buffer length");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", "count less than 0");
			}
			if (count > (buffer.Length - offset))
			{
				throw new ArgumentOutOfRangeException("count", "count is greater than buffer length - offset");
			}

			var proceedAfterHandshake = count != 0;

			var internalAsyncResult = new InternalAsyncResult(
				asyncCallback, 
				asyncState, 
				buffer, 
				offset, 
				count, 
				false, 
				proceedAfterHandshake);

			if (NeedHandshake)
			{
				BeginHandshake(internalAsyncResult);
			}
			else
			{
				InternalBeginRead(internalAsyncResult);
			}

			return internalAsyncResult;
		}
Ejemplo n.º 36
0
 private void InternalReadCallback(IAsyncResult result)
 {
     if (!disposed)
     {
         object[]            array  = (object[])result.AsyncState;
         byte[]              array2 = (byte[])array[0];
         InternalAsyncResult internalAsyncResult = (InternalAsyncResult)array[1];
         try
         {
             int num = innerStream.EndRead(result);
             if (num > 0)
             {
                 recordStream.Write(array2, 0, num);
                 bool flag     = false;
                 long position = recordStream.Position;
                 recordStream.Position = 0L;
                 byte[] array3 = null;
                 if (recordStream.Length >= 5)
                 {
                     array3 = protocol.ReceiveRecord(recordStream);
                 }
                 while (array3 != null)
                 {
                     long   num2   = recordStream.Length - recordStream.Position;
                     byte[] array4 = null;
                     if (num2 > 0)
                     {
                         array4 = new byte[num2];
                         recordStream.Read(array4, 0, array4.Length);
                     }
                     lock (read)
                     {
                         long position2 = inputBuffer.Position;
                         if (array3.Length > 0)
                         {
                             inputBuffer.Seek(0L, SeekOrigin.End);
                             inputBuffer.Write(array3, 0, array3.Length);
                             inputBuffer.Seek(position2, SeekOrigin.Begin);
                             flag = true;
                         }
                     }
                     recordStream.SetLength(0L);
                     array3 = null;
                     if (num2 > 0)
                     {
                         recordStream.Write(array4, 0, array4.Length);
                         if (recordStream.Length >= 5)
                         {
                             recordStream.Position = 0L;
                             array3 = protocol.ReceiveRecord(recordStream);
                             if (array3 == null)
                             {
                                 position = recordStream.Length;
                             }
                         }
                         else
                         {
                             position = num2;
                         }
                     }
                     else
                     {
                         position = 0L;
                     }
                 }
                 if (!flag && num > 0)
                 {
                     if (context.ReceivedConnectionEnd)
                     {
                         internalAsyncResult.SetComplete(0);
                     }
                     else
                     {
                         recordStream.Position = recordStream.Length;
                         innerStream.BeginRead(array2, 0, array2.Length, InternalReadCallback, array);
                     }
                 }
                 else
                 {
                     recordStream.Position = position;
                     int complete = 0;
                     lock (read)
                     {
                         complete = inputBuffer.Read(internalAsyncResult.Buffer, internalAsyncResult.Offset, internalAsyncResult.Count);
                     }
                     internalAsyncResult.SetComplete(complete);
                 }
             }
             else
             {
                 internalAsyncResult.SetComplete(0);
             }
         }
         catch (Exception complete2)
         {
             internalAsyncResult.SetComplete(complete2);
         }
     }
 }
Ejemplo n.º 37
0
		// read encrypted data until we have enough to decrypt (at least) one
		// record and return are the records (may be more than one) we have
		private void InternalReadCallback_inner(InternalAsyncResult internalResult, byte[] recbuf, object[] state, bool didRead, int n)
		{
			if (this.disposed)
				return;

			try
			{
				bool dataToReturn = false;
				long pos = recordStream.Position;

				recordStream.Position = 0;
				byte[] record = null;

				// don't try to decode record unless we have at least 5 bytes
				// i.e. type (1), protocol (2) and length (2)
				if (recordStream.Length >= 5)
				{
					record = this.protocol.ReceiveRecord(recordStream);
				}

				// a record of 0 length is valid (and there may be more record after it)
				while (record != null)
				{
					// we probably received more stuff after the record, and we must keep it!
					long remainder = recordStream.Length - recordStream.Position;
					byte[] outofrecord = null;
					if (remainder > 0)
					{
						outofrecord = new byte[remainder];
						recordStream.Read(outofrecord, 0, outofrecord.Length);
					}

					lock (this.read)
					{
						long position = this.inputBuffer.Position;

						if (record.Length > 0)
						{
							// Write new data to the inputBuffer
							this.inputBuffer.Seek(0, SeekOrigin.End);
							this.inputBuffer.Write(record, 0, record.Length);

							// Restore buffer position
							this.inputBuffer.Seek(position, SeekOrigin.Begin);
							dataToReturn = true;
						}
					}

					recordStream.SetLength(0);
					record = null;

					if (remainder > 0)
					{
						recordStream.Write(outofrecord, 0, outofrecord.Length);
						// type (1), protocol (2) and length (2)
						if (recordStream.Length >= 5)
						{
							// try to see if another record is available
							recordStream.Position = 0;
							record = this.protocol.ReceiveRecord(recordStream);
							if (record == null)
								pos = recordStream.Length;
						}
						else
							pos = remainder;
					}
					else
						pos = 0;
				}

				if (!dataToReturn && (!didRead || (n > 0)))
				{
					if (context.ReceivedConnectionEnd) {
						internalResult.SetComplete (0);
					} else {
						// there is no record to return to caller and (possibly) more data waiting
						// so continue reading from network (and appending to stream)
						recordStream.Position = recordStream.Length;
						this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
							new AsyncCallback(InternalReadCallback), state);
					}
				}
				else
				{
					// we have record(s) to return -or- no more available to read from network
					// reset position for further reading
					recordStream.Position = pos;

					int bytesRead = 0;
					lock (this.read)
					{
						bytesRead = this.inputBuffer.Read(internalResult.Buffer, internalResult.Offset, internalResult.Count);
					}

					internalResult.SetComplete(bytesRead);
				}
			}
			catch (Exception ex)
			{
				internalResult.SetComplete(ex);
			}
		}
Ejemplo n.º 38
0
		private void InternalBeginWrite(InternalAsyncResult asyncResult)
		{
			byte[] new_buffer = asyncResult.Buffer;

			if (asyncResult.Offset != 0 && asyncResult.Count != 0)
			{
				new_buffer = new byte[asyncResult.Count];
				Array.Copy(asyncResult.Buffer, asyncResult.Offset, new_buffer, 0, asyncResult.Count);
			}

			// Only write to the SSL object if we have data
			if (asyncResult.Count != 0)
			{
				int bytesWritten = ssl.Write(new_buffer, asyncResult.Count);
				if (bytesWritten < 0)
				{
					SslError lastError = ssl.GetError(bytesWritten);
					if (lastError == SslError.SSL_ERROR_WANT_READ)
					{
						//!!TODO - Log - unexpected renogiation request
					}
					throw new OpenSslException();
				}
			}
			uint bytesPending = write_bio.BytesPending;
			//!!while (bytesPending > 0)
			{
				ArraySegment<byte> buf = write_bio.ReadBytes((int)bytesPending);
				innerStream.BeginWrite(buf.Array, 0, buf.Count, new AsyncCallback(InternalWriteCallback), asyncResult);
				//!!bytesPending = write_bio.BytesPending;
			}
		}
Ejemplo n.º 39
0
        private void InternalReadCallback(IAsyncResult asyncResult)
        {
            InternalAsyncResult internalAsyncResult = (InternalAsyncResult)asyncResult.AsyncState;
            bool haveDataToReturn = false;

            try
            {
                int bytesRead = 0;
                try
                {
                    bytesRead = innerStream.EndRead(asyncResult);
                }
                catch (Exception ex)
                {
                    // Set the exception into the internal async result
                    internalAsyncResult.SetComplete(ex);
                }
                if (bytesRead <= 0)
                {
                    // Zero byte read most likely indicates connection closed (if it's a network stream)
                    internalAsyncResult.SetComplete(0);
                    return;
                }
                else
                {
                    // Copy encrypted data into the SSL read_bio
                    read_bio.Write(read_buffer, bytesRead);
                    if (handShakeState == HandshakeState.InProcess ||
                        handShakeState == HandshakeState.RenegotiateInProcess)
                    {
                        // We are in the handshake, complete the async operation to fire the async
                        // handshake callback for processing
                        internalAsyncResult.SetComplete(bytesRead);
                        return;
                    }
                    uint   nBytesPending = read_bio.BytesPending;
                    byte[] decrypted_buf = new byte[SSL3_RT_MAX_PACKET_SIZE];
                    while (nBytesPending > 0)
                    {
                        int decryptedBytesRead = ssl.Read(decrypted_buf, decrypted_buf.Length);
                        if (decryptedBytesRead <= 0)
                        {
                            SslError lastError = ssl.GetError(decryptedBytesRead);
                            if (lastError == SslError.SSL_ERROR_WANT_READ)
                            {
                                // if we have bytes pending in the write bio.
                                // the client has requested a renegotiation
                                if (write_bio.BytesPending > 0)
                                {
                                    // Start the renegotiation by writing the write_bio data, and use the RenegotiationWriteCallback
                                    // to handle the rest of the renegotiation
                                    ArraySegment <byte> buf = write_bio.ReadBytes((int)write_bio.BytesPending);
                                    innerStream.BeginWrite(buf.Array, 0, buf.Count, new AsyncCallback(RenegotiationWriteCallback), internalAsyncResult);
                                    return;
                                }
                                // no data in the out bio, we just need more data to complete the record
                                //break;
                            }
                            else if (lastError == SslError.SSL_ERROR_WANT_WRITE)
                            {
                                // unexpected error!
                                //!!TODO debug log
                            }
                            else if (lastError == SslError.SSL_ERROR_ZERO_RETURN)
                            {
                                // Shutdown alert
                                SendShutdownAlert();
                                break;
                            }
                            else
                            {
                                throw new OpenSslException();
                            }
                        }
                        if (decryptedBytesRead > 0)
                        {
                            // Write decrypted data to memory stream
                            long pos = decrypted_data_stream.Position;
                            decrypted_data_stream.Seek(0, SeekOrigin.End);
                            decrypted_data_stream.Write(decrypted_buf, 0, decryptedBytesRead);
                            decrypted_data_stream.Seek(pos, SeekOrigin.Begin);
                            haveDataToReturn = true;
                        }

                        // See if we have more data to process
                        nBytesPending = read_bio.BytesPending;
                    }
                    // Check to see if we have data to return, if not, fire the async read again
                    if (!haveDataToReturn)
                    {
                        innerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(InternalReadCallback), internalAsyncResult);
                    }
                    else
                    {
                        int bytesReadIntoUserBuffer = 0;

                        // Read the data into the buffer provided by the user (now hosted in the InternalAsyncResult)
                        bytesReadIntoUserBuffer = decrypted_data_stream.Read(internalAsyncResult.Buffer, internalAsyncResult.Offset, internalAsyncResult.Count);

                        internalAsyncResult.SetComplete(bytesReadIntoUserBuffer);
                    }
                }
            }
            catch (Exception ex)
            {
                internalAsyncResult.SetComplete(ex);
            }
        }
Ejemplo n.º 40
0
        private void AsyncHandshakeCallback(IAsyncResult asyncResult)
        {
            // Get the handshake internal result instance
            InternalAsyncResult internalAsyncResult = (InternalAsyncResult)asyncResult.AsyncState;
            int bytesRead = 0;

            if (internalAsyncResult.IsWriteOperation)
            {
                EndWrite(asyncResult);
                // Check to see if the handshake is complete (this could have been
                // the last response packet from the server.  If so, we want to finalize
                // the async operation and call the HandshakeComplete callback
                if (handShakeState == HandshakeState.Complete)
                {
                    internalAsyncResult.SetComplete();
                    return;
                }
                // Check to see if we saved an exception from the last Handshake process call
                // the if the client gets an error code, it needs to send the alert, and then
                // throw the exception here.
                if (handshakeException != null)
                {
                    internalAsyncResult.SetComplete(handshakeException);
                    return;
                }
                // We wrote out the handshake data, now read to get the response
                internalAsyncResult.IsWriteOperation = false;
                BeginRead(new byte[0], 0, 0, new AsyncCallback(AsyncHandshakeCallback), internalAsyncResult);
            }
            else
            {
                try
                {
                    bytesRead = EndRead(asyncResult);
                    if (bytesRead > 0)
                    {
                        if (ProcessHandshake())
                        {
                            //inHandshakeLoop = false;
                            handShakeState = HandshakeState.Complete;
                            // We have completed the handshake, but need to send the
                            // last response packet.
                            if (write_bio.BytesPending > 0)
                            {
                                internalAsyncResult.IsWriteOperation = true;
                                BeginWrite(new byte[0], 0, 0, new AsyncCallback(AsyncHandshakeCallback), internalAsyncResult);
                            }
                            else
                            {
                                internalAsyncResult.SetComplete();
                                return;
                            }
                        }
                        else
                        {
                            // Not complete with the handshake yet, write the handshake packet out
                            internalAsyncResult.IsWriteOperation = true;
                            BeginWrite(new byte[0], 0, 0, new AsyncCallback(AsyncHandshakeCallback), internalAsyncResult);
                        }
                    }
                    else
                    {
                        // Read read 0 bytes, the remote socket has been closed, so complete the operation
                        internalAsyncResult.SetComplete(new IOException("The remote stream has been closed"));
                    }
                }
                catch (Exception ex)
                {
                    internalAsyncResult.SetComplete(ex);
                }
            }
        }
Ejemplo n.º 41
0
		/*
		public abstract virtual bool ProcessRenegotiation();

		private IAsyncResult BeginRenegotiate(InternalAsyncResult readwriteAsyncResult)
		{
			Console.WriteLine("BeginRenegotiate");

			handShakeState = HandshakeState.Renegotiate;

			// Wrap the readwriteAsyncResult in the renegotiateAsyncResult
			InternalAsyncResult renegotiateAsyncResult = new InternalAsyncResult(new AsyncCallback(RenegotiateComplete), readwriteAsyncResult, null, 0, 0, readwriteAsyncResult.IsWriteOperation, readwriteAsyncResult.ContinueAfterHandshake);

			if (ProcessRenegotiation())
			{
				handShakeState = HandshakeState.Complete;
				renegotiateAsyncResult.SetComplete();
			}
			else
			{
				//!! if (readwriteAsyncResult.IsWriteOperation)
				if (write_bio.BytesPending > 0)
				{
					renegotiateAsyncResult.IsWriteOperation = true;
					BeginWrite(new byte[0], 0, 0, new AsyncCallback(RenegotiateCallback), renegotiateAsyncResult);
				}
				else
				{
					renegotiateAsyncResult.IsWriteOperation = false;
					BeginRead(new byte[0], 0, 0, new AsyncCallback(RenegotiateCallback), renegotiateAsyncResult);
				}
			}
			return renegotiateAsyncResult;
		}

		private void RenegotiateCallback(IAsyncResult asyncResult)
		{
			InternalAsyncResult renegotiateAsyncResult = asyncResult.AsyncState as InternalAsyncResult;
		}
		*/

		private IAsyncResult BeginHandshake(InternalAsyncResult readwriteAsyncResult)
		{
			//!!
			// Move the handshake state to the next state
			//if (handShakeState == HandshakeState.Renegotiate)
			//{
			//    handShakeState = HandshakeState.RenegotiateInProcess;
			//}
			//else
			if (handShakeState != HandshakeState.Renegotiate)
			{
				handShakeState = HandshakeState.InProcess;
			}

			// Wrap the read/write InternalAsyncResult in the Handshake InternalAsyncResult instance
			InternalAsyncResult handshakeAsyncResult = new InternalAsyncResult(new AsyncCallback(AsyncHandshakeComplete), readwriteAsyncResult, null, 0, 0, readwriteAsyncResult.IsWriteOperation, readwriteAsyncResult.ContinueAfterHandshake);

			if (ProcessHandshake())
			{
				//inHandshakeLoop = false;
				handShakeState = HandshakeState.Complete;
				handshakeAsyncResult.SetComplete();
			}
			else
			{
				//!! if (readwriteAsyncResult.IsWriteOperation)
				if (write_bio.BytesPending > 0)
				{
					handshakeAsyncResult.IsWriteOperation = true;
					BeginWrite(new byte[0], 0, 0, new AsyncCallback(AsyncHandshakeCallback), handshakeAsyncResult);
				}
				else
				{
					handshakeAsyncResult.IsWriteOperation = false;
					BeginRead(new byte[0], 0, 0, new AsyncCallback(AsyncHandshakeCallback), handshakeAsyncResult);
				}
			}
			return handshakeAsyncResult;
		}