summary refs log tree commit diff
path: root/src/CacheCryptoStructs.h
blob: ee352c6b4fe40aea8acaad799d61b1a7e321629f (plain) (blame)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// SPDX-FileCopyrightText: 2021 Nheko Contributors
// SPDX-FileCopyrightText: 2022 Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QObject>

#include <map>
#include <mutex>
#include <set>

#include <mtx/events/encrypted.hpp>
#include <mtx/responses/crypto.hpp>
#include <mtxclient/crypto/objects.hpp>

namespace crypto {
Q_NAMESPACE
//! How much a participant is trusted.
enum Trust
{
    Unverified, //! Device unverified or master key changed.
    TOFU,       //! Device is signed by the sender, but the user is not verified, but they never
                //! changed the master key.
    Verified,   //! User was verified and has crosssigned this device or device is verified.
};
Q_ENUM_NS(Trust)
}

struct DeviceKeysToMsgIndex
{
    // map from device key to message_index
    // Using the device id is safe because we check for reuse on device list updates
    // Using the device id makes our logic much easier to read.
    std::map<std::string, uint64_t> deviceids;
};

struct SharedWithUsers
{
    // userid to keys
    std::map<std::string, DeviceKeysToMsgIndex> keys;
};

// Extra information associated with an outbound megolm session.
struct GroupSessionData
{
    uint64_t message_index = 0;
    uint64_t timestamp     = 0;

    // If we got the session via key sharing or forwarding, we can usually trust it.
    // If it came from asymmetric key backup, it is not trusted.
    // TODO(Nico): What about forwards? They might come from key backup?
    bool trusted = true;

    std::string sender_claimed_ed25519_key;
    std::vector<std::string> forwarding_curve25519_key_chain;

    //! map from index to event_id to check for replay attacks
    std::map<uint32_t, std::string> indices;

    // who has access to this session.
    // Rotate, when a user leaves the room and share, when a user gets added.
    SharedWithUsers currently;
};

void
to_json(nlohmann::json &obj, const GroupSessionData &msg);
void
from_json(const nlohmann::json &obj, GroupSessionData &msg);

struct OutboundGroupSessionDataRef
{
    mtx::crypto::OutboundGroupSessionPtr session;
    GroupSessionData data;
};

struct DevicePublicKeys
{
    std::string ed25519;
    std::string curve25519;
};

void
to_json(nlohmann::json &obj, const DevicePublicKeys &msg);
void
from_json(const nlohmann::json &obj, DevicePublicKeys &msg);

//! Represents a unique megolm session identifier.
struct MegolmSessionIndex
{
    MegolmSessionIndex() = default;
    MegolmSessionIndex(std::string room_id_, const mtx::events::msg::Encrypted &e)
      : room_id(std::move(room_id_))
      , session_id(e.session_id)
      , sender_key(e.sender_key)
    {}

    //! The room in which this session exists.
    std::string room_id;
    //! The session_id of the megolm session.
    std::string session_id;
    //! The curve25519 public key of the sender.
    std::string sender_key;
};

void
to_json(nlohmann::json &obj, const MegolmSessionIndex &msg);
void
from_json(const nlohmann::json &obj, MegolmSessionIndex &msg);

struct StoredOlmSession
{
    std::uint64_t last_message_ts = 0;
    std::string pickled_session;
};
void
to_json(nlohmann::json &obj, const StoredOlmSession &msg);
void
from_json(const nlohmann::json &obj, StoredOlmSession &msg);

//! Verification status of a single user
struct VerificationStatus
{
    //! True, if the users master key is verified
    crypto::Trust user_verified = crypto::Trust::Unverified;
    //! List of all devices marked as verified
    std::set<std::string> verified_devices;
    //! Map from sender key/curve25519 to trust status
    std::map<std::string, crypto::Trust> verified_device_keys;
    //! Count of unverified devices
    int unverified_device_count = 0;
    // if the keys are not in cache
    bool no_keys = false;
};

//! In memory cache of verification status
struct VerificationStorage
{
    //! mapping of user to verification status
    std::map<std::string, VerificationStatus> status;
    std::mutex verification_storage_mtx;
};

//! In memory cache of verification status
struct SecretsStorage
{
    //! secret name -> secret
    std::map<std::string, std::string> secrets;
    std::mutex mtx;
};

// this will store the keys of the user with whom a encrypted room is shared with
struct UserKeyCache
{
    //! Device id to device keys
    std::map<std::string, mtx::crypto::DeviceKeys> device_keys;
    //! cross signing keys
    mtx::crypto::CrossSigningKeys master_keys, user_signing_keys, self_signing_keys;
    //! Sync token when nheko last fetched the keys
    std::string updated_at;
    //! Sync token when the keys last changed. updated != last_changed means they are outdated.
    std::string last_changed;
    //! if the master key has ever changed
    bool master_key_changed = false;
    //! Device keys that were already used at least once
    std::set<std::string> seen_device_keys;
    //! Device ids that were already used at least once
    std::set<std::string> seen_device_ids;
};

void
to_json(nlohmann::json &j, const UserKeyCache &info);
void
from_json(const nlohmann::json &j, UserKeyCache &info);

// the reason these are stored in a seperate cache rather than storing it in the user cache is
// UserKeyCache stores only keys of users with which encrypted room is shared
struct VerificationCache
{
    //! list of verified device_ids with device-verification
    std::set<std::string> device_verified;
    //! list of devices the user blocks
    std::set<std::string> device_blocked;
};

void
to_json(nlohmann::json &j, const VerificationCache &info);
void
from_json(const nlohmann::json &j, VerificationCache &info);

struct OnlineBackupVersion
{
    //! the version of the online backup currently enabled
    std::string version;
    //! the algorithm used by the backup
    std::string algorithm;
};

void
to_json(nlohmann::json &j, const OnlineBackupVersion &info);
void
from_json(const nlohmann::json &j, OnlineBackupVersion &info);