From d46adba7a7e596bf245ed30d9e0d26e7dd755b2f Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Thu, 24 Aug 2023 16:45:01 +0300
Subject: [PATCH] Add generateBsSpekeWithPassphrase

---
 .../SharedSecretStorageService.kt             | 13 ++++--
 .../DefaultSharedSecretStorageService.kt      | 45 ++++++++++++++++---
 2 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt
index 1f3dc4bb..d48a72b5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt
@@ -137,13 +137,18 @@ interface SharedSecretStorageService {
 
     suspend fun requestSecret(name: String, myOtherDeviceId: String)
 
-    suspend fun generateKeyWithPassphrase(
+    suspend fun generateBCryptKeyWithPassphrase(
             keyId: String,
-            keyName: String,
             passphrase: String,
             keySigner: KeySigner,
             progressListener: ProgressListener?,
-            userName: String? = null,
-            isBsSpeke: Boolean = false
+            userName: String
+    ): SsssKeyCreationInfo
+
+    suspend fun generateBsSpekeWithPassphrase(
+            keyId: String,
+            privateKey: ByteArray,
+            keySigner: KeySigner,
+            progressListener: ProgressListener?
     ): SsssKeyCreationInfo
 }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
index 4c149e59..b886751b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt
@@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.crypto.secrets
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.withContext
 import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
+import org.matrix.android.sdk.api.crypto.BCRYPT_ALGORITHM_BACKUP
+import org.matrix.android.sdk.api.crypto.BSSPEKE_ALGORITHM_BACKUP
 import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2
 import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2
 import org.matrix.android.sdk.api.extensions.orFalse
@@ -180,6 +182,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
                             throw SharedSecretStorageError.UnknownAlgorithm(key.keyInfo.content.algorithm ?: "")
                         }
                     }
+
                     is KeyInfoResult.Error   -> throw key.error
                 }
             }
@@ -390,22 +393,19 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
         secretShareManager.requestSecretTo(myOtherDeviceId, name)
     }
 
-    override suspend fun generateKeyWithPassphrase(
+    override suspend fun generateBCryptKeyWithPassphrase(
             keyId: String,
-            keyName: String,
             passphrase: String,
             keySigner: KeySigner,
             progressListener: ProgressListener?,
-            userName: String?,
-            isBsSpeke: Boolean
+            userName: String
     ): SsssKeyCreationInfo {
         return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
-            val privatePart = if (isBsSpeke) BCryptManager.generateBcryptPrivateKeyWithPassword(userName ?: "", passphrase)
-            else generatePrivateKeyWithPassword(passphrase, progressListener)
+            val privatePart = BCryptManager.generateBcryptPrivateKeyWithPassword(userName, passphrase)
 
             val storageKeyContent = SecretStorageKeyContent(
                     algorithm = SSSS_ALGORITHM_AES_HMAC_SHA2,
-                    passphrase = SsssPassphrase(algorithm = "m.pbkdf2", iterations = privatePart.iterations, salt = privatePart.salt)
+                    passphrase = SsssPassphrase(algorithm = BCRYPT_ALGORITHM_BACKUP, iterations = privatePart.iterations, salt = privatePart.salt)
             )
 
             val signedContent = keySigner.sign(storageKeyContent.canonicalSignable())?.let {
@@ -426,4 +426,35 @@ internal class DefaultSharedSecretStorageService @Inject constructor(
             )
         }
     }
+
+    override suspend fun generateBsSpekeWithPassphrase(
+            keyId: String,
+            privateKey: ByteArray,
+            keySigner: KeySigner,
+            progressListener: ProgressListener?
+    ): SsssKeyCreationInfo {
+        return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) {
+            val storageKeyContent = SecretStorageKeyContent(
+                    algorithm = SSSS_ALGORITHM_AES_HMAC_SHA2,
+                    passphrase = SsssPassphrase(algorithm = BSSPEKE_ALGORITHM_BACKUP, iterations = null, salt = null)
+            )
+
+            val signedContent = keySigner.sign(storageKeyContent.canonicalSignable())?.let {
+                storageKeyContent.copy(
+                        signatures = it
+                )
+            } ?: storageKeyContent
+
+            accountDataService.updateUserAccountData(
+                    "$KEY_ID_BASE.$keyId",
+                    signedContent.toContent()
+            )
+            SsssKeyCreationInfo(
+                    keyId = keyId,
+                    content = storageKeyContent,
+                    recoveryKey = computeRecoveryKey(privateKey),
+                    keySpec = RawBytesKeySpec(privateKey)
+            )
+        }
+    }
 }
-- 
GitLab