Example #1
0
        /// <summary>
        /// Login to Mega.co.nz service using hashed credentials
        /// </summary>
        /// <param name="authInfos">Authentication informations generated by <see cref="GenerateAuthInfos"/> method</param>
        /// <exception cref="ApiException">Service is not available or authInfos is invalid</exception>
        /// <exception cref="ArgumentNullException">authInfos is null</exception>
        /// <exception cref="NotSupportedException">Already logged in</exception>
        public LogonSessionToken Login(AuthInfos authInfos)
        {
            if (authInfos == null)
            {
                throw new ArgumentNullException("authInfos");
            }

            this.EnsureLoggedOut();
            this.authenticatedLogin = true;

            // Request Mega Api
            LoginRequest  request  = new LoginRequest(authInfos.Email, authInfos.Hash);
            LoginResponse response = this.Request <LoginResponse>(request);

            // Decrypt master key using our password key
            byte[] cryptedMasterKey = response.MasterKey.FromBase64();
            this.masterKey = Crypto.DecryptKey(cryptedMasterKey, authInfos.PasswordAesKey);

            // Decrypt RSA private key using decrypted master key
            byte[]       cryptedRsaPrivateKey    = response.PrivateKey.FromBase64();
            BigInteger[] rsaPrivateKeyComponents = Crypto.GetRsaPrivateKeyComponents(cryptedRsaPrivateKey, this.masterKey);

            // Decrypt session id
            byte[] encryptedSid = response.SessionId.FromBase64();
            byte[] sid          = Crypto.RsaDecrypt(encryptedSid.FromMPINumber(), rsaPrivateKeyComponents[0], rsaPrivateKeyComponents[1], rsaPrivateKeyComponents[2]);

            // Session id contains only the first 58 base64 characters
            this.sessionId = sid.ToBase64().Substring(0, 58);

            return(new LogonSessionToken(this.sessionId, this.masterKey));
        }
Example #2
0
        // Token: 0x06000938 RID: 2360 RVA: 0x0004B5FC File Offset: 0x000497FC
        public MegaApiClient.LogonSessionToken Login(MegaApiClient.AuthInfos authInfos)
        {
            if (authInfos == null)
            {
                throw new ArgumentNullException("authInfos");
            }
            this.EnsureLoggedOut();
            this.authenticatedLogin = true;
            LoginRequest request;

            if (!string.IsNullOrEmpty(authInfos.MFAKey))
            {
                request = new LoginRequest(authInfos.Email, authInfos.Hash, authInfos.MFAKey);
            }
            else
            {
                request = new LoginRequest(authInfos.Email, authInfos.Hash);
            }
            LoginResponse loginResponse = this.Request <LoginResponse>(request, null);

            byte[] data = loginResponse.MasterKey.FromBase64();
            this.masterKey = Crypto.DecryptKey(data, authInfos.PasswordAesKey);
            BigInteger[] rsaPrivateKeyComponents = Crypto.GetRsaPrivateKeyComponents(loginResponse.PrivateKey.FromBase64(), this.masterKey);
            byte[]       source = Crypto.RsaDecrypt(loginResponse.SessionId.FromBase64().FromMPINumber(), rsaPrivateKeyComponents[0], rsaPrivateKeyComponents[1], rsaPrivateKeyComponents[2]);
            this.sessionId = source.Take(43).ToArray <byte>().ToBase64();
            return(new MegaApiClient.LogonSessionToken(this.sessionId, this.masterKey));
        }
Example #3
0
        /// <summary>
        /// Login to Mega.co.nz service using hashed credentials
        /// </summary>
        /// <param name="authInfos">Authentication informations generated by <see cref="GenerateAuthInfos"/> method</param>
        /// <exception cref="ApiException">Service is not available or authInfos is invalid</exception>
        /// <exception cref="ArgumentNullException">authInfos is null</exception>
        /// <exception cref="NotSupportedException">Already logged in</exception>
        public void Login(AuthInfos authInfos)
        {
            if (authInfos == null)
            {
                throw new ArgumentNullException("authInfos");
            }

            this.EnsureLoggedOut();

            // Store authInfos to relogin if required
            this._authInfos = authInfos;

            // Request Mega Api
            LoginRequest  request  = new LoginRequest(authInfos.Email, authInfos.Hash);
            LoginResponse response = this.Request <LoginResponse>(request);

            // Decrypt master key using our password key
            byte[] cryptedMasterKey = response.MasterKey.FromBase64();
            this._masterKey = Crypto.DecryptKey(cryptedMasterKey, authInfos.PasswordAesKey);

            // Decrypt RSA private key using decrypted master key
            byte[]       cryptedRsaPrivateKey    = response.PrivateKey.FromBase64();
            BigInteger[] rsaPrivateKeyComponents = Crypto.GetRsaPrivateKeyComponents(cryptedRsaPrivateKey, this._masterKey);

            // Decrypt session id
            byte[] encryptedSid = response.SessionId.FromBase64();
            byte[] sid          = Crypto.RsaDecrypt(encryptedSid.FromMPINumber(), rsaPrivateKeyComponents[0], rsaPrivateKeyComponents[1], rsaPrivateKeyComponents[2]);

            // Session id contains only the first 43 decrypted bytes
            this._sessionId = sid.CopySubArray(43).ToBase64();
        }
