예제 #1
0
        private void ProcessRecord(DTLSRecord record)
        {
            try
            {
#if DEBUG
                Console.WriteLine(record.RecordType.ToString());
#endif
                switch (record.RecordType)
                {
                case TRecordType.ChangeCipherSpec:
                    if (_ServerEpoch.HasValue)
                    {
                        _ServerEpoch++;
                        _ServerSequenceNumber = 0;
                        _EncyptedServerEpoch  = _ServerEpoch;
                    }
                    break;

                case TRecordType.Alert:
                    AlertRecord alertRecord;
                    try
                    {
                        if ((_Cipher == null) || (!_EncyptedServerEpoch.HasValue))
                        {
                            alertRecord = AlertRecord.Deserialise(record.Fragment);
                        }
                        else
                        {
                            long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                            byte[] data           = _Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length);
                            alertRecord = AlertRecord.Deserialise(data);
                        }
                    }
                    catch
                    {
                        alertRecord = new AlertRecord
                        {
                            AlertLevel = TAlertLevel.Fatal
                        };
                    }
                    if (alertRecord.AlertLevel == TAlertLevel.Fatal)
                    {
                        _Connected.Set();
                        //Terminate
                    }
                    else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify))
                    {
                        if (alertRecord.AlertDescription == TAlertDescription.CloseNotify)
                        {
                            SendAlert(TAlertLevel.Warning, TAlertDescription.CloseNotify);
                            _Connected.Set();
                        }
                        //_Sessions.Remove(session, address);
                    }
                    break;

                case TRecordType.Handshake:
                    ProcessHandshake(record);
                    _ServerSequenceNumber = record.SequenceNumber + 1;
                    break;

                case TRecordType.ApplicationData:
                    if (_Cipher != null)
                    {
                        long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                        byte[] data           = _Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length);
                        DataReceived?.Invoke(record.RemoteEndPoint, data);
                    }
                    _ServerSequenceNumber = record.SequenceNumber + 1;
                    break;

                default:
                    break;
                }
            }
#if DEBUG
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                StackFrame callStack = new StackFrame(1, true);
                Console.WriteLine($"Exception! Type: { ex.GetType()}\n\tData: { ex.Data.Count}\n\tMessage: { ex.Message}\n\tSource: { ex.Source}\n\t" +
                                  $"StackTrace: { ex.StackTrace}\n\tFile: {callStack.GetFileName()}\n\t" +
                                  $"Line: {callStack.GetFileLineNumber()}");
#else
            catch
            {
#endif
            }
        }
예제 #2
0
        private void ProcessRecord(DTLSRecord record)
        {
            try
            {
#if DEBUG
                Console.WriteLine(record.RecordType.ToString());
#endif
                switch (record.RecordType)
                {
                case TRecordType.ChangeCipherSpec:
                    if (_ServerEpoch.HasValue)
                    {
                        _ServerEpoch++;
                        _ServerSequenceNumber = 0;
                        _EncyptedServerEpoch  = _ServerEpoch;
                    }
                    break;

                case TRecordType.Alert:
                    AlertRecord alertRecord;
                    try
                    {
                        if ((_Cipher == null) || (!_EncyptedServerEpoch.HasValue))
                        {
                            alertRecord = AlertRecord.Deserialise(record.Fragment);
                        }
                        else
                        {
                            long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                            byte[] data           = _Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length);
                            alertRecord = AlertRecord.Deserialise(data);
                        }
                    }
                    catch
                    {
                        alertRecord            = new AlertRecord();
                        alertRecord.AlertLevel = TAlertLevel.Fatal;
                    }
                    if (alertRecord.AlertLevel == TAlertLevel.Fatal)
                    {
                        _Connected.Set();
                        //Terminate
                    }
                    else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify))
                    {
                        if (alertRecord.AlertDescription == TAlertDescription.CloseNotify)
                        {
                            SendAlert(TAlertLevel.Warning, TAlertDescription.CloseNotify);
                            _Connected.Set();
                        }
                        //_Sessions.Remove(session, address);
                    }
                    break;

                case TRecordType.Handshake:
                    ProcessHandshake(record);
                    _ServerSequenceNumber = record.SequenceNumber + 1;
                    break;

                case TRecordType.ApplicationData:
                    if (_Cipher != null)
                    {
                        long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                        byte[] data           = _Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length);
                        if (DataReceived != null)
                        {
                            DataReceived(record.RemoteEndPoint, data);
                        }
                    }
                    _ServerSequenceNumber = record.SequenceNumber + 1;
                    break;

                default:
                    break;
                }
            }
#if DEBUG
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
#else
            catch
            {
#endif
            }
        }
예제 #3
0
        private void ProcessRecord(SocketAddress address, Session session, DTLSRecord record)
        {
            try
            {
#if DEBUG
                Console.WriteLine(record.RecordType.ToString());
#endif
                switch (record.RecordType)
                {
                case TRecordType.ChangeCipherSpec:
                    if (session != null)
                    {
                        session.ClientEpoch++;
                        session.ClientSequenceNumber = 0;
                        session.SetEncyptChange(record);
                    }
                    break;

                case TRecordType.Alert:
                    if (session != null)
                    {
                        AlertRecord alertRecord;
                        try
                        {
                            if (session.Cipher == null)
                            {
                                alertRecord = AlertRecord.Deserialise(record.Fragment);
                            }
                            else
                            {
                                long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                                byte[] data           = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length);
                                alertRecord = AlertRecord.Deserialise(data);
                            }
                        }
                        catch
                        {
                            alertRecord            = new AlertRecord();
                            alertRecord.AlertLevel = TAlertLevel.Fatal;
                        }
                        if (alertRecord.AlertLevel == TAlertLevel.Fatal)
                        {
                            _Sessions.Remove(session, address);
                        }
                        else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify))
                        {
                            if (alertRecord.AlertDescription == TAlertDescription.CloseNotify)
                            {
                                SendAlert(session, address, TAlertLevel.Warning, TAlertDescription.CloseNotify);
                            }
                            _Sessions.Remove(session, address);
                        }
                    }
                    break;

                case TRecordType.Handshake:
                    _Handshake.ProcessHandshake(record);
                    break;

                case TRecordType.ApplicationData:
                    if (session != null)
                    {
                        if (session.Cipher != null)
                        {
                            long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                            byte[] data           = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length);
                            if (DataReceived != null)
                            {
                                DataReceived(record.RemoteEndPoint, data);
                            }
                        }
                    }
                    break;

                default:
                    break;
                }
            }
#if DEBUG
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
#else
            catch
            {
#endif
                SendAlert(session, address, TAlertLevel.Fatal, TAlertDescription.InternalError);
            }
        }
예제 #4
0
        private async Task _ProcessRecordAsync(DTLSRecord record)
        {
            try
            {
                if (record == null)
                {
                    throw new ArgumentNullException(nameof(record));
                }

                switch (record.RecordType)
                {
                case TRecordType.ChangeCipherSpec:
                {
                    this._ReceivedData = new byte[0];
                    if (this._ServerEpoch.HasValue)
                    {
                        this._ServerEpoch++;
                        this._ServerSequenceNumber = 0;
                        this._EncyptedServerEpoch  = this._ServerEpoch;
                    }
                    break;
                }

                case TRecordType.Alert:
                {
                    this._ReceivedData = new byte[0];
                    AlertRecord alertRecord;
                    try
                    {
                        if ((this._Cipher == null) || (!this._EncyptedServerEpoch.HasValue))
                        {
                            alertRecord = AlertRecord.Deserialise(record.Fragment);
                        }
                        else
                        {
                            var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                            var data           = this._Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length);
                            alertRecord = AlertRecord.Deserialise(data);
                        }
                    }
                    catch
                    {
                        alertRecord = new AlertRecord
                        {
                            AlertLevel = TAlertLevel.Fatal
                        };
                    }
                    if (alertRecord.AlertLevel == TAlertLevel.Fatal)
                    {
                        this._ConnectionComplete = true;
                    }
                    else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify))
                    {
                        if (alertRecord.AlertDescription == TAlertDescription.CloseNotify)
                        {
                            await this._SendAlertAsync(TAlertLevel.Warning, TAlertDescription.CloseNotify).ConfigureAwait(false);

                            this._ConnectionComplete = true;
                        }
                    }
                    break;
                }

                case TRecordType.Handshake:
                {
                    this._ReceivedData = new byte[0];
                    await this._ProcessHandshakeAsync(record).ConfigureAwait(false);

                    this._ServerSequenceNumber = record.SequenceNumber + 1;
                    break;
                }

                case TRecordType.ApplicationData:
                {
                    if (this._Cipher != null)
                    {
                        var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                        var data           = this._Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length);
                        this._DataReceivedFunction?.Invoke(record.RemoteEndPoint, data);
                        this._ReceivedData = data;
                    }
                    this._ServerSequenceNumber = record.SequenceNumber + 1;
                    break;
                }

                default:
                    break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
