Exemplo n.º 1
0
        private void SendHandshakeCallback(IAsyncResult asyncResult)
        {
            AsyncHandshakeResult asyncHandshakeResult = (AsyncHandshakeResult)asyncResult.AsyncState;

            try {
                _recordStream.EndSend(asyncResult);
                lock (_handshakeLock) {
                    if (_isAuthenticated && !_isHandshaking)
                    {
                        // Mark send result as complete
                        asyncHandshakeResult.SetComplete();
                        return;
                    }
                }

                // Handshake not finished yet, continue performing
                ProcessSendHandshakePacket(asyncHandshakeResult);
            } catch (AlertException ae) {
                ProcessSendFatalAlert(new Alert(ae.AlertDescription, _handshakeSession.NegotiatedVersion));
                asyncHandshakeResult.SetComplete(new Exception("Connection closed because of local alert", ae));
            } catch (IOException) {
                asyncHandshakeResult.SetComplete(new EndOfStreamException("Connection closed unexpectedly"));
            } catch (Exception e) {
                ProcessSendFatalAlert(new Alert(AlertDescription.InternalError, _handshakeSession.NegotiatedVersion));
                asyncHandshakeResult.SetComplete(new Exception("Connection closed because of local error", e));
            }
        }
Exemplo n.º 2
0
 private void ProcessSendHandshakePacket(AsyncHandshakeResult asyncHandshakeResult)
 {
     HandshakeMessage[] messages = _handshakeSession.GetOutputMessages();
     Record[]           records  = _handshakePacketizer.ProcessHandshakeMessages(_handshakeSession.NegotiatedVersion, messages, _recordStream.MaximumFragmentLength);
     if (records.Length > 0)
     {
         // Encrypt the handshake records
         for (int i = 0; i < records.Length; i++)
         {
             _recordHandler.ProcessOutputRecord(records[i]);
         }
         _recordStream.BeginSend(records, new AsyncCallback(SendHandshakeCallback), asyncHandshakeResult);
     }
     else
     {
         if (_handshakeSession.State == HandshakeState.Finished)
         {
             // Handshake finished, mark result as complete
             asyncHandshakeResult.SetComplete();
         }
         else if (_handshakeSession.State == HandshakeState.SendChangeCipherSpec)
         {
             ProcessSendChangeCipherSpec(asyncHandshakeResult);
         }
         else
         {
             // Handshake not finished, receive the next handshake packet
             _recordStream.BeginReceive(new AsyncCallback(ReceiveHandshakeCallback), asyncHandshakeResult);
         }
     }
 }
Exemplo n.º 3
0
 private void ProcessSendHandshakePacket(AsyncHandshakeResult asyncHandshakeResult)
 {
     HandshakeMessage[] messages = _handshakeSession.GetOutputMessages();
     Record[] records = _handshakePacketizer.ProcessHandshakeMessages(_handshakeSession.NegotiatedVersion, messages, _recordStream.MaximumFragmentLength);
     if (records.Length > 0) {
         // Encrypt the handshake records
         for (int i=0; i<records.Length; i++) {
             _recordHandler.ProcessOutputRecord(records[i]);
         }
         _recordStream.BeginSend(records, new AsyncCallback(SendHandshakeCallback), asyncHandshakeResult);
     } else {
         if (_handshakeSession.State == HandshakeState.Finished) {
             // Handshake finished, mark result as complete
             asyncHandshakeResult.SetComplete();
         } else if (_handshakeSession.State == HandshakeState.SendChangeCipherSpec) {
             ProcessSendChangeCipherSpec(asyncHandshakeResult);
         } else {
             // Handshake not finished, receive the next handshake packet
             _recordStream.BeginReceive(new AsyncCallback(ReceiveHandshakeCallback), asyncHandshakeResult);
         }
     }
 }
Exemplo n.º 4
0
        private void ReceiveHandshakeCallback(IAsyncResult asyncResult)
        {
            AsyncHandshakeResult asyncHandshakeResult = (AsyncHandshakeResult)asyncResult.AsyncState;

            try {
                Record[] records = _recordStream.EndReceive(asyncResult);
                for (int i = 0; i < records.Length; i++)
                {
                    Record record = records[i];
                    if (!_recordHandler.ProcessInputRecord(record))
                    {
                        // Ignore records from invalid epoch
                        continue;
                    }

                    lock (_handshakeLock) {
                        if (!_isAuthenticated && record.Type == RecordType.Data)
                        {
                            // Refuse data packets before authentication
                            throw new AlertException(AlertDescription.UnexpectedMessage,
                                                     "Data packet received before handshake");
                        }
                        if (!_isHandshaking && (record.Type == RecordType.ChangeCipherSpec || record.Type == RecordType.Handshake))
                        {
                            // Refuse ChangeCipherSpec and Handshake packets if not handshaking
                            // TODO: Should handle HelloRequest if renegotiation is supported
                            throw new AlertException(AlertDescription.UnexpectedMessage,
                                                     "Handshake packet received outside handshake");
                        }
                        if (_isHandshaking && record.Type == RecordType.Data)
                        {
                            // Queue data packets during new handshake to avoid sync problems
                            // TODO: Should handle the data correctly if renegotiation is supported
                            throw new AlertException(AlertDescription.UnexpectedMessage,
                                                     "Received a data packet during handshake");
                        }
                    }

                    switch (record.Type)
                    {
                    case RecordType.ChangeCipherSpec:
                        ProcessChangeCipherSpecRecord(record, asyncHandshakeResult);
                        break;

                    case RecordType.Alert:
                        ProcessAlertRecord(record, asyncHandshakeResult);
                        break;

                    case RecordType.Handshake:
                        ProcessHandshakeRecord(record, asyncHandshakeResult);
                        break;

                    case RecordType.Data:
                        // TODO: Implement this properly if renegotiation is supported
                        break;

                    default:
                        ProcessUnknownRecord(record, asyncHandshakeResult);
                        break;
                    }
                }
            } catch (AlertException ae) {
                ProcessSendFatalAlert(new Alert(ae.AlertDescription, _handshakeSession.NegotiatedVersion));
                asyncHandshakeResult.SetComplete(new Exception("Connection closed because of local alert", ae));
            } catch (IOException) {
                asyncHandshakeResult.SetComplete(new EndOfStreamException("Connection closed unexpectedly"));
            } catch (Exception e) {
                ProcessSendFatalAlert(new Alert(AlertDescription.InternalError, _handshakeSession.NegotiatedVersion));
                asyncHandshakeResult.SetComplete(new Exception("Connection closed because of local error", e));
            }
        }