Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Pass room_version into add_hashes_and_signatures #6806

Merged
merged 4 commits into from
Jan 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/6806.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactoring work in preparation for changing the event redaction algorithm.
20 changes: 13 additions & 7 deletions synapse/crypto/event_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@

from canonicaljson import encode_canonical_json
from signedjson.sign import sign_json
from signedjson.types import SigningKey
from unpaddedbase64 import decode_base64, encode_base64

from synapse.api.errors import Codes, SynapseError
from synapse.api.room_versions import RoomVersion
from synapse.events.utils import prune_event, prune_event_dict
from synapse.types import JsonDict

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -137,20 +140,23 @@ def compute_event_signature(event_dict, signature_name, signing_key):


def add_hashes_and_signatures(
event_dict, signature_name, signing_key, hash_algorithm=hashlib.sha256
room_version: RoomVersion,
event_dict: JsonDict,
signature_name: str,
signing_key: SigningKey,
):
"""Add content hash and sign the event

Args:
event_dict (dict): The event to add hashes to and sign
signature_name (str): The name of the entity signing the event
room_version: the version of the room this event is in

event_dict: The event to add hashes to and sign
signature_name: The name of the entity signing the event
(typically the server's hostname).
signing_key (syutil.crypto.SigningKey): The key to sign with
hash_algorithm: A hasher from `hashlib`, e.g. hashlib.sha256, to use
to hash the event
signing_key: The key to sign with
"""

name, digest = compute_content_hash(event_dict, hash_algorithm=hash_algorithm)
name, digest = compute_content_hash(event_dict, hash_algorithm=hashlib.sha256)

event_dict.setdefault("hashes", {})[name] = encode_base64(digest)

Expand Down
52 changes: 25 additions & 27 deletions synapse/events/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Optional

import attr
from nacl.signing import SigningKey

from twisted.internet import defer

Expand All @@ -23,13 +25,18 @@
KNOWN_EVENT_FORMAT_VERSIONS,
KNOWN_ROOM_VERSIONS,
EventFormatVersions,
RoomVersion,
)
from synapse.crypto.event_signing import add_hashes_and_signatures
from synapse.types import EventID
from synapse.events import (
EventBase,
_EventInternalMetadata,
event_type_from_format_version,
)
from synapse.types import EventID, JsonDict
from synapse.util import Clock
from synapse.util.stringutils import random_string

from . import _EventInternalMetadata, event_type_from_format_version


@attr.s(slots=True, cmp=False, frozen=True)
class EventBuilder(object):
Expand All @@ -40,7 +47,7 @@ class EventBuilder(object):
content/unsigned/internal_metadata fields are still mutable)

Attributes:
format_version (int): Event format version
room_version: Version of the target room
room_id (str)
type (str)
sender (str)
Expand All @@ -63,7 +70,7 @@ class EventBuilder(object):
_hostname = attr.ib()
_signing_key = attr.ib()

format_version = attr.ib()
room_version = attr.ib(type=RoomVersion)

room_id = attr.ib()
type = attr.ib()
Expand Down Expand Up @@ -108,7 +115,8 @@ def build(self, prev_event_ids):
)
auth_ids = yield self._auth.compute_auth_events(self, state_ids)

if self.format_version == EventFormatVersions.V1:
format_version = self.room_version.event_format
if format_version == EventFormatVersions.V1:
auth_events = yield self._store.add_event_hashes(auth_ids)
prev_events = yield self._store.add_event_hashes(prev_event_ids)
else:
Expand Down Expand Up @@ -148,7 +156,7 @@ def build(self, prev_event_ids):
clock=self._clock,
hostname=self._hostname,
signing_key=self._signing_key,
format_version=self.format_version,
room_version=self.room_version,
event_dict=event_dict,
internal_metadata_dict=self.internal_metadata.get_dict(),
)
Expand Down Expand Up @@ -201,7 +209,7 @@ def for_room_version(self, room_version, key_values):
clock=self.clock,
hostname=self.hostname,
signing_key=self.signing_key,
format_version=room_version.event_format,
room_version=room_version,
type=key_values["type"],
state_key=key_values.get("state_key"),
room_id=key_values["room_id"],
Expand All @@ -214,29 +222,19 @@ def for_room_version(self, room_version, key_values):


