diff --git a/modules/federation/user_keys_query.cc b/modules/federation/user_keys_query.cc index ae21df608..8e911c9b5 100644 --- a/modules/federation/user_keys_query.cc +++ b/modules/federation/user_keys_query.cc @@ -155,23 +155,104 @@ _query_master_keys(client &client, user_id_ }; - const m::user::room room + const m::user::room user_room { user_id }; const auto event_idx { - room.get(std::nothrow, "ircd.cross_signing.master", "") + user_room.get(std::nothrow, "ircd.cross_signing.master", "") }; - m::get(std::nothrow, event_idx, "content", [&response_keys, &user_id] - (const json::object &content) + m::get(std::nothrow, event_idx, "content", [&user_room, &user_id, &response_keys] + (const json::object &device_keys) { - json::stack::member + json::stack::object object { - response_keys, user_id, content + response_keys, user_id }; + + for(const auto &member : device_keys) + if(member.first != "signatures") + json::stack::member + { + object, member + }; + + const json::object device_keys_sigs + { + device_keys["signatures"] + }; + + json::stack::object sigs + { + object, "signatures" + }; + + json::stack::object user_sigs + { + sigs, user_id + }; + + const json::object device_keys_user_sigs + { + device_keys_sigs[user_id] + }; + + for(const auto &member : device_keys_user_sigs) + json::stack::member + { + user_sigs, member + }; + + const m::room::state state + { + user_room + }; + + for(const auto &[key_id__, key] : json::object(device_keys["keys"])) + { + const auto &[algo, key_id_] + { + split(key_id__, ':') + }; + + const auto key_id(key_id_); + state.for_each("ircd.keys.signatures", [&user_id, &user_sigs, &key_id] + (const string_view &, const string_view &state_key, const auto &event_idx) + { + const auto &[target, source] + { + rsplit(state_key, '%') + }; + + if(target != key_id) + return true; + + m::get(std::nothrow, event_idx, "content", [&user_id, &user_sigs] + (const json::object &device_sigs) + { + const json::object device_sigs_sigs + { + device_sigs["signatures"] + }; + + const json::object device_sigs_user_sigs + { + device_sigs_sigs[user_id] + }; + + for(const auto &member : device_sigs_user_sigs) + json::stack::member + { + user_sigs, member + }; + }); + + return true; + }); + } }); } }