diff --git a/CHANGELOG b/CHANGELOG index 7ffa5361a..e17546cc7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ KeePassDX(2.9.19) * Fix search slowdown #964 * Fix closing notification after lock request #965 * Better temp advanced unlocking code implementation #965 + * Fix OTP token generation #967 KeePassDX(2.9.18) * Move groups #658 diff --git a/app/src/main/java/com/kunzisoft/keepass/otp/OtpElement.kt b/app/src/main/java/com/kunzisoft/keepass/otp/OtpElement.kt index 5244fac28..5b34eabc9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/otp/OtpElement.kt +++ b/app/src/main/java/com/kunzisoft/keepass/otp/OtpElement.kt @@ -93,7 +93,7 @@ data class OtpElement(var otpModel: OtpModel = OtpModel()) { value } else { TokenCalculator.HOTP_INITIAL_COUNTER - throw IllegalArgumentException() + throw NumberFormatException() } } @@ -186,7 +186,7 @@ data class OtpElement(var otpModel: OtpModel = OtpModel()) { } companion object { - const val MIN_HOTP_COUNTER = 1 + const val MIN_HOTP_COUNTER = 0 const val MAX_HOTP_COUNTER = Long.MAX_VALUE const val MIN_TOTP_PERIOD = 1 diff --git a/app/src/main/java/com/kunzisoft/keepass/otp/OtpEntryFields.kt b/app/src/main/java/com/kunzisoft/keepass/otp/OtpEntryFields.kt index 204288c3e..2d4fbeb9c 100644 --- a/app/src/main/java/com/kunzisoft/keepass/otp/OtpEntryFields.kt +++ b/app/src/main/java/com/kunzisoft/keepass/otp/OtpEntryFields.kt @@ -295,22 +295,30 @@ object OtpEntryFields { secretHexField != null -> otpElement.setHexSecret(secretHexField) secretBase32Field != null -> otpElement.setBase32Secret(secretBase32Field) secretBase64Field != null -> otpElement.setBase64Secret(secretBase64Field) - lengthField != null -> otpElement.digits = lengthField.toIntOrNull() ?: OTP_DEFAULT_DIGITS - periodField != null -> otpElement.period = periodField.toIntOrNull() ?: TOTP_DEFAULT_PERIOD - algorithmField != null -> otpElement.algorithm = - when (algorithmField.toUpperCase(Locale.ENGLISH)) { - TIMEOTP_ALGORITHM_SHA1_VALUE -> HashAlgorithm.SHA1 - TIMEOTP_ALGORITHM_SHA256_VALUE -> HashAlgorithm.SHA256 - TIMEOTP_ALGORITHM_SHA512_VALUE -> HashAlgorithm.SHA512 - else -> HashAlgorithm.SHA1 - } else -> return false } + otpElement.type = OtpType.TOTP + if (lengthField != null) { + otpElement.digits = lengthField.toIntOrNull() ?: OTP_DEFAULT_DIGITS + } + if (lengthField != null) { + otpElement.digits = lengthField.toIntOrNull() ?: OTP_DEFAULT_DIGITS + } + if (periodField != null) { + otpElement.period = periodField.toIntOrNull() ?: TOTP_DEFAULT_PERIOD + } + if (algorithmField != null) { + otpElement.algorithm = + when (algorithmField.toUpperCase(Locale.ENGLISH)) { + TIMEOTP_ALGORITHM_SHA1_VALUE -> HashAlgorithm.SHA1 + TIMEOTP_ALGORITHM_SHA256_VALUE -> HashAlgorithm.SHA256 + TIMEOTP_ALGORITHM_SHA512_VALUE -> HashAlgorithm.SHA512 + else -> HashAlgorithm.SHA1 + } + } } catch (exception: Exception) { return false } - - otpElement.type = OtpType.TOTP return true } @@ -321,10 +329,10 @@ object OtpEntryFields { return try { // KeeOtp string format val query = breakDownKeyValuePairs(plainText) + otpElement.type = OtpType.TOTP otpElement.setBase32Secret(query[SEED_KEY] ?: "") otpElement.digits = query[DIGITS_KEY]?.toIntOrNull() ?: OTP_DEFAULT_DIGITS otpElement.period = query[STEP_KEY]?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD - otpElement.type = OtpType.TOTP true } catch (exception: Exception) { false @@ -351,6 +359,7 @@ object OtpEntryFields { // malformed return false } + otpElement.type = OtpType.TOTP otpElement.period = matcher.group(1)?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD matcher.group(2)?.let { secondMatcher -> try { @@ -365,7 +374,6 @@ object OtpEntryFields { } catch (exception: Exception) { return false } - otpElement.type = OtpType.TOTP return true } @@ -374,6 +382,7 @@ object OtpEntryFields { val secretHexField = getField(HMACOTP_SECRET_HEX_FIELD) val secretBase32Field = getField(HMACOTP_SECRET_BASE32_FIELD) val secretBase64Field = getField(HMACOTP_SECRET_BASE64_FIELD) + val secretCounterField = getField(HMACOTP_SECRET_COUNTER_FIELD) try { when { secretField != null -> otpElement.setUTF8Secret(secretField) @@ -382,16 +391,13 @@ object OtpEntryFields { secretBase64Field != null -> otpElement.setBase64Secret(secretBase64Field) else -> return false } - - val secretCounterField = getField(HMACOTP_SECRET_COUNTER_FIELD) + otpElement.type = OtpType.HOTP if (secretCounterField != null) { otpElement.counter = secretCounterField.toLongOrNull() ?: HOTP_INITIAL_COUNTER } } catch (exception: Exception) { return false } - - otpElement.type = OtpType.HOTP return true } diff --git a/fastlane/metadata/android/en-US/changelogs/73.txt b/fastlane/metadata/android/en-US/changelogs/73.txt index 04068c54b..fb1c35e5a 100644 --- a/fastlane/metadata/android/en-US/changelogs/73.txt +++ b/fastlane/metadata/android/en-US/changelogs/73.txt @@ -1,3 +1,4 @@ * Fix search slowdown #964 * Fix closing notification after lock request #965 - * Better temp advanced unlocking code implementation #965 \ No newline at end of file + * Better temp advanced unlocking code implementation #965 + * Fix OTP token generation #967 \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/changelogs/73.txt b/fastlane/metadata/android/fr-FR/changelogs/73.txt index 526a96056..ce7da5396 100644 --- a/fastlane/metadata/android/fr-FR/changelogs/73.txt +++ b/fastlane/metadata/android/fr-FR/changelogs/73.txt @@ -1,3 +1,4 @@ * Correction du ralentissement de la recherche #964 * Correction de la fermeture de notification après une requête de verrouillage #965 - * Meilleure implémentation du déverrouillage avancé temporaire #965 \ No newline at end of file + * Meilleure implémentation du déverrouillage avancé temporaire #965 + * Correction de la génération des jetons de mots de passe uniques #967 \ No newline at end of file