// -- public byte[] GetAssembledData() { if (data != null) { return(data); } int index = 0; byte[] buffer; byte[] contentBytes = Serialization.Binary.Serialize(content); // Sign before encrypting this.signature = Core.CryptoProvider.SignData(contentBytes, new SHA1CryptoServiceProvider()); this.signatureLength = (ulong)this.signature.Length; if (Message.TypeIsEncrypted(type)) { if (!network.Nodes.ContainsKey(to)) { throw new Exception("network.Nodes[to] was null!... to was " + to); } // Encrypt if needed contentBytes = Security.Encryption.Encrypt(network.Nodes[to].CreateEncryptor(), contentBytes); } signatureLength = (ulong)signature.Length; contentLength = contentBytes.Length; buffer = new byte[8 + (int)signatureLength + 64 + 64 + 1 + 16 + 8 + 4 + contentBytes.Length]; AppendULongToBuffer(signatureLength, ref buffer, ref index); // 8 AppendBytesToBuffer(signature, ref buffer, ref index); // ? AppendStringToBuffer(from, ref buffer, ref index); // 64 AppendStringToBuffer(to, ref buffer, ref index); // 64 AppendByteToBuffer((byte)type, ref buffer, ref index); // 1 byte[] idBytes = new Guid(id).ToByteArray(); AppendBytesToBuffer(idBytes, ref buffer, ref index); // 16 AppendULongToBuffer(timestamp, ref buffer, ref index); // 8 AppendIntToBuffer(contentLength, ref buffer, ref index); // 4 AppendBytesToBuffer(contentBytes, ref buffer, ref index); // ? if (index != buffer.Length) { throw new Exception("Array was the wrong size: " + index + " " + buffer.Length); } return(buffer); }
private Message(Network network, byte[] data, out string messageFrom) { if (network == null) { throw new ArgumentNullException("network"); } if (data == null) { throw new ArgumentNullException("data"); } this.network = network; this.data = data; // Read message header int offset = 0; signatureLength = EndianBitConverter.ToUInt64(data, offset); offset += 8; signature = new byte[signatureLength]; Buffer.BlockCopy(data, offset, signature, 0, (int)signatureLength); offset += (int)signatureLength; byte[] fromBuffer = new byte[64]; Buffer.BlockCopy(data, offset, fromBuffer, 0, fromBuffer.Length); from = BitConverter.ToString(fromBuffer).Replace("-", String.Empty); messageFrom = from; offset += 64; byte[] toBuffer = new byte[64]; Buffer.BlockCopy(data, offset, toBuffer, 0, toBuffer.Length); to = BitConverter.ToString(toBuffer).Replace("-", String.Empty); offset += 64; type = (MessageType)data[offset]; offset += 1; byte[] idBytes = new byte[16]; Buffer.BlockCopy(data, offset, idBytes, 0, 16); id = new Guid(idBytes).ToString(); offset += 16; timestamp = EndianBitConverter.ToUInt64(data, offset); offset += 8; contentLength = EndianBitConverter.ToInt32(data, offset); offset += 4; int remainingLength = data.Length - offset; if (remainingLength != contentLength) { throw new Exception(String.Format("Message size mismatch! Content length should be {0}, was {1}", contentLength, remainingLength)); } // If this message isn't for us, ignore the content. if (to == Core.MyNodeID || to == Network.BroadcastNodeID) { byte[] contentBuffer = new byte[contentLength]; Buffer.BlockCopy(data, offset, contentBuffer, 0, contentLength); // Decrypt if needed if (Message.TypeIsEncrypted(type)) { if (From != Core.MyNodeID) { if (network.Nodes.ContainsKey(From)) { contentBuffer = Security.Encryption.Decrypt(network.Nodes[From].CreateDecryptor(), contentBuffer); } else { throw new Exception(String.Format("Node not found: {0}", From)); } } else { contentBuffer = Security.Encryption.Decrypt(network.Nodes[To].CreateDecryptor(), contentBuffer); } } // Verify signature if (From != Core.MyNodeID) { if (network.TrustedNodes.ContainsKey(from)) { bool validSignature = network.TrustedNodes[from].Crypto.VerifyData(contentBuffer, new SHA1CryptoServiceProvider(), signature); if (validSignature == false) { throw new InvalidSignatureException(); } } else if (Message.TypeIsEncrypted(type)) { throw new Exception("Unable to verify message signature! (Type: " + type.ToString() + ")"); } } else { bool validSignature = Core.CryptoProvider.VerifyData(contentBuffer, new SHA1CryptoServiceProvider(), signature); if (validSignature == false) { throw new InvalidSignatureException(); } } // Now deserialize content content = Serialization.Binary.Deserialize(contentBuffer); } }