[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,
.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;
}

View file

@ -32,6 +32,7 @@
#include <Room.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Base64.h>
#include <Cytoplasm/Util.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Db.h>
@ -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)

View file

@ -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.