internal Vault(R.Vault blob, string password) { var accounts = new Dictionary <string, Account>(); var keyCache = new Parse.DerivedKeyCache(); // This is used with the MFA. The server supplies the password prefix that is used in encryption. var serverKey = blob.ServerKey ?? ""; var fullPassword = serverKey + password; var fullFile = blob.EncryptedAccounts; if (!string.IsNullOrWhiteSpace(fullFile)) { foreach (var i in Parse.ExtractEncryptedAccounts(fullFile.Decode64(), fullPassword, keyCache)) { accounts[i.Id] = i; } } foreach (var transaction in blob.Transactions ?? new R.Transaction[0]) { if (transaction.Kind != "AUTHENTIFIANT") { continue; } switch (transaction.Action) { case "BACKUP_EDIT": var content = transaction.Content; if (!string.IsNullOrWhiteSpace(content)) { foreach (var i in Parse.ExtractEncryptedAccounts(content.Decode64(), fullPassword, keyCache)) { accounts[i.Id] = i; } } break; case "BACKUP_REMOVE": var id = transaction.Id; if (id != null) { accounts.Remove(id); } break; } } Accounts = accounts.Values.OrderBy(i => i.Id).ToArray(); }
internal static EncryptedVault ParseGetVaultResponse(R.Vault response) { var salt = response.Customer.Salt.DecodeHex(); var key = response.Customer.Kek.Decode64(); var accounts = response .Accounts .Select(i => new EncryptedAccount(id: i.Id, name: i.Name ?? "", username: i.Username ?? "", encryptedPassword: (i.EncryptedPassword ?? "").Decode64(), url: i.Url ?? "", encryptedNote: (i.EncryptedNote ?? "").Decode64())) .ToArray(); return(new EncryptedVault(salt, key, accounts)); }