diff options
| author | Joel Beckmeyer <joel@thebeckmeyers.xyz> | 2018-09-25 13:45:54 -0400 |
|---|---|---|
| committer | حسين <zidhussein@gmail.com> | 2018-09-25 18:45:54 +0100 |
| commit | eea0e68dda1eb7248c6d458f52baeedb318b466a (patch) | |
| tree | 73ff2b2f121b8db3097671f0e0639906edc2abea /app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java | |
| parent | ac889abdd3d71ffb7f064a384c375ec22e7734c4 (diff) | |
| download | HardenedPass-eea0e68dda1eb7248c6d458f52baeedb318b466a.tar.gz HardenedPass-eea0e68dda1eb7248c6d458f52baeedb318b466a.zip | |
Display HOTP code if password contains HOTP secret, unify HOTP and TOTP code (#413)
* Display HOTP code if password contains HOTP secret, unify HOTP and TOTP code
* Add ability to show HOTP instead of showing every decrypt
* Fix off by 1 error
* fix return intent logic so that edits and HOTP increments are properly committed
* fix linting errors
* Fix broken logic for case when a password is created
* add ability to choose if password entry will be updated on HOTP code calculation
Diffstat (limited to 'app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java')
| -rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java index ba689fe9..590a779e 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java @@ -12,10 +12,14 @@ public class PasswordEntry { private static final String[] USERNAME_FIELDS = new String[]{"login", "username"}; - private final String extraContent; + private String extraContent; private final String password; private final String username; private final String totpSecret; + private final String hotpSecret; + private final Long hotpCounter; + private final String content; + private boolean isIncremented = false; public PasswordEntry(final ByteArrayOutputStream os) throws UnsupportedEncodingException { this(os.toString("UTF-8")); @@ -23,11 +27,14 @@ public class PasswordEntry { public PasswordEntry(final String decryptedContent) { final String[] passContent = decryptedContent.split("\n", 2); + content = decryptedContent; password = passContent[0]; - extraContent = passContent.length > 1 ? passContent[1] : ""; + totpSecret = findTotpSecret(content); + hotpSecret = findHotpSecret(content); + hotpCounter = findHotpCounter(content); + extraContent = findExtraContent(passContent); username = findUsername(); - totpSecret = findTotpSecret(decryptedContent); - } + } public String getPassword() { return password; @@ -45,6 +52,14 @@ public class PasswordEntry { return totpSecret; } + public Long getHotpCounter() { + return hotpCounter; + } + + public String getHotpSecret() { + return hotpSecret; + } + public boolean hasExtraContent() { return extraContent.length() != 0; } @@ -53,7 +68,24 @@ public class PasswordEntry { return username != null; } - public boolean hasTotp() { return totpSecret != null; } + public boolean hasTotp() { + return totpSecret != null; + } + + public boolean hasHotp() { + return hotpSecret != null && hotpCounter != null; + } + + public boolean hotpIsIncremented() { return isIncremented; } + + public void incrementHotp() { + for (String line : content.split("\n")) { + if (line.startsWith("otpauth://hotp/")) { + extraContent = extraContent.replaceFirst("counter=[0-9]+", "counter=" + Long.toString(hotpCounter + 1)); + isIncremented = true; + } + } + } private String findUsername() { final String[] extraLines = extraContent.split("\n"); @@ -75,4 +107,31 @@ public class PasswordEntry { } return null; } + + private String findHotpSecret(String decryptedContent) { + for (String line : decryptedContent.split("\n")) { + if (line.startsWith("otpauth://hotp/")) { + return Uri.parse(line).getQueryParameter("secret"); + } + } + return null; + } + + private Long findHotpCounter(String decryptedContent) { + for (String line : decryptedContent.split("\n")) { + if (line.startsWith("otpauth://hotp/")) { + return Long.parseLong(Uri.parse(line).getQueryParameter("counter")); + } + } + return null; + } + + private String findExtraContent(String [] passContent) { + String extraContent = passContent.length > 1 ? passContent[1] : ""; + // if there is a HOTP URI, we must return the extra content with the counter incremented + if (hasHotp()) { + return extraContent.replaceFirst("counter=[0-9]+", "counter=" + Long.toString(hotpCounter)); + } + return extraContent; + } } |
