Update after MSC change

This commit is contained in:
Benoit Marty 2020-01-22 18:22:01 +01:00
parent 41c691f26c
commit cbf418c401
3 changed files with 34 additions and 43 deletions

View File

@ -26,8 +26,7 @@ import im.vector.matrix.android.api.permalinks.PermalinkFactory
* request=<event-id> * request=<event-id>
* &action=verify * &action=verify
* &key_<keyid>=<key-in-base64>... * &key_<keyid>=<key-in-base64>...
* &verification_algorithms=<algorithm> * &secret=<shared_secret>
* &verification_key=<random-key-in-base64>
* &other_user_key=<master-key-in-base64> * &other_user_key=<master-key-in-base64>
* </pre> * </pre>
*/ */
@ -35,18 +34,17 @@ fun QrCodeData.toUrl(): String {
return buildString { return buildString {
append(PermalinkFactory.createPermalink(userId)) append(PermalinkFactory.createPermalink(userId))
append("?request=") append("?request=")
append(PermalinkFactory.escape(requestId)) append(PermalinkFactory.escape(requestEventId))
append("&action=verify") append("&action=")
append(action)
for ((keyId, key) in keys) { for ((keyId, key) in keys) {
append("&key_$keyId=") append("&key_$keyId=")
append(PermalinkFactory.escape(key)) append(PermalinkFactory.escape(key))
} }
append("&verification_algorithms=") append("&secret=")
append(PermalinkFactory.escape(verificationAlgorithms)) append(PermalinkFactory.escape(sharedSecret))
append("&verification_key=")
append(PermalinkFactory.escape(verificationKey))
append("&other_user_key=") append("&other_user_key=")
append(PermalinkFactory.escape(otherUserKey)) append(PermalinkFactory.escape(otherUserKey))
} }
@ -85,15 +83,12 @@ fun String.toQrCodeData(): QrCodeData? {
(it.substringBefore("=") to it.substringAfter("=")) (it.substringBefore("=") to it.substringAfter("="))
}.toMap() }.toMap()
if (keyValues["action"] != "verify") { val action = keyValues["action"] ?: return null
return null
}
val requestId = keyValues["request"] val requestId = keyValues["request"]
?.let { PermalinkFactory.unescape(it) } ?.let { PermalinkFactory.unescape(it) }
?.takeIf { MatrixPatterns.isEventId(it) } ?: return null ?.takeIf { MatrixPatterns.isEventId(it) } ?: return null
val verificationAlgorithms = keyValues["verification_algorithms"] ?: return null val sharedSecret = keyValues["secret"] ?: return null
val verificationKey = keyValues["verification_key"] ?: return null
val otherUserKey = keyValues["other_user_key"] ?: return null val otherUserKey = keyValues["other_user_key"] ?: return null
val keys = keyValues.keys val keys = keyValues.keys
@ -106,9 +101,9 @@ fun String.toQrCodeData(): QrCodeData? {
return QrCodeData( return QrCodeData(
userId, userId,
requestId, requestId,
action,
keys, keys,
verificationAlgorithms, sharedSecret,
verificationKey,
otherUserKey otherUserKey
) )
} }

View File

@ -22,15 +22,19 @@ package im.vector.matrix.android.internal.crypto.verification.qrcode
data class QrCodeData( data class QrCodeData(
val userId: String, val userId: String,
// the event ID of the associated verification request event. // the event ID of the associated verification request event.
val requestId: String, val requestEventId: String,
// The action
val action: String,
// key_<key_id>: each key that the user wants verified will have an entry of this form, where the value is the key in unpadded base64. // key_<key_id>: each key that the user wants verified will have an entry of this form, where the value is the key in unpadded base64.
// The QR code should contain at least the user's master cross-signing key. // The QR code should contain at least the user's master cross-signing key.
val keys: Map<String, String>, val keys: Map<String, String>,
// algorithm
val verificationAlgorithms: String,
// random single-use shared secret in unpadded base64. It must be at least 256-bits long (43 characters when base64-encoded). // random single-use shared secret in unpadded base64. It must be at least 256-bits long (43 characters when base64-encoded).
val verificationKey: String, val sharedSecret: String,
// the other user's master cross-signing key, in unpadded base64. In other words, if Alice is displaying the QR code, // the other user's master cross-signing key, in unpadded base64. In other words, if Alice is displaying the QR code,
// this would be the copy of Bob's master cross-signing key that Alice has. // this would be the copy of Bob's master cross-signing key that Alice has.
val otherUserKey: String val otherUserKey: String
) ) {
companion object {
const val ACTION_VERIFY = "verify"
}
}

View File

