summaryrefslogtreecommitdiff
path: root/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java138
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt114
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt6
3 files changed, 117 insertions, 141 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java
deleted file mode 100644
index d876aefd..00000000
--- a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package com.zeapo.pwdstore;
-
-import android.net.Uri;
-
-import java.io.ByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * A single entry in password store.
- */
-public class PasswordEntry {
-
- private static final String[] USERNAME_FIELDS = new String[]{"login", "username"};
- 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 String extraContent;
- private boolean isIncremented = false;
-
- public PasswordEntry(final ByteArrayOutputStream os) throws UnsupportedEncodingException {
- this(os.toString("UTF-8"));
- }
-
- public PasswordEntry(final String decryptedContent) {
- final String[] passContent = decryptedContent.split("\n", 2);
- content = decryptedContent;
- password = passContent[0];
- totpSecret = findTotpSecret(content);
- hotpSecret = findHotpSecret(content);
- hotpCounter = findHotpCounter(content);
- extraContent = findExtraContent(passContent);
- username = findUsername();
- }
-
- public String getPassword() {
- return password;
- }
-
- public String getExtraContent() {
- return extraContent;
- }
-
- public String getUsername() {
- return username;
- }
-
- public String getTotpSecret() {
- return totpSecret;
- }
-
- public Long getHotpCounter() {
- return hotpCounter;
- }
-
- public String getHotpSecret() {
- return hotpSecret;
- }
-
- public boolean hasExtraContent() {
- return extraContent.length() != 0;
- }
-
- public boolean hasUsername() {
- return username != 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");
- for (String line : extraLines) {
- for (String field : USERNAME_FIELDS) {
- if (line.toLowerCase().startsWith(field + ":")) {
- return line.split(": *", 2)[1];
- }
- }
- }
- return null;
- }
-
- private String findTotpSecret(String decryptedContent) {
- for (String line : decryptedContent.split("\n")) {
- if (line.startsWith("otpauth://totp/")) {
- return Uri.parse(line).getQueryParameter("secret");
- }
- }
- 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;
- }
-}
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt
new file mode 100644
index 00000000..757681c5
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.kt
@@ -0,0 +1,114 @@
+package com.zeapo.pwdstore
+
+import android.net.Uri
+
+import java.io.ByteArrayOutputStream
+import java.io.UnsupportedEncodingException
+
+/**
+ * A single entry in password store.
+ */
+class PasswordEntry(private val content: String) {
+ val password: String
+ val username: String?
+ val totpSecret: String?
+ val hotpSecret: String?
+ val hotpCounter: Long?
+ var extraContent: String? = null
+ private set
+ private var isIncremented = false
+
+ @Throws(UnsupportedEncodingException::class)
+ constructor(os: ByteArrayOutputStream) : this(os.toString("UTF-8"))
+
+ init {
+ val passContent = content.split("\n".toRegex(), 2).toTypedArray()
+ password = passContent[0]
+ totpSecret = findTotpSecret(content)
+ hotpSecret = findHotpSecret(content)
+ hotpCounter = findHotpCounter(content)
+ extraContent = findExtraContent(passContent)
+ username = findUsername()
+ }
+
+ fun hasExtraContent(): Boolean {
+ return !extraContent.isNullOrEmpty()
+ }
+
+ fun hasUsername(): Boolean {
+ return username != null
+ }
+
+ fun hasTotp(): Boolean {
+ return totpSecret != null
+ }
+
+ fun hasHotp(): Boolean {
+ return hotpSecret != null && hotpCounter != null
+ }
+
+ fun hotpIsIncremented(): Boolean {
+ return isIncremented
+ }
+
+ fun incrementHotp() {
+ content.split("\n".toRegex()).forEach { line ->
+ if (line.startsWith("otpauth://hotp/")) {
+ extraContent = extraContent?.replaceFirst("counter=[0-9]+".toRegex(), "counter=${hotpCounter!! + 1}")
+ isIncremented = true
+ }
+ }
+ }
+
+ private fun findUsername(): String? {
+ val extraLines = extraContent!!.split("\n".toRegex())
+ for (line in extraLines) {
+ for (field in USERNAME_FIELDS) {
+ if (line.toLowerCase().startsWith("$field:")) {
+ return line.split(": *".toRegex(), 2).toTypedArray()[1]
+ }
+ }
+ }
+ return null
+ }
+
+ private fun findTotpSecret(decryptedContent: String): String? {
+ decryptedContent.split("\n".toRegex()).forEach { line ->
+ if (line.startsWith("otpauth://totp/")) {
+ return Uri.parse(line).getQueryParameter("secret")
+ }
+ }
+ return null
+ }
+
+ private fun findHotpSecret(decryptedContent: String): String? {
+ decryptedContent.split("\n".toRegex()).forEach { line ->
+ if (line.startsWith("otpauth://hotp/")) {
+ return Uri.parse(line).getQueryParameter("secret")
+ }
+ }
+ return null
+ }
+
+ private fun findHotpCounter(decryptedContent: String): Long? {
+ decryptedContent.split("\n".toRegex()).forEach { line ->
+ if (line.startsWith("otpauth://hotp/")) {
+ return java.lang.Long.parseLong(Uri.parse(line).getQueryParameter("counter")!!)
+ }
+ }
+ return null
+ }
+
+ private fun findExtraContent(passContent: Array<String>): String {
+ val extraContent = if (passContent.size > 1) passContent[1] else ""
+ // if there is a HOTP URI, we must return the extra content with the counter incremented
+ return if (hasHotp()) {
+ extraContent.replaceFirst("counter=[0-9]+".toRegex(), "counter=" + java.lang.Long.toString(hotpCounter!!))
+ } else extraContent
+ }
+
+ companion object {
+
+ private val USERNAME_FIELDS = arrayOf("login", "username")
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt
index 9828f43a..93fd7489 100644
--- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt
+++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt
@@ -281,7 +281,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
crypto_username_show_label.visibility = View.VISIBLE
crypto_copy_username.visibility = View.VISIBLE
- crypto_copy_username.setOnClickListener { copyUsernameToClipBoard(entry.username) }
+ crypto_copy_username.setOnClickListener { copyUsernameToClipBoard(entry.username!!) }
crypto_username_show.typeface = monoTypeface
crypto_username_show.text = entry.username
} else {
@@ -494,8 +494,8 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
}
private fun calculateHotp(entry: PasswordEntry) {
- copyOtpToClipBoard(Otp.calculateCode(entry.hotpSecret, entry.hotpCounter + 1))
- crypto_otp_show.text = Otp.calculateCode(entry.hotpSecret, entry.hotpCounter + 1)
+ copyOtpToClipBoard(Otp.calculateCode(entry.hotpSecret, entry.hotpCounter!! + 1))
+ crypto_otp_show.text = Otp.calculateCode(entry.hotpSecret, entry.hotpCounter!! + 1)
crypto_extra_show.text = entry.extraContent
}