abouttreesummaryrefslogcommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/matrix.c214
-rw-r--r--src/matrix.h61
2 files changed, 259 insertions, 16 deletions
diff --git a/src/matrix.c b/src/matrix.c
index 33988b4..d1878c5 100644
--- a/src/matrix.c
+++ b/src/matrix.c
@@ -22,12 +22,17 @@
#define KEYS_QUERY_REQUEST_SIZE 256
#define KEYS_QUERY_RESPONSE_SIZE 1024
+#define UPLOAD_KEYS_REQUEST_SIZE 512
+#define UPLOAD_KEYS_REQUEST_SIGNED_SIZE 1024
+
#define JSON_QUERY_SIZE 128
void
-Randomize(uint8_t * random, int randomLen)
+Randomize(
+ uint8_t * random,
+ int randomLen)
{
static bool first = false;
if (first) { srand(time(0)); first = false; }
@@ -65,6 +70,61 @@ JsonEscape(
return true;
}
+bool JsonSign(
+ MatrixClient * client,
+ char * sIn, int sInLen,
+ char * sOut, int sOutCap)
+{
+ static char signature[OLM_SIGNATURE_SIZE];
+ size_t res =
+ olm_account_sign(client->olmAccount.account,
+ sIn, sInLen,
+ signature, OLM_SIGNATURE_SIZE);
+
+ int signatureLen = res;
+
+ static char signatureJson[JSON_SIGNATURE_SIZE];
+ int signatureJsonLen =
+ mjson_snprintf(signatureJson, JSON_SIGNATURE_SIZE,
+ "{"
+ "\"signatures\":{"
+ "\"%s\":{"
+ "\"ed25519:%s\":\"%.*s\""
+ "}"
+ "}"
+ "}",
+ client->userId,
+ client->deviceId,
+ signatureLen, signature);
+
+ struct mjson_fixedbuf result = { sOut, sOutCap, 0 };
+ mjson_merge(
+ sIn, sInLen,
+ signatureJson, signatureJsonLen,
+ mjson_print_fixed_buf,
+ &result);
+
+ return true;
+}
+
+
+bool
+MatrixOlmAccountInit(
+ MatrixOlmAccount * account)
+{
+ account->account = olm_account(account->memory);
+
+ static uint8_t random[OLM_ACCOUNT_RANDOM_SIZE];
+ Randomize(random, OLM_ACCOUNT_RANDOM_SIZE);
+
+ size_t res = olm_create_account(
+ account->account,
+ random,
+ OLM_ACCOUNT_RANDOM_SIZE);
+
+ return res != olm_error();
+}
+
// TODO: in/outbound sessions
bool
MatrixOlmSessionInit(
@@ -158,22 +218,13 @@ MatrixClientInit(
strcpy(client->server, server);
// init olm account
- client->olmAccount = olm_account(client->olmAccountMemory);
-
- static uint8_t random[OLM_ACCOUNT_RANDOM_SIZE];
- Randomize(random, OLM_ACCOUNT_RANDOM_SIZE);
-
- size_t res;
- res = olm_create_account(
- client->olmAccount,
- random,
- OLM_ACCOUNT_RANDOM_SIZE);
+ MatrixOlmAccountInit(&client->olmAccount);
// set device key
static char deviceKeysJson[OLM_IDENTITY_KEYS_JSON_SIZE];
- res =
+ size_t res =
olm_account_identity_keys(
- client->olmAccount,
+ client->olmAccount.account,
deviceKeysJson,
OLM_IDENTITY_KEYS_JSON_SIZE);
@@ -219,6 +270,113 @@ MatrixClientSetDeviceId(
return true;
}
+bool
+MatrixClientSetUserId(
+ MatrixClient * client,
+ const char * userId)
+{
+ int userIdLen = strlen(userId);
+
+ if (userIdLen > USER_ID_SIZE - 1)
+ return false;
+
+ for (int i = 0; i < userIdLen; i++)
+ client->userId[i] = userId[i];
+
+ return true;
+}
+
+bool
+MatrixClientGenerateOnetimeKeys(
+ MatrixClient * client,
+ int numberOfKeys)
+{
+ static uint8_t random[OLM_ONETIME_KEYS_RANDOM_SIZE];
+ Randomize(random, OLM_ONETIME_KEYS_RANDOM_SIZE);
+
+ size_t res =
+ olm_account_generate_one_time_keys(client->olmAccount.account,
+ numberOfKeys, random, OLM_ONETIME_KEYS_RANDOM_SIZE);
+
+ return res != olm_error();
+}
+
+bool
+MatrixClientUploadOnetimeKeys(
+ MatrixClient * client)
+{
+ static char requestBuffer[UPLOAD_KEYS_REQUEST_SIZE];
+
+ mjson_snprintf(requestBuffer, UPLOAD_KEYS_REQUEST_SIZE,
+ "{\"one_time_keys\":{");
+
+ static char onetimeKeysBuffer[1024];
+ olm_account_one_time_keys(client->olmAccount.account,
+ onetimeKeysBuffer, 1024);
+
+ const char *keys;
+ int keysLen;
+ mjson_find(onetimeKeysBuffer, strlen(onetimeKeysBuffer), "$.curve25519", &keys, &keysLen);
+
+ int koff, klen, voff, vlen, vtype, off = 0;
+ while ((off = mjson_next(keys, keysLen, off, &koff, &klen, &voff, &vlen, &vtype)) != 0) {
+ static char keyJson[JSON_ONETIME_KEY_SIZE];
+
+ snprintf(keyJson, JSON_ONETIME_KEY_SIZE,
+ "{\"key\":\"%.*s\"}",
+ vlen-2, keys + voff+1);
+
+ static char keyJsonSigned[JSON_ONETIME_KEY_SIGNED_SIZE];
+
+ JsonSign(client,
+ keyJson, JSON_ONETIME_KEY_SIZE,
+ keyJsonSigned, JSON_ONETIME_KEY_SIGNED_SIZE);
+
+ mjson_snprintf(requestBuffer+strlen(requestBuffer), UPLOAD_KEYS_REQUEST_SIZE-strlen(requestBuffer),
+ "\"signed_curve25519:%.*s\":%s,",
+ klen-2, keys + koff+1,
+ keyJsonSigned);
+ }
+
+ mjson_snprintf(requestBuffer+strlen(requestBuffer), UPLOAD_KEYS_REQUEST_SIZE-strlen(requestBuffer),
+ "}}");
+
+ printf("%s\n", requestBuffer);
+
+ return true;
+}
+
+bool
+MatrixClientUploadDeviceKeys(
+ MatrixClient * client)
+{
+ static char deviceKeysBuffer[UPLOAD_KEYS_REQUEST_SIZE];
+
+ mjson_snprintf(deviceKeysBuffer, UPLOAD_KEYS_REQUEST_SIZE,
+ "{\"device_keys\":{"
+ "\"algorithms\":[\"m.olm.v1.curve25519-aes-sha2\",\"m.megolm.v1.aes-sha2\"],"
+ "\"device_id\":\"%s\","
+ "\"keys\":{"
+ "\"curve25519:%s\":\"%s\","
+ "\"ed25519:%s\":\"%s\""
+ "},"
+ "\"user_id\":\"%s\""
+ "}}",
+ client->deviceId,
+ client->deviceId, client->deviceKey,
+ client->deviceId, client->signingKey,
+ client->userId);
+
+ static char deviceKeysSignedBuffer[UPLOAD_KEYS_REQUEST_SIGNED_SIZE];
+ JsonSign(client,
+ deviceKeysBuffer, UPLOAD_KEYS_REQUEST_SIZE,
+ deviceKeysSignedBuffer, UPLOAD_KEYS_REQUEST_SIZE);
+
+ printf("%s\n", deviceKeysSignedBuffer);
+
+ return true;
+}
+
// https://spec.matrix.org/v1.6/client-server-api/#post_matrixclientv3login
bool
MatrixClientLoginPassword(
@@ -405,6 +563,36 @@ MatrixClientShareMegolmOutSession(
return true;
}
+bool
+MatrixClientShareMegolmOutSessionTest(
+ MatrixClient * client,
+ const char * deviceId,
+ MatrixMegolmOutSession * session)
+{
+ // generate room key event
+ char eventBuffer[KEY_SHARE_EVENT_LEN];
+ sprintf(eventBuffer,
+ "{"
+ "\"algorithm\":\"m.megolm.v1.aes-sha2\","
+ "\"room_id\":\"%s\","
+ "\"session_id\":\"%s\","
+ "\"session_key\":\"%s\""
+ "}",
+ session->roomId,
+ session->id,
+ session->key
+ );
+
+ // send
+ MatrixClientSendToDevice(client,
+ client->userId,
+ deviceId,
+ eventBuffer,
+ "m.room_key");
+
+ return true;
+}
+
// bool
// MatrixClientSetMegolmOutSession(
// MatrixClient * client,
diff --git a/src/matrix.h b/src/matrix.h
index 60561aa..38fb767 100644
--- a/src/matrix.h
+++ b/src/matrix.h
@@ -25,16 +25,25 @@
#define KEY_SHARE_EVENT_LEN 1024
#define OLM_ACCOUNT_MEMORY_SIZE 7528
-#define OLM_ACCOUNT_RANDOM_SIZE 32+32
+#define OLM_ACCOUNT_RANDOM_SIZE (32+32)
#define OLM_SESSION_MEMORY_SIZE 3352
#define OLM_ENCRYPT_RANDOM_SIZE 32
+#define OLM_ONETIME_KEYS_RANDOM_SIZE 32*10
+#define OLM_KEY_ID_SIZE 32
+
+#define OLM_SIGNATURE_SIZE 128
+
#define MEGOLM_OUTBOUND_SESSION_MEMORY_SIZE 232
#define MEGOLM_SESSION_ID_SIZE 44
#define MEGOLM_SESSION_KEY_SIZE 306
#define MEGOLM_INIT_RANDOM_SIZE (4*32 + 32)
+#define JSON_ONETIME_KEY_SIZE 128
+#define JSON_ONETIME_KEY_SIGNED_SIZE 256
+#define JSON_SIGNATURE_SIZE 256
+
#define NUM_MEGOLM_SESSIONS 10
#define NUM_OLM_SESSIONS 10
#define NUM_DEVICES 10
@@ -46,12 +55,33 @@ bool
JsonEscape(
char * sIn, int sInLen,
char * sOut, int sOutCap);
+
+bool JsonSign(
+ char * sIn, int sInLen,
+ char * sOut, int sOutCap);
+
+// Matrix Device
typedef struct MatrixDevice {
char deviceId[DEVICE_ID_SIZE];
char deviceKey[DEVICE_KEY_SIZE];
} MatrixDevice;
+
+// Matrix Olm Account
+
+typedef struct MatrixOlmAccount {
+ OlmAccount * account;
+ char memory[OLM_ACCOUNT_MEMORY_SIZE];
+} MatrixOlmAccount;
+
+bool
+MatrixOlmAccountInit(
+ MatrixOlmAccount * account);
+
+
+// Matrix Olm Session
+
typedef struct MatrixOlmSession {
const char * deviceId;
@@ -72,6 +102,7 @@ MatrixOlmSessionEncrypt(
char * outBuffer, int outBufferCap);
+// Matrix Megolm Session
typedef struct MatrixMegolmInSession {
OlmInboundGroupSession * session;
@@ -99,10 +130,10 @@ MatrixMegolmOutSessionEncrypt(
char * outBuffer, int outBufferCap);
+// Matrix Client
typedef struct MatrixClient {
- OlmAccount * olmAccount;
- char olmAccountMemory[OLM_ACCOUNT_MEMORY_SIZE];
+ MatrixOlmAccount olmAccount;
MatrixMegolmInSession megolmInSessions[NUM_MEGOLM_SESSIONS];
int numMegolmInSessions;
@@ -143,6 +174,24 @@ MatrixClientSetDeviceId(
const char * deviceId);
bool
+MatrixClientSetUserId(
+ MatrixClient * client,
+ const char * userId);
+
+bool
+MatrixClientGenerateOnetimeKeys(
+ MatrixClient * client,
+ int numberOfKeys);
+
+bool
+MatrixClientUploadOnetimeKeys(
+ MatrixClient * client);
+
+bool
+MatrixClientUploadDeviceKeys(
+ MatrixClient * client);
+
+bool
MatrixClientLoginPassword(
MatrixClient * client,
const char * username,
@@ -175,6 +224,12 @@ MatrixClientShareMegolmOutSession(
MatrixMegolmOutSession * session);
bool
+MatrixClientShareMegolmOutSessionTest(
+ MatrixClient * client,
+ const char * deviceId,
+ MatrixMegolmOutSession * session);
+
+bool
MatrixClientGetMegolmOutSession(
MatrixClient * client,
const char * roomId,