public void TestByte() { _writer.Write((byte)0xFE); _writer.Write((byte)0xFA); Assert.Equal <byte[]>(new byte[] { 0xFE, 0xFA }, _writer.ToBytes()); }
/// <summary> /// Sends an auxiliary chunk. /// </summary> /// <returns>The async.</returns> /// <param name="bytes">Plaintext bytes.</param> public async Task SendAsync(byte[] bytes) { logger.LogTrace($"Sending auxiliary stream buffer: {bytes.Length} bytes"); var writer = new EndianWriter(); writer.Write(new byte[] { 0xde, 0xad }); writer.WriteBE((ushort)bytes.Length); writer.Write(_cryptoContext.Encrypt(bytes)); writer.Write(_cryptoContext.CalculateMessageSignature(writer.ToBytes())); var buffer = writer.ToBytes(); await _client.GetStream().WriteAsync(buffer, 0, buffer.Length); }
private byte[] AssembleMessage(IMessage message) { var writer = new EndianWriter(); message.Serialize(writer); return(writer.ToBytes()); }
private byte[] AssembleSessionMessage(SessionMessageBase message, uint sequenceNumber, uint sourceParticipantId, uint targetParticipantId = 0) { var fragment = new SessionFragmentMessage(); fragment.Header.IsFragment = message.Header.IsFragment; fragment.Header.ChannelId = message.Header.ChannelId; fragment.Header.RequestAcknowledge = message.Header.RequestAcknowledge; fragment.Header.SessionMessageType = message.Header.SessionMessageType; fragment.Header.Version = message.Header.Version; fragment.Header.SequenceNumber = sequenceNumber; fragment.Header.SourceParticipantId = sourceParticipantId; fragment.Header.TargetParticipantId = targetParticipantId; var writer = new EndianWriter(); message.Serialize(writer); fragment.Fragment = writer.ToBytes(); ((ICryptoMessage)fragment).Crypto = _crypto; var finalWriter = new EndianWriter(); fragment.Serialize(finalWriter); return(finalWriter.ToBytes()); }
/// <summary> /// Sends a packet /// </summary> /// <returns>The send task.</returns> /// <param name="message">SmartGlass SimpleMessage to sent</param> public async Task SendAsync(IMessage message) { var cryptoMessage = message as ICryptoMessage; if (cryptoMessage != null) { cryptoMessage.Crypto = _crypto; } var writer = new EndianWriter(); message.Serialize(writer); var serialized = writer.ToBytes(); if (_addressOrHostname == null) { await _client.SendAsync(serialized, serialized.Length, new IPEndPoint(IPAddress.Broadcast, 5050)); await _client.SendAsync(serialized, serialized.Length, new IPEndPoint(MULTICAST_ADDR, 5050)); } else { await _client.SendAsync(serialized, serialized.Length); } }
public override void Serialize(EndianWriter writer) { var messageWriter = new EndianWriter(); base.Serialize(messageWriter); var message = messageWriter.ToBytes(); var initVectorSource = message.Take(16).ToArray(); var initVector = Crypto.CreateDerivedInitVector(initVectorSource); var fragmentWriter = new EndianWriter(); byte[] padding = Padding.CreatePaddingData( PaddingType.PKCS7, Fragment, alignment: payloadSizeAlignment ); fragmentWriter.Write(Fragment); fragmentWriter.Write(padding); var encryptedFragment = Crypto.EncryptWithoutPadding(fragmentWriter.ToBytes(), initVector); Header.Serialize(writer); writer.Write(encryptedFragment); var signature = Crypto.CalculateMessageSignature(writer.ToBytes()); writer.Write(signature); }
public SessionMessageBase AssembleFragment(SessionMessageBase message, uint sequenceNumber) { FragmentMessage fragment = message as FragmentMessage; SessionMessageType messageType = fragment.Header.SessionMessageType; int sequenceBegin = (int)fragment.SequenceBegin; int sequenceEnd = (int)fragment.SequenceEnd; _fragmentQueue[(int)sequenceNumber] = fragment.Data; IEnumerable <int> neededSequences = Enumerable.Range(sequenceBegin, sequenceEnd - sequenceBegin); foreach (var seq in neededSequences) { if (!_fragmentQueue.ContainsKey(seq)) { return(null); } } EndianWriter writer = new EndianWriter(); foreach (int seq in neededSequences) { byte[] data = _fragmentQueue[seq]; writer.Write(data); _fragmentQueue.Remove(seq); } SessionMessageBase assembled = SessionMessageTransport.CreateFromMessageType(messageType); assembled.Deserialize(new EndianReader(writer.ToBytes())); return(assembled); }
public override void Serialize(EndianWriter writer) { var protectedPayloadWriter = new EndianWriter(); SerializeProtectedPayload(protectedPayloadWriter); // length is before padding Header.ProtectedPayloadLength = (ushort)protectedPayloadWriter.Length; // padding is before encryption byte[] padding = Padding.CreatePaddingData( PaddingType.PKCS7, protectedPayloadWriter.Length, alignment: payloadSizeAlignment ); protectedPayloadWriter.Write(padding); // encrypt without adding padding to the encrypted value var encryptedPayload = Crypto.EncryptWithoutPadding(protectedPayloadWriter.ToBytes(), InitVector); base.Serialize(writer); writer.Write(encryptedPayload); var signature = Crypto.CalculateMessageSignature(writer.ToBytes()); writer.Write(signature); }
public virtual void Serialize(EndianWriter writer) { var payloadWriter = new EndianWriter(); SerializePayload(payloadWriter); var payload = payloadWriter.ToBytes(); Header.PayloadLength = (ushort)payload.Length; Header.Serialize(writer); writer.Write(payload); }
public void Serialize(EndianWriter writer) { // Write out payload first to get its size EndianWriter tmpWriter = new EndianWriter(); SerializeStreamer(tmpWriter); byte[] streamerData = tmpWriter.ToBytes(); StreamerSize = (uint)streamerData.Length; StreamerHeader.Serialize(writer); writer.WriteLE(StreamerSize); writer.Write(streamerData); }
public static byte[] AssemblePacket(INanoPacket packet, NanoChannelContext context) { if (packet.Channel == NanoChannel.Unknown) { throw new NanoPackingException("AssemblePacket: INanoPacket.Channel is UNKNOWN"); } // Serialize payload and append padding if needed byte[] payloadData = null; using (EndianWriter payloadWriter = new EndianWriter()) { packet.Serialize(payloadWriter); byte[] padding = Padding.CreatePaddingData( PaddingType.ANSI_X923, payloadWriter.ToBytes(), alignment: 4); // Append padding if (padding.Length > 0) { payloadWriter.Write(padding); packet.Header.Padding = true; } payloadData = payloadWriter.ToBytes(); } EndianWriter packetWriter = new EndianWriter(); packet.Header.ChannelId = context.GetChannelId(packet.Channel); // Serialize header packet.Header.Serialize(packetWriter); // Append payload to header packetWriter.Write(payloadData); return(packetWriter.ToBytes()); }
private Task SendFragmentAsync(SessionMessageBase message, uint sequenceNumber) { var fragment = new SessionFragmentMessage(); fragment.Header.ChannelId = message.Header.ChannelId; fragment.Header.RequestAcknowledge = message.Header.RequestAcknowledge; fragment.Header.SessionMessageType = message.Header.SessionMessageType; fragment.Header.Version = message.Header.Version; fragment.Header.SequenceNumber = sequenceNumber; fragment.Header.SourceParticipantId = _participantId; var writer = new EndianWriter(); message.Serialize(writer); fragment.Fragment = writer.ToBytes(); return(_transport.SendAsync(fragment)); }
public override void Serialize(EndianWriter writer) { var protectedPayloadWriter = new EndianWriter(); SerializeProtectedPayload(protectedPayloadWriter); var protectedPayload = protectedPayloadWriter.ToBytes(); Header.ProtectedPayloadLength = (ushort)protectedPayload.Length; var encryptedPayload = protectedPayload.Length > 0 ? Crypto.Encrypt(protectedPayload, InitVector) : new byte[] { }; base.Serialize(writer); writer.Write(encryptedPayload); var signature = Crypto.CalculateMessageSignature(writer.ToBytes()); writer.Write(signature); }
/// <summary> /// Reads and decrypts auxiliary channel chunk. /// </summary> /// <returns>Decrypted chunk.</returns> /// <param name="stream">Stream.</param> private byte[] ReadAndDecryptChunk(Stream stream) { var reader = new EndianReader(stream); // 0xde, 0xad reader.ReadBytes(2); var length = reader.ReadUInt16BE(); var encryptedPayloadLength = length + Padding.CalculatePaddingSize(length, 16); var encryptedPayloadBytes = new byte[encryptedPayloadLength]; var encryptedPayloadPosition = 0; while (encryptedPayloadPosition < encryptedPayloadLength - 1) { var received = reader.ReadBytes(encryptedPayloadLength - encryptedPayloadPosition); received.CopyTo(encryptedPayloadBytes, encryptedPayloadPosition); encryptedPayloadPosition += received.Length; } var signature = reader.ReadBytes(32); var bodyWriter = new EndianWriter(); bodyWriter.Write(new byte[] { 0xde, 0xad }); bodyWriter.WriteBE(length); bodyWriter.Write(encryptedPayloadBytes); var messageSignature = _cryptoContext.CalculateMessageSignature(bodyWriter.ToBytes()); if (!signature.SequenceEqual(messageSignature)) { throw new InvalidDataException("Invalid message signature."); } var decryptedPayload = _cryptoContext.Decrypt(encryptedPayloadBytes); return(decryptedPayload.Take(length).ToArray()); }
/// <summary> /// Encrypt the specified data. /// </summary> /// <returns>The encrypted data</returns> /// <param name="data">Encrypted data.</param> public byte[] Encrypt(byte[] data) { var writer = new EndianWriter(); byte[] padding = Padding.CreatePaddingData( PaddingType.PKCS7, data, alignment: 16); writer.Write(data); writer.Write(padding); var paddedData = writer.ToBytes(); var output = new byte[paddedData.Length]; for (var i = 0; i < paddedData.Length; i += 16) { _clientCipher.ProcessBlock(paddedData, i, output, i); } return(output); }
/// <summary> /// Generates the connect request. /// Either returns a single ConnectRequest if no authorization data is /// provided or more-than-one if authorization data is provided. /// </summary> /// <returns>An Enumerable of connect requests.</returns> /// <param name="deviceId">Client device Id.</param> /// <param name="xboxLiveUserHash">Xbox live user hash.</param> /// <param name="xboxLiveAuthorization">Xbox live authorization token (XToken).</param> /// <param name="initialSequenceNumber">Initial sequence number.</param> public static IEnumerable <ConnectRequestMessage> GenerateConnectRequest( Guid deviceId, CryptoContext crypto, string xboxLiveUserHash, string xboxLiveAuthorization, int initialSequenceNumber = 0) { var requests = new List <ConnectRequestMessage>(); /* * Get size of anonymous ConnectRequest to calculate * available space for authentication data */ var anonymousRequest = GenerateAnonymousRequest(deviceId, crypto, initialSequenceNumber); EndianWriter bw = new EndianWriter(); ((ICryptoMessage)anonymousRequest).Crypto = crypto; anonymousRequest.Serialize(bw); var connectRequestSize = bw.ToBytes().Length; if (String.IsNullOrEmpty(xboxLiveAuthorization) || String.IsNullOrEmpty(xboxLiveUserHash)) { // Incomplete authoritzation data // Return anonymous connect request requests.Add(anonymousRequest); return(requests); } var authenticationStringLength = xboxLiveUserHash.Length + xboxLiveAuthorization.Length; var maxStringSize = 1024 - connectRequestSize; var fragmentCount = authenticationStringLength / maxStringSize; if ((authenticationStringLength % maxStringSize) > 0) { fragmentCount++; } if (fragmentCount <= 1) { throw new InvalidOperationException( "Authentication data too small to fragment"); } var xtokenPosition = 0; for (int fragment = 0; fragment < fragmentCount; fragment++) { var availableBytes = maxStringSize; var currentUserhash = String.Empty; var currentXToken = String.Empty; if (fragment == 0) { // Userhash fits in first fragment currentUserhash = xboxLiveUserHash; availableBytes -= currentUserhash.Length; } var xtokenCopyLength = availableBytes > (xboxLiveAuthorization.Length - xtokenPosition) ? xboxLiveAuthorization.Length - xtokenPosition : availableBytes; currentXToken = xboxLiveAuthorization.Substring(xtokenPosition, xtokenCopyLength); xtokenPosition += currentXToken.Length; var requestFragment = new ConnectRequestMessage() { InitVector = SmartGlass.Connection.CryptoContext.GenerateRandomInitVector(), DeviceId = deviceId, UserHash = currentUserhash, Authorization = currentXToken, SequenceNumber = (uint)(initialSequenceNumber + fragment), SequenceBegin = (uint)initialSequenceNumber, SequenceEnd = (uint)(initialSequenceNumber + fragmentCount) }; requests.Add(requestFragment); } return(requests); }