@ -28,17 +28,17 @@ class QrCodeTest {
private val basicQrCodeData = QrCodeData( private val basicQrCodeData = QrCodeData(
userId = "@benoit:matrix.org", userId = "@benoit:matrix.org",
requestId = "\$azertyazerty", requestEventId = "\$azertyazerty",
action = QrCodeData.ACTION_VERIFY,
keys = mapOf( keys = mapOf(
"1" to "abcdef", "1" to "abcdef",
"2" to "ghijql" "2" to "ghijql"
), ),
verificationAlgorithms = "verificationAlgorithm", sharedSecret = "sharedSecret",
verificationKey = "verificationKey",
otherUserKey = "otherUserKey" otherUserKey = "otherUserKey"
) )
private val basicUrl = "https://matrix.to/#/@benoit:matrix.org?request=\$azertyazerty&action=verify&key_1=abcdef&key_2=ghijql&verification_algorithms=verificationAlgorithm&verification_key=verificationKey&other_user_key=otherUserKey" private val basicUrl = "https://matrix.to/#/@benoit:matrix.org?request=\$azertyazerty&action=verify&key_1=abcdef&key_2=ghijql&secret=sharedSecret&other_user_key=otherUserKey"
@Test @Test
fun testNominalCase() { fun testNominalCase() {
@ -51,11 +51,10 @@ class QrCodeTest {
decodedData.shouldNotBeNull() decodedData.shouldNotBeNull()
decodedData.userId shouldBeEqualTo "@benoit:matrix.org" decodedData.userId shouldBeEqualTo "@benoit:matrix.org"
decodedData.requestId shouldBeEqualTo "\$azertyazerty" decodedData.requestEventId shouldBeEqualTo "\$azertyazerty"
decodedData.keys["1"]?.shouldBeEqualTo("abcdef") decodedData.keys["1"]?.shouldBeEqualTo("abcdef")
decodedData.keys["2"]?.shouldBeEqualTo("ghijql") decodedData.keys["2"]?.shouldBeEqualTo("ghijql")
decodedData.verificationAlgorithms shouldBeEqualTo "verificationAlgorithm" decodedData.sharedSecret shouldBeEqualTo "sharedSecret"
decodedData.verificationKey shouldBeEqualTo "verificationKey"
decodedData.otherUserKey shouldBeEqualTo "otherUserKey" decodedData.otherUserKey shouldBeEqualTo "otherUserKey"
} }
@ -64,7 +63,7 @@ class QrCodeTest {
val url = basicQrCodeData val url = basicQrCodeData
.copy( .copy(
userId = "@benoit/foo:matrix.org", userId = "@benoit/foo:matrix.org",
requestId = "\$azertyazerty/bar" requestEventId = "\$azertyazerty/bar"
) )
.toUrl() .toUrl()
@ -77,11 +76,10 @@ class QrCodeTest {
decodedData.shouldNotBeNull() decodedData.shouldNotBeNull()
decodedData.userId shouldBeEqualTo "@benoit/foo:matrix.org" decodedData.userId shouldBeEqualTo "@benoit/foo:matrix.org"
decodedData.requestId shouldBeEqualTo "\$azertyazerty/bar" decodedData.requestEventId shouldBeEqualTo "\$azertyazerty/bar"
decodedData.keys["1"]?.shouldBeEqualTo("abcdef") decodedData.keys["1"]?.shouldBeEqualTo("abcdef")
decodedData.keys["2"]?.shouldBeEqualTo("ghijql") decodedData.keys["2"]?.shouldBeEqualTo("ghijql")
decodedData.verificationAlgorithms shouldBeEqualTo "verificationAlgorithm" decodedData.sharedSecret shouldBeEqualTo "sharedSecret"
decodedData.verificationKey shouldBeEqualTo "verificationKey"
decodedData.otherUserKey shouldBeEqualTo "otherUserKey" decodedData.otherUserKey shouldBeEqualTo "otherUserKey"
} }
@ -93,14 +91,15 @@ class QrCodeTest {
} }
@Test @Test
fun testBadActionCase() { fun testOtherActionCase() {
basicUrl.replace("&action=verify", "&action=confirm") basicUrl.replace("&action=verify", "&action=confirm")
.toQrCodeData() .toQrCodeData()
.shouldBeNull() ?.action
?.shouldBeEqualTo("confirm")
} }
@Test @Test
fun testBadRequestId() { fun testBadRequestEventId() {
basicUrl.replace("\$azertyazerty", "@azertyazerty") basicUrl.replace("\$azertyazerty", "@azertyazerty")
.toQrCodeData() .toQrCodeData()
.shouldBeNull() .shouldBeNull()
@ -121,15 +120,8 @@ class QrCodeTest {
} }
@Test @Test
fun testMissingVerificationAlgorithm() { fun testMissingSecret() {
basicUrl.replace("&verification_algorithms=verificationAlgorithm", "") basicUrl.replace("&secret=sharedSecret", "")
.toQrCodeData()
.shouldBeNull()
}
@Test
fun testMissingVerificationKey() {
basicUrl.replace("&verification_key=verificationKey", "")
.toQrCodeData() .toQrCodeData()
.shouldBeNull() .shouldBeNull()
} }