def create_local_event_from_event_dict(
clock,
hostname,
signing_key,
format_version,
event_dict,
internal_metadata_dict=None,
):
clock: Clock,
hostname: str,
signing_key: SigningKey,
room_version: RoomVersion,
event_dict: JsonDict,
internal_metadata_dict: Optional[JsonDict] = None,
) -> EventBase:
"""Takes a fully formed event dict, ensuring that fields like `origin`
and `origin_server_ts` have correct values for a locally produced event,
then signs and hashes it.

Args:
clock (Clock)
hostname (str)
signing_key
format_version (int)
event_dict (dict)
internal_metadata_dict (dict|None)

Returns:
FrozenEvent
"""

format_version = room_version.event_format
if format_version not in KNOWN_EVENT_FORMAT_VERSIONS:
raise Exception("No event format defined for version %r" % (format_version,))

Expand All @@ -257,7 +255,7 @@ def create_local_event_from_event_dict(

event_dict.setdefault("signatures", {})

add_hashes_and_signatures(event_dict, hostname, signing_key)
add_hashes_and_signatures(room_version, event_dict, hostname, signing_key)
return event_type_from_format_version(format_version)(
event_dict, internal_metadata_dict=internal_metadata_dict
)
Expand Down
4 changes: 1 addition & 3 deletions synapse/federation/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,6 @@ def send_request(destination):
if not room_version:
raise UnsupportedRoomVersionError()

event_format = room_version_to_event_format(room_version_id)

pdu_dict = ret.get("event", None)
if not isinstance(pdu_dict, dict):
raise InvalidResponseError("Bad 'event' field in response")
Expand All @@ -490,7 +488,7 @@ def send_request(destination):
self._clock,
self.hostname,
self.signing_key,
format_version=event_format,
room_version=room_version,
event_dict=pdu_dict,
)

Expand Down
9 changes: 7 additions & 2 deletions tests/crypto/test_event_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import nacl.signing
from unpaddedbase64 import decode_base64

from synapse.api.room_versions import RoomVersions
from synapse.crypto.event_signing import add_hashes_and_signatures
from synapse.events import FrozenEvent

Expand Down Expand Up @@ -49,7 +50,9 @@ def test_sign_minimal(self):
"unsigned": {"age_ts": 1000000},
}

add_hashes_and_signatures(event_dict, HOSTNAME, self.signing_key)
add_hashes_and_signatures(
RoomVersions.V1, event_dict, HOSTNAME, self.signing_key
)

event = FrozenEvent(event_dict)

Expand Down Expand Up @@ -81,7 +84,9 @@ def test_sign_message(self):
"unsigned": {"age_ts": 1000000},
}

add_hashes_and_signatures(event_dict, HOSTNAME, self.signing_key)
add_hashes_and_signatures(
RoomVersions.V1, event_dict, HOSTNAME, self.signing_key
)

event = FrozenEvent(event_dict)

Expand Down
4 changes: 2 additions & 2 deletions tests/handlers/test_presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from signedjson.key import generate_signing_key

from synapse.api.constants import EventTypes, Membership, PresenceState
from synapse.events import room_version_to_event_format
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
from synapse.events.builder import EventBuilder
from synapse.handlers.presence import (
EXTERNAL_PROCESS_EXPIRY,
Expand Down Expand Up @@ -597,7 +597,7 @@ def _add_new_user(self, room_id, user_id):
clock=self.clock,
hostname=hostname,
signing_key=self.random_signing_key,
format_version=room_version_to_event_format(room_version),
room_version=KNOWN_ROOM_VERSIONS[room_version],
room_id=room_id,
type=EventTypes.Member,
sender=user_id,
Expand Down