From: Patrick Date: Thu, 29 Jun 2023 05:13:02 +0000 (+0200) Subject: generate key upload json + json signing X-Git-Url: https://gitweb.ps.run/matrix_esp_thesis/commitdiff_plain/fb5f3a8652d1cd3e4d8207f8718359f90636b5b3 generate key upload json + json signing --- diff --git a/examples/Keys.c b/examples/Keys.c index 77196ba..6dc2cc0 100644 --- a/examples/Keys.c +++ b/examples/Keys.c @@ -15,6 +15,10 @@ main(void) SERVER); MatrixHttpInit(&client); + + MatrixClientSetAccessToken(&client, ACCESS_TOKEN); + MatrixClientSetDeviceId(&client, DEVICE_ID); + MatrixClientSetUserId(&client, USER_ID); MatrixClientGenerateOnetimeKeys(&client, 10); diff --git a/examples/SendEncrypted.c b/examples/SendEncrypted.c index 0c4a7c8..f2bb8df 100644 --- a/examples/SendEncrypted.c +++ b/examples/SendEncrypted.c @@ -4,7 +4,8 @@ #define SERVER "https://matrix.org" #define ACCESS_TOKEN "syt_cHNjaG8_yBvTjVTquGCikvsAenOJ_49mBMO" #define DEVICE_ID "MAZNCCZLBR" -#define ROOM_ID "!koVStwyiiKcBVbXZYz:matrix.org" +#define USER_ID "@pscho:matrix.org" +#define ROOM_ID "!XKFUjAsGrSSrpDFIxB:matrix.org" int main(void) @@ -19,6 +20,8 @@ main(void) ACCESS_TOKEN); MatrixClientSetDeviceId(&client, DEVICE_ID); + MatrixClientSetUserId(&client, + USER_ID); // MatrixMegolmOutSession megolmOutSession; // MatrixMegolmOutSessionInit(&megolmOutSession); @@ -31,6 +34,10 @@ main(void) ROOM_ID, "m.room.message", "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}"); + + MatrixClientShareMegolmOutSessionTest(&client, + "ULZZOKJBYN", + &client.megolmOutSessions[0]); MatrixHttpDeinit(&client); diff --git a/src/matrix.c b/src/matrix.c index 33988b4..d1878c5 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -22,12 +22,17 @@ #define KEYS_QUERY_REQUEST_SIZE 256 #define KEYS_QUERY_RESPONSE_SIZE 1024 +#define UPLOAD_KEYS_REQUEST_SIZE 512 +#define UPLOAD_KEYS_REQUEST_SIGNED_SIZE 1024 + #define JSON_QUERY_SIZE 128 void -Randomize(uint8_t * random, int randomLen) +Randomize( + uint8_t * random, + int randomLen) { static bool first = false; if (first) { srand(time(0)); first = false; } @@ -65,6 +70,61 @@ JsonEscape( return true; } +bool JsonSign( + MatrixClient * client, + char * sIn, int sInLen, + char * sOut, int sOutCap) +{ + static char signature[OLM_SIGNATURE_SIZE]; + size_t res = + olm_account_sign(client->olmAccount.account, + sIn, sInLen, + signature, OLM_SIGNATURE_SIZE); + + int signatureLen = res; + + static char signatureJson[JSON_SIGNATURE_SIZE]; + int signatureJsonLen = + mjson_snprintf(signatureJson, JSON_SIGNATURE_SIZE, + "{" + "\"signatures\":{" + "\"%s\":{" + "\"ed25519:%s\":\"%.*s\"" + "}" + "}" + "}", + client->userId, + client->deviceId, + signatureLen, signature); + + struct mjson_fixedbuf result = { sOut, sOutCap, 0 }; + mjson_merge( + sIn, sInLen, + signatureJson, signatureJsonLen, + mjson_print_fixed_buf, + &result); + + return true; +} + + +bool +MatrixOlmAccountInit( + MatrixOlmAccount * account) +{ + account->account = olm_account(account->memory); + + static uint8_t random[OLM_ACCOUNT_RANDOM_SIZE]; + Randomize(random, OLM_ACCOUNT_RANDOM_SIZE); + + size_t res = olm_create_account( + account->account, + random, + OLM_ACCOUNT_RANDOM_SIZE); + + return res != olm_error(); +} + // TODO: in/outbound sessions bool MatrixOlmSessionInit( @@ -158,22 +218,13 @@ MatrixClientInit( strcpy(client->server, server); // init olm account - client->olmAccount = olm_account(client->olmAccountMemory); - - static uint8_t random[OLM_ACCOUNT_RANDOM_SIZE]; - Randomize(random, OLM_ACCOUNT_RANDOM_SIZE); - - size_t res; - res = olm_create_account( - client->olmAccount, - random, - OLM_ACCOUNT_RANDOM_SIZE); + MatrixOlmAccountInit(&client->olmAccount); // set device key static char deviceKeysJson[OLM_IDENTITY_KEYS_JSON_SIZE]; - res = + size_t res = olm_account_identity_keys( - client->olmAccount, + client->olmAccount.account, deviceKeysJson, OLM_IDENTITY_KEYS_JSON_SIZE); @@ -219,6 +270,113 @@ MatrixClientSetDeviceId( return true; } +bool +MatrixClientSetUserId( + MatrixClient * client, + const char * userId) +{ + int userIdLen = strlen(userId); + + if (userIdLen > USER_ID_SIZE - 1) + return false; + + for (int i = 0; i < userIdLen; i++) + client->userId[i] = userId[i]; + + return true; +} + +bool +MatrixClientGenerateOnetimeKeys( + MatrixClient * client, + int numberOfKeys) +{ + static uint8_t random[OLM_ONETIME_KEYS_RANDOM_SIZE]; + Randomize(random, OLM_ONETIME_KEYS_RANDOM_SIZE); + + size_t res = + olm_account_generate_one_time_keys(client->olmAccount.account, + numberOfKeys, random, OLM_ONETIME_KEYS_RANDOM_SIZE); + + return res != olm_error(); +} + +bool +MatrixClientUploadOnetimeKeys( + MatrixClient * client) +{ + static char requestBuffer[UPLOAD_KEYS_REQUEST_SIZE]; + + mjson_snprintf(requestBuffer, UPLOAD_KEYS_REQUEST_SIZE, + "{\"one_time_keys\":{"); + + static char onetimeKeysBuffer[1024]; + olm_account_one_time_keys(client->olmAccount.account, + onetimeKeysBuffer, 1024); + + const char *keys; + int keysLen; + mjson_find(onetimeKeysBuffer, strlen(onetimeKeysBuffer), "$.curve25519", &keys, &keysLen); + + int koff, klen, voff, vlen, vtype, off = 0; + while ((off = mjson_next(keys, keysLen, off, &koff, &klen, &voff, &vlen, &vtype)) != 0) { + static char keyJson[JSON_ONETIME_KEY_SIZE]; + + snprintf(keyJson, JSON_ONETIME_KEY_SIZE, + "{\"key\":\"%.*s\"}", + vlen-2, keys + voff+1); + + static char keyJsonSigned[JSON_ONETIME_KEY_SIGNED_SIZE]; + + JsonSign(client, + keyJson, JSON_ONETIME_KEY_SIZE, + keyJsonSigned, JSON_ONETIME_KEY_SIGNED_SIZE); + + mjson_snprintf(requestBuffer+strlen(requestBuffer), UPLOAD_KEYS_REQUEST_SIZE-strlen(requestBuffer), + "\"signed_curve25519:%.*s\":%s,", + klen-2, keys + koff+1, + keyJsonSigned); + } + + mjson_snprintf(requestBuffer+strlen(requestBuffer), UPLOAD_KEYS_REQUEST_SIZE-strlen(requestBuffer), + "}}"); + + printf("%s\n", requestBuffer); + + return true; +} + +bool +MatrixClientUploadDeviceKeys( + MatrixClient * client) +{ + static char deviceKeysBuffer[UPLOAD_KEYS_REQUEST_SIZE]; + + mjson_snprintf(deviceKeysBuffer, UPLOAD_KEYS_REQUEST_SIZE, + "{\"device_keys\":{" + "\"algorithms\":[\"m.olm.v1.curve25519-aes-sha2\",\"m.megolm.v1.aes-sha2\"]," + "\"device_id\":\"%s\"," + "\"keys\":{" + "\"curve25519:%s\":\"%s\"," + "\"ed25519:%s\":\"%s\"" + "}," + "\"user_id\":\"%s\"" + "}}", + client->deviceId, + client->deviceId, client->deviceKey, + client->deviceId, client->signingKey, + client->userId); + + static char deviceKeysSignedBuffer[UPLOAD_KEYS_REQUEST_SIGNED_SIZE]; + JsonSign(client, + deviceKeysBuffer, UPLOAD_KEYS_REQUEST_SIZE, + deviceKeysSignedBuffer, UPLOAD_KEYS_REQUEST_SIZE); + + printf("%s\n", deviceKeysSignedBuffer); + + return true; +} + // https://spec.matrix.org/v1.6/client-server-api/#post_matrixclientv3login bool MatrixClientLoginPassword( @@ -405,6 +563,36 @@ MatrixClientShareMegolmOutSession( return true; } +bool +MatrixClientShareMegolmOutSessionTest( + MatrixClient * client, + const char * deviceId, + MatrixMegolmOutSession * session) +{ + // generate room key event + char eventBuffer[KEY_SHARE_EVENT_LEN]; + sprintf(eventBuffer, + "{" + "\"algorithm\":\"m.megolm.v1.aes-sha2\"," + "\"room_id\":\"%s\"," + "\"session_id\":\"%s\"," + "\"session_key\":\"%s\"" + "}", + session->roomId, + session->id, + session->key + ); + + // send + MatrixClientSendToDevice(client, + client->userId, + deviceId, + eventBuffer, + "m.room_key"); + + return true; +} + // bool // MatrixClientSetMegolmOutSession( // MatrixClient * client, diff --git a/src/matrix.h b/src/matrix.h index 60561aa..38fb767 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -25,16 +25,25 @@ #define KEY_SHARE_EVENT_LEN 1024 #define OLM_ACCOUNT_MEMORY_SIZE 7528 -#define OLM_ACCOUNT_RANDOM_SIZE 32+32 +#define OLM_ACCOUNT_RANDOM_SIZE (32+32) #define OLM_SESSION_MEMORY_SIZE 3352 #define OLM_ENCRYPT_RANDOM_SIZE 32 +#define OLM_ONETIME_KEYS_RANDOM_SIZE 32*10 +#define OLM_KEY_ID_SIZE 32 + +#define OLM_SIGNATURE_SIZE 128 + #define MEGOLM_OUTBOUND_SESSION_MEMORY_SIZE 232 #define MEGOLM_SESSION_ID_SIZE 44 #define MEGOLM_SESSION_KEY_SIZE 306 #define MEGOLM_INIT_RANDOM_SIZE (4*32 + 32) +#define JSON_ONETIME_KEY_SIZE 128 +#define JSON_ONETIME_KEY_SIGNED_SIZE 256 +#define JSON_SIGNATURE_SIZE 256 + #define NUM_MEGOLM_SESSIONS 10 #define NUM_OLM_SESSIONS 10 #define NUM_DEVICES 10 @@ -46,12 +55,33 @@ bool JsonEscape( char * sIn, int sInLen, char * sOut, int sOutCap); + +bool JsonSign( + char * sIn, int sInLen, + char * sOut, int sOutCap); + +// Matrix Device typedef struct MatrixDevice { char deviceId[DEVICE_ID_SIZE]; char deviceKey[DEVICE_KEY_SIZE]; } MatrixDevice; + +// Matrix Olm Account + +typedef struct MatrixOlmAccount { + OlmAccount * account; + char memory[OLM_ACCOUNT_MEMORY_SIZE]; +} MatrixOlmAccount; + +bool +MatrixOlmAccountInit( + MatrixOlmAccount * account); + + +// Matrix Olm Session + typedef struct MatrixOlmSession { const char * deviceId; @@ -72,6 +102,7 @@ MatrixOlmSessionEncrypt( char * outBuffer, int outBufferCap); +// Matrix Megolm Session typedef struct MatrixMegolmInSession { OlmInboundGroupSession * session; @@ -99,10 +130,10 @@ MatrixMegolmOutSessionEncrypt( char * outBuffer, int outBufferCap); +// Matrix Client typedef struct MatrixClient { - OlmAccount * olmAccount; - char olmAccountMemory[OLM_ACCOUNT_MEMORY_SIZE]; + MatrixOlmAccount olmAccount; MatrixMegolmInSession megolmInSessions[NUM_MEGOLM_SESSIONS]; int numMegolmInSessions; @@ -142,6 +173,24 @@ MatrixClientSetDeviceId( MatrixClient * client, const char * deviceId); +bool +MatrixClientSetUserId( + MatrixClient * client, + const char * userId); + +bool +MatrixClientGenerateOnetimeKeys( + MatrixClient * client, + int numberOfKeys); + +bool +MatrixClientUploadOnetimeKeys( + MatrixClient * client); + +bool +MatrixClientUploadDeviceKeys( + MatrixClient * client); + bool MatrixClientLoginPassword( MatrixClient * client, @@ -174,6 +223,12 @@ MatrixClientShareMegolmOutSession( const char * deviceId, MatrixMegolmOutSession * session); +bool +MatrixClientShareMegolmOutSessionTest( + MatrixClient * client, + const char * deviceId, + MatrixMegolmOutSession * session); + bool MatrixClientGetMegolmOutSession( MatrixClient * client,