Page MenuHomePhorge

D160.1732550242.diff
No OneTemporary

Size
13 KB
Referenced Files
None
Subscribers
None

D160.1732550242.diff

diff --git a/src/crypto/outbound-group-session-p.hpp b/src/crypto/outbound-group-session-p.hpp
--- a/src/crypto/outbound-group-session-p.hpp
+++ b/src/crypto/outbound-group-session-p.hpp
@@ -9,7 +9,7 @@
#include "outbound-group-session.hpp"
-#include <olm/olm.h>
+#include <vodozemac.h>
#include <immer/map.hpp>
@@ -25,8 +25,7 @@
OutboundGroupSessionPrivate(const OutboundGroupSessionPrivate &that);
~OutboundGroupSessionPrivate() = default;
- ByteArray sessionData;
- OlmOutboundGroupSession *session;
+ std::optional<rust::Box<vodozemac::megolm::GroupSession>> session;
bool valid{false};
@@ -34,12 +33,9 @@
std::string initialSessionKey;
-
- std::size_t checkError(std::size_t code) const;
- std::string error() const;
-
std::string pickle() const;
bool unpickle(std::string pickleData);
+ bool unpickleFromLibolm(std::string pickleData);
std::string sessionKey();
};
diff --git a/src/crypto/outbound-group-session.hpp b/src/crypto/outbound-group-session.hpp
--- a/src/crypto/outbound-group-session.hpp
+++ b/src/crypto/outbound-group-session.hpp
@@ -26,7 +26,6 @@
*/
static std::size_t constructRandomSize();
- [[deprecated("Use deterministic variant instead. In the future, this will construct an invalid OutboundGroupSession.")]]
explicit OutboundGroupSession();
/**
diff --git a/src/crypto/outbound-group-session.cpp b/src/crypto/outbound-group-session.cpp
--- a/src/crypto/outbound-group-session.cpp
+++ b/src/crypto/outbound-group-session.cpp
@@ -1,6 +1,6 @@
/*
* This file is part of libkazv.
- * SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
+ * SPDX-FileCopyrightText: 2021-2024 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -8,61 +8,36 @@
#include "outbound-group-session-p.hpp"
-
+#include "crypto-util-p.hpp"
#include <debug.hpp>
#include "time-util.hpp"
namespace Kazv
{
- std::size_t OutboundGroupSessionPrivate::checkError(std::size_t code) const
- {
- if (code == olm_error()) {
- kzo.crypto.warn() << "Olm outbound group session error: "
- << olm_outbound_group_session_last_error(session) << std::endl;
- }
- return code;
- }
-
- std::string OutboundGroupSessionPrivate::error() const
- {
- return olm_outbound_group_session_last_error(session);
- }
-
-
OutboundGroupSessionPrivate::OutboundGroupSessionPrivate()
- : sessionData(olm_outbound_group_session_size(), '\0')
- , session(olm_outbound_group_session(sessionData.data()))
+ : session(std::nullopt)
{
- auto randomData = genRandom(olm_init_outbound_group_session_random_length(session));
- auto res = checkError(olm_init_outbound_group_session(session, randomData.data(), randomData.size()));
-
- if (res != olm_error()) {
- valid = true;
- initialSessionKey = sessionKey();
- }
-
- creationTime = currentTimeMs();
}
- OutboundGroupSessionPrivate::OutboundGroupSessionPrivate(RandomTag,
- RandomData random,
- Timestamp creationTime)
- : sessionData(olm_outbound_group_session_size(), '\0')
- , session(olm_outbound_group_session(sessionData.data()))
+ OutboundGroupSessionPrivate::OutboundGroupSessionPrivate(
+ RandomTag,
+ [[maybe_unused]] RandomData random,
+ Timestamp creationTime)
+ : session(std::nullopt)
, creationTime(creationTime)
{
- assert(random.size() >= OutboundGroupSession::constructRandomSize());
- auto res = checkError(olm_init_outbound_group_session(session, reinterpret_cast<std::uint8_t *>(random.data()), random.size()));
+ session = checkVodozemacError([&]() {
+ return vodozemac::megolm::new_group_session();
+ });
- if (res != olm_error()) {
+ if (session.has_value()) {
valid = true;
initialSessionKey = sessionKey();
}
}
OutboundGroupSessionPrivate::OutboundGroupSessionPrivate(const OutboundGroupSessionPrivate &that)
- : sessionData(olm_outbound_group_session_size(), '\0')
- , session(olm_outbound_group_session(sessionData.data()))
+ : session(std::nullopt)
, creationTime(that.creationTime)
, initialSessionKey(that.initialSessionKey)
{
@@ -71,35 +46,29 @@
std::string OutboundGroupSessionPrivate::pickle() const
{
- auto pickleData = std::string(olm_pickle_outbound_group_session_length(session), '\0');
- auto key = ByteArray(3, 'x');
- checkError(olm_pickle_outbound_group_session(session,
- key.data(), key.size(),
- pickleData.data(), pickleData.size()));
- return pickleData;
+ auto pickleData = session.value()->pickle(VODOZEMAC_PICKLE_KEY);
+ return static_cast<std::string>(pickleData);
}
bool OutboundGroupSessionPrivate::unpickle(std::string pickleData)
{
- auto key = ByteArray(3, 'x');
- auto res = checkError(olm_unpickle_outbound_group_session(
- session,
- key.data(), key.size(),
- pickleData.data(), pickleData.size()));
+ session = checkVodozemacError([&]() {
+ return vodozemac::megolm::group_session_from_pickle(pickleData, VODOZEMAC_PICKLE_KEY);
+ });
+ return session.has_value();
+ }
- return res != olm_error();
+ bool OutboundGroupSessionPrivate::unpickleFromLibolm(std::string pickleData)
+ {
+ session = checkVodozemacError([&]() {
+ return vodozemac::megolm::group_session_from_libolm_pickle(pickleData, rust::Slice<const unsigned char>(OLM_PICKLE_KEY.data(), OLM_PICKLE_KEY.size()));
+ });
+ return session.has_value();
}
std::size_t OutboundGroupSession::constructRandomSize()
{
- static std::size_t s =
- []() {
- ByteArray sessionData(olm_outbound_group_session_size(), '\0');
- OlmOutboundGroupSession *session(olm_outbound_group_session(sessionData.data()));
- return olm_init_outbound_group_session_random_length(session);
- }();
-
- return s;
+ return 0;
}
OutboundGroupSession::OutboundGroupSession()
@@ -144,27 +113,22 @@
std::string OutboundGroupSession::encrypt(std::string plainText)
{
- auto plain = ByteArray(plainText.begin(), plainText.end());
- auto size = olm_group_encrypt_message_length(m_d->session, plainText.size());
- auto encrypted = ByteArray(size, '\0');
-
+ auto res = checkVodozemacError([&]() {
+ return m_d->session.value()->encrypt(rust::Str(plainText));
+ });
- auto actualSize = m_d->checkError(olm_group_encrypt(
- m_d->session,
- plain.data(), plain.size(),
- encrypted.data(), encrypted.size()));
+ if (!res.has_value()) {
+ return std::string();
+ }
- return std::string(encrypted.begin(), encrypted.begin() + actualSize);
+ return static_cast<std::string>(res.value()->to_base64());
}
std::string OutboundGroupSessionPrivate::sessionKey()
{
- auto size = olm_outbound_group_session_key_length(session);
- auto keyBuf = ByteArray(size, '\0');
- auto actualSize = checkError(
- olm_outbound_group_session_key(session, keyBuf.data(), keyBuf.size()));
+ auto key = session.value()->session_key()->to_base64();
- return std::string(keyBuf.begin(), keyBuf.begin() + actualSize);
+ return static_cast<std::string>(key);
}
std::string OutboundGroupSession::sessionKey()
@@ -179,17 +143,13 @@
std::string OutboundGroupSession::sessionId()
{
- auto size = olm_outbound_group_session_id_length(m_d->session);
- auto idBuf = ByteArray(size, '\0');
- auto actualSize = m_d->checkError(
- olm_outbound_group_session_id(m_d->session, idBuf.data(), idBuf.size()));
-
- return std::string(idBuf.begin(), idBuf.begin() + actualSize);
+ auto id = m_d->session.value()->session_id();
+ return static_cast<std::string>(id);
}
int OutboundGroupSession::messageIndex()
{
- return olm_outbound_group_session_message_index(m_d->session);
+ return m_d->session.value()->message_index();
}
Timestamp OutboundGroupSession::creationTimeMs() const
@@ -200,6 +160,7 @@
void to_json(nlohmann::json &j, const OutboundGroupSession &s)
{
j = nlohmann::json::object();
+ j["version"] = 1;
j["valid"] = s.m_d->valid;
j["creationTime"] = s.m_d->creationTime;
j["initialSessionKey"] = s.m_d->initialSessionKey;
@@ -214,7 +175,11 @@
s.m_d->creationTime = j.at("creationTime");
s.m_d->initialSessionKey = j.at("initialSessionKey");
if (s.m_d->valid) {
- s.m_d->valid = s.m_d->unpickle(j.at("session"));
+ if (j.contains("version") && j["version"] == 1) {
+ s.m_d->valid = s.m_d->unpickle(j.at("session"));
+ } else {
+ s.m_d->valid = s.m_d->unpickleFromLibolm(j.at("session"));
+ }
}
}
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -110,6 +110,7 @@
crypto-test.cpp
crypto/deterministic-test.cpp
crypto/inbound-group-session-test.cpp
+ crypto/outbound-group-session-test.cpp
EXTRA_LINK_LIBRARIES kazvcrypto
)
diff --git a/src/tests/crypto/deterministic-test.cpp b/src/tests/crypto/deterministic-test.cpp
--- a/src/tests/crypto/deterministic-test.cpp
+++ b/src/tests/crypto/deterministic-test.cpp
@@ -15,7 +15,7 @@
using namespace Kazv;
-TEST_CASE("Deterministic constructors of Crypto and OutboundGroupSession", "[crypto][deterministic]")
+TEST_CASE("Deterministic constructors of Crypto", "[crypto][deterministic]")
{
auto rg = RandomInterface{RandomDeviceGenerator{}};
auto random = rg.generateRange<RandomData>(Crypto::constructRandomSize());
@@ -23,14 +23,6 @@
Crypto crypto2(RandomTag{}, random);
REQUIRE(crypto1.toJson() == crypto2.toJson());
-
- random = rg.generateRange<RandomData>(OutboundGroupSession::constructRandomSize());
- auto creationTime = currentTimeMs();
-
- OutboundGroupSession ogs1(RandomTag{}, random, creationTime);
- OutboundGroupSession ogs2(RandomTag{}, random, creationTime);
-
- REQUIRE(nlohmann::json(ogs1) == nlohmann::json(ogs2));
}
TEST_CASE("Deterministic generating of one-time keys", "[crypto][deterministic]")
diff --git a/src/tests/crypto/outbound-group-session-test.cpp b/src/tests/crypto/outbound-group-session-test.cpp
new file mode 100644
--- /dev/null
+++ b/src/tests/crypto/outbound-group-session-test.cpp
@@ -0,0 +1,59 @@
+/*
+ * This file is part of libkazv.
+ * SPDX-FileCopyrightText: 2024 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libkazv-config.hpp>
+#include <catch2/catch_test_macros.hpp>
+#include <outbound-group-session.hpp>
+#include <crypto.hpp>
+#include "crypto-test-resource.hpp"
+
+using namespace Kazv;
+
+static const auto resource = cryptoDumpResource();
+
+TEST_CASE("OutboundGroupSession conversion from libolm to vodozemac")
+{
+ auto sessionJson = resource["a"]["outboundGroupSessions"]["!foo:example.com"];
+ auto session = sessionJson.template get<OutboundGroupSession>();
+ REQUIRE(session.valid());
+ REQUIRE(session.initialSessionKey() == sessionJson["initialSessionKey"]);
+}
+
+TEST_CASE("OutboundGroupSession serialization roundtrip")
+{
+ auto session = OutboundGroupSession(RandomTag{}, genRandomData(OutboundGroupSession::constructRandomSize()), 0);
+ json j = session;
+ auto session2 = j.template get<OutboundGroupSession>();
+ REQUIRE(session2.valid());
+ REQUIRE(session.initialSessionKey() == session2.initialSessionKey());
+ REQUIRE(session.sessionId() == session2.sessionId());
+}
+
+TEST_CASE("OutboundGroupSession::from_json error handling")
+{
+ auto sessionJson = resource["a"]["outboundGroupSessions"]["!foo:example.com"];
+ sessionJson["session"] = "AAAAAAAAAA";
+ auto session = sessionJson.template get<OutboundGroupSession>();
+ REQUIRE(!session.valid());
+}
+
+TEST_CASE("OutboundGroupSession ctor")
+{
+ auto session = OutboundGroupSession();
+ REQUIRE(!session.valid());
+}
+
+TEST_CASE("OutboundGroupSession::encrypt error handling")
+{
+ // invalid utf8 will cause rust::Str to throw
+ // https://stackoverflow.com/questions/1301402/example-invalid-utf8-string
+ std::string plainText = "\xc3\x28";
+ auto session = OutboundGroupSession(RandomTag{}, genRandomData(OutboundGroupSession::constructRandomSize()), 0);
+ auto originalIndex = session.messageIndex();
+ auto res = session.encrypt(plainText);
+ REQUIRE(res.empty());
+ REQUIRE(originalIndex == session.messageIndex());
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 7:57 AM (10 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39559
Default Alt Text
D160.1732550242.diff (13 KB)

Event Timeline