mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: Private key format #2164
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.kunzisoft.keepass.credentialprovider.passkey.data
|
package com.kunzisoft.keepass.credentialprovider.passkey.data
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.credentials.exceptions.GetCredentialUnknownException
|
import androidx.credentials.exceptions.GetCredentialUnknownException
|
||||||
import com.kunzisoft.encrypt.Signature
|
import com.kunzisoft.encrypt.Signature
|
||||||
import com.kunzisoft.encrypt.Base64Helper.Companion.b64Encode
|
import com.kunzisoft.encrypt.Base64Helper.Companion.b64Encode
|
||||||
@@ -46,8 +47,12 @@ class AuthenticatorAssertionResponse(
|
|||||||
private var signature: ByteArray = byteArrayOf()
|
private var signature: ByteArray = byteArrayOf()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
try {
|
||||||
signature = Signature.sign(privateKey, dataToSign())
|
signature = Signature.sign(privateKey, dataToSign())
|
||||||
?: throw GetCredentialUnknownException("signing failed")
|
} catch (e: Exception) {
|
||||||
|
Log.e(this::class.java.simpleName, "Unable to sign: ${e.message}")
|
||||||
|
throw GetCredentialUnknownException("Signing failed")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dataToSign(): ByteArray {
|
private fun dataToSign(): ByteArray {
|
||||||
|
|||||||
@@ -58,12 +58,17 @@ object Signature {
|
|||||||
|
|
||||||
const val ED_DSA_ALGORITHM: Long = -8
|
const val ED_DSA_ALGORITHM: Long = -8
|
||||||
|
|
||||||
|
private const val BEGIN_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----"
|
||||||
|
private const val BEGIN_PRIVATE_KEY_LINE_BREAK = "$BEGIN_PRIVATE_KEY\n"
|
||||||
|
private const val END_PRIVATE_KEY = "-----END PRIVATE KEY-----"
|
||||||
|
private const val END_PRIVATE_KEY_LINE_BREAK = "\n$END_PRIVATE_KEY"
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME)
|
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME)
|
||||||
Security.addProvider(BouncyCastleProvider())
|
Security.addProvider(BouncyCastleProvider())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sign(privateKeyPem: String, message: ByteArray): ByteArray? {
|
fun sign(privateKeyPem: String, message: ByteArray): ByteArray {
|
||||||
val privateKey = createPrivateKey(privateKeyPem)
|
val privateKey = createPrivateKey(privateKeyPem)
|
||||||
val algorithmKey = privateKey.algorithm
|
val algorithmKey = privateKey.algorithm
|
||||||
val algorithmSignature = when (algorithmKey) {
|
val algorithmSignature = when (algorithmKey) {
|
||||||
@@ -71,22 +76,30 @@ object Signature {
|
|||||||
"ECDSA" -> "SHA256withECDSA"
|
"ECDSA" -> "SHA256withECDSA"
|
||||||
"RSA" -> "SHA256withRSA"
|
"RSA" -> "SHA256withRSA"
|
||||||
"Ed25519" -> "Ed25519"
|
"Ed25519" -> "Ed25519"
|
||||||
else -> null
|
else -> throw SecurityException("$algorithmKey algorithm is unknown")
|
||||||
}
|
}
|
||||||
if (algorithmSignature == null) {
|
val sig = Signature.getInstance(
|
||||||
Log.e(this::class.java.simpleName, "sign: the algorithm $algorithmKey is unknown")
|
algorithmSignature,
|
||||||
return null
|
BouncyCastleProvider.PROVIDER_NAME
|
||||||
}
|
)
|
||||||
val sig = Signature.getInstance(algorithmSignature, BouncyCastleProvider.PROVIDER_NAME)
|
|
||||||
sig.initSign(privateKey)
|
sig.initSign(privateKey)
|
||||||
sig.update(message)
|
sig.update(message)
|
||||||
return sig.sign()
|
return sig.sign()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createPrivateKey(privateKeyPem: String): PrivateKey {
|
fun createPrivateKey(privateKeyPem: String): PrivateKey {
|
||||||
val targetReader = StringReader(privateKeyPem)
|
var privateKeyString = privateKeyPem
|
||||||
|
if (privateKeyPem.startsWith(BEGIN_PRIVATE_KEY_LINE_BREAK).not()) {
|
||||||
|
privateKeyString = privateKeyString.removePrefix(BEGIN_PRIVATE_KEY)
|
||||||
|
privateKeyString = "$BEGIN_PRIVATE_KEY_LINE_BREAK$privateKeyString"
|
||||||
|
}
|
||||||
|
if (privateKeyPem.endsWith(END_PRIVATE_KEY_LINE_BREAK).not()) {
|
||||||
|
privateKeyString = privateKeyString.removeSuffix(END_PRIVATE_KEY)
|
||||||
|
privateKeyString += END_PRIVATE_KEY_LINE_BREAK
|
||||||
|
}
|
||||||
|
val targetReader = StringReader(privateKeyString)
|
||||||
val pemParser = PEMParser(targetReader)
|
val pemParser = PEMParser(targetReader)
|
||||||
val privateKeyInfo = pemParser.readObject() as PrivateKeyInfo
|
val privateKeyInfo = pemParser.readObject() as? PrivateKeyInfo?
|
||||||
val privateKey = JcaPEMKeyConverter().getPrivateKey(privateKeyInfo)
|
val privateKey = JcaPEMKeyConverter().getPrivateKey(privateKeyInfo)
|
||||||
pemParser.close()
|
pemParser.close()
|
||||||
targetReader.close()
|
targetReader.close()
|
||||||
|
|||||||
Reference in New Issue
Block a user