public void OnDeserialized(StreamingContext ctx) { byte[] masterKey = (byte[])((object[])ctx.Context)[0]; GetNodesResponse nodesResponse = (GetNodesResponse)((object[])ctx.Context)[1]; this.LastModificationDate = OriginalDateTime.AddSeconds(this.SerializedLastModificationDate).ToLocalTime(); if (this.Type == NodeType.File || this.Type == NodeType.Directory) { int splitPosition = this.SerializedKey.IndexOf(":", StringComparison.InvariantCulture); byte[] encryptedKey = this.SerializedKey.Substring(splitPosition + 1).FromBase64(); this.DecryptedKey = Crypto.DecryptKey(encryptedKey, masterKey); this.Key = this.DecryptedKey; // If node is shared, we need to retrieve shared masterkey if (nodesResponse.SharedKeys != null) { string owner = this.SerializedKey.Substring(0, splitPosition); GetNodesResponse.SharedKey sharedKey = nodesResponse.SharedKeys.FirstOrDefault(x => x.Id == owner); if (sharedKey != null) { masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), masterKey); if (this.Type == NodeType.Directory) { this.DecryptedKey = masterKey; } this.Key = Crypto.DecryptKey(encryptedKey, masterKey); } } if (this.Type == NodeType.File) { // Extract Iv and MetaMac byte[] iv = new byte[8]; byte[] metaMac = new byte[8]; Array.Copy(this.DecryptedKey, 16, iv, 0, 8); Array.Copy(this.DecryptedKey, 24, metaMac, 0, 8); this.Iv = iv; this.MetaMac = metaMac; // For files, key is 256 bits long. Compute the key to retrieve 128 AES key this.Key = new byte[16]; for (int idx = 0; idx < 16; idx++) { this.Key[idx] = (byte)(this.DecryptedKey[idx] ^ this.DecryptedKey[idx + 16]); } } Attributes attributes = Crypto.DecryptAttributes(this.SerializedAttributes.FromBase64(), this.Key); this.Name = attributes.Name; } }
public void OnDeserialized(StreamingContext ctx) { object[] context = (object[])ctx.Context; GetNodesResponse nodesResponse = (GetNodesResponse)context[0]; if (context.Length == 1) { // Add key from incoming sharing. if (this.SharingKey != null) { nodesResponse.SharedKeys.Add(new GetNodesResponse.SharedKey(this.Id, this.SharingKey)); } return; } else { byte[] masterKey = (byte[])context[1]; this.LastModificationDate = OriginalDateTime.AddSeconds(this.SerializedLastModificationDate).ToLocalTime(); if (this.Type == NodeType.File || this.Type == NodeType.Directory) { // There are cases where the SerializedKey property contains multiple keys separated with / // This can occur when a folder is shared and the parent is shared too. // Both keys are working so we use the first one string serializedKey = this.SerializedKey.Split('/')[0]; int splitPosition = serializedKey.IndexOf(":", StringComparison.InvariantCulture); byte[] encryptedKey = serializedKey.Substring(splitPosition + 1).FromBase64(); // If node is shared, we need to retrieve shared masterkey if (nodesResponse.SharedKeys != null) { string handle = serializedKey.Substring(0, splitPosition); GetNodesResponse.SharedKey sharedKey = nodesResponse.SharedKeys.FirstOrDefault(x => x.Id == handle); if (sharedKey != null) { masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), masterKey); if (this.Type == NodeType.Directory) { this.SharedKey = masterKey; } else { this.SharedKey = Crypto.DecryptKey(encryptedKey, masterKey); } } } this.Key = Crypto.DecryptKey(encryptedKey, masterKey); if (this.Type == NodeType.File) { byte[] iv, metaMac, fileKey; Crypto.GetPartsFromDecryptedKey(this.Key, out iv, out metaMac, out fileKey); this.Iv = iv; this.MetaMac = metaMac; this.Key = fileKey; } Attributes attributes = Crypto.DecryptAttributes(this.SerializedAttributes.FromBase64(), this.Key); this.Name = attributes.Name; } } }