From c05cfa114da88b6c7a885d5e79a33ad068d06d3a Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris <sideris.konstantin@gmail.com> Date: Tue, 3 Apr 2018 12:28:35 +0300 Subject: [PATCH] Implement /keys/query --- src/client.cpp | 9 +++++ src/client.hpp | 5 +++ tests/e2ee.cpp | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/src/client.cpp b/src/client.cpp index 71ebb954c..b19f6fc7b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -568,3 +568,12 @@ Client::upload_keys( post<mtx::requests::UploadKeys, mtx::responses::UploadKeys>( "/client/r0/keys/upload", req, callback); } + +void +Client::query_keys( + const mtx::requests::QueryKeys &req, + std::function<void(const mtx::responses::QueryKeys &res, RequestErr err)> callback) +{ + post<mtx::requests::QueryKeys, mtx::responses::QueryKeys>( + "/client/r0/keys/query", req, callback); +} diff --git a/src/client.hpp b/src/client.hpp index 94509748e..4ba7d1169 100644 --- a/src/client.hpp +++ b/src/client.hpp @@ -206,6 +206,11 @@ public: const mtx::requests::UploadKeys &req, std::function<void(const mtx::responses::UploadKeys &res, RequestErr err)> cb); + //! Returns the current devices and identity keys for the given users. + void query_keys( + const mtx::requests::QueryKeys &req, + std::function<void(const mtx::responses::QueryKeys &res, RequestErr err)> cb); + private: template<class Request, class Response> void post(const std::string &endpoint, diff --git a/tests/e2ee.cpp b/tests/e2ee.cpp index 3eb8de83a..52c04dad7 100644 --- a/tests/e2ee.cpp +++ b/tests/e2ee.cpp @@ -162,3 +162,110 @@ TEST(Encryption, UploadKeys) alice->close(); } + +TEST(Encryption, QueryKeys) +{ + auto alice = std::make_shared<Client>("localhost"); + auto alice_olm = mtx::client::crypto::olm_new_account(); + + auto bob = std::make_shared<Client>("localhost"); + auto bob_olm = mtx::client::crypto::olm_new_account(); + + alice->login( + "alice", "secret", [](const mtx::responses::Login &, ErrType err) { check_error(err); }); + + bob->login( + "bob", "secret", [](const mtx::responses::Login &, ErrType err) { check_error(err); }); + + while (alice->access_token().empty() || bob->access_token().empty()) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // Create and upload keys for both users. + auto alice_idks = mtx::client::crypto::identity_keys(alice_olm); + auto bob_idks = mtx::client::crypto::identity_keys(bob_olm); + + mtx::client::crypto::generate_one_time_keys(alice_olm, 1); + mtx::client::crypto::generate_one_time_keys(bob_olm, 1); + + auto alice_otks = mtx::client::crypto::one_time_keys(alice_olm); + auto bob_otks = mtx::client::crypto::one_time_keys(bob_olm); + + auto alice_req = mtx::client::crypto::create_upload_keys_request( + alice_olm, alice_idks, alice_otks, alice->user_id(), alice->device_id()); + + auto bob_req = mtx::client::crypto::create_upload_keys_request( + bob_olm, bob_idks, bob_otks, bob->user_id(), bob->device_id()); + + // Validates that both upload requests are finished. + atomic_int uploads(0); + + alice->upload_keys(alice_req, + [&uploads](const mtx::responses::UploadKeys &res, ErrType err) { + check_error(err); + EXPECT_EQ(res.one_time_key_counts.size(), 1); + EXPECT_EQ(res.one_time_key_counts.at("signed_curve25519"), 1); + + uploads += 1; + }); + + bob->upload_keys(bob_req, [&uploads](const mtx::responses::UploadKeys &res, ErrType err) { + check_error(err); + EXPECT_EQ(res.one_time_key_counts.size(), 1); + EXPECT_EQ(res.one_time_key_counts.at("signed_curve25519"), 1); + + uploads += 1; + }); + + while (uploads != 2) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + atomic_int responses(0); + + // Each user is requests each other's keys. + mtx::requests::QueryKeys alice_rk; + alice_rk.device_keys[bob->user_id().to_string()] = {}; + alice->query_keys( + alice_rk, [&responses, bob, bob_req](const mtx::responses::QueryKeys &res, ErrType err) { + check_error(err); + + ASSERT_TRUE(res.failures.size() == 0); + + auto bob_devices = res.device_keys.at(bob->user_id().to_string()); + ASSERT_TRUE(bob_devices.size() > 0); + + auto dev_keys = bob_devices.at(bob->device_id()); + EXPECT_EQ(dev_keys.user_id, bob->user_id().to_string()); + EXPECT_EQ(dev_keys.device_id, bob->device_id()); + EXPECT_EQ(dev_keys.keys, bob_req.device_keys.keys); + EXPECT_EQ(dev_keys.signatures, bob_req.device_keys.signatures); + + responses += 1; + }); + + mtx::requests::QueryKeys bob_rk; + bob_rk.device_keys[alice->user_id().to_string()] = {}; + bob->query_keys( + bob_rk, + [&responses, alice, alice_req](const mtx::responses::QueryKeys &res, ErrType err) { + check_error(err); + + ASSERT_TRUE(res.failures.size() == 0); + + auto bob_devices = res.device_keys.at(alice->user_id().to_string()); + ASSERT_TRUE(bob_devices.size() > 0); + + auto dev_keys = bob_devices.at(alice->device_id()); + EXPECT_EQ(dev_keys.user_id, alice->user_id().to_string()); + EXPECT_EQ(dev_keys.device_id, alice->device_id()); + EXPECT_EQ(dev_keys.keys, alice_req.device_keys.keys); + EXPECT_EQ(dev_keys.signatures, alice_req.device_keys.signatures); + + responses += 1; + }); + + while (responses != 2) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + alice->close(); + bob->close(); +} -- GitLab