-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSecureSession.h
More file actions
109 lines (95 loc) · 4.11 KB
/
SecureSession.h
File metadata and controls
109 lines (95 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#pragma once
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <map>
#include <tev-cpp/Tev.h>
#include <js-style-co-routine/AsyncGenerator.h>
#include <js-style-co-routine/Promise.h>
#include "network/IConnection.h"
#include "network/IServer.h"
#include "CallerId.h"
#include "cipher/ChaCha20Poly1305.h"
#include "cipher/EcdhePsk.h"
#include "cipher/FakeCredentialGenerator.h"
#include "cipher/BruteForceLimiter.h"
#include "common/Cache.h"
#include "IMessageCodec.h"
namespace TUI::Application::SecureSession
{
class Server;
class Connection : public Network::IConnection<CallerId>
{
friend class Server;
public:
~Connection() override;
Connection(const Connection&) = delete;
Connection& operator=(const Connection&) = delete;
Connection(Connection&&) = delete;
Connection& operator=(Connection&&) = delete;
void Close() override;
bool IsClosed() const noexcept override;
void Send(std::vector<std::uint8_t> message) override;
JS::Promise<std::optional<std::vector<std::uint8_t>>> ReceiveAsync() override;
CallerId GetId() const override;
private:
Connection(
std::shared_ptr<Network::IConnection<void>> connection,
const CallerId& callerId,
std::function<void(CallerId)> onClose,
const std::vector<std::shared_ptr<IMessageCodec>>& messageCodecs);
std::shared_ptr<Network::IConnection<void>> _connection;
CallerId _callerId;
std::function<void(CallerId)> _onClose;
bool _closed{false};
std::vector<std::shared_ptr<IMessageCodec>> _messageCodecs{};
};
class Server : public Network::IServer<CallerId>, public std::enable_shared_from_this<Server>
{
public:
/** 10 seconds */
static constexpr uint64_t AUTH_TIMEOUT_MS = 10 * 1000;
/** 5 minutes */
static constexpr uint64_t RESUMPTION_KEY_TIMEOUT_MS = 5 * 60 * 1000;
using GetUserCredentialFunc = std::function<std::optional<std::pair<std::string, Common::Uuid>>(const std::string&)>;
enum class ProtocolType : uint8_t
{
Password = 0,
Psk = 1,
};
static std::shared_ptr<Network::IServer<CallerId>> Create(
Tev& tev,
std::shared_ptr<Network::IServer<void>> server,
GetUserCredentialFunc getUserCredential,
const std::vector<std::shared_ptr<IMessageCodec>>& messageCodecs = {});
~Server() override;
Server(const Server&) = delete;
Server& operator=(const Server&) = delete;
Server(Server&&) = delete;
Server& operator=(Server&&) = delete;
void Close() override;
bool IsClosed() const noexcept override;
JS::Promise<std::optional<std::shared_ptr<Network::IConnection<CallerId>>>> AcceptAsync() override;
private:
Tev& _tev;
std::shared_ptr<Network::IServer<void>> _server;
std::function<std::optional<std::pair<std::string, Common::Uuid>>(const std::string&)> _getUserCredential;
JS::AsyncGenerator<std::shared_ptr<Network::IConnection<CallerId>>> _connectionGenerator{};
std::map<std::string, std::pair<Cipher::EcdhePsk::Psk, CallerId>> _sessionResumptionKeys{};
std::map<std::string, Tev::Timeout> _resumptionKeyTimeouts{};
std::unordered_map<CallerId, std::shared_ptr<Connection>> _connections{};
bool _closed{false};
Cipher::FakeCredentialGenerator _fakeCredentialGenerator{10000};
/** 5 trials per window, 5 min to 6 hours of lock out time. */
Cipher::BruteForceLimiter _bruteForceLimiter{5, 5 * 60 * 1000, 6 * 60 * 60 * 1000};
std::vector<std::shared_ptr<IMessageCodec>> _messageCodecs{};
Server(
Tev& tev,
std::shared_ptr<Network::IServer<void>> server,
GetUserCredentialFunc getUserCredential,
const std::vector<std::shared_ptr<IMessageCodec>>& messageCodecs);
JS::Promise<void> HandleRawConnections();
JS::Promise<void> HandleHandshakeAsync(std::shared_ptr<Network::IConnection<void>> connection);
};
}