From: Patrick Date: Sat, 26 Aug 2023 12:41:39 +0000 (+0200) Subject: able to send encrypted messages :) X-Git-Url: https://gitweb.ps.run/matrix_esp_thesis/commitdiff_plain/8d8ae609f0201ec4640738ff49b768e899695423 able to send encrypted messages :) --- diff --git a/Makefile b/Makefile index e508b2e..c82a055 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CC=clang +CC=clang++ C_OPTS=-Wall -Wextra -pedantic C_OPTS+=src/matrix.c @@ -13,7 +13,7 @@ C_OPTS+=-l ws2_32 C_OPTS+=-l ssl C_OPTS+=-l crypto C_OPTS+=-l stdc++ -C_OPTS+=out/olm/libolm.a +C_OPTS+=out/olmdbg/libolm.a C_OPTS+=-D MG_ENABLE_OPENSSL=1 C_OPTS+=-fuse-ld=lld.exe -g -gcodeview -Wl,/debug,/pdb:out/test.pdb # C_OPTS+=-I ext/curl/include/ diff --git a/Todo.md b/Todo.md index 3e5dc6b..6698a4c 100644 --- a/Todo.md +++ b/Todo.md @@ -5,14 +5,14 @@ - automate script to generate header with size defines # Matrix Lib -- manage keys -- upload keys ++ manage keys ++ upload keys - create olm session - incoming - - outgoing -- store keys/sessions + + outgoing ++ store keys/sessions - respond to events - room_key_request -- add client saving/loading -- esp compatibility ++ add client saving/loading ++ esp compatibility - http requests in chunks/dynamically allocated \ No newline at end of file diff --git a/examples/Cli.c b/examples/Cli.c index daf79e9..56c23e1 100644 --- a/examples/Cli.c +++ b/examples/Cli.c @@ -5,8 +5,6 @@ #include #define SERVER "https://matrix.org" -#define ACCESS_TOKEN "syt_cHNjaG8_yBvTjVTquGCikvsAenOJ_49mBMO" -#define DEVICE_ID "MAZNCCZLBR" #define USER_ID "@pscho:matrix.org" #define ROOM_ID "!XKFUjAsGrSSrpDFIxB:matrix.org" @@ -70,29 +68,59 @@ Usage( printf("Usage: %s %s\n", cmd, args); } -void +bool ExecuteCommand( MatrixClient * client, const char * cmd, int nargs, char ** args ) { -#define CHECK_ARGS(N, ARGS) if (nargs != N) { Usage(cmd, ARGS); return; } - /**/ if (CheckCommand(cmd, "devicekey")) { - printf("%s\n", client->deviceKey); +#define CHECK_ARGS(N, ARGS) if (nargs != N) { Usage(cmd, ARGS); return true; } + + /**/ if (CheckCommand(cmd, "exit")) { + return false; + } + else if (CheckCommand(cmd, "devicekey")) { + static char key[DEVICE_KEY_SIZE]; + if (MatrixOlmAccountGetDeviceKey(&client->olmAccount, key, DEVICE_KEY_SIZE)) + printf("%s\n", key); + } + else if (CheckCommand(cmd, "accesstoken")) { + printf("%s\n", client->accessToken); } else if (CheckCommand(cmd, "genkeys")) { CHECK_ARGS(1, "") MatrixClientGenerateOnetimeKeys(client, atoi(args[0])); } - else if (CheckCommand(cmd, "uploadkeys")) { + else if (CheckCommand(cmd, "uploadonetimekeys")) { MatrixClientUploadOnetimeKeys(client); } + else if (CheckCommand(cmd, "uploaddevicekey")) { + MatrixClientUploadDeviceKey(client); + } else if (CheckCommand(cmd, "onetimekeys")) { static char buffer[1024]; olm_account_one_time_keys(client->olmAccount.account, buffer, 1024); printf("%s\n", buffer); } + else if (CheckCommand(cmd, "sendto")) { + CHECK_ARGS(3, " ") + + MatrixClientSendToDevice(client, + USER_ID, + args[0], + args[2], + args[1]); + } + else if (CheckCommand(cmd, "sendtoe")) { + CHECK_ARGS(3, " ") + + MatrixClientSendToDeviceEncrypted(client, + USER_ID, + args[0], + args[2], + args[1]); + } else if (CheckCommand(cmd, "getkeys")) { MatrixClientRequestDeviceKeys(client); for (int i = 0; i < client->numDevices; i++) @@ -115,6 +143,14 @@ ExecuteCommand( " ", mjson_print_fixed_buf, &fb); printf("%.*s\n", fb.len, fb.ptr); } + else if (CheckCommand(cmd, "login")) { + CHECK_ARGS(3, " ") + + MatrixClientLoginPassword(client, + args[0], + args[1], + args[2]); + } else if (CheckCommand(cmd, "save")) { CHECK_ARGS(1, "") @@ -138,6 +174,19 @@ ExecuteCommand( "m.room.message", body); } + else if (CheckCommand(cmd, "sendencrypted")) { + CHECK_ARGS(2, " ") + + static char body[1024]; + snprintf(body, 1024, + "{\"body\":\"%s\",\"msgtype\":\"m.text\"}", + args[1]); + + MatrixClientSendEventEncrypted(client, + args[0], + "m.room.message", + body); + } else if (CheckCommand(cmd, "setuserid")) { CHECK_ARGS(1, "") @@ -212,6 +261,8 @@ ExecuteCommand( printf("Unknown command\n"); } #undef CHECK_ARGS + + return true; } int @@ -223,12 +274,13 @@ main(void) MatrixHttpInit(&client); - MatrixClientSetAccessToken(&client, - ACCESS_TOKEN); - MatrixClientSetDeviceId(&client, - DEVICE_ID); - MatrixClientSetUserId(&client, - USER_ID); + + MatrixClientSetUserId(&client, USER_ID); + MatrixClientLoginPassword(&client, "@pscho:matrix.org", "Wc23EbmB9G3faMq", "abc"); + MatrixClientGenerateOnetimeKeys(&client, 10); + MatrixClientUploadDeviceKey(&client); + MatrixClientUploadOnetimeKeys(&client); + static char cmd[BUFFER_SIZE]; static char args_[NUMBER_ARGS][BUFFER_SIZE]; @@ -236,13 +288,18 @@ main(void) for (int i = 0; i < NUMBER_ARGS; i++) args[i] = args_[i]; int nargs; - do { + while (1) { GetCommand(cmd, &nargs, args); - ExecuteCommand(&client, cmd, nargs, args); - - } while (strcmp(cmd, "exit") != 0); + bool res = + ExecuteCommand(&client, cmd, nargs, args); + if (! res) + break; + } + + MatrixClientDeleteDevice(&client); + MatrixHttpDeinit(&client); return 0; diff --git a/examples/Cli.rdbg b/examples/Cli.rdbg new file mode 100644 index 0000000..f669888 Binary files /dev/null and b/examples/Cli.rdbg differ diff --git a/examples/OlmJS.c b/examples/OlmJS.c new file mode 100644 index 0000000..ea32858 --- /dev/null +++ b/examples/OlmJS.c @@ -0,0 +1,66 @@ +#include +#include + +#define SERVER "https://matrix.org" +#define USER_ID "@pscho:matrix.org" +#define DEVICE_ID "BYFEHWFCIV" +#define ACCESS_TOKEN "syt_cHNjaG8_GgutapSEvKWBQYTqjxQw_2UOtb4" + +char ROOM_ID[] = "!gngUimLZDmREazBCUv:matrix.org"; +char TARGET_DEVICE_ID[] = "ULZZOKJBYN"; +char TARGET_DEVICE_KEY[] = "cjP41XzRlY+pd8DoiBuKQJj9o15mrx6gkrpqTkAPZ2c"; +char OLM_PICKLE_KEY[] = "DEFAULT_KEY"; +char OLM_ACC_PICKLED[] = "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"; +char OLM_SESS_PICKLED[] = "zzgNbSTtwx2T1XjDqMuUSbk5aiIUZAsi4emwn8Ooxhxg1TVA73c+p4j9WypfAJjKoJin9cf23k00m1G/6wmISG6WB6KE9FO1jCTYYyDJX+GQxfUVvYwMlavZ9lN2Wax+wxP+3wJ0XZn7aFdjl//I7/lI3kCZGBPnNH+zWjv+19vJyOqz4SGKVTO1ojrds7tA7D7BOT/VxLziQK0XS/k604mWuSJd6BfMmU1bsadSxL2nT0UfhzJckfBkO7q/06twsnIwewKoskv5ZlCo5THoCxinm6aaC/VWozgU7n609xWGtuYdG2C6ijMmAjrfpNFAD9BNu/yqvU/ETfdMDYkhm+RDPlogr2mP"; + +// session id +// "dBe606wVTSvCSqvSz5pSHtH+f8CvjoB3od6UqOJkssI" + +int +main(void) +{ + MatrixClient client; + MatrixClientInit(&client, + SERVER); + + MatrixHttpInit(&client); + + MatrixClientSetUserId(&client, USER_ID); + MatrixClientSetDeviceId(&client, DEVICE_ID); + MatrixClientSetAccessToken(&client, ACCESS_TOKEN); + + MatrixOlmAccountUnpickle(&client.olmAccount, + OLM_ACC_PICKLED, strlen(OLM_ACC_PICKLED), + OLM_PICKLE_KEY, strlen(OLM_PICKLE_KEY)); + + // client.numOlmSessions = 1; + // MatrixOlmSessionUnpickle(&client.olmSessions[0], + // TARGET_DEVICE_ID, + // OLM_SESS_PICKLED, strlen(OLM_SESS_PICKLED), + // OLM_PICKLE_KEY, strlen(OLM_PICKLE_KEY)); + + // char id[1024]; + // int idLen = olm_session_id(client.olmSessions[0].session, id, 1024); + // printf("id: %s\n", id, idLen); + + // create megolmsession + MatrixMegolmOutSession * megolmOutSession; + MatrixClientGetMegolmOutSession(&client, + ROOM_ID, + &megolmOutSession); + printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key); + + MatrixClientShareMegolmOutSession(&client, + USER_ID, + TARGET_DEVICE_ID, + megolmOutSession); + + // MatrixClientSendEventEncrypted(&client, + // ROOM_ID, + // "m.room.message", + // "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}"); + + MatrixHttpDeinit(&client); + + return 0; +} diff --git a/examples/OlmJS.rdbg b/examples/OlmJS.rdbg new file mode 100644 index 0000000..dbd3618 Binary files /dev/null and b/examples/OlmJS.rdbg differ diff --git a/examples/SendEncrypted.c b/examples/SendEncrypted.c index 0005592..df1d272 100644 --- a/examples/SendEncrypted.c +++ b/examples/SendEncrypted.c @@ -2,8 +2,6 @@ #include #define SERVER "https://matrix.org" -#define ACCESS_TOKEN "syt_cHNjaG8_yBvTjVTquGCikvsAenOJ_49mBMO" -#define DEVICE_ID "MAZNCCZLBR" #define USER_ID "@pscho:matrix.org" #define ROOM_ID "!XKFUjAsGrSSrpDFIxB:matrix.org" @@ -16,32 +14,55 @@ main(void) MatrixHttpInit(&client); - MatrixClientSetAccessToken(&client, - ACCESS_TOKEN); - MatrixClientSetDeviceId(&client, - DEVICE_ID); - MatrixClientSetUserId(&client, - USER_ID); + MatrixClientSetUserId(&client, USER_ID); + MatrixClientLoginPassword(&client, + "pscho", + "Wc23EbmB9G3faMq", + "Test1"); - MatrixClientUploadDeviceKeys(&client); + MatrixClientUploadDeviceKey(&client); + MatrixClientGenerateOnetimeKeys(&client, 10); + MatrixClientUploadOnetimeKeys(&client); - MatrixClientSendEventEncrypted(&client, + // // get device key + // static char deviceKey[128]; + // MatrixClientGetDeviceKey(&client, + // "ULZZOKJBYN", + // deviceKey, 128); + // printf("device key for %s: %s\n", "ULZZOKJBYN", deviceKey); + + // create megolmsession + MatrixMegolmOutSession * megolmOutSession; + MatrixClientGetMegolmOutSession(&client, ROOM_ID, - "m.room.message", - "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}"); + &megolmOutSession); + printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key); - MatrixClientSendToDeviceEncrypted(&client, - USER_ID, - "ULZZOKJBYN", - "{}", - "m.dummy"); + // // create olmsession + // MatrixOlmSession * olmSession; + // MatrixClientGetOlmSession(&client, + // USER_ID, + // "ULZZOKJBYN", + // &olmSession); + // printf("olm session created\n"); MatrixClientShareMegolmOutSession(&client, USER_ID, "ULZZOKJBYN", - &client.megolmOutSessions[0]); + megolmOutSession); + // MatrixClientShareMegolmOutSessionTest(&client, + // USER_ID, + // "ULZZOKJBYN", + // megolmOutSession); + + MatrixClientSendEventEncrypted(&client, + ROOM_ID, + "m.room.message", + "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}"); + MatrixClientDeleteDevice(&client); + MatrixHttpDeinit(&client); return 0; diff --git a/examples/SendEncrypted.rdbg b/examples/SendEncrypted.rdbg index 120f0a0..8b74b2d 100644 Binary files a/examples/SendEncrypted.rdbg and b/examples/SendEncrypted.rdbg differ diff --git a/src/matrix.c b/src/matrix.c index de936de..06409b8 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -23,8 +23,8 @@ #define KEYS_QUERY_RESPONSE_SIZE (1024*10) #define KEYS_UPLOAD_URL "/_matrix/client/v3/keys/upload" -#define KEYS_UPLOAD_REQUEST_SIZE 1024 -#define KEYS_UPLOAD_REQUEST_SIGNED_SIZE 2048 +#define KEYS_UPLOAD_REQUEST_SIZE 1024*4 +#define KEYS_UPLOAD_REQUEST_SIGNED_SIZE 2048*4 #define KEYS_UPLOAD_RESPONSE_SIZE 2048 #define KEYS_CLAIM_URL "/_matrix/client/v3/keys/claim" @@ -88,6 +88,9 @@ bool JsonSign( signature, OLM_SIGNATURE_SIZE); int signatureLen = res; + + char thisSigningKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetSigningKey(&client->olmAccount, thisSigningKey, DEVICE_KEY_SIZE); static char signatureJson[JSON_SIGNATURE_SIZE]; int signatureJsonLen = @@ -100,7 +103,7 @@ bool JsonSign( "}" "}", client->userId, - client->deviceId, + "1", signatureLen, signature); struct mjson_fixedbuf result = { sOut, sOutCap, 0 }; @@ -131,7 +134,54 @@ MatrixOlmAccountInit( return res != olm_error(); } -// TODO: in/outbound sessions +bool +MatrixOlmAccountUnpickle( + MatrixOlmAccount * account, + void * pickled, int pickledLen, + const void * key, int keyLen) +{ + size_t res; + res = olm_unpickle_account(account->account, + key, keyLen, + pickled, pickledLen); + if (res == olm_error()) { + printf("error unpickling olm account:%s\n", + olm_account_last_error(account->account)); + } + return res != olm_error(); +} + +bool +MatrixOlmAccountGetDeviceKey( + MatrixOlmAccount * account, + char * key, int keyCap) +{ + static char deviceKeysJson[OLM_IDENTITY_KEYS_JSON_SIZE]; + size_t res = + olm_account_identity_keys(account->account, + deviceKeysJson, OLM_IDENTITY_KEYS_JSON_SIZE); + mjson_get_string(deviceKeysJson, res, + "$.curve25519", + key, keyCap); + return true; +} + +bool +MatrixOlmAccountGetSigningKey( + MatrixOlmAccount * account, + char * key, int keyCap) +{ + static char deviceKeysJson[OLM_IDENTITY_KEYS_JSON_SIZE]; + size_t res = + olm_account_identity_keys(account->account, + deviceKeysJson, OLM_IDENTITY_KEYS_JSON_SIZE); + mjson_get_string(deviceKeysJson, res, + "$.ed25519", + key, keyCap); + return true; +} + +// TODO:in/outbound sessions bool MatrixOlmSessionTo( MatrixOlmSession * session, @@ -158,12 +208,38 @@ MatrixOlmSessionTo( random, OLM_OUTBOUND_SESSION_RANDOM_SIZE); if (res == olm_error()) { - printf("error olm: %s\n", olm_account_last_error(olmAccount)); + printf("error olm:%s\n", olm_session_last_error(session->session)); } return session->session != NULL; } +bool +MatrixOlmSessionUnpickle( + MatrixOlmSession * session, + const char * deviceId, + void * pickled, int pickledLen, + const void * key, int keyLen) +{ + memset(session, 0, sizeof(MatrixOlmSession)); + + session->deviceId = deviceId; + + session->session = + olm_session(session->memory); + + size_t res; + res = olm_unpickle_session(session->session, + key, keyLen, + pickled, pickledLen); + + if (res == olm_error()) { + printf("error unpickling olm session:%s\n", olm_session_last_error(session->session)); + } + + return res != olm_error(); +} + bool MatrixOlmSessionEncrypt( MatrixOlmSession * session, @@ -306,21 +382,6 @@ MatrixClientInit( // init olm account MatrixOlmAccountInit(&client->olmAccount); - // set device key - static char deviceKeysJson[OLM_IDENTITY_KEYS_JSON_SIZE]; - size_t res = - olm_account_identity_keys( - client->olmAccount.account, - deviceKeysJson, - OLM_IDENTITY_KEYS_JSON_SIZE); - - mjson_get_string(deviceKeysJson, res, - "$.curve25519", - client->deviceKey, DEVICE_KEY_SIZE); - mjson_get_string(deviceKeysJson, res, - "$.ed25519", - client->signingKey, SIGNING_KEY_SIZE); - return true; } @@ -331,8 +392,15 @@ MatrixClientSave( { FILE * f = fopen(filename, "w"); - fwrite(client->deviceKey, 1, DEVICE_KEY_SIZE, f); - fwrite(client->signingKey, 1, DEVICE_KEY_SIZE, f); + + char thisDeviceKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE); + char thisSigningKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetSigningKey(&client->olmAccount, thisSigningKey, DEVICE_KEY_SIZE); + + + fwrite(thisDeviceKey, 1, DEVICE_KEY_SIZE, f); + fwrite(thisSigningKey, 1, DEVICE_KEY_SIZE, f); fwrite(client->userId, 1, USER_ID_SIZE, f); fwrite(client->server, 1, SERVER_SIZE, f); fwrite(client->accessToken, 1, ACCESS_TOKEN_SIZE, f); @@ -357,8 +425,15 @@ MatrixClientLoad( { FILE * f = fopen(filename, "r"); - fread(client->deviceKey, 1, DEVICE_KEY_SIZE, f); - fread(client->signingKey, 1, DEVICE_KEY_SIZE, f); + + char thisDeviceKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE); + char thisSigningKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetSigningKey(&client->olmAccount, thisSigningKey, DEVICE_KEY_SIZE); + + + fread(thisDeviceKey, 1, DEVICE_KEY_SIZE, f); + fread(thisSigningKey, 1, DEVICE_KEY_SIZE, f); fread(client->userId, 1, USER_ID_SIZE, f); fread(client->server, 1, SERVER_SIZE, f); fread(client->accessToken, 1, ACCESS_TOKEN_SIZE, f); @@ -480,9 +555,14 @@ MatrixClientUploadOnetimeKeys( // https://spec.matrix.org/v1.7/client-server-api/#post_matrixclientv3keysupload bool -MatrixClientUploadDeviceKeys( +MatrixClientUploadDeviceKey( MatrixClient * client) { + char thisDeviceKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE); + char thisSigningKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetSigningKey(&client->olmAccount, thisSigningKey, DEVICE_KEY_SIZE); + static char deviceKeysBuffer[KEYS_UPLOAD_REQUEST_SIZE]; mjson_snprintf(deviceKeysBuffer, KEYS_UPLOAD_REQUEST_SIZE, @@ -496,8 +576,8 @@ MatrixClientUploadDeviceKeys( "\"user_id\":\"%s\"" "}}", client->deviceId, - client->deviceId, client->deviceKey, - client->deviceId, client->signingKey, + client->deviceId, thisDeviceKey, + client->deviceId, thisSigningKey, client->userId); static char deviceKeysSignedBuffer[KEYS_UPLOAD_REQUEST_SIGNED_SIZE]; @@ -527,12 +607,12 @@ MatrixClientClaimOnetimeKey( static char requestBuffer[KEYS_CLAIM_REQUEST_SIZE]; mjson_snprintf(requestBuffer, KEYS_CLAIM_REQUEST_SIZE, "{" - "\"one_time_keys\": {" - "\"%s\": {" - "\"%s\": \"signed_curve25519\"" + "\"one_time_keys\":{" + "\"%s\":{" + "\"%s\":\"signed_curve25519\"" "}" "}," - "\"timeout\": 10000" + "\"timeout\":10000" "}", userId, deviceId); @@ -567,7 +647,7 @@ MatrixClientClaimOnetimeKey( mjson_get_string(keyObject + voff, vlen, "$.key", outOnetimeKey, outOnetimeKeyCap); - // TODO: verify signature + // TODO:verify signature return true; } @@ -584,13 +664,13 @@ MatrixClientLoginPassword( mjson_snprintf(requestBuffer, LOGIN_REQUEST_SIZE, "{" - "\"type\": \"m.login.password\"," - "\"identifier\": {" - "\"type\": \"m.id.user\"," - "\"user\": \"%s\"" + "\"type\":\"m.login.password\"," + "\"identifier\":{" + "\"type\":\"m.id.user\"," + "\"user\":\"%s\"" "}," - "\"password\": \"%s\"," - "\"initial_device_display_name\": \"%s\"" + "\"password\":\"%s\"," + "\"initial_device_display_name\":\"%s\"" "}", username, password, @@ -604,10 +684,10 @@ MatrixClientLoginPassword( responseBuffer, LOGIN_RESPONSE_SIZE, false); - int responseLen = strlen(responseBuffer); - if (!result) return false; + + int responseLen = strlen(responseBuffer); mjson_get_string(responseBuffer, responseLen, "$.access_token", @@ -679,8 +759,12 @@ MatrixClientSendEventEncrypted( requestBuffer, encryptedBuffer, ENCRYPTED_REQUEST_SIZE); + char thisDeviceKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE); + + // encrypted event json - const char * senderKey = client->deviceKey; + const char * senderKey = thisDeviceKey; const char * sessionId = outSession->id; const char * deviceId = client->deviceId; @@ -762,6 +846,7 @@ MatrixClientShareMegolmOutSession( bool MatrixClientShareMegolmOutSessionTest( MatrixClient * client, + const char * userId, const char * deviceId, MatrixMegolmOutSession * session) { @@ -781,7 +866,7 @@ MatrixClientShareMegolmOutSessionTest( // send MatrixClientSendToDevice(client, - client->userId, + userId, deviceId, eventBuffer, "m.room_key"); @@ -866,7 +951,7 @@ MatrixClientGetOlmSession( if (client->numOlmSessions < NUM_OLM_SESSIONS) { static char deviceKey[DEVICE_KEY_SIZE]; - MatrixClientGetDeviceKey(client, + MatrixClientRequestDeviceKey(client, deviceId, deviceKey, DEVICE_KEY_SIZE); @@ -909,8 +994,8 @@ MatrixClientSendToDevice( static char eventBuffer[TODEVICE_EVENT_SIZE]; snprintf(eventBuffer, TODEVICE_EVENT_SIZE, "{" - "\"messages\": {" - "\"%s\": {" + "\"messages\":{" + "\"%s\":{" "\"%s\":%s" "}" "}" @@ -943,29 +1028,36 @@ MatrixClientSendToDeviceEncrypted( MatrixClientGetOlmSession(client, userId, deviceId, &olmSession); // create event json - char deviceKey[DEVICE_KEY_SIZE]; - MatrixClientGetDeviceKey(client, deviceId, deviceKey, DEVICE_KEY_SIZE); + char targetDeviceKey[DEVICE_KEY_SIZE]; + MatrixClientRequestDeviceKey(client, deviceId, targetDeviceKey, DEVICE_KEY_SIZE); + char targetSigningKey[SIGNING_KEY_SIZE]; + MatrixClientRequestSigningKey(client, deviceId, targetSigningKey, SIGNING_KEY_SIZE); + char thisSigningKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetSigningKey(&client->olmAccount, thisSigningKey, DEVICE_KEY_SIZE); + static char eventBuffer[TODEVICE_EVENT_SIZE]; sprintf(eventBuffer, "{" - "\"type\": \"%s\"," - "\"content\": \"%s\"," - "\"sender\": \"%s\"," - "\"recipient\": \"%s\"," - "\"recipient_keys\": {" - "\"ed25519\": \"%s\"" + "\"type\":\"%s\"," + "\"content\":%s," + "\"sender\":\"%s\"," + "\"recipient\":\"%s\"," + "\"recipient_keys\":{" + "\"ed25519\":\"%s\"" "}," - "\"keys\": {" - "\"ed25519\": \"%s\"" + "\"keys\":{" + "\"ed25519\":\"%s\"" "}" "}", msgType, message, client->userId, userId, // recipient user id - deviceKey, // recipient device key - client->deviceKey); + targetSigningKey, // recipient device key + thisSigningKey); + + printf("%s\n", eventBuffer); // encrypt static char encryptedBuffer[ENCRYPTED_REQUEST_SIZE]; @@ -973,6 +1065,10 @@ MatrixClientSendToDeviceEncrypted( eventBuffer, encryptedBuffer, ENCRYPTED_REQUEST_SIZE); + char thisDeviceKey[DEVICE_KEY_SIZE]; + MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE); + + static char encryptedEventBuffer[ENCRYPTED_EVENT_SIZE]; sprintf(encryptedEventBuffer, "{" @@ -986,11 +1082,11 @@ MatrixClientSendToDeviceEncrypted( "\"device_id\":\"%s\"," "\"sender_key\":\"%s\"" "}", - deviceKey, + targetDeviceKey, encryptedBuffer, - 0, //olmSession->type, + olm_session_has_received_message(olmSession->session), client->deviceId, - client->deviceKey); + thisDeviceKey); // send return MatrixClientSendToDevice( @@ -1023,7 +1119,7 @@ MatrixClientFindDevice( } bool -MatrixClientGetDeviceKey( +MatrixClientRequestDeviceKey( MatrixClient * client, const char * deviceId, char * outDeviceKey, int outDeviceKeyCap) @@ -1047,6 +1143,31 @@ MatrixClientGetDeviceKey( return false; } +bool +MatrixClientRequestSigningKey( + MatrixClient * client, + const char * deviceId, + char * outSigningKey, int outSigningKeyCap) +{ + MatrixDevice * device; + + if (MatrixClientFindDevice(client, deviceId, &device)) + { + strncpy(outSigningKey, device->signingKey, outSigningKeyCap); + return true; + } + + MatrixClientRequestDeviceKeys(client); + + if (MatrixClientFindDevice(client, deviceId, &device)) + { + strncpy(outSigningKey, device->signingKey, outSigningKeyCap); + return true; + } + + return false; +} + // https://spec.matrix.org/v1.6/client-server-api/#post_matrixclientv3keysquery bool MatrixClientRequestDeviceKeys( @@ -1079,7 +1200,7 @@ MatrixClientRequestDeviceKeys( int slen; mjson_find(responseBuffer, strlen(responseBuffer), query, &s, &slen); - + // loop over keys int koff, klen, voff, vlen, vtype, off = 0; @@ -1100,11 +1221,26 @@ MatrixClientRequestDeviceKeys( mjson_get_string(val, vlen, deviceKeyQuery, d.deviceKey, DEVICE_KEY_SIZE); + // look for signing key in value + static char signingKeyQuery[JSON_QUERY_SIZE]; + snprintf(signingKeyQuery, JSON_QUERY_SIZE, + "$.keys.ed25519:%s", d.deviceId); + mjson_get_string(val, vlen, + signingKeyQuery, d.signingKey, SIGNING_KEY_SIZE); + // add device if (client->numDevices < NUM_DEVICES) { - client->devices[client->numDevices] = d; - client->numDevices++; + bool foundDevice = false; + for (int i = 0; i < client->numDevices; i++) + if (strcmp(client->devices[i].deviceId, d.deviceId) == 0) + foundDevice = true; + + if (! foundDevice) { + printf("new device: %s %s %s\n", d.deviceId, d.deviceKey, d.signingKey); + client->devices[client->numDevices] = d; + client->numDevices++; + } } else { @@ -1114,3 +1250,17 @@ MatrixClientRequestDeviceKeys( return true; } + +bool +MatrixClientDeleteDevice( + MatrixClient * client) +{ + static char deleteRequest[1024]; + snprintf(deleteRequest, 1024, + "{\"devices\":[\"%s\"]}", + client->deviceId); + static char deleteResponse[1024]; + bool res = MatrixHttpPost(client, "/_matrix/client/v3/delete_devices", + deleteRequest, deleteResponse, 1024, true); + return res; +} \ No newline at end of file diff --git a/src/matrix.h b/src/matrix.h index 3614b6a..b51d0e9 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -56,6 +56,7 @@ typedef struct MatrixDevice { char deviceId[DEVICE_ID_SIZE]; char deviceKey[DEVICE_KEY_SIZE]; + char signingKey[SIGNING_KEY_SIZE]; } MatrixDevice; @@ -70,17 +71,40 @@ bool MatrixOlmAccountInit( MatrixOlmAccount * account); +bool +MatrixOlmAccountUnpickle( + MatrixOlmAccount * account, + void * pickled, int pickledLen, + const void * key, int keyLen); + +bool +MatrixOlmAccountGetDeviceKey( + MatrixOlmAccount * account, + char * key, int keyCap); + +bool +MatrixOlmAccountGetSigningKey( + MatrixOlmAccount * account, + char * key, int keyCap); + // Matrix Olm Session typedef struct MatrixOlmSession { - const char * deviceId; + const char * deviceId; // TODO: char[] int type; OlmSession * session; char memory[OLM_SESSION_MEMORY_SIZE]; } MatrixOlmSession; +bool +MatrixOlmSessionUnpickle( + MatrixOlmSession * session, + const char * deviceId, + void * pickled, int pickledLen, + const void * key, int keyLen); + bool MatrixOlmSessionTo( MatrixOlmSession * session, @@ -151,8 +175,8 @@ typedef struct MatrixClient { MatrixDevice devices[NUM_DEVICES]; int numDevices; - char deviceKey[DEVICE_KEY_SIZE]; - char signingKey[DEVICE_KEY_SIZE]; + // char deviceKey[DEVICE_KEY_SIZE]; + // char signingKey[DEVICE_KEY_SIZE]; char userId[USER_ID_SIZE]; char server[SERVER_SIZE]; @@ -204,7 +228,7 @@ MatrixClientUploadOnetimeKeys( MatrixClient * client); bool -MatrixClientUploadDeviceKeys( +MatrixClientUploadDeviceKey( MatrixClient * client); bool @@ -250,6 +274,7 @@ MatrixClientShareMegolmOutSession( bool MatrixClientShareMegolmOutSessionTest( MatrixClient * client, + const char * userId, const char * deviceId, MatrixMegolmOutSession * session); @@ -294,21 +319,25 @@ MatrixClientSendToDeviceEncrypted( const char * msgType); bool -MatrixClientGetDeviceKey( +MatrixClientRequestDeviceKey( MatrixClient * client, const char * deviceId, char * outDeviceKey, int outDeviceKeyCap); - + bool -MatrixClientGetDeviceKey( +MatrixClientRequestSigningKey( MatrixClient * client, const char * deviceId, - char * outDeviceKey, int outDeviceKeyCap); + char * outSigningKey, int outSigningKeyCap); bool MatrixClientRequestDeviceKeys( MatrixClient * client); +bool +MatrixClientDeleteDevice( + MatrixClient * client); + @@ -357,7 +386,8 @@ JsonEscape( const char * sIn, int sInLen, char * sOut, int sOutCap); -bool JsonSign( +bool +JsonSign( MatrixClient * client, const char * sIn, int sInLen, char * sOut, int sOutCap); diff --git a/src/matrix_http_mongoose.c b/src/matrix_http_mongoose.c index a514f72..b9b2ca3 100644 --- a/src/matrix_http_mongoose.c +++ b/src/matrix_http_mongoose.c @@ -132,6 +132,15 @@ MatrixHttpGet( else authorizationHeader[0] = '\0'; + printf( + "GET %s HTTP/1.1\r\n" + "Host: %.*s\r\n" + "%s" + "\r\n", + url, + host.len, host.ptr, + authorizationHeader); + mg_printf(conn->connection, "GET %s HTTP/1.1\r\n" "Host: %.*s\r\n" @@ -173,6 +182,21 @@ MatrixHttpPost( else authorizationHeader[0] = '\0'; + printf( + "POST %s HTTP/1.0\r\n" + "Host: %.*s\r\n" + "%s" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "\r\n" + "%s" + "\r\n", + url, + host.len, host.ptr, + authorizationHeader, + strlen(requestBuffer), + requestBuffer); + mg_printf(conn->connection, "POST %s HTTP/1.0\r\n" "Host: %.*s\r\n" @@ -220,6 +244,22 @@ MatrixHttpPut( else authorizationHeader[0] = '\0'; + + printf( + "PUT %s HTTP/1.0\r\n" + "Host: %.*s\r\n" + "%s" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "\r\n" + "%s" + "\r\n", + url, + host.len, host.ptr, + authorizationHeader, + strlen(requestBuffer), + requestBuffer); + mg_printf(conn->connection, "PUT %s HTTP/1.0\r\n" "Host: %.*s\r\n"