diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt index f1c998cee5..6e4960b821 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/crosssigning/CrossSigningService.kt @@ -74,6 +74,7 @@ interface CrossSigningService { otherDeviceId: String, locallyTrusted: Boolean?): DeviceTrustResult + fun onSecretMSKGossip(mskPrivateKey: String) fun onSecretSSKGossip(sskPrivateKey: String) fun onSecretUSKGossip(uskPrivateKey: String) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt index a588cdc66e..4b031211e1 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt @@ -34,6 +34,7 @@ import im.vector.matrix.android.api.listeners.ProgressListener import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME +import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.keyshare.GossipingRequestListener @@ -835,6 +836,10 @@ internal class DefaultCryptoService @Inject constructor( */ private fun handleSDKLevelGossip(secretName: String?, secretValue: String): Boolean { return when (secretName) { + MASTER_KEY_SSSS_NAME -> { + crossSigningService.onSecretMSKGossip(secretValue) + true + } SELF_SIGNING_KEY_SSSS_NAME -> { crossSigningService.onSecretSSKGossip(secretValue) true diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt index 38f81ba47d..addcc539e4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/IncomingGossipingRequestManager.kt @@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.crypto import im.vector.matrix.android.api.auth.data.Credentials import im.vector.matrix.android.api.crypto.MXCryptoConfig import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME +import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.keyshare.GossipingRequestListener @@ -310,8 +311,8 @@ internal class IncomingGossipingRequestManager @Inject constructor( val isDeviceLocallyVerified = cryptoStore.getUserDevice(userId, deviceId)?.trustLevel?.isLocallyVerified() - // Should SDK always Silently reject any request for the master key? when (secretName) { + MASTER_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.master SELF_SIGNING_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.selfSigned USER_SIGNING_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.user KEYBACKUP_SECRET_SSSS_NAME -> cryptoStore.getKeyBackupRecoveryKeyInfo()?.recoveryKey diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt index 2fee8130fb..445c44de0e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/crosssigning/DefaultCrossSigningService.kt @@ -168,6 +168,33 @@ internal class DefaultCrossSigningService @Inject constructor( }.executeBy(taskExecutor) } + override fun onSecretMSKGossip(mskPrivateKey: String) { + Timber.i("## CrossSigning - onSecretSSKGossip") + val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { + Timber.e("## CrossSigning - onSecretMSKGossip() received secret but public key is not known") + } + + mskPrivateKey.fromBase64() + .let { privateKeySeed -> + val pkSigning = OlmPkSigning() + try { + if (pkSigning.initWithSeed(privateKeySeed) == mxCrossSigningInfo.masterKey()?.unpaddedBase64PublicKey) { + masterPkSigning?.releaseSigning() + masterPkSigning = pkSigning + Timber.i("## CrossSigning - Loading MSK success") + cryptoStore.storeMSKPrivateKey(mskPrivateKey) + return + } else { + Timber.e("## CrossSigning - onSecretMSKGossip() private key do not match public key") + pkSigning.releaseSigning() + } + } catch (failure: Throwable) { + Timber.e("## CrossSigning - onSecretMSKGossip() ${failure.localizedMessage}") + pkSigning.releaseSigning() + } + } + } + override fun onSecretSSKGossip(sskPrivateKey: String) { Timber.i("## CrossSigning - onSecretSSKGossip") val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt index 69f0985391..7125cadebf 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt @@ -397,6 +397,7 @@ internal interface IMXCryptoStore { fun markMyMasterKeyAsLocallyTrusted(trusted: Boolean) fun storePrivateKeysInfo(msk: String?, usk: String?, ssk: String?) + fun storeMSKPrivateKey(msk: String?) fun storeSSKPrivateKey(ssk: String?) fun storeUSKPrivateKey(usk: String?) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt index a78ab70b72..7910bfc72c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt @@ -395,6 +395,14 @@ internal class RealmCryptoStore @Inject constructor( } } + override fun storeMSKPrivateKey(msk: String?) { + doRealmTransaction(realmConfiguration) { realm -> + realm.where().findFirst()?.apply { + xSignMasterPrivateKey = msk + } + } + } + override fun storeSSKPrivateKey(ssk: String?) { doRealmTransaction(realmConfiguration) { realm -> realm.where().findFirst()?.apply { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt index 0f1666bd9d..1b50d3caa1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt @@ -23,6 +23,7 @@ import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME +import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME import im.vector.matrix.android.api.session.crypto.verification.CancelCode @@ -809,6 +810,8 @@ internal class DefaultVerificationService @Inject constructor( ?.let { vt -> val otherDeviceId = vt.otherDeviceId if (!crossSigningService.canCrossSign()) { + outgoingGossipingRequestManager.sendSecretShareRequest(MASTER_KEY_SSSS_NAME, mapOf(userId to listOf(otherDeviceId + ?: "*"))) outgoingGossipingRequestManager.sendSecretShareRequest(SELF_SIGNING_KEY_SSSS_NAME, mapOf(userId to listOf(otherDeviceId ?: "*"))) outgoingGossipingRequestManager.sendSecretShareRequest(USER_SIGNING_KEY_SSSS_NAME, mapOf(userId to listOf(otherDeviceId @@ -821,7 +824,7 @@ internal class DefaultVerificationService @Inject constructor( } private fun handleDoneReceived(senderId: String, doneReq: ValidVerificationDone) { - Timber.v("## SAS Done receieved $doneReq") + Timber.v("## SAS Done received $doneReq") val existing = getExistingTransaction(senderId, doneReq.transactionId) if (existing == null) { Timber.e("## SAS Received invalid Done request")