diff --git a/app/src/main/java/com/beemdevelopment/aegis/importers/TwoFASImporter.java b/app/src/main/java/com/beemdevelopment/aegis/importers/TwoFASImporter.java index 8c896980c6..e618bf59bb 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/importers/TwoFASImporter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/importers/TwoFASImporter.java @@ -10,6 +10,7 @@ import com.beemdevelopment.aegis.otp.HotpInfo; import com.beemdevelopment.aegis.otp.OtpInfo; import com.beemdevelopment.aegis.otp.OtpInfoException; +import com.beemdevelopment.aegis.otp.SteamInfo; import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.util.IOUtils; @@ -60,7 +61,7 @@ public State read(InputStream stream, boolean isInternal) throws DatabaseImporte String json = new String(IOUtils.readAll(stream), StandardCharsets.UTF_8); JSONObject obj = new JSONObject(json); int version = obj.getInt("schemaVersion"); - if (version > 3) { + if (version > 4) { throw new DatabaseImporterException(String.format("Unsupported schema version: %d", version)); } @@ -187,6 +188,9 @@ private static VaultEntry convertEntry(JSONObject obj) throws DatabaseImporterEn } else if (tokenType.equals("HOTP")) { long counter = info.optLong("counter", 0); otp = new HotpInfo(secret, algorithm, digits, counter); + } else if (tokenType.equals("STEAM")) { + int period = info.optInt("period", TotpInfo.DEFAULT_PERIOD); + otp = new SteamInfo(secret, algorithm, digits, period); } else { throw new DatabaseImporterEntryException(String.format("Unrecognized tokenType: %s", tokenType), obj.toString()); } diff --git a/app/src/test/java/com/beemdevelopment/aegis/importers/DatabaseImporterTest.java b/app/src/test/java/com/beemdevelopment/aegis/importers/DatabaseImporterTest.java index 68ee956ab5..d376dfe3f3 100644 --- a/app/src/test/java/com/beemdevelopment/aegis/importers/DatabaseImporterTest.java +++ b/app/src/test/java/com/beemdevelopment/aegis/importers/DatabaseImporterTest.java @@ -324,6 +324,21 @@ public void testImportTwoFASAuthenticatorSchema3Encrypted() throws DatabaseImpor checkImportedEntries(entries); } + @Test + public void testImportTwoFASAuthenticatorSchema4Plain() throws DatabaseImporterException, IOException, OtpInfoException { + List entries = importPlain(TwoFASImporter.class, "2fas_authenticator_plain_v4.2fas"); + checkImportedEntries(entries); + } + + @Test + public void testImportTwoFASAuthenticatorSchema4Encrypted() throws DatabaseImporterException, IOException, OtpInfoException { + List entries = importEncrypted(TwoFASImporter.class, "2fas_authenticator_encrypted_v4.2fas", encryptedState -> { + final char[] password = "test".toCharArray(); + return ((TwoFASImporter.EncryptedState) encryptedState).decrypt(password); + }); + checkImportedEntries(entries); + } + private List importPlain(Class type, String resName) throws IOException, DatabaseImporterException { return importPlain(type, resName, false); diff --git a/app/src/test/resources/com/beemdevelopment/aegis/importers/2fas_authenticator_encrypted_v4.2fas b/app/src/test/resources/com/beemdevelopment/aegis/importers/2fas_authenticator_encrypted_v4.2fas new file mode 100644 index 0000000000..d064d8759f --- /dev/null +++ b/app/src/test/resources/com/beemdevelopment/aegis/importers/2fas_authenticator_encrypted_v4.2fas @@ -0,0 +1 @@ +{"services":[],"groups":[],"updatedAt":1702934782660,"schemaVersion":4,"appVersionCode":5000009,"appVersionName":"5.1.0","appOrigin":"android","servicesEncrypted":"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:dhXb6HzrC+U59zVJXnImEPsfhv1QxfxcgLeR80iKdwe7p4nfZ39VjMOiVlw2hOBHOX6qithmOvMBxxHMF/o7z6Ve+nIkBpZM59l12FcLPrMPihNtROYPCbJjjIxthpROhsI+VLuednyNaJYym0yfFli0wiWxU1xL4O4nyFIXWg3ZkbTVE0SiKI6ZmgsX2EmkJ9ZnKBVY00+62nxInCy8wgHfWZuD3jQlxccJrFezwg7KYNTZUuxAZmZl1nZIOdjhhPu4YMlHIMliiSLeJEPvTS5tmzOSMzjDXrwBl7pv8jtcYQSMfJPsVbFV4+Y1LA4E9jDzJcBgNU0sS5cbwLji8g==:6i0mYmyWAq70J5bD","reference":"QkyMxyhB3DZkI2hpz1c9OpnrWtcAkHXbTPgGFcXKRwvSR8DxaFem7cJz06ybopbBaxzELw+95jtYf5O90956urWFVD0G62xNj0gfqtwty3jXVRYimp+V6ufLlJx3b6aINwiDs/59GweFXaLTIju5HXen2gBiay5GkE2SUzaDaDovWXQ4XgQGdLHDkMuPMScNOhaU019zKYXcXM7wyG+8o/VtybIrc74U/C7d/Y2wz5e2/CjuwbLlGlEdYXx5+dggHhIJRLiLtN4KNwCY1fSP0J/y/sxoaYv3FP9tUIdG84yQvDgu6VOl7swC0+O1GiAcTzb3aygEmlssbx8+8cdb0cZf9Oq/aoxa1Qm5g8dtKrY=:dhXb6HzrC+U59zVJXnImEPsfhv1QxfxcgLeR80iKdwe7p4nfZ39VjMOiVlw2hOBHOX6qithmOvMBxxHMF/o7z6Ve+nIkBpZM59l12FcLPrMPihNtROYPCbJjjIxthpROhsI+VLuednyNaJYym0yfFli0wiWxU1xL4O4nyFIXWg3ZkbTVE0SiKI6ZmgsX2EmkJ9ZnKBVY00+62nxInCy8wgHfWZuD3jQlxccJrFezwg7KYNTZUuxAZmZl1nZIOdjhhPu4YMlHIMliiSLeJEPvTS5tmzOSMzjDXrwBl7pv8jtcYQSMfJPsVbFV4+Y1LA4E9jDzJcBgNU0sS5cbwLji8g==:u6Y8Kcpqe8hQaOW6"} \ No newline at end of file diff --git a/app/src/test/resources/com/beemdevelopment/aegis/importers/2fas_authenticator_plain_v4.2fas b/app/src/test/resources/com/beemdevelopment/aegis/importers/2fas_authenticator_plain_v4.2fas new file mode 100644 index 0000000000..013fadc31c --- /dev/null +++ b/app/src/test/resources/com/beemdevelopment/aegis/importers/2fas_authenticator_plain_v4.2fas @@ -0,0 +1 @@ +{"services":[{"name":"Deno","secret":"4SJHB4GSD43FZBAI7C2HLRJGPQ","updatedAt":1702934567518,"otp":{"link":"otpauth://totp/Deno:Mason?secret=4SJHB4GSD43FZBAI7C2HLRJGPQ&issuer=Deno&algorithm=SHA1&digits=6&period=30","label":"Mason","account":"Mason","issuer":"Deno","digits":6,"period":30,"algorithm":"SHA1","tokenType":"TOTP","source":"Link"},"order":{"position":0},"icon":{"selected":"Label","label":{"text":"DE","backgroundColor":"Yellow"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"Issuu","secret":"YOOMIXWS5GN6RTBPUFFWKTW5M4","updatedAt":1702934586420,"otp":{"link":"otpauth://hotp/Issuu:James?secret=YOOMIXWS5GN6RTBPUFFWKTW5M4&issuer=Issuu&algorithm=SHA1&digits=6&counter=1","label":"James","account":"James","issuer":"Issuu","digits":6,"algorithm":"SHA1","counter":1,"tokenType":"HOTP","source":"Link"},"order":{"position":1},"icon":{"selected":"Label","label":{"text":"IS","backgroundColor":"Brown"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"Air Canada","secret":"KUVJJOM753IHTNDSZVCNKL7GII","updatedAt":1702934590910,"otp":{"link":"otpauth://hotp/Air%20Canada:Benjamin?secret=KUVJJOM753IHTNDSZVCNKL7GII&issuer=Air+Canada&algorithm=SHA256&digits=7&counter=50","label":"Benjamin","account":"Benjamin","issuer":"Air Canada","digits":7,"algorithm":"SHA256","counter":50,"tokenType":"HOTP","source":"Link"},"order":{"position":2},"icon":{"selected":"Label","label":{"text":"AI","backgroundColor":"Orange"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"WWE","secret":"5VAML3X35THCEBVRLV24CGBKOY","updatedAt":1702934596091,"otp":{"link":"otpauth://hotp/WWE:Mason?secret=5VAML3X35THCEBVRLV24CGBKOY&issuer=WWE&algorithm=SHA512&digits=8&counter=10300","label":"Mason","account":"Mason","issuer":"WWE","digits":8,"algorithm":"SHA512","counter":10300,"tokenType":"HOTP","source":"Link"},"order":{"position":3},"icon":{"selected":"Label","label":{"text":"WW","backgroundColor":"Default"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"Boeing","secret":"JRZCL47CMXVOQMNPZR2F7J4RGI","updatedAt":1702934600248,"otp":{"link":"otpauth://steam/Boeing:Sophia?secret=JRZCL47CMXVOQMNPZR2F7J4RGI&issuer=Boeing&algorithm=SHA1&digits=5&period=30","label":"Sophia","account":"Sophia","issuer":"Boeing","digits":5,"period":30,"algorithm":"SHA1","tokenType":"STEAM","source":"Link"},"order":{"position":4},"icon":{"selected":"Label","label":{"text":"BO","backgroundColor":"Pink"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}}],"groups":[],"updatedAt":1702934732299,"schemaVersion":4,"appVersionCode":5000009,"appVersionName":"5.1.0","appOrigin":"android"} \ No newline at end of file