Exemple #1
0
        public async Task <Node> CreateFolder(string name, Node parent, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            if (parent.Type == NodeType.File)
            {
                throw new ArgumentException("Invalid parent node");
            }

            //this.EnsureLoggedIn();
            var key = Crypto.CreateAesKey();

            byte[] attributes   = EncryptAttributes(new Attributes(name), key);
            byte[] encryptedKey = Crypto.EncryptAes(key, this._masterKey);

            CreateNodeRequest request  = CreateNodeRequest.CreateFolderNodeRequest(parent, attributes.ToBase64(), encryptedKey.ToBase64());
            GetNodesResponse  response = await Post <CreateNodeRequest, GetNodesResponse>(request, cancellationToken);

            var node = response.Nodes[0];

            DecriptNode(node, response);
            return(node);
        }
Exemple #2
0
        private void DecriptNode(Node node, GetNodesResponse response)
        {
            node.LastModificationDate = Node.OriginalDateTime.AddSeconds(node.SerializedLastModificationDate).ToLocalTime();
            if (node.Type == NodeType.File || node.Type == NodeType.Directory)
            {
                string serializedKey = node.SerializedKey;
                int    splitPosition = serializedKey.IndexOf(":");
                byte[] encryptedKey  = serializedKey.Substring(splitPosition + 1).FromBase64();

                var decryptedKey = Crypto.DecryptKey(encryptedKey, _masterKey);
                node.Key = decryptedKey;

                // If node is shared, we need to retrieve shared masterkey
                if (response.SharedKeys != null)
                {
                    string owner     = splitPosition > -1 ? serializedKey.Substring(0, splitPosition) : serializedKey;
                    var    sharedKey = response.SharedKeys.FirstOrDefault(x => x.Id == owner);
                    if (sharedKey != null)
                    {
                        var masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), _masterKey);

                        if (node.Type == NodeType.Directory)
                        {
                            decryptedKey = masterKey;
                        }

                        node.Key = Crypto.DecryptKey(encryptedKey, masterKey);
                    }
                }

                if (node.Type == NodeType.File)
                {
                    // Extract Iv and MetaMac
                    byte[] iv      = new byte[8];
                    byte[] metaMac = new byte[8];
                    Array.Copy(decryptedKey, 16, iv, 0, 8);
                    Array.Copy(decryptedKey, 24, metaMac, 0, 8);
                    node.Iv      = iv;
                    node.MetaMac = metaMac;

                    // For files, key is 256 bits long. Compute the key to retrieve 128 AES key
                    node.Key = new byte[16];
                    for (int idx = 0; idx < 16; idx++)
                    {
                        node.Key[idx] = (byte)(decryptedKey[idx] ^ decryptedKey[idx + 16]);
                    }
                }

                Attributes attributes = DecryptAttributes(node.SerializedAttributes.FromBase64(), node.Key);
                node.Name = attributes.Name;
            }
            //if (this._trashNode == null)
            //{
            //    this._trashNode = nodes.First(n => n.Type == NodeType.Trash);
            //}
        }
Exemple #3
0
        /// <summary>
        /// Retrieve all filesystem nodes
        /// </summary>
        /// <returns>Flat representation of all the filesystem nodes</returns>
        /// <exception cref="NotSupportedException">Not logged in</exception>
        /// <exception cref="ApiException">Mega.co.nz service reports an error</exception>
        public async Task <IEnumerable <Node> > GetNodes(CancellationToken cancellationToken)
        {
            //this.EnsureLoggedIn();

            GetNodesRequest  request  = new GetNodesRequest();
            GetNodesResponse response = await Post <GetNodesRequest, GetNodesResponse>(request, cancellationToken);

            Node[] nodes = response.Nodes;
            foreach (var node in nodes)
            {
                DecriptNode(node, response);
            }
            return(nodes);
        }
Exemple #4
0
        public async Task <Node> Upload(Stream fileContent, string name, Node parent, IProgress <StreamProgress> progress, CancellationToken cancellationToken)
        {
            if (fileContent == null)
            {
                throw new ArgumentNullException("fileContent");
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            if (parent.Type == NodeType.File)
            {
                throw new ArgumentException("Invalid parent node");
            }

            //this.EnsureLoggedIn();
            // Retrieve upload URL
            var length = fileContent.GetLength();

            if (!length.HasValue)
            {
                fileContent = new MemoryStream(await fileContent.ReadAsBufferAsync(cancellationToken));
                length      = fileContent.GetLength();
            }
            UploadUrlRequest  uploadRequest  = new UploadUrlRequest(length.Value);
            UploadUrlResponse uploadResponse = await Post <UploadUrlRequest, UploadUrlResponse>(uploadRequest, cancellationToken);

            var    megaStream = new MegaEncryptStream(fileContent);
            string completionHandle;

            try
            {
                completionHandle = await PostRaw(new Uri(uploadResponse.Url), megaStream, progress, cancellationToken);
            }
            finally
            {
                megaStream.Dispose();
            }

            // Encrypt attributes
            byte[] cryptedAttributes = EncryptAttributes(new Attributes(name), megaStream.FileKey);

            // Compute the file key
            byte[] fileKey = new byte[32];
            for (int i = 0; i < 8; i++)
            {
                fileKey[i]      = (byte)(megaStream.FileKey[i] ^ megaStream.IV[i]);
                fileKey[i + 16] = megaStream.IV[i];
            }

            for (int i = 8; i < 16; i++)
            {
                fileKey[i]      = (byte)(megaStream.FileKey[i] ^ megaStream.MetaMac[i - 8]);
                fileKey[i + 16] = megaStream.MetaMac[i - 8];
            }

            byte[] encryptedKey = Crypto.EncryptKey(fileKey, this._masterKey);

            CreateNodeRequest createNodeRequest  = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), completionHandle);
            GetNodesResponse  createNodeResponse = await Post <CreateNodeRequest, GetNodesResponse>(createNodeRequest, cancellationToken);

            var node = createNodeResponse.Nodes[0];

            DecriptNode(node, createNodeResponse);
            return(node);
        }