mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-11-12 13:47:11 +00:00
Keystore AES-GCM for stored secrets; biometric unlock bound to a keystore key (#32)
* Encrypt stored secrets with a keystore AES-GCM key and migrate old values on read Secrets and the PIN were AES-CBC without authentication, under a random key kept in shared preferences and wrapped by a keystore RSA key with PKCS#1 v1.5 padding. They are now AES-256-GCM under a key that never leaves the Android keystore, stored as "v2:" + Base64. Old values stay readable through a read-only decrypter of the previous scheme; nothing is written in it any more and no new RSA key is created. A legacy value is re-encrypted when it is read, and replaced only once the new copy decrypts to the same text. A value that cannot be decrypted now reads as absent and is left untouched, where decrypt() used to return "" and let a caller treat it as a value. * Bind biometric unlock to a keystore key A biometric success was taken from the prompt callback alone. With strong biometrics the prompt now carries a cipher of a keystore key that requires user authentication and is invalidated when biometrics are enrolled: the first prompt seals a random token, later ones must open it, and only an opened token unlocks. If biometrics changed, biometry is turned off and the PIN is asked for. Weak biometrics (most face unlock) cannot use a keystore key and keep the plain prompt. androidx.biometric goes to 1.1.0 for the authenticator classes. * Log the light client under a fixed tag; LOG_TAG in a coroutine named the coroutine
This commit is contained in:
1 parent
35c71062f0
commit
de826acc70
12 files changed
+486
-251
No files matched your search
+6
-5
@@ -2,7 +2,6 @@ package io.novafoundation.nova.runtime.multiNetwork.connection.light
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import io.novafoundation.nova.common.utils.LOG_TAG
|
||||
import io.novafoundation.nova.lightclient.HostResolver
|
||||
import io.novafoundation.nova.lightclient.PezkuwiLight
|
||||
import io.novafoundation.nova.runtime.multiNetwork.chain.model.ChainId
|
||||
@@ -58,7 +57,7 @@ class LightClients(
|
||||
inUse += chainId
|
||||
PezkuwiLight.chainUrl(base, chainId)
|
||||
}.onFailure {
|
||||
Log.w(LOG_TAG, "Light client unavailable for $chainId", it)
|
||||
Log.w(TAG, "Light client unavailable for $chainId", it)
|
||||
}.getOrNull()
|
||||
}
|
||||
}
|
||||
@@ -75,7 +74,7 @@ class LightClients(
|
||||
// Still registered on failure, so a later url() does not register it twice
|
||||
runCatching { PezkuwiLight.removeChain(unused) }
|
||||
.onSuccess { registered -= unused }
|
||||
.onFailure { Log.w(LOG_TAG, "Cannot stop the light client for $unused", it) }
|
||||
.onFailure { Log.w(TAG, "Cannot stop the light client for $unused", it) }
|
||||
.getOrNull() ?: break
|
||||
}
|
||||
}
|
||||
@@ -96,9 +95,9 @@ class LightClients(
|
||||
val candidate = specApi.spec(SPEC_SOURCE + chain.file)
|
||||
if (LightSpecs.isUpdate(current = spec(chain), candidate = candidate)) {
|
||||
writeAtomically(storedSpec(chain), candidate)
|
||||
Log.d(LOG_TAG, "Light client specification ${chain.file} updated")
|
||||
Log.d(TAG, "Light client specification ${chain.file} updated")
|
||||
}
|
||||
}.onFailure { Log.w(LOG_TAG, "Cannot refresh light client specification ${chain.file}", it) }
|
||||
}.onFailure { Log.w(TAG, "Cannot refresh light client specification ${chain.file}", it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,6 +136,8 @@ class LightClients(
|
||||
const val ZAGROS: ChainId = "1b0b4727bbb5e44ed587d1056b4ad537ffb330034509a58866a088d77e792cd5"
|
||||
const val ZAGROS_PEOPLE: ChainId = "c72b38f36affaeb2661018b201c2be02e8c09fc699640525d39200a10fd77878"
|
||||
|
||||
// Not LOG_TAG: called inside a coroutine, it gives the coroutine class name
|
||||
const val TAG = "LightClients"
|
||||
const val DATABASE_DIR = "light-client"
|
||||
const val SPECS_DIR = "light-client-specs"
|
||||
const val BUNDLED_DIR = "light-client/"
|
||||
|
||||
Reference in new issue
Block a user