Update after MSC change
This commit is contained in:
parent
41c691f26c
commit
cbf418c401
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue