-
Notifications
You must be signed in to change notification settings - Fork 564
Relax validation of signature upload for master keys, and allow updates #19915
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
4d6d6aa
6681afc
9e38f10
b99257d
d3c8975
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Don't validate signatures with unknown algorithms for master keys, and allow updates to signatures. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| -- | ||
| -- This file is licensed under the Affero General Public License (AGPL) version 3. | ||
| -- | ||
| -- Copyright (C) 2026 New Vector, Ltd | ||
| -- | ||
| -- This program is free software: you can redistribute it and/or modify | ||
| -- it under the terms of the GNU Affero General Public License as | ||
| -- published by the Free Software Foundation, either version 3 of the | ||
| -- License, or (at your option) any later version. | ||
| -- | ||
| -- See the GNU Affero General Public License for more details: | ||
| -- <https://www.gnu.org/licenses/agpl-3.0.html>. | ||
|
|
||
| -- Adds the `key_id` to the e2e_cross_signing_signatures index, since the | ||
| -- ("user_id", "key_id", "target_user_id", "target_device_id") should be | ||
| -- unique. | ||
| INSERT INTO background_updates (ordering, update_name, progress_json) VALUES | ||
| (9205, 'e2e_cross_signing_signatures_add_key_id_to_index', '{}'); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,7 +20,7 @@ | |
| # | ||
| # | ||
| import time | ||
| from typing import Iterable | ||
| from typing import Any, Iterable | ||
| from unittest import mock | ||
|
|
||
| from parameterized import parameterized | ||
|
|
@@ -817,6 +817,102 @@ def test_reupload_signatures(self) -> None: | |
| self.assertDictEqual(devices["device_keys"][local_user]["abc"], device_key_1) | ||
| self.assertDictEqual(devices["device_keys"][local_user]["def"], device_key_2) | ||
|
|
||
| def test_update_signature_master_key(self) -> None: | ||
| """should be able to update a signature on the Master signing key with an unknown algorithm""" | ||
| local_user = "@boris:" + self.hs.hostname | ||
| master_key: dict[str, Any] = { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This type annotation seems overly broad to me, so suggestions welcome. Without it, mypy complains when I try to assign to |
||
| # private key: HvQBbU+hc2Zr+JP1sE0XwBe1pfZZEYtJNPJLZJtS+F8 | ||
| "user_id": local_user, | ||
| "usage": ["master"], | ||
| "keys": { | ||
| "ed25519:EmkqvokUn8p+vQAGZitOk4PWjp7Ukp3txV2TbMPEiBQ": "EmkqvokUn8p+vQAGZitOk4PWjp7Ukp3txV2TbMPEiBQ" | ||
| }, | ||
| "signatures": {local_user: {"unknown:abcdefg": "abcdefg"}}, | ||
| } | ||
| self_signing_key = { | ||
| # private key: 2lonYOM6xYKdEsO+6KrC766xBcHnYnim1x/4LFGF8B0 | ||
| "user_id": local_user, | ||
| "usage": ["self_signing"], | ||
| "keys": { | ||
| "ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk": "nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk" | ||
| }, | ||
| } | ||
| master_signing_key = key.decode_signing_key_base64( | ||
| "ed25519", | ||
| "EmkqvokUn8p+vQAGZitOk4PWjp7Ukp3txV2TbMPEiBQ", | ||
| "HvQBbU+hc2Zr+JP1sE0XwBe1pfZZEYtJNPJLZJtS+F8", | ||
| ) | ||
| sign.sign_json(self_signing_key, local_user, master_signing_key) | ||
| self.get_success( | ||
| self.handler.upload_signing_keys_for_user( | ||
| local_user, | ||
| {"master_key": master_key, "self_signing_key": self_signing_key}, | ||
| ) | ||
| ) | ||
|
|
||
| device_key: JsonDict = { | ||
| "user_id": local_user, | ||
| "device_id": "abc", | ||
| "algorithms": [ | ||
| "m.olm.curve25519-aes-sha2", | ||
| RoomEncryptionAlgorithms.MEGOLM_V1_AES_SHA2, | ||
| ], | ||
| "keys": { | ||
| "ed25519:abc": "base64+ed25519+key", | ||
| "curve25519:abc": "base64+curve25519+key", | ||
| }, | ||
| "signatures": {local_user: {"ed25519:abc": "base64+signature"}}, | ||
| } | ||
| self.get_success( | ||
| self.handler.upload_keys_for_user( | ||
| local_user, "abc", {"device_keys": device_key} | ||
| ) | ||
| ) | ||
|
|
||
| # update the signature and upload it | ||
| master_key["signatures"][local_user]["unknown:abcdefg"] = "ABCDEFG" | ||
| self.get_success( | ||
| self.handler.upload_signatures_for_device_keys( | ||
| local_user, | ||
| { | ||
| local_user: { | ||
| "EmkqvokUn8p+vQAGZitOk4PWjp7Ukp3txV2TbMPEiBQ": master_key | ||
| } | ||
| }, | ||
| ) | ||
| ) | ||
|
|
||
| devices = self.get_success( | ||
| self.handler.query_devices( | ||
| {"device_keys": {local_user: []}}, 0, local_user, "device123" | ||
| ) | ||
| ) | ||
| if "unsigned" in devices["master_keys"][local_user]: | ||
| del devices["master_keys"][local_user]["unsigned"] | ||
| self.assertDictEqual(devices["master_keys"][local_user], master_key) | ||
|
|
||
| # update the signature and upload it | ||
| master_key["signatures"][local_user]["unknown:abcdefg"] = "AbCdEfG" | ||
| self.get_success( | ||
| self.handler.upload_signatures_for_device_keys( | ||
| local_user, | ||
| { | ||
| local_user: { | ||
| "EmkqvokUn8p+vQAGZitOk4PWjp7Ukp3txV2TbMPEiBQ": master_key | ||
| } | ||
| }, | ||
| ) | ||
| ) | ||
|
|
||
| devices = self.get_success( | ||
| self.handler.query_devices( | ||
| {"device_keys": {local_user: []}}, 0, local_user, "device123" | ||
| ) | ||
| ) | ||
| if "unsigned" in devices["master_keys"][local_user]: | ||
| del devices["master_keys"][local_user]["unsigned"] | ||
| self.assertDictEqual(devices["master_keys"][local_user], master_key) | ||
|
|
||
| def test_self_signing_key_doesnt_show_up_as_device(self) -> None: | ||
| """signing keys should be hidden when fetching a user's devices""" | ||
| local_user = "@boris:" + self.hs.hostname | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what's the proper way to handle the case where we end up with duplicate values on those columns. I think that we shouldn't have any, but we should probably try to be safe.