Add support for importing 2FAS schema v2 backups

This commit is contained in:
Alexander Bakker 2022-02-10 20:58:06 +01:00
parent acfb70c267
commit fcb7bf032b
5 changed files with 227 additions and 15 deletions

View file

@ -1,5 +1,10 @@
package com.beemdevelopment.aegis.importers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.content.Context;
import android.os.Build;
@ -27,11 +32,6 @@ import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@Config(sdk = { Build.VERSION_CODES.P })
@RunWith(RobolectricTestRunner.class)
public class DatabaseImporterTest {
@ -233,7 +233,7 @@ public class DatabaseImporterTest {
}
@Test
public void testImportTwoFASAuthenticator() throws DatabaseImporterException, IOException, OtpInfoException {
public void testImportTwoFASAuthenticatorSchema1() throws DatabaseImporterException, IOException, OtpInfoException {
List<VaultEntry> entries = importPlain(TwoFASImporter.class, "2fas_authenticator.json");
for (VaultEntry entry : entries) {
// 2FAS Authenticator doesn't support HOTP, different hash algorithms, periods or digits, so fix those up here
@ -243,6 +243,21 @@ public class DatabaseImporterTest {
}
}
@Test
public void testImportTwoFASAuthenticatorSchema2Plain() throws DatabaseImporterException, IOException, OtpInfoException {
List<VaultEntry> entries = importPlain(TwoFASImporter.class, "2fas_authenticator_plain.2fas");
checkImportedTwoFASEntries(entries);
}
@Test
public void testImportTwoFASAuthenticatorSchema2Encrypted() throws DatabaseImporterException, IOException, OtpInfoException {
List<VaultEntry> entries = importEncrypted(TwoFASImporter.class, "2fas_authenticator_encrypted.2fas", encryptedState -> {
final char[] password = "test".toCharArray();
return ((TwoFASImporter.EncryptedState) encryptedState).decrypt(password);
});
checkImportedTwoFASEntries(entries);
}
private List<VaultEntry> importPlain(Class<? extends DatabaseImporter> type, String resName)
throws IOException, DatabaseImporterException {
return importPlain(type, resName, false);
@ -285,6 +300,20 @@ public class DatabaseImporterTest {
return result.getEntries();
}
private void checkImportedTwoFASEntries(List<VaultEntry> entries) throws OtpInfoException {
for (VaultEntry entry : entries) {
// 2FAS Authenticator doesn't support certain features, so fix those entries up here
VaultEntry entryVector = getEntryVectorBySecret(entry.getInfo().getSecret());
OtpInfo info = entryVector.getInfo();
int period = TotpInfo.DEFAULT_PERIOD;
if (info instanceof TotpInfo) {
period = ((TotpInfo) info).getPeriod();
}
entryVector.setInfo(new TotpInfo(info.getSecret(), info.getAlgorithm(false), info.getDigits(), period));
checkImportedEntry(entryVector, entry);
}
}
private void checkImportedAuthyEntries(List<VaultEntry> entries) throws OtpInfoException {
for (VaultEntry entry : entries) {
// Authy doesn't support different hash algorithms or periods, so fix those up here

View file

@ -0,0 +1,11 @@
{
"services": [],
"updatedAt": 1644513883359,
"schemaVersion": 2,
"appVersionCode": 3080200,
"appVersionName": "3.8.2",
"appOrigin": "android",
"groups": [],
"servicesEncrypted": "5UGWlz8mZARCfCtbDgwAr0pjWORfch9aK+El1Eed9Axi6cQcaJKPTfwlZ3XDS7rGRZbw0yt9fs2ALp3SBcfTAVAHyw3sE9kyQobPieTtdQLeUrOp8JT6HrfGQKwpuZHLGmSmXXjWPmX8cBnESYijg8Es5J6pnsgCkOIMluJndkD8BI3HK8tcVWfk28UA2LZrvtLXY8W3\/+MSL0qJrjMsldqC6+NszCuWAJpqDDPZK9CyD1DbxTYplTHm+UlJWzdNpB0v1VVtGFHhRbrrRuG0BKXXN65nkw9aAUXpSSvgGgNGHZMwsmBVy\/192gKN\/pR8c31gqP4Yv959mjAGob1Wme1SaE0Oc4RGuOM3H8PINSf6acQSH1P3EnIjLm79snANmKW24B78CDvFeVcr9AupfbOYE7Tr2jJ23Gp06r73Jb55beZ5OYKwYGw\/EyzeV6qNd6A2e\/D98gTpyFP5Tcvxh3NWIMmc\/hzUZ449ZbZ1D3daxZN5pjkNHdb6616tpjtj1uxQTQBxwkAU6Gb0PrPasUtHD+QDLL5r1MvO4LRdiFWWrD2aTlhf2OOrrdsG4L6\/CZWgf\/TnyAy7f\/gCpdJ\/VVyESixlb7+AlqlZhOltQNOWd7j+aWUTxhmLpQ55vXOL5slYtibuQkSRVwL6CvY9SB5DpBYp7Yq5tD3ydV+S8S1imk+lq9PcxUO5Ex1TbwXVFucwuRKLlAA1TILIvMHJIyu1Zc8U409E1BThUxKI2S+t3fA9cl3ahTb8hmI1tGojLnwL+9OAIoIoTqZSd\/EWeECpqEadveboGuhdZsCXoi8UYaEYXrtApaGJ+V27POUDQbIALkgqJO0XVpSfeogPvyw08olOs36aUIfsDZ2Uwc8G9\/pg3u1KPeIf87SJO+HSGnoYMw0BjRXwbOuMANoJQrSbm5c34iOklJ7W0IDIIgPfVPKrJaE+D2pzbm0rBnh4\/p8w8an1V3y5b1kEsDWqU0uWI4zToToBrbqVxnEvQEvWqAa2\/MWCUC1QMy+t3KcZCl9wEWiNQ7JuHdY0WnWWjXRCq2AG3tIcqYsidX3MX8ku+Gyl+VqIthyB1RLPDQiNnZOIsfO2fscIfipuPSIDZMsaB4x04KAfhBG1RJHtFWAjgGrjPK\/u6WGydGABxAgNv\/CjmjgKx4ZzIksvkvARiDtcypy09pJz0FsbGEUr7q2vv7VXCHYprhM=:sOQnCCWbD76OERGCIMeG3Y1pg1skE4yKkqCg0iKW3HKyfPeOEEQ+xqSIhyNJiW4Q6HPYa4tYl2zViNv+JK\/pj65fpSEna55myY101Gx2gF7VUjuj1ujd+iz\/ib17DAedbMRu2IY\/bxjJ295yAX+iKxQZSBSt4MwXKCtT1\/HyfTNNmkCSblXQpfhuN0WiwFWGoQB1IPFVwKejD0JknBviVtbFCMg9VPvNYXGk7hyhOh2KnRrNQVGGYwGqoZI20lg1VK0Nn0E6eDc8MMD0ljUHKWQWGDRsriojCA4beaxtWTdtHHy2LBA5kiOv6nb62O5TsInscTxcJ\/2CBUJOVY+eJQ==:fCOmxT+T1J6nT5OX",
"reference": "EIqX5g2b2C5gXoDSmKs\/j6Xby2Opz7rTqDWCO\/AxKAiniUVWV15U5f9\/fpAxr4dygurCZ5ctrj7NSmbAVAF\/FfPyMaGFqT028yVmt499nm8kLqeq64Yx77oQ\/ADeh70cR4VmVfsC6DxPeSCLRQHcUNRm+7y8kEQ8sPu9QRSxVoU\/lEy2fltQSByqgzk3eIjsBxVrHgVG4mVqV6yLT47GLbBdh6CiZiqkNx9pUXhhXR0ej1Sp7tF0hXuZTh7+CTZvfJp2QA\/KA77F9Aa\/u1N1b8+5br8\/legiMjsMvVmKCXyyKzm6+Yt7VdrapKucyB+zJpH6IsTyxQpBsUV4cFGgqJhnX4qfoxzcWV6KqdFi22E=:sOQnCCWbD76OERGCIMeG3Y1pg1skE4yKkqCg0iKW3HKyfPeOEEQ+xqSIhyNJiW4Q6HPYa4tYl2zViNv+JK\/pj65fpSEna55myY101Gx2gF7VUjuj1ujd+iz\/ib17DAedbMRu2IY\/bxjJ295yAX+iKxQZSBSt4MwXKCtT1\/HyfTNNmkCSblXQpfhuN0WiwFWGoQB1IPFVwKejD0JknBviVtbFCMg9VPvNYXGk7hyhOh2KnRrNQVGGYwGqoZI20lg1VK0Nn0E6eDc8MMD0ljUHKWQWGDRsriojCA4beaxtWTdtHHy2LBA5kiOv6nb62O5TsInscTxcJ\/2CBUJOVY+eJQ==:+W6Bn5NEHwBE8S32"
}

View file

@ -0,0 +1,76 @@
{
"services": [
{
"name": "Deno",
"secret": "4SJHB4GSD43FZBAI7C2HLRJGPQ",
"updatedAt": 1644513743278,
"type": "Unknown",
"otp": {
"label": "Deno:Mason",
"account": "Mason",
"issuer": "Deno",
"digits": 6,
"period": 30,
"algorithm": "SHA1"
},
"order": {
"position": 0
}
},
{
"name": "Airbnb",
"secret": "7ELGJSGXNCCTV3O6LKJWYFV2RA",
"updatedAt": 1644513778354,
"type": "Unknown",
"otp": {
"label": "Airbnb:Elijah",
"account": "Elijah",
"issuer": "Airbnb",
"digits": 8,
"period": 50,
"algorithm": "SHA512"
},
"order": {
"position": 1
}
},
{
"name": "Issuu",
"secret": "YOOMIXWS5GN6RTBPUFFWKTW5M4",
"updatedAt": 1644513786834,
"type": "Unknown",
"otp": {
"label": "Issuu:James",
"account": "James",
"issuer": "Issuu",
"digits": 6,
"algorithm": "SHA1"
},
"order": {
"position": 2
}
},
{
"name": "WWE",
"secret": "5VAML3X35THCEBVRLV24CGBKOY",
"updatedAt": 1644513801596,
"type": "Unknown",
"otp": {
"label": "WWE:Mason",
"account": "Mason",
"issuer": "WWE",
"digits": 8,
"algorithm": "SHA512"
},
"order": {
"position": 3
}
}
],
"updatedAt": 1644513857707,
"schemaVersion": 2,
"appVersionCode": 3080200,
"appVersionName": "3.8.2",
"appOrigin": "android",
"groups": []
}