aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-09-21 16:11:39 +0200
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-09-26 10:46:34 +0200
commitbc1ded73bedf593acda80b00eb7da32f688c4843 (patch)
tree48867f314c028cdf4ddb17d72ef964f5f5954b89
parentbcc05aa1d52cae2b6d8e70bb6cf04fa49904687a (diff)
downloadlibquotient-bc1ded73bedf593acda80b00eb7da32f688c4843.tar.gz
libquotient-bc1ded73bedf593acda80b00eb7da32f688c4843.zip
RandomBuffer
A convenient abstraction swallowing all the type casts and, more importantly, cleanup on destruction (previous code only cleaned up the buffer upon a successful call to Olm API but not upon an error).
-rw-r--r--lib/connection.cpp2
-rw-r--r--lib/e2ee/qolmaccount.cpp9
-rw-r--r--lib/e2ee/qolmoutboundsession.cpp9
-rw-r--r--lib/e2ee/qolmsession.cpp12
-rw-r--r--lib/e2ee/qolmutils.cpp7
-rw-r--r--lib/e2ee/qolmutils.h23
-rw-r--r--lib/events/filesourceinfo.cpp8
-rw-r--r--lib/keyverificationsession.cpp3
8 files changed, 41 insertions, 32 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index f38bb751..cd8ee727 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -614,7 +614,7 @@ void Connection::Private::completeSetup(const QString& mxId)
loop.exec();
if (job.error() == QKeychain::Error::EntryNotFound) {
- picklingMode = Encrypted { getRandom(128) };
+ picklingMode = Encrypted { RandomBuffer(128) };
QKeychain::WritePasswordJob job(qAppName());
job.setAutoDelete(false);
job.setKey(accountSettings.userId() + QStringLiteral("-Pickle"));
diff --git a/lib/e2ee/qolmaccount.cpp b/lib/e2ee/qolmaccount.cpp
index 556a8274..b56272ef 100644
--- a/lib/e2ee/qolmaccount.cpp
+++ b/lib/e2ee/qolmaccount.cpp
@@ -44,8 +44,7 @@ void QOlmAccount::createNewAccount()
{
m_account = olm_account(new uint8_t[olm_account_size()]);
const auto randomLength = olm_create_account_random_length(m_account);
- QByteArray randomData = getRandom(randomLength);
- if (olm_create_account(m_account, randomData.data(), randomLength)
+ if (olm_create_account(m_account, RandomBuffer(randomLength), randomLength)
== olm_error()) {
throw lastError();
}
@@ -133,10 +132,8 @@ size_t QOlmAccount::generateOneTimeKeys(size_t numberOfKeys)
const auto randomLength =
olm_account_generate_one_time_keys_random_length(m_account,
numberOfKeys);
- QByteArray randomBuffer = getRandom(randomLength);
- const auto result =
- 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()) {
throw lastError();
diff --git a/lib/e2ee/qolmoutboundsession.cpp b/lib/e2ee/qolmoutboundsession.cpp
index 22107a21..3d176274 100644
--- a/lib/e2ee/qolmoutboundsession.cpp
+++ b/lib/e2ee/qolmoutboundsession.cpp
@@ -34,11 +34,10 @@ QOlmOutboundGroupSessionPtr QOlmOutboundGroupSession::create()
{
auto *olmOutboundGroupSession = olm_outbound_group_session(new uint8_t[olm_outbound_group_session_size()]);
const auto randomLength = olm_init_outbound_group_session_random_length(olmOutboundGroupSession);
- QByteArray randomBuf = getRandom(randomLength);
- if (olm_init_outbound_group_session(
- olmOutboundGroupSession,
- reinterpret_cast<uint8_t*>(randomBuf.data()), randomBuf.length())
+ if (olm_init_outbound_group_session(olmOutboundGroupSession,
+ RandomBuffer(randomLength).bytes(),
+ randomLength)
== olm_error()) {
// FIXME: create the session object earlier and use lastError()
throw olm_outbound_group_session_last_error_code(olmOutboundGroupSession);
@@ -50,8 +49,6 @@ QOlmOutboundGroupSessionPtr QOlmOutboundGroupSession::create()
olm_outbound_group_session_key(olmOutboundGroupSession, reinterpret_cast<uint8_t *>(keyBuffer.data()),
keyMaxLength);
- randomBuf.clear();
-
return std::make_unique<QOlmOutboundGroupSession>(olmOutboundGroupSession);
}
diff --git a/lib/e2ee/qolmsession.cpp b/lib/e2ee/qolmsession.cpp
index e252c37f..7c102a96 100644
--- a/lib/e2ee/qolmsession.cpp
+++ b/lib/e2ee/qolmsession.cpp
@@ -80,13 +80,13 @@ QOlmExpected<QOlmSessionPtr> QOlmSession::createOutboundSession(
const QByteArray& theirOneTimeKey)
{
auto* olmOutboundSession = create();
- auto randomBuf = getRandom(
- olm_create_outbound_session_random_length(olmOutboundSession));
+ const auto randomLength =
+ olm_create_outbound_session_random_length(olmOutboundSession);
if (olm_create_outbound_session(
olmOutboundSession, account->data(), theirIdentityKey.data(),
theirIdentityKey.length(), theirOneTimeKey.data(),
- theirOneTimeKey.length(), randomBuf.data(), randomBuf.length())
+ theirOneTimeKey.length(), RandomBuffer(randomLength), randomLength)
== olm_error()) {
// FIXME: the QOlmSession object should be created earlier
const auto lastErr = olm_session_last_error_code(olmOutboundSession);
@@ -96,7 +96,6 @@ QOlmExpected<QOlmSessionPtr> QOlmSession::createOutboundSession(
return lastErr;
}
- randomBuf.clear();
return std::make_unique<QOlmSession>(olmOutboundSession);
}
@@ -136,15 +135,14 @@ QOlmMessage QOlmSession::encrypt(const QByteArray& plaintext)
QByteArray messageBuf(messageMaxLength, '0');
// NB: The type has to be calculated before calling olm_encrypt()
const auto messageType = olm_encrypt_message_type(m_session);
- auto randomBuf = getRandom(olm_encrypt_random_length(m_session));
+ const auto randomLength = olm_encrypt_random_length(m_session);
if (olm_encrypt(m_session, plaintext.data(), plaintext.length(),
- randomBuf.data(), randomBuf.length(), messageBuf.data(),
+ RandomBuffer(randomLength), randomLength, messageBuf.data(),
messageBuf.length())
== olm_error()) {
throw lastError();
}
- randomBuf.clear();
return QOlmMessage(messageBuf, QOlmMessage::Type(messageType));
}
diff --git a/lib/e2ee/qolmutils.cpp b/lib/e2ee/qolmutils.cpp
index 6f7937e8..c6e51bcd 100644
--- a/lib/e2ee/qolmutils.cpp
+++ b/lib/e2ee/qolmutils.cpp
@@ -15,9 +15,8 @@ QByteArray Quotient::toKey(const Quotient::PicklingMode &mode)
return std::get<Quotient::Encrypted>(mode).key;
}
-QByteArray Quotient::getRandom(size_t bufferSize)
+RandomBuffer::RandomBuffer(size_t size)
+ : QByteArray(static_cast<int>(size), '\0')
{
- QByteArray buffer(bufferSize, '0');
- QRandomGenerator::system()->generate(buffer.begin(), buffer.end());
- return buffer;
+ QRandomGenerator::system()->generate(begin(), end());
}
diff --git a/lib/e2ee/qolmutils.h b/lib/e2ee/qolmutils.h
index 7a8511c3..da9d2d18 100644
--- a/lib/e2ee/qolmutils.h
+++ b/lib/e2ee/qolmutils.h
@@ -12,5 +12,26 @@ namespace Quotient {
// Convert PicklingMode to key
QUOTIENT_API QByteArray toKey(const PicklingMode &mode);
-QUOTIENT_API QByteArray getRandom(size_t bufferSize);
+
+class QUOTIENT_API RandomBuffer : public QByteArray {
+public:
+ explicit RandomBuffer(size_t size);
+ ~RandomBuffer() { clear(); }
+
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ QUO_IMPLICIT operator void*() { return data(); }
+ char* chars() { return data(); }
+ uint8_t* bytes() { return reinterpret_cast<uint8_t*>(data()); }
+
+ Q_DISABLE_COPY(RandomBuffer)
+ RandomBuffer(RandomBuffer&&) = default;
+ void operator=(RandomBuffer&&) = delete;
+};
+
+[[deprecated("Create RandomBuffer directly")]] inline auto getRandom(
+ size_t bufferSize)
+{
+ return RandomBuffer(bufferSize);
}
+
+} // namespace Quotient
diff --git a/lib/events/filesourceinfo.cpp b/lib/events/filesourceinfo.cpp
index 6abe6a08..a60d86d2 100644
--- a/lib/events/filesourceinfo.cpp
+++ b/lib/events/filesourceinfo.cpp
@@ -59,19 +59,17 @@ std::pair<EncryptedFileMetadata, QByteArray> Quotient::encryptFile(
const QByteArray& plainText)
{
#ifdef Quotient_E2EE_ENABLED
- auto k = getRandom(32);
+ auto k = RandomBuffer(32);
auto kBase64 = k.toBase64(QByteArray::Base64UrlEncoding
| QByteArray::OmitTrailingEquals);
- auto iv = getRandom(16);
+ auto iv = RandomBuffer(16);
JWK key = {
"oct"_ls, { "encrypt"_ls, "decrypt"_ls }, "A256CTR"_ls, kBase64, true
};
int length = -1;
auto* ctx = EVP_CIPHER_CTX_new();
- EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr,
- reinterpret_cast<const unsigned char*>(k.data()),
- reinterpret_cast<const unsigned char*>(iv.data()));
+ EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, k.bytes(), iv.bytes());
const auto blockSize = EVP_CIPHER_CTX_block_size(ctx);
QByteArray cipherText(plainText.size() + blockSize - 1, '\0');
EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char*>(cipherText.data()),
diff --git a/lib/keyverificationsession.cpp b/lib/keyverificationsession.cpp
index 0f24c743..171596c0 100644
--- a/lib/keyverificationsession.cpp
+++ b/lib/keyverificationsession.cpp
@@ -72,8 +72,7 @@ void KeyVerificationSession::init(milliseconds timeout)
m_sas = olm_sas(new std::byte[olm_sas_size()]);
const auto randomLength = olm_create_sas_random_length(m_sas);
- auto random = getRandom(randomLength);
- olm_create_sas(m_sas, random.data(), randomLength);
+ olm_create_sas(m_sas, RandomBuffer(randomLength), randomLength);
}
KeyVerificationSession::~KeyVerificationSession()