Page MenuHomePhorge

No OneTemporary

Size
33 KB
Referenced Files
None
Subscribers
None
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

Mime Type
text/x-diff
Expires
Fri, Oct 9, 9:51 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1784654
Default Alt Text
(33 KB)

Event Timeline