mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix OTP token generation #967
This commit is contained in:
@@ -2,6 +2,7 @@ KeePassDX(2.9.19)
|
|||||||
* Fix search slowdown #964
|
* Fix search slowdown #964
|
||||||
* Fix closing notification after lock request #965
|
* Fix closing notification after lock request #965
|
||||||
* Better temp advanced unlocking code implementation #965
|
* Better temp advanced unlocking code implementation #965
|
||||||
|
* Fix OTP token generation #967
|
||||||
|
|
||||||
KeePassDX(2.9.18)
|
KeePassDX(2.9.18)
|
||||||
* Move groups #658
|
* Move groups #658
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ data class OtpElement(var otpModel: OtpModel = OtpModel()) {
|
|||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
TokenCalculator.HOTP_INITIAL_COUNTER
|
TokenCalculator.HOTP_INITIAL_COUNTER
|
||||||
throw IllegalArgumentException()
|
throw NumberFormatException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ data class OtpElement(var otpModel: OtpModel = OtpModel()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MIN_HOTP_COUNTER = 1
|
const val MIN_HOTP_COUNTER = 0
|
||||||
const val MAX_HOTP_COUNTER = Long.MAX_VALUE
|
const val MAX_HOTP_COUNTER = Long.MAX_VALUE
|
||||||
|
|
||||||
const val MIN_TOTP_PERIOD = 1
|
const val MIN_TOTP_PERIOD = 1
|
||||||
|
|||||||
@@ -295,22 +295,30 @@ object OtpEntryFields {
|
|||||||
secretHexField != null -> otpElement.setHexSecret(secretHexField)
|
secretHexField != null -> otpElement.setHexSecret(secretHexField)
|
||||||
secretBase32Field != null -> otpElement.setBase32Secret(secretBase32Field)
|
secretBase32Field != null -> otpElement.setBase32Secret(secretBase32Field)
|
||||||
secretBase64Field != null -> otpElement.setBase64Secret(secretBase64Field)
|
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
|
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) {
|
} catch (exception: Exception) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
otpElement.type = OtpType.TOTP
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,10 +329,10 @@ object OtpEntryFields {
|
|||||||
return try {
|
return try {
|
||||||
// KeeOtp string format
|
// KeeOtp string format
|
||||||
val query = breakDownKeyValuePairs(plainText)
|
val query = breakDownKeyValuePairs(plainText)
|
||||||
|
otpElement.type = OtpType.TOTP
|
||||||
otpElement.setBase32Secret(query[SEED_KEY] ?: "")
|
otpElement.setBase32Secret(query[SEED_KEY] ?: "")
|
||||||
otpElement.digits = query[DIGITS_KEY]?.toIntOrNull() ?: OTP_DEFAULT_DIGITS
|
otpElement.digits = query[DIGITS_KEY]?.toIntOrNull() ?: OTP_DEFAULT_DIGITS
|
||||||
otpElement.period = query[STEP_KEY]?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
|
otpElement.period = query[STEP_KEY]?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
|
||||||
otpElement.type = OtpType.TOTP
|
|
||||||
true
|
true
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
false
|
false
|
||||||
@@ -351,6 +359,7 @@ object OtpEntryFields {
|
|||||||
// malformed
|
// malformed
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
otpElement.type = OtpType.TOTP
|
||||||
otpElement.period = matcher.group(1)?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
|
otpElement.period = matcher.group(1)?.toIntOrNull() ?: TOTP_DEFAULT_PERIOD
|
||||||
matcher.group(2)?.let { secondMatcher ->
|
matcher.group(2)?.let { secondMatcher ->
|
||||||
try {
|
try {
|
||||||
@@ -365,7 +374,6 @@ object OtpEntryFields {
|
|||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
otpElement.type = OtpType.TOTP
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,6 +382,7 @@ object OtpEntryFields {
|
|||||||
val secretHexField = getField(HMACOTP_SECRET_HEX_FIELD)
|
val secretHexField = getField(HMACOTP_SECRET_HEX_FIELD)
|
||||||
val secretBase32Field = getField(HMACOTP_SECRET_BASE32_FIELD)
|
val secretBase32Field = getField(HMACOTP_SECRET_BASE32_FIELD)
|
||||||
val secretBase64Field = getField(HMACOTP_SECRET_BASE64_FIELD)
|
val secretBase64Field = getField(HMACOTP_SECRET_BASE64_FIELD)
|
||||||
|
val secretCounterField = getField(HMACOTP_SECRET_COUNTER_FIELD)
|
||||||
try {
|
try {
|
||||||
when {
|
when {
|
||||||
secretField != null -> otpElement.setUTF8Secret(secretField)
|
secretField != null -> otpElement.setUTF8Secret(secretField)
|
||||||
@@ -382,16 +391,13 @@ object OtpEntryFields {
|
|||||||
secretBase64Field != null -> otpElement.setBase64Secret(secretBase64Field)
|
secretBase64Field != null -> otpElement.setBase64Secret(secretBase64Field)
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
|
otpElement.type = OtpType.HOTP
|
||||||
val secretCounterField = getField(HMACOTP_SECRET_COUNTER_FIELD)
|
|
||||||
if (secretCounterField != null) {
|
if (secretCounterField != null) {
|
||||||
otpElement.counter = secretCounterField.toLongOrNull() ?: HOTP_INITIAL_COUNTER
|
otpElement.counter = secretCounterField.toLongOrNull() ?: HOTP_INITIAL_COUNTER
|
||||||
}
|
}
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
otpElement.type = OtpType.HOTP
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
* Fix search slowdown #964
|
* Fix search slowdown #964
|
||||||
* Fix closing notification after lock request #965
|
* Fix closing notification after lock request #965
|
||||||
* Better temp advanced unlocking code implementation #965
|
* Better temp advanced unlocking code implementation #965
|
||||||
|
* Fix OTP token generation #967
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
* Correction du ralentissement de la recherche #964
|
* Correction du ralentissement de la recherche #964
|
||||||
* Correction de la fermeture de notification après une requête de verrouillage #965
|
* Correction de la fermeture de notification après une requête de verrouillage #965
|
||||||
* Meilleure implémentation du déverrouillage avancé temporaire #965
|
* Meilleure implémentation du déverrouillage avancé temporaire #965
|
||||||
|
* Correction de la génération des jetons de mots de passe uniques #967
|
||||||
Reference in New Issue
Block a user