diff --git a/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/create/CreatePassPhraseDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/create/CreatePassPhraseDataSource.kt index 9dc6c754bad907b60df768099265a5be0d9b2405..01a12aa6442689d3216853431eea1bbf2d723e11 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/create/CreatePassPhraseDataSource.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/create/CreatePassPhraseDataSource.kt @@ -1,6 +1,7 @@ package org.futo.circles.auth.feature.pass_phrase.create import android.content.Context +import android.util.Log import androidx.lifecycle.MutableLiveData import dagger.hilt.android.qualifiers.ApplicationContext import org.futo.circles.auth.R @@ -28,11 +29,16 @@ class CreatePassPhraseDataSource @Inject constructor( suspend fun createPassPhraseBackup() { loadingLiveData.postValue(LoadingData(messageId = R.string.generating_recovery_key)) val keyBackupPrivateKey = generateRandomPrivateKey() + Log.d("MyLog", "createPassPhraseBackup random private key $keyBackupPrivateKey") + val backupCreationInfo = keysBackupService.prepareKeysBackupVersion(keyBackupPrivateKey, null) + + Log.d("MyLog", "createPassPhraseBackup backupCreationInfo $backupCreationInfo") + createKeyBackup(backupCreationInfo) - val keyData = ssssDataSource.storeBsSpekeKeyIntoSSSS(keyBackupPrivateKey) - crossSigningDataSource.initCrossSigningIfNeed(keyData.keySpec) + val keySpec = ssssDataSource.storeBsSpekeKeyIntoSSSS(keyBackupPrivateKey) + crossSigningDataSource.initCrossSigningIfNeed(keySpec) loadingLiveData.postValue(LoadingData(isLoading = false)) } diff --git a/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/RestoreBackupDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/RestoreBackupDataSource.kt index fcdd46dd01766e4535130bacbb3a4c3895d69e41..b422a3843d1c7ccbe138f9d576907f431f7c9348 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/RestoreBackupDataSource.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/RestoreBackupDataSource.kt @@ -3,16 +3,16 @@ package org.futo.circles.auth.feature.pass_phrase.restore import android.annotation.SuppressLint import android.content.Context import android.net.Uri +import android.util.Log import androidx.lifecycle.MutableLiveData import dagger.hilt.android.qualifiers.ApplicationContext import org.futo.circles.auth.R import org.futo.circles.auth.feature.cross_signing.CrossSigningDataSource -import org.futo.circles.auth.model.KeyData +import org.futo.circles.auth.model.SecretKeyData import org.futo.circles.core.model.LoadingData import org.futo.circles.core.provider.MatrixSessionProvider import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.listeners.StepProgressListener -import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult import javax.inject.Inject @@ -75,7 +75,7 @@ class RestoreBackupDataSource @Inject constructor( suspend fun restoreWithBsSpekeKey() { try { - val keyData = ssssDataSource.getBsSpekeRecoveryKey(progressObserver) + val keyData = ssssDataSource.getBsSpekeSecretKeyData(progressObserver) restoreKeysWithRecoveryKey(keyData) } catch (e: Throwable) { loadingLiveData.postValue(LoadingData(isLoading = false)) @@ -87,7 +87,7 @@ class RestoreBackupDataSource @Inject constructor( suspend fun restoreKeysWithPassPhase(passphrase: String) { try { val keyData = - ssssDataSource.getRecoveryKeyFromPassphrase(passphrase, progressObserver) + ssssDataSource.getSecretKeyDataFromPassphrase(passphrase, progressObserver) restoreKeysWithRecoveryKey(keyData) } catch (e: Throwable) { loadingLiveData.postValue(LoadingData(isLoading = false)) @@ -96,18 +96,20 @@ class RestoreBackupDataSource @Inject constructor( loadingLiveData.postValue(LoadingData(isLoading = false)) } - private suspend fun restoreKeysWithRecoveryKey(keyData: KeyData) { + private suspend fun restoreKeysWithRecoveryKey(secretKeyData: SecretKeyData) { + + Log.d("MyLog", "keydata $secretKeyData") val keysBackupService = getKeysBackupService() try { val keyVersion = getKeysVersion(keysBackupService) keysBackupService.restoreKeysWithRecoveryKey( keyVersion, - BackupRecoveryKey.fromBase58(keyData.recoveryKey), + secretKeyData.getBackupRecoveryKey(), null, MatrixSessionProvider.currentSession?.myUserId, progressObserver ) - crossSigningDataSource.configureCrossSigning(keyData.keySpec) + crossSigningDataSource.configureCrossSigning(secretKeyData.keySpec) keysBackupService.trustKeysBackupVersion(keyVersion, true) } catch (e: Throwable) { loadingLiveData.postValue(LoadingData(isLoading = false)) @@ -118,7 +120,7 @@ class RestoreBackupDataSource @Inject constructor( suspend fun restoreKeysWithRawKey(rawKey: String) { try { - val keyData = ssssDataSource.getRecoveryKeyFromFileKey(rawKey, progressObserver) + val keyData = ssssDataSource.getSecretKeyDataKeyFromFileKey(rawKey, progressObserver) restoreKeysWithRecoveryKey(keyData) } catch (e: Throwable) { loadingLiveData.postValue(LoadingData(isLoading = false)) @@ -130,7 +132,7 @@ class RestoreBackupDataSource @Inject constructor( suspend fun restoreKeysWithRecoveryKey(uri: Uri) { try { val key = readRecoveryKeyFile(uri) - val keyData = ssssDataSource.getRecoveryKeyFromFileKey(key, progressObserver) + val keyData = ssssDataSource.getSecretKeyDataKeyFromFileKey(key, progressObserver) restoreKeysWithRecoveryKey(keyData) } catch (e: Throwable) { loadingLiveData.postValue(LoadingData(isLoading = false)) diff --git a/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/SSSSDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/SSSSDataSource.kt index 142ffd9c2589611e7785cd3fca601bc81297cb3a..ba30e61befffc0d19d2587fcaa63dddcfeb345b4 100644 --- a/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/SSSSDataSource.kt +++ b/auth/src/main/java/org/futo/circles/auth/feature/pass_phrase/restore/SSSSDataSource.kt @@ -1,14 +1,13 @@ package org.futo.circles.auth.feature.pass_phrase.restore +import android.util.Log import org.futo.circles.auth.bsspeke.BSSpekeClientProvider -import org.futo.circles.auth.model.KeyData +import org.futo.circles.auth.model.SecretKeyData import org.futo.circles.core.provider.MatrixSessionProvider import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME -import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey -import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner import org.matrix.android.sdk.api.session.securestorage.KeyInfo @@ -16,35 +15,43 @@ import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult import org.matrix.android.sdk.api.session.securestorage.KeyRef import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo -import org.matrix.android.sdk.api.util.fromBase64 +import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec import org.matrix.android.sdk.api.util.toBase64NoPadding import javax.inject.Inject class SSSSDataSource @Inject constructor() { - suspend fun storeBsSpekeKeyIntoSSSS(keyBackupPrivateKey: ByteArray): KeyData { + suspend fun storeBsSpekeKeyIntoSSSS(keyBackupPrivateKey: ByteArray): SsssKeySpec { val session = MatrixSessionProvider.getSessionOrThrow() val bsSpekeClient = BSSpekeClientProvider.getClientOrThrow() val keyId = bsSpekeClient.generateKeyId() val key = bsSpekeClient.generateHashKey() + Log.d("MyLog", "store key $key") + val keyInfo = session.sharedSecretStorageService() .generateBsSpekeKeyInfo(keyId, key, EmptyKeySigner()) + + Log.d("MyLog", "store keyinfo $keyInfo") + storeSecret(session, keyBackupPrivateKey, keyInfo) - return KeyData(keyInfo.recoveryKey, keyInfo.keySpec) + return keyInfo.keySpec } - suspend fun getBsSpekeRecoveryKey(progressObserver: StepProgressListener): KeyData { + suspend fun getBsSpekeSecretKeyData(progressObserver: StepProgressListener): SecretKeyData { progressObserver.onStepProgress( StepProgressListener.Step.ComputingKey(0, 0) ) val keyInfo = getKeyInfo() + Log.d("MyLog", "key info $keyInfo") val keySpec = RawBytesKeySpec( BSSpekeClientProvider.getClientOrThrow().generateHashKey() ) + Log.d("MyLog", "key spec $keySpec") + val secret = getSecret(keyInfo, keySpec) ?: throw Exception("Backup could not be decrypted with this passphrase") - return KeyData(computeRecoveryKey(secret.fromBase64()), keySpec) + return SecretKeyData(secret, keySpec) } suspend fun replaceBsSpeke4SKey() { @@ -57,10 +64,10 @@ class SSSSDataSource @Inject constructor() { storeBsSpekeKeyIntoSSSS(secret) } - suspend fun getRecoveryKeyFromPassphrase( + suspend fun getSecretKeyDataFromPassphrase( passphrase: String, progressObserver: StepProgressListener - ): KeyData { + ): SecretKeyData { val keyInfo = getKeyInfo() progressObserver.onStepProgress( @@ -82,13 +89,13 @@ class SSSSDataSource @Inject constructor() { val secret = getSecret(keyInfo, keySpec) ?: throw Exception("Backup could not be decrypted with this passphrase") - return KeyData(computeRecoveryKey(secret.fromBase64()), keySpec) + return SecretKeyData(secret, keySpec) } - suspend fun getRecoveryKeyFromFileKey( + suspend fun getSecretKeyDataKeyFromFileKey( recoveryKey: String, progressObserver: StepProgressListener - ): KeyData { + ): SecretKeyData { val keyInfo = getKeyInfo() progressObserver.onStepProgress( @@ -100,7 +107,7 @@ class SSSSDataSource @Inject constructor() { val secret = getSecret(keyInfo, keySpec) ?: throw Exception("Backup could not be decrypted with this recovery key") - return KeyData(computeRecoveryKey(secret.fromBase64()), keySpec) + return SecretKeyData(secret, keySpec) } private suspend fun storeSecret( @@ -113,8 +120,16 @@ class SSSSDataSource @Inject constructor() { secretBase64 = keyBackupPrivateKey.toBase64NoPadding(), keys = listOf(KeyRef(keyInfo.keyId, keyInfo.keySpec)) ) + + Log.d( + "MyLog", + "storeSecret secretBase64 ${keyBackupPrivateKey.toBase64NoPadding()}, key info $keyInfo" + ) + session.cryptoService().keysBackupService() .onSecretKeyGossip(keyBackupPrivateKey.toBase64NoPadding()) + Log.d("MyLog", "onSecretKeyGossip secretBase64 ${keyBackupPrivateKey.toBase64NoPadding()}") + session.sharedSecretStorageService().setDefaultKey(keyInfo.keyId) } diff --git a/auth/src/main/java/org/futo/circles/auth/model/KeyData.kt b/auth/src/main/java/org/futo/circles/auth/model/KeyData.kt deleted file mode 100644 index a565dd9d4e711904bf12cac02669656b81034699..0000000000000000000000000000000000000000 --- a/auth/src/main/java/org/futo/circles/auth/model/KeyData.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.futo.circles.auth.model - -import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec - -data class KeyData( - val recoveryKey: String, - val keySpec: SsssKeySpec -) \ No newline at end of file diff --git a/auth/src/main/java/org/futo/circles/auth/model/SecretKeyData.kt b/auth/src/main/java/org/futo/circles/auth/model/SecretKeyData.kt new file mode 100644 index 0000000000000000000000000000000000000000..9a21d80ca11cc84b5d1fd10a59c29e7201655996 --- /dev/null +++ b/auth/src/main/java/org/futo/circles/auth/model/SecretKeyData.kt @@ -0,0 +1,17 @@ +package org.futo.circles.auth.model + +import org.matrix.android.sdk.api.session.crypto.keysbackup.BackupRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey +import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec +import org.matrix.android.sdk.api.util.fromBase64 + +data class SecretKeyData( + val secretBase64: String, + val keySpec: SsssKeySpec +) { + fun getBackupRecoveryKey(): BackupRecoveryKey { + val recoveryBase58 = computeRecoveryKey(secretBase64.fromBase64()) + return BackupRecoveryKey.fromBase58(recoveryBase58) + } + +} \ No newline at end of file diff --git a/core/build.gradle b/core/build.gradle index 84ac56eaafd83159a8f56bfc5fba84868db860d4..932d0edb44b93011cd83f02f22068a1ed738a1ce 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -85,7 +85,7 @@ dependencies { // } //Matrix mavenLocal testing - api "org.futo.gitlab.circles:matrix-android-sdk:0.1.46" + api "org.futo.gitlab.circles:matrix-android-sdk:0.1.57" //Retrofit2 def retrofit_version = '2.11.0' diff --git a/settings/src/main/java/org/futo/circles/settings/feature/active_sessions/ActiveSessionsDataSource.kt b/settings/src/main/java/org/futo/circles/settings/feature/active_sessions/ActiveSessionsDataSource.kt index f3f8a057aeac6c75cc27d1bc7b0be625a30e80cc..55a4b4dd60ccd20617793b1e93cff575ab5ca8ee 100644 --- a/settings/src/main/java/org/futo/circles/settings/feature/active_sessions/ActiveSessionsDataSource.kt +++ b/settings/src/main/java/org/futo/circles/settings/feature/active_sessions/ActiveSessionsDataSource.kt @@ -74,14 +74,14 @@ class ActiveSessionsDataSource @Inject constructor( if (otherSessions.isNotEmpty()) { sessionsList.add(SessionHeader(context.getString(R.string.other_sessions))) sessionsList.addAll(otherSessions.mapNotNull { - if (!it.isDehydrated) { + // if (!it.isDehydrated) { ActiveSession( cryptoDeviceInfo = it, canVerify = isCurrentSessionVerified && it.trustLevel?.isCrossSigningVerified() != true, isResetKeysVisible = false, isOptionsVisible = sessionsWithVisibleOptions.contains(it.deviceId) ) - } else null + //} else null } ) }