From 882e65081baa0b9b40f473d757c553b881104314 Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Wed, 29 Mar 2023 15:37:05 +0300 Subject: [PATCH] Add bsspeke decoding for ssss --- .../SharedSecretStorageService.kt | 10 +++++ .../api/session/securestorage/SsssKeySpec.kt | 14 +++++++ .../DefaultSharedSecretStorageService.kt | 40 ++++++++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) 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 bdbbd3ea..1f3dc4bb 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 @@ -136,4 +136,14 @@ interface SharedSecretStorageService { fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult suspend fun requestSecret(name: String, myOtherDeviceId: String) + + suspend fun generateKeyWithPassphrase( + keyId: String, + keyName: String, + passphrase: String, + keySigner: KeySigner, + progressListener: ProgressListener?, + userName: String? = null, + isBsSpeke: Boolean = false + ): SsssKeyCreationInfo } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt index 35a67b08..a9248c57 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session.securestorage import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey +import org.matrix.android.sdk.internal.crypto.keysbackup.BCryptManager import org.matrix.android.sdk.internal.crypto.keysbackup.deriveKey /** Tag class. */ @@ -47,6 +48,19 @@ data class RawBytesKeySpec( ) } } + + fun fromPassphrase(passphrase: String, salt: String, iterations: Int, + progressListener: ProgressListener?, isBsSpeke: Boolean = false): RawBytesKeySpec { + return RawBytesKeySpec( + privateKey = if (isBsSpeke) BCryptManager.retrievePrivateKeyWithPassword(passphrase, salt, iterations) + else deriveKey( + passphrase, + salt, + iterations, + progressListener + ) + ) + } } override fun equals(other: Any?): Boolean { 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 ddb048a9..4c149e59 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 @@ -42,6 +42,7 @@ import org.matrix.android.sdk.api.session.securestorage.SsssPassphrase import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.SecretShareManager +import org.matrix.android.sdk.internal.crypto.keysbackup.BCryptManager import org.matrix.android.sdk.internal.crypto.keysbackup.generatePrivateKeyWithPassword import org.matrix.android.sdk.internal.crypto.tools.HkdfSha256 import org.matrix.android.sdk.internal.crypto.tools.withOlmDecryption @@ -179,7 +180,7 @@ internal class DefaultSharedSecretStorageService @Inject constructor( throw SharedSecretStorageError.UnknownAlgorithm(key.keyInfo.content.algorithm ?: "") } } - is KeyInfoResult.Error -> throw key.error + is KeyInfoResult.Error -> throw key.error } } @@ -388,4 +389,41 @@ internal class DefaultSharedSecretStorageService @Inject constructor( override suspend fun requestSecret(name: String, myOtherDeviceId: String) { secretShareManager.requestSecretTo(myOtherDeviceId, name) } + + override suspend fun generateKeyWithPassphrase( + keyId: String, + keyName: String, + passphrase: String, + keySigner: KeySigner, + progressListener: ProgressListener?, + userName: String?, + isBsSpeke: Boolean + ): SsssKeyCreationInfo { + return withContext(cryptoCoroutineScope.coroutineContext + coroutineDispatchers.computation) { + val privatePart = if (isBsSpeke) BCryptManager.generateBcryptPrivateKeyWithPassword(userName ?: "", passphrase) + else generatePrivateKeyWithPassword(passphrase, progressListener) + + val storageKeyContent = SecretStorageKeyContent( + algorithm = SSSS_ALGORITHM_AES_HMAC_SHA2, + passphrase = SsssPassphrase(algorithm = "m.pbkdf2", iterations = privatePart.iterations, salt = privatePart.salt) + ) + + 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(privatePart.privateKey), + keySpec = RawBytesKeySpec(privatePart.privateKey) + ) + } + } } -- GitLab