diff options
Diffstat (limited to 'include/erebos')
-rw-r--r-- | include/erebos/attach.h | 49 | ||||
-rw-r--r-- | include/erebos/identity.h | 1 | ||||
-rw-r--r-- | include/erebos/network.h | 20 | ||||
-rw-r--r-- | include/erebos/pairing.h | 104 | ||||
-rw-r--r-- | include/erebos/storage.h | 9 |
5 files changed, 182 insertions, 1 deletions
diff --git a/include/erebos/attach.h b/include/erebos/attach.h new file mode 100644 index 0000000..14e6af3 --- /dev/null +++ b/include/erebos/attach.h @@ -0,0 +1,49 @@ +#pragma once + +#include <erebos/pairing.h> + +#include <future> +#include <mutex> +#include <optional> +#include <string> +#include <vector> + +namespace erebos { + +using std::mutex; +using std::optional; +using std::promise; +using std::string; +using std::vector; + +struct AttachIdentity; + +class AttachService : public PairingService<AttachIdentity> +{ +public: + AttachService(); + virtual ~AttachService(); + + UUID uuid() const override; + + void attachTo(const Peer &); + +protected: + virtual Stored<AttachIdentity> handlePairingComplete(const Peer &) override; + virtual void handlePairingResult(Context &, Stored<AttachIdentity>) override; + + mutex handlerLock; +}; + +template<class T> class Signed; + +struct AttachIdentity +{ + Stored<Signed<class IdentityData>> identity; + vector<vector<uint8_t>> keys; + + static AttachIdentity load(const Ref &); + Ref store(const Storage &) const; +}; + +} diff --git a/include/erebos/identity.h b/include/erebos/identity.h index 66a4afb..aeddd08 100644 --- a/include/erebos/identity.h +++ b/include/erebos/identity.h @@ -20,6 +20,7 @@ public: std::optional<Identity> owner() const; const Identity & finalOwner() const; + Stored<class PublicKey> keyIdentity() const; Stored<class PublicKey> keyMessage() const; bool sameAs(const Identity &) const; diff --git a/include/erebos/network.h b/include/erebos/network.h index 8f3debe..5a1fca6 100644 --- a/include/erebos/network.h +++ b/include/erebos/network.h @@ -10,10 +10,15 @@ namespace erebos { class Server { + struct Priv; public: Server(const Head<LocalState> &, std::vector<std::unique_ptr<Service>> &&); + Server(const std::shared_ptr<Priv> &); ~Server(); + const Head<LocalState> & localHead() const; + + const Identity & identity() const; template<class S> S & svc(); class PeerList & peerList() const; @@ -22,7 +27,6 @@ public: private: Service & svcHelper(const std::type_info &); - struct Priv; const std::shared_ptr<Priv> p; }; @@ -39,13 +43,27 @@ public: Peer(const std::shared_ptr<Priv> & p); ~Peer(); + Server server() const; + + const Storage & tempStorage() const; + const PartialStorage & partialStorage() const; + std::string name() const; std::optional<Identity> identity() const; bool hasChannel() const; bool send(UUID, const Ref &) const; + bool send(UUID, const Object &) const; + + bool operator==(const Peer & other) const; + bool operator!=(const Peer & other) const; + bool operator<(const Peer & other) const; + bool operator<=(const Peer & other) const; + bool operator>(const Peer & other) const; + bool operator>=(const Peer & other) const; private: + bool send(UUID, const Ref &, const Object &) const; std::shared_ptr<Priv> p; }; diff --git a/include/erebos/pairing.h b/include/erebos/pairing.h new file mode 100644 index 0000000..f0952d8 --- /dev/null +++ b/include/erebos/pairing.h @@ -0,0 +1,104 @@ +#pragma once + +#include <erebos/identity.h> +#include <erebos/network.h> +#include <erebos/service.h> + +#include <future> +#include <map> +#include <mutex> +#include <string> +#include <variant> +#include <vector> + +namespace erebos { + +using std::function; +using std::future; +using std::map; +using std::mutex; +using std::string; +using std::variant; +using std::vector; + +/** + * Template-less base class for the paring functionality that does not depend + * on the result parameter. + */ +class PairingServiceBase : public Service +{ +public: + typedef function<void(const Peer &)> RequestInitHook; + void onRequestInit(RequestInitHook); + + typedef function<future<bool>(const Peer &, string)> ConfirmHook; + void onResponse(ConfirmHook); + void onRequest(ConfirmHook); + + typedef function<void(const Peer &)> RequestNonceFailedHook; + void onRequestNonceFailed(RequestNonceFailedHook); + +protected: + void requestPairing(UUID serviceId, const Peer & peer); + virtual void handle(Context &) override; + virtual Ref handlePairingCompleteRef(const Peer &) = 0; + virtual void handlePairingResult(Context &) = 0; + +private: + static vector<uint8_t> nonceDigest(const Identity & id1, const Identity & id2, + const vector<uint8_t> & nonce1, const vector<uint8_t> & nonce2); + static string confirmationNumber(const vector<uint8_t> &); + void waitForConfirmation(Peer peer, string confirm); + + RequestInitHook requestInitHook; + ConfirmHook responseHook; + ConfirmHook requestHook; + RequestNonceFailedHook requestNonceFailedHook; + + optional<Ref> result; + + enum class StatePhase { + NoPairing, + OurRequest, + OurRequestConfirm, + OurRequestReady, + PeerRequest, + PeerRequestConfirm, + PairingDone, + PairingFailed + }; + + struct State { + StatePhase phase; + vector<uint8_t> nonce; + vector<uint8_t> peerCheck; + }; + + map<Peer, State> peerStates; + mutex stateLock; +}; + +template<class Result> +class PairingService : public PairingServiceBase +{ +protected: + virtual Stored<Result> handlePairingComplete(const Peer &) = 0; + virtual void handlePairingResult(Context &, Stored<Result>) = 0; + + virtual Ref handlePairingCompleteRef(const Peer &) override final; + virtual void handlePairingResult(Context &) override final; +}; + +template<class Result> +Ref PairingService<Result>::handlePairingCompleteRef(const Peer & peer) +{ + return handlePairingComplete(peer).ref(); +} + +template<class Result> +void PairingService<Result>::handlePairingResult(Context & ctx) +{ + handlePairingResult(ctx, Stored<Result>::load(ctx.ref())); +} + +} diff --git a/include/erebos/storage.h b/include/erebos/storage.h index 29eaa8f..4f67a4b 100644 --- a/include/erebos/storage.h +++ b/include/erebos/storage.h @@ -123,6 +123,9 @@ public: explicit operator std::string() const; bool isZero() const; + static Digest of(const std::vector<uint8_t> & content); + template<class S> static Digest of(const ObjectT<S> &); + const std::array<uint8_t, size> & arr() const { return value; } bool operator==(const Digest & other) const { return value == other.value; } @@ -136,6 +139,12 @@ private: std::array<uint8_t, size> value; }; +template<class S> +Digest Digest::of(const ObjectT<S> & obj) +{ + return Digest::of(obj.encode()); +} + class PartialRef { public: |