From 9dcaab0819b8b5e345bb4bd8b8acac17ae5b2b85 Mon Sep 17 00:00:00 2001 From: lda Date: Sun, 19 May 2024 19:11:33 +0200 Subject: [PATCH] [ADD/FIX/WIP] Fix content hashing, respect creation_content. Oops, I *should* have known sha256 are stored as raw unpadded b64!base64! --- src/CanonicalJson.c | 7 ++----- src/Room.c | 39 +++++++++++++++++++++++++++++++------ src/include/CanonicalJson.h | 4 ++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/CanonicalJson.c b/src/CanonicalJson.c index 5847ef2..0de8abc 100644 --- a/src/CanonicalJson.c +++ b/src/CanonicalJson.c @@ -199,23 +199,20 @@ static const IoFunctions Functions = { .close = NULL, .seek = NULL }; -char * +unsigned char * CanonicalJsonHash(HashMap *json) { char *string = NULL; unsigned char *sha; - char *shastr; Io *string_writer = IoCreate(&string, Functions); Stream *io_stream = StreamIo(string_writer); CanonicalJsonEncode(json, io_stream); StreamFlush(io_stream); sha = Sha256(string); - shastr = ShaToHex(sha); Free(string); - Free(sha); StreamClose(io_stream); - return shastr; + return sha; } diff --git a/src/Room.c b/src/Room.c index d13dfc9..ce99bae 100644 --- a/src/Room.c +++ b/src/Room.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -82,7 +83,7 @@ static void RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s) { CommonID sender; - char *sender_str, *key; + char *sender_str, *key, *version; HashMap *content, *event, *override; Array *initial_states; JsonValue *val; @@ -104,6 +105,23 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s) { JsonSet(content, JsonValueString(sender_str), 1, "creator"); } + + version = req->room_version ? + StrDuplicate(req->room_version) : StrInt(room->version); + JsonSet(content, JsonValueString(version), 1, "room_version"); + Free(version); + + while (HashMapIterate(req->creation_content, &key, (void **) &val)) + { + JsonValue *content_v = HashMapGet(content, key); + if (content_v && + !StrEquals(key, "creator") && + !StrEquals(key, "room_version")) + { + continue; + } + JsonValueFree(HashMapSet(content, key, JsonValueDuplicate(val))); + } event = RoomEventCreate(sender_str, "m.room.create", "", content); JsonFree(RoomEventSend(room, event)); JsonFree(event); @@ -1428,23 +1446,32 @@ char * EventContentHash(HashMap * pdu_json) { HashMap * copy = JsonDuplicate(pdu_json); - char *hash; + unsigned char *sha; + char *b64; + JsonValueFree(HashMapDelete(copy, "unsigned")); JsonValueFree(HashMapDelete(copy, "signatures")); JsonValueFree(HashMapDelete(copy, "hashes")); - hash = CanonicalJsonHash(copy); + sha = CanonicalJsonHash(copy); + b64 = Base64Encode((const char *) sha, 32); + Base64Unpad(b64, strlen(b64)); + + Free(sha); JsonFree(copy); - return hash; + + return b64; } static char * RoomHashEventV1(PduV1 pdu) { HashMap *json = PduV1ToJson(&pdu); - char *sha = EventContentHash(json); + char *b64; + + b64 = EventContentHash(json); JsonFree(json); - return sha; + return b64; } static bool EventFits(HashMap *pdu) diff --git a/src/include/CanonicalJson.h b/src/include/CanonicalJson.h index 978de40..fad9371 100644 --- a/src/include/CanonicalJson.h +++ b/src/include/CanonicalJson.h @@ -83,11 +83,11 @@ extern int CanonicalJsonEncode(HashMap *, Stream *); * Computes a JSON object encoded as Canonical JSON's SHA-256 * hash. * - * This function returns a SHA-256 string stored on the heap, + * This function returns a SHA-256 hexstream stored on the heap, * which will need to be freed with * .Fn Free . */ -extern char * CanonicalJsonHash(HashMap *); +extern unsigned char * CanonicalJsonHash(HashMap *); /** * Encode a JSON value following the rules of Canonical JSON.