Refactor into dedicated files and companion objects

This commit is contained in:
Hugh Nimmo-Smith 2022-10-17 11:24:48 +01:00
parent ed6bc01bef
commit 33be5c257d
8 changed files with 159 additions and 76 deletions

View file

@ -17,13 +17,13 @@
package org.matrix.android.sdk.api.rendezvous
import android.net.Uri
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.rendezvous.channels.ECDHRendezvousChannel
import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
import org.matrix.android.sdk.api.rendezvous.model.Payload
import org.matrix.android.sdk.api.rendezvous.model.PayloadType
import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransport
import org.matrix.android.sdk.api.session.Session
@ -35,35 +35,6 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_S
import org.matrix.android.sdk.api.util.MatrixJsonParser
import timber.log.Timber
internal enum class PayloadType(val value: String) {
@Json(name = "m.login.start")
Start("m.login.start"),
@Json(name = "m.login.finish")
Finish("m.login.finish"),
@Json(name = "m.login.progress")
Progress("m.login.progress")
}
@JsonClass(generateAdapter = true)
internal data class Payload(
@Json val type: PayloadType,
@Json val intent: RendezvousIntent? = null,
@Json val outcome: String? = null,
@Json val protocols: List<String>? = null,
@Json val protocol: String? = null,
@Json val homeserver: String? = null,
@Json(name = "login_token") val loginToken: String? = null,
@Json(name = "device_id") val deviceId: String? = null,
@Json(name = "device_key") val deviceKey: String? = null,
@Json(name = "verifying_device_id") val verifyingDeviceId: String? = null,
@Json(name = "verifying_device_key") val verifyingDeviceKey: String? = null,
@Json(name = "master_key") val masterKey: String? = null
)
private val TAG = LoggerTag(Rendezvous::class.java.simpleName, LoggerTag.RENDEZVOUS).value
/**
* Implementation of MSC3906 to sign in + E2EE set up using a QR code.
*/
@ -72,6 +43,8 @@ class Rendezvous(
val theirIntent: RendezvousIntent,
) {
companion object {
private val TAG = LoggerTag(Rendezvous::class.java.simpleName, LoggerTag.RENDEZVOUS).value
fun buildChannelFromCode(code: String, onCancelled: (reason: RendezvousFailureReason) -> Unit): Rendezvous {
val parsed = MatrixJsonParser.getMoshi().adapter(ECDHRendezvousCode::class.java).fromJson(code) ?: throw RuntimeException("Invalid code")
@ -176,7 +149,9 @@ class Rendezvous(
val verifyingDeviceId = verificationResponse?.verifyingDeviceId ?: throw RuntimeException("No verifying device id returned")
val verifyingDeviceFromServer = crypto.getCryptoDeviceInfo(userId, verifyingDeviceId)
if (verifyingDeviceFromServer?.fingerprint() != verificationResponse.verifyingDeviceKey) {
Timber.tag(TAG).w("Verifying device $verifyingDeviceId key doesn't match: ${verifyingDeviceFromServer?.fingerprint()} vs ${verificationResponse.verifyingDeviceKey})")
Timber.tag(TAG).w("Verifying device $verifyingDeviceId key doesn't match: ${
verifyingDeviceFromServer?.fingerprint()} vs ${verificationResponse.verifyingDeviceKey})"
)
throw RuntimeException("Key from verifying device doesn't match")
}

View file

@ -29,7 +29,7 @@ import org.matrix.android.sdk.api.rendezvous.model.ECDHRendezvousCode
import org.matrix.android.sdk.api.rendezvous.model.RendezvousError
import org.matrix.android.sdk.api.rendezvous.model.RendezvousIntent
import org.matrix.android.sdk.api.rendezvous.model.SecureRendezvousChannelAlgorithm
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransportDetails
import org.matrix.android.sdk.api.rendezvous.model.SimpleHttpRendezvousTransportDetails
import org.matrix.android.sdk.api.util.MatrixJsonParser
import org.matrix.android.sdk.internal.extensions.toUnsignedInt
import org.matrix.olm.OlmSAS
@ -40,39 +40,40 @@ import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
@JsonClass(generateAdapter = true)
data class ECDHPayload(
@Json val algorithm: SecureRendezvousChannelAlgorithm? = null,
@Json val key: String? = null,
@Json val ciphertext: String? = null,
@Json val iv: String? = null
)
private val TAG = LoggerTag(ECDHRendezvousChannel::class.java.simpleName, LoggerTag.RENDEZVOUS).value
fun getDecimalCodeRepresentation(byteArray: ByteArray): String {
val b0 = byteArray[0].toUnsignedInt() // need unsigned byte
val b1 = byteArray[1].toUnsignedInt() // need unsigned byte
val b2 = byteArray[2].toUnsignedInt() // need unsigned byte
val b3 = byteArray[3].toUnsignedInt() // need unsigned byte
val b4 = byteArray[4].toUnsignedInt() // need unsigned byte
// (B0 << 5 | B1 >> 3) + 1000
val first = (b0.shl(5) or b1.shr(3)) + 1000
// ((B1 & 0x7) << 10 | B2 << 2 | B3 >> 6) + 1000
val second = ((b1 and 0x7).shl(10) or b2.shl(2) or b3.shr(6)) + 1000
// ((B3 & 0x3f) << 7 | B4 >> 1) + 1000
val third = ((b3 and 0x3f).shl(7) or b4.shr(1)) + 1000
return "$first-$second-$third"
}
const val ALGORITHM_SPEC = "AES/GCM/NoPadding"
const val KEY_SPEC = "AES"
/**
* Implements X25519 ECDH key agreement and AES-256-GCM encryption channel as per MSC3903:
* https://github.com/matrix-org/matrix-spec-proposals/pull/3903
*/
class ECDHRendezvousChannel(override var transport: RendezvousTransport, theirPublicKeyBase64: String?) : RendezvousChannel {
companion object {
private const val ALGORITHM_SPEC = "AES/GCM/NoPadding"
private const val KEY_SPEC = "AES"
private val TAG = LoggerTag(ECDHRendezvousChannel::class.java.simpleName, LoggerTag.RENDEZVOUS).value
private fun getDecimalCodeRepresentation(byteArray: ByteArray): String {
val b0 = byteArray[0].toUnsignedInt() // need unsigned byte
val b1 = byteArray[1].toUnsignedInt() // need unsigned byte
val b2 = byteArray[2].toUnsignedInt() // need unsigned byte
val b3 = byteArray[3].toUnsignedInt() // need unsigned byte
val b4 = byteArray[4].toUnsignedInt() // need unsigned byte
// (B0 << 5 | B1 >> 3) + 1000
val first = (b0.shl(5) or b1.shr(3)) + 1000
// ((B1 & 0x7) << 10 | B2 << 2 | B3 >> 6) + 1000
val second = ((b1 and 0x7).shl(10) or b2.shl(2) or b3.shr(6)) + 1000
// ((B3 & 0x3f) << 7 | B4 >> 1) + 1000
val third = ((b3 and 0x3f).shl(7) or b4.shr(1)) + 1000
return "$first-$second-$third"
}
}
@JsonClass(generateAdapter = true)
internal data class ECDHPayload(
@Json val algorithm: SecureRendezvousChannelAlgorithm? = null,
@Json val key: String? = null,
@Json val ciphertext: String? = null,
@Json val iv: String? = null
)
private var olmSAS: OlmSAS?
private val ourPublicKey: ByteArray
private val ecdhAdapter = MatrixJsonParser.getMoshi().adapter(ECDHPayload::class.java)

View file

@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.rendezvous.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.rendezvous.transports.SimpleHttpRendezvousTransportDetails
@JsonClass(generateAdapter = true)
data class ECDHRendezvous(
@ -26,9 +25,3 @@ data class ECDHRendezvous(
@Json val algorithm: SecureRendezvousChannelAlgorithm,
@Json val key: String
)
@JsonClass(generateAdapter = true)
data class ECDHRendezvousCode(
@Json val intent: RendezvousIntent,
@Json val rendezvous: ECDHRendezvous
)

View file

@ -0,0 +1,26 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.rendezvous.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class ECDHRendezvousCode(
@Json val intent: RendezvousIntent,
@Json val rendezvous: ECDHRendezvous
)

View file

@ -0,0 +1,36 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.rendezvous.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class Payload(
@Json val type: PayloadType,
@Json val intent: RendezvousIntent? = null,
@Json val outcome: String? = null,
@Json val protocols: List<String>? = null,
@Json val protocol: String? = null,
@Json val homeserver: String? = null,
@Json(name = "login_token") val loginToken: String? = null,
@Json(name = "device_id") val deviceId: String? = null,
@Json(name = "device_key") val deviceKey: String? = null,
@Json(name = "verifying_device_id") val verifyingDeviceId: String? = null,
@Json(name = "verifying_device_key") val verifyingDeviceKey: String? = null,
@Json(name = "master_key") val masterKey: String? = null
)

View file

@ -0,0 +1,30 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.rendezvous.model
import com.squareup.moshi.Json
internal enum class PayloadType(val value: String) {
@Json(name = "m.login.start")
Start("m.login.start"),
@Json(name = "m.login.finish")
Finish("m.login.finish"),
@Json(name = "m.login.progress")
Progress("m.login.progress")
}

View file

@ -0,0 +1,25 @@
/*
* Copyright 2022 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.rendezvous.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class SimpleHttpRendezvousTransportDetails(
@Json val uri: String
) : RendezvousTransportDetails(type = RendezvousTransportType.MSC3886_SIMPLE_HTTP_V1)

View file

@ -26,22 +26,19 @@ import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.rendezvous.RendezvousFailureReason
import org.matrix.android.sdk.api.rendezvous.RendezvousTransport
import org.matrix.android.sdk.api.rendezvous.model.RendezvousTransportDetails
import org.matrix.android.sdk.api.rendezvous.model.RendezvousTransportType
import org.matrix.android.sdk.api.rendezvous.model.SimpleHttpRendezvousTransportDetails
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.Date
private val TAG = LoggerTag(SimpleHttpRendezvousTransport::class.java.simpleName, LoggerTag.RENDEZVOUS).value
@JsonClass(generateAdapter = true)
data class SimpleHttpRendezvousTransportDetails(
@Json val uri: String
) : RendezvousTransportDetails(type = RendezvousTransportType.MSC3886_SIMPLE_HTTP_V1)
/**
* Implementation of the Simple HTTP transport MSC3886: https://github.com/matrix-org/matrix-spec-proposals/pull/3886
*/
class SimpleHttpRendezvousTransport(override var onCancelled: ((reason: RendezvousFailureReason) -> Unit)?, rendezvousUri: String?) : RendezvousTransport {
companion object {
private val TAG = LoggerTag(SimpleHttpRendezvousTransport::class.java.simpleName, LoggerTag.RENDEZVOUS).value
}
override var ready = false
private var cancelled = false
private var uri: String?