/// <summary> /// Read file at path, split the contents in chunks and store them together with a StreamChunk. /// </summary> public static ChunkHash GenerateChunk(string path, Repo repo) { StreamChunk message = new StreamChunk (); using (Stream stream = new FileStream(path, FileMode.Open)) { BinaryReader br = new BinaryReader (stream); message.Size = (ulong)stream.Length; while (true) { byte[] data = br.ReadBytes (4096); if (data.Length == 0) break; Chunk c = new Chunk (data); ChunkHash ch = repo.WriteChunk (c); message.Chunks.Add (ch.bytes); } } byte[] messageBytes = StreamChunk.SerializeToBytes (message); Chunk messageChunk = new Chunk (messageBytes); ChunkHash messageHash = repo.WriteChunk (messageChunk); return messageHash; }
public static ChunkHash GenerateChunk(string path, Repo repo) { string fullPath = Path.GetFullPath (path); TreeChunk tree = new TreeChunk (); //Subdirectories string[] dirs = Directory.GetDirectories (fullPath); foreach (string d in dirs) { TreeFile df = new TreeFile (); df.Name = Path.GetFileName (d); df.TreeChunkHash = TreeChunk.GenerateChunk (d, repo).bytes; tree.Directories.Add (df); } //Files string[] files = Directory.GetFiles (fullPath); foreach (string f in files) { TreeFile ff = new TreeFile (); ff.Name = Path.GetFileName (f); ff.TreeChunkHash = StreamChunk.GenerateChunk (f, repo).bytes; tree.Files.Add (ff); } Chunk treeChunk = new Chunk (TreeChunk.SerializeToBytes (tree)); ChunkHash ch = repo.WriteChunk (treeChunk); return ch; }
public CustomID GetID(Chunk chunk) { using (MemoryStream ms = new MemoryStream()) { ms.Write(keyBuffer, 0, keyBuffer.Length); ProtocolParser.WriteBytes(ms, chunk.ClearHash.bytes); return CustomID.FromBytes(Hash.ComputeHash(ms.ToArray()).bytes); } }
public override Chunk ReadChunk(ChunkHash chunkHash) { //Read Data string dataPath = GetPath (chunkHash); Chunk chunk = new Chunk (File.ReadAllBytes (dataPath)); //Verify Hash if (chunk.ChunkHash.Equals (chunkHash) == false) throw new InvalidDataException ("Hash mismatch: " + chunkHash); //Read keys chunk.ClearHash = ClearHash.FromHashBytes (chunkHash.bytes); return chunk; }
public override ChunkHash WriteChunk(Chunk chunk) { if (recipientKeys.Count == 0) throw new InvalidOperationException ("EncryptedRepo must have at least one key"); //Encrypt Chunk encryptedChunk = Encrypt (chunk); //Reuse already existsing CustomID if (chunk.CustomID != null) { ChunkHash hash = GetCustomHash (chunk.CustomID); if (hash != null) return hash; } return base.WriteChunk (encryptedChunk); }
public static Message FromChunk(Chunk chunk, KeyStorage keyStorage) { if (chunk == null) return null; using (MemoryStream ms = new MemoryStream(chunk.Data)) { byte[] whisper = new byte[7]; if (ms.Read (whisper, 0, whisper.Length) != whisper.Length) throw new InvalidDataException ("Header not right length"); if (Encoding.ASCII.GetString (whisper) != "Whisper") throw new InvalidDataException ("Missing header"); MessageHeader header = MessageHeader.Deserialize (ProtocolParser.ReadBytes (ms)); byte[] messageBytes = ProtocolParser.ReadBytes (ms); Message message; switch (header.MessageId) { case 1: message = TreeMessage.Deserialize (messageBytes); break; case 2: message = RouteMessage.Deserialize (messageBytes); break; case 3: message = ListMessage.Deserialize (messageBytes); break; default: throw new NotImplementedException (); } //Verify signature if (header.Signature != null) { foreach (PublicKey key in keyStorage.PublicKeys) { if (key.Verify (messageBytes, header.Signature)) { message.Signature = key; break; } } } return message; } }
/// <summary> /// Test reading and writing to repo /// </summary> public static void Main(string[] args, KeyStorage keyStorage) { //Test buffer to transmit byte[] buffer = new byte[4096]; Random r = new Random (); r.NextBytes (buffer); string recipientName = null; if (args.Length == 3) recipientName = args [2]; if (args.Length > 3 || args.Length < 2) throw new HelpException ("Missing arguments"); string repoPath = args [1]; //Repository Repo repo = Repo.Create (repoPath); //Sender and Recipient keys PublicKey recipientKey = null; if (recipientName != null) { recipientKey = keyStorage.GetPublic (recipientName); EncryptedRepo er = new EncryptedRepo (repo, keyStorage); er.AddKey (recipientKey); repo = er; } Chunk c = new Chunk (buffer); var ch = repo.WriteChunk (c); Chunk c2 = repo.ReadChunk (ch); for (int n = 0; n < buffer.Length; n++) if (buffer [n] != c2.Data [n]) throw new InvalidDataException ("Failed at byte " + n); Console.WriteLine ("Test succeded"); }
void ProcessWriteChunk() { RequestWriteChunk request = RequestWriteChunk.Deserialize (ProtocolParser.ReadBytes (input)); ReplyWriteChunk reply = new ReplyWriteChunk (); Chunk chunk = new Chunk (request.ChunkData); localRepo.WriteChunk (chunk); ProtocolParser.WriteBytes (output, ReplyWriteChunk.SerializeToBytes (reply)); }
public override ChunkHash WriteChunk(Chunk chunk) { //Data string dataPath = GetPath (chunk.ChunkHash); Directory.CreateDirectory (Path.GetDirectoryName (dataPath)); File.WriteAllBytes (dataPath, chunk.Data); //ID if (chunk.CustomID != null) { string idPath = Path.Combine (idRoot, chunk.CustomID.ToString () + ".id"); File.WriteAllBytes (idPath, chunk.ChunkHash.bytes); } return chunk.ChunkHash; }
public static Message FromChunk(Chunk chunk) { return FromChunk (chunk, null); }
/// <summary> /// Encrypt chunk data into a new chunk /// </summary> Chunk Encrypt(Chunk chunk) { KeysHeader kh = new KeysHeader (); //Generate key kh.RM.GenerateIV (); kh.RM.GenerateKey (); //Add recipient keys foreach (PublicKey pubkey in recipientKeys) { byte[] bk = pubkey.Encrypt (kh.RM.Key); kh.EncryptedKeys.Add (bk); } //Encrypt data using (MemoryStream ms = new MemoryStream()) { //Headers ProtocolBuffers.ProtocolParser.WriteBytes (ms, KeysHeader.SerializeToBytes (kh)); //Encrypted data using (CryptoStream cs = new CryptoStream(ms, kh.RM.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write (chunk.Data, 0, chunk.Data.Length); } return new Chunk (ms.ToArray ()); } }
/// <summary> /// Return new chunk with decrypted data /// </summary> Chunk Decrypt(Chunk chunk) { //Read header int headerSize; KeysHeader head; using (MemoryStream chunkStream = new MemoryStream(chunk.Data)) { head = KeysHeader.Deserialize (ProtocolBuffers.ProtocolParser.ReadBytes (chunkStream)); headerSize = (int)chunkStream.Position; } //Decrypt Key byte[] key = Decrypt (head.EncryptedKeys); if (key == null) return null; head.RM.Key = key; //Decrypt Data head.RM.Mode = CipherMode.CBC; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, head.RM.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write (chunk.Data, headerSize, chunk.Data.Length - headerSize); } return new Chunk (ms.ToArray ()); } }
public override ChunkHash WriteChunk(Chunk chunk) { ChunkHash hash = base.WriteChunk (chunk); this.RouteMessage.Chunks.Add (hash.bytes); return hash; }
public override ChunkHash WriteChunk(Chunk chunk) { Chunk encrypted = new Chunk (Encrypt (chunk.Data)); return base.WriteChunk (encrypted); }
public CustomID GetID(Chunk chunk) { return null; }