crypto: Verified identity changes TDD

This commit is contained in:
Valere
2024-08-02 08:46:26 +02:00
parent b4fe3059c3
commit 3d3f93a33d
2 changed files with 686 additions and 0 deletions

View File

@@ -2023,4 +2023,269 @@ pub(crate) mod tests {
assert!(!other_identity.has_pin_violation());
}
// Set up a machine do initial own key query and import cross-signing secret to
// make the current session verified.
async fn common_verification_latch_machine_setup() -> OlmMachine {
use test_json::keys_query_sets::VerificationLatchTestData as DataSet;
let machine = OlmMachine::new(DataSet::own_id(), device_id!("LOCAL")).await;
let keys_query = DataSet::own_keys_query_response_1();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
machine
.import_cross_signing_keys(CrossSigningKeyExport {
master_key: DataSet::MASTER_KEY_PRIVATE_EXPORT.to_owned().into(),
self_signing_key: DataSet::SELF_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
user_signing_key: DataSet::USER_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
})
.await
.unwrap();
machine
}
#[async_test]
async fn test_manager_verified_latch_setup_on_new_identities() {
use test_json::keys_query_sets::VerificationLatchTestData as DataSet;
let machine = common_verification_latch_machine_setup().await;
// ######
// First test: Assert that the latch is properly set on new identities
// ######
let keys_query = DataSet::bob_keys_query_response_signed();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
let own_identity =
machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap().own().unwrap();
// For sanity check that own identity is trusted
assert!(own_identity.is_verified());
let bob_identity =
machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
// The verified latch should be true
assert!(bob_identity.is_verified_latch_set());
// And bob is verified
assert!(bob_identity.is_verified());
// ######
// Second test: Assert that the local latch stays on if the identity is rotated
// ######
let keys_query = DataSet::bob_keys_query_response_rotated();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
let bob_identity =
machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
// Bob is not verified anymore
assert!(!bob_identity.is_verified());
// The verified latch should still be true
assert!(bob_identity.is_verified_latch_set());
// Bob device_2 is self-signed even if there is this verification latch
// violation
let bob_device = machine
.get_device(DataSet::bob_id(), DataSet::bob_device_2_id(), None)
.await
.unwrap()
.unwrap();
assert!(bob_identity.is_device_signed(&bob_device).is_ok());
// there is also a pin violation
assert!(bob_identity.has_pin_violation());
// Fixing the pin violation won't fix the verification latch violation
bob_identity.pin_current_master_key().await.unwrap();
assert!(!bob_identity.has_pin_violation());
let has_latch_violation =
bob_identity.is_verified_latch_set() && !bob_identity.is_verified();
assert!(has_latch_violation);
}
#[async_test]
async fn test_manager_verified_latch_setup_on_updated_identities() {
use test_json::keys_query_sets::VerificationLatchTestData as DataSet;
let machine = common_verification_latch_machine_setup().await;
// ######
// Get the Carol identity for the first time
// ######
let keys_query = DataSet::carol_keys_query_response_unsigned();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
let carol_identity = machine
.get_identity(DataSet::carol_id(), None)
.await
.unwrap()
.unwrap()
.other()
.unwrap();
// The identity is not verified
assert!(!carol_identity.is_verified());
// The verified latch is off
assert!(!carol_identity.is_verified_latch_set());
// Carol is verified, likely from another session. Ensure the latch is updated
// when the key query response is processes
let keys_query = DataSet::carol_keys_query_response_signed();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
let carol_identity = machine
.get_identity(DataSet::carol_id(), None)
.await
.unwrap()
.unwrap()
.other()
.unwrap();
assert!(carol_identity.is_verified());
// This should have updated the latch
assert!(carol_identity.is_verified_latch_set());
// It is the same identity, it's just signed now so no pin violation
assert!(!carol_identity.has_pin_violation());
}
// Set up a machine do initial own key query.
// The cross signing secrets are not yet uploaded.
// Then query keys for carol and bob (both signed by own identity)
async fn common_verification_latch_own_trust_change_machine_setup() -> OlmMachine {
use test_json::keys_query_sets::VerificationLatchTestData as DataSet;
// Start on a non-verified session
let machine = OlmMachine::new(DataSet::own_id(), device_id!("LOCAL")).await;
let keys_query = DataSet::own_keys_query_response_1();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
// For sanity check that own identity is not trusted
let own_identity =
machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap().own().unwrap();
assert!(!own_identity.is_verified());
let keys_query = DataSet::own_keys_query_response_1();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
// Get Bob and Carol already signed
let keys_query = DataSet::bob_keys_query_response_signed();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
let keys_query = DataSet::carol_keys_query_response_signed();
let txn_id = TransactionId::new();
machine.mark_request_as_sent(&txn_id, &keys_query).await.unwrap();
machine.update_tracked_users(vec![DataSet::bob_id(), DataSet::carol_id()]).await.unwrap();
machine
}
#[async_test]
async fn test_manager_verified_latch_setup_on_own_identity_trust_change() {
use test_json::keys_query_sets::VerificationLatchTestData as DataSet;
let machine = common_verification_latch_own_trust_change_machine_setup().await;
let own_identity =
machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap().own().unwrap();
let bob_identity =
machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
// Carol is verified by our identity but our own identity is not yet trusted
assert!(own_identity.is_identity_signed(&bob_identity).is_ok());
assert!(!bob_identity.is_verified_latch_set());
let carol_identity = machine
.get_identity(DataSet::carol_id(), None)
.await
.unwrap()
.unwrap()
.other()
.unwrap();
// Carol is verified by our identity but our own identity is not yet trusted
assert!(own_identity.is_identity_signed(&carol_identity).is_ok());
assert!(!carol_identity.is_verified_latch_set());
// Marking our own identity as trusted should update the existing identities
let _ = own_identity.verify().await;
let own_identity =
machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap().own().unwrap();
assert!(own_identity.is_verified());
let carol_identity = machine
.get_identity(DataSet::carol_id(), None)
.await
.unwrap()
.unwrap()
.other()
.unwrap();
assert!(carol_identity.is_verified());
// The latch should be set now
assert!(carol_identity.is_verified_latch_set());
let bob_identity =
machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
assert!(bob_identity.is_verified());
// The latch should be set now
assert!(bob_identity.is_verified_latch_set());
}
#[async_test]
async fn test_manager_verified_latch_setup_on_import_secrets() {
use test_json::keys_query_sets::VerificationLatchTestData as DataSet;
let machine = common_verification_latch_own_trust_change_machine_setup().await;
let own_identity =
machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap().own().unwrap();
let bob_identity =
machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
// Carol is verified by our identity but our own identity is not yet trusted
assert!(own_identity.is_identity_signed(&bob_identity).is_ok());
assert!(!bob_identity.is_verified_latch_set());
let carol_identity = machine
.get_identity(DataSet::carol_id(), None)
.await
.unwrap()
.unwrap()
.other()
.unwrap();
// Carol is verified by our identity but our own identity is not yet trusted
assert!(own_identity.is_identity_signed(&carol_identity).is_ok());
assert!(!carol_identity.is_verified_latch_set());
// Marking our own identity as trusted should update the existing identities
machine
.import_cross_signing_keys(CrossSigningKeyExport {
master_key: DataSet::MASTER_KEY_PRIVATE_EXPORT.to_owned().into(),
self_signing_key: DataSet::SELF_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
user_signing_key: DataSet::USER_SIGNING_KEY_PRIVATE_EXPORT.to_owned().into(),
})
.await
.unwrap();
let own_identity =
machine.get_identity(DataSet::own_id(), None).await.unwrap().unwrap().own().unwrap();
assert!(own_identity.is_verified());
let carol_identity = machine
.get_identity(DataSet::carol_id(), None)
.await
.unwrap()
.unwrap()
.other()
.unwrap();
assert!(carol_identity.is_verified());
// The latch should be set now
assert!(carol_identity.is_verified_latch_set());
let bob_identity =
machine.get_identity(DataSet::bob_id(), None).await.unwrap().unwrap().other().unwrap();
assert!(bob_identity.is_verified());
// The latch should be set now
assert!(bob_identity.is_verified_latch_set());
}
}

