mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Merge pull request #1223 from vector-im/feature/cross_signing_as_task
Make initialize cross signing as a task
This commit is contained in:
commit
f6f6fa99fb
@ -66,6 +66,7 @@ import im.vector.matrix.android.internal.crypto.tasks.DefaultDownloadKeysForUser
|
|||||||
import im.vector.matrix.android.internal.crypto.tasks.DefaultEncryptEventTask
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultEncryptEventTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.DefaultGetDeviceInfoTask
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultGetDeviceInfoTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.DefaultGetDevicesTask
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultGetDevicesTask
|
||||||
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultInitializeCrossSigningTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.DefaultSendToDeviceTask
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultSendToDeviceTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.DefaultSendVerificationMessageTask
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultSendVerificationMessageTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.DefaultSetDeviceNameTask
|
import im.vector.matrix.android.internal.crypto.tasks.DefaultSetDeviceNameTask
|
||||||
@ -78,6 +79,7 @@ import im.vector.matrix.android.internal.crypto.tasks.DownloadKeysForUsersTask
|
|||||||
import im.vector.matrix.android.internal.crypto.tasks.EncryptEventTask
|
import im.vector.matrix.android.internal.crypto.tasks.EncryptEventTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.GetDeviceInfoTask
|
import im.vector.matrix.android.internal.crypto.tasks.GetDeviceInfoTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
|
import im.vector.matrix.android.internal.crypto.tasks.GetDevicesTask
|
||||||
|
import im.vector.matrix.android.internal.crypto.tasks.InitializeCrossSigningTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
import im.vector.matrix.android.internal.crypto.tasks.SendToDeviceTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.SendVerificationMessageTask
|
import im.vector.matrix.android.internal.crypto.tasks.SendVerificationMessageTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
|
import im.vector.matrix.android.internal.crypto.tasks.SetDeviceNameTask
|
||||||
@ -245,4 +247,7 @@ internal abstract class CryptoModule {
|
|||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
abstract fun bindComputeShieldTrustTask(task: DefaultComputeTrustTask): ComputeTrustTask
|
abstract fun bindComputeShieldTrustTask(task: DefaultComputeTrustTask): ComputeTrustTask
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindInitializeCrossSigningTask(task: DefaultInitializeCrossSigningTask): InitializeCrossSigningTask
|
||||||
}
|
}
|
||||||
|
@ -17,22 +17,17 @@
|
|||||||
package im.vector.matrix.android.internal.crypto.crosssigning
|
package im.vector.matrix.android.internal.crypto.crosssigning
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import dagger.Lazy
|
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService
|
import im.vector.matrix.android.api.session.crypto.crosssigning.CrossSigningService
|
||||||
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
|
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||||
import im.vector.matrix.android.api.util.Optional
|
import im.vector.matrix.android.api.util.Optional
|
||||||
import im.vector.matrix.android.internal.crypto.DeviceListManager
|
import im.vector.matrix.android.internal.crypto.DeviceListManager
|
||||||
import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
|
||||||
import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.KeyUsage
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
||||||
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
||||||
import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
|
import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
|
||||||
|
import im.vector.matrix.android.internal.crypto.tasks.InitializeCrossSigningTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.UploadSignaturesTask
|
import im.vector.matrix.android.internal.crypto.tasks.UploadSignaturesTask
|
||||||
import im.vector.matrix.android.internal.crypto.tasks.UploadSigningKeysTask
|
|
||||||
import im.vector.matrix.android.internal.di.UserId
|
import im.vector.matrix.android.internal.di.UserId
|
||||||
import im.vector.matrix.android.internal.session.SessionScope
|
import im.vector.matrix.android.internal.session.SessionScope
|
||||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||||
@ -53,12 +48,9 @@ import javax.inject.Inject
|
|||||||
internal class DefaultCrossSigningService @Inject constructor(
|
internal class DefaultCrossSigningService @Inject constructor(
|
||||||
@UserId private val userId: String,
|
@UserId private val userId: String,
|
||||||
private val cryptoStore: IMXCryptoStore,
|
private val cryptoStore: IMXCryptoStore,
|
||||||
private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
|
|
||||||
private val olmDevice: MXOlmDevice,
|
|
||||||
private val deviceListManager: DeviceListManager,
|
private val deviceListManager: DeviceListManager,
|
||||||
private val uploadSigningKeysTask: UploadSigningKeysTask,
|
private val initializeCrossSigningTask: InitializeCrossSigningTask,
|
||||||
private val uploadSignaturesTask: UploadSignaturesTask,
|
private val uploadSignaturesTask: UploadSignaturesTask,
|
||||||
private val computeTrustTask: ComputeTrustTask,
|
|
||||||
private val taskExecutor: TaskExecutor,
|
private val taskExecutor: TaskExecutor,
|
||||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||||
private val cryptoCoroutineScope: CoroutineScope,
|
private val cryptoCoroutineScope: CoroutineScope,
|
||||||
@ -151,153 +143,31 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||||||
override fun initializeCrossSigning(authParams: UserPasswordAuth?, callback: MatrixCallback<Unit>?) {
|
override fun initializeCrossSigning(authParams: UserPasswordAuth?, callback: MatrixCallback<Unit>?) {
|
||||||
Timber.d("## CrossSigning initializeCrossSigning")
|
Timber.d("## CrossSigning initializeCrossSigning")
|
||||||
|
|
||||||
// =================
|
val params = InitializeCrossSigningTask.Params(
|
||||||
// MASTER KEY
|
authParams = authParams
|
||||||
// =================
|
|
||||||
val masterPkOlm = OlmPkSigning()
|
|
||||||
val masterKeyPrivateKey = OlmPkSigning.generateSeed()
|
|
||||||
val masterPublicKey = masterPkOlm.initWithSeed(masterKeyPrivateKey)
|
|
||||||
|
|
||||||
Timber.v("## CrossSigning - masterPublicKey:$masterPublicKey")
|
|
||||||
|
|
||||||
// =================
|
|
||||||
// USER KEY
|
|
||||||
// =================
|
|
||||||
val userSigningPkOlm = OlmPkSigning()
|
|
||||||
val uskPrivateKey = OlmPkSigning.generateSeed()
|
|
||||||
val uskPublicKey = userSigningPkOlm.initWithSeed(uskPrivateKey)
|
|
||||||
|
|
||||||
Timber.v("## CrossSigning - uskPublicKey:$uskPublicKey")
|
|
||||||
|
|
||||||
// Sign userSigningKey with master
|
|
||||||
val signedUSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
|
|
||||||
.key(uskPublicKey)
|
|
||||||
.build()
|
|
||||||
.canonicalSignable()
|
|
||||||
.let { masterPkOlm.sign(it) }
|
|
||||||
|
|
||||||
// =================
|
|
||||||
// SELF SIGNING KEY
|
|
||||||
// =================
|
|
||||||
val selfSigningPkOlm = OlmPkSigning()
|
|
||||||
val sskPrivateKey = OlmPkSigning.generateSeed()
|
|
||||||
val sskPublicKey = selfSigningPkOlm.initWithSeed(sskPrivateKey)
|
|
||||||
|
|
||||||
Timber.v("## CrossSigning - sskPublicKey:$sskPublicKey")
|
|
||||||
|
|
||||||
// Sign userSigningKey with master
|
|
||||||
val signedSSK = JsonCanonicalizer.getCanonicalJson(Map::class.java, CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
|
|
||||||
.key(sskPublicKey)
|
|
||||||
.build().signalableJSONDictionary()).let { masterPkOlm.sign(it) }
|
|
||||||
|
|
||||||
// I need to upload the keys
|
|
||||||
val mskCrossSigningKeyInfo = CryptoCrossSigningKey.Builder(userId, KeyUsage.MASTER)
|
|
||||||
.key(masterPublicKey)
|
|
||||||
.build()
|
|
||||||
val params = UploadSigningKeysTask.Params(
|
|
||||||
masterKey = mskCrossSigningKeyInfo,
|
|
||||||
userKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
|
|
||||||
.key(uskPublicKey)
|
|
||||||
.signature(userId, masterPublicKey, signedUSK)
|
|
||||||
.build(),
|
|
||||||
selfSignedKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
|
|
||||||
.key(sskPublicKey)
|
|
||||||
.signature(userId, masterPublicKey, signedSSK)
|
|
||||||
.build(),
|
|
||||||
userPasswordAuth = authParams
|
|
||||||
)
|
)
|
||||||
|
initializeCrossSigningTask.configureWith(params) {
|
||||||
this.masterPkSigning = masterPkOlm
|
this.callbackThread = TaskThread.CRYPTO
|
||||||
this.userPkSigning = userSigningPkOlm
|
this.callback = object : MatrixCallback<InitializeCrossSigningTask.Result> {
|
||||||
this.selfSigningPkSigning = selfSigningPkOlm
|
override fun onFailure(failure: Throwable) {
|
||||||
|
callback?.onFailure(failure)
|
||||||
val crossSigningInfo = MXCrossSigningInfo(userId, listOf(params.masterKey, params.userKey, params.selfSignedKey))
|
|
||||||
cryptoStore.setMyCrossSigningInfo(crossSigningInfo)
|
|
||||||
setUserKeysAsTrusted(userId, true)
|
|
||||||
cryptoStore.storePrivateKeysInfo(masterKeyPrivateKey?.toBase64NoPadding(), uskPrivateKey?.toBase64NoPadding(), sskPrivateKey?.toBase64NoPadding())
|
|
||||||
|
|
||||||
uploadSigningKeysTask.configureWith(params) {
|
|
||||||
this.executionThread = TaskThread.CRYPTO
|
|
||||||
this.callback = object : MatrixCallback<Unit> {
|
|
||||||
override fun onSuccess(data: Unit) {
|
|
||||||
Timber.i("## CrossSigning - Keys successfully uploaded")
|
|
||||||
|
|
||||||
// Sign the current device with SSK
|
|
||||||
val uploadSignatureQueryBuilder = UploadSignatureQueryBuilder()
|
|
||||||
|
|
||||||
val myDevice = myDeviceInfoHolder.get().myDevice
|
|
||||||
val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, myDevice.signalableJSONDictionary())
|
|
||||||
val signedDevice = selfSigningPkOlm.sign(canonicalJson)
|
|
||||||
val updateSignatures = (myDevice.signatures?.toMutableMap() ?: HashMap())
|
|
||||||
.also {
|
|
||||||
it[userId] = (it[userId]
|
|
||||||
?: HashMap()) + mapOf("ed25519:$sskPublicKey" to signedDevice)
|
|
||||||
}
|
|
||||||
myDevice.copy(signatures = updateSignatures).let {
|
|
||||||
uploadSignatureQueryBuilder.withDeviceInfo(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// sign MSK with device key (migration) and upload signatures
|
|
||||||
val message = JsonCanonicalizer.getCanonicalJson(Map::class.java, mskCrossSigningKeyInfo.signalableJSONDictionary())
|
|
||||||
olmDevice.signMessage(message)?.let { sign ->
|
|
||||||
val mskUpdatedSignatures = (mskCrossSigningKeyInfo.signatures?.toMutableMap()
|
|
||||||
?: HashMap()).also {
|
|
||||||
it[userId] = (it[userId]
|
|
||||||
?: HashMap()) + mapOf("ed25519:${myDevice.deviceId}" to sign)
|
|
||||||
}
|
|
||||||
mskCrossSigningKeyInfo.copy(
|
|
||||||
signatures = mskUpdatedSignatures
|
|
||||||
).let {
|
|
||||||
uploadSignatureQueryBuilder.withSigningKeyInfo(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resetTrustOnKeyChange()
|
|
||||||
uploadSignaturesTask.configureWith(UploadSignaturesTask.Params(uploadSignatureQueryBuilder.build())) {
|
|
||||||
// this.retryCount = 3
|
|
||||||
this.executionThread = TaskThread.CRYPTO
|
|
||||||
this.callback = object : MatrixCallback<Unit> {
|
|
||||||
override fun onSuccess(data: Unit) {
|
|
||||||
Timber.i("## CrossSigning - signatures successfully uploaded")
|
|
||||||
callback?.onSuccess(Unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
|
||||||
// Clear
|
|
||||||
Timber.e(failure, "## CrossSigning - Failed to upload signatures")
|
|
||||||
clearSigningKeys()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.executeBy(taskExecutor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onSuccess(data: InitializeCrossSigningTask.Result) {
|
||||||
Timber.e(failure, "## CrossSigning - Failed to upload signing keys")
|
val crossSigningInfo = MXCrossSigningInfo(userId, listOf(data.masterKeyInfo, data.userKeyInfo, data.selfSignedKeyInfo))
|
||||||
clearSigningKeys()
|
cryptoStore.setMyCrossSigningInfo(crossSigningInfo)
|
||||||
callback?.onFailure(failure)
|
setUserKeysAsTrusted(userId, true)
|
||||||
|
cryptoStore.storePrivateKeysInfo(data.masterKeyPK, data.userKeyPK, data.selfSigningKeyPK)
|
||||||
|
masterPkSigning = OlmPkSigning().apply { initWithSeed(data.masterKeyPK.fromBase64()) }
|
||||||
|
userPkSigning = OlmPkSigning().apply { initWithSeed(data.userKeyPK.fromBase64()) }
|
||||||
|
selfSigningPkSigning = OlmPkSigning().apply { initWithSeed(data.selfSigningKeyPK.fromBase64()) }
|
||||||
|
|
||||||
|
callback?.onSuccess(Unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.executeBy(taskExecutor)
|
}.executeBy(taskExecutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearSigningKeys() {
|
|
||||||
masterPkSigning?.releaseSigning()
|
|
||||||
userPkSigning?.releaseSigning()
|
|
||||||
selfSigningPkSigning?.releaseSigning()
|
|
||||||
|
|
||||||
masterPkSigning = null
|
|
||||||
userPkSigning = null
|
|
||||||
selfSigningPkSigning = null
|
|
||||||
|
|
||||||
cryptoStore.setMyCrossSigningInfo(null)
|
|
||||||
cryptoStore.storePrivateKeysInfo(null, null, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun resetTrustOnKeyChange() {
|
|
||||||
Timber.i("## CrossSigning - Clear all other user trust")
|
|
||||||
cryptoStore.clearOtherUserTrust()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSecretSSKGossip(sskPrivateKey: String) {
|
override fun onSecretSSKGossip(sskPrivateKey: String) {
|
||||||
Timber.i("## CrossSigning - onSecretSSKGossip")
|
Timber.i("## CrossSigning - onSecretSSKGossip")
|
||||||
val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also {
|
val mxCrossSigningInfo = getMyCrossSigningKeys() ?: return Unit.also {
|
||||||
|
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.internal.crypto.tasks
|
||||||
|
|
||||||
|
import dagger.Lazy
|
||||||
|
import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||||
|
import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
|
||||||
|
import im.vector.matrix.android.internal.crypto.crosssigning.canonicalSignable
|
||||||
|
import im.vector.matrix.android.internal.crypto.crosssigning.toBase64NoPadding
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.KeyUsage
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth
|
||||||
|
import im.vector.matrix.android.internal.di.UserId
|
||||||
|
import im.vector.matrix.android.internal.task.Task
|
||||||
|
import im.vector.matrix.android.internal.util.JsonCanonicalizer
|
||||||
|
import org.matrix.olm.OlmPkSigning
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal interface InitializeCrossSigningTask : Task<InitializeCrossSigningTask.Params, InitializeCrossSigningTask.Result> {
|
||||||
|
data class Params(
|
||||||
|
val authParams: UserPasswordAuth?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Result(
|
||||||
|
val masterKeyPK: String,
|
||||||
|
val userKeyPK: String,
|
||||||
|
val selfSigningKeyPK: String,
|
||||||
|
val masterKeyInfo: CryptoCrossSigningKey,
|
||||||
|
val userKeyInfo: CryptoCrossSigningKey,
|
||||||
|
val selfSignedKeyInfo: CryptoCrossSigningKey
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DefaultInitializeCrossSigningTask @Inject constructor(
|
||||||
|
@UserId private val userId: String,
|
||||||
|
private val olmDevice: MXOlmDevice,
|
||||||
|
private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
|
||||||
|
private val uploadSigningKeysTask: UploadSigningKeysTask,
|
||||||
|
private val uploadSignaturesTask: UploadSignaturesTask
|
||||||
|
) : InitializeCrossSigningTask {
|
||||||
|
|
||||||
|
override suspend fun execute(params: InitializeCrossSigningTask.Params): InitializeCrossSigningTask.Result {
|
||||||
|
var masterPkOlm: OlmPkSigning? = null
|
||||||
|
var userSigningPkOlm: OlmPkSigning? = null
|
||||||
|
var selfSigningPkOlm: OlmPkSigning? = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
// =================
|
||||||
|
// MASTER KEY
|
||||||
|
// =================
|
||||||
|
|
||||||
|
masterPkOlm = OlmPkSigning()
|
||||||
|
val masterKeyPrivateKey = OlmPkSigning.generateSeed()
|
||||||
|
val masterPublicKey = masterPkOlm.initWithSeed(masterKeyPrivateKey)
|
||||||
|
|
||||||
|
Timber.v("## CrossSigning - masterPublicKey:$masterPublicKey")
|
||||||
|
|
||||||
|
// =================
|
||||||
|
// USER KEY
|
||||||
|
// =================
|
||||||
|
userSigningPkOlm = OlmPkSigning()
|
||||||
|
val uskPrivateKey = OlmPkSigning.generateSeed()
|
||||||
|
val uskPublicKey = userSigningPkOlm.initWithSeed(uskPrivateKey)
|
||||||
|
|
||||||
|
Timber.v("## CrossSigning - uskPublicKey:$uskPublicKey")
|
||||||
|
|
||||||
|
// Sign userSigningKey with master
|
||||||
|
val signedUSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
|
||||||
|
.key(uskPublicKey)
|
||||||
|
.build()
|
||||||
|
.canonicalSignable()
|
||||||
|
.let { masterPkOlm.sign(it) }
|
||||||
|
|
||||||
|
// =================
|
||||||
|
// SELF SIGNING KEY
|
||||||
|
// =================
|
||||||
|
selfSigningPkOlm = OlmPkSigning()
|
||||||
|
val sskPrivateKey = OlmPkSigning.generateSeed()
|
||||||
|
val sskPublicKey = selfSigningPkOlm.initWithSeed(sskPrivateKey)
|
||||||
|
|
||||||
|
Timber.v("## CrossSigning - sskPublicKey:$sskPublicKey")
|
||||||
|
|
||||||
|
// Sign userSigningKey with master
|
||||||
|
val signedSSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
|
||||||
|
.key(sskPublicKey)
|
||||||
|
.build()
|
||||||
|
.canonicalSignable()
|
||||||
|
.let { masterPkOlm.sign(it) }
|
||||||
|
|
||||||
|
// I need to upload the keys
|
||||||
|
val mskCrossSigningKeyInfo = CryptoCrossSigningKey.Builder(userId, KeyUsage.MASTER)
|
||||||
|
.key(masterPublicKey)
|
||||||
|
.build()
|
||||||
|
val uploadSigningKeysParams = UploadSigningKeysTask.Params(
|
||||||
|
masterKey = mskCrossSigningKeyInfo,
|
||||||
|
userKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.USER_SIGNING)
|
||||||
|
.key(uskPublicKey)
|
||||||
|
.signature(userId, masterPublicKey, signedUSK)
|
||||||
|
.build(),
|
||||||
|
selfSignedKey = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
|
||||||
|
.key(sskPublicKey)
|
||||||
|
.signature(userId, masterPublicKey, signedSSK)
|
||||||
|
.build(),
|
||||||
|
userPasswordAuth = params.authParams
|
||||||
|
)
|
||||||
|
|
||||||
|
uploadSigningKeysTask.execute(uploadSigningKeysParams)
|
||||||
|
|
||||||
|
// Sign the current device with SSK
|
||||||
|
val uploadSignatureQueryBuilder = UploadSignatureQueryBuilder()
|
||||||
|
|
||||||
|
val myDevice = myDeviceInfoHolder.get().myDevice
|
||||||
|
val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, myDevice.signalableJSONDictionary())
|
||||||
|
val signedDevice = selfSigningPkOlm.sign(canonicalJson)
|
||||||
|
val updateSignatures = (myDevice.signatures?.toMutableMap() ?: HashMap())
|
||||||
|
.also {
|
||||||
|
it[userId] = (it[userId]
|
||||||
|
?: HashMap()) + mapOf("ed25519:$sskPublicKey" to signedDevice)
|
||||||
|
}
|
||||||
|
myDevice.copy(signatures = updateSignatures).let {
|
||||||
|
uploadSignatureQueryBuilder.withDeviceInfo(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sign MSK with device key (migration) and upload signatures
|
||||||
|
val message = JsonCanonicalizer.getCanonicalJson(Map::class.java, mskCrossSigningKeyInfo.signalableJSONDictionary())
|
||||||
|
olmDevice.signMessage(message)?.let { sign ->
|
||||||
|
val mskUpdatedSignatures = (mskCrossSigningKeyInfo.signatures?.toMutableMap()
|
||||||
|
?: HashMap()).also {
|
||||||
|
it[userId] = (it[userId]
|
||||||
|
?: HashMap()) + mapOf("ed25519:${myDevice.deviceId}" to sign)
|
||||||
|
}
|
||||||
|
mskCrossSigningKeyInfo.copy(
|
||||||
|
signatures = mskUpdatedSignatures
|
||||||
|
).let {
|
||||||
|
uploadSignatureQueryBuilder.withSigningKeyInfo(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO should we ignore failure of that?
|
||||||
|
uploadSignaturesTask.execute(UploadSignaturesTask.Params(uploadSignatureQueryBuilder.build()))
|
||||||
|
|
||||||
|
return InitializeCrossSigningTask.Result(
|
||||||
|
masterKeyPK = masterKeyPrivateKey.toBase64NoPadding(),
|
||||||
|
userKeyPK = uskPrivateKey.toBase64NoPadding(),
|
||||||
|
selfSigningKeyPK = sskPrivateKey.toBase64NoPadding(),
|
||||||
|
masterKeyInfo = uploadSigningKeysParams.masterKey,
|
||||||
|
userKeyInfo = uploadSigningKeysParams.userKey,
|
||||||
|
selfSignedKeyInfo = uploadSigningKeysParams.selfSignedKey
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
masterPkOlm?.releaseSigning()
|
||||||
|
userSigningPkOlm?.releaseSigning()
|
||||||
|
selfSigningPkOlm?.releaseSigning()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.crypto.tools
|
|||||||
|
|
||||||
import org.matrix.olm.OlmPkDecryption
|
import org.matrix.olm.OlmPkDecryption
|
||||||
import org.matrix.olm.OlmPkEncryption
|
import org.matrix.olm.OlmPkEncryption
|
||||||
|
import org.matrix.olm.OlmPkSigning
|
||||||
|
|
||||||
fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
|
fun <T> withOlmEncryption(block: (OlmPkEncryption) -> T): T {
|
||||||
val olmPkEncryption = OlmPkEncryption()
|
val olmPkEncryption = OlmPkEncryption()
|
||||||
@ -36,3 +37,12 @@ fun <T> withOlmDecryption(block: (OlmPkDecryption) -> T): T {
|
|||||||
olmPkDecryption.releaseDecryption()
|
olmPkDecryption.releaseDecryption()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> withOlmSigning(block: (OlmPkSigning) -> T): T {
|
||||||
|
val olmPkSigning = OlmPkSigning()
|
||||||
|
try {
|
||||||
|
return block(olmPkSigning)
|
||||||
|
} finally {
|
||||||
|
olmPkSigning.releaseSigning()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user