]> gitweb.ps.run Git - matrix_esp_thesis/commitdiff
fix examples
authorPatrick <patrick.schoenberger@posteo.de>
Mon, 13 Nov 2023 21:26:34 +0000 (22:26 +0100)
committerPatrick <patrick.schoenberger@posteo.de>
Mon, 13 Nov 2023 21:26:34 +0000 (22:26 +0100)
esp32/esp_project/main/SendEncrypted.c
esp32/esp_project/main/Verify.c
examples/SendEncrypted.c
examples/Verify.c

index 900856d1b06e4a7cda951285235a924490da2501..8d813adff96e134109516efe1cf11ca6013de3b2 100644 (file)
 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;
 }
index 989b151a0ac2d2cfaa1fbab782e51d8362662ff1..91f9be85845e2c928cb450cd61eef6c01ff748d0 100644 (file)
 
 // 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);
 
@@ -501,7 +42,7 @@ main(void)
     printf("deviceId: %s\n", client->deviceId);
     MatrixClientGenerateOnetimeKeys(client, 10);
     MatrixClientUploadOnetimeKeys(client);
-    MatrixClientUploadDeviceKey(client);
+    MatrixClientUploadDeviceKeys(client);
 
     STATIC char eventBuffer[1024];
     MatrixClientGetRoomEvent(client,
@@ -514,9 +55,10 @@ main(void)
 
     // 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");
@@ -532,29 +74,8 @@ main(void)
         "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]))]);
@@ -563,34 +84,7 @@ main(void)
             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);
         
index a6cedb5924c26ac18cacce10c560c7115a395dff..3debeabb2005cafe21a545d0814290a0d2b44b36 100644 (file)
@@ -24,13 +24,6 @@ main(void)
     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
@@ -38,22 +31,10 @@ main(void)
         &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
index 2544f16dfbe643b0ba104b9d1489db4e79fddcc8..c9680e07fd56d89b555d8e83d9ef00f32c7357a7 100644 (file)
 #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