View File

@@ -667,3 +667,424 @@ impl IdentityChangeDataSet {
.expect("Can't parse the `/keys/upload` response")
}
}
pub struct VerificationLatchTestData {}
#[allow(dead_code)]
impl VerificationLatchTestData {
pub const MASTER_KEY_PRIVATE_EXPORT: &'static str =
"bSa0nVTocZArMzL7OLmeFUIVF4ycp64rrkVMgqOYg6Y";
pub const SELF_SIGNING_KEY_PRIVATE_EXPORT: &'static str =
"MQ7b3MDXvOEMDvIOWkuH1XCNUyqBLqbdd1bT00p8HPU";
pub const USER_SIGNING_KEY_PRIVATE_EXPORT: &'static str =
"v77s+TlT5/NbcQym2B7Rwf20HOAhyInF2p1ZUYDPtow";
pub fn own_id() -> &'static UserId {
user_id!("@alice:localhost")
}
pub fn bob_id() -> &'static UserId {
user_id!("@bob:localhost")
}
pub fn carol_id() -> &'static UserId {
user_id!("@carol:localhost")
}
/// Current user keys query response containing the cross-signing keys
pub fn own_keys_query_response_1() -> KeyQueryResponse {
let data = json!({
"master_keys": {
"@alice:localhost": {
"keys": {
"ed25519:EPVg/QLG9+FmNvKjNXfycZEpQLtfHDaTN+rENAURZSk": "EPVg/QLG9+FmNvKjNXfycZEpQLtfHDaTN+rENAURZSk"
},
"signatures": {
"@alice:localhost": {
"ed25519:EPVg/QLG9+FmNvKjNXfycZEpQLtfHDaTN+rENAURZSk": "FX+srrw9SRmi12fexYHH1jrlEIWgOfre1aPNzDZWcAlaP9WKRdhcQGh70/3F9hk/PGr51I+ux62YgU4xnRTqAA",
"ed25519:PWVCNMMGCT": "teLq0rCYKX9h8WXu6kH8UE6HPKAtkF/DwCncxJGvVBCyZRtLHD8W1yYEzJXjTNynn+4fibQZBhR3th1RGLn4Ag"
}
},
"usage": [
"master"
],
"user_id": "@alice:localhost"
}
},
"self_signing_keys": {
"@alice:localhost": {
"keys": {
"ed25519:WXLer0esHUanp8DCeu2Be0xB5ms9aKFFBrCFl50COjw": "WXLer0esHUanp8DCeu2Be0xB5ms9aKFFBrCFl50COjw"
},
"signatures": {
"@alice:localhost": {
"ed25519:EPVg/QLG9+FmNvKjNXfycZEpQLtfHDaTN+rENAURZSk": "lCV9R1xjD34arzq/CAuej1XBv+Ip4dFfAGHfe7znbW7rnwKDaX5PaX3MHk+EIC7nXvUYEAn502WcUFme5c0cCQ"
}
},
"usage": [
"self_signing"
],
"user_id": "@alice:localhost"
}
},
"user_signing_keys": {
"@alice:localhost": {
"keys": {
"ed25519:MXob/N/bYI7U2655O1/AI9NOX1245RnE03Nl4Hvf+u0": "MXob/N/bYI7U2655O1/AI9NOX1245RnE03Nl4Hvf+u0"
},
"signatures": {
"@alice:localhost": {
"ed25519:EPVg/QLG9+FmNvKjNXfycZEpQLtfHDaTN+rENAURZSk": "A73QfZ5Dzhh7abdal/sEaq1bfgxzPFU8Bvwa9Y5TIe/a5jTmLVubNmsMSsO5tOT+b6aVJg1G4FtId0Q/cb1aAA"
}
},
"usage": [
"user_signing"
],
"user_id": "@alice:localhost"
}
}
});
let data = response_from_file(&data);
KeyQueryResponse::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
pub fn device_keys_payload_bob_unsigned_device() -> Value {
json!({
"algorithms": [
"m.olm.v1.curve25519-aes-sha2",
"m.megolm.v1.aes-sha2"
],
"device_id": "XCYNVRMTER",
"keys": {
"curve25519:XCYNVRMTER": "xGKYkFcHGlJ+I1yiefPyZu1EY8i2h1eed5uk3PAW6GA",
"ed25519:XCYNVRMTER": "EsU8MJzTYE+/VJs1K9HkGqb8UXCByPioynGrV28WocU"
},
"signatures": {
"@bob:localhost": {
"ed25519:XCYNVRMTER": "yZ7cpaoA+0rRx+bmklsP1iAd0eGPH6gsdywC11VE98/mrcbeFuxjQVn39Ds7h+vmciu5GRzwWgDgv+6go6FHAQ",
// Remove the cross-signature
// "ed25519:e8JFSrW8LW3UK6SSXh2ZESUzptFbapr28/+WqndD+Xk": "xYnGmU9FEdoavB5P743gx3xbEy29tlfRX5lT3JO0dWhHdsP+muqBXUYMBl1RRFeZtIE0GYc9ORb6Yf88EdeoCw"
}
},
"user_id": "@bob:localhost",
"unsigned": {}
})
}
pub fn bob_keys_query_response_signed() -> KeyQueryResponse {
let data = json!({
"device_keys": {
"@bob:localhost": {
"RLZGZIHKMP": {
"algorithms": [
"m.olm.v1.curve25519-aes-sha2",
"m.megolm.v1.aes-sha2"
],
"device_id": "RLZGZIHKMP",
"keys": {
"curve25519:RLZGZIHKMP": "Zd8uO9Rr1PtqNno3//ybeUZ3JuqFtm17TQTWW0f47AU",
"ed25519:RLZGZIHKMP": "kH+Zn2m7LPES/XLOyVvnf8t4Byfj3mAbngHptHZFzk0"
},
"signatures": {
"@bob:localhost": {
"ed25519:RLZGZIHKMP": "w4MOkDiD+4XatQrRzGrcaqwVmiZrAjxmaIA8aSuzQveD2SJ2eVZq3OSpqx6QRUbG/gkkZxGmY13PkS/iAOv0AA",
"ed25519:e8JFSrW8LW3UK6SSXh2ZESUzptFbapr28/+WqndD+Xk": "ki+cV0EVe5cYXnzqU078qy1qu2rnaxaBQU+KwyvPpEUotNTXjWKUOJfxast42d5tjI5vsI5aiQ6XkYfjBJ74Bw"
}
},
"user_id": "@bob:localhost",
"unsigned": {}
},
"XCYNVRMTER": Self::device_keys_payload_bob_unsigned_device(),
}
},
"failures": {},
"master_keys": {
"@bob:localhost": {
"keys": {
"ed25519:xZPyb4hxM8zaedDFz5m8HsDpX1fknd/V/69THLhNX9I": "xZPyb4hxM8zaedDFz5m8HsDpX1fknd/V/69THLhNX9I"
},
"signatures": {
"@bob:localhost": {
"ed25519:RLZGZIHKMP": "5bHLrx0HwYsNRtd65s1a1wVGlwgJU8yb8cq/Qbq04o9nVdQuY8+woQVWq9nxk59u6QFZIpFdVjXsuTPkDJLsBA",
"ed25519:xZPyb4hxM8zaedDFz5m8HsDpX1fknd/V/69THLhNX9I": "NA+cLNIPpmECcBIcmAH5l1K4IDXI6Xss1VmU8TZ04AYQSAh/2sv7NixEBO1/Raz0nErzkOl8gpRswHbHv1p7Dw"
},
"@alice:localhost": {
"ed25519:MXob/N/bYI7U2655O1/AI9NOX1245RnE03Nl4Hvf+u0": "n3X6afWYoSywqBpPlaDfQ2BNjl3ez5AzxEVwaB5/KEAzgwsq5B2qBW9N5uZaNWEq5M3JBrh0doj1FgUg4R3yBQ"
}
},
"usage": [
"master"
],
"user_id": "@bob:localhost"
}
},
"self_signing_keys": {
"@bob:localhost": {
"keys": {
"ed25519:e8JFSrW8LW3UK6SSXh2ZESUzptFbapr28/+WqndD+Xk": "e8JFSrW8LW3UK6SSXh2ZESUzptFbapr28/+WqndD+Xk"
},
"signatures": {
"@bob:localhost": {
"ed25519:xZPyb4hxM8zaedDFz5m8HsDpX1fknd/V/69THLhNX9I": "kkGZHLY18jyqXs412VB31u6vxijbaBgVrIMR/LBAFULhTZk6HGH951N6NxMZnYHyH0sFaQhsl4DUqt7XthBHBQ"
}
},
"usage": [
"self_signing"
],
"user_id": "@bob:localhost"
}
},
"user_signing_keys": {}
});
let data = response_from_file(&data);
KeyQueryResponse::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
pub fn bob_device_1_id() -> &'static DeviceId {
device_id!("RLZGZIHKMP")
}
pub fn bob_device_2_id() -> &'static DeviceId {
device_id!("XCYNVRMTER")
}
// Bob has a new identity, the two devices are properly self-signed
pub fn bob_keys_query_response_rotated() -> KeyQueryResponse {
let data = json!({
"device_keys": {
"@bob:localhost": {
"RLZGZIHKMP": {
"algorithms": [
"m.olm.v1.curve25519-aes-sha2",
"m.megolm.v1.aes-sha2"
],
"device_id": "RLZGZIHKMP",
"keys": {
"curve25519:RLZGZIHKMP": "Zd8uO9Rr1PtqNno3//ybeUZ3JuqFtm17TQTWW0f47AU",
"ed25519:RLZGZIHKMP": "kH+Zn2m7LPES/XLOyVvnf8t4Byfj3mAbngHptHZFzk0"
},
"signatures": {
"@bob:localhost": {
"ed25519:RLZGZIHKMP": "w4MOkDiD+4XatQrRzGrcaqwVmiZrAjxmaIA8aSuzQveD2SJ2eVZq3OSpqx6QRUbG/gkkZxGmY13PkS/iAOv0AA",
// "ed25519:At1ai1VUZrCncCI7V7fEAJmBShfpqZ30xRzqcEjTjdc": "rg3b3DovN3VztdcKyOcOlIGQxmm+8VC9+ImuXdgug/kPSi7QcljwOtjnk4LMkHexB3xVzB0ANcyNjbJ2cJuYBg",
"ed25519:e8JFSrW8LW3UK6SSXh2ZESUzptFbapr28/+WqndD+Xk": "ki+cV0EVe5cYXnzqU078qy1qu2rnaxaBQU+KwyvPpEUotNTXjWKUOJfxast42d5tjI5vsI5aiQ6XkYfjBJ74Bw"
}
},
"user_id": "@bob:localhost",
"unsigned": {
"device_display_name": "develop.element.io: Chrome on macOS"
}
},
"XCYNVRMTER": {
"algorithms": [
"m.olm.v1.curve25519-aes-sha2",
"m.megolm.v1.aes-sha2"
],
"device_id": "XCYNVRMTER",
"keys": {
"curve25519:XCYNVRMTER": "xGKYkFcHGlJ+I1yiefPyZu1EY8i2h1eed5uk3PAW6GA",
"ed25519:XCYNVRMTER": "EsU8MJzTYE+/VJs1K9HkGqb8UXCByPioynGrV28WocU"
},
"signatures": {
"@bob:localhost": {
"ed25519:XCYNVRMTER": "yZ7cpaoA+0rRx+bmklsP1iAd0eGPH6gsdywC11VE98/mrcbeFuxjQVn39Ds7h+vmciu5GRzwWgDgv+6go6FHAQ",
"ed25519:e8JFSrW8LW3UK6SSXh2ZESUzptFbapr28/+WqndD+Xk": "xYnGmU9FEdoavB5P743gx3xbEy29tlfRX5lT3JO0dWhHdsP+muqBXUYMBl1RRFeZtIE0GYc9ORb6Yf88EdeoCw",
"ed25519:NWoyMF4Ox8PEj+8l1e70zuIUg0D+wL9wtcj1KhWL0Bc": "2ieX8z+oW9JhdyIIkTDsQ2o5VWxcO6dOgeyPbRwbAL6Q8J6xujzYSIi568UAlPt+wg+RkNLshneexCPNMgSiDQ"
}
},
"user_id": "@bob:localhost",
"unsigned": {
"device_display_name": "app.element.io: Chrome on mac"
}
}
}
},
"failures": {},
"master_keys": {
"@bob:localhost": {
"keys": {
"ed25519:xaFlsDqlDRRy7Idtt1dW9mdhH/gvvax34q+HxepjNWY": "xaFlsDqlDRRy7Idtt1dW9mdhH/gvvax34q+HxepjNWY"
},
"signatures": {
"@bob:localhost": {
"ed25519:XCYNVRMTER": "K1aPl+GtcNi8yDqn1zvKIJMg3PFLQkwoXJeFJMmct4SA2SiQIl1S2x1bDTC3kQ4/LA7ULiQgKlxkXdQVf2GZDw",
"ed25519:xaFlsDqlDRRy7Idtt1dW9mdhH/gvvax34q+HxepjNWY": "S5vw8moiPudKhmF1qIv3/ehbZ7uohJbcQaLcOV+DDh9iC/YX0UqnaGn1ZYWJpIN7Kxe2ZWCBwzp35DOVZKfxBw"
}
},
"usage": [
"master"
],
"user_id": "@bob:localhost"
}
},
"self_signing_keys": {
"@bob:localhost": {
"keys": {
"ed25519:NWoyMF4Ox8PEj+8l1e70zuIUg0D+wL9wtcj1KhWL0Bc": "NWoyMF4Ox8PEj+8l1e70zuIUg0D+wL9wtcj1KhWL0Bc"
},
"signatures": {
"@bob:localhost": {
"ed25519:xaFlsDqlDRRy7Idtt1dW9mdhH/gvvax34q+HxepjNWY": "rwQIkR7JbZOrwGrmkW9QzFlK+lMjRDHVcGVlYNS/zVeDyvWxD0WFHcmy4p/LSgJDyrVt+th7LH7Bj+Ed/EGvCw"
}
},
"usage": [
"self_signing"
],
"user_id": "@bob:localhost"
}
},
"user_signing_keys": {}
});
let data = response_from_file(&data);
KeyQueryResponse::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
pub fn device_1_keys_payload_carol() -> Value {
json!({
// Not self signed
"algorithms": [
"m.olm.v1.curve25519-aes-sha2",
"m.megolm.v1.aes-sha2"
],
"device_id": "BAZAPVEHGA",
"keys": {
"curve25519:BAZAPVEHGA": "/mCcWJb5mtNGPC7m4iQeW8gVJB4nG8z/z2QQXzzNijw",
"ed25519:BAZAPVEHGA": "MLSoOlk27qcS/2O9Etp6XwgF8j+UT06yy/ypSeE9JRA"
},
"signatures": {
"@carol:localhost": {
"ed25519:BAZAPVEHGA": "y2+Z0ofRRoNMj864SoAcNEXRToYVeiARu39CO0Vj2GcSIxlpR7B8K1wDYV4luP4gOL1t1tPgJPXL1WO//AHHCw",
}
},
"user_id": "@carol:localhost"
})
}
pub fn device_2_keys_payload_carol() -> Value {
// Self-signed device
json!({
"algorithms": [
"m.olm.v1.curve25519-aes-sha2",
"m.megolm.v1.aes-sha2"
],
"device_id": "JBRBCHOFDZ",
"keys": {
"curve25519:JBRBCHOFDZ": "900HdrlfxlH8yMSmEQ3C32uVyXCuxKs5oPKS/wUgzVQ",
"ed25519:JBRBCHOFDZ": "BOINY06uroLYscHUq0e0FmUo/W0LC4/fsIPkZQe71NY"
},
"signatures": {
"@carol:localhost": {
"ed25519:JBRBCHOFDZ": "MmSJS3yEdeuseiLTDCQwImZBPNFMdhhkAFjRZZrIONoGFR0AMSzgLtx/nSgXP8RwVxpycvb6OAqvSk2toK3PDg",
"ed25519:ZOMWgk5LAogkwDEdZl9Rv7FRGu0nGbeLtMHx6anzhQs": "VtoxmPn/BQVDlpEHPEI2wPUlruUX9m2zV3FChNkRyEEWur4St27WA1He8BwjVRiiT0bdUnVH3xfmucoV9UnbDA"
}
},
"user_id": "@carol:localhost",
})
}
pub fn ssk_payload_carol() -> Value {
json!({
"@carol:localhost": {
"keys": {
"ed25519:ZOMWgk5LAogkwDEdZl9Rv7FRGu0nGbeLtMHx6anzhQs": "ZOMWgk5LAogkwDEdZl9Rv7FRGu0nGbeLtMHx6anzhQs"
},
"signatures": {
"@carol:localhost": {
"ed25519:itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U": "thjR1/kxHADXqLqxc4Q3OZhAaLq7SPL96LNCGVGN64OYAJ5yG1cpqAXBiBCUaBUTdRTb0ys601RR8djPdTK/BQ"
}
},
"usage": [
"self_signing"
],
"user_id": "@carol:localhost"
}
})
}
// Carol key query response with one signed and one unsigned device.
// Bob has not verified Carol yet
pub fn carol_keys_query_response_unsigned() -> KeyQueryResponse {
let data = json!({
"device_keys": {
"@carol:localhost": {
"BAZAPVEHGA": Self::device_1_keys_payload_carol(),
"JBRBCHOFDZ": Self::device_2_keys_payload_carol()
}
},
"failures": {},
"master_keys": {
"@carol:localhost": {
"keys": {
"ed25519:itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U": "itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U"
},
"signatures": {
"@carol:localhost": {
"ed25519:JBRBCHOFDZ": "eRA4jRSszQVuYpMtHTBuWGLEzcdUojyCW4/XKHRIQ2solv7iTC/MWES6I20YrHJa7H82CVoyNxS1Y3AwttBbCg",
"ed25519:itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U": "e3r5L+JLv6FB8+Tt4BlIbz4wk2qPeMoKL1uR079qZzYMvtKoWGK9p000cZIhA5R1Tl7buQ9ODUfizued8g3TAg"
},
// "@alice:localhost": {
// "ed25519:MXob/N/bYI7U2655O1/AI9NOX1245RnE03Nl4Hvf+u0": "yfRUvkaVg3KizC/HDXcuP4+gtYhxgzr8X916Wt4GRXjj4qhDjsCkf8mYZ7x4lcEXzRkYql5KelabgVzP12qmAA"
// }
},
"usage": [
"master"
],
"user_id": "@carol:localhost"
}
},
"self_signing_keys": Self::ssk_payload_carol(),
"user_signing_keys": {}
});
let data = response_from_file(&data);
KeyQueryResponse::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
pub fn carol_keys_query_response_signed() -> KeyQueryResponse {
let data = json!({
"device_keys": {
"@carol:localhost": {
"BAZAPVEHGA": Self::device_1_keys_payload_carol(),
"JBRBCHOFDZ": Self::device_2_keys_payload_carol()
}
},
"failures": {},
"master_keys": {
"@carol:localhost": {
"keys": {
"ed25519:itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U": "itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U"
},
"signatures": {
"@carol:localhost": {
"ed25519:JBRBCHOFDZ": "eRA4jRSszQVuYpMtHTBuWGLEzcdUojyCW4/XKHRIQ2solv7iTC/MWES6I20YrHJa7H82CVoyNxS1Y3AwttBbCg",
"ed25519:itnwUCRfBPW08IrmBks9MTp/Qm5AJ2WNca13ptIZF8U": "e3r5L+JLv6FB8+Tt4BlIbz4wk2qPeMoKL1uR079qZzYMvtKoWGK9p000cZIhA5R1Tl7buQ9ODUfizued8g3TAg"
},
"@alice:localhost": {
"ed25519:MXob/N/bYI7U2655O1/AI9NOX1245RnE03Nl4Hvf+u0": "yfRUvkaVg3KizC/HDXcuP4+gtYhxgzr8X916Wt4GRXjj4qhDjsCkf8mYZ7x4lcEXzRkYql5KelabgVzP12qmAA"
}
},
"usage": [
"master"
],
"user_id": "@carol:localhost"
}
},
"self_signing_keys": Self::ssk_payload_carol(),
"user_signing_keys": {}
});
let data = response_from_file(&data);
KeyQueryResponse::try_from_http_response(data)
.expect("Can't parse the `/keys/upload` response")
}
}