private DTLSRecord CreateRecord(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Handshake; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; if (session.Version != null) { record.Version = session.Version; } HandshakeRecord handshakeRecord = new HandshakeRecord(); handshakeRecord.MessageType = handshakeMessage.MessageType; handshakeRecord.MessageSeq = messageSequence; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); } return(record); }
private void SendResponseEnd(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = CreateRecord(session, handshakeMessage, messageSequence); session.Handshake.MessageSequence++; DTLSRecord recordEnd = CreateRecord(session, new ServerHelloDone(), session.Handshake.MessageSequence); session.Handshake.MessageSequence++; int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length + DTLSRecord.RECORD_OVERHEAD + recordEnd.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); recordEnd.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendHandshakeMessage(IHandshakeMessage handshakeMessage, bool encrypt) { int size = handshakeMessage.CalculateSize(_Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = _Epoch, SequenceNumber = NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size] }; if (_Version != null) { record.Version = _Version; } HandshakeRecord handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = _MessageSequence }; _MessageSequence++; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, _Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { _HandshakeInfo.UpdateHandshakeHash(record.Fragment); } int responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if ((_Cipher != null) && encrypt) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = _Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = _ServerEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendResponse(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Handshake; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; if (session.Version != null) { record.Version = session.Version; } HandshakeRecord handshakeRecord = new HandshakeRecord(); handshakeRecord.MessageType = handshakeMessage.MessageType; handshakeRecord.MessageSeq = messageSequence; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } int responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private DTLSRecord CreateRecord(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (handshakeMessage == null) { throw new ArgumentNullException(nameof(handshakeMessage)); } var size = handshakeMessage.CalculateSize(session.Version); var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = session.Epoch, SequenceNumber = session.NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size] }; if (session.Version != null) { record.Version = session.Version; } var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = messageSequence, Length = (uint)size, FragmentLength = (uint)size }; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } if (session.Cipher != null) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); } return(record); }
private void SendResponseEnd(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (handshakeMessage == null) { throw new ArgumentNullException(nameof(handshakeMessage)); } var size = handshakeMessage.CalculateSize(session.Version); var maxPayloadSize = this._MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { //fragments return; } var record = this.CreateRecord(session, handshakeMessage, messageSequence); session.Handshake.MessageSequence++; var recordEnd = this.CreateRecord(session, new ServerHelloDone(), session.Handshake.MessageSequence); session.Handshake.MessageSequence++; var responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length + DTLSRecord.RECORD_OVERHEAD + recordEnd.Fragment.Length; var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); recordEnd.Serialise(stream); } var parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); this._Socket.SendToAsync(parameters); }
private IEnumerable <byte[]> _GetBytes(IHandshakeMessage handshakeMessage, bool encrypt) { if (handshakeMessage == null) { throw new ArgumentNullException(nameof(handshakeMessage)); } var size = handshakeMessage.CalculateSize(this._Version); var maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { var wholeMessage = new List <byte[]>(); var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = _Epoch, Version = this._Version }; var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = _MessageSequence }; if (!(handshakeMessage.MessageType == THandshakeType.HelloVerifyRequest || (handshakeMessage.MessageType == THandshakeType.ClientHello && (handshakeMessage as ClientHello).Cookie == null))) { record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; handshakeRecord.FragmentOffset = 0u; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, this._Version); } this._HandshakeInfo.UpdateHandshakeHash(record.Fragment); } var dataMessage = new byte[size]; using (var stream = new MemoryStream(dataMessage)) { handshakeMessage.Serialise(stream, this._Version); } var dataMessageFragments = dataMessage.ChunkBySize(maxPayloadSize); handshakeRecord.FragmentOffset = 0U; dataMessageFragments.ForEach(x => { handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)x.Count(); record.SequenceNumber = this._NextSequenceNumber(); var baseMessage = new byte[HandshakeRecord.RECORD_OVERHEAD]; using (var stream = new MemoryStream(baseMessage)) { handshakeRecord.Serialise(stream); } record.Fragment = baseMessage.Concat(x).ToArray(); var responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + x.Count(); if ((this._Cipher != null) && encrypt) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = this._Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } wholeMessage.Add(response); handshakeRecord.FragmentOffset += (uint)x.Count(); }); this._MessageSequence++; return(wholeMessage); } else { var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = _Epoch, SequenceNumber = this._NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size], Version = this._Version }; var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = _MessageSequence }; this._MessageSequence++; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, this._Version); } if (!(handshakeMessage.MessageType == THandshakeType.HelloVerifyRequest || (handshakeMessage.MessageType == THandshakeType.ClientHello && (handshakeMessage as ClientHello).Cookie == null))) { this._HandshakeInfo.UpdateHandshakeHash(record.Fragment); } var responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if ((this._Cipher != null) && encrypt) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = this._Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } return(new List <byte[]>() { response }); } }
private DTLSRecord CreateRecord(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Handshake; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; if (session.Version != null) record.Version = session.Version; HandshakeRecord handshakeRecord = new HandshakeRecord(); handshakeRecord.MessageType = handshakeMessage.MessageType; handshakeRecord.MessageSeq = messageSequence; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); } return record; }
private void SendResponseEnd(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = CreateRecord(session, handshakeMessage, messageSequence); session.Handshake.MessageSequence++; DTLSRecord recordEnd = CreateRecord(session, new ServerHelloDone(), session.Handshake.MessageSequence); session.Handshake.MessageSequence++; int responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length + DTLSRecord.RECORD_OVERHEAD + recordEnd.Fragment.Length; byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); recordEnd.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendResponse(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { int size = handshakeMessage.CalculateSize(session.Version); int maxPayloadSize = _MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { } else { DTLSRecord record = new DTLSRecord(); record.RecordType = TRecordType.Handshake; record.Epoch = session.Epoch; record.SequenceNumber = session.NextSequenceNumber(); record.Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size]; if (session.Version != null) record.Version = session.Version; HandshakeRecord handshakeRecord = new HandshakeRecord(); handshakeRecord.MessageType = handshakeMessage.MessageType; handshakeRecord.MessageSeq = messageSequence; handshakeRecord.Length = (uint)size; handshakeRecord.FragmentLength = (uint)size; using (MemoryStream stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } int responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if (session.Cipher != null) { long sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } byte[] response = new byte[responseSize]; using (MemoryStream stream = new MemoryStream(response)) { record.Serialise(stream); } SocketAsyncEventArgs parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); _Socket.SendToAsync(parameters); } }
private void SendResponse(Session session, IHandshakeMessage handshakeMessage, ushort messageSequence) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (handshakeMessage == null) { throw new ArgumentNullException(nameof(handshakeMessage)); } var size = handshakeMessage.CalculateSize(session.Version); var maxPayloadSize = this._MaxPacketSize - DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD; if (size > maxPayloadSize) { //fragments return; } var record = new DTLSRecord { RecordType = TRecordType.Handshake, Epoch = session.Epoch, SequenceNumber = session.NextSequenceNumber(), Fragment = new byte[HandshakeRecord.RECORD_OVERHEAD + size] }; if (session.Version != null) { record.Version = session.Version; } var handshakeRecord = new HandshakeRecord { MessageType = handshakeMessage.MessageType, MessageSeq = messageSequence, Length = (uint)size, FragmentLength = (uint)size }; using (var stream = new MemoryStream(record.Fragment)) { handshakeRecord.Serialise(stream); handshakeMessage.Serialise(stream, session.Version); } if (handshakeMessage.MessageType != THandshakeType.HelloVerifyRequest) { session.Handshake.UpdateHandshakeHash(record.Fragment); } var responseSize = DTLSRecord.RECORD_OVERHEAD + HandshakeRecord.RECORD_OVERHEAD + size; if (session.Cipher != null) { var sequenceNumber = ((long)record.Epoch << 48) + record.SequenceNumber; record.Fragment = session.Cipher.EncodePlaintext(sequenceNumber, (byte)TRecordType.Handshake, record.Fragment, 0, record.Fragment.Length); responseSize = DTLSRecord.RECORD_OVERHEAD + record.Fragment.Length; } var response = new byte[responseSize]; using (var stream = new MemoryStream(response)) { record.Serialise(stream); } var parameters = new SocketAsyncEventArgs() { RemoteEndPoint = session.RemoteEndPoint }; parameters.SetBuffer(response, 0, responseSize); this._Socket.SendToAsync(parameters); }