aboutsummaryrefslogtreecommitdiff
path: root/lib/e2ee/qolminboundsession.cpp
diff options
context:
space:
mode:
authorn-peugnet <n.peugnet@free.fr>2022-10-06 19:27:24 +0200
committern-peugnet <n.peugnet@free.fr>2022-10-06 19:27:24 +0200
commitd911b207f49e936b3e992200796110f0749ed150 (patch)
tree96d20ebb4d074a4c1755e21cb316a52d584daee3 /lib/e2ee/qolminboundsession.cpp
parent8ad8a74152c5701b6ca1f9a00487ba9257a439b4 (diff)
parent56c2f2e2b809b9077393eb617828f33d144f5634 (diff)
downloadlibquotient-d911b207f49e936b3e992200796110f0749ed150.tar.gz
libquotient-d911b207f49e936b3e992200796110f0749ed150.zip
New upstream version 0.7.0
Diffstat (limited to 'lib/e2ee/qolminboundsession.cpp')
-rw-r--r--lib/e2ee/qolminboundsession.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/e2ee/qolminboundsession.cpp b/lib/e2ee/qolminboundsession.cpp
new file mode 100644
index 00000000..18275dc0
--- /dev/null
+++ b/lib/e2ee/qolminboundsession.cpp
@@ -0,0 +1,192 @@
+// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "qolminboundsession.h"
+#include "qolmutils.h"
+#include "../logging.h"
+
+#include <cstring>
+#include <iostream>
+#include <olm/olm.h>
+
+using namespace Quotient;
+
+OlmErrorCode QOlmInboundGroupSession::lastErrorCode() const {
+ return olm_inbound_group_session_last_error_code(m_groupSession);
+}
+
+const char* QOlmInboundGroupSession::lastError() const
+{
+ return olm_inbound_group_session_last_error(m_groupSession);
+}
+
+QOlmInboundGroupSession::QOlmInboundGroupSession(OlmInboundGroupSession *session)
+ : m_groupSession(session)
+{}
+
+QOlmInboundGroupSession::~QOlmInboundGroupSession()
+{
+ olm_clear_inbound_group_session(m_groupSession);
+ //delete[](reinterpret_cast<uint8_t *>(m_groupSession));
+}
+
+QOlmExpected<QOlmInboundGroupSessionPtr> QOlmInboundGroupSession::create(
+ const QByteArray& key)
+{
+ const auto olmInboundGroupSession = olm_inbound_group_session(new uint8_t[olm_inbound_group_session_size()]);
+ if (olm_init_inbound_group_session(
+ olmInboundGroupSession,
+ reinterpret_cast<const uint8_t*>(key.constData()), key.size())
+ == olm_error()) {
+ // FIXME: create QOlmInboundGroupSession earlier and use lastErrorCode()
+ qWarning(E2EE) << "Failed to create an inbound group session:"
+ << olm_inbound_group_session_last_error(
+ olmInboundGroupSession);
+ return olm_inbound_group_session_last_error_code(olmInboundGroupSession);
+ }
+
+ return std::make_unique<QOlmInboundGroupSession>(olmInboundGroupSession);
+}
+
+QOlmExpected<QOlmInboundGroupSessionPtr> QOlmInboundGroupSession::importSession(
+ const QByteArray& key)
+{
+ const auto olmInboundGroupSession = olm_inbound_group_session(new uint8_t[olm_inbound_group_session_size()]);
+
+ if (olm_import_inbound_group_session(
+ olmInboundGroupSession,
+ reinterpret_cast<const uint8_t*>(key.data()), key.size())
+ == olm_error()) {
+ // FIXME: create QOlmInboundGroupSession earlier and use lastError()
+ qWarning(E2EE) << "Failed to import an inbound group session:"
+ << olm_inbound_group_session_last_error(
+ olmInboundGroupSession);
+ return olm_inbound_group_session_last_error_code(olmInboundGroupSession);
+ }
+
+ return std::make_unique<QOlmInboundGroupSession>(olmInboundGroupSession);
+}
+
+QByteArray QOlmInboundGroupSession::pickle(const PicklingMode& mode) const
+{
+ QByteArray pickledBuf(
+ olm_pickle_inbound_group_session_length(m_groupSession), '\0');
+ if (const auto key = toKey(mode);
+ olm_pickle_inbound_group_session(m_groupSession, key.data(),
+ key.length(), pickledBuf.data(),
+ pickledBuf.length())
+ == olm_error()) {
+ QOLM_INTERNAL_ERROR("Failed to pickle the inbound group session");
+ }
+ return pickledBuf;
+}
+
+QOlmExpected<QOlmInboundGroupSessionPtr> QOlmInboundGroupSession::unpickle(
+ QByteArray&& pickled, const PicklingMode& mode)
+{
+ const auto groupSession = olm_inbound_group_session(new uint8_t[olm_inbound_group_session_size()]);
+ auto key = toKey(mode);
+ if (olm_unpickle_inbound_group_session(groupSession, key.data(),
+ key.length(), pickled.data(),
+ pickled.size())
+ == olm_error()) {
+ // FIXME: create QOlmInboundGroupSession earlier and use lastError()
+ qWarning(E2EE) << "Failed to unpickle an inbound group session:"
+ << olm_inbound_group_session_last_error(groupSession);
+ return olm_inbound_group_session_last_error_code(groupSession);
+ }
+ key.clear();
+
+ return std::make_unique<QOlmInboundGroupSession>(groupSession);
+}
+
+QOlmExpected<std::pair<QByteArray, uint32_t>> QOlmInboundGroupSession::decrypt(
+ const QByteArray& message)
+{
+ // This is for capturing the output of olm_group_decrypt
+ uint32_t messageIndex = 0;
+
+ // We need to clone the message because
+ // olm_decrypt_max_plaintext_length destroys the input buffer
+ QByteArray messageBuf(message.length(), '\0');
+ std::copy(message.begin(), message.end(), messageBuf.begin());
+
+ QByteArray plaintextBuf(olm_group_decrypt_max_plaintext_length(
+ m_groupSession,
+ reinterpret_cast<uint8_t*>(messageBuf.data()),
+ messageBuf.length()),
+ '\0');
+
+ messageBuf = QByteArray(message.length(), '\0');
+ std::copy(message.begin(), message.end(), messageBuf.begin());
+
+ const auto plaintextLen = olm_group_decrypt(m_groupSession, reinterpret_cast<uint8_t *>(messageBuf.data()),
+ messageBuf.length(), reinterpret_cast<uint8_t *>(plaintextBuf.data()), plaintextBuf.length(), &messageIndex);
+ if (plaintextLen == olm_error()) {
+ qWarning(E2EE) << "Failed to decrypt the message:" << lastError();
+ return lastErrorCode();
+ }
+
+ QByteArray output(plaintextLen, '\0');
+ std::memcpy(output.data(), plaintextBuf.data(), plaintextLen);
+
+ return std::make_pair(output, messageIndex);
+}
+
+QOlmExpected<QByteArray> QOlmInboundGroupSession::exportSession(
+ uint32_t messageIndex)
+{
+ const auto keyLength = olm_export_inbound_group_session_length(m_groupSession);
+ QByteArray keyBuf(keyLength, '\0');
+ if (olm_export_inbound_group_session(
+ m_groupSession, reinterpret_cast<uint8_t*>(keyBuf.data()),
+ keyLength, messageIndex)
+ == olm_error()) {
+ QOLM_FAIL_OR_LOG(OLM_OUTPUT_BUFFER_TOO_SMALL,
+ "Failed to export the inbound group session");
+ return lastErrorCode();
+ }
+ return keyBuf;
+}
+
+uint32_t QOlmInboundGroupSession::firstKnownIndex() const
+{
+ return olm_inbound_group_session_first_known_index(m_groupSession);
+}
+
+QByteArray QOlmInboundGroupSession::sessionId() const
+{
+ QByteArray sessionIdBuf(olm_inbound_group_session_id_length(m_groupSession),
+ '\0');
+ if (olm_inbound_group_session_id(
+ m_groupSession, reinterpret_cast<uint8_t*>(sessionIdBuf.data()),
+ sessionIdBuf.length())
+ == olm_error())
+ QOLM_INTERNAL_ERROR("Failed to obtain the group session id");
+
+ return sessionIdBuf;
+}
+
+bool QOlmInboundGroupSession::isVerified() const
+{
+ return olm_inbound_group_session_is_verified(m_groupSession) != 0;
+}
+
+QString QOlmInboundGroupSession::olmSessionId() const
+{
+ return m_olmSessionId;
+}
+void QOlmInboundGroupSession::setOlmSessionId(const QString& newOlmSessionId)
+{
+ m_olmSessionId = newOlmSessionId;
+}
+
+QString QOlmInboundGroupSession::senderId() const
+{
+ return m_senderId;
+}
+void QOlmInboundGroupSession::setSenderId(const QString& senderId)
+{
+ m_senderId = senderId;
+}