Better implementation for challenge response intent

This commit is contained in:
J-Jamet
2022-04-27 14:39:08 +02:00
parent e8f79ae467
commit 5b4338abae

View File

@@ -64,62 +64,41 @@ class HardwareKeyResponseHelper {
fun launchChallengeForResponse(databaseUri: Uri) { fun launchChallengeForResponse(databaseUri: Uri) {
fragment?.context?.contentResolver ?: activity?.contentResolver ?.let { contentResolver -> fragment?.context?.contentResolver ?: activity?.contentResolver ?.let { contentResolver ->
getTransformSeedFromHeader(databaseUri, contentResolver)?.let { seed -> getTransformSeedFromHeader(databaseUri, contentResolver)?.let { seed ->
// seed: 32 byte transform seed, needs to be padded before sent to the hardware
val challenge = ByteArray(64)
System.arraycopy(seed, 0, challenge, 0, 32)
challenge.fill(32, 32, 64)
val intent = Intent("net.pp3345.ykdroid.intent.action.CHALLENGE_RESPONSE")
Log.d(TAG, "Challenge sent to yubikey: " + challenge.contentToString())
intent.putExtra("challenge", challenge)
try { try {
getChallengeResponseResultLauncher?.launch(intent) getChallengeResponseResultLauncher?.launch(Intent(YKDROID_CHALLENGE_RESPONSE_INTENT).apply {
putExtra(YKDROID_SEED_KEY, seed)
})
Log.d(TAG, "Challenge sent : " + seed.contentToString())
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
// TODO better error // TODO better error
throw IOException("No activity to handle CHALLENGE_RESPONSE intent") throw IOException("No activity to handle $YKDROID_CHALLENGE_RESPONSE_INTENT intent")
} }
} }
} }
} }
private fun getTransformSeedFromHeader(uri: Uri, contentResolver: ContentResolver): ByteArray? { private fun getTransformSeedFromHeader(uri: Uri, contentResolver: ContentResolver): ByteArray? {
// TODO better implementation
var databaseInputStream: InputStream? = null
var challenge: ByteArray? = null
try { try {
// Load Data, pass Uris as InputStreams BufferedInputStream(UriUtil.getUriInputStream(contentResolver, uri)).use { databaseInputStream ->
val databaseStream = UriUtil.getUriInputStream(contentResolver, uri) val header = DatabaseHeaderKDBX(DatabaseKDBX())
?: throw IOException("Database input stream cannot be retrieve") header.loadFromFile(databaseInputStream)
val challenge = ByteArray(64)
databaseInputStream = BufferedInputStream(databaseStream) header.transformSeed?.copyInto(challenge, 0, 0, 32)
if (!databaseInputStream.markSupported()) { // seed: 32 byte transform seed, needs to be padded before sent to the hardware
throw IOException("Input stream does not support mark.") challenge.fill(32, 32, 64)
return challenge
} }
// We'll end up reading 8 bytes to identify the header. Might as well use two extra.
databaseInputStream.mark(10)
// Return to the start
databaseInputStream.reset()
val header = DatabaseHeaderKDBX(DatabaseKDBX())
header.loadFromFile(databaseInputStream)
challenge = ByteArray(64)
System.arraycopy(header.transformSeed, 0, challenge, 0, 32)
challenge.fill(32, 32, 64)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Could not read transform seed from file") Log.e(TAG, "Could not read transform seed from file", e)
} finally {
databaseInputStream?.close()
} }
return null
return challenge
} }
companion object { companion object {
private val TAG = HardwareKeyResponseHelper::class.java.simpleName private val TAG = HardwareKeyResponseHelper::class.java.simpleName
private const val YKDROID_CHALLENGE_RESPONSE_INTENT = "net.pp3345.ykdroid.intent.action.CHALLENGE_RESPONSE"
private const val YKDROID_SEED_KEY = "challenge"
} }
} }