aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java')
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java69
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;
+ }
}