1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "testolmutility.h"
#include "e2ee/qolmaccount.h"
#include "e2ee/qolmutility.h"
using namespace Quotient;
void TestOlmUtility::canonicalJSON()
{
// Examples taken from
// https://matrix.org/docs/spec/appendices.html#canonical-json
auto data = QJsonDocument::fromJson(QByteArrayLiteral(R"({
"auth": {
"success": true,
"mxid": "@john.doe:example.com",
"profile": {
"display_name": "John Doe",
"three_pids": [{
"medium": "email",
"address": "john.doe@example.org"
}, {
"medium": "msisdn",
"address": "123456789"
}]
}}})"));
QCOMPARE(data.toJson(QJsonDocument::Compact),
"{\"auth\":{\"mxid\":\"@john.doe:example.com\",\"profile\":{\"display_name\":\"John "
"Doe\",\"three_pids\":[{\"address\":\"john.doe@example.org\",\"medium\":\"email\"},{"
"\"address\":\"123456789\",\"medium\":\"msisdn\"}]},\"success\":true}}");
auto data0 = QJsonDocument::fromJson(QByteArrayLiteral(R"({"b":"2","a":"1"})"));
QCOMPARE(data0.toJson(QJsonDocument::Compact), "{\"a\":\"1\",\"b\":\"2\"}");
auto data1 = QJsonDocument::fromJson(QByteArrayLiteral(R"({ "本": 2, "日": 1 })"));
QCOMPARE(data1.toJson(QJsonDocument::Compact), "{\"日\":1,\"本\":2}");
auto data2 = QJsonDocument::fromJson(QByteArrayLiteral(R"({"a": "\u65E5"})"));
QCOMPARE(data2.toJson(QJsonDocument::Compact), "{\"a\":\"日\"}");
auto data3 = QJsonDocument::fromJson(QByteArrayLiteral(R"({ "a": null })"));
QCOMPARE(data3.toJson(QJsonDocument::Compact), "{\"a\":null}");
}
void TestOlmUtility::verifySignedOneTimeKey()
{
QOlmAccount aliceOlm { "@alice:matrix.org", "aliceDevice" };
aliceOlm.createNewAccount();
aliceOlm.generateOneTimeKeys(1);
auto keys = aliceOlm.oneTimeKeys();
auto firstKey = keys.curve25519().keyValueBegin()->second;
auto msgObj = QJsonObject({{"key", firstKey}});
auto sig = aliceOlm.sign(msgObj);
auto msg = QJsonDocument(msgObj).toJson(QJsonDocument::Compact);
auto utilityBuf = new uint8_t[olm_utility_size()];
auto utility = olm_utility(utilityBuf);
QByteArray signatureBuf1(sig.length(), '0');
std::copy(sig.begin(), sig.end(), signatureBuf1.begin());
auto res = olm_ed25519_verify(utility,
aliceOlm.identityKeys().ed25519.data(),
aliceOlm.identityKeys().ed25519.size(),
msg.data(),
msg.size(),
(void *)sig.data(),
sig.size());
QCOMPARE(std::string(olm_utility_last_error(utility)), "SUCCESS");
QCOMPARE(res, 0);
delete[](reinterpret_cast<uint8_t *>(utility));
QOlmUtility utility2;
auto res2 = std::get<bool>(utility2.ed25519Verify(aliceOlm.identityKeys().ed25519, msg, signatureBuf1));
//QCOMPARE(std::string(olm_utility_last_error(utility)), "SUCCESS");
QCOMPARE(res2, true);
}
void TestOlmUtility::validUploadKeysRequest()
{
const auto userId = QStringLiteral("@alice:matrix.org");
const auto deviceId = QStringLiteral("FKALSOCCC");
QOlmAccount alice { userId, deviceId };
alice.createNewAccount();
alice.generateOneTimeKeys(1);
auto idSig = alice.signIdentityKeys();
QJsonObject body
{
{"algorithms", QJsonArray{"m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"}},
{"user_id", userId},
{"device_id", deviceId},
{"keys",
QJsonObject{
{QStringLiteral("curve25519:") + deviceId, QString::fromUtf8(alice.identityKeys().curve25519)},
{QStringLiteral("ed25519:") + deviceId, QString::fromUtf8(alice.identityKeys().ed25519)}
}
},
{"signatures",
QJsonObject{
{userId,
QJsonObject{
{"ed25519:" + deviceId, QString::fromUtf8(idSig)}
}
}
}
}
};
DeviceKeys deviceKeys = alice.deviceKeys();
QCOMPARE(QJsonDocument(toJson(deviceKeys)).toJson(QJsonDocument::Compact),
QJsonDocument(body).toJson(QJsonDocument::Compact));
QVERIFY(verifyIdentitySignature(fromJson<DeviceKeys>(body), deviceId, userId));
QVERIFY(verifyIdentitySignature(deviceKeys, deviceId, userId));
}
QTEST_MAIN(TestOlmUtility)
|