int
main(void)
{
- // static MatrixClient _client;
- // MatrixClient * client = &_client;
- MatrixClient * client = (MatrixClient*)malloc(sizeof(MatrixClient));
- MatrixClientInit(client);
+ MatrixClient client;
+ MatrixClientInit(&client);
+
+ MatrixHttpInit(&client.hc, SERVER);
- MatrixHttpInit(&client->hc, SERVER);
- MatrixClientSetUserId(client, USER_ID);
+ MatrixClientSetUserId(&client, USER_ID);
- static char key[1024];
- MatrixOlmAccountGetDeviceKey(&client->olmAccount, key, 1024);
- printf("key: %s\n", key);
-
- //MatrixClientSetUserId(client, USER_ID);
-
- MatrixClientLoginPassword(client,
+ MatrixClientLoginPassword(&client,
"pscho",
"Wc23EbmB9G3faMq",
"Test1");
- // MatrixClientSendEvent(client,
- // ROOM_ID,
- // "m.room.message",
- // "{\"body\":\"Hello\",\"msgtype\":\"m.text\"}");
-
- MatrixClientUploadDeviceKey(client);
- MatrixClientGenerateOnetimeKeys(client, 10);
- MatrixClientUploadOnetimeKeys(client);
+ MatrixClientUploadDeviceKeys(&client);
+ MatrixClientGenerateOnetimeKeys(&client, 10);
+ MatrixClientUploadOnetimeKeys(&client);
// create megolmsession
MatrixMegolmOutSession * megolmOutSession;
- MatrixClientNewMegolmOutSession(client,
+ MatrixClientNewMegolmOutSession(&client,
ROOM_ID,
&megolmOutSession);
printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);
- // heap_caps_get_free_size();
- // xPortGetFreeHeapSize();
-
- MatrixClientShareMegolmOutSession(client,
+ MatrixClientShareMegolmOutSession(&client,
USER_ID,
"ULZZOKJBYN",
megolmOutSession);
- MatrixClientSendEventEncrypted(client,
+ MatrixClientSendEventEncrypted(&client,
ROOM_ID,
"m.room.message",
"{\"body\":\"Hello\",\"msgtype\":\"m.text\"}");
-
- MatrixClientDeleteDevice(client);
+
+ MatrixClientDeleteDevice(&client);
- MatrixHttpDeinit(&client->hc);
+ MatrixHttpDeinit(&client.hc);
return 0;
}
// main stack size: 3584
-bool verified = false;
-char transactionId[64];
-OlmSAS * olmSas = NULL;
-
#define STATIC static
-STATIC char encrypted[2048];
-STATIC char decrypted[2048];
-
-void
-HandleEvent(
- MatrixClient * client,
- const char * event, int eventLen
-) {
- STATIC char eventType[128];
- memset(eventType, 0, sizeof(eventType));
- mjson_get_string(event, eventLen, "$.type", eventType, 128);
-
- if (strcmp(eventType, "m.key.verification.request") == 0) {
- mjson_get_string(event, eventLen, "$.content.transaction_id", transactionId, 256);
-
- char verificationReadyBuffer[2048];
- snprintf(verificationReadyBuffer, 2048,
- "{"
- "\"from_device\":\"%s\","
- "\"methods\":[\"m.sas.v1\"],"
- "\"transaction_id\":\"%s\""
- "}",
- client->deviceId,
- transactionId);
-
- MatrixClientSendToDevice(client,
- USER_ID,
- DEVICE_ID,
- verificationReadyBuffer,
- "m.key.verification.ready");
- }
- else if (strcmp(eventType, "m.key.verification.start") == 0) {
- olmSas = olm_sas(malloc(olm_sas_size()));
- void * sasRandomBytes = malloc(olm_create_sas_random_length(olmSas));
- olm_create_sas(olmSas,
- sasRandomBytes,
- olm_create_sas_random_length(olmSas));
-
- OlmUtility * olmUtil = olm_utility(malloc(olm_utility_size()));
-
- STATIC char publicKey[64];
- STATIC char keyStartJsonCanonical[512];
- STATIC char concat[512+64];
- STATIC char commitment[1024];
- olm_sas_get_pubkey(olmSas,
- publicKey,
- 64);
- printf("public key: %.*s\n", olm_sas_pubkey_length(olmSas), publicKey);
-
- const char * keyStartJson;
- int keyStartJsonLen;
- mjson_find(event, eventLen, "$.content", &keyStartJson, &keyStartJsonLen);
- JsonCanonicalize(keyStartJson, keyStartJsonLen, keyStartJsonCanonical, 512);
-
- printf("json:\n%.*s\ncanonical json:\n%s\n", keyStartJsonLen, keyStartJson, keyStartJsonCanonical);
-
- int concatLen =
- snprintf(concat, 512+64, "%.*s%s", olm_sas_pubkey_length(olmSas), publicKey, keyStartJsonCanonical);
-
- int commitmentLen =
- olm_sha256(olmUtil, concat, concatLen, commitment, 1024);
-
- STATIC char verificationAcceptBuffer[512];
- snprintf(verificationAcceptBuffer, 512,
- "{"
- "\"commitment\":\"%.*s\","
- "\"hash\":\"sha256\","
- "\"key_agreement_protocol\":\"curve25519\","
- "\"message_authentication_code\":\"hkdf-hmac-sha256.v2\","
- "\"method\":\"m.sas.v1\","
- "\"short_authentication_string\":[\"decimal\"],"
- "\"transaction_id\":\"%s\""
- "}",
- commitmentLen, commitment,
- transactionId);
-
- MatrixClientSendToDevice(client,
- USER_ID,
- DEVICE_ID,
- verificationAcceptBuffer,
- "m.key.verification.accept");
- }
- else if (strcmp(eventType, "m.key.verification.key") == 0) {
- STATIC char publicKey[128];
- olm_sas_get_pubkey(olmSas,
- publicKey,
- 128);
-
- STATIC char theirPublicKey[128];
- int theirPublicKeyLen =
- mjson_get_string(event, eventLen, "$.content.key", theirPublicKey, 128);
-
- printf("event: %.*s\n", eventLen, event);
- printf("theirPublicKey: %.*s\n", theirPublicKeyLen, theirPublicKey);
- printf("publicKey: %.*s\n", olm_sas_pubkey_length(olmSas), publicKey);
-
- olm_sas_set_their_key(olmSas, theirPublicKey, theirPublicKeyLen);
-
- STATIC char verificationKeyBuffer[256];
- snprintf(verificationKeyBuffer, 256,
- "{"
- "\"key\":\"%.*s\","
- "\"transaction_id\":\"%s\""
- "}",
- olm_sas_pubkey_length(olmSas), publicKey,
- transactionId);
-
- MatrixClientSendToDevice(client,
- USER_ID,
- DEVICE_ID,
- verificationKeyBuffer,
- "m.key.verification.key");
-
- // sas
- STATIC char hkdfInfo[1024];
- int hkdfInfoLen =
- snprintf(hkdfInfo, 1024,
- "MATRIX_KEY_VERIFICATION_SAS%s%s%s%s%s",
- USER_ID,
- DEVICE_ID,
- USER_ID,
- client->deviceId,
- transactionId);
-
- unsigned char sasBytes[5];
- olm_sas_generate_bytes(olmSas,
- hkdfInfo, hkdfInfoLen,
- sasBytes, 5);
- int b0 = sasBytes[0];
- int b1 = sasBytes[1];
- int b2 = sasBytes[2];
- int b3 = sasBytes[3];
- int b4 = sasBytes[4];
-
- printf("%d %d %d %d %d\n", b0, b1, b2, b3, b4);
-
- // https://spec.matrix.org/v1.7/client-server-api/#sas-method-decimal
- printf("%d | %d | %d\n",
- (b0 << 5 | b1 >> 3) + 1000,
- ((b1 & 0x7) << 10 | b2 << 2 | b3 >> 6) + 1000,
- ((b3 & 0x3F) << 7 | b4 >> 1) + 1000);
- printf("%d | %d | %d\n",
- ((b0 << 5) | (b1 >> 3)) + 1000,
- (((b1 & 0x7) << 10) | (b2 << 2) | (b3 >> 6)) + 1000,
- (((b3 & 0x3F) << 7) | (b4 >> 1)) + 1000);
- }
- else if (strcmp(eventType, "m.key.verification.mac") == 0) {
- // mac
- const char * masterKey = "vt8tJ5/SxqkvXS+XoGxr+4rJNe8fJfZT3/e/FTwlFsI";
-
- STATIC char keyList[256];
- STATIC char keyListMac[256];
- STATIC char key1Id[128];
- STATIC char key1[128];
- STATIC char key1Mac[128];
- STATIC char key2Id[128];
- STATIC char key2[128];
- STATIC char key2Mac[128];
-
- if (strcmp(masterKey, client->deviceId) < 0) {
- snprintf(key1Id, 1024, "ed25519:%s", masterKey);
- strcpy(key1, masterKey);
- snprintf(key2Id, 1024, "ed25519:%s", client->deviceId);
- MatrixOlmAccountGetSigningKey(&client->olmAccount, key2, 1024);
- }
- else {
- snprintf(key1Id, 1024, "ed25519:%s", client->deviceId);
- MatrixOlmAccountGetSigningKey(&client->olmAccount, key1, 1024);
- snprintf(key2Id, 1024, "ed25519:%s", masterKey);
- strcpy(key2, masterKey);
- }
-
- snprintf(keyList, 1024,
- "%s,%s", key1Id, key2Id);
-
- STATIC char macInfo[1024];
- int macInfoLen;
- {
- macInfoLen =
- snprintf(macInfo, 1024,
- "MATRIX_KEY_VERIFICATION_MAC%s%s%s%s%s%s",
- USER_ID,
- client->deviceId,
- USER_ID,
- DEVICE_ID,
- transactionId,
- "KEY_IDS");
- olm_sas_calculate_mac_fixed_base64(olmSas, keyList, strlen(keyList), macInfo, macInfoLen, keyListMac, 1024);
- }
- {
- macInfoLen =
- snprintf(macInfo, 1024,
- "MATRIX_KEY_VERIFICATION_MAC%s%s%s%s%s%s",
- USER_ID,
- client->deviceId,
- USER_ID,
- DEVICE_ID,
- transactionId,
- key1Id);
- olm_sas_calculate_mac_fixed_base64(olmSas, key1, strlen(key1), macInfo, macInfoLen, key1Mac, 1024);
- }
- {
- macInfoLen =
- snprintf(macInfo, 1024,
- "MATRIX_KEY_VERIFICATION_MAC%s%s%s%s%s%s",
- USER_ID,
- client->deviceId,
- USER_ID,
- DEVICE_ID,
- transactionId,
- key2Id);
- olm_sas_calculate_mac_fixed_base64(olmSas, key2, strlen(key2), macInfo, macInfoLen, key2Mac, 1024);
- }
-
- STATIC char verificationMacBuffer[1024];
- snprintf(verificationMacBuffer, 1024,
- "{"
- "\"keys\":\"%s\","
- "\"mac\":{"
- "\"%s\":\"%s\","
- "\"%s\":\"%s\""
- "},"
- "\"transaction_id\":\"%s\""
- "}",
- keyListMac,
- key1Id,
- key1Mac,
- key2Id,
- key2Mac,
- transactionId);
-
- MatrixClientSendToDevice(client,
- USER_ID,
- DEVICE_ID,
- verificationMacBuffer,
- "m.key.verification.mac");
-
- STATIC char verificationDoneBuffer[128];
- snprintf(verificationDoneBuffer, 128,
- "{"
- "\"transaction_id\":\"%s\""
- "}",
- transactionId);
-
- MatrixClientSendToDevice(client,
- USER_ID,
- DEVICE_ID,
- verificationDoneBuffer,
- "m.key.verification.done");
-
- verified = true;
- }
- else if (strcmp(eventType, "m.room.encrypted") == 0) {
- STATIC char algorithm[128];
- mjson_get_string(event, eventLen, "$.content.algorithm", algorithm, 128);
-
- if (strcmp(algorithm, "m.olm.v1.curve25519-aes-sha2") == 0) {
- STATIC char thisDeviceKey[DEVICE_KEY_SIZE];
- MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE);
-
- STATIC char jp[128];
- snprintf(jp, 128, "$.content.ciphertext.%s.type", thisDeviceKey);
-
- double messageType;
- mjson_get_number(event, eventLen, jp, &messageType);
- int messageTypeInt = (int)messageType;
-
- snprintf(jp, 128, "$.content.ciphertext.%s.body", thisDeviceKey);
-
- mjson_get_string(event, eventLen, jp, encrypted, 2048);
-
- MatrixOlmSession * olmSession;
-
- if (! MatrixClientGetOlmSession(client, USER_ID, DEVICE_ID, &olmSession))
- {
- if (messageTypeInt == 0) {
- MatrixClientNewOlmSessionIn(client,
- USER_ID,
- DEVICE_ID,
- encrypted,
- &olmSession);
- }
- else {
- MatrixClientNewOlmSessionOut(client,
- USER_ID,
- DEVICE_ID,
- &olmSession);
- }
- }
-
- printf("event: %.*s\n", eventLen, event);
- printf("encrypted: %s\n", encrypted);
-
- MatrixOlmSessionDecrypt(olmSession,
- messageTypeInt, encrypted, decrypted, 2048);
-
- printf("decrypted: %s\n", decrypted);
-
- HandleEvent(client, decrypted, strlen(decrypted));
- }
- }
- else if (strcmp(eventType, "m.room_key") == 0 ||
- strcmp(eventType, "m.forwarded_room_key") == 0) {
- STATIC char roomId[128];
- STATIC char sessionId[128];
- STATIC char sessionKey[1024];
- mjson_get_string(event, eventLen, "$.content.room_id", roomId, 128);
- mjson_get_string(event, eventLen, "$.content.session_id", sessionId, 128);
- mjson_get_string(event, eventLen, "$.content.session_key", sessionKey, 1024);
-
- printf("sessionId: %s\n", sessionId);
- printf("sessionKey: %s\n", sessionKey);
-
- MatrixMegolmInSession * megolmInSession;
- MatrixClientNewMegolmInSession(client, roomId, sessionId, sessionKey, &megolmInSession);
- }
-}
-
-void
-HandleRoomEvent(
- MatrixClient * client,
- const char * room, int roomLen,
- const char * event, int eventLen)
-{
- STATIC char eventType[128];
- memset(eventType, 0, sizeof(eventType));
- mjson_get_string(event, eventLen, "$.type", eventType, 128);
-
- if (strcmp(eventType, "m.room.encrypted") == 0) {
- STATIC char algorithm[128];
- mjson_get_string(event, eventLen, "$.content.algorithm", algorithm, 128);
-
- if (strcmp(algorithm, "m.megolm.v1.aes-sha2") == 0) {
- STATIC char sessionId[128];
- int sessionIdLen =
- mjson_get_string(event, eventLen, "$.content.session_id", sessionId, 128);
-
- bool res;
-
- MatrixMegolmInSession * megolmInSession;
- res = MatrixClientGetMegolmInSession(client,
- room, roomLen,
- sessionId, sessionIdLen,
- &megolmInSession);
-
- if (res) {
- mjson_get_string(event, eventLen, "$.content.ciphertext", encrypted, 2048);
-
- MatrixMegolmInSessionDecrypt(megolmInSession, encrypted, strlen(encrypted), decrypted, 2048);
-
- printf("decrypted: %s\n", decrypted);
-
- HandleEvent(client, decrypted, strlen(decrypted));
- }
- else {
- printf("megolm session not known\n");
- }
- }
- }
- HandleEvent(client, event, eventLen);
-}
-
-void
-Sync(
- MatrixClient * client,
- char * syncBuffer, int syncBufferLen)
-{
- STATIC char nextBatch[1024] = {0};
-
- MatrixClientSync(client, syncBuffer, syncBufferLen, nextBatch);
-
- int res;
-
- const char * s = syncBuffer;
- int slen = strlen(syncBuffer);
-
- printf("sync:\n\n%s\n\n", syncBuffer);
-
- // {
- // int koff, klen, voff, vlen, vtype, off = 0;
- // for (off = 0; (off = mjson_next(s, slen, off, &koff, &klen,
- // &voff, &vlen, &vtype)) != 0; ) {
- // const char * k = s + koff;
- // const char * v = s + voff;
-
- // printf("%.*s: %.100s\n", klen, k, v);
- // }
- // }
-
- mjson_get_string(s, slen, "$.next_batch", nextBatch, 1024);
-
- // to_device
-
- const char * events;
- int eventsLen;
- res =
- mjson_find(s, slen, "$.to_device.events", &events, &eventsLen);
-
- if (res != MJSON_TOK_INVALID) {
- {
- int koff, klen, voff, vlen, vtype, off = 0;
- for (off = 0; (off = mjson_next(events, eventsLen, off, &koff, &klen,
- &voff, &vlen, &vtype)) != 0; ) {
- const char * v = events + voff;
-
- HandleEvent(client, v, vlen);
- }
- }
- }
-
- // rooms
-
- const char * rooms;
- int roomsLen;
- res =
- mjson_find(s, slen, "$.rooms.join", &rooms, &roomsLen);
-
- if (res != MJSON_TOK_INVALID) {
- {
- int koff, klen, voff, vlen, vtype, off = 0;
- for (off = 0; (off = mjson_next(rooms, roomsLen, off, &koff, &klen,
- &voff, &vlen, &vtype)) != 0; ) {
- const char * k = rooms + koff;
- const char * v = rooms + voff;
-
- const char * events;
- int eventsLen;
- res =
- mjson_find(v, vlen, "$.timeline.events", &events, &eventsLen);
-
- if (res != MJSON_TOK_INVALID) {
- {
- int koff2, klen2, voff2, vlen2, vtype2, off2 = 0;
- for (off2 = 0; (off2 = mjson_next(events, eventsLen, off2, &koff2, &klen2,
- &voff2, &vlen2, &vtype2)) != 0; ) {
- const char * v2 = events + voff2;
-
- HandleRoomEvent(client,
- k+1, klen-2,
- v2, vlen2);
- }
- }
- }
- }
- }
- }
-}
int
main(void)
{
- // sizeof(MatrixOlmAccount);
- // sizeof(MatrixMegolmInSession);
- // sizeof(MatrixMegolmOutSession);
- // sizeof(MatrixOlmSession);
- // sizeof(MatrixDevice);
-
- // STATIC MatrixClient _client;
- // MatrixClient * client = &_client;
MatrixClient * client = (MatrixClient*)malloc(sizeof(MatrixClient));
MatrixClientInit(client);
printf("deviceId: %s\n", client->deviceId);
MatrixClientGenerateOnetimeKeys(client, 10);
MatrixClientUploadOnetimeKeys(client);
- MatrixClientUploadDeviceKey(client);
+ MatrixClientUploadDeviceKeys(client);
STATIC char eventBuffer[1024];
MatrixClientGetRoomEvent(client,
// char * syncBuffer = (char*)malloc(SYNC_BUFFER_SIZE);
STATIC char syncBuffer[SYNC_BUFFER_SIZE];
+ STATIC char nextBatch[1024];
- while (! verified) {
- Sync(client, syncBuffer, SYNC_BUFFER_SIZE);
+ while (! client->verified) {
+ MatrixClientSync(client, syncBuffer, SYNC_BUFFER_SIZE, nextBatch, 1024);
}
printf("verified!\n");
"ULZZOKJBYN",
megolmOutSession);
-
- // int c;
- // while ((c=getchar()) != 'q') {
- // vTaskDelay(1000/portTICK_PERIOD_MS);
-
- // if (c == 's') {
- // Sync(client, syncBuffer, SYNC_BUFFER_SIZE);
- // }
- // else if (c == 'm') {
- // static const char * msgs[] = { "A", "B", "C" };
- // static char msg[128];
- // snprintf(msg, 128, "{\"body\":\"%s\",\"msgtype\":\"m.text\"}", msgs[rand()%(sizeof(msgs)/sizeof(msgs[0]))]);
-
- // MatrixClientSendEventEncrypted(client,
- // ROOM_ID,
- // "m.room.message",
- // msg);
- // printf("Message sent. Message index: %d\n", (int)olm_outbound_group_session_message_index(megolmOutSession->session));
- // }
- // }
-
+ // send 10 random messages
for (int i = 0; i < 10; i++) {
-
static const char * msgs[] = { "A", "B", "C" };
static char msg[128];
snprintf(msg, 128, "{\"body\":\"%s\",\"msgtype\":\"m.text\"}", msgs[rand()%(sizeof(msgs)/sizeof(msgs[0]))]);
ROOM_ID,
"m.room.message",
msg);
-
- vTaskDelay(5000/portTICK_PERIOD_MS);
}
-
- // MatrixClientRequestMegolmInSession(client,
- // ROOM_ID,
- // SESSION_ID,
- // SENDER_KEY,
- // USER_ID,
- // DEVICE_ID);
-
- // MatrixMegolmInSession * megolmInSession;
- // while (! MatrixClientGetMegolmInSession(client,
- // ROOM_ID, strlen(ROOM_ID),
- // SESSION_ID, strlen(SESSION_ID),
- // &megolmInSession))
- // Sync(client, syncBuffer, SYNC_BUFFER_SIZE);
-
- // int encryptedLen =
- // mjson_get_string(eventBuffer, strlen(eventBuffer), "$.content.ciphertext", encrypted, 1024);
-
- // printf("encrypted: [%.*s]\n", encryptedLen, encrypted);
-
- // MatrixMegolmInSessionDecrypt(megolmInSession,
- // encrypted, encryptedLen,
- // decrypted, 1024);
-
- // printf("decrypted: %s\n", decrypted);
MatrixClientDeleteDevice(client);
MatrixClientGenerateOnetimeKeys(&client, 10);\r
MatrixClientUploadOnetimeKeys(&client);\r
\r
- // // get device key\r
- // static char deviceKey[128];\r
- // MatrixClientGetDeviceKey(&client,\r
- // "ULZZOKJBYN",\r
- // deviceKey, 128);\r
- // printf("device key for %s: %s\n", "ULZZOKJBYN", deviceKey);\r
-\r
// create megolmsession\r
MatrixMegolmOutSession * megolmOutSession;\r
MatrixClientNewMegolmOutSession(&client,\r
&megolmOutSession);\r
printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);\r
\r
- // // create olmsession\r
- // MatrixOlmSession * olmSession;\r
- // MatrixClientGetOlmSession(&client,\r
- // USER_ID,\r
- // "ULZZOKJBYN",\r
- // &olmSession);\r
- // printf("olm session created\n");\r
-\r
MatrixClientShareMegolmOutSession(&client,\r
USER_ID,\r
"ULZZOKJBYN",\r
megolmOutSession);\r
- // MatrixClientShareMegolmOutSessionTest(&client,\r
- // USER_ID,\r
- // "ULZZOKJBYN",\r
- // megolmOutSession);\r
\r
MatrixClientSendEventEncrypted(&client,\r
ROOM_ID,\r
#define EVENT_ID "$vOS09eUaI0CduqAcaIU5ZVk6ljLQfLspz7UThP8vaUM"\r
#define SESSION_ID "90UbGLue3ADVhvW7hFjoA2c6yg0JJKs/lPdMDZXnZAk"\r
\r
-\r
-bool verified = false;\r
-char transactionId[256];\r
-OlmSAS * olmSas = NULL;\r
-\r
-void\r
-HandleEvent(\r
- MatrixClient * client,\r
- const char * event, int eventLen\r
-) {\r
- static char eventType[128];\r
- memset(eventType, 0, sizeof(eventType));\r
- mjson_get_string(event, eventLen, "$.type", eventType, 128);\r
-\r
- if (strcmp(eventType, "m.key.verification.request") == 0) {\r
- mjson_get_string(event, eventLen, "$.content.transaction_id", transactionId, 256);\r
- \r
- char verificationReadyBuffer[2048];\r
- snprintf(verificationReadyBuffer, 2048,\r
- "{"\r
- "\"from_device\":\"%s\","\r
- "\"methods\":[\"m.sas.v1\"],"\r
- "\"transaction_id\":\"%s\""\r
- "}",\r
- client->deviceId,\r
- transactionId);\r
- \r
- MatrixClientSendToDevice(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- verificationReadyBuffer,\r
- "m.key.verification.ready");\r
- }\r
- else if (strcmp(eventType, "m.key.verification.start") == 0) {\r
- olmSas = olm_sas(malloc(olm_sas_size()));\r
- void * sasRandomBytes = malloc(olm_create_sas_random_length(olmSas));\r
- olm_create_sas(olmSas,\r
- sasRandomBytes,\r
- olm_create_sas_random_length(olmSas));\r
- \r
- OlmUtility * olmUtil = olm_utility(malloc(olm_utility_size()));\r
- \r
- char publicKey[128];\r
- char keyStartJsonCanonical[1024];\r
- char concat[1024];\r
- char commitment[256];\r
- olm_sas_get_pubkey(olmSas,\r
- publicKey,\r
- 128);\r
- printf("public key: %.*s\n", olm_sas_pubkey_length(olmSas), publicKey);\r
-\r
- const char * keyStartJson;\r
- int keyStartJsonLen;\r
- mjson_find(event, eventLen, "$.content", &keyStartJson, &keyStartJsonLen);\r
- JsonCanonicalize(keyStartJson, keyStartJsonLen, keyStartJsonCanonical, 1024);\r
-\r
- printf("json:\n%.*s\ncanonical json:\n%s\n", keyStartJsonLen, keyStartJson, keyStartJsonCanonical);\r
-\r
- int concatLen =\r
- snprintf(concat, 1024, "%.*s%s", olm_sas_pubkey_length(olmSas), publicKey, keyStartJsonCanonical);\r
-\r
- int commitmentLen =\r
- olm_sha256(olmUtil, concat, concatLen, commitment, 256);\r
- \r
- char verificationAcceptBuffer[2048];\r
- snprintf(verificationAcceptBuffer, 2048,\r
- "{"\r
- "\"commitment\":\"%.*s\","\r
- "\"hash\":\"sha256\","\r
- "\"key_agreement_protocol\":\"curve25519\","\r
- "\"message_authentication_code\":\"hkdf-hmac-sha256.v2\","\r
- "\"method\":\"m.sas.v1\","\r
- "\"short_authentication_string\":[\"decimal\"],"\r
- "\"transaction_id\":\"%s\""\r
- "}",\r
- commitmentLen, commitment,\r
- transactionId);\r
- \r
- MatrixClientSendToDevice(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- verificationAcceptBuffer,\r
- "m.key.verification.accept");\r
- }\r
- else if (strcmp(eventType, "m.key.verification.key") == 0) {\r
- char publicKey[128];\r
- olm_sas_get_pubkey(olmSas,\r
- publicKey,\r
- 128);\r
-\r
- char theirPublicKey[128];\r
- int theirPublicKeyLen =\r
- mjson_get_string(event, eventLen, "$.content.key", theirPublicKey, 128);\r
- \r
- printf("event: %.*s\n", eventLen, event);\r
- printf("theirPublicKey: %.*s\n", theirPublicKeyLen, theirPublicKey);\r
- printf("publicKey: %.*s\n", olm_sas_pubkey_length(olmSas), publicKey);\r
-\r
- olm_sas_set_their_key(olmSas, theirPublicKey, theirPublicKeyLen);\r
- \r
- char verificationKeyBuffer[2048];\r
- snprintf(verificationKeyBuffer, 2048,\r
- "{"\r
- "\"key\":\"%.*s\","\r
- "\"transaction_id\":\"%s\""\r
- "}",\r
- olm_sas_pubkey_length(olmSas), publicKey,\r
- transactionId);\r
- \r
- MatrixClientSendToDevice(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- verificationKeyBuffer,\r
- "m.key.verification.key");\r
- \r
- // sas\r
- char hkdfInfo[1024];\r
- int hkdfInfoLen =\r
- snprintf(hkdfInfo, 1024,\r
- "MATRIX_KEY_VERIFICATION_SAS%s%s%s%s%s",\r
- USER_ID,\r
- DEVICE_ID,\r
- USER_ID,\r
- client->deviceId,\r
- transactionId);\r
-\r
- unsigned char sasBytes[5];\r
- olm_sas_generate_bytes(olmSas,\r
- hkdfInfo, hkdfInfoLen,\r
- sasBytes, 5);\r
- int b0 = sasBytes[0];\r
- int b1 = sasBytes[1];\r
- int b2 = sasBytes[2];\r
- int b3 = sasBytes[3];\r
- int b4 = sasBytes[4];\r
- \r
- printf("%d %d %d %d %d\n", b0, b1, b2, b3, b4);\r
-\r
- // https://spec.matrix.org/v1.7/client-server-api/#sas-method-decimal\r
- printf("%d | %d | %d\n",\r
- (b0 << 5 | b1 >> 3) + 1000,\r
- ((b1 & 0x7) << 10 | b2 << 2 | b3 >> 6) + 1000,\r
- ((b3 & 0x3F) << 7 | b4 >> 1) + 1000);\r
- printf("%d | %d | %d\n",\r
- ((b0 << 5) | (b1 >> 3)) + 1000,\r
- (((b1 & 0x7) << 10) | (b2 << 2) | (b3 >> 6)) + 1000,\r
- (((b3 & 0x3F) << 7) | (b4 >> 1)) + 1000);\r
- }\r
- else if (strcmp(eventType, "m.key.verification.mac") == 0) { \r
- // mac\r
- const char * masterKey = "vt8tJ5/SxqkvXS+XoGxr+4rJNe8fJfZT3/e/FTwlFsI";\r
-\r
- char keyList[1024];\r
- char keyListMac[1024];\r
- char key1Id[1024];\r
- char key1[1024];\r
- char key1Mac[1024];\r
- char key2Id[1024];\r
- char key2[1024];\r
- char key2Mac[1024];\r
-\r
- if (strcmp(masterKey, client->deviceId) < 0) {\r
- snprintf(key1Id, 1024, "ed25519:%s", masterKey);\r
- strcpy(key1, masterKey);\r
- snprintf(key2Id, 1024, "ed25519:%s", client->deviceId);\r
- MatrixOlmAccountGetSigningKey(&client->olmAccount, key2, 1024);\r
- }\r
- else {\r
- snprintf(key1Id, 1024, "ed25519:%s", client->deviceId);\r
- MatrixOlmAccountGetSigningKey(&client->olmAccount, key1, 1024);\r
- snprintf(key2Id, 1024, "ed25519:%s", masterKey);\r
- strcpy(key2, masterKey);\r
- }\r
-\r
- snprintf(keyList, 1024,\r
- "%s,%s", key1Id, key2Id);\r
- \r
- char macInfo[1024];\r
- int macInfoLen;\r
- {\r
- macInfoLen =\r
- snprintf(macInfo, 1024,\r
- "MATRIX_KEY_VERIFICATION_MAC%s%s%s%s%s%s",\r
- USER_ID,\r
- client->deviceId,\r
- USER_ID,\r
- DEVICE_ID,\r
- transactionId,\r
- "KEY_IDS");\r
- olm_sas_calculate_mac_fixed_base64(olmSas, keyList, strlen(keyList), macInfo, macInfoLen, keyListMac, 1024);\r
- }\r
- {\r
- macInfoLen =\r
- snprintf(macInfo, 1024,\r
- "MATRIX_KEY_VERIFICATION_MAC%s%s%s%s%s%s",\r
- USER_ID,\r
- client->deviceId,\r
- USER_ID,\r
- DEVICE_ID,\r
- transactionId,\r
- key1Id);\r
- olm_sas_calculate_mac_fixed_base64(olmSas, key1, strlen(key1), macInfo, macInfoLen, key1Mac, 1024);\r
- }\r
- {\r
- macInfoLen =\r
- snprintf(macInfo, 1024,\r
- "MATRIX_KEY_VERIFICATION_MAC%s%s%s%s%s%s",\r
- USER_ID,\r
- client->deviceId,\r
- USER_ID,\r
- DEVICE_ID,\r
- transactionId,\r
- key2Id);\r
- olm_sas_calculate_mac_fixed_base64(olmSas, key2, strlen(key2), macInfo, macInfoLen, key2Mac, 1024);\r
- }\r
-\r
- char verificationMacBuffer[2048];\r
- snprintf(verificationMacBuffer, 2048,\r
- "{"\r
- "\"keys\":\"%s\","\r
- "\"mac\":{"\r
- "\"%s\":\"%s\","\r
- "\"%s\":\"%s\""\r
- "},"\r
- "\"transaction_id\":\"%s\""\r
- "}",\r
- keyListMac,\r
- key1Id,\r
- key1Mac,\r
- key2Id,\r
- key2Mac,\r
- transactionId);\r
- \r
- MatrixClientSendToDevice(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- verificationMacBuffer,\r
- "m.key.verification.mac");\r
-\r
- char verificationDoneBuffer[2048];\r
- snprintf(verificationDoneBuffer, 2048,\r
- "{"\r
- "\"transaction_id\":\"%s\""\r
- "}",\r
- transactionId);\r
- \r
- MatrixClientSendToDevice(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- verificationDoneBuffer,\r
- "m.key.verification.done");\r
- \r
- verified = true;\r
- }\r
- else if (strcmp(eventType, "m.room.encrypted") == 0) {\r
- static char algorithm[128];\r
- mjson_get_string(event, eventLen, "$.content.algorithm", algorithm, 128);\r
-\r
- if (strcmp(algorithm, "m.olm.v1.curve25519-aes-sha2") == 0) {\r
- static char thisDeviceKey[DEVICE_KEY_SIZE];\r
- MatrixOlmAccountGetDeviceKey(&client->olmAccount, thisDeviceKey, DEVICE_KEY_SIZE);\r
-\r
- static char jp[128];\r
- snprintf(jp, 128, "$.content.ciphertext.%s.type", thisDeviceKey);\r
-\r
- double messageType;\r
- mjson_get_number(event, eventLen, jp, &messageType);\r
- int messageTypeInt = (int)messageType;\r
- \r
- static char encrypted[2048];\r
- static char decrypted[2048];\r
-\r
- snprintf(jp, 128, "$.content.ciphertext.%s.body", thisDeviceKey);\r
-\r
- mjson_get_string(event, eventLen, jp, encrypted, 2048);\r
-\r
- MatrixOlmSession * olmSession;\r
- if (messageTypeInt == 0) {\r
- MatrixClientNewOlmSessionIn(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- encrypted,\r
- &olmSession);\r
- } else {\r
- MatrixClientNewOlmSessionOut(client,\r
- USER_ID,\r
- DEVICE_ID,\r
- &olmSession);\r
- }\r
-\r
- printf("event: %.*s\n", eventLen, event);\r
- printf("encrypted: %s\n", encrypted);\r
- \r
- MatrixOlmSessionDecrypt(olmSession,\r
- messageTypeInt, encrypted, decrypted, 2048);\r
- \r
- printf("decrypted: %s\n", decrypted);\r
- \r
- HandleEvent(client, decrypted, strlen(decrypted));\r
- }\r
- }\r
- else if (strcmp(eventType, "m.room_key") == 0) {\r
- static char roomId[128];\r
- static char sessionId[128];\r
- static char sessionKey[1024];\r
- mjson_get_string(event, eventLen, "$.content.room_id", roomId, 128);\r
- mjson_get_string(event, eventLen, "$.content.session_id", sessionId, 128);\r
- mjson_get_string(event, eventLen, "$.content.session_key", sessionKey, 1024);\r
- \r
- printf("sessionId: %s\n", sessionId);\r
- printf("sessionKey: %s\n", sessionKey);\r
-\r
- MatrixMegolmInSession * megolmInSession;\r
- MatrixClientNewMegolmInSession(client, roomId, sessionId, sessionKey, &megolmInSession);\r
- }\r
- else if (strcmp(eventType, "m.forwarded_room_key") == 0) {\r
- static char roomId[128];\r
- static char sessionId[128];\r
- static char sessionKey[1024];\r
- mjson_get_string(event, eventLen, "$.content.room_id", roomId, 128);\r
- mjson_get_string(event, eventLen, "$.content.session_id", sessionId, 128);\r
- mjson_get_string(event, eventLen, "$.content.session_key", sessionKey, 1024);\r
- \r
- printf("sessionId: %s\n", sessionId);\r
- printf("sessionKey: %s\n", sessionKey);\r
-\r
- MatrixMegolmInSession * megolmInSession;\r
- MatrixClientNewMegolmInSession(client, roomId, sessionId, sessionKey, &megolmInSession);\r
- }\r
-}\r
-\r
-void\r
-HandleRoomEvent(\r
- MatrixClient * client,\r
- const char * room, int roomLen,\r
- const char * event, int eventLen)\r
-{\r
- static char eventType[128];\r
- memset(eventType, 0, sizeof(eventType));\r
- mjson_get_string(event, eventLen, "$.type", eventType, 128);\r
-\r
- if (strcmp(eventType, "m.room.encrypted") == 0) {\r
- static char algorithm[128];\r
- mjson_get_string(event, eventLen, "$.content.algorithm", algorithm, 128);\r
-\r
- if (strcmp(algorithm, "m.megolm.v1.aes-sha2") == 0) {\r
- static char sessionId[128];\r
- int sessionIdLen =\r
- mjson_get_string(event, eventLen, "$.content.session_id", sessionId, 128);\r
-\r
- bool res;\r
-\r
- MatrixMegolmInSession * megolmInSession;\r
- res = MatrixClientGetMegolmInSession(client,\r
- room, roomLen,\r
- sessionId, sessionIdLen,\r
- &megolmInSession);\r
-\r
- if (res) {\r
- static char encrypted[2048];\r
- static char decrypted[2048];\r
- mjson_get_string(event, eventLen, "$.content.ciphertext", encrypted, 2048);\r
-\r
- MatrixMegolmInSessionDecrypt(megolmInSession, encrypted, strlen(encrypted), decrypted, 2048);\r
-\r
- printf("decrypted: %s\n", decrypted);\r
-\r
- HandleEvent(client, decrypted, strlen(decrypted));\r
- }\r
- else {\r
- printf("megolm session not known\n");\r
- }\r
- }\r
- }\r
- HandleEvent(client, event, eventLen);\r
-}\r
-\r
-void\r
-Sync(\r
- MatrixClient * client\r
-) {\r
- static char nextBatch[1024];\r
-\r
- static char syncBuffer[1024*50];\r
- MatrixClientSync(client, syncBuffer, 1024*50, nextBatch);\r
- \r
- int res;\r
-\r
- const char * s = syncBuffer;\r
- int slen = strlen(syncBuffer);\r
- \r
- // {\r
- // int koff, klen, voff, vlen, vtype, off = 0;\r
- // for (off = 0; (off = mjson_next(s, slen, off, &koff, &klen,\r
- // &voff, &vlen, &vtype)) != 0; ) {\r
- // const char * k = s + koff;\r
- // const char * v = s + voff;\r
-\r
- // printf("%.*s: %.100s\n", klen, k, v);\r
- // }\r
- // }\r
-\r
- mjson_get_string(s, slen, "$.next_batch", nextBatch, 1024);\r
-\r
- // to_device\r
-\r
- const char * events;\r
- int eventsLen;\r
- res =\r
- mjson_find(s, slen, "$.to_device.events", &events, &eventsLen);\r
- \r
- if (res != MJSON_TOK_INVALID) {\r
- {\r
- int koff, klen, voff, vlen, vtype, off = 0;\r
- for (off = 0; (off = mjson_next(events, eventsLen, off, &koff, &klen,\r
- &voff, &vlen, &vtype)) != 0; ) {\r
- const char * v = events + voff;\r
-\r
- HandleEvent(client, v, vlen);\r
- }\r
- }\r
- }\r
-\r
- // rooms\r
- \r
- const char * rooms;\r
- int roomsLen;\r
- res =\r
- mjson_find(s, slen, "$.rooms.join", &rooms, &roomsLen);\r
- \r
- if (res != MJSON_TOK_INVALID) {\r
- {\r
- int koff, klen, voff, vlen, vtype, off = 0;\r
- for (off = 0; (off = mjson_next(rooms, roomsLen, off, &koff, &klen,\r
- &voff, &vlen, &vtype)) != 0; ) {\r
- const char * k = rooms + koff;\r
- const char * v = rooms + voff;\r
-\r
- const char * events;\r
- int eventsLen;\r
- res =\r
- mjson_find(v, vlen, "$.timeline.events", &events, &eventsLen);\r
- \r
- if (res != MJSON_TOK_INVALID) {\r
- {\r
- int koff2, klen2, voff2, vlen2, vtype2, off2 = 0;\r
- for (off2 = 0; (off2 = mjson_next(events, eventsLen, off2, &koff2, &klen2,\r
- &voff2, &vlen2, &vtype2)) != 0; ) {\r
- const char * v2 = events + voff2;\r
-\r
- HandleRoomEvent(client,\r
- k+1, klen-2,\r
- v2, vlen2);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-}\r
-\r
+#define STATIC static\r
\r
int\r
main(void)\r
{\r
- MatrixClient client;\r
- MatrixClientInit(&client);\r
- MatrixHttpInit(&client.hc, SERVER);\r
- MatrixClientSetUserId(&client, USER_ID);\r
+ MatrixClient * client = (MatrixClient*)malloc(sizeof(MatrixClient));\r
+ MatrixClientInit(client);\r
+\r
+ MatrixHttpInit(&client->hc, SERVER);\r
+ MatrixClientSetUserId(client, USER_ID);\r
\r
- MatrixClientLoginPassword(&client,\r
+ MatrixClientLoginPassword(client,\r
"pscho",\r
"Wc23EbmB9G3faMq",\r
"Test1");\r
- printf("deviceId: %s\n", client.deviceId);\r
- MatrixClientGenerateOnetimeKeys(&client, 10);\r
- MatrixClientUploadOnetimeKeys(&client);\r
- MatrixClientUploadDeviceKeys(&client);\r
+ printf("deviceId: %s\n", client->deviceId);\r
+ MatrixClientGenerateOnetimeKeys(client, 10);\r
+ MatrixClientUploadOnetimeKeys(client);\r
+ MatrixClientUploadDeviceKeys(client);\r
\r
- static char eventBuffer[1024];\r
- MatrixClientGetRoomEvent(&client,\r
+ STATIC char eventBuffer[1024];\r
+ MatrixClientGetRoomEvent(client,\r
ROOM_ID,\r
EVENT_ID,\r
eventBuffer, 1024);\r
printf("event: %s\n", eventBuffer);\r
- \r
- while (! verified)\r
- Sync(&client);\r
- \r
- // while (getchar() != 'q')\r
- // Sync(&client);\r
- \r
- MatrixClientRequestMegolmInSession(&client,\r
- ROOM_ID,\r
- SESSION_ID,\r
- SENDER_KEY,\r
- USER_ID,\r
- DEVICE_ID);\r
\r
- MatrixMegolmInSession * megolmInSession;\r
- while (! MatrixClientGetMegolmInSession(&client,\r
- ROOM_ID, strlen(ROOM_ID),\r
- SESSION_ID, strlen(SESSION_ID),\r
- &megolmInSession))\r
- Sync(&client);\r
+ #define SYNC_BUFFER_SIZE 1024*10\r
\r
- static char encryptedBuffer[1024];\r
- int encryptedBufferLen =\r
- mjson_get_string(eventBuffer, strlen(eventBuffer), "$.content.ciphertext", encryptedBuffer, 1024);\r
- \r
- printf("encryptedBuffer: [%.*s]\n", encryptedBufferLen, encryptedBuffer);\r
+ // char * syncBuffer = (char*)malloc(SYNC_BUFFER_SIZE);\r
+ STATIC char syncBuffer[SYNC_BUFFER_SIZE];\r
+ STATIC char nextBatch[1024];\r
\r
- static char decryptedBuffer[1024];\r
- MatrixMegolmInSessionDecrypt(megolmInSession,\r
- encryptedBuffer, encryptedBufferLen,\r
- decryptedBuffer, 1024);\r
+ while (! client->verified) {\r
+ MatrixClientSync(client, syncBuffer, SYNC_BUFFER_SIZE, nextBatch, 1024);\r
+ }\r
+\r
+ printf("verified!\n");\r
\r
- printf("decrypted: %s\n", decryptedBuffer);\r
+ // create and share megolm out session\r
+ MatrixMegolmOutSession * megolmOutSession;\r
+ MatrixClientNewMegolmOutSession(client,\r
+ ROOM_ID,\r
+ &megolmOutSession);\r
+ printf("megolm session id: %.10s... key: %.10s...\n", megolmOutSession->id, megolmOutSession->key);\r
+ MatrixClientShareMegolmOutSession(client,\r
+ USER_ID,\r
+ "ULZZOKJBYN",\r
+ megolmOutSession);\r
+\r
+ // send 10 random messages\r
+ for (int i = 0; i < 10; i++) {\r
+ static const char * msgs[] = { "A", "B", "C" };\r
+ static char msg[128];\r
+ snprintf(msg, 128, "{\"body\":\"%s\",\"msgtype\":\"m.text\"}", msgs[rand()%(sizeof(msgs)/sizeof(msgs[0]))]);\r
+\r
+ MatrixClientSendEventEncrypted(client,\r
+ ROOM_ID,\r
+ "m.room.message",\r
+ msg);\r
+ }\r
\r
- MatrixClientDeleteDevice(&client);\r
+ MatrixClientDeleteDevice(client);\r
\r
- MatrixHttpDeinit(&client.hc);\r
+ MatrixHttpDeinit(&client->hc);\r
\r
return 0;\r
}\r