public IAsyncResult BeginReceiveRecord(Stream record, AsyncCallback callback, object state) { if (context.ReceivedConnectionEnd) { throw new TlsException(AlertDescription.InternalError, "The session is finished and it's no longer valid."); } record_processing.Reset(); byte[] initialBuffer = new byte[1]; ReceiveRecordAsyncResult receiveRecordAsyncResult = new ReceiveRecordAsyncResult(callback, state, initialBuffer, record); record.BeginRead(receiveRecordAsyncResult.InitialBuffer, 0, receiveRecordAsyncResult.InitialBuffer.Length, InternalReceiveRecordCallback, receiveRecordAsyncResult); return(receiveRecordAsyncResult); }
public byte[] EndReceiveRecord(IAsyncResult asyncResult) { ReceiveRecordAsyncResult receiveRecordAsyncResult = asyncResult as ReceiveRecordAsyncResult; if (receiveRecordAsyncResult == null) { throw new ArgumentException("Either the provided async result is null or was not created by this RecordProtocol."); } if (!receiveRecordAsyncResult.IsCompleted) { receiveRecordAsyncResult.AsyncWaitHandle.WaitOne(); } if (receiveRecordAsyncResult.CompletedWithError) { throw receiveRecordAsyncResult.AsyncException; } byte[] resultingBuffer = receiveRecordAsyncResult.ResultingBuffer; record_processing.Set(); return(resultingBuffer); }
public IAsyncResult BeginReceiveRecord(Stream record, AsyncCallback callback, object state) { if (this.context.ConnectionEnd) { throw new TlsException( AlertDescription.InternalError, "The session is finished and it's no longer valid."); } record_processing.Reset (); byte[] recordTypeBuffer = new byte[1]; ReceiveRecordAsyncResult internalResult = new ReceiveRecordAsyncResult(callback, state, recordTypeBuffer, record); record.BeginRead(internalResult.InitialBuffer, 0, internalResult.InitialBuffer.Length, new AsyncCallback(InternalReceiveRecordCallback), internalResult); return internalResult; }
private void InternalReceiveRecordCallback(IAsyncResult asyncResult) { ReceiveRecordAsyncResult internalResult = asyncResult.AsyncState as ReceiveRecordAsyncResult; Stream record = internalResult.Record; try { int bytesRead = internalResult.Record.EndRead(asyncResult); //We're at the end of the stream. Time to bail. if (bytesRead == 0) { internalResult.SetComplete((byte[])null); return; } // Try to read the Record Content Type int type = internalResult.InitialBuffer[0]; // Set last handshake message received to None this.context.LastHandshakeMsg = HandshakeType.ClientHello; ContentType contentType = (ContentType)type; byte[] buffer = this.ReadRecordBuffer(type, record); if (buffer == null) { // record incomplete (at the moment) internalResult.SetComplete((byte[])null); return; } // Decrypt message contents if needed if (contentType == ContentType.Alert && buffer.Length == 2) { } else if ((this.Context.Read != null) && (this.Context.Read.Cipher != null)) { buffer = this.decryptRecordFragment(contentType, buffer); DebugHelper.WriteLine("Decrypted record data", buffer); } // Process record switch (contentType) { case ContentType.Alert: this.ProcessAlert((AlertLevel)buffer [0], (AlertDescription)buffer [1]); if (record.CanSeek) { // don't reprocess that memory block record.SetLength(0); } buffer = null; break; case ContentType.ChangeCipherSpec: this.ProcessChangeCipherSpec(); break; case ContentType.ApplicationData: break; case ContentType.Handshake: TlsStream message = new TlsStream(buffer); while (!message.EOF) { this.ProcessHandshakeMessage(message); } break; case (ContentType)0x80: this.context.HandshakeMessages.Write(buffer); break; default: throw new TlsException( AlertDescription.UnexpectedMessage, "Unknown record received from server."); } internalResult.SetComplete(buffer); } catch (Exception ex) { internalResult.SetComplete(ex); } }
private void InternalReceiveRecordCallback(IAsyncResult asyncResult) { ReceiveRecordAsyncResult receiveRecordAsyncResult = asyncResult.AsyncState as ReceiveRecordAsyncResult; Stream record = receiveRecordAsyncResult.Record; try { if (receiveRecordAsyncResult.Record.EndRead(asyncResult) == 0) { receiveRecordAsyncResult.SetComplete((byte[])null); } else { int num = receiveRecordAsyncResult.InitialBuffer[0]; context.LastHandshakeMsg = HandshakeType.ClientHello; ContentType contentType = (ContentType)num; byte[] array = ReadRecordBuffer(num, record); if (array == null) { receiveRecordAsyncResult.SetComplete((byte[])null); } else { if ((contentType != ContentType.Alert || array.Length != 2) && Context.Read != null && Context.Read.Cipher != null) { array = decryptRecordFragment(contentType, array); } switch (contentType) { case ContentType.Alert: ProcessAlert((AlertLevel)array[0], (AlertDescription)array[1]); if (record.CanSeek) { record.SetLength(0L); } array = null; break; case ContentType.ChangeCipherSpec: ProcessChangeCipherSpec(); break; case ContentType.Handshake: { TlsStream tlsStream = new TlsStream(array); while (!tlsStream.EOF) { ProcessHandshakeMessage(tlsStream); } break; } case (ContentType)128: context.HandshakeMessages.Write(array); break; default: throw new TlsException(AlertDescription.UnexpectedMessage, "Unknown record received from server."); case ContentType.ApplicationData: break; } receiveRecordAsyncResult.SetComplete(array); } } } catch (Exception complete) { receiveRecordAsyncResult.SetComplete(complete); } }