예제 #5
0
        private void ProcessRecord(SocketAddress address, Session session, DTLSRecord record)
        {
            try
            {
#if DEBUG
                Console.WriteLine($"> RecordType={record.RecordType.ToString()} sessionID={session?.SessionID} remoteEndPoint={record?.RemoteEndPoint}");
                Console.Write($"Data: {TLSUtils.WriteToString(record?.Fragment)}");
#endif
                switch (record.RecordType)
                {
                case TRecordType.ChangeCipherSpec:
                    if (session != null)
                    {
                        session.ClientEpoch++;
                        session.ClientSequenceNumber = 0;
                        session.SetEncyptChange(record);
                    }
                    break;

                case TRecordType.Alert:
                    if (session != null)
                    {
                        AlertRecord alertRecord;
                        try
                        {
                            if (session.Cipher == null)
                            {
                                alertRecord = AlertRecord.Deserialise(record.Fragment);
                            }
                            else
                            {
                                long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                                byte[] data           = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.Alert, record.Fragment, 0, record.Fragment.Length);
                                alertRecord = AlertRecord.Deserialise(data);
                            }
                        }
                        catch
                        {
                            alertRecord = new AlertRecord
                            {
                                AlertLevel = TAlertLevel.Fatal
                            };
                        }
                        if (alertRecord.AlertLevel == TAlertLevel.Fatal)
                        {
                            _Sessions.Remove(session, address);
                        }
                        else if ((alertRecord.AlertLevel == TAlertLevel.Warning) || (alertRecord.AlertDescription == TAlertDescription.CloseNotify))
                        {
                            if (alertRecord.AlertDescription == TAlertDescription.CloseNotify)
                            {
                                SendAlert(session, address, TAlertLevel.Warning, TAlertDescription.CloseNotify);
                            }
                            _Sessions.Remove(session, address);
                        }
                    }
                    break;

                case TRecordType.Handshake:
                    _Handshake.ProcessHandshake(record);
                    break;

                case TRecordType.ApplicationData:
                    if (session != null)
                    {
                        if (session.Cipher != null)
                        {
                            long   sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber;
                            byte[] data           = session.Cipher.DecodeCiphertext(sequenceNumber, (byte)TRecordType.ApplicationData, record.Fragment, 0, record.Fragment.Length);
                            DataReceived?.Invoke(record.RemoteEndPoint, data);
                        }
                    }
                    break;

                default:
                    break;
                }
            }
#if DEBUG
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                StackFrame callStack = new StackFrame(1, true);
                Console.WriteLine($"Exception! Type: { ex.GetType()}\n\tData: { ex.Data.Count}\n\tMessage: { ex.Message}\n\tSource: { ex.Source}\n\t" +
                                  $"StackTrace: { ex.StackTrace}\n\tFile: {callStack.GetFileName()}\n\t" +
                                  $"Line: {callStack.GetFileLineNumber()}");
#else
            catch
            {
#endif
                SendAlert(session, address, TAlertLevel.Fatal, TAlertDescription.InternalError);
            }
        }