mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Encapsulate String util and fix Key File recognition #844
This commit is contained in:
@@ -43,10 +43,10 @@ import com.kunzisoft.keepass.database.element.security.MemoryProtectionConfig
|
||||
import com.kunzisoft.keepass.database.exception.UnknownKDF
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_3
|
||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_4
|
||||
import com.kunzisoft.keepass.utils.StringUtil.removeSpaceChars
|
||||
import com.kunzisoft.keepass.utils.UnsignedInt
|
||||
import com.kunzisoft.keepass.utils.VariantDictionary
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.Text
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
@@ -385,29 +385,27 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
val doc = documentBuilder.parse(keyInputStream)
|
||||
|
||||
val docElement = doc.documentElement
|
||||
if (docElement == null || !docElement.nodeName.equals(RootElementName, ignoreCase = true)) {
|
||||
val keyFileChildNodes = docElement.childNodes
|
||||
// Root node must be unique and "KeyFile"
|
||||
if (docElement == null
|
||||
|| !docElement.nodeName.equals(XML_NODE_ROOT_NAME, ignoreCase = true)
|
||||
|| keyFileChildNodes.length < 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
val children = docElement.childNodes
|
||||
if (children.length < 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (i in 0 until children.length) {
|
||||
val child = children.item(i)
|
||||
|
||||
if (child.nodeName.equals(KeyElementName, ignoreCase = true)) {
|
||||
val keyChildren = child.childNodes
|
||||
for (j in 0 until keyChildren.length) {
|
||||
val keyChild = keyChildren.item(j)
|
||||
if (keyChild.nodeName.equals(KeyDataElementName, ignoreCase = true)) {
|
||||
val children2 = keyChild.childNodes
|
||||
for (k in 0 until children2.length) {
|
||||
val text = children2.item(k)
|
||||
if (text.nodeType == Node.TEXT_NODE) {
|
||||
val txt = text as Text
|
||||
return Base64.decode(txt.nodeValue, BASE_64_FLAG)
|
||||
for (keyFileChildPosition in 0 until keyFileChildNodes.length) {
|
||||
val keyFileChildNode = keyFileChildNodes.item(keyFileChildPosition)
|
||||
if (keyFileChildNode.nodeName.equals(XML_NODE_KEY_NAME, ignoreCase = true)) {
|
||||
val keyChildNodes = keyFileChildNode.childNodes
|
||||
for (keyChildPosition in 0 until keyChildNodes.length) {
|
||||
val keyChildNode = keyChildNodes.item(keyChildPosition)
|
||||
if (keyChildNode.nodeName.equals(XML_NODE_DATA_NAME, ignoreCase = true)) {
|
||||
val dataChildNodes = keyChildNode.childNodes
|
||||
for (dataChildPosition in 0 until dataChildNodes.length) {
|
||||
val dataChildNode = dataChildNodes.item(dataChildPosition)
|
||||
if (dataChildNode.nodeType == Node.TEXT_NODE) {
|
||||
return Base64.decode(dataChildNode.textContent.removeSpaceChars(),
|
||||
BASE_64_FLAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,11 +632,11 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
private const val DEFAULT_HISTORY_MAX_ITEMS = 10 // -1 unlimited
|
||||
private const val DEFAULT_HISTORY_MAX_SIZE = (6 * 1024 * 1024).toLong() // -1 unlimited
|
||||
|
||||
private const val RootElementName = "KeyFile"
|
||||
//private const val MetaElementName = "Meta";
|
||||
//private const val VersionElementName = "Version";
|
||||
private const val KeyElementName = "Key"
|
||||
private const val KeyDataElementName = "Data"
|
||||
private const val XML_NODE_ROOT_NAME = "KeyFile"
|
||||
private const val XML_NODE_META_NAME = "Meta";
|
||||
private const val XML_NODE_VERSION_NAME = "Version";
|
||||
private const val XML_NODE_KEY_NAME = "Key"
|
||||
private const val XML_NODE_DATA_NAME = "Data"
|
||||
|
||||
const val BASE_64_FLAG = Base64.NO_WRAP
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package com.kunzisoft.keepass.otp
|
||||
|
||||
import com.kunzisoft.keepass.model.OtpModel
|
||||
import com.kunzisoft.keepass.utils.StringUtil.removeSpaceChars
|
||||
import org.apache.commons.codec.binary.Base32
|
||||
import org.apache.commons.codec.binary.Base64
|
||||
import org.apache.commons.codec.binary.Hex
|
||||
@@ -216,17 +217,9 @@ data class OtpElement(var otpModel: OtpModel = OtpModel()) {
|
||||
return secret.isNotEmpty() && checkBase64Secret(secret)
|
||||
}
|
||||
|
||||
fun removeLineChars(parameter: String): String {
|
||||
return parameter.replace("[\\r|\\n|\\t|\\u00A0]+".toRegex(), "")
|
||||
}
|
||||
|
||||
fun removeSpaceChars(parameter: String): String {
|
||||
return parameter.replace("[\\r|\\n|\\t|\\s|\\u00A0]+".toRegex(), "")
|
||||
}
|
||||
|
||||
fun replaceBase32Chars(parameter: String): String {
|
||||
// Add 'A' at end if not Base32 length
|
||||
var parameterNewSize = removeSpaceChars(parameter.toUpperCase(Locale.ENGLISH))
|
||||
var parameterNewSize = parameter.toUpperCase(Locale.ENGLISH).removeSpaceChars()
|
||||
while (parameterNewSize.length % 8 != 0) {
|
||||
parameterNewSize += 'A'
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ import android.net.Uri
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.model.Field
|
||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.removeLineChars
|
||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.removeSpaceChars
|
||||
import com.kunzisoft.keepass.otp.TokenCalculator.*
|
||||
import com.kunzisoft.keepass.utils.StringUtil.removeLineChars
|
||||
import com.kunzisoft.keepass.utils.StringUtil.removeSpaceChars
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -126,7 +126,7 @@ object OtpEntryFields {
|
||||
private fun parseOTPUri(getField: (id: String) -> String?, otpElement: OtpElement): Boolean {
|
||||
val otpPlainText = getField(OTP_FIELD)
|
||||
if (otpPlainText != null && otpPlainText.isNotEmpty() && isOTPUri(otpPlainText)) {
|
||||
val uri = Uri.parse(removeSpaceChars(otpPlainText))
|
||||
val uri = Uri.parse(otpPlainText.removeSpaceChars())
|
||||
|
||||
if (uri.scheme == null || OTP_SCHEME != uri.scheme!!.toLowerCase(Locale.ENGLISH)) {
|
||||
Log.e(TAG, "Invalid or missing scheme in uri")
|
||||
@@ -159,16 +159,16 @@ object OtpEntryFields {
|
||||
if (nameParam != null && nameParam.isNotEmpty()) {
|
||||
val userIdArray = nameParam.split(":", "%3A")
|
||||
if (userIdArray.size > 1) {
|
||||
otpElement.issuer = removeLineChars(userIdArray[0])
|
||||
otpElement.name = removeLineChars(userIdArray[1])
|
||||
otpElement.issuer = userIdArray[0].removeLineChars()
|
||||
otpElement.name = userIdArray[1].removeLineChars()
|
||||
} else {
|
||||
otpElement.name = removeLineChars(nameParam)
|
||||
otpElement.name = nameParam.removeLineChars()
|
||||
}
|
||||
}
|
||||
|
||||
val issuerParam = uri.getQueryParameter(ISSUER_URL_PARAM)
|
||||
if (issuerParam != null && issuerParam.isNotEmpty())
|
||||
otpElement.issuer = removeLineChars(issuerParam)
|
||||
otpElement.issuer = issuerParam.removeLineChars()
|
||||
|
||||
val secretParam = uri.getQueryParameter(SECRET_URL_PARAM)
|
||||
if (secretParam != null && secretParam.isNotEmpty()) {
|
||||
@@ -262,7 +262,7 @@ object OtpEntryFields {
|
||||
}
|
||||
|
||||
private fun encodeParameter(parameter: String): String {
|
||||
return Uri.encode(OtpElement.removeLineChars(parameter))
|
||||
return Uri.encode(parameter.removeLineChars())
|
||||
}
|
||||
|
||||
private fun parseTOTPKeyValues(getField: (id: String) -> String?, otpElement: OtpElement): Boolean {
|
||||
|
||||
12
app/src/main/java/com/kunzisoft/keepass/utils/StringUtil.kt
Normal file
12
app/src/main/java/com/kunzisoft/keepass/utils/StringUtil.kt
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.kunzisoft.keepass.utils
|
||||
|
||||
object StringUtil {
|
||||
|
||||
fun String.removeLineChars(): String {
|
||||
return this.replace("[\\r|\\n|\\t|\\u00A0]+".toRegex(), "")
|
||||
}
|
||||
|
||||
fun String.removeSpaceChars(): String {
|
||||
return this.replace("[\\r|\\n|\\t|\\s|\\u00A0]+".toRegex(), "")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user