Example #4
0
        public void OnDeserialized(StreamingContext ctx)
        {
            // Add key from incoming sharing.
            if (this.SharingKey != null && this.sharedKeys.Any(x => x.Id == this.Id) == false)
            {
                this.sharedKeys.Add(new SharedKey(this.Id, this.SharingKey));
            }

            this.CreationDate = this.SerializedCreationDate.ToDateTime();

            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.Ordinal);
                byte[] encryptedKey  = serializedKey.Substring(splitPosition + 1).FromBase64();

                // If node is shared, we need to retrieve shared masterkey
                if (this.sharedKeys != null)
                {
                    string    handle    = serializedKey.Substring(0, splitPosition);
                    SharedKey sharedKey = this.sharedKeys.FirstOrDefault(x => x.Id == handle);
                    if (sharedKey != null)
                    {
                        this.masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), this.masterKey);
                        if (this.Type == NodeType.Directory)
                        {
                            this.SharedKey = this.masterKey;
                        }
                        else
                        {
                            this.SharedKey = Crypto.DecryptKey(encryptedKey, this.masterKey);
                        }
                    }
                }

                this.FullKey = Crypto.DecryptKey(encryptedKey, this.masterKey);

                if (this.Type == NodeType.File)
                {
                    byte[] iv, metaMac, fileKey;
                    Crypto.GetPartsFromDecryptedKey(this.FullKey, out iv, out metaMac, out fileKey);

                    this.Iv      = iv;
                    this.MetaMac = metaMac;
                    this.Key     = fileKey;
                }
                else
                {
                    this.Key = this.FullKey;
                }

                this.Attributes = Crypto.DecryptAttributes(this.SerializedAttributes.FromBase64(), this.Key);
            }
        }
Example #5
0
 public void OnDeserialized(StreamingContext ctx)
 {
     if (this.SharingKey != null && !this.sharedKeys.Any((SharedKey x) => x.Id == base.Id))
     {
         this.sharedKeys.Add(new SharedKey(base.Id, this.SharingKey));
     }
     this.CreationDate = this.SerializedCreationDate.ToDateTime();
     if (base.Type == NodeType.File || base.Type == NodeType.Directory)
     {
         if (string.IsNullOrEmpty(this.SerializedKey))
         {
             this.EmptyKey = true;
             return;
         }
         string text = this.SerializedKey.Split(new char[]
         {
             '/'
         })[0];
         int    num  = text.IndexOf(":", StringComparison.Ordinal);
         byte[] data = text.Substring(num + 1).FromBase64();
         if (this.sharedKeys != null)
         {
             string    handle    = text.Substring(0, num);
             SharedKey sharedKey = this.sharedKeys.FirstOrDefault((SharedKey x) => x.Id == handle);
             if (sharedKey != null)
             {
                 this.masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), this.masterKey);
                 if (base.Type == NodeType.Directory)
                 {
                     this.SharedKey = this.masterKey;
                 }
                 else
                 {
                     this.SharedKey = Crypto.DecryptKey(data, this.masterKey);
                 }
             }
         }
         this.FullKey = Crypto.DecryptKey(data, this.masterKey);
         if (base.Type == NodeType.File)
         {
             byte[] iv;
             byte[] metaMac;
             byte[] key;
             Crypto.GetPartsFromDecryptedKey(this.FullKey, out iv, out metaMac, out key);
             this.Iv      = iv;
             this.MetaMac = metaMac;
             this.Key     = key;
         }
         else
         {
             this.Key = this.FullKey;
         }
         base.Attributes = Crypto.DecryptAttributes(this.SerializedAttributes.FromBase64(), this.Key);
     }
 }
Example #6
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;
            }
        }
Example #7
0
 // Token: 0x060007F3 RID: 2035 RVA: 0x0003997C File Offset: 0x00037B7C
 public static BigInteger[] GetRsaPrivateKeyComponents(byte[] encodedRsaPrivateKey, byte[] masterKey)
 {
     encodedRsaPrivateKey = encodedRsaPrivateKey.CopySubArray(encodedRsaPrivateKey.Length + (16 - encodedRsaPrivateKey.Length % 16), 0);
     byte[]       array  = Crypto.DecryptKey(encodedRsaPrivateKey, masterKey);
     BigInteger[] array2 = new BigInteger[4];
     for (int i = 0; i < 4; i++)
     {
         array2[i] = array.FromMPINumber();
         int num = ((int)array[0] * 256 + (int)array[1] + 7) / 8;
         array = array.CopySubArray(array.Length - num - 2, num + 2);
     }
     return(array2);
 }
