From 4125baf0666765f392685014e7af1992dce7e037 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 19 Jun 2020 23:44:16 +0200 Subject: [PATCH] Some more cleanup on the model used to download and to upload keys --- .../internal/crypto/model/CryptoDeviceInfo.kt | 10 +-- .../internal/crypto/model/CryptoInfoMapper.kt | 14 ++--- .../internal/crypto/model/rest/DeviceKeys.kt | 27 ++++++-- .../model/rest/DeviceKeysWithUnsigned.kt | 62 +++++++++++++++++++ .../crypto/model/rest/KeysQueryResponse.kt | 16 ++--- .../crypto/model/rest/KeysUploadBody.kt | 16 ++++- .../crypto/model/rest/KeysUploadResponse.kt | 3 +- .../crypto/model/rest/RestDeviceInfo.kt | 60 ------------------ .../internal/crypto/model/rest/RestKeyInfo.kt | 1 + .../crypto/model/rest/UnsignedDeviceInfo.kt | 29 +++++++++ .../crypto/store/db/model/CryptoMapper.kt | 13 ++-- .../internal/crypto/tasks/UploadKeysTask.kt | 4 +- 12 files changed, 157 insertions(+), 98 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt delete mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestDeviceInfo.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UnsignedDeviceInfo.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt index fc6e2cc436..bc73111ace 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoDeviceInfo.kt @@ -15,9 +15,9 @@ */ package im.vector.matrix.android.internal.crypto.model -import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel -import im.vector.matrix.android.internal.crypto.model.rest.RestDeviceInfo +import im.vector.matrix.android.internal.crypto.model.rest.DeviceKeys +import im.vector.matrix.android.internal.crypto.model.rest.UnsignedDeviceInfo import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMapper import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntity @@ -27,7 +27,7 @@ data class CryptoDeviceInfo( var algorithms: List? = null, override val keys: Map? = null, override val signatures: Map>? = null, - val unsigned: JsonDict? = null, + val unsigned: UnsignedDeviceInfo? = null, var trustLevel: DeviceTrustLevel? = null, var isBlocked: Boolean = false, val firstTimeSeenLocalTs: Long? = null @@ -61,7 +61,7 @@ data class CryptoDeviceInfo( * @return the display name */ fun displayName(): String? { - return unsigned?.get("device_display_name") as? String + return unsigned?.deviceDisplayName } override fun signalableJSONDictionary(): Map { @@ -74,7 +74,7 @@ data class CryptoDeviceInfo( } } -internal fun CryptoDeviceInfo.toRest(): RestDeviceInfo { +internal fun CryptoDeviceInfo.toRest(): DeviceKeys { return CryptoInfoMapper.map(this) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt index 37aae2c47b..3129752b97 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/CryptoInfoMapper.kt @@ -15,15 +15,16 @@ */ package im.vector.matrix.android.internal.crypto.model -import im.vector.matrix.android.internal.crypto.model.rest.RestDeviceInfo +import im.vector.matrix.android.internal.crypto.model.rest.DeviceKeys +import im.vector.matrix.android.internal.crypto.model.rest.DeviceKeysWithUnsigned import im.vector.matrix.android.internal.crypto.model.rest.RestKeyInfo internal object CryptoInfoMapper { - fun map(restDeviceInfo: RestDeviceInfo): CryptoDeviceInfo { + fun map(restDeviceInfo: DeviceKeysWithUnsigned): CryptoDeviceInfo { return CryptoDeviceInfo( - deviceId = restDeviceInfo.deviceId, - userId = restDeviceInfo.userId, + deviceId = restDeviceInfo.deviceId ?: "", + userId = restDeviceInfo.userId ?: "", algorithms = restDeviceInfo.algorithms, keys = restDeviceInfo.keys, signatures = restDeviceInfo.signatures, @@ -32,13 +33,12 @@ internal object CryptoInfoMapper { ) } - fun map(cryptoDeviceInfo: CryptoDeviceInfo): RestDeviceInfo { - return RestDeviceInfo( + fun map(cryptoDeviceInfo: CryptoDeviceInfo): DeviceKeys { + return DeviceKeys( deviceId = cryptoDeviceInfo.deviceId, algorithms = cryptoDeviceInfo.algorithms, keys = cryptoDeviceInfo.keys, signatures = cryptoDeviceInfo.signatures, - unsigned = cryptoDeviceInfo.unsigned, userId = cryptoDeviceInfo.userId ) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeys.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeys.kt index 563e0499ae..7a31e5b78f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeys.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeys.kt @@ -21,21 +21,36 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class DeviceKeys( + /** + * Required. The ID of the user the device belongs to. Must match the user ID used when logging in. + */ @Json(name = "user_id") - val userId: String?, + val userId: String, + /** + * Required. The ID of the device these keys belong to. Must match the device ID used when logging in. + */ @Json(name = "device_id") - val deviceId: String?, + val deviceId: String, + /** + * Required. The encryption algorithms supported by this device. + */ @Json(name = "algorithms") val algorithms: List?, + /** + * Required. Public identity keys. The names of the properties should be in the format :. + * The keys themselves should be encoded as specified by the key algorithm. + */ @Json(name = "keys") val keys: Map?, + /** + * Required. Signatures for the device key object. A map from user ID, to a map from : to the signature. + * The signature is calculated using the process described at https://matrix.org/docs/spec/appendices.html#signing-json. + */ @Json(name = "signatures") - val signatures: Map>?, - - @Json(name = "usage") - val usage: List? = null + val signatures: Map>? ) + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt new file mode 100644 index 0000000000..77111827ed --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt @@ -0,0 +1,62 @@ +/* + * 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.model.rest + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class DeviceKeysWithUnsigned( + /** + * Required. The ID of the user the device belongs to. Must match the user ID used when logging in. + */ + @Json(name = "user_id") + val userId: String?, + + /** + * Required. The ID of the device these keys belong to. Must match the device ID used when logging in. + */ + @Json(name = "device_id") + val deviceId: String?, + + /** + * Required. The encryption algorithms supported by this device. + */ + @Json(name = "algorithms") + val algorithms: List?, + + /** + * Required. Public identity keys. The names of the properties should be in the format :. + * The keys themselves should be encoded as specified by the key algorithm. + */ + @Json(name = "keys") + val keys: Map?, + + /** + * Required. Signatures for the device key object. A map from user ID, to a map from : to the signature. + * The signature is calculated using the process described at https://matrix.org/docs/spec/appendices.html#signing-json. + */ + @Json(name = "signatures") + val signatures: Map>?, + + /** + * Additional data added to the device key information by intermediate servers, and not covered by the signatures. + */ + @Json(name = "unsigned") + val unsigned: UnsignedDeviceInfo? = null +) + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryResponse.kt index aea8eeb301..82ea793116 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryResponse.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysQueryResponse.kt @@ -28,18 +28,20 @@ import com.squareup.moshi.JsonClass * The user_signing_keys property will only be included when a user requests their own keys. */ @JsonClass(generateAdapter = true) -internal data class KeysQueryResponse( +internal data class KeysQueryResponse( /** - * The device keys per devices per users. - * Map from userId to map from deviceId to MXDeviceInfo - * TODO Use MXUsersDevicesMap? + * Information on the queried devices. A map from user ID, to a map from device ID to device information. + * For each device, the information returned will be the same as uploaded via /keys/upload, with the addition of an unsigned property. */ @Json(name = "device_keys") - val deviceKeys: Map>? = null, + val deviceKeys: Map>? = null, /** - * The failures sorted by homeservers. TODO Bad comment ? - * TODO Use MXUsersDevicesMap? + * If any remote homeservers could not be reached, they are recorded here. The names of the + * properties are the names of the unreachable servers. + * + * If the homeserver could be reached, but the user or device was unknown, no failure is recorded. + * Instead, the corresponding user or device is missing from the device_keys result. */ val failures: Map>? = null, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadBody.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadBody.kt index 2267c25534..516f64f40e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadBody.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadBody.kt @@ -20,11 +20,25 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.util.JsonDict +/** + * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-keys-upload + */ @JsonClass(generateAdapter = true) internal data class KeysUploadBody( + /** + * Identity keys for the device. + * + * May be absent if no new identity keys are required. + */ @Json(name = "device_keys") - val deviceKeys: RestDeviceInfo? = null, + val deviceKeys: DeviceKeys? = null, + /** + * One-time public keys for "pre-key" messages. The names of the properties should be in the + * format :. The format of the key is determined by the key algorithm. + * + * May be absent if no new one-time keys are required. + */ @Json(name = "one_time_keys") val oneTimeKeys: JsonDict? = null ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt index cd71749acf..70eca3bf0b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/KeysUploadResponse.kt @@ -24,7 +24,8 @@ import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) internal data class KeysUploadResponse( /** - * The count per algorithm as returned by the home server: a map (algorithm to count). + * Required. For each key algorithm, the number of unclaimed one-time keys + * of that type currently held on the server for this device. */ @Json(name = "one_time_key_counts") val oneTimeKeyCounts: Map? = null diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestDeviceInfo.kt deleted file mode 100644 index 1fc1e599b7..0000000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestDeviceInfo.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 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.model.rest - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass -import im.vector.matrix.android.api.util.JsonDict - -@JsonClass(generateAdapter = true) -internal data class RestDeviceInfo( - /** - * The id of this device. - */ - @Json(name = "device_id") - val deviceId: String, - - /** - * the user id - */ - @Json(name = "user_id") - val userId: String, - - /** - * The list of algorithms supported by this device. - */ - @Json(name = "algorithms") - val algorithms: List? = null, - - /** - * A map from ":" to "". - */ - @Json(name = "keys") - val keys: Map? = null, - - /** - * The signature of this MXDeviceInfo. - * A map from "" to a map from ":" to "" - */ - @Json(name = "signatures") - val signatures: Map>? = null, - - /* - * Additional data from the home server. - */ - @Json(name = "unsigned") - val unsigned: JsonDict? = null -) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestKeyInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestKeyInfo.kt index 5c4ff4d7e4..4788f98a6d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestKeyInfo.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/RestKeyInfo.kt @@ -27,6 +27,7 @@ internal data class RestKeyInfo( */ @Json(name = "user_id") val userId: String, + /** * Allowed uses for the key. * Must contain "master" for master keys, "self_signing" for self-signing keys, and "user_signing" for user-signing keys. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UnsignedDeviceInfo.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UnsignedDeviceInfo.kt new file mode 100644 index 0000000000..364e213e3a --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/model/rest/UnsignedDeviceInfo.kt @@ -0,0 +1,29 @@ +/* + * 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.model.rest + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class UnsignedDeviceInfo( + /** + * The display name which the user set on the device. + */ + @Json(name = "device_display_name") + val deviceDisplayName: String? = null +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt index d222fe0eed..b11c068413 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/model/CryptoMapper.kt @@ -20,6 +20,7 @@ import com.squareup.moshi.Types import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo +import im.vector.matrix.android.internal.crypto.model.rest.UnsignedDeviceInfo import im.vector.matrix.android.internal.di.SerializeNulls import timber.log.Timber @@ -57,7 +58,8 @@ object CryptoMapper { locallyVerified = it.locallyVerified ) }, - unsignedMapJson = mapMigrationAdapter.toJson(deviceInfo.unsigned) + // We store the device name if present now + unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName ) } @@ -69,14 +71,7 @@ object CryptoMapper { trustLevel = deviceInfoEntity.trustLevelEntity?.let { DeviceTrustLevel(it.crossSignedVerified ?: false, it.locallyVerified) }, - unsigned = deviceInfoEntity.unsignedMapJson?.let { - try { - mapMigrationAdapter.fromJson(it) - } catch (failure: Throwable) { - Timber.e(failure) - null - } - }, + unsigned = deviceInfoEntity.unsignedMapJson?.let { UnsignedDeviceInfo(deviceDisplayName = it) }, signatures = deviceInfoEntity.signatureMapJson?.let { try { mapOfStringMigrationAdapter.fromJson(it) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadKeysTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadKeysTask.kt index 8f14e08676..2a11e5da5b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadKeysTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/tasks/UploadKeysTask.kt @@ -18,9 +18,9 @@ package im.vector.matrix.android.internal.crypto.tasks import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.internal.crypto.api.CryptoApi +import im.vector.matrix.android.internal.crypto.model.rest.DeviceKeys import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadBody import im.vector.matrix.android.internal.crypto.model.rest.KeysUploadResponse -import im.vector.matrix.android.internal.crypto.model.rest.RestDeviceInfo import im.vector.matrix.android.internal.network.executeRequest import im.vector.matrix.android.internal.task.Task import org.greenrobot.eventbus.EventBus @@ -30,7 +30,7 @@ import javax.inject.Inject internal interface UploadKeysTask : Task { data class Params( // the device keys to send. - val deviceKeys: RestDeviceInfo?, + val deviceKeys: DeviceKeys?, // the one-time keys to send. val oneTimeKeys: JsonDict? )