Coverage Report

Created: 2025-07-11 06:15

/src/rnp/include/rekey/rnp_key_store.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2017-2023 [Ribose Inc](https://www.ribose.com).
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright notice,
9
 *     this list of conditions and the following disclaimer.
10
 *
11
 * 2.  Redistributions in binary form must reproduce the above copyright notice,
12
 *     this list of conditions and the following disclaimer in the documentation
13
 *     and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#ifndef KEY_STORE_H_
28
#define KEY_STORE_H_
29
30
#include <stdint.h>
31
#include <stdbool.h>
32
#include "rnp.h"
33
#include "librepgp/stream-common.h"
34
#include "key.hpp"
35
#include <string>
36
#include <list>
37
#include <map>
38
#include <unordered_map>
39
#include <memory>
40
#include "librekey/kbx_blob.hpp"
41
#include "sec_profile.hpp"
42
43
/* Key import status. Order of elements is important. */
44
typedef enum pgp_key_import_status_t {
45
    PGP_KEY_IMPORT_STATUS_UNKNOWN = 0,
46
    PGP_KEY_IMPORT_STATUS_UNCHANGED,
47
    PGP_KEY_IMPORT_STATUS_UPDATED,
48
    PGP_KEY_IMPORT_STATUS_NEW,
49
} pgp_key_import_status_t;
50
51
typedef enum pgp_sig_import_status_t {
52
    PGP_SIG_IMPORT_STATUS_UNKNOWN = 0,
53
    PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY,
54
    PGP_SIG_IMPORT_STATUS_UNCHANGED,
55
    PGP_SIG_IMPORT_STATUS_NEW
56
} pgp_sig_import_status_t;
57
58
namespace rnp {
59
60
typedef std::unordered_map<pgp::Fingerprint, std::list<Key>::iterator> KeyFingerprintMap;
61
62
class KeyStore {
63
  private:
64
    Key *                   add_subkey(Key &srckey, Key *oldkey);
65
    pgp_sig_import_status_t import_subkey_signature(Key &key, const pgp::pkt::Signature &sig);
66
    bool                    refresh_subkey_grips(Key &key);
67
68
  public:
69
    std::string      path;
70
    KeyFormat        format;
71
    SecurityContext &secctx;
72
    bool             disable_validation =
73
      false; /* do not automatically validate keys, added to this key store */
74
75
    std::list<Key>                           keys;
76
    KeyFingerprintMap                        keybyfp;
77
    std::vector<std::unique_ptr<kbx_blob_t>> blobs;
78
79
    ~KeyStore();
80
3.12k
    KeyStore(SecurityContext &ctx) : path(""), format(KeyFormat::Unknown), secctx(ctx){};
81
    KeyStore(const std::string &path, SecurityContext &ctx, KeyFormat format = KeyFormat::GPG);
82
    /* make sure we use only empty constructor */
83
    KeyStore(KeyStore &&src) = delete;
84
    KeyStore &operator=(KeyStore &&) = delete;
85
    KeyStore(const KeyStore &src) = delete;
86
    KeyStore &operator=(const KeyStore &) = delete;
87
88
    /**
89
     * @brief Try to load key store from path.
90
     */
91
    bool load(const KeyProvider *key_provider = nullptr);
92
93
    /**
94
     * @brief Try to load key store from source.
95
     */
96
    bool load(pgp_source_t &src, const KeyProvider *key_provider = nullptr);
97
98
    /**
99
     * @brief Load all keys from the source, assuming openpgp format.
100
     *
101
     * @param src source to load the keys from.
102
     * @param skiperrors ignore key parsing errors, allowing to skip malformed/unsupported
103
     *                   keys.
104
     */
105
    rnp_result_t load_pgp(pgp_source_t &src, bool skiperrors = false);
106
107
    /**
108
     * @brief Load single key (including subkeys) from the source, assuming openpgp format.
109
     *
110
     * @param src source to load the key from.
111
     * @param skiperrors ignore key parsing errors, allowing to skip malformed/unknown subkeys.
112
     */
113
    rnp_result_t load_pgp_key(pgp_source_t &src, bool skiperrors = false);
114
115
    /**
116
     * @brief Load keystore in kbx format.
117
     */
118
    bool load_kbx(pgp_source_t &src, const KeyProvider *key_provider = nullptr);
119
120
    /**
121
     * @brief Load keystore in g10 format.
122
     */
123
    bool load_g10(pgp_source_t &src, const KeyProvider *key_provider = nullptr);
124
125
    /**
126
     * @brief Write keystore to the path.
127
     */
128
    bool write();
129
130
    /**
131
     * @brief Write keystore to the dest.
132
     */
133
    bool write(pgp_dest_t &dst);
134
135
    /**
136
     * @brief Write keystore to the dest in pgp format.
137
     */
138
    bool write_pgp(pgp_dest_t &dst);
139
140
    /**
141
     * @brief Write keystore to the dest in kbx format.
142
     *
143
     */
144
    bool write_kbx(pgp_dest_t &dst);
145
146
    void clear();
147
148
    size_t key_count() const;
149
150
    Key *      get_key(const pgp::Fingerprint &fpr);
151
    const Key *get_key(const pgp::Fingerprint &fpr) const;
152
153
    /**
154
     * @brief Get the key's subkey by its index
155
     *
156
     * @param key primary key
157
     * @param idx index of the subkey
158
     * @return pointer to the subkey or nullptr if subkey was found
159
     */
160
    Key *get_subkey(const Key &key, size_t idx);
161
162
    /**
163
     * @brief Get the signer's key for signature
164
     *
165
     * @param sig signature
166
     * @param prov key provider to request needed key.
167
     * @return pointer to the key or nullptr if signer's key was not found.
168
     */
169
    Key *get_signer(const pgp::pkt::Signature &sig, const KeyProvider *prov = nullptr);
170
171
    /**
172
     * @brief Add key to the keystore, copying it.
173
     * @return pointer to the added key or nullptr if failed.
174
     */
175
    Key *add_key(Key &key);
176
177
    /**
178
     * @brief Add signature of the specific key to the keystore, revalidating and refreshing
179
     *        key's data.
180
     *
181
     * @param keyfp key's fingerprint.
182
     * @param sig signature packet.
183
     * @param uid userid to which signature should be attached. If NULL then signature will be
184
     *            attached directly to the key.
185
     * @param front set to true if signature should be added to the beginning of the signature
186
     *              list.
187
     * @return pointer to the newly added signature or nullptr if error occurred (key not
188
     *         found, whatever else).
189
     */
190
    Signature *add_key_sig(const pgp::Fingerprint &   keyfp,
191
                           const pgp::pkt::Signature &sig,
192
                           const pgp_userid_pkt_t *   uid,
193
                           bool                       front);
194
195
    /**
196
     * @brief Add transferable key to the keystore.
197
     *
198
     * @param tkey parsed key.
199
     */
200
    bool add_ts_key(pgp_transferable_key_t &tkey);
201
202
    /**
203
     * @brief Add transferable subkey to the keystore.
204
     *
205
     * @param tskey parsed subkey.
206
     * @param pkey primary key, may be nullptr.
207
     */
208
    bool add_ts_subkey(const pgp_transferable_subkey_t &tskey, Key *pkey = nullptr);
209
210
    /**
211
     * @brief Import key to the keystore.
212
     *
213
     * @param srckey source key.
214
     * @param pubkey import just public key part.
215
     * @param status if not nullptr then import status will be stored here.
216
     * @return Key*
217
     */
218
    Key *import_key(Key &srckey, bool pubkey, pgp_key_import_status_t *status = nullptr);
219
220
    /**
221
     * @brief Import signature for the specified key.
222
     */
223
    pgp_sig_import_status_t import_signature(Key &key, const pgp::pkt::Signature &sig);
224
225
    /**
226
     * @brief Import revocation or direct-key signature to the keystore.
227
     *
228
     * @param sig signature to import.
229
     * @param status signature import status will be put here, if not nullptr.
230
     * @return pointer to the key to which this signature belongs (or nullptr if key was not
231
     * found)
232
     */
233
    Key *import_signature(const pgp::pkt::Signature &sig, pgp_sig_import_status_t *status);
234
235
    /**
236
     * @brief Remove key from the keystore.
237
     *
238
     * @param key key to remove. Must be from this keystore.
239
     * @param subkeys remove subkeys or not.
240
     * @return true if key was successfully removed, or false if key was not found in keystore.
241
     */
242
    bool remove_key(const Key &key, bool subkeys = false);
243
244
    /**
245
     * @brief Get primary key for the subkey, if any.
246
     */
247
    Key *primary_key(const Key &subkey);
248
249
    Key *search(const KeySearch &search, Key *after = nullptr);
250
};
251
} // namespace rnp
252
253
#endif /* KEY_STORE_H_ */