Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F112199
D160.1732277055.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D160.1732277055.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 22, 4:04 AM (14 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38689
Default Alt Text
D160.1732277055.diff (13 KB)
Attached To
Mode
D160: Port OutboundGroupsession to vodozemac
Attached
Detach File
Event Timeline
Log In to Comment