Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85803628
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
33 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/crypto/verification-process.cpp b/src/crypto/verification-process.cpp
index a9143e5..a68cd75 100644
--- a/src/crypto/verification-process.cpp
+++ b/src/crypto/verification-process.cpp
@@ -1,25 +1,49 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <olm/sas.h>
#include "verification-process.hpp"
namespace Kazv
{
std::size_t SASVerificationProcess::constructRandomSize()
{
static std::size_t size = [] {
auto sas = ByteArray(olm_sas_size(), 0);
auto sasPointer = olm_sas(sas.data());
return olm_create_sas_random_length(sasPointer);
}();
return size;
}
+
+ struct SASVerificationProcess::Private
+ {
+ };
+
+
+ SASVerificationProcess::~SASVerificationProcess() = default;
+
+ struct VerificationProcess::Private
+ {
+ };
+
+ VerificationProcess::VerificationProcess()
+ : m_d(new Private)
+ {}
+
+ VerificationProcess::VerificationProcess(ToDeviceTag, Timestamp ts, std::string txnId, immer::flex_vector<std::string> methods)
+ : m_d(new Private)
+ {
+ }
+
+ KAZV_DEFINE_COPYABLE_UNIQUE_PTR(VerificationProcess, m_d)
+
+ VerificationProcess::~VerificationProcess() = default;
}
diff --git a/src/crypto/verification-process.hpp b/src/crypto/verification-process.hpp
index c376613..9d1a857 100644
--- a/src/crypto/verification-process.hpp
+++ b/src/crypto/verification-process.hpp
@@ -1,134 +1,163 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <libkazv-config.hpp>
#include <immer/flex_vector.hpp>
#include <nlohmann/json.hpp>
#include <copy-helper.hpp>
+#include <event.hpp>
#include "crypto-util.hpp"
namespace Kazv
{
class SASVerificationProcess
{
public:
/**
* The initiator of the process.
*
* The one who sends the m.key.verification.start event is considered the initiator.
*
* The other party than the initiator will send a commitment hash.
*/
enum Initiator
{
Us,
Them
};
/**
* Indicate to create an incoming process.
*
* A process is incoming iff. the initiator is us.
*/
struct IncomingTag {};
/**
* Indicate to create an outgoing process.
*
* A process in outgoing iff. the initiator is them.
*/
struct OutgoingTag {};
inline static immer::flex_vector<std::string> defaultShortAuthenticationString = {"emoji", "decimal"};
/**
* The random size needed to construct an instance.
*/
static std::size_t constructRandomSize();
/**
* Construct an empty SASVerificationProcess.
*/
SASVerificationProcess();
/**
* Construct an incoming SASVerificationProcess using provided random data to
* generate an ephemeral key pair.
*
* @param random The random data to generate the key pair.
* @param event The `m.key.verification.start` event json we received from the other party.
* @param shortAuthenticationString The type of short authentication strings this client can accept.
* Default to both emoji and decimal.
*/
SASVerificationProcess(RandomTag, IncomingTag, RandomData random,
const nlohmann::json &event,
immer::flex_vector<std::string> shortAuthenticationString = defaultShortAuthenticationString);
/**
* Construct an outgoing SASVerificationProcess using provided random data to
* generate an ephemeral key pair.
*
* @param random The random data to generate the key pair.
* @param shortAuthenticationString The type of short authentication strings this client can accept.
* Default to both emoji and decimal.
*/
SASVerificationProcess(RandomTag, OutgoingTag, RandomData random,
immer::flex_vector<std::string> shortAuthenticationString = defaultShortAuthenticationString);
KAZV_DECLARE_COPYABLE(SASVerificationProcess)
~SASVerificationProcess();
/**
* Check whether this is valid.
*
* One constructed from the defualt constructor is invalid.
* One copy- or move-constructed from an invalid object is invalid.
* All other `SASVerificationProcess`es are valid.
*
* @return Whether this is valid.
*/
bool valid() const;
// immer::flex_vector<std::string> hashes() const;
// std::string selectedHash() const;
// immer::flex_vector<std::string> keyAgreementProtocols() const;
// std::string selectedKeyAgreementProtocols() const;
// immer::flex_vector<std::string> shortAuthenticationString() const;
// std::string ourKey() const;
// std::string theirKey() const;
Initiator initiator() const;
// std::string ourCommitment() const;
// std::string theirCommitment() const;
std::string setTheirCommitment();
/**
* Get the json of the m.verification.start event to send.
* Only available if this is outgoing.
*
* @return The json of the m.verification.start event to send.
*/
nlohmann::json startEvent() const;
private:
struct Private;
std::unique_ptr<Private> m_d;
};
+
+ class VerificationProcess
+ {
+ public:
+ struct ToDeviceTag {};
+
+ struct ToRoomTag {};
+
+ VerificationProcess();
+
+ /**
+ * Construct a VerificationProcess that is to send via a to-device message.
+ */
+ VerificationProcess(ToDeviceTag, Timestamp ts, std::string txnId, immer::flex_vector<std::string> methods);
+
+ KAZV_DECLARE_COPYABLE(VerificationProcess)
+
+ ~VerificationProcess();
+
+ /**
+ * The methods this process supports.
+ */
+ immer::flex_vector<std::string> methods() const;
+
+ private:
+ struct Private;
+ std::unique_ptr<Private> m_d;
+ };
}
diff --git a/src/crypto/verification-tracker.cpp b/src/crypto/verification-tracker.cpp
index 59769a9..8696e29 100644
--- a/src/crypto/verification-tracker.cpp
+++ b/src/crypto/verification-tracker.cpp
@@ -1,133 +1,284 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <algorithm>
#include <immer/set.hpp>
#include <types.hpp>
#include <debug.hpp>
#include "verification-tracker.hpp"
#include "verification-process.hpp"
namespace Kazv
{
+ using namespace VerificationTrackerActions;
+ using TrackerAct = VerificationTrackerAction;
+ using TrackerRes = VerificationTrackerResult;
+
static const auto supportedVerificationMethods =
immer::set<std::string>{}.insert("m.sas.v1");
static bool methodSupported(immer::flex_vector<std::string> methods)
{
return std::any_of(methods.begin(), methods.end(),
[](auto method) { return supportedVerificationMethods.count(method); });
}
static std::string idealMethod(immer::flex_vector<std::string> /* methods */)
{
return "m.sas.v1";
}
static std::size_t processRequestRandomSize(std::string method)
{
if (method == "m.sas.v1") {
return SASVerificationProcess::constructRandomSize();
}
return 0;
}
static std::size_t processStartRandomSize(std::string method)
{
if (method == "m.sas.v1") {
return SASVerificationProcess::constructRandomSize();
}
return 0;
}
static bool isEventWellFormed(const nlohmann::json &event)
{
return event.is_object()
&& event.contains("content")
&& event["content"].is_object()
&& event.contains("type")
&& event["type"].is_string()
- && (event["content"].contains("transaction_id")
- && event["content"]["transaction_id"].is_string());
+ && event["content"].contains("from_device")
+ && event["content"]["from_device"].is_string()
+ && (
+ event["content"].contains("transaction_id")
+ && event["content"]["transaction_id"].is_string()
+ );
+ }
+
+ namespace
+ {
+ enum CheckStatus
+ {
+ Ok,
+ NotOfType,
+ NotWellFormed
+ };
+ }
+
+ static CheckStatus isRequest(const nlohmann::json &event)
+ {
+ if (!(event["type"].template get<std::string>() == "m.key.verification.request")) {
+ return NotOfType;
+ }
+
+ if (!(event["content"].contains("methods") && event["content"]["methods"].is_array())) {
+ kzo.crypto.dbg() << "methods not an array" << std::endl;
+ return NotWellFormed;
+ }
+
+ return Ok;
+ }
+
+ static CheckStatus isReady(const nlohmann::json &event)
+ {
+ if (!(event["type"].template get<std::string>() == "m.key.verification.ready")) {
+ return NotOfType;
+ }
+
+ if (!(event["content"].contains("methods") && event["content"]["methods"].is_array())) {
+ kzo.crypto.dbg() << "methods not an array" << std::endl;
+ return NotWellFormed;
+ }
+
+ return Ok;
+ }
+
+ using Methods = immer::flex_vector<std::string>;
+
+ static Methods methodsForEvent(const nlohmann::json &event)
+ {
+ return event["content"]["methods"]
+ .template get<immer::flex_vector<std::string>>();
}
struct VerificationTracker::Private
{
+ std::string userId;
+ std::string deviceId;
+
+ using ProcessMap = immer::map<std::string, immer::map<std::string, VerificationProcess>>;
+
+ ProcessMap processes;
+
+ nlohmann::json makeEvent(std::string type, Timestamp ts, std::string txnId, nlohmann::json content) const;
+ std::string nextTxnId(Timestamp ts);
+ bool hasExistingProcessForIncomingEvent(const nlohmann::json &event) const;
+ void addProcess(std::string userId, immer::flex_vector<std::string> deviceIds, VerificationProcess process);
+ void removeProcess(std::string userId, immer::flex_vector<std::string> deviceIds);
};
+ nlohmann::json VerificationTracker::Private::makeEvent(std::string type, Timestamp ts, std::string txnId, nlohmann::json content) const
+ {
+ auto ev = nlohmann::json{
+ {"type", type},
+ {"content", content}
+ };
+
+ ev["content"]["from_device"] = deviceId;
+ ev["content"]["timestamp"] = ts;
+ ev["content"]["transaction_id"] = txnId;
+
+ return ev;
+ }
+
+ std::string VerificationTracker::Private::nextTxnId(Timestamp ts)
+ {
+ return std::to_string(ts);
+ }
+
VerificationTracker::VerificationTracker()
+ : m_d(new Private{})
{
}
VerificationTracker::VerificationTracker(std::string userId, std::string deviceId)
+ : m_d(new Private{userId, deviceId, {}})
{
}
KAZV_DEFINE_COPYABLE_UNIQUE_PTR(VerificationTracker, m_d);
- VerificationTracker::~VerificationTracker()
- {
- }
+ VerificationTracker::~VerificationTracker() = default;
std::size_t VerificationTracker::processRandomSize(const nlohmann::json &event)
{
if (!isEventWellFormed(event)) {
return 0;
}
kzo.crypto.dbg() << "event: " << event.dump() << std::endl;
- if (event["type"].template get<std::string>() == "m.key.verification.request") {
- if (!(event["content"].contains("methods") && event["content"]["methods"].is_array())) {
- kzo.crypto.dbg() << "methods not an array" << std::endl;
- return 0;
- }
+ auto checkRequestRes = isRequest(event);
+ if (checkRequestRes == NotWellFormed) {
+ return 0;
+ }
- auto methods = event["content"]["methods"]
- .template get<immer::flex_vector<std::string>>();
+ if (checkRequestRes != NotOfType) {
+ auto methods = methodsForEvent(event);
if (methodSupported(methods)) {
kzo.crypto.dbg() << "methods supported" << std::endl;
return processRequestRandomSize(idealMethod(methods));
}
kzo.crypto.dbg() << "methods not supported" << std::endl;
+
return 0;
}
if (event["type"].template get<std::string>() == "m.key.verification.start") {
if (!(event["content"].contains("method") && event["content"]["method"].is_string())) {
return 0;
}
auto method = event["content"]["method"]
.template get<std::string>();
if (methodSupported({ method })) {
return processStartRandomSize(method);
}
return 0;
}
return 0;
}
- VerificationTrackerResult VerificationTracker::process(const nlohmann::json &event, RandomData random, Timestamp ts)
+ VerificationTrackerResult VerificationTracker::process(std::string theirUserId, const nlohmann::json &event, RandomData random, Timestamp ts)
{
+ auto sendCancel = TrackerRes{}; // TODO
+ if (!isEventWellFormed(event)) {
+ return sendCancel;
+ }
+
+ // Process request event
+ auto checkRequestRes = isRequest(event);
+ if (checkRequestRes != NotOfType) {
+ if (checkRequestRes == NotWellFormed) {
+ return sendCancel;
+ }
+
+ auto methods = event["content"]["methods"]
+ .template get<immer::flex_vector<std::string>>();
+ if (!methodSupported(methods)) {
+ kzo.crypto.warn() << "We do not support any methods provided." << std::endl;
+ return sendCancel;
+ }
+
+ auto methodToUse = idealMethod(methods);
+ kzo.crypto.dbg() << "choosing method: " << methodToUse << std::endl;
+
+ auto theirDeviceId = event["content"]["from_device"].template get<std::string>();
+
+ // TODO: add a new process to the tracker
+ auto notifyAction = TrackerAct{ShowStatus{theirUserId, theirDeviceId, ShowStatus::Status::Requested}};
+
+ auto sendReadyAction = TrackerAct{SendEvent{
+ theirUserId,
+ { theirDeviceId },
+ m_d->makeEvent(
+ "m.key.verification.ready",
+ ts,
+ m_d->nextTxnId(ts),
+ nlohmann::json::object({{"methods", nlohmann::json::array({ methodToUse })}})
+ )
+ }};
+
+ // TODO: send a real start event for the method
+
+ auto sendStartAction = TrackerAct{SendEvent{
+ theirUserId,
+ { theirDeviceId },
+ m_d->makeEvent(
+ "m.key.verification.start",
+ ts,
+ m_d->nextTxnId(ts),
+ nlohmann::json::object({{"methods", nlohmann::json::array({ methodToUse })}})
+ )
+ }};
+
+ return TrackerRes{notifyAction, sendReadyAction, sendStartAction};
+ }
+
+
return {};
}
VerificationTrackerResult VerificationTracker::requestVerification(
std::string userId, immer::flex_vector<std::string> deviceIds, Timestamp ts)
{
- return {};
+ auto sendEventAction = TrackerAct(SendEvent{
+ userId,
+ deviceIds,
+ m_d->makeEvent(
+ "m.key.verification.request",
+ ts,
+ m_d->nextTxnId(ts),
+ nlohmann::json::object({{"methods", supportedVerificationMethods}})
+ )
+ });
+
+ return TrackerRes{sendEventAction};
}
}
diff --git a/src/crypto/verification-tracker.hpp b/src/crypto/verification-tracker.hpp
index c8d7de6..d9c7f76 100644
--- a/src/crypto/verification-tracker.hpp
+++ b/src/crypto/verification-tracker.hpp
@@ -1,104 +1,106 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <libkazv-config.hpp>
#include <immer/flex_vector.hpp>
#include <nlohmann/json.hpp>
#include <copy-helper.hpp>
#include <event.hpp>
#include "crypto-util.hpp"
namespace Kazv
{
namespace VerificationTrackerActions
{
struct SendEvent
{
std::string userId;
immer::flex_vector<std::string> deviceIds;
nlohmann::json event;
};
struct DisplayCodes
{
std::string emojiCode;
std::string decimalCode;
};
struct ShowStatus
{
enum Status
{
Cancelled,
Verified,
- VerificationFailed
+ VerificationFailed,
+ Requested
};
std::string userId;
std::string deviceId;
Status status;
};
}
using VerificationTrackerAction =
std::variant<VerificationTrackerActions::SendEvent,
VerificationTrackerActions::DisplayCodes,
VerificationTrackerActions::ShowStatus>;
using VerificationTrackerResult = immer::flex_vector<VerificationTrackerAction>;
class VerificationTracker
{
public:
/**
* Construct an invalid verification tracker.
*/
VerificationTracker();
/**
* Construct an verification tracker for a specific device.
*
* @param userId The user id for the current user.
* @param deviceId the device id for the current device.
*/
VerificationTracker(std::string userId, std::string deviceId);
KAZV_DECLARE_COPYABLE(VerificationTracker);
~VerificationTracker();
/**
* @return The random size needed for process().
*/
static std::size_t processRandomSize(const nlohmann::json &event);
/**
* Process the event.
*
+ * @param userId The user id of the sender of the event.
* @param event A json of the m.key.verification.* event.
* @param random Random data needed to process the event.
* @param ts The current timestamp.
*/
- VerificationTrackerResult process(const nlohmann::json &event, RandomData random, Timestamp ts);
+ VerificationTrackerResult process(std::string userId, const nlohmann::json &event, RandomData random, Timestamp ts);
/**
* Create a new verification request.
*
* @param userId The user id of the user to verify.
* @param deviceIds The device ids of the devices to verify.
* @param ts The current timestamp.
*/
VerificationTrackerResult requestVerification(std::string userId, immer::flex_vector<std::string> deviceIds, Timestamp ts);
private:
struct Private;
std::unique_ptr<Private> m_d;
};
}
diff --git a/src/tests/crypto/verification-process-test.cpp b/src/tests/crypto/verification-process-test.cpp
index dad32d8..c7f250e 100644
--- a/src/tests/crypto/verification-process-test.cpp
+++ b/src/tests/crypto/verification-process-test.cpp
@@ -1,384 +1,387 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <catch2/catch.hpp>
#include <iostream>
#include <verification-process.hpp>
#include <verification-tracker.hpp>
using namespace Kazv;
// Taken from https://matrix.org/docs/spec/client_server/r0.6.1
static auto requestEvent = R"({
"content": {
"from_device": "AliceDevice2",
"methods": [
"m.sas.v1"
],
"timestamp": 1559598944869,
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.request"
})"_json;
static auto requestEventUnsupportedMethod = R"({
"content": {
"from_device": "AliceDevice2",
"methods": [
"moe.kazv.mxc.fake-method"
],
"timestamp": 1559598944869,
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.request"
})"_json;
static auto requestEventMultiMethods = R"({
"content": {
"from_device": "AliceDevice2",
"methods": [
"m.sas.v1",
"moe.kazv.mxc.fake-method"
],
"timestamp": 1559598944869,
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.request"
})"_json;
static auto startEvent = R"({
"content": {
"from_device": "BobDevice1",
"method": "m.sas.v1",
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.start"
})"_json;
static auto startEventUnsupportedMethod = R"({
"content": {
"from_device": "BobDevice1",
"method": "moe.kazv.mxc.fake-method",
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.start"
})"_json;
static auto cancelEvent = R"({
"content": {
"code": "m.user",
"reason": "User rejected the key verification request",
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.cancel"
})"_json;
static auto sasStartEvent = R"({
"content": {
"from_device": "BobDevice1",
"hashes": [
"sha256"
],
"key_agreement_protocols": [
"curve25519"
],
"message_authentication_codes": [
"hkdf-hmac-sha256"
],
"method": "m.sas.v1",
"short_authentication_string": [
"decimal",
"emoji"
],
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.start"
})"_json;
static auto sasAcceptEvent = R"({
"content": {
"commitment": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg",
"hash": "sha256",
"key_agreement_protocol": "curve25519",
"message_authentication_code": "hkdf-hmac-sha256",
"method": "m.sas.v1",
"short_authentication_string": [
"decimal",
"emoji"
],
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.accept"
})"_json;
static auto sasKeyEvent = R"({
"content": {
"key": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg",
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.key"
})"_json;
static auto sasMacEvent = R"({
"content": {
"keys": "2Wptgo4CwmLo/Y8B8qinxApKaCkBG2fjTWB7AbP5Uy+aIbygsSdLOFzvdDjww8zUVKCmI02eP9xtyJxc/cLiBA",
"mac": {
"ed25519:ABCDEF": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
},
"transaction_id": "S0meUniqueAndOpaqueString"
},
"type": "m.key.verification.mac"
})"_json;
static auto unknownEvent = R"({
"content": {
"transaction_id": "xxx"
},
"type": "moe.kazv.mxc.key.verification.unknown"
})"_json;
static auto malformedEvent = R"({
"type": "moe.kazv.mxc.key.verification.unknown"
})"_json;
static bool displays(const VerificationTrackerAction &action)
{
return
std::holds_alternative<VerificationTrackerActions::DisplayCodes>(action)
|| std::holds_alternative<VerificationTrackerActions::ShowStatus>(action);
}
static bool displaysCode(const VerificationTrackerAction &action)
{
return std::holds_alternative<VerificationTrackerActions::DisplayCodes>(action);
}
static bool displaysNothing(VerificationTrackerResult res)
{
return std::all_of(res.begin(), res.end(), [](const auto &action) {
return !displays(action);
});
}
static bool sendsEventOfType(VerificationTrackerResult res, std::string type)
{
return std::any_of(res.begin(), res.end(), [=](const auto &action) {
return std::holds_alternative<VerificationTrackerActions::SendEvent>(action)
&& std::get<VerificationTrackerActions::SendEvent>(action)
.event
.at("type")
.template get<std::string>() == type;
});
}
static bool sendsCancellation(VerificationTrackerResult res)
{
return sendsEventOfType(res, "m.key.verification.cancel");
}
static bool sendsRequest(VerificationTrackerResult res)
{
return sendsEventOfType(res, "m.key.verification.request");
}
static bool sendsStart(VerificationTrackerResult res)
{
return sendsEventOfType(res, "m.key.verification.start");
}
static bool sendsAccept(VerificationTrackerResult res)
{
return sendsEventOfType(res, "m.key.verification.accept");
}
static bool sendsKey(VerificationTrackerResult res)
{
return sendsEventOfType(res, "m.key.verification.key");
}
static bool sendsMac(VerificationTrackerResult res)
{
return sendsEventOfType(res, "m.key.verification.mac");
}
static nlohmann::json firstEventSent(VerificationTrackerResult res)
{
auto it = std::find_if(res.begin(), res.end(), [](const auto &action) {
return std::holds_alternative<VerificationTrackerActions::SendEvent>(action);
});
return std::get<VerificationTrackerActions::SendEvent>(*it).event;
}
static bool sendsNothing(VerificationTrackerResult res)
{
return std::all_of(res.begin(), res.end(), [](const auto &action) {
return !std::holds_alternative<VerificationTrackerActions::SendEvent>(action);
});
}
// TEST_CASE("Construct sas verification process", "[client][verification-proc]")
// {
// auto proc1 = SASVerificationProcess();
// REQUIRE(!proc1.valid());
// auto proc2 = SASVerificationProcess(RandomTag{}, );
// }
TEST_CASE("VerificationTracker is a value type", "[client][verification-proc]")
{
auto tracker = VerificationTracker{};
auto tracker2 = tracker;
(void) tracker2;
auto tracker3 = std::move(tracker);
(void) tracker3;
}
TEST_CASE("VerificationTracker processRandomSize", "[client][verification-proc]")
{
auto sasConstructRandomSize = SASVerificationProcess::constructRandomSize();
REQUIRE(sasConstructRandomSize != 0);
REQUIRE(VerificationTracker::processRandomSize(requestEvent) == sasConstructRandomSize);
REQUIRE(VerificationTracker::processRandomSize(requestEventUnsupportedMethod) == 0);
REQUIRE(VerificationTracker::processRandomSize(requestEventMultiMethods) == sasConstructRandomSize);
REQUIRE(VerificationTracker::processRandomSize(startEvent) == sasConstructRandomSize);
REQUIRE(VerificationTracker::processRandomSize(sasStartEvent) == sasConstructRandomSize);
REQUIRE(VerificationTracker::processRandomSize(startEventUnsupportedMethod) == 0);
REQUIRE(VerificationTracker::processRandomSize(cancelEvent) == 0);
REQUIRE(VerificationTracker::processRandomSize(sasAcceptEvent) == 0);
REQUIRE(VerificationTracker::processRandomSize(sasKeyEvent) == 0);
REQUIRE(VerificationTracker::processRandomSize(sasMacEvent) == 0);
REQUIRE(VerificationTracker::processRandomSize(unknownEvent) == 0);
REQUIRE(VerificationTracker::processRandomSize(malformedEvent) == 0);
}
TEST_CASE("VerificationTracker process() error handling", "[client][verification-proc]")
{
auto reqRandomSize = VerificationTracker::processRandomSize(requestEvent);
auto random = genRandomData(reqRandomSize);
auto tracker = VerificationTracker{};
auto afterReasonablyShortTime = requestEvent["content"]["timestamp"].template get<Timestamp>() + 1;
+ auto uid = std::string("@u:a.b");
WHEN ("processing a request way long ago") {
auto afterTenMins = requestEvent["content"]["timestamp"].template get<Timestamp>() + 10 * 60 * 1000 + 1;
- auto res = tracker.process(requestEvent, random, afterTenMins);
+ auto res = tracker.process(uid, requestEvent, random, afterTenMins);
THEN ("we should ignore and send cancellation") {
REQUIRE(displaysNothing(res));
REQUIRE(sendsCancellation(res));
}
}
WHEN ("processing a request way in the future") {
auto beforeFiveMins = requestEvent["content"]["timestamp"].template get<Timestamp>() - 5 * 60 * 1000 - 1;
- auto res = tracker.process(requestEvent, random, beforeFiveMins);
+ auto res = tracker.process(uid, requestEvent, random, beforeFiveMins);
THEN ("we should ignore and send cancellation") {
REQUIRE(displaysNothing(res));
REQUIRE(sendsCancellation(res));
}
}
WHEN ("processing a non-request, non-cancel event whose transaction id is never encountered") {
- auto res = tracker.process(sasAcceptEvent, random, afterReasonablyShortTime);
+ auto res = tracker.process(uid, sasAcceptEvent, random, afterReasonablyShortTime);
THEN ("we should ignore and send cancellation") {
REQUIRE(displaysNothing(res));
REQUIRE(sendsCancellation(res));
}
}
WHEN ("processing a cancel event whose transaction id is never encountered") {
- auto res = tracker.process(cancelEvent, random, afterReasonablyShortTime);
+ auto res = tracker.process(uid, cancelEvent, random, afterReasonablyShortTime);
THEN ("we should ignore only") {
REQUIRE(displaysNothing(res));
REQUIRE(sendsNothing(res));
}
}
}
TEST_CASE("VerificationTracker full process", "[client][verification-proc]")
{
- auto alice = VerificationTracker("@alice:example.org", "AliceDevice1");
- auto bob = VerificationTracker("@bob:example.org", "BobDevice1");
+ auto aliceUid = std::string("@alice:example.org");
+ auto bobUid = std::string("@bob:example.org");
+ auto alice = VerificationTracker(aliceUid, "AliceDevice1");
+ auto bob = VerificationTracker(bobUid, "BobDevice1");
auto ts = 1000;
- auto requestRes = alice.requestVerification("@bob:example.org", {"BobDevice1"}, ts);
+ auto requestRes = alice.requestVerification(bobUid, {"BobDevice1"}, ts);
THEN ("Alice should send a request event and notify") {
REQUIRE(sendsRequest(requestRes));
}
auto requestEvent = firstEventSent(requestRes);
- auto processRequestRes = bob.process(requestEvent,
+ auto processRequestRes = bob.process(aliceUid, requestEvent,
genRandomData(VerificationTracker::processRandomSize(requestEvent)), ts);
THEN ("Bob should notify first and start sas") {
REQUIRE(displays(processRequestRes.at(0)));
REQUIRE(sendsStart(processRequestRes));
}
auto startEvent = firstEventSent(processRequestRes);
- auto processStartRes = alice.process(startEvent,
+ auto processStartRes = alice.process(bobUid, startEvent,
genRandomData(VerificationTracker::processRandomSize(startEvent)), ts);
THEN ("Alice should notify first and accept sas") {
REQUIRE(displays(processStartRes.at(0)));
REQUIRE(sendsAccept(processStartRes));
}
auto acceptEvent = firstEventSent(processStartRes);
- auto processAcceptRes = bob.process(acceptEvent,
+ auto processAcceptRes = bob.process(aliceUid, acceptEvent,
genRandomData(VerificationTracker::processRandomSize(acceptEvent)), ts);
THEN ("Bob should notify and send key") {
REQUIRE(!displaysNothing(processAcceptRes));
REQUIRE(sendsKey(processAcceptRes));
}
auto bobKeyEvent = firstEventSent(processAcceptRes);
- auto aliceProcessKeyRes = alice.process(bobKeyEvent,
+ auto aliceProcessKeyRes = alice.process(bobUid, bobKeyEvent,
genRandomData(VerificationTracker::processRandomSize(bobKeyEvent)), ts);
THEN ("Alice should send key and display code") {
REQUIRE(!displaysNothing(aliceProcessKeyRes));
REQUIRE(sendsKey(aliceProcessKeyRes));
}
auto aliceKeyEvent = firstEventSent(aliceProcessKeyRes);
- auto bobProcessKeyRes = bob.process(aliceKeyEvent,
+ auto bobProcessKeyRes = bob.process(aliceUid, aliceKeyEvent,
genRandomData(VerificationTracker::processRandomSize(aliceKeyEvent)), ts);
THEN ("Bob should display code first and send mac") {
REQUIRE(displaysCode(bobProcessKeyRes.at(0)));
REQUIRE(sendsMac(bobProcessKeyRes));
}
auto bobMacEvent = firstEventSent(bobProcessKeyRes);
- auto aliceProcessMacRes = alice.process(bobMacEvent,
+ auto aliceProcessMacRes = alice.process(bobUid, bobMacEvent,
genRandomData(VerificationTracker::processRandomSize(bobMacEvent)), ts);
THEN ("Alice should send mac and show success") {
REQUIRE(sendsMac(aliceProcessMacRes));
REQUIRE(!displaysNothing(aliceProcessMacRes));
}
auto aliceMacEvent = firstEventSent(aliceProcessMacRes);
- auto bobProcessMacRes = bob.process(aliceMacEvent,
+ auto bobProcessMacRes = bob.process(aliceUid, aliceMacEvent,
genRandomData(VerificationTracker::processRandomSize(aliceMacEvent)), ts);
THEN ("Bob should show success") {
REQUIRE(sendsNothing(bobProcessMacRes));
REQUIRE(!displaysNothing(bobProcessMacRes));
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Oct 9, 9:51 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1784654
Default Alt Text
(33 KB)
Attached To
Mode
rL libkazv
Attached
Detach File
Event Timeline
Log In to Comment