From dca69e8326ce6fd0374123ad8c167a2b0051d8fb Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Sun, 24 Jan 2021 20:54:30 +0100 Subject: Add group session decrypt/encrypt test and fix bug found by it --- lib/olm/qolminboundsession.cpp | 19 ++++++++++++------- lib/olm/qolminboundsession.h | 4 +++- lib/olm/qolmoutboundsession.cpp | 6 +++--- lib/olm/qolmoutboundsession.h | 7 +++++-- 4 files changed, 23 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/olm/qolminboundsession.cpp b/lib/olm/qolminboundsession.cpp index d3b98a63..11558f51 100644 --- a/lib/olm/qolminboundsession.cpp +++ b/lib/olm/qolminboundsession.cpp @@ -5,6 +5,7 @@ #ifdef Quotient_E2EE_ENABLED #include "olm/qolminboundsession.h" #include +#include using namespace Quotient; OlmError lastError(OlmInboundGroupSession *session) { @@ -89,22 +90,24 @@ std::variant, OlmError> QOlmInboundGrou return std::make_unique(groupSession); } -std::variant, OlmError> QOlmInboundGroupSession::decrypt(QString &message) +std::variant, OlmError> 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.toUtf8(); + 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(messageBuf.data()), messageBuf.length()), '0'); - const auto messageLen = messageBuf.length(); - const auto plaintextMaxLen = plaintextBuf.length(); + + messageBuf = QByteArray(message.length(), '0'); + std::copy(message.begin(), message.end(), messageBuf.begin()); const auto plaintextLen = olm_group_decrypt(m_groupSession, reinterpret_cast(messageBuf.data()), - messageLen, reinterpret_cast(plaintextBuf.data()), plaintextMaxLen, &messageIndex); + messageBuf.length(), reinterpret_cast(plaintextBuf.data()), plaintextBuf.length(), &messageIndex); // Error code or plaintext length is returned const auto decryptError = plaintextLen; @@ -113,8 +116,10 @@ std::variant, OlmError> QOlmInboundGroupSession::de return lastError(m_groupSession); } - plaintextBuf.truncate(plaintextLen); - return std::make_pair(QString(plaintextBuf), messageIndex); + QByteArray output(plaintextLen, '0'); + std::memcpy(output.data(), plaintextBuf.data(), plaintextLen); + + return std::make_pair(QString(output), messageIndex); } std::variant QOlmInboundGroupSession::exportSession(uint32_t messageIndex) diff --git a/lib/olm/qolminboundsession.h b/lib/olm/qolminboundsession.h index ccc53ba8..eb698868 100644 --- a/lib/olm/qolminboundsession.h +++ b/lib/olm/qolminboundsession.h @@ -31,7 +31,7 @@ public: //! an `OlmInboundGroupSession`. static std::variant, OlmError> unpickle(QByteArray &picked, const PicklingMode &mode); //! Decrypts ciphertext received for this group session. - std::variant, OlmError> decrypt(QString &message); + std::variant, OlmError> decrypt(const QByteArray &message); //! Export the base64-encoded ratchet key for this session, at the given index, //! in a format which can be used by import. std::variant exportSession(uint32_t messageIndex); @@ -44,5 +44,7 @@ public: private: OlmInboundGroupSession *m_groupSession; }; + +using QOlmInboundGroupSessionPtr = std::unique_ptr; } // namespace Quotient #endif diff --git a/lib/olm/qolmoutboundsession.cpp b/lib/olm/qolmoutboundsession.cpp index ba8be4f6..4f3cc827 100644 --- a/lib/olm/qolmoutboundsession.cpp +++ b/lib/olm/qolmoutboundsession.cpp @@ -84,7 +84,7 @@ std::variant, OlmError> QOlmOutboundGr return std::make_unique(olmOutboundGroupSession); } -std::variant QOlmOutboundGroupSession::encrypt(QString &plaintext) +std::variant QOlmOutboundGroupSession::encrypt(const QString &plaintext) { QByteArray plaintextBuf = plaintext.toUtf8(); const auto messageMaxLen = olm_group_encrypt_message_length(m_groupSession, plaintextBuf.length()); @@ -104,14 +104,14 @@ uint32_t QOlmOutboundGroupSession::sessionMessageIndex() const return olm_outbound_group_session_message_index(m_groupSession); } -std::variant QOlmOutboundGroupSession::sessionId() const +QByteArray QOlmOutboundGroupSession::sessionId() const { const auto idMaxLength = olm_outbound_group_session_id_length(m_groupSession); QByteArray idBuffer(idMaxLength, '0'); const auto error = olm_outbound_group_session_id(m_groupSession, reinterpret_cast(idBuffer.data()), idBuffer.length()); if (error == olm_error()) { - return lastError(m_groupSession); + throw lastError(m_groupSession); } return idBuffer; } diff --git a/lib/olm/qolmoutboundsession.h b/lib/olm/qolmoutboundsession.h index 29776a3d..a642f581 100644 --- a/lib/olm/qolmoutboundsession.h +++ b/lib/olm/qolmoutboundsession.h @@ -11,6 +11,7 @@ namespace Quotient { + //! An out-bound group session is responsible for encrypting outgoing //! communication in a Megolm session. class QOlmOutboundGroupSession @@ -26,7 +27,7 @@ public: //! pickling a `QOlmOutboundGroupSession`. static std::variant, OlmError> unpickle(QByteArray &pickled, const PicklingMode &mode); //! Encrypts a plaintext message using the session. - std::variant encrypt(QString &plaintext); + std::variant encrypt(const QString &plaintext); //! Get the current message index for this session. //! @@ -35,7 +36,7 @@ public: uint32_t sessionMessageIndex() const; //! Get a base64-encoded identifier for this session. - std::variant sessionId() const; + QByteArray sessionId() const; //! Get the base64-encoded current ratchet key for this session. //! @@ -46,5 +47,7 @@ public: private: OlmOutboundGroupSession *m_groupSession; }; + +using QOlmOutboundGroupSessionPtr = std::unique_ptr; } #endif -- cgit v1.2.3