From fd8293ba55fcc9ef4bb2f22bcf2680fca4ba3b5c Mon Sep 17 00:00:00 2001 From: Brian Yencho Date: Mon, 15 Jan 2024 22:18:22 -0600 Subject: [PATCH] Add getPinProtectedUserKey to VaultSdkSource (#632) --- .../vault/datasource/sdk/VaultSdkSource.kt | 14 +++++++++++ .../datasource/sdk/VaultSdkSourceImpl.kt | 10 ++++++++ .../datasource/sdk/VaultSdkSourceTest.kt | 24 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSource.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSource.kt index d551d1d11..a1222ae75 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSource.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSource.kt @@ -41,6 +41,20 @@ interface VaultSdkSource { pin: String, ): Result + /** + * Derives a pin-protected user key from the given [encryptedPin] for the given [userId]. This + * value must be derived from a previous call to [derivePinKey] with a plaintext PIN. This can + * be used to later unlock their vault via a call to [initializeCrypto] with + * [InitUserCryptoMethod.Pin]. + * + * This should only be called after a successful call to [initializeCrypto] for the associated + * user. + */ + suspend fun derivePinProtectedUserKey( + userId: String, + encryptedPin: String, + ): Result + /** * Gets the user's encryption key, which can be used to later unlock their vault via a call to * [initializeCrypto] with [InitUserCryptoMethod.DecryptedKey]. diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt index 220349752..fd0d29cb0 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceImpl.kt @@ -42,6 +42,16 @@ class VaultSdkSourceImpl( .derivePinKey(pin = pin) } + override suspend fun derivePinProtectedUserKey( + userId: String, + encryptedPin: String, + ): Result = + runCatching { + getClient(userId = userId) + .crypto() + .derivePinUserKey(encryptedPin = encryptedPin) + } + override suspend fun getUserEncryptionKey( userId: String, ): Result = diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt index 044b5f157..b27b9b18b 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/VaultSdkSourceTest.kt @@ -83,6 +83,30 @@ class VaultSdkSourceTest { verify { sdkClientManager.getOrCreateClient(userId = userId) } } + @Suppress("MaxLineLength") + @Test + fun `derivePinProtectedUserKey should call SDK and return a Result with the correct data`() = + runBlocking { + val userId = "userId" + val encryptedPin = "encryptedPin" + val expectedResult = "pinProtectedUserKey" + coEvery { + clientCrypto.derivePinUserKey(encryptedPin = encryptedPin) + } returns expectedResult + val result = vaultSdkSource.derivePinProtectedUserKey( + userId = userId, + encryptedPin = encryptedPin, + ) + assertEquals( + expectedResult.asSuccess(), + result, + ) + coVerify { + clientCrypto.derivePinUserKey(encryptedPin = encryptedPin) + } + verify { sdkClientManager.getOrCreateClient(userId = userId) } + } + @Test fun `getUserEncryptionKey should call SDK and return a Result with correct data`() = runBlocking {