1 #pragma once
2 
3 /// @file
4 /// @brief Various type definitions for the crypto API.
5 
6 #if __has_include(<nlohmann/json_fwd.hpp>)
7 #include <nlohmann/json_fwd.hpp>
8 #else
9 #include <nlohmann/json.hpp>
10 #endif
11 
12 namespace mtx {
13 namespace crypto {
14 //! Constant for ed25519 keys
15 constexpr auto ED25519 = "ed25519";
16 //! Constant for curve25519 keys
17 constexpr auto CURVE25519 = "curve25519";
18 //! Constant for signed curve25519 keys
19 constexpr auto SIGNED_CURVE25519 = "signed_curve25519";
20 //! The algorithm used for group messages.
21 constexpr auto MEGOLM_ALGO = "m.megolm.v1.aes-sha2";
22 
23 //! An exported megolm group session
24 struct ExportedSession
25 {
26     //! Required. The Ed25519 key of the device which initiated the session originally.
27     std::map<std::string, std::string> sender_claimed_keys; // currently unused.
28     //! Required. Chain of Curve25519 keys through which this session was forwarded, via
29     //! m.forwarded_room_key events.
30     std::vector<std::string> forwarding_curve25519_key_chain; // currently unused.
31 
32     //! Required. The encryption algorithm that the session uses. Must be m.megolm.v1.aes-sha2.
33     std::string algorithm = MEGOLM_ALGO;
34     //! Required. The room where the session is used.
35     std::string room_id;
36     //! Required. The Curve25519 key of the device which initiated the session originally.
37     std::string sender_key;
38     //! Required. The ID of the session.
39     std::string session_id;
40     //! Required. The key for the session.
41     std::string session_key;
42 };
43 
44 //! A list of exported sessions.
45 struct ExportedSessionKeys
46 {
47     //! The actual sessions.
48     std::vector<ExportedSession> sessions;
49 };
50 
51 //! A pair of keys connected to an olm account.
52 struct IdentityKeys
53 {
54     //! The identity key.
55     std::string curve25519;
56     //! The signing key.
57     std::string ed25519;
58 };
59 
60 //! A list of one time keys.
61 struct OneTimeKeys
62 {
63     //! The key id type.
64     using KeyId = std::string;
65     //! The type for the keys.
66     using EncodedKey = std::string;
67 
68     //! The one time keys by key id.
69     std::map<KeyId, EncodedKey> curve25519;
70 };
71 
72 void
73 to_json(nlohmann::json &obj, const ExportedSession &s);
74 
75 void
76 from_json(const nlohmann::json &obj, ExportedSession &s);
77 
78 void
79 to_json(nlohmann::json &obj, const ExportedSessionKeys &keys);
80 
81 void
82 from_json(const nlohmann::json &obj, ExportedSessionKeys &keys);
83 
84 void
85 to_json(nlohmann::json &obj, const IdentityKeys &keys);
86 
87 void
88 from_json(const nlohmann::json &obj, IdentityKeys &keys);
89 
90 void
91 to_json(nlohmann::json &obj, const OneTimeKeys &keys);
92 
93 void
94 from_json(const nlohmann::json &obj, OneTimeKeys &keys);
95 
96 template<class T, class Name>
97 class strong_type
98 {
99 public:
100     strong_type() = default;
strong_type(const T & value)101     explicit strong_type(const T &value)
102       : value_(value)
103     {}
strong_type(T && value)104     explicit strong_type(T &&value)
105       : value_(std::forward<T>(value))
106     {}
107 
operator T&()108     operator T &() noexcept { return value_; }
operator const T&() const109     constexpr operator const T &() const noexcept { return value_; }
110 
get()111     T &get() { return value_; }
get() const112     T const &get() const { return value_; }
113 
114 private:
115     T value_;
116 };
117 
118 // Macro for concisely defining a strong type
119 #define STRONG_TYPE(type_name, value_type)                                                         \
120     struct type_name : mtx::crypto::strong_type<value_type, type_name>                             \
121     {                                                                                              \
122         using strong_type::strong_type;                                                            \
123     };
124 
125 } // namespace crypto
126 } // namespace mtx
127 
128 STRONG_TYPE(UserId, std::string)
129 STRONG_TYPE(DeviceId, std::string)
130 STRONG_TYPE(RoomId, std::string)
131