예제 #1
0
        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;
            }
        }
예제 #2
0
        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;
                }
            }
        }