BIT-1033: Store user key and private key to disc (#197)

This commit is contained in:
Ramsey Smith
2023-11-02 10:41:21 -06:00
committed by Álison Fernandes
parent ad44263028
commit ea5908d2ca
11 changed files with 390 additions and 98 deletions

View File

@@ -21,4 +21,24 @@ interface AuthDiskSource {
* Emits updates that track [userState]. This will replay the last known value, if any.
*/
val userStateFlow: Flow<UserStateJson?>
/**
* Retrieves a user key using a [userId].
*/
fun getUserKey(userId: String): String?
/**
* Stores a user key using a [userId].
*/
fun storeUserKey(userId: String, userKey: String?)
/**
* Retrieves a private key using a [userId].
*/
fun getPrivateKey(userId: String): String?
/**
* Stores a private key using a [userId].
*/
fun storePrivateKey(userId: String, privateKey: String?)
}

View File

@@ -12,6 +12,8 @@ import kotlinx.serialization.json.Json
private const val REMEMBERED_EMAIL_ADDRESS_KEY = "$BASE_KEY:rememberedEmail"
private const val STATE_KEY = "$BASE_KEY:state"
private const val MASTER_KEY_ENCRYPTION_USER_KEY = "masterKeyEncryptedUserKey"
private const val MASTER_KEY_ENCRYPTION_PRIVATE_KEY = "encPrivateKey"
/**
* Primary implementation of [AuthDiskSource].
@@ -56,4 +58,24 @@ class AuthDiskSourceImpl(
STATE_KEY -> mutableUserStateFlow.tryEmit(userState)
}
}
override fun getUserKey(userId: String): String? =
getString(key = "${MASTER_KEY_ENCRYPTION_USER_KEY}_$userId")
override fun storeUserKey(userId: String, userKey: String?) {
putString(
key = "${MASTER_KEY_ENCRYPTION_USER_KEY}_$userId",
value = userKey,
)
}
override fun getPrivateKey(userId: String): String? =
getString(key = "${MASTER_KEY_ENCRYPTION_PRIVATE_KEY}_$userId")
override fun storePrivateKey(userId: String, privateKey: String?) {
putString(
key = "${MASTER_KEY_ENCRYPTION_PRIVATE_KEY}_$userId",
value = privateKey,
)
}
}

View File

@@ -112,6 +112,16 @@ class AuthRepositoryImpl @Inject constructor(
.toUserState(
previousUserState = authDiskSource.userState,
)
.also { userState ->
authDiskSource.storeUserKey(
userId = userState.activeUserId,
userKey = it.key,
)
authDiskSource.storePrivateKey(
userId = userState.activeUserId,
privateKey = it.privateKey,
)
}
LoginResult.Success
}
@@ -131,7 +141,8 @@ class AuthRepositoryImpl @Inject constructor(
val updatedAccounts = currentUserState
.accounts
.filterKeys { it != activeUserId }
authDiskSource.storeUserKey(userId = activeUserId, userKey = null)
authDiskSource.storePrivateKey(userId = activeUserId, privateKey = null)
// Check if there is a new active user
if (updatedAccounts.isNotEmpty()) {
val (updatedActiveUserId, updatedActiveAccount) =

View File

@@ -1,5 +1,6 @@
package com.x8bit.bitwarden.data.vault.repository
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
@@ -15,6 +16,7 @@ import kotlinx.coroutines.launch
class VaultRepositoryImpl constructor(
private val syncService: SyncService,
private val vaultSdkSource: VaultSdkSource,
private val authDiskSource: AuthDiskSource,
dispatcherManager: DispatcherManager,
) : VaultRepository {
@@ -29,8 +31,11 @@ class VaultRepositoryImpl constructor(
.sync()
.fold(
onSuccess = { syncResponse ->
storeUserKeyAndPrivateKey(
userKey = syncResponse.profile?.key,
privateKey = syncResponse.profile?.privateKey,
)
// TODO transform into domain object consumable by VaultViewModel BIT-205.
// TODO initialize crypto in BIT-990
syncResponse.ciphers?.let { networkCiphers ->
vaultSdkSource.decryptCipherList(
@@ -49,4 +54,22 @@ class VaultRepositoryImpl constructor(
)
}
}
private fun storeUserKeyAndPrivateKey(
userKey: String?,
privateKey: String?,
) {
val userId = authDiskSource.userState?.activeUserId ?: return
if (userKey == null || privateKey == null) return
authDiskSource.apply {
storeUserKey(
userId = userId,
userKey = userKey,
)
storePrivateKey(
userId = userId,
privateKey = privateKey,
)
}
}
}

View File

@@ -1,5 +1,6 @@
package com.x8bit.bitwarden.data.vault.repository.di
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
@@ -23,10 +24,12 @@ class VaultRepositoryModule {
fun providesVaultRepository(
syncService: SyncService,
vaultSdkSource: VaultSdkSource,
authDiskSource: AuthDiskSource,
dispatcherManager: DispatcherManager,
): VaultRepository = VaultRepositoryImpl(
syncService = syncService,
vaultSdkSource = vaultSdkSource,
authDiskSource = authDiskSource,
dispatcherManager = dispatcherManager,
)
}