/// <summary> /// Serializes the message into a binary format. /// </summary> /// <returns></returns> internal byte[] Serialize(MessageClientBase messageClient, string clientName, EncryptionOption encryptionOption) { var formatter = new BinaryFormatter(); byte[] data; using (MemoryStream stream = new MemoryStream()) { formatter.Serialize(stream, this); stream.Seek(0, SeekOrigin.Begin); data = new byte[stream.Length]; if (stream.Read(data, 0, data.Length) != data.Length) { throw new Exception(); } } byte[] iv = null; MessageSerializationWrapper header; if (encryptionOption == EncryptionOption.EncryptWithPrivateKey) { (data, iv) = messageClient.EncryptDataWithClientKey(data, clientName); } else if (encryptionOption == EncryptionOption.EncryptWithSystemSharedKey) { (data, iv) = messageClient.EncryptDataWithSystemSharedKey(data); } byte[] signature = messageClient.SignData(data); if (encryptionOption != EncryptionOption.None) { header = new MessageSerializationWrapper(signature, iv, encryptionOption); } else { header = new MessageSerializationWrapper(signature); } byte[] output = new byte[header.Length + data.Length]; header.CopyTo(output, 0); data.CopyTo(output, header.Length); return(output); }
/// <summary> /// /// </summary> /// <returns></returns> /// <remarks> /// Message Wrapper Format: /// /// [ Info Bits ][ Info Numbers ][ Timestamp ][ Sender Name ][ IV - Optional][ Serialized Message (encryption optional)][ Signature ] /// [ Signature based on this data ] /// /// </remarks> public byte[] Serialize() { int index = 0; byte[] senderBytes = Encoding.UTF8.GetBytes(SenderIdentityHash); byte[] iv = Array.Empty <byte>(); int sharedKeyId = 0; var messageBytes = Message.Serialize(); // Add encryption, if required; if (this._encryptionOption == EncryptionOption.EncryptWithPrivateKey) { (messageBytes, iv) = this._messageClient.EncryptDataWithClientKey(messageBytes, this.RecipientIdentityHash); } else if (this._encryptionOption == EncryptionOption.EncryptWithSystemSharedKey) { (messageBytes, iv, sharedKeyId) = this._messageClient.EncryptDataWithSystemSharedKey(messageBytes, this.Timestamp); } int totalBufferSize = 8 + sizeof(long) + senderBytes.Length + messageBytes.Length + iv.Length + _messageClient.SignatureLength; byte[] bytes = new byte[totalBufferSize]; // Load bits; var bits = new BitVector32(0); //bits[isClientAnnounceMask] = this.Message.GetType() == typeof(ClientAnnounceMessage); //bits[isClientAnnounceResponseMask] = false; //this.Message.GetType() == typeof(ClientAnnounceResponseMessage); BitConverter.GetBytes(bits.Data).CopyTo(bytes, index); index += 4; // Load numbers var numbers = new BitVector32(0); numbers[signatureLengthSection] = _messageClient.SignatureLength; numbers[encryptionOptionSection] = (int)_encryptionOption; numbers[senderNameLengthSection] = SenderIdentityHash.Length; numbers[ivLengthSection] = iv.Length; numbers[sharedKeyIdSection] = sharedKeyId; BitConverter.GetBytes(numbers.Data).CopyTo(bytes, index); index += 4; // Copy fields BitConverter.GetBytes(this.Timestamp.Ticks).CopyTo(bytes, index); index += sizeof(long); senderBytes.CopyTo(bytes, index); index += senderBytes.Length; iv.CopyTo(bytes, index); index += iv.Length; messageBytes.CopyTo(bytes, index); index += messageBytes.Length; byte[] signature = _messageClient.SignData(bytes, 0, totalBufferSize - _messageClient.SignatureLength); if (signature.Length != _messageClient.SignatureLength) { // Made bad assumption of signature length! throw new NotImplementedException(); } signature.CopyTo(bytes, totalBufferSize - signature.Length); return(bytes); }