Example #8
0
        public void OnDeserialized(StreamingContext ctx)
        {
            // Add key from incoming sharing.
            if (this.SharingKey != null && this.sharedKeys.Any(x => x.Id == this.Id) == false)
            {
                this.sharedKeys.Add(new SharedKey(this.Id, this.SharingKey));
            }

            this.CreationDate = this.SerializedCreationDate.ToDateTime();

            if (this.Type == NodeType.File || this.Type == NodeType.Directory)
            {
                // Check if file is not yet decrypted
                if (string.IsNullOrEmpty(this.SerializedKey))
                {
                    this.EmptyKey = true;

                    return;
                }

                // 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.Ordinal);
                byte[] encryptedKey  = serializedKey.Substring(splitPosition + 1).FromBase64();

                // If node is shared, we need to retrieve shared masterkey
                if (this.sharedKeys != null)
                {
                    string    handle    = serializedKey.Substring(0, splitPosition);
                    SharedKey sharedKey = this.sharedKeys.FirstOrDefault(x => x.Id == handle);
                    if (sharedKey != null)
                    {
                        this.masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), this.masterKey);
                        if (this.Type == NodeType.Directory)
                        {
                            this.SharedKey = this.masterKey;
                        }
                        else
                        {
                            this.SharedKey = Crypto.DecryptKey(encryptedKey, this.masterKey);
                        }
                    }
                }

                this.FullKey = Crypto.DecryptKey(encryptedKey, this.masterKey);

                if (this.Type == NodeType.File)
                {
                    byte[] iv, metaMac, fileKey;
                    Crypto.GetPartsFromDecryptedKey(this.FullKey, out iv, out metaMac, out fileKey);

                    this.Iv      = iv;
                    this.MetaMac = metaMac;
                    this.Key     = fileKey;
                }
                else
                {
                    this.Key = this.FullKey;
                }

                this.Attributes = Crypto.DecryptAttributes(this.SerializedAttributes.FromBase64(), this.Key);

                if (this.SerializedFileAttributes != null)
                {
                    var attributes = this.SerializedFileAttributes.Split('/');
                    this.FileAttributes = attributes
                                          .Select(_ => FileAttributeRegex.Match(_))
                                          .Where(_ => _.Success)
                                          .Select(_ => new FileAttribute(
                                                      int.Parse(_.Groups["id"].Value),
                                                      (FileAttributeType)Enum.Parse(typeof(FileAttributeType), _.Groups["type"].Value),
                                                      _.Groups["handle"].Value))
                                          .ToArray();
                }
            }
        }
Example #9
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;
                }
            }
        }
Example #10
0
        public void OnDeserialized(StreamingContext ctx)
        {
            // Add key from incoming sharing.
            if (SharingKey != null && _sharedKeys.Any(x => x.Id == Id) == false)
            {
                _sharedKeys.Add(new SharedKey(Id, SharingKey));
            }

            CreationDate = SerializedCreationDate.ToDateTime();

            if (Type == NodeType.File || Type == NodeType.Directory)
            {
                // Check if file is not yet decrypted
                if (string.IsNullOrEmpty(SerializedKey))
                {
                    EmptyKey = true;

                    return;
                }

                // 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
                var serializedKey = SerializedKey.Split('/')[0];
                var splitPosition = serializedKey.IndexOf(":", StringComparison.Ordinal);
                var encryptedKey  = serializedKey.Substring(splitPosition + 1).FromBase64();

                // If node is shared, we need to retrieve shared masterkey
                if (_sharedKeys != null)
                {
                    var handle    = serializedKey.Substring(0, splitPosition);
                    var sharedKey = _sharedKeys.FirstOrDefault(x => x.Id == handle);
                    if (sharedKey != null)
                    {
                        _masterKey = Crypto.DecryptKey(sharedKey.Key.FromBase64(), _masterKey);
                        if (Type == NodeType.Directory)
                        {
                            SharedKey = _masterKey;
                        }
                        else
                        {
                            SharedKey = Crypto.DecryptKey(encryptedKey, _masterKey);
                        }
                    }
                }

                if (encryptedKey.Length != 16 && encryptedKey.Length != 32)
                {
                    // Invalid key size
                    return;
                }

                FullKey = Crypto.DecryptKey(encryptedKey, _masterKey);

                if (Type == NodeType.File)
                {
                    Crypto.GetPartsFromDecryptedKey(FullKey, out var iv, out var metaMac, out var fileKey);

                    Iv      = iv;
                    MetaMac = metaMac;
                    Key     = fileKey;
                }
                else
                {
                    Key = FullKey;
                }

                Attributes     = Crypto.DecryptAttributes(SerializedAttributes.FromBase64(), Key);
                FileAttributes = DeserializeFileAttributes(SerializedFileAttributes);
            }
        }