[ADD/FIX/WIP] Fix content hashing, respect creation_content.
Some checks are pending
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Waiting to run

Oops, I *should* have known sha256 are stored as raw unpadded b64!base64!
This commit is contained in:
lda 2024-05-19 19:11:33 +02:00
parent cacc72bf84
commit 9dcaab0819
3 changed files with 37 additions and 13 deletions

View file

@ -199,23 +199,20 @@ static const IoFunctions Functions = {
.close = NULL, .close = NULL,
.seek = NULL .seek = NULL
}; };
char * unsigned char *
CanonicalJsonHash(HashMap *json) CanonicalJsonHash(HashMap *json)
{ {
char *string = NULL; char *string = NULL;
unsigned char *sha; unsigned char *sha;
char *shastr;
Io *string_writer = IoCreate(&string, Functions); Io *string_writer = IoCreate(&string, Functions);
Stream *io_stream = StreamIo(string_writer); Stream *io_stream = StreamIo(string_writer);
CanonicalJsonEncode(json, io_stream); CanonicalJsonEncode(json, io_stream);
StreamFlush(io_stream); StreamFlush(io_stream);
sha = Sha256(string); sha = Sha256(string);
shastr = ShaToHex(sha);
Free(string); Free(string);
Free(sha);
StreamClose(io_stream); StreamClose(io_stream);
return shastr; return sha;
} }

View file

@ -32,6 +32,7 @@
#include <Room.h> #include <Room.h>
#include <Cytoplasm/Memory.h> #include <Cytoplasm/Memory.h>
#include <Cytoplasm/Base64.h>
#include <Cytoplasm/Util.h> #include <Cytoplasm/Util.h>
#include <Cytoplasm/Str.h> #include <Cytoplasm/Str.h>
#include <Cytoplasm/Db.h> #include <Cytoplasm/Db.h>
@ -82,7 +83,7 @@ static void
RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s) RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
{ {
CommonID sender; CommonID sender;
char *sender_str, *key; char *sender_str, *key, *version;
HashMap *content, *event, *override; HashMap *content, *event, *override;
Array *initial_states; Array *initial_states;
JsonValue *val; JsonValue *val;
@ -104,6 +105,23 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
{ {
JsonSet(content, JsonValueString(sender_str), 1, "creator"); 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); event = RoomEventCreate(sender_str, "m.room.create", "", content);
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
@ -1428,23 +1446,32 @@ char *
EventContentHash(HashMap * pdu_json) EventContentHash(HashMap * pdu_json)
{ {
HashMap * copy = JsonDuplicate(pdu_json); HashMap * copy = JsonDuplicate(pdu_json);
char *hash; unsigned char *sha;
char *b64;
JsonValueFree(HashMapDelete(copy, "unsigned")); JsonValueFree(HashMapDelete(copy, "unsigned"));
JsonValueFree(HashMapDelete(copy, "signatures")); JsonValueFree(HashMapDelete(copy, "signatures"));
JsonValueFree(HashMapDelete(copy, "hashes")); JsonValueFree(HashMapDelete(copy, "hashes"));
hash = CanonicalJsonHash(copy); sha = CanonicalJsonHash(copy);
b64 = Base64Encode((const char *) sha, 32);
Base64Unpad(b64, strlen(b64));
Free(sha);
JsonFree(copy); JsonFree(copy);
return hash;
return b64;
} }
static char * static char *
RoomHashEventV1(PduV1 pdu) RoomHashEventV1(PduV1 pdu)
{ {
HashMap *json = PduV1ToJson(&pdu); HashMap *json = PduV1ToJson(&pdu);
char *sha = EventContentHash(json); char *b64;
b64 = EventContentHash(json);
JsonFree(json); JsonFree(json);
return sha; return b64;
} }
static bool static bool
EventFits(HashMap *pdu) EventFits(HashMap *pdu)

View file

@ -83,11 +83,11 @@ extern int CanonicalJsonEncode(HashMap *, Stream *);
* Computes a JSON object encoded as Canonical JSON's SHA-256 * Computes a JSON object encoded as Canonical JSON's SHA-256
* hash. * 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 * which will need to be freed with
* .Fn Free . * .Fn Free .
*/ */
extern char * CanonicalJsonHash(HashMap *); extern unsigned char * CanonicalJsonHash(HashMap *);
/** /**
* Encode a JSON value following the rules of Canonical JSON. * Encode a JSON value following the rules of Canonical JSON.