/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_ */ |