aboutsummaryrefslogtreecommitdiff
path: root/lib/e2ee/qolmaccount.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/e2ee/qolmaccount.cpp')
-rw-r--r--lib/e2ee/qolmaccount.cpp151
1 files changed, 79 insertions, 72 deletions
diff --git a/lib/e2ee/qolmaccount.cpp b/lib/e2ee/qolmaccount.cpp
index 1b04dae7..345ab16b 100644
--- a/lib/e2ee/qolmaccount.cpp
+++ b/lib/e2ee/qolmaccount.cpp
@@ -18,15 +18,20 @@
using namespace Quotient;
// Convert olm error to enum
-QOlmError lastError(OlmAccount *account) {
- return fromString(olm_account_last_error(account));
+OlmErrorCode QOlmAccount::lastErrorCode() const {
+ return olm_account_last_error_code(m_account);
}
-QOlmAccount::QOlmAccount(const QString& userId, const QString& deviceId,
+const char* QOlmAccount::lastError() const
+{
+ return olm_account_last_error(m_account);
+}
+
+QOlmAccount::QOlmAccount(QStringView userId, QStringView deviceId,
QObject* parent)
: QObject(parent)
- , m_userId(userId)
- , m_deviceId(deviceId)
+ , m_userId(userId.toString())
+ , m_deviceId(deviceId.toString())
{}
QOlmAccount::~QOlmAccount()
@@ -38,50 +43,52 @@ QOlmAccount::~QOlmAccount()
void QOlmAccount::createNewAccount()
{
m_account = olm_account(new uint8_t[olm_account_size()]);
- size_t randomSize = olm_create_account_random_length(m_account);
- QByteArray randomData = getRandom(randomSize);
- const auto error = olm_create_account(m_account, randomData.data(), randomSize);
- if (error == olm_error()) {
- throw lastError(m_account);
- }
+ if (const auto randomLength = olm_create_account_random_length(m_account);
+ olm_create_account(m_account, RandomBuffer(randomLength), randomLength)
+ == olm_error())
+ QOLM_INTERNAL_ERROR("Failed to create a new account");
+
emit needsSave();
}
-void QOlmAccount::unpickle(QByteArray &pickled, const PicklingMode &mode)
+OlmErrorCode QOlmAccount::unpickle(QByteArray&& pickled,
+ const PicklingMode& mode)
{
m_account = olm_account(new uint8_t[olm_account_size()]);
- const QByteArray key = toKey(mode);
- const auto error = olm_unpickle_account(m_account, key.data(), key.length(), pickled.data(), pickled.size());
- if (error == olm_error()) {
- qCWarning(E2EE) << "Failed to unpickle olm account";
- //TODO: Do something that is not dying
+ if (const auto key = toKey(mode);
+ olm_unpickle_account(m_account, key.data(), key.length(),
+ pickled.data(), pickled.size())
+ == olm_error()) {
// Probably log the user out since we have no way of getting to the keys
- //throw lastError(m_account);
+ return lastErrorCode();
}
+ return OLM_SUCCESS;
}
-QOlmExpected<QByteArray> QOlmAccount::pickle(const PicklingMode &mode)
+QByteArray QOlmAccount::pickle(const PicklingMode &mode)
{
const QByteArray key = toKey(mode);
const size_t pickleLength = olm_pickle_account_length(m_account);
- QByteArray pickleBuffer(pickleLength, '0');
- const auto error = olm_pickle_account(m_account, key.data(),
- key.length(), pickleBuffer.data(), pickleLength);
- if (error == olm_error()) {
- return lastError(m_account);
- }
+ QByteArray pickleBuffer(pickleLength, '\0');
+ if (olm_pickle_account(m_account, key.data(), key.length(),
+ pickleBuffer.data(), pickleLength)
+ == olm_error())
+ QOLM_INTERNAL_ERROR(qPrintable("Failed to pickle Olm account "
+ + accountId()));
+
return pickleBuffer;
}
IdentityKeys QOlmAccount::identityKeys() const
{
const size_t keyLength = olm_account_identity_keys_length(m_account);
- QByteArray keyBuffer(keyLength, '0');
- const auto error = olm_account_identity_keys(m_account, keyBuffer.data(), keyLength);
- if (error == olm_error()) {
- throw lastError(m_account);
+ QByteArray keyBuffer(keyLength, '\0');
+ if (olm_account_identity_keys(m_account, keyBuffer.data(), keyLength)
+ == olm_error()) {
+ QOLM_INTERNAL_ERROR(
+ qPrintable("Failed to get " % accountId() % " identity keys"));
}
- const QJsonObject key = QJsonDocument::fromJson(keyBuffer).object();
+ const auto key = QJsonDocument::fromJson(keyBuffer).object();
return IdentityKeys {
key.value(QStringLiteral("curve25519")).toString().toUtf8(),
key.value(QStringLiteral("ed25519")).toString().toUtf8()
@@ -90,14 +97,13 @@ IdentityKeys QOlmAccount::identityKeys() const
QByteArray QOlmAccount::sign(const QByteArray &message) const
{
- QByteArray signatureBuffer(olm_account_signature_length(m_account), '0');
+ QByteArray signatureBuffer(olm_account_signature_length(m_account), '\0');
- const auto error = olm_account_sign(m_account, message.data(), message.length(),
- signatureBuffer.data(), signatureBuffer.length());
+ if (olm_account_sign(m_account, message.data(), message.length(),
+ signatureBuffer.data(), signatureBuffer.length())
+ == olm_error())
+ QOLM_INTERNAL_ERROR("Failed to sign a message");
- if (error == olm_error()) {
- throw lastError(m_account);
- }
return signatureBuffer;
}
@@ -109,15 +115,15 @@ QByteArray QOlmAccount::sign(const QJsonObject &message) const
QByteArray QOlmAccount::signIdentityKeys() const
{
const auto keys = identityKeys();
- return sign(QJsonObject {
- { "algorithms", QJsonArray { "m.olm.v1.curve25519-aes-sha2",
- "m.megolm.v1.aes-sha2" } },
+ return sign(QJsonObject{
+ { "algorithms", QJsonArray{ "m.olm.v1.curve25519-aes-sha2",
+ "m.megolm.v1.aes-sha2" } },
{ "user_id", m_userId },
{ "device_id", m_deviceId },
- { "keys", QJsonObject { { QStringLiteral("curve25519:") + m_deviceId,
- QString::fromUtf8(keys.curve25519) },
- { QStringLiteral("ed25519:") + m_deviceId,
- QString::fromUtf8(keys.ed25519) } } } });
+ { "keys", QJsonObject{ { QStringLiteral("curve25519:") + m_deviceId,
+ QString::fromUtf8(keys.curve25519) },
+ { QStringLiteral("ed25519:") + m_deviceId,
+ QString::fromUtf8(keys.ed25519) } } } });
}
size_t QOlmAccount::maxNumberOfOneTimeKeys() const
@@ -127,32 +133,31 @@ size_t QOlmAccount::maxNumberOfOneTimeKeys() const
size_t QOlmAccount::generateOneTimeKeys(size_t numberOfKeys)
{
- const size_t randomLength =
+ const auto randomLength =
olm_account_generate_one_time_keys_random_length(m_account,
numberOfKeys);
- QByteArray randomBuffer = getRandom(randomLength);
- const auto error =
- olm_account_generate_one_time_keys(m_account, numberOfKeys,
- randomBuffer.data(), randomLength);
+ const auto result = olm_account_generate_one_time_keys(
+ m_account, numberOfKeys, RandomBuffer(randomLength), randomLength);
+
+ if (result == olm_error())
+ QOLM_INTERNAL_ERROR(qPrintable(
+ "Failed to generate one-time keys for account " + accountId()));
- if (error == olm_error()) {
- throw lastError(m_account);
- }
emit needsSave();
- return error;
+ return result;
}
UnsignedOneTimeKeys QOlmAccount::oneTimeKeys() const
{
- const size_t oneTimeKeyLength = olm_account_one_time_keys_length(m_account);
- QByteArray oneTimeKeysBuffer(static_cast<int>(oneTimeKeyLength), '0');
-
- const auto error = olm_account_one_time_keys(m_account,
- oneTimeKeysBuffer.data(),
- oneTimeKeyLength);
- if (error == olm_error()) {
- throw lastError(m_account);
- }
+ const auto oneTimeKeyLength = olm_account_one_time_keys_length(m_account);
+ QByteArray oneTimeKeysBuffer(static_cast<int>(oneTimeKeyLength), '\0');
+
+ if (olm_account_one_time_keys(m_account, oneTimeKeysBuffer.data(),
+ oneTimeKeyLength)
+ == olm_error())
+ QOLM_INTERNAL_ERROR(qPrintable(
+ "Failed to obtain one-time keys for account" % accountId()));
+
const auto json = QJsonDocument::fromJson(oneTimeKeysBuffer).object();
UnsignedOneTimeKeys oneTimeKeys;
fromJson(json, oneTimeKeys.keys);
@@ -171,16 +176,16 @@ OneTimeKeys QOlmAccount::signOneTimeKeys(const UnsignedOneTimeKeys &keys) const
return signedOneTimeKeys;
}
-std::optional<QOlmError> QOlmAccount::removeOneTimeKeys(
- const QOlmSession& session)
+OlmErrorCode QOlmAccount::removeOneTimeKeys(const QOlmSession& session)
{
- const auto error = olm_remove_one_time_keys(m_account, session.raw());
-
- if (error == olm_error()) {
- return lastError(m_account);
+ if (olm_remove_one_time_keys(m_account, session.raw()) == olm_error()) {
+ qWarning(E2EE).nospace()
+ << "Failed to remove one-time keys for session "
+ << session.sessionId() << ": " << lastError();
+ return lastErrorCode();
}
emit needsSave();
- return std::nullopt;
+ return OLM_SUCCESS;
}
OlmAccount* QOlmAccount::data() { return m_account; }
@@ -191,13 +196,13 @@ DeviceKeys QOlmAccount::deviceKeys() const
SupportedAlgorithms.cend());
const auto idKeys = identityKeys();
- return DeviceKeys {
+ return DeviceKeys{
.userId = m_userId,
.deviceId = m_deviceId,
.algorithms = Algorithms,
- .keys { { "curve25519:" + m_deviceId, idKeys.curve25519 },
- { "ed25519:" + m_deviceId, idKeys.ed25519 } },
- .signatures {
+ .keys{ { "curve25519:" + m_deviceId, idKeys.curve25519 },
+ { "ed25519:" + m_deviceId, idKeys.ed25519 } },
+ .signatures{
{ m_userId, { { "ed25519:" + m_deviceId, signIdentityKeys() } } } }
};
}
@@ -266,3 +271,5 @@ bool Quotient::ed25519VerifySignature(const QString& signingKey,
auto signatureBuf = signature.toUtf8();
return utility.ed25519Verify(signingKeyBuf, canonicalJson, signatureBuf);
}
+
+QString QOlmAccount::accountId() const { return m_userId % '/' % m_deviceId; }