feat: migrate secret management to datastore proto and tink

This commit is contained in:
2026-06-02 18:15:22 +02:00
parent 2be68d38a5
commit e8b3f898e8
16 changed files with 328 additions and 128 deletions
@@ -0,0 +1,45 @@
package com.bitcointxoko.gudariwallet.security
import android.content.Context
import android.util.Log
import com.bitcointxoko.gudariwallet.util.WalletConstants
import com.google.crypto.tink.StreamingAead
import com.google.crypto.tink.integration.android.AndroidKeysetManager
import com.google.crypto.tink.streamingaead.StreamingAeadConfig
import com.google.crypto.tink.KeyTemplates
/**
* Manages the Tink keyset used to encrypt the credentials DataStore file.
*
* The keyset itself is stored in SharedPreferences, encrypted under an
* Android Keystore master key — so the key material never leaves secure hardware.
*/
object CredentialsTinkManager {
private const val TAG = "CredentialsTinkManager"
init {
// Register all StreamingAead primitives once at class load time
StreamingAeadConfig.register()
Log.d(TAG, "StreamingAeadConfig registered")
}
fun getOrCreateStreamingAead(context: Context): StreamingAead {
return try {
val handle = AndroidKeysetManager.Builder()
.withSharedPref(context, WalletConstants.TINK_KEYSET_KEY, WalletConstants.TINK_KEYSET_PREF)
.withKeyTemplate(KeyTemplates.get("AES256_GCM_HKDF_4KB"))
.withMasterKeyUri(WalletConstants.TINK_MASTER_KEY_URI)
.build()
.keysetHandle
Log.i(TAG, "Keyset loaded — key count: ${handle.size()}, primary key ID: ${handle.primary.id}")
handle.getPrimitive(StreamingAead::class.java).also {
Log.i(TAG, "StreamingAead primitive acquired successfully")
}
} catch (e: Exception) {
Log.e(TAG, "Failed to initialise StreamingAead — Keystore may be unavailable", e)
throw e
}
}
}