1 /*
2  * Copyright (c) 2017-2020 [Ribose Inc](https://www.ribose.com).
3  * Copyright (c) 2009 The NetBSD Foundation, Inc.
4  * All rights reserved.
5  *
6  * This code is originally derived from software contributed to
7  * The NetBSD Foundation by Alistair Crooks (agc@netbsd.org), and
8  * carried further by Ribose Inc (https://www.ribose.com).
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*
32  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
33  * All rights reserved.
34  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
35  * their moral rights under the UK Copyright Design and Patents Act 1988 to
36  * be recorded as the authors of this copyright work.
37  *
38  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
39  * use this file except in compliance with the License.
40  *
41  * You may obtain a copy of the License at
42  *     http://www.apache.org/licenses/LICENSE-2.0
43  *
44  * Unless required by applicable law or agreed to in writing, software
45  * distributed under the License is distributed on an "AS IS" BASIS,
46  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47  *
48  * See the License for the specific language governing permissions and
49  * limitations under the License.
50  */
51 
52 #include "pgp-key.h"
53 #include "utils.h"
54 #include <librekey/key_store_pgp.h>
55 #include <librekey/key_store_g10.h>
56 #include "crypto.h"
57 #include "crypto/s2k.h"
58 #include "crypto/mem.h"
59 #include "crypto/signatures.h"
60 #include "fingerprint.h"
61 
62 #include <librepgp/stream-packet.h>
63 #include <librepgp/stream-key.h>
64 #include <librepgp/stream-sig.h>
65 #include <librepgp/stream-armor.h>
66 
67 #include <stdio.h>
68 #include <string.h>
69 #include <stdlib.h>
70 #include <assert.h>
71 #include <time.h>
72 #include <algorithm>
73 #include <stdexcept>
74 #include "defaults.h"
75 
76 pgp_key_pkt_t *
pgp_decrypt_seckey_pgp(const pgp_rawpacket_t & raw,const pgp_key_pkt_t & pubkey,const char * password)77 pgp_decrypt_seckey_pgp(const pgp_rawpacket_t &raw,
78                        const pgp_key_pkt_t &  pubkey,
79                        const char *           password)
80 {
81     pgp_source_t   src = {0};
82     pgp_key_pkt_t *res = NULL;
83 
84     if (init_mem_src(&src, raw.raw.data(), raw.raw.size(), false)) {
85         return NULL;
86     }
87     try {
88         res = new pgp_key_pkt_t();
89         if (res->parse(src)) {
90             goto error;
91         }
92     } catch (const std::exception &e) {
93         RNP_LOG("%s", e.what());
94         goto error;
95     }
96     if (decrypt_secret_key(res, password)) {
97         goto error;
98     }
99 
100     src_close(&src);
101     return res;
102 error:
103     src_close(&src);
104     delete res;
105     return NULL;
106 }
107 
108 /* Note that this function essentially serves two purposes.
109  * - In the case of a protected key, it requests a password and
110  *   uses it to decrypt the key and fill in key->key.seckey.
111  * - In the case of an unprotected key, it simply re-loads
112  *   key->key.seckey by parsing the key data in packets[0].
113  */
114 pgp_key_pkt_t *
pgp_decrypt_seckey(const pgp_key_t & key,const pgp_password_provider_t & provider,const pgp_password_ctx_t & ctx)115 pgp_decrypt_seckey(const pgp_key_t &              key,
116                    const pgp_password_provider_t &provider,
117                    const pgp_password_ctx_t &     ctx)
118 {
119     // sanity checks
120     if (!key.is_secret()) {
121         RNP_LOG("invalid args");
122         return NULL;
123     }
124     // ask the provider for a password
125     rnp::secure_array<char, MAX_PASSWORD_LENGTH> password;
126     if (key.is_protected() &&
127         !pgp_request_password(&provider, &ctx, password.data(), password.size())) {
128         return NULL;
129     }
130     // attempt to decrypt with the provided password
131     switch (key.format) {
132     case PGP_KEY_STORE_GPG:
133     case PGP_KEY_STORE_KBX:
134         return pgp_decrypt_seckey_pgp(key.rawpkt(), key.pkt(), password.data());
135     case PGP_KEY_STORE_G10:
136         return g10_decrypt_seckey(key.rawpkt(), key.pkt(), password.data());
137     default:
138         RNP_LOG("unexpected format: %d", key.format);
139         return NULL;
140     }
141 }
142 
143 pgp_key_t *
pgp_sig_get_signer(const pgp_subsig_t & sig,rnp_key_store_t * keyring,pgp_key_provider_t * prov)144 pgp_sig_get_signer(const pgp_subsig_t &sig, rnp_key_store_t *keyring, pgp_key_provider_t *prov)
145 {
146     pgp_key_request_ctx_t ctx = {};
147     /* if we have fingerprint let's check it */
148     if (sig.sig.has_keyfp()) {
149         ctx.search.by.fingerprint = sig.sig.keyfp();
150         ctx.search.type = PGP_KEY_SEARCH_FINGERPRINT;
151     }
152     if ((ctx.search.type == PGP_KEY_SEARCH_UNKNOWN) && sig.sig.has_keyid()) {
153         ctx.search.by.keyid = sig.sig.keyid();
154         ctx.search.type = PGP_KEY_SEARCH_KEYID;
155     }
156     if (ctx.search.type == PGP_KEY_SEARCH_UNKNOWN) {
157         RNP_LOG("No way to search for the signer.");
158         return NULL;
159     }
160 
161     pgp_key_t *key = rnp_key_store_search(keyring, &ctx.search, NULL);
162     if (key || !prov) {
163         return key;
164     }
165 
166     ctx.op = PGP_OP_VERIFY;
167     ctx.secret = false;
168     return pgp_request_key(prov, &ctx);
169 }
170 
171 static const id_str_pair ss_rr_code_map[] = {
172   {PGP_REVOCATION_NO_REASON, "No reason specified"},
173   {PGP_REVOCATION_SUPERSEDED, "Key is superseded"},
174   {PGP_REVOCATION_COMPROMISED, "Key material has been compromised"},
175   {PGP_REVOCATION_RETIRED, "Key is retired and no longer used"},
176   {PGP_REVOCATION_NO_LONGER_VALID, "User ID information is no longer valid"},
177   {0x00, NULL},
178 };
179 
180 pgp_key_t *
pgp_key_get_subkey(const pgp_key_t * key,rnp_key_store_t * store,size_t idx)181 pgp_key_get_subkey(const pgp_key_t *key, rnp_key_store_t *store, size_t idx)
182 {
183     try {
184         return rnp_key_store_get_key_by_fpr(store, key->get_subkey_fp(idx));
185     } catch (const std::exception &e) {
186         RNP_LOG("%s", e.what());
187         return NULL;
188     }
189 }
190 
191 pgp_key_flags_t
pgp_pk_alg_capabilities(pgp_pubkey_alg_t alg)192 pgp_pk_alg_capabilities(pgp_pubkey_alg_t alg)
193 {
194     switch (alg) {
195     case PGP_PKA_RSA:
196         return pgp_key_flags_t(PGP_KF_SIGN | PGP_KF_CERTIFY | PGP_KF_AUTH | PGP_KF_ENCRYPT);
197 
198     case PGP_PKA_RSA_SIGN_ONLY:
199         // deprecated, but still usable
200         return PGP_KF_SIGN;
201 
202     case PGP_PKA_RSA_ENCRYPT_ONLY:
203         // deprecated, but still usable
204         return PGP_KF_ENCRYPT;
205 
206     case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: /* deprecated */
207         // These are no longer permitted per the RFC
208         return PGP_KF_NONE;
209 
210     case PGP_PKA_DSA:
211     case PGP_PKA_ECDSA:
212     case PGP_PKA_EDDSA:
213         return pgp_key_flags_t(PGP_KF_SIGN | PGP_KF_CERTIFY | PGP_KF_AUTH);
214 
215     case PGP_PKA_SM2:
216         return pgp_key_flags_t(PGP_KF_SIGN | PGP_KF_CERTIFY | PGP_KF_AUTH | PGP_KF_ENCRYPT);
217 
218     case PGP_PKA_ECDH:
219     case PGP_PKA_ELGAMAL:
220         return PGP_KF_ENCRYPT;
221 
222     default:
223         RNP_LOG("unknown pk alg: %d\n", alg);
224         return PGP_KF_NONE;
225     }
226 }
227 
228 bool
write_sec_pgp(pgp_dest_t & dst,pgp_key_pkt_t & seckey,const std::string & password,rnp::RNG & rng)229 pgp_key_t::write_sec_pgp(pgp_dest_t &       dst,
230                          pgp_key_pkt_t &    seckey,
231                          const std::string &password,
232                          rnp::RNG &         rng)
233 {
234     bool           res = false;
235     pgp_pkt_type_t oldtag = seckey.tag;
236 
237     seckey.tag = type();
238     if (encrypt_secret_key(&seckey, password.c_str(), rng)) {
239         goto done;
240     }
241     try {
242         seckey.write(dst);
243         res = !dst.werr;
244     } catch (const std::exception &e) {
245         RNP_LOG("%s", e.what());
246     }
247 done:
248     seckey.tag = oldtag;
249     return res;
250 }
251 
252 bool
write_sec_rawpkt(pgp_key_pkt_t & seckey,const std::string & password,rnp::RNG & rng)253 pgp_key_t::write_sec_rawpkt(pgp_key_pkt_t &seckey, const std::string &password, rnp::RNG &rng)
254 {
255     pgp_dest_t memdst = {};
256     if (init_mem_dest(&memdst, NULL, 0)) {
257         return false;
258     }
259 
260     bool ret = false;
261     // encrypt+write the key in the appropriate format
262     try {
263         switch (format) {
264         case PGP_KEY_STORE_GPG:
265         case PGP_KEY_STORE_KBX:
266             if (!write_sec_pgp(memdst, seckey, password, rng)) {
267                 RNP_LOG("failed to write secret key");
268                 goto done;
269             }
270             break;
271         case PGP_KEY_STORE_G10:
272             if (!g10_write_seckey(&memdst, &seckey, password.c_str(), rng)) {
273                 RNP_LOG("failed to write g10 secret key");
274                 goto done;
275             }
276             break;
277         default:
278             RNP_LOG("invalid format");
279             goto done;
280         }
281 
282         uint8_t *mem = (uint8_t *) mem_dest_get_memory(&memdst);
283         rawpkt_ = pgp_rawpacket_t(mem, memdst.writeb, type());
284     } catch (const std::exception &e) {
285         RNP_LOG("%s", e.what());
286         goto done;
287     }
288     ret = true;
289 done:
290     dst_close(&memdst, true);
291     return ret;
292 }
293 
294 static bool
update_sig_expiration(pgp_signature_t * dst,const pgp_signature_t * src,uint32_t expiry)295 update_sig_expiration(pgp_signature_t *dst, const pgp_signature_t *src, uint32_t expiry)
296 {
297     try {
298         *dst = *src;
299         if (!expiry) {
300             dst->remove_subpkt(dst->get_subpkt(PGP_SIG_SUBPKT_KEY_EXPIRY));
301         } else {
302             dst->set_key_expiration(expiry);
303         }
304         dst->set_creation(time(NULL));
305         return true;
306     } catch (const std::exception &e) {
307         RNP_LOG("%s", e.what());
308         return false;
309     }
310 }
311 
312 bool
pgp_key_set_expiration(pgp_key_t * key,pgp_key_t * seckey,uint32_t expiry,const pgp_password_provider_t & prov,rnp::SecurityContext & ctx)313 pgp_key_set_expiration(pgp_key_t *                    key,
314                        pgp_key_t *                    seckey,
315                        uint32_t                       expiry,
316                        const pgp_password_provider_t &prov,
317                        rnp::SecurityContext &         ctx)
318 {
319     if (!key->is_primary()) {
320         RNP_LOG("Not a primary key");
321         return false;
322     }
323 
324     std::vector<pgp_sig_id_t> sigs;
325     /* update expiration for the latest direct-key signature and self-signature for each userid
326      */
327     pgp_subsig_t *sig = key->latest_selfsig(PGP_UID_NONE);
328     if (sig) {
329         sigs.push_back(sig->sigid);
330     }
331     for (size_t uid = 0; uid < key->uid_count(); uid++) {
332         sig = key->latest_selfsig(uid);
333         if (sig) {
334             sigs.push_back(sig->sigid);
335         }
336     }
337     if (sigs.empty()) {
338         RNP_LOG("No valid self-signature(s)");
339         return false;
340     }
341 
342     rnp::KeyLocker seclock(*seckey);
343     for (const auto &sigid : sigs) {
344         pgp_subsig_t &sig = key->get_sig(sigid);
345         /* update signature and re-sign it */
346         if (!expiry && !sig.sig.has_subpkt(PGP_SIG_SUBPKT_KEY_EXPIRY)) {
347             continue;
348         }
349 
350         /* unlock secret key if needed */
351         if (seckey->is_locked() && !seckey->unlock(prov)) {
352             RNP_LOG("Failed to unlock secret key");
353             return false;
354         }
355 
356         pgp_signature_t newsig;
357         pgp_sig_id_t    oldsigid = sigid;
358         if (!update_sig_expiration(&newsig, &sig.sig, expiry)) {
359             return false;
360         }
361         try {
362             if (sig.is_cert()) {
363                 if (sig.uid >= key->uid_count()) {
364                     RNP_LOG("uid not found");
365                     return false;
366                 }
367                 seckey->sign_cert(key->pkt(), key->get_uid(sig.uid).pkt, newsig, ctx);
368             } else {
369                 /* direct-key signature case */
370                 seckey->sign_direct(key->pkt(), newsig, ctx);
371             }
372             /* replace signature, first for secret key since it may be replaced in public */
373             if (seckey->has_sig(oldsigid)) {
374                 seckey->replace_sig(oldsigid, newsig);
375             }
376             if (key != seckey) {
377                 key->replace_sig(oldsigid, newsig);
378             }
379         } catch (const std::exception &e) {
380             RNP_LOG("failed to calculate or add signature: %s", e.what());
381             return false;
382         }
383     }
384 
385     if (!seckey->refresh_data(ctx)) {
386         RNP_LOG("Failed to refresh seckey data.");
387         return false;
388     }
389     if ((key != seckey) && !key->refresh_data(ctx)) {
390         RNP_LOG("Failed to refresh key data.");
391         return false;
392     }
393     return true;
394 }
395 
396 bool
pgp_subkey_set_expiration(pgp_key_t * sub,pgp_key_t * primsec,pgp_key_t * secsub,uint32_t expiry,const pgp_password_provider_t & prov,rnp::SecurityContext & ctx)397 pgp_subkey_set_expiration(pgp_key_t *                    sub,
398                           pgp_key_t *                    primsec,
399                           pgp_key_t *                    secsub,
400                           uint32_t                       expiry,
401                           const pgp_password_provider_t &prov,
402                           rnp::SecurityContext &         ctx)
403 {
404     if (!sub->is_subkey()) {
405         RNP_LOG("Not a subkey");
406         return false;
407     }
408 
409     /* find the latest valid subkey binding */
410     pgp_subsig_t *subsig = sub->latest_binding();
411     if (!subsig) {
412         RNP_LOG("No valid subkey binding");
413         return false;
414     }
415     if (!expiry && !subsig->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_EXPIRY)) {
416         return true;
417     }
418 
419     rnp::KeyLocker primlock(*primsec);
420     if (primsec->is_locked() && !primsec->unlock(prov)) {
421         RNP_LOG("Failed to unlock primary key");
422         return false;
423     }
424     bool           subsign = secsub->can_sign();
425     rnp::KeyLocker sublock(*secsub);
426     if (subsign && secsub->is_locked() && !secsub->unlock(prov)) {
427         RNP_LOG("Failed to unlock subkey");
428         return false;
429     }
430 
431     try {
432         /* update signature and re-sign */
433         pgp_signature_t newsig;
434         pgp_sig_id_t    oldsigid = subsig->sigid;
435         if (!update_sig_expiration(&newsig, &subsig->sig, expiry)) {
436             return false;
437         }
438         primsec->sign_subkey_binding(*secsub, newsig, ctx);
439         /* replace signature, first for the secret key since it may be replaced in public */
440         if (secsub->has_sig(oldsigid)) {
441             secsub->replace_sig(oldsigid, newsig);
442             if (!secsub->refresh_data(primsec, ctx)) {
443                 return false;
444             }
445         }
446         if (sub == secsub) {
447             return true;
448         }
449         sub->replace_sig(oldsigid, newsig);
450         return sub->refresh_data(primsec, ctx);
451     } catch (const std::exception &e) {
452         RNP_LOG("%s", e.what());
453         return false;
454     }
455 }
456 
457 pgp_key_t *
find_suitable_key(pgp_op_t op,pgp_key_t * key,pgp_key_provider_t * key_provider,uint8_t desired_usage,bool no_primary)458 find_suitable_key(pgp_op_t            op,
459                   pgp_key_t *         key,
460                   pgp_key_provider_t *key_provider,
461                   uint8_t             desired_usage,
462                   bool                no_primary)
463 {
464     assert(desired_usage);
465     if (!key) {
466         return NULL;
467     }
468     if (!no_primary && key->valid() && (key->flags() & desired_usage)) {
469         return key;
470     }
471     pgp_key_request_ctx_t ctx{.op = op, .secret = key->is_secret()};
472     ctx.search.type = PGP_KEY_SEARCH_FINGERPRINT;
473 
474     pgp_key_t *subkey = NULL;
475     for (auto &fp : key->subkey_fps()) {
476         ctx.search.by.fingerprint = fp;
477         pgp_key_t *cur = pgp_request_key(key_provider, &ctx);
478         if (!cur || !(cur->flags() & desired_usage) || !cur->valid()) {
479             continue;
480         }
481         if (!subkey || (cur->creation() > subkey->creation())) {
482             subkey = cur;
483         }
484     }
485     return subkey;
486 }
487 
488 pgp_hash_alg_t
pgp_hash_adjust_alg_to_key(pgp_hash_alg_t hash,const pgp_key_pkt_t * pubkey)489 pgp_hash_adjust_alg_to_key(pgp_hash_alg_t hash, const pgp_key_pkt_t *pubkey)
490 {
491     if ((pubkey->alg != PGP_PKA_DSA) && (pubkey->alg != PGP_PKA_ECDSA)) {
492         return hash;
493     }
494 
495     pgp_hash_alg_t hash_min;
496     if (pubkey->alg == PGP_PKA_ECDSA) {
497         hash_min = ecdsa_get_min_hash(pubkey->material.ec.curve);
498     } else {
499         hash_min = dsa_get_min_hash(mpi_bits(&pubkey->material.dsa.q));
500     }
501 
502     if (rnp::Hash::size(hash) < rnp::Hash::size(hash_min)) {
503         return hash_min;
504     }
505     return hash;
506 }
507 
508 static void
mem_dest_to_vector(pgp_dest_t * dst,std::vector<uint8_t> & vec)509 mem_dest_to_vector(pgp_dest_t *dst, std::vector<uint8_t> &vec)
510 {
511     uint8_t *mem = (uint8_t *) mem_dest_get_memory(dst);
512     try {
513         vec = std::vector<uint8_t>(mem, mem + dst->writeb);
514         dst_close(dst, true);
515     } catch (const std::exception &e) {
516         RNP_LOG("%s", e.what());
517         dst_close(dst, true);
518         throw;
519     }
520 }
521 
522 static void
bytevec_append_uniq(std::vector<uint8_t> & vec,uint8_t val)523 bytevec_append_uniq(std::vector<uint8_t> &vec, uint8_t val)
524 {
525     if (std::find(vec.begin(), vec.end(), val) == vec.end()) {
526         vec.push_back(val);
527     }
528 }
529 
530 void
set_symm_algs(const std::vector<uint8_t> & algs)531 pgp_user_prefs_t::set_symm_algs(const std::vector<uint8_t> &algs)
532 {
533     symm_algs = algs;
534 }
535 
536 void
add_symm_alg(pgp_symm_alg_t alg)537 pgp_user_prefs_t::add_symm_alg(pgp_symm_alg_t alg)
538 {
539     bytevec_append_uniq(symm_algs, alg);
540 }
541 
542 void
set_hash_algs(const std::vector<uint8_t> & algs)543 pgp_user_prefs_t::set_hash_algs(const std::vector<uint8_t> &algs)
544 {
545     hash_algs = algs;
546 }
547 
548 void
add_hash_alg(pgp_hash_alg_t alg)549 pgp_user_prefs_t::add_hash_alg(pgp_hash_alg_t alg)
550 {
551     bytevec_append_uniq(hash_algs, alg);
552 }
553 
554 void
set_z_algs(const std::vector<uint8_t> & algs)555 pgp_user_prefs_t::set_z_algs(const std::vector<uint8_t> &algs)
556 {
557     z_algs = algs;
558 }
559 
560 void
add_z_alg(pgp_compression_type_t alg)561 pgp_user_prefs_t::add_z_alg(pgp_compression_type_t alg)
562 {
563     bytevec_append_uniq(z_algs, alg);
564 }
565 
566 void
set_ks_prefs(const std::vector<uint8_t> & prefs)567 pgp_user_prefs_t::set_ks_prefs(const std::vector<uint8_t> &prefs)
568 {
569     ks_prefs = prefs;
570 }
571 
572 void
add_ks_pref(pgp_key_server_prefs_t pref)573 pgp_user_prefs_t::add_ks_pref(pgp_key_server_prefs_t pref)
574 {
575     bytevec_append_uniq(ks_prefs, pref);
576 }
577 
pgp_rawpacket_t(const pgp_signature_t & sig)578 pgp_rawpacket_t::pgp_rawpacket_t(const pgp_signature_t &sig)
579 {
580     pgp_dest_t dst = {};
581 
582     if (init_mem_dest(&dst, NULL, 0)) {
583         throw std::bad_alloc();
584     }
585 
586     try {
587         sig.write(dst);
588     } catch (const std::exception &e) {
589         dst_close(&dst, true);
590         throw;
591     }
592     mem_dest_to_vector(&dst, raw);
593     tag = PGP_PKT_SIGNATURE;
594 }
595 
pgp_rawpacket_t(pgp_key_pkt_t & key)596 pgp_rawpacket_t::pgp_rawpacket_t(pgp_key_pkt_t &key)
597 {
598     pgp_dest_t dst = {};
599 
600     if (init_mem_dest(&dst, NULL, 0)) {
601         throw std::bad_alloc();
602     }
603     try {
604         key.write(dst);
605     } catch (const std::exception &e) {
606         dst_close(&dst, true);
607         throw;
608     }
609     mem_dest_to_vector(&dst, raw);
610     tag = key.tag;
611 }
612 
pgp_rawpacket_t(const pgp_userid_pkt_t & uid)613 pgp_rawpacket_t::pgp_rawpacket_t(const pgp_userid_pkt_t &uid)
614 {
615     pgp_dest_t dst = {};
616 
617     if (init_mem_dest(&dst, NULL, 0)) {
618         throw std::bad_alloc();
619     }
620     try {
621         uid.write(dst);
622     } catch (const std::exception &e) {
623         dst_close(&dst, true);
624         throw;
625     }
626     mem_dest_to_vector(&dst, raw);
627     tag = uid.tag;
628 }
629 
630 void
write(pgp_dest_t & dst) const631 pgp_rawpacket_t::write(pgp_dest_t &dst) const
632 {
633     dst_write(&dst, raw.data(), raw.size());
634 }
635 
636 void
mark_valid()637 pgp_validity_t::mark_valid()
638 {
639     validated = true;
640     valid = true;
641     expired = false;
642 }
643 
644 void
reset()645 pgp_validity_t::reset()
646 {
647     validated = false;
648     valid = false;
649     expired = false;
650 }
651 
pgp_subsig_t(const pgp_signature_t & pkt)652 pgp_subsig_t::pgp_subsig_t(const pgp_signature_t &pkt)
653 {
654     sig = pkt;
655     sigid = sig.get_id();
656     if (sig.has_subpkt(PGP_SIG_SUBPKT_TRUST)) {
657         trustlevel = sig.trust_level();
658         trustamount = sig.trust_amount();
659     }
660     prefs.set_symm_algs(sig.preferred_symm_algs());
661     prefs.set_hash_algs(sig.preferred_hash_algs());
662     prefs.set_z_algs(sig.preferred_z_algs());
663 
664     if (sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
665         key_flags = sig.key_flags();
666     }
667     if (sig.has_subpkt(PGP_SIG_SUBPKT_KEYSERV_PREFS)) {
668         prefs.set_ks_prefs({sig.key_server_prefs()});
669     }
670     if (sig.has_subpkt(PGP_SIG_SUBPKT_PREF_KEYSERV)) {
671         prefs.key_server = sig.key_server();
672     }
673     /* add signature rawpacket */
674     rawpkt = pgp_rawpacket_t(sig);
675 }
676 
677 bool
valid() const678 pgp_subsig_t::valid() const
679 {
680     return validity.validated && validity.valid && !validity.expired;
681 }
682 
683 bool
validated() const684 pgp_subsig_t::validated() const
685 {
686     return validity.validated;
687 }
688 
689 bool
is_cert() const690 pgp_subsig_t::is_cert() const
691 {
692     pgp_sig_type_t type = sig.type();
693     return (type == PGP_CERT_CASUAL) || (type == PGP_CERT_GENERIC) ||
694            (type == PGP_CERT_PERSONA) || (type == PGP_CERT_POSITIVE);
695 }
696 
697 bool
expired() const698 pgp_subsig_t::expired() const
699 {
700     /* sig expiration: absence of subpkt or 0 means it never expires */
701     uint64_t expiration = sig.expiration();
702     if (!expiration) {
703         return false;
704     }
705     uint64_t now = time(NULL);
706     return expiration + sig.creation() < now;
707 }
708 
pgp_userid_t(const pgp_userid_pkt_t & uidpkt)709 pgp_userid_t::pgp_userid_t(const pgp_userid_pkt_t &uidpkt)
710 {
711     /* copy packet data */
712     pkt = uidpkt;
713     rawpkt = pgp_rawpacket_t(uidpkt);
714     /* populate uid string */
715     if (uidpkt.tag == PGP_PKT_USER_ID) {
716         str = std::string(uidpkt.uid, uidpkt.uid + uidpkt.uid_len);
717     } else {
718         str = "(photo)";
719     }
720 }
721 
722 size_t
sig_count() const723 pgp_userid_t::sig_count() const
724 {
725     return sigs_.size();
726 }
727 
728 const pgp_sig_id_t &
get_sig(size_t idx) const729 pgp_userid_t::get_sig(size_t idx) const
730 {
731     if (idx >= sigs_.size()) {
732         throw std::out_of_range("idx");
733     }
734     return sigs_[idx];
735 }
736 
737 bool
has_sig(const pgp_sig_id_t & id) const738 pgp_userid_t::has_sig(const pgp_sig_id_t &id) const
739 {
740     return std::find(sigs_.begin(), sigs_.end(), id) != sigs_.end();
741 }
742 
743 void
add_sig(const pgp_sig_id_t & sig)744 pgp_userid_t::add_sig(const pgp_sig_id_t &sig)
745 {
746     sigs_.push_back(sig);
747 }
748 
749 void
replace_sig(const pgp_sig_id_t & id,const pgp_sig_id_t & newsig)750 pgp_userid_t::replace_sig(const pgp_sig_id_t &id, const pgp_sig_id_t &newsig)
751 {
752     auto it = std::find(sigs_.begin(), sigs_.end(), id);
753     if (it == sigs_.end()) {
754         throw std::invalid_argument("id");
755     }
756     *it = newsig;
757 }
758 
759 bool
del_sig(const pgp_sig_id_t & id)760 pgp_userid_t::del_sig(const pgp_sig_id_t &id)
761 {
762     auto it = std::find(sigs_.begin(), sigs_.end(), id);
763     if (it == sigs_.end()) {
764         return false;
765     }
766     sigs_.erase(it);
767     return true;
768 }
769 
770 void
clear_sigs()771 pgp_userid_t::clear_sigs()
772 {
773     sigs_.clear();
774 }
775 
pgp_revoke_t(pgp_subsig_t & sig)776 pgp_revoke_t::pgp_revoke_t(pgp_subsig_t &sig)
777 {
778     uid = sig.uid;
779     sigid = sig.sigid;
780     if (!sig.sig.has_subpkt(PGP_SIG_SUBPKT_REVOCATION_REASON)) {
781         RNP_LOG("Warning: no revocation reason in the revocation");
782         code = PGP_REVOCATION_NO_REASON;
783     } else {
784         code = sig.sig.revocation_code();
785         reason = sig.sig.revocation_reason();
786     }
787     if (reason.empty()) {
788         reason = id_str_pair::lookup(ss_rr_code_map, code);
789     }
790 }
791 
pgp_key_t(const pgp_key_pkt_t & keypkt)792 pgp_key_t::pgp_key_t(const pgp_key_pkt_t &keypkt) : pkt_(keypkt)
793 {
794     if (!is_key_pkt(pkt_.tag) || !pkt_.material.alg) {
795         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
796     }
797     if (pgp_keyid(keyid_, pkt_) || pgp_fingerprint(fingerprint_, pkt_) ||
798         !rnp_key_store_get_key_grip(&pkt_.material, grip_)) {
799         throw rnp::rnp_exception(RNP_ERROR_GENERIC);
800     }
801 
802     /* parse secret key if not encrypted */
803     if (is_secret_key_pkt(pkt_.tag)) {
804         bool cleartext = pkt_.sec_protection.s2k.usage == PGP_S2KU_NONE;
805         if (cleartext && decrypt_secret_key(&pkt_, NULL)) {
806             RNP_LOG("failed to setup key fields");
807             throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
808         }
809         /* decryption resets validity */
810         pkt_.material.validity = keypkt.material.validity;
811     }
812     /* add rawpacket */
813     rawpkt_ = pgp_rawpacket_t(pkt_);
814     format = PGP_KEY_STORE_GPG;
815 }
816 
pgp_key_t(const pgp_key_pkt_t & pkt,pgp_key_t & primary)817 pgp_key_t::pgp_key_t(const pgp_key_pkt_t &pkt, pgp_key_t &primary) : pgp_key_t(pkt)
818 {
819     primary.link_subkey_fp(*this);
820 }
821 
pgp_key_t(const pgp_key_t & src,bool pubonly)822 pgp_key_t::pgp_key_t(const pgp_key_t &src, bool pubonly)
823 {
824     /* Do some checks for g10 keys */
825     if (src.format == PGP_KEY_STORE_G10) {
826         if (pubonly) {
827             RNP_LOG("attempt to copy public part from g10 key");
828             throw std::invalid_argument("pubonly");
829         }
830     }
831 
832     if (pubonly) {
833         pkt_ = pgp_key_pkt_t(src.pkt_, true);
834         rawpkt_ = pgp_rawpacket_t(pkt_);
835     } else {
836         pkt_ = src.pkt_;
837         rawpkt_ = src.rawpkt_;
838     }
839 
840     uids_ = src.uids_;
841     sigs_ = src.sigs_;
842     sigs_map_ = src.sigs_map_;
843     keysigs_ = src.keysigs_;
844     subkey_fps_ = src.subkey_fps_;
845     primary_fp_set_ = src.primary_fp_set_;
846     primary_fp_ = src.primary_fp_;
847     expiration_ = src.expiration_;
848     flags_ = src.flags_;
849     keyid_ = src.keyid_;
850     fingerprint_ = src.fingerprint_;
851     grip_ = src.grip_;
852     uid0_ = src.uid0_;
853     uid0_set_ = src.uid0_set_;
854     revoked_ = src.revoked_;
855     revocation_ = src.revocation_;
856     format = src.format;
857     validity_ = src.validity_;
858     valid_till_ = src.valid_till_;
859 }
860 
pgp_key_t(const pgp_transferable_key_t & src)861 pgp_key_t::pgp_key_t(const pgp_transferable_key_t &src) : pgp_key_t(src.key)
862 {
863     /* add direct-key signatures */
864     for (auto &sig : src.signatures) {
865         add_sig(sig);
866     }
867 
868     /* add userids and their signatures */
869     for (auto &uid : src.userids) {
870         add_uid(uid);
871     }
872 }
873 
pgp_key_t(const pgp_transferable_subkey_t & src,pgp_key_t * primary)874 pgp_key_t::pgp_key_t(const pgp_transferable_subkey_t &src, pgp_key_t *primary)
875     : pgp_key_t(src.subkey)
876 {
877     /* add subkey binding signatures */
878     for (auto &sig : src.signatures) {
879         add_sig(sig);
880     }
881 
882     /* setup key grips if primary is available */
883     if (primary) {
884         primary->link_subkey_fp(*this);
885     }
886 }
887 
888 size_t
sig_count() const889 pgp_key_t::sig_count() const
890 {
891     return sigs_.size();
892 }
893 
894 pgp_subsig_t &
get_sig(size_t idx)895 pgp_key_t::get_sig(size_t idx)
896 {
897     if (idx >= sigs_.size()) {
898         throw std::out_of_range("idx");
899     }
900     return get_sig(sigs_[idx]);
901 }
902 
903 const pgp_subsig_t &
get_sig(size_t idx) const904 pgp_key_t::get_sig(size_t idx) const
905 {
906     if (idx >= sigs_.size()) {
907         throw std::out_of_range("idx");
908     }
909     return get_sig(sigs_[idx]);
910 }
911 
912 bool
has_sig(const pgp_sig_id_t & id) const913 pgp_key_t::has_sig(const pgp_sig_id_t &id) const
914 {
915     return sigs_map_.count(id);
916 }
917 
918 pgp_subsig_t &
get_sig(const pgp_sig_id_t & id)919 pgp_key_t::get_sig(const pgp_sig_id_t &id)
920 {
921     if (!has_sig(id)) {
922         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
923     }
924     return sigs_map_.at(id);
925 }
926 
927 const pgp_subsig_t &
get_sig(const pgp_sig_id_t & id) const928 pgp_key_t::get_sig(const pgp_sig_id_t &id) const
929 {
930     if (!has_sig(id)) {
931         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
932     }
933     return sigs_map_.at(id);
934 }
935 
936 pgp_subsig_t &
replace_sig(const pgp_sig_id_t & id,const pgp_signature_t & newsig)937 pgp_key_t::replace_sig(const pgp_sig_id_t &id, const pgp_signature_t &newsig)
938 {
939     /* save oldsig's uid */
940     size_t uid = get_sig(id).uid;
941     /* delete first old sig since we may have theoretically the same sigid */
942     pgp_sig_id_t oldid = id;
943     sigs_map_.erase(oldid);
944     auto &res = sigs_map_.emplace(std::make_pair(newsig.get_id(), newsig)).first->second;
945     res.uid = uid;
946     auto it = std::find(sigs_.begin(), sigs_.end(), oldid);
947     if (it == sigs_.end()) {
948         throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
949     }
950     *it = res.sigid;
951     if (uid == PGP_UID_NONE) {
952         auto it = std::find(keysigs_.begin(), keysigs_.end(), oldid);
953         if (it == keysigs_.end()) {
954             throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
955         }
956         *it = res.sigid;
957     } else {
958         uids_[uid].replace_sig(oldid, res.sigid);
959     }
960     return res;
961 }
962 
963 pgp_subsig_t &
add_sig(const pgp_signature_t & sig,size_t uid)964 pgp_key_t::add_sig(const pgp_signature_t &sig, size_t uid)
965 {
966     const pgp_sig_id_t sigid = sig.get_id();
967     sigs_map_.erase(sigid);
968     pgp_subsig_t &res = sigs_map_.emplace(std::make_pair(sigid, sig)).first->second;
969     res.uid = uid;
970     sigs_.push_back(sigid);
971     if (uid == PGP_UID_NONE) {
972         keysigs_.push_back(sigid);
973     } else {
974         uids_[uid].add_sig(sigid);
975     }
976     return res;
977 }
978 
979 bool
del_sig(const pgp_sig_id_t & sigid)980 pgp_key_t::del_sig(const pgp_sig_id_t &sigid)
981 {
982     if (!has_sig(sigid)) {
983         return false;
984     }
985     uint32_t uid = get_sig(sigid).uid;
986     if (uid == PGP_UID_NONE) {
987         /* signature over the key itself */
988         auto it = std::find(keysigs_.begin(), keysigs_.end(), sigid);
989         if (it != keysigs_.end()) {
990             keysigs_.erase(it);
991         }
992     } else if (uid < uids_.size()) {
993         /* userid-related signature */
994         uids_[uid].del_sig(sigid);
995     }
996     auto it = std::find(sigs_.begin(), sigs_.end(), sigid);
997     if (it != sigs_.end()) {
998         sigs_.erase(it);
999     }
1000     return sigs_map_.erase(sigid);
1001 }
1002 
1003 size_t
del_sigs(const std::vector<pgp_sig_id_t> & sigs)1004 pgp_key_t::del_sigs(const std::vector<pgp_sig_id_t> &sigs)
1005 {
1006     /* delete actual signatures */
1007     size_t res = 0;
1008     for (auto &sig : sigs) {
1009         res += sigs_map_.erase(sig);
1010     }
1011     /* rebuild vectors with signatures order */
1012     keysigs_.clear();
1013     for (auto &uid : uids_) {
1014         uid.clear_sigs();
1015     }
1016     std::vector<pgp_sig_id_t> newsigs;
1017     newsigs.reserve(sigs_map_.size());
1018     for (auto &sigid : sigs_) {
1019         if (!sigs_map_.count(sigid)) {
1020             continue;
1021         }
1022         newsigs.push_back(sigid);
1023         uint32_t uid = get_sig(sigid).uid;
1024         if (uid == PGP_UID_NONE) {
1025             keysigs_.push_back(sigid);
1026         } else {
1027             uids_[uid].add_sig(sigid);
1028         }
1029     }
1030     sigs_ = std::move(newsigs);
1031     return res;
1032 }
1033 
1034 size_t
keysig_count() const1035 pgp_key_t::keysig_count() const
1036 {
1037     return keysigs_.size();
1038 }
1039 
1040 pgp_subsig_t &
get_keysig(size_t idx)1041 pgp_key_t::get_keysig(size_t idx)
1042 {
1043     if (idx >= keysigs_.size()) {
1044         throw std::out_of_range("idx");
1045     }
1046     return get_sig(keysigs_[idx]);
1047 }
1048 
1049 size_t
uid_count() const1050 pgp_key_t::uid_count() const
1051 {
1052     return uids_.size();
1053 }
1054 
1055 pgp_userid_t &
get_uid(size_t idx)1056 pgp_key_t::get_uid(size_t idx)
1057 {
1058     if (idx >= uids_.size()) {
1059         throw std::out_of_range("idx");
1060     }
1061     return uids_[idx];
1062 }
1063 
1064 const pgp_userid_t &
get_uid(size_t idx) const1065 pgp_key_t::get_uid(size_t idx) const
1066 {
1067     if (idx >= uids_.size()) {
1068         throw std::out_of_range("idx");
1069     }
1070     return uids_[idx];
1071 }
1072 
1073 bool
has_uid(const std::string & uidstr) const1074 pgp_key_t::has_uid(const std::string &uidstr) const
1075 {
1076     for (auto &userid : uids_) {
1077         if (!userid.valid) {
1078             continue;
1079         }
1080         if (userid.str == uidstr) {
1081             return true;
1082         }
1083     }
1084     return false;
1085 }
1086 
1087 void
del_uid(size_t idx)1088 pgp_key_t::del_uid(size_t idx)
1089 {
1090     if (idx >= uids_.size()) {
1091         throw std::out_of_range("idx");
1092     }
1093 
1094     std::vector<pgp_sig_id_t> newsigs;
1095     /* copy sigs which do not belong to uid */
1096     newsigs.reserve(sigs_.size());
1097     for (auto &id : sigs_) {
1098         if (get_sig(id).uid == idx) {
1099             sigs_map_.erase(id);
1100             continue;
1101         }
1102         newsigs.push_back(id);
1103     }
1104     sigs_ = newsigs;
1105     uids_.erase(uids_.begin() + idx);
1106     /* update uids */
1107     if (idx == uids_.size()) {
1108         return;
1109     }
1110     for (auto &sig : sigs_map_) {
1111         if ((sig.second.uid == PGP_UID_NONE) || (sig.second.uid <= idx)) {
1112             continue;
1113         }
1114         sig.second.uid--;
1115     }
1116 }
1117 
1118 bool
has_primary_uid() const1119 pgp_key_t::has_primary_uid() const
1120 {
1121     return uid0_set_;
1122 }
1123 
1124 uint32_t
get_primary_uid() const1125 pgp_key_t::get_primary_uid() const
1126 {
1127     if (!uid0_set_) {
1128         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
1129     }
1130     return uid0_;
1131 }
1132 
1133 pgp_userid_t &
add_uid(const pgp_transferable_userid_t & uid)1134 pgp_key_t::add_uid(const pgp_transferable_userid_t &uid)
1135 {
1136     /* construct userid */
1137     uids_.emplace_back(uid.uid);
1138     /* add certifications */
1139     for (auto &sig : uid.signatures) {
1140         add_sig(sig, uid_count() - 1);
1141     }
1142     return uids_.back();
1143 }
1144 
1145 bool
revoked() const1146 pgp_key_t::revoked() const
1147 {
1148     return revoked_;
1149 }
1150 
1151 const pgp_revoke_t &
revocation() const1152 pgp_key_t::revocation() const
1153 {
1154     if (!revoked_) {
1155         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
1156     }
1157     return revocation_;
1158 }
1159 
1160 void
clear_revokes()1161 pgp_key_t::clear_revokes()
1162 {
1163     revoked_ = false;
1164     revocation_ = {};
1165     for (auto &uid : uids_) {
1166         uid.revoked = false;
1167         uid.revocation = {};
1168     }
1169 }
1170 
1171 const pgp_key_pkt_t &
pkt() const1172 pgp_key_t::pkt() const
1173 {
1174     return pkt_;
1175 }
1176 
1177 pgp_key_pkt_t &
pkt()1178 pgp_key_t::pkt()
1179 {
1180     return pkt_;
1181 }
1182 
1183 void
set_pkt(const pgp_key_pkt_t & pkt)1184 pgp_key_t::set_pkt(const pgp_key_pkt_t &pkt)
1185 {
1186     pkt_ = pkt;
1187 }
1188 
1189 pgp_key_material_t &
material()1190 pgp_key_t::material()
1191 {
1192     return pkt_.material;
1193 }
1194 
1195 pgp_pubkey_alg_t
alg() const1196 pgp_key_t::alg() const
1197 {
1198     return pkt_.alg;
1199 }
1200 
1201 pgp_curve_t
curve() const1202 pgp_key_t::curve() const
1203 {
1204     switch (alg()) {
1205     case PGP_PKA_ECDH:
1206     case PGP_PKA_ECDSA:
1207     case PGP_PKA_EDDSA:
1208     case PGP_PKA_SM2:
1209         return pkt_.material.ec.curve;
1210     default:
1211         return PGP_CURVE_UNKNOWN;
1212     }
1213 }
1214 
1215 pgp_version_t
version() const1216 pgp_key_t::version() const
1217 {
1218     return pkt().version;
1219 }
1220 
1221 pgp_pkt_type_t
type() const1222 pgp_key_t::type() const
1223 {
1224     return pkt().tag;
1225 }
1226 
1227 bool
encrypted() const1228 pgp_key_t::encrypted() const
1229 {
1230     return is_secret() && !pkt().material.secret;
1231 }
1232 
1233 uint8_t
flags() const1234 pgp_key_t::flags() const
1235 {
1236     return flags_;
1237 }
1238 
1239 bool
can_sign() const1240 pgp_key_t::can_sign() const
1241 {
1242     return flags_ & PGP_KF_SIGN;
1243 }
1244 
1245 bool
can_certify() const1246 pgp_key_t::can_certify() const
1247 {
1248     return flags_ & PGP_KF_CERTIFY;
1249 }
1250 
1251 bool
can_encrypt() const1252 pgp_key_t::can_encrypt() const
1253 {
1254     return flags_ & PGP_KF_ENCRYPT;
1255 }
1256 
1257 uint32_t
expiration() const1258 pgp_key_t::expiration() const
1259 {
1260     if (pkt_.version >= 4) {
1261         return expiration_;
1262     }
1263     /* too large value for pkt.v3_days may overflow uint32_t */
1264     if (pkt_.v3_days > (0xffffffffu / 86400)) {
1265         return 0xffffffffu;
1266     }
1267     return (uint32_t) pkt_.v3_days * 86400;
1268 }
1269 
1270 bool
expired() const1271 pgp_key_t::expired() const
1272 {
1273     return validity_.expired;
1274 }
1275 
1276 uint32_t
creation() const1277 pgp_key_t::creation() const
1278 {
1279     return pkt_.creation_time;
1280 }
1281 
1282 bool
is_public() const1283 pgp_key_t::is_public() const
1284 {
1285     return is_public_key_pkt(pkt_.tag);
1286 }
1287 
1288 bool
is_secret() const1289 pgp_key_t::is_secret() const
1290 {
1291     return is_secret_key_pkt(pkt_.tag);
1292 }
1293 
1294 bool
is_primary() const1295 pgp_key_t::is_primary() const
1296 {
1297     return is_primary_key_pkt(pkt_.tag);
1298 }
1299 
1300 bool
is_subkey() const1301 pgp_key_t::is_subkey() const
1302 {
1303     return is_subkey_pkt(pkt_.tag);
1304 }
1305 
1306 bool
is_locked() const1307 pgp_key_t::is_locked() const
1308 {
1309     if (!is_secret()) {
1310         RNP_LOG("key is not a secret key");
1311         return false;
1312     }
1313     return encrypted();
1314 }
1315 
1316 bool
is_protected() const1317 pgp_key_t::is_protected() const
1318 {
1319     // sanity check
1320     if (!is_secret()) {
1321         RNP_LOG("Warning: this is not a secret key");
1322     }
1323     return pkt_.sec_protection.s2k.usage != PGP_S2KU_NONE;
1324 }
1325 
1326 bool
valid() const1327 pgp_key_t::valid() const
1328 {
1329     return validity_.validated && validity_.valid && !validity_.expired;
1330 }
1331 
1332 bool
validated() const1333 pgp_key_t::validated() const
1334 {
1335     return validity_.validated;
1336 }
1337 
1338 uint64_t
valid_till_common(bool expiry) const1339 pgp_key_t::valid_till_common(bool expiry) const
1340 {
1341     if (!validated()) {
1342         return 0;
1343     }
1344     uint64_t till = expiration() ? (uint64_t) creation() + expiration() : UINT64_MAX;
1345     if (valid()) {
1346         return till;
1347     }
1348     if (revoked()) {
1349         /* we should not believe to the compromised key at all */
1350         if (revocation_.code == PGP_REVOCATION_COMPROMISED) {
1351             return 0;
1352         }
1353         const pgp_subsig_t &revsig = get_sig(revocation_.sigid);
1354         if (revsig.sig.creation() > creation()) {
1355             /* pick less time from revocation time and expiration time */
1356             return std::min((uint64_t) revsig.sig.creation(), till);
1357         }
1358         return 0;
1359     }
1360     /* if key is not marked as expired then it wasn't valid at all */
1361     return expiry ? till : 0;
1362 }
1363 
1364 uint64_t
valid_till() const1365 pgp_key_t::valid_till() const
1366 {
1367     return valid_till_;
1368 }
1369 
1370 bool
valid_at(uint64_t timestamp) const1371 pgp_key_t::valid_at(uint64_t timestamp) const
1372 {
1373     /* TODO: consider implementing more sophisticated checks, as key validity time could
1374      * possibly be non-continuous */
1375     return (timestamp >= creation()) && timestamp && (timestamp <= valid_till());
1376 }
1377 
1378 const pgp_key_id_t &
keyid() const1379 pgp_key_t::keyid() const
1380 {
1381     return keyid_;
1382 }
1383 
1384 const pgp_fingerprint_t &
fp() const1385 pgp_key_t::fp() const
1386 {
1387     return fingerprint_;
1388 }
1389 
1390 const pgp_key_grip_t &
grip() const1391 pgp_key_t::grip() const
1392 {
1393     return grip_;
1394 }
1395 
1396 const pgp_fingerprint_t &
primary_fp() const1397 pgp_key_t::primary_fp() const
1398 {
1399     if (!primary_fp_set_) {
1400         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
1401     }
1402     return primary_fp_;
1403 }
1404 
1405 bool
has_primary_fp() const1406 pgp_key_t::has_primary_fp() const
1407 {
1408     return primary_fp_set_;
1409 }
1410 
1411 void
unset_primary_fp()1412 pgp_key_t::unset_primary_fp()
1413 {
1414     primary_fp_set_ = false;
1415     primary_fp_ = {};
1416 }
1417 
1418 void
link_subkey_fp(pgp_key_t & subkey)1419 pgp_key_t::link_subkey_fp(pgp_key_t &subkey)
1420 {
1421     if (!is_primary() || !subkey.is_subkey()) {
1422         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
1423     }
1424     subkey.primary_fp_ = fp();
1425     subkey.primary_fp_set_ = true;
1426     add_subkey_fp(subkey.fp());
1427 }
1428 
1429 void
add_subkey_fp(const pgp_fingerprint_t & fp)1430 pgp_key_t::add_subkey_fp(const pgp_fingerprint_t &fp)
1431 {
1432     if (std::find(subkey_fps_.begin(), subkey_fps_.end(), fp) == subkey_fps_.end()) {
1433         subkey_fps_.push_back(fp);
1434     }
1435 }
1436 
1437 size_t
subkey_count() const1438 pgp_key_t::subkey_count() const
1439 {
1440     return subkey_fps_.size();
1441 }
1442 
1443 void
remove_subkey_fp(const pgp_fingerprint_t & fp)1444 pgp_key_t::remove_subkey_fp(const pgp_fingerprint_t &fp)
1445 {
1446     auto it = std::find(subkey_fps_.begin(), subkey_fps_.end(), fp);
1447     if (it != subkey_fps_.end()) {
1448         subkey_fps_.erase(it);
1449     }
1450 }
1451 
1452 const pgp_fingerprint_t &
get_subkey_fp(size_t idx) const1453 pgp_key_t::get_subkey_fp(size_t idx) const
1454 {
1455     return subkey_fps_[idx];
1456 }
1457 
1458 const std::vector<pgp_fingerprint_t> &
subkey_fps() const1459 pgp_key_t::subkey_fps() const
1460 {
1461     return subkey_fps_;
1462 }
1463 
1464 size_t
rawpkt_count() const1465 pgp_key_t::rawpkt_count() const
1466 {
1467     if (format == PGP_KEY_STORE_G10) {
1468         return 1;
1469     }
1470     return 1 + uid_count() + sig_count();
1471 }
1472 
1473 pgp_rawpacket_t &
rawpkt()1474 pgp_key_t::rawpkt()
1475 {
1476     return rawpkt_;
1477 }
1478 
1479 const pgp_rawpacket_t &
rawpkt() const1480 pgp_key_t::rawpkt() const
1481 {
1482     return rawpkt_;
1483 }
1484 
1485 void
set_rawpkt(const pgp_rawpacket_t & src)1486 pgp_key_t::set_rawpkt(const pgp_rawpacket_t &src)
1487 {
1488     rawpkt_ = src;
1489 }
1490 
1491 bool
unlock(const pgp_password_provider_t & provider,pgp_op_t op)1492 pgp_key_t::unlock(const pgp_password_provider_t &provider, pgp_op_t op)
1493 {
1494     // sanity checks
1495     if (!is_secret()) {
1496         RNP_LOG("key is not a secret key");
1497         return false;
1498     }
1499     // see if it's already unlocked
1500     if (!is_locked()) {
1501         return true;
1502     }
1503 
1504     pgp_password_ctx_t ctx = {.op = (uint8_t) op, .key = this};
1505     pgp_key_pkt_t *    decrypted_seckey = pgp_decrypt_seckey(*this, provider, ctx);
1506     if (!decrypted_seckey) {
1507         return false;
1508     }
1509 
1510     // this shouldn't really be necessary, but just in case
1511     forget_secret_key_fields(&pkt_.material);
1512     // copy the decrypted mpis into the pgp_key_t
1513     pkt_.material = decrypted_seckey->material;
1514     pkt_.material.secret = true;
1515     delete decrypted_seckey;
1516     return true;
1517 }
1518 
1519 bool
lock()1520 pgp_key_t::lock()
1521 {
1522     // sanity checks
1523     if (!is_secret()) {
1524         RNP_LOG("invalid args");
1525         return false;
1526     }
1527 
1528     // see if it's already locked
1529     if (is_locked()) {
1530         return true;
1531     }
1532 
1533     forget_secret_key_fields(&pkt_.material);
1534     return true;
1535 }
1536 
1537 bool
protect(const rnp_key_protection_params_t & protection,const pgp_password_provider_t & password_provider,rnp::RNG & rng)1538 pgp_key_t::protect(const rnp_key_protection_params_t &protection,
1539                    const pgp_password_provider_t &    password_provider,
1540                    rnp::RNG &                         rng)
1541 {
1542     pgp_password_ctx_t ctx;
1543     memset(&ctx, 0, sizeof(ctx));
1544     ctx.op = PGP_OP_PROTECT;
1545     ctx.key = this;
1546 
1547     // ask the provider for a password
1548     rnp::secure_array<char, MAX_PASSWORD_LENGTH> password;
1549     if (!pgp_request_password(&password_provider, &ctx, password.data(), password.size())) {
1550         return false;
1551     }
1552     return protect(pkt_, protection, password.data(), rng);
1553 }
1554 
1555 bool
protect(pgp_key_pkt_t & decrypted,const rnp_key_protection_params_t & protection,const std::string & new_password,rnp::RNG & rng)1556 pgp_key_t::protect(pgp_key_pkt_t &                    decrypted,
1557                    const rnp_key_protection_params_t &protection,
1558                    const std::string &                new_password,
1559                    rnp::RNG &                         rng)
1560 {
1561     if (!is_secret()) {
1562         RNP_LOG("Warning: this is not a secret key");
1563         return false;
1564     }
1565     bool ownpkt = &decrypted == &pkt_;
1566     if (!decrypted.material.secret) {
1567         RNP_LOG("Decrypted secret key must be provided");
1568         return false;
1569     }
1570 
1571     /* force encrypted-and-hashed and iterated-and-salted as it's the only method we support*/
1572     pkt_.sec_protection.s2k.usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
1573     pkt_.sec_protection.s2k.specifier = PGP_S2KS_ITERATED_AND_SALTED;
1574     /* use default values where needed */
1575     pkt_.sec_protection.symm_alg =
1576       protection.symm_alg ? protection.symm_alg : DEFAULT_PGP_SYMM_ALG;
1577     pkt_.sec_protection.cipher_mode =
1578       protection.cipher_mode ? protection.cipher_mode : DEFAULT_PGP_CIPHER_MODE;
1579     pkt_.sec_protection.s2k.hash_alg =
1580       protection.hash_alg ? protection.hash_alg : DEFAULT_PGP_HASH_ALG;
1581     auto iter = protection.iterations;
1582     if (!iter) {
1583         iter = pgp_s2k_compute_iters(
1584           pkt_.sec_protection.s2k.hash_alg, DEFAULT_S2K_MSEC, DEFAULT_S2K_TUNE_MSEC);
1585     }
1586     pkt_.sec_protection.s2k.iterations = pgp_s2k_round_iterations(iter);
1587     if (!ownpkt) {
1588         /* decrypted is assumed to be temporary variable so we may modify it */
1589         decrypted.sec_protection = pkt_.sec_protection;
1590     }
1591 
1592     /* write the protected key to raw packet */
1593     return write_sec_rawpkt(decrypted, new_password, rng);
1594 }
1595 
1596 bool
unprotect(const pgp_password_provider_t & password_provider,rnp::RNG & rng)1597 pgp_key_t::unprotect(const pgp_password_provider_t &password_provider, rnp::RNG &rng)
1598 {
1599     /* sanity check */
1600     if (!is_secret()) {
1601         RNP_LOG("Warning: this is not a secret key");
1602         return false;
1603     }
1604     /* already unprotected */
1605     if (!is_protected()) {
1606         return true;
1607     }
1608     /* simple case */
1609     if (!encrypted()) {
1610         pkt_.sec_protection.s2k.usage = PGP_S2KU_NONE;
1611         return write_sec_rawpkt(pkt_, "", rng);
1612     }
1613 
1614     pgp_password_ctx_t ctx;
1615     memset(&ctx, 0, sizeof(ctx));
1616     ctx.op = PGP_OP_UNPROTECT;
1617     ctx.key = this;
1618 
1619     pgp_key_pkt_t *decrypted_seckey = pgp_decrypt_seckey(*this, password_provider, ctx);
1620     if (!decrypted_seckey) {
1621         return false;
1622     }
1623     decrypted_seckey->sec_protection.s2k.usage = PGP_S2KU_NONE;
1624     if (!write_sec_rawpkt(*decrypted_seckey, "", rng)) {
1625         delete decrypted_seckey;
1626         return false;
1627     }
1628     pkt_ = std::move(*decrypted_seckey);
1629     /* current logic is that unprotected key should be additionally unlocked */
1630     forget_secret_key_fields(&pkt_.material);
1631     delete decrypted_seckey;
1632     return true;
1633 }
1634 
1635 void
write(pgp_dest_t & dst) const1636 pgp_key_t::write(pgp_dest_t &dst) const
1637 {
1638     /* write key rawpacket */
1639     rawpkt_.write(dst);
1640 
1641     if (format == PGP_KEY_STORE_G10) {
1642         return;
1643     }
1644 
1645     /* write signatures on key */
1646     for (auto &sigid : keysigs_) {
1647         get_sig(sigid).rawpkt.write(dst);
1648     }
1649 
1650     /* write uids and their signatures */
1651     for (const auto &uid : uids_) {
1652         uid.rawpkt.write(dst);
1653         for (size_t idx = 0; idx < uid.sig_count(); idx++) {
1654             get_sig(uid.get_sig(idx)).rawpkt.write(dst);
1655         }
1656     }
1657 }
1658 
1659 void
write_xfer(pgp_dest_t & dst,const rnp_key_store_t * keyring) const1660 pgp_key_t::write_xfer(pgp_dest_t &dst, const rnp_key_store_t *keyring) const
1661 {
1662     write(dst);
1663     if (dst.werr) {
1664         RNP_LOG("Failed to export primary key");
1665         return;
1666     }
1667 
1668     if (!keyring) {
1669         return;
1670     }
1671 
1672     // Export subkeys
1673     for (auto &fp : subkey_fps_) {
1674         const pgp_key_t *subkey = rnp_key_store_get_key_by_fpr(keyring, fp);
1675         if (!subkey) {
1676             char fphex[PGP_FINGERPRINT_SIZE * 2 + 1] = {0};
1677             rnp::hex_encode(
1678               fp.fingerprint, fp.length, fphex, sizeof(fphex), rnp::HEX_LOWERCASE);
1679             RNP_LOG("Warning! Subkey %s not found.", fphex);
1680             continue;
1681         }
1682         subkey->write(dst);
1683         if (dst.werr) {
1684             RNP_LOG("Error occurred when exporting a subkey");
1685             return;
1686         }
1687     }
1688 }
1689 
1690 bool
write_autocrypt(pgp_dest_t & dst,pgp_key_t & sub,uint32_t uid)1691 pgp_key_t::write_autocrypt(pgp_dest_t &dst, pgp_key_t &sub, uint32_t uid)
1692 {
1693     pgp_subsig_t *cert = latest_uid_selfcert(uid);
1694     if (!cert) {
1695         RNP_LOG("No valid uid certification");
1696         return false;
1697     }
1698     pgp_subsig_t *binding = sub.latest_binding();
1699     if (!binding) {
1700         RNP_LOG("No valid binding for subkey");
1701         return false;
1702     }
1703     /* write all or nothing */
1704     pgp_dest_t memdst = {};
1705     if (init_mem_dest(&memdst, NULL, 0)) {
1706         RNP_LOG("Allocation failed");
1707         return false;
1708     }
1709 
1710     bool res = false;
1711     try {
1712         if (is_secret()) {
1713             pgp_key_pkt_t pkt(pkt_, true);
1714             pkt.write(memdst);
1715         } else {
1716             pkt().write(memdst);
1717         }
1718         get_uid(uid).pkt.write(memdst);
1719         cert->sig.write(memdst);
1720         if (sub.is_secret()) {
1721             pgp_key_pkt_t pkt(sub.pkt(), true);
1722             pkt.write(memdst);
1723         } else {
1724             sub.pkt().write(memdst);
1725         }
1726         binding->sig.write(memdst);
1727         dst_write(&dst, mem_dest_get_memory(&memdst), memdst.writeb);
1728         res = !dst.werr;
1729     } catch (const std::exception &e) {
1730         RNP_LOG("%s", e.what());
1731     }
1732     dst_close(&memdst, true);
1733     return res;
1734 }
1735 
1736 /* look only for primary userids */
1737 #define PGP_UID_PRIMARY ((uint32_t) -2)
1738 /* look for any uid, except PGP_UID_NONE) */
1739 #define PGP_UID_ANY ((uint32_t) -3)
1740 
1741 pgp_subsig_t *
latest_selfsig(uint32_t uid)1742 pgp_key_t::latest_selfsig(uint32_t uid)
1743 {
1744     uint32_t      latest = 0;
1745     pgp_subsig_t *res = nullptr;
1746 
1747     for (auto &sigid : sigs_) {
1748         auto &sig = get_sig(sigid);
1749         if (!sig.valid()) {
1750             continue;
1751         }
1752         bool skip = false;
1753         switch (uid) {
1754         case PGP_UID_NONE:
1755             skip = (sig.uid != PGP_UID_NONE) || !is_direct_self(sig);
1756             break;
1757         case PGP_UID_PRIMARY: {
1758             pgp_sig_subpkt_t *subpkt = sig.sig.get_subpkt(PGP_SIG_SUBPKT_PRIMARY_USER_ID);
1759             skip = !is_self_cert(sig) || !subpkt || !subpkt->fields.primary_uid ||
1760                    (sig.uid == PGP_UID_NONE);
1761             break;
1762         }
1763         case PGP_UID_ANY:
1764             skip = !is_self_cert(sig) || (sig.uid == PGP_UID_NONE);
1765             break;
1766         default:
1767             skip = (sig.uid != uid) || !is_self_cert(sig);
1768             break;
1769         }
1770         if (skip) {
1771             continue;
1772         }
1773 
1774         uint32_t creation = sig.sig.creation();
1775         if (creation >= latest) {
1776             latest = creation;
1777             res = &sig;
1778         }
1779     }
1780 
1781     /* if there is later self-sig for the same uid without primary flag, then drop res */
1782     if ((uid == PGP_UID_PRIMARY) && res) {
1783         pgp_subsig_t *overres = latest_selfsig(res->uid);
1784         if (overres && (overres->sig.creation() > res->sig.creation())) {
1785             res = nullptr;
1786         }
1787     }
1788     return res;
1789 }
1790 
1791 pgp_subsig_t *
latest_binding(bool validated)1792 pgp_key_t::latest_binding(bool validated)
1793 {
1794     uint32_t      latest = 0;
1795     pgp_subsig_t *res = NULL;
1796 
1797     for (auto &sigid : sigs_) {
1798         auto &sig = get_sig(sigid);
1799         if (validated && !sig.valid()) {
1800             continue;
1801         }
1802         if (!is_binding(sig)) {
1803             continue;
1804         }
1805 
1806         uint32_t creation = sig.sig.creation();
1807         if (creation >= latest) {
1808             latest = creation;
1809             res = &sig;
1810         }
1811     }
1812     return res;
1813 }
1814 
1815 pgp_subsig_t *
latest_uid_selfcert(uint32_t uid)1816 pgp_key_t::latest_uid_selfcert(uint32_t uid)
1817 {
1818     uint32_t      latest = 0;
1819     pgp_subsig_t *res = NULL;
1820 
1821     if (uid >= uids_.size()) {
1822         return NULL;
1823     }
1824 
1825     for (size_t idx = 0; idx < uids_[uid].sig_count(); idx++) {
1826         auto &sig = get_sig(uids_[uid].get_sig(idx));
1827         if (!sig.valid() || (sig.uid != uid)) {
1828             continue;
1829         }
1830         if (!is_self_cert(sig)) {
1831             continue;
1832         }
1833 
1834         uint32_t creation = sig.sig.creation();
1835         if (creation >= latest) {
1836             latest = creation;
1837             res = &sig;
1838         }
1839     }
1840     return res;
1841 }
1842 
1843 bool
is_signer(const pgp_subsig_t & sig) const1844 pgp_key_t::is_signer(const pgp_subsig_t &sig) const
1845 {
1846     /* if we have fingerprint let's check it */
1847     if (sig.sig.has_keyfp()) {
1848         return sig.sig.keyfp() == fp();
1849     }
1850     if (!sig.sig.has_keyid()) {
1851         return false;
1852     }
1853     return keyid() == sig.sig.keyid();
1854 }
1855 
1856 bool
expired_with(const pgp_subsig_t & sig) const1857 pgp_key_t::expired_with(const pgp_subsig_t &sig) const
1858 {
1859     /* key expiration: absence of subpkt or 0 means it never expires */
1860     uint64_t expiration = sig.sig.key_expiration();
1861     if (!expiration) {
1862         return false;
1863     }
1864     uint64_t now = time(NULL);
1865     return expiration + creation() < now;
1866 }
1867 
1868 bool
is_self_cert(const pgp_subsig_t & sig) const1869 pgp_key_t::is_self_cert(const pgp_subsig_t &sig) const
1870 {
1871     return is_primary() && sig.is_cert() && is_signer(sig);
1872 }
1873 
1874 bool
is_direct_self(const pgp_subsig_t & sig) const1875 pgp_key_t::is_direct_self(const pgp_subsig_t &sig) const
1876 {
1877     return is_primary() && (sig.sig.type() == PGP_SIG_DIRECT) && is_signer(sig);
1878 }
1879 
1880 bool
is_revocation(const pgp_subsig_t & sig) const1881 pgp_key_t::is_revocation(const pgp_subsig_t &sig) const
1882 {
1883     return is_primary() ? (sig.sig.type() == PGP_SIG_REV_KEY) :
1884                           (sig.sig.type() == PGP_SIG_REV_SUBKEY);
1885 }
1886 
1887 bool
is_uid_revocation(const pgp_subsig_t & sig) const1888 pgp_key_t::is_uid_revocation(const pgp_subsig_t &sig) const
1889 {
1890     return is_primary() && (sig.sig.type() == PGP_SIG_REV_CERT);
1891 }
1892 
1893 bool
is_binding(const pgp_subsig_t & sig) const1894 pgp_key_t::is_binding(const pgp_subsig_t &sig) const
1895 {
1896     return is_subkey() && (sig.sig.type() == PGP_SIG_SUBKEY);
1897 }
1898 
1899 void
validate_sig(const pgp_key_t & key,pgp_subsig_t & sig,const rnp::SecurityContext & ctx) const1900 pgp_key_t::validate_sig(const pgp_key_t &           key,
1901                         pgp_subsig_t &              sig,
1902                         const rnp::SecurityContext &ctx) const noexcept
1903 {
1904     sig.validity.reset();
1905 
1906     pgp_signature_info_t sinfo = {};
1907     sinfo.sig = &sig.sig;
1908     sinfo.signer_valid = true;
1909     if (key.is_self_cert(sig) || key.is_binding(sig)) {
1910         sinfo.ignore_expiry = true;
1911     }
1912 
1913     pgp_sig_type_t stype = sig.sig.type();
1914     try {
1915         switch (stype) {
1916         case PGP_SIG_BINARY:
1917         case PGP_SIG_TEXT:
1918         case PGP_SIG_STANDALONE:
1919         case PGP_SIG_PRIMARY:
1920             RNP_LOG("Invalid key signature type: %d", (int) stype);
1921             return;
1922         case PGP_CERT_GENERIC:
1923         case PGP_CERT_PERSONA:
1924         case PGP_CERT_CASUAL:
1925         case PGP_CERT_POSITIVE:
1926         case PGP_SIG_REV_CERT: {
1927             if (sig.uid >= key.uid_count()) {
1928                 RNP_LOG("Userid not found");
1929                 return;
1930             }
1931             validate_cert(sinfo, key.pkt(), key.get_uid(sig.uid).pkt, ctx);
1932             break;
1933         }
1934         case PGP_SIG_SUBKEY:
1935             if (!is_signer(sig)) {
1936                 RNP_LOG("Invalid subkey binding's signer.");
1937                 return;
1938             }
1939             validate_binding(sinfo, key, ctx);
1940             break;
1941         case PGP_SIG_DIRECT:
1942         case PGP_SIG_REV_KEY:
1943             validate_direct(sinfo, ctx);
1944             break;
1945         case PGP_SIG_REV_SUBKEY:
1946             if (!is_signer(sig)) {
1947                 RNP_LOG("Invalid subkey revocation's signer.");
1948                 return;
1949             }
1950             validate_sub_rev(sinfo, key.pkt(), ctx);
1951             break;
1952         default:
1953             RNP_LOG("Unsupported key signature type: %d", (int) stype);
1954             return;
1955         }
1956     } catch (const std::exception &e) {
1957         RNP_LOG("Key signature validation failed: %s", e.what());
1958     }
1959 
1960     sig.validity.validated = true;
1961     sig.validity.valid = sinfo.valid;
1962     /* revocation signature cannot expire */
1963     if ((stype != PGP_SIG_REV_KEY) && (stype != PGP_SIG_REV_SUBKEY) &&
1964         (stype != PGP_SIG_REV_CERT)) {
1965         sig.validity.expired = sinfo.expired;
1966     }
1967 }
1968 
1969 void
validate_sig(pgp_signature_info_t & sinfo,rnp::Hash & hash,const rnp::SecurityContext & ctx) const1970 pgp_key_t::validate_sig(pgp_signature_info_t &      sinfo,
1971                         rnp::Hash &                 hash,
1972                         const rnp::SecurityContext &ctx) const noexcept
1973 {
1974     sinfo.no_signer = false;
1975     sinfo.valid = false;
1976     sinfo.expired = false;
1977 
1978     /* Validate signature itself */
1979     if (sinfo.signer_valid || valid_at(sinfo.sig->creation())) {
1980         sinfo.valid = !signature_validate(*sinfo.sig, pkt_.material, hash, ctx);
1981     } else {
1982         sinfo.valid = false;
1983         RNP_LOG("invalid or untrusted key");
1984     }
1985 
1986     /* Check signature's expiration time */
1987     uint32_t now = time(NULL);
1988     uint32_t create = sinfo.sig->creation();
1989     uint32_t expiry = sinfo.sig->expiration();
1990     if (create > now) {
1991         /* signature created later then now */
1992         RNP_LOG("signature created %d seconds in future", (int) (create - now));
1993         sinfo.expired = true;
1994     }
1995     if (create && expiry && (create + expiry < now)) {
1996         /* signature expired */
1997         RNP_LOG("signature expired");
1998         sinfo.expired = true;
1999     }
2000 
2001     /* check key creation time vs signature creation */
2002     if (creation() > create) {
2003         RNP_LOG("key is newer than signature");
2004         sinfo.valid = false;
2005     }
2006 
2007     /* check whether key was not expired when sig created */
2008     if (!sinfo.ignore_expiry && expiration() && (creation() + expiration() < create)) {
2009         RNP_LOG("signature made after key expiration");
2010         sinfo.valid = false;
2011     }
2012 
2013     /* Check signer's fingerprint */
2014     if (sinfo.sig->has_keyfp() && (sinfo.sig->keyfp() != fp())) {
2015         RNP_LOG("issuer fingerprint doesn't match signer's one");
2016         sinfo.valid = false;
2017     }
2018 
2019     /* Check for unknown critical notations */
2020     for (auto &subpkt : sinfo.sig->subpkts) {
2021         if (!subpkt.critical || (subpkt.type != PGP_SIG_SUBPKT_NOTATION_DATA)) {
2022             continue;
2023         }
2024         std::string name(subpkt.fields.notation.name,
2025                          subpkt.fields.notation.name + subpkt.fields.notation.nlen);
2026         RNP_LOG("unknown critical notation: %s", name.c_str());
2027         sinfo.valid = false;
2028     }
2029 }
2030 
2031 void
validate_cert(pgp_signature_info_t & sinfo,const pgp_key_pkt_t & key,const pgp_userid_pkt_t & uid,const rnp::SecurityContext & ctx) const2032 pgp_key_t::validate_cert(pgp_signature_info_t &      sinfo,
2033                          const pgp_key_pkt_t &       key,
2034                          const pgp_userid_pkt_t &    uid,
2035                          const rnp::SecurityContext &ctx) const
2036 {
2037     rnp::Hash hash;
2038     signature_hash_certification(*sinfo.sig, key, uid, hash);
2039     validate_sig(sinfo, hash, ctx);
2040 }
2041 
2042 void
validate_binding(pgp_signature_info_t & sinfo,const pgp_key_t & subkey,const rnp::SecurityContext & ctx) const2043 pgp_key_t::validate_binding(pgp_signature_info_t &      sinfo,
2044                             const pgp_key_t &           subkey,
2045                             const rnp::SecurityContext &ctx) const
2046 {
2047     rnp::Hash hash;
2048     signature_hash_binding(*sinfo.sig, pkt(), subkey.pkt(), hash);
2049     validate_sig(sinfo, hash, ctx);
2050     if (!sinfo.valid || !(sinfo.sig->key_flags() & PGP_KF_SIGN)) {
2051         return;
2052     }
2053 
2054     /* check primary key binding signature if any */
2055     sinfo.valid = false;
2056     pgp_sig_subpkt_t *subpkt = sinfo.sig->get_subpkt(PGP_SIG_SUBPKT_EMBEDDED_SIGNATURE, false);
2057     if (!subpkt) {
2058         RNP_LOG("error! no primary key binding signature");
2059         return;
2060     }
2061     if (!subpkt->parsed) {
2062         RNP_LOG("invalid embedded signature subpacket");
2063         return;
2064     }
2065     if (subpkt->fields.sig->type() != PGP_SIG_PRIMARY) {
2066         RNP_LOG("invalid primary key binding signature");
2067         return;
2068     }
2069     if (subpkt->fields.sig->version < PGP_V4) {
2070         RNP_LOG("invalid primary key binding signature version");
2071         return;
2072     }
2073 
2074     signature_hash_binding(*subpkt->fields.sig, pkt(), subkey.pkt(), hash);
2075     pgp_signature_info_t bindinfo = {};
2076     bindinfo.sig = subpkt->fields.sig;
2077     bindinfo.signer_valid = true;
2078     bindinfo.ignore_expiry = true;
2079     subkey.validate_sig(bindinfo, hash, ctx);
2080     sinfo.valid = bindinfo.valid && !bindinfo.expired;
2081 }
2082 
2083 void
validate_sub_rev(pgp_signature_info_t & sinfo,const pgp_key_pkt_t & subkey,const rnp::SecurityContext & ctx) const2084 pgp_key_t::validate_sub_rev(pgp_signature_info_t &      sinfo,
2085                             const pgp_key_pkt_t &       subkey,
2086                             const rnp::SecurityContext &ctx) const
2087 {
2088     rnp::Hash hash;
2089     signature_hash_binding(*sinfo.sig, pkt(), subkey, hash);
2090     validate_sig(sinfo, hash, ctx);
2091 }
2092 
2093 void
validate_direct(pgp_signature_info_t & sinfo,const rnp::SecurityContext & ctx) const2094 pgp_key_t::validate_direct(pgp_signature_info_t &sinfo, const rnp::SecurityContext &ctx) const
2095 {
2096     rnp::Hash hash;
2097     signature_hash_direct(*sinfo.sig, pkt(), hash);
2098     validate_sig(sinfo, hash, ctx);
2099 }
2100 
2101 void
validate_self_signatures(const rnp::SecurityContext & ctx)2102 pgp_key_t::validate_self_signatures(const rnp::SecurityContext &ctx)
2103 {
2104     for (auto &sigid : sigs_) {
2105         pgp_subsig_t &sig = get_sig(sigid);
2106         if (sig.validity.validated) {
2107             continue;
2108         }
2109 
2110         if (is_direct_self(sig) || is_self_cert(sig) || is_uid_revocation(sig) ||
2111             is_revocation(sig)) {
2112             validate_sig(*this, sig, ctx);
2113         }
2114     }
2115 }
2116 
2117 void
validate_self_signatures(pgp_key_t & primary,const rnp::SecurityContext & ctx)2118 pgp_key_t::validate_self_signatures(pgp_key_t &primary, const rnp::SecurityContext &ctx)
2119 {
2120     for (auto &sigid : sigs_) {
2121         pgp_subsig_t &sig = get_sig(sigid);
2122         if (sig.validity.validated) {
2123             continue;
2124         }
2125 
2126         if (is_binding(sig) || is_revocation(sig)) {
2127             primary.validate_sig(*this, sig, ctx);
2128         }
2129     }
2130 }
2131 
2132 void
validate_primary(rnp_key_store_t & keyring)2133 pgp_key_t::validate_primary(rnp_key_store_t &keyring)
2134 {
2135     /* validate signatures if needed */
2136     validate_self_signatures(keyring.secctx);
2137 
2138     /* consider public key as valid on this level if it is not expired and has at least one
2139      * valid self-signature, and is not revoked */
2140     validity_.reset();
2141     validity_.validated = true;
2142     bool has_cert = false;
2143     bool has_expired = false;
2144     /* check whether key is revoked */
2145     for (auto &sigid : sigs_) {
2146         pgp_subsig_t &sig = get_sig(sigid);
2147         if (!sig.valid()) {
2148             continue;
2149         }
2150         if (is_revocation(sig)) {
2151             return;
2152         }
2153     }
2154     /* if we have direct-key signature, then it has higher priority for expiration check */
2155     pgp_subsig_t *dirsig = latest_selfsig(PGP_UID_NONE);
2156     if (dirsig) {
2157         has_expired = expired_with(*dirsig);
2158         has_cert = !has_expired;
2159     }
2160     /* if we have primary uid and it is more restrictive, then use it as well */
2161     pgp_subsig_t *prisig = NULL;
2162     if (!has_expired && (prisig = latest_selfsig(PGP_UID_PRIMARY))) {
2163         has_expired = expired_with(*prisig);
2164         has_cert = !has_expired;
2165     }
2166     /* if we don't have direct-key sig and primary uid, use the latest self-cert */
2167     pgp_subsig_t *latest = NULL;
2168     if (!dirsig && !prisig && (latest = latest_selfsig(PGP_UID_ANY))) {
2169         has_expired = expired_with(*latest);
2170         has_cert = !has_expired;
2171     }
2172 
2173     /* we have at least one non-expiring key self-signature */
2174     if (has_cert) {
2175         validity_.valid = true;
2176         return;
2177     }
2178     /* we have valid self-signature which expires key */
2179     if (has_expired) {
2180         validity_.expired = true;
2181         return;
2182     }
2183 
2184     /* let's check whether key has at least one valid subkey binding */
2185     for (size_t i = 0; i < subkey_count(); i++) {
2186         pgp_key_t *sub = pgp_key_get_subkey(this, &keyring, i);
2187         if (!sub) {
2188             continue;
2189         }
2190         sub->validate_self_signatures(*this, keyring.secctx);
2191         pgp_subsig_t *sig = sub->latest_binding();
2192         if (!sig) {
2193             continue;
2194         }
2195         /* check whether subkey is expired - then do not mark key as valid */
2196         if (sub->expired_with(*sig)) {
2197             continue;
2198         }
2199         validity_.valid = true;
2200         return;
2201     }
2202 }
2203 
2204 void
validate_subkey(pgp_key_t * primary,const rnp::SecurityContext & ctx)2205 pgp_key_t::validate_subkey(pgp_key_t *primary, const rnp::SecurityContext &ctx)
2206 {
2207     /* consider subkey as valid on this level if it has valid primary key, has at least one
2208      * non-expired binding signature, and is not revoked. */
2209     validity_.reset();
2210     validity_.validated = true;
2211     if (!primary || !primary->valid()) {
2212         return;
2213     }
2214     /* validate signatures if needed */
2215     validate_self_signatures(*primary, ctx);
2216 
2217     bool has_binding = false;
2218     bool has_expired = false;
2219     for (auto &sigid : sigs_) {
2220         pgp_subsig_t &sig = get_sig(sigid);
2221         if (!sig.valid()) {
2222             continue;
2223         }
2224 
2225         if (is_binding(sig) && !has_binding) {
2226             /* check whether subkey is expired */
2227             if (expired_with(sig)) {
2228                 has_expired = true;
2229                 continue;
2230             }
2231             has_binding = true;
2232         } else if (is_revocation(sig)) {
2233             return;
2234         }
2235     }
2236     validity_.valid = has_binding;
2237     if (!validity_.valid) {
2238         validity_.expired = has_expired;
2239     }
2240 }
2241 
2242 void
validate(rnp_key_store_t & keyring)2243 pgp_key_t::validate(rnp_key_store_t &keyring)
2244 {
2245     validity_.reset();
2246     if (!is_subkey()) {
2247         validate_primary(keyring);
2248     } else {
2249         pgp_key_t *primary = NULL;
2250         if (has_primary_fp()) {
2251             primary = rnp_key_store_get_key_by_fpr(&keyring, primary_fp());
2252         }
2253         validate_subkey(primary, keyring.secctx);
2254     }
2255 }
2256 
2257 void
revalidate(rnp_key_store_t & keyring)2258 pgp_key_t::revalidate(rnp_key_store_t &keyring)
2259 {
2260     if (is_subkey()) {
2261         pgp_key_t *primary = rnp_key_store_get_primary_key(&keyring, this);
2262         if (primary) {
2263             primary->revalidate(keyring);
2264         } else {
2265             validate_subkey(NULL, keyring.secctx);
2266         }
2267         return;
2268     }
2269 
2270     validate(keyring);
2271     if (!refresh_data(keyring.secctx)) {
2272         RNP_LOG("Failed to refresh key data");
2273     }
2274     /* validate/re-validate all subkeys as well */
2275     for (auto &fp : subkey_fps_) {
2276         pgp_key_t *subkey = rnp_key_store_get_key_by_fpr(&keyring, fp);
2277         if (subkey) {
2278             subkey->validate_subkey(this, keyring.secctx);
2279             if (!subkey->refresh_data(this, keyring.secctx)) {
2280                 RNP_LOG("Failed to refresh subkey data");
2281             }
2282         }
2283     }
2284 }
2285 
2286 void
mark_valid()2287 pgp_key_t::mark_valid()
2288 {
2289     validity_.mark_valid();
2290     for (size_t i = 0; i < sig_count(); i++) {
2291         get_sig(i).validity.mark_valid();
2292     }
2293 }
2294 
2295 void
sign_init(pgp_signature_t & sig,pgp_hash_alg_t hash) const2296 pgp_key_t::sign_init(pgp_signature_t &sig, pgp_hash_alg_t hash) const
2297 {
2298     sig.version = PGP_V4;
2299     sig.halg = pgp_hash_adjust_alg_to_key(hash, &pkt_);
2300     sig.palg = alg();
2301     sig.set_keyfp(fp());
2302     sig.set_creation(time(NULL));
2303     sig.set_keyid(keyid());
2304 }
2305 
2306 void
sign_cert(const pgp_key_pkt_t & key,const pgp_userid_pkt_t & uid,pgp_signature_t & sig,rnp::SecurityContext & ctx)2307 pgp_key_t::sign_cert(const pgp_key_pkt_t &   key,
2308                      const pgp_userid_pkt_t &uid,
2309                      pgp_signature_t &       sig,
2310                      rnp::SecurityContext &  ctx)
2311 {
2312     rnp::Hash hash;
2313     sig.fill_hashed_data();
2314     signature_hash_certification(sig, key, uid, hash);
2315     signature_calculate(sig, pkt_.material, hash, ctx);
2316 }
2317 
2318 void
sign_direct(const pgp_key_pkt_t & key,pgp_signature_t & sig,rnp::SecurityContext & ctx)2319 pgp_key_t::sign_direct(const pgp_key_pkt_t & key,
2320                        pgp_signature_t &     sig,
2321                        rnp::SecurityContext &ctx)
2322 {
2323     rnp::Hash hash;
2324     sig.fill_hashed_data();
2325     signature_hash_direct(sig, key, hash);
2326     signature_calculate(sig, pkt_.material, hash, ctx);
2327 }
2328 
2329 void
sign_binding(const pgp_key_pkt_t & key,pgp_signature_t & sig,rnp::SecurityContext & ctx)2330 pgp_key_t::sign_binding(const pgp_key_pkt_t & key,
2331                         pgp_signature_t &     sig,
2332                         rnp::SecurityContext &ctx)
2333 {
2334     rnp::Hash hash;
2335     sig.fill_hashed_data();
2336     if (is_primary()) {
2337         signature_hash_binding(sig, pkt(), key, hash);
2338     } else {
2339         signature_hash_binding(sig, key, pkt(), hash);
2340     }
2341     signature_calculate(sig, pkt_.material, hash, ctx);
2342 }
2343 
2344 void
gen_revocation(const pgp_revoke_t & revoke,pgp_hash_alg_t hash,const pgp_key_pkt_t & key,pgp_signature_t & sig,rnp::SecurityContext & ctx)2345 pgp_key_t::gen_revocation(const pgp_revoke_t &  revoke,
2346                           pgp_hash_alg_t        hash,
2347                           const pgp_key_pkt_t & key,
2348                           pgp_signature_t &     sig,
2349                           rnp::SecurityContext &ctx)
2350 {
2351     sign_init(sig, hash);
2352     sig.set_type(is_primary_key_pkt(key.tag) ? PGP_SIG_REV_KEY : PGP_SIG_REV_SUBKEY);
2353     sig.set_revocation_reason(revoke.code, revoke.reason);
2354 
2355     if (is_primary_key_pkt(key.tag)) {
2356         sign_direct(key, sig, ctx);
2357     } else {
2358         sign_binding(key, sig, ctx);
2359     }
2360 }
2361 
2362 void
sign_subkey_binding(pgp_key_t & sub,pgp_signature_t & sig,rnp::SecurityContext & ctx,bool subsign)2363 pgp_key_t::sign_subkey_binding(pgp_key_t &           sub,
2364                                pgp_signature_t &     sig,
2365                                rnp::SecurityContext &ctx,
2366                                bool                  subsign)
2367 {
2368     if (!is_primary()) {
2369         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
2370     }
2371     sign_binding(sub.pkt(), sig, ctx);
2372     /* add primary key binding subpacket if requested */
2373     if (subsign) {
2374         pgp_signature_t embsig;
2375         sub.sign_init(embsig, sig.halg);
2376         embsig.set_type(PGP_SIG_PRIMARY);
2377         sub.sign_binding(pkt(), embsig, ctx);
2378         sig.set_embedded_sig(embsig);
2379     }
2380 }
2381 
2382 void
add_uid_cert(rnp_selfsig_cert_info_t & cert,pgp_hash_alg_t hash,rnp::SecurityContext & ctx,pgp_key_t * pubkey)2383 pgp_key_t::add_uid_cert(rnp_selfsig_cert_info_t &cert,
2384                         pgp_hash_alg_t           hash,
2385                         rnp::SecurityContext &   ctx,
2386                         pgp_key_t *              pubkey)
2387 {
2388     if (!cert.userid[0]) {
2389         /* todo: why not to allow empty uid? */
2390         RNP_LOG("wrong parameters");
2391         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
2392     }
2393     // userids are only valid for primary keys, not subkeys
2394     if (!is_primary()) {
2395         RNP_LOG("cannot add a userid to a subkey");
2396         throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
2397     }
2398     // see if the key already has this userid
2399     if (has_uid((const char *) cert.userid)) {
2400         RNP_LOG("key already has this userid");
2401         throw rnp::rnp_exception(RNP_ERROR_BAD_PARAMETERS);
2402     }
2403     // this isn't really valid for this format
2404     if (format == PGP_KEY_STORE_G10) {
2405         RNP_LOG("Unsupported key store type");
2406         throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
2407     }
2408     // We only support modifying v4 and newer keys
2409     if (pkt().version < PGP_V4) {
2410         RNP_LOG("adding a userid to V2/V3 key is not supported");
2411         throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
2412     }
2413     /* TODO: if key has at least one uid then has_primary_uid() will be always true! */
2414     if (has_primary_uid() && cert.primary) {
2415         RNP_LOG("changing the primary userid is not supported");
2416         throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
2417     }
2418 
2419     /* Fill the transferable userid */
2420     pgp_userid_pkt_t uid;
2421     pgp_signature_t  sig;
2422     sign_init(sig, hash);
2423     cert.populate(uid, sig);
2424     try {
2425         sign_cert(pkt_, uid, sig, ctx);
2426     } catch (const std::exception &e) {
2427         RNP_LOG("Failed to certify: %s", e.what());
2428         throw;
2429     }
2430     /* add uid and signature to the key and pubkey, if non-NULL */
2431     uids_.emplace_back(uid);
2432     add_sig(sig, uid_count() - 1);
2433     refresh_data(ctx);
2434     if (!pubkey) {
2435         return;
2436     }
2437     pubkey->uids_.emplace_back(uid);
2438     pubkey->add_sig(sig, pubkey->uid_count() - 1);
2439     pubkey->refresh_data(ctx);
2440 }
2441 
2442 void
add_sub_binding(pgp_key_t & subsec,pgp_key_t & subpub,const rnp_selfsig_binding_info_t & binding,pgp_hash_alg_t hash,rnp::SecurityContext & ctx)2443 pgp_key_t::add_sub_binding(pgp_key_t &                       subsec,
2444                            pgp_key_t &                       subpub,
2445                            const rnp_selfsig_binding_info_t &binding,
2446                            pgp_hash_alg_t                    hash,
2447                            rnp::SecurityContext &            ctx)
2448 {
2449     if (!is_primary()) {
2450         RNP_LOG("must be called on primary key");
2451         throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
2452     }
2453 
2454     /* populate signature */
2455     pgp_signature_t sig;
2456     sign_init(sig, hash);
2457     sig.set_type(PGP_SIG_SUBKEY);
2458     if (binding.key_expiration) {
2459         sig.set_key_expiration(binding.key_expiration);
2460     }
2461     if (binding.key_flags) {
2462         sig.set_key_flags(binding.key_flags);
2463     }
2464     /* calculate binding */
2465     pgp_key_flags_t realkf = (pgp_key_flags_t) binding.key_flags;
2466     if (!realkf) {
2467         realkf = pgp_pk_alg_capabilities(subsec.alg());
2468     }
2469     sign_subkey_binding(subsec, sig, ctx, realkf & PGP_KF_SIGN);
2470     /* add to the secret and public key */
2471     subsec.add_sig(sig);
2472     subpub.add_sig(sig);
2473 }
2474 
2475 bool
refresh_data(const rnp::SecurityContext & ctx)2476 pgp_key_t::refresh_data(const rnp::SecurityContext &ctx)
2477 {
2478     if (!is_primary()) {
2479         RNP_LOG("key must be primary");
2480         return false;
2481     }
2482     /* validate self-signatures if not done yet */
2483     validate_self_signatures(ctx);
2484     /* key expiration */
2485     expiration_ = 0;
2486     /* if we have direct-key signature, then it has higher priority */
2487     pgp_subsig_t *dirsig = latest_selfsig(PGP_UID_NONE);
2488     if (dirsig) {
2489         expiration_ = dirsig->sig.key_expiration();
2490     }
2491     /* if we have primary uid and it is more restrictive, then use it as well */
2492     pgp_subsig_t *prisig = latest_selfsig(PGP_UID_PRIMARY);
2493     if (prisig && prisig->sig.key_expiration() &&
2494         (!expiration_ || (prisig->sig.key_expiration() < expiration_))) {
2495         expiration_ = prisig->sig.key_expiration();
2496     }
2497     /* if we don't have direct-key sig and primary uid, use the latest self-cert */
2498     pgp_subsig_t *latest = latest_selfsig(PGP_UID_ANY);
2499     if (!dirsig && !prisig && latest) {
2500         expiration_ = latest->sig.key_expiration();
2501     }
2502     /* key flags: check in direct-key sig first, then primary uid, and then latest */
2503     if (dirsig && dirsig->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
2504         flags_ = dirsig->key_flags;
2505     } else if (prisig && prisig->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
2506         flags_ = prisig->key_flags;
2507     } else if (latest && latest->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
2508         flags_ = latest->key_flags;
2509     } else {
2510         flags_ = pgp_pk_alg_capabilities(alg());
2511     }
2512     /* revocation(s) */
2513     clear_revokes();
2514     for (size_t i = 0; i < sig_count(); i++) {
2515         pgp_subsig_t &sig = get_sig(i);
2516         if (!sig.valid()) {
2517             continue;
2518         }
2519         try {
2520             if (is_revocation(sig)) {
2521                 if (revoked_) {
2522                     continue;
2523                 }
2524                 revoked_ = true;
2525                 revocation_ = pgp_revoke_t(sig);
2526             } else if (is_uid_revocation(sig)) {
2527                 if (sig.uid >= uid_count()) {
2528                     RNP_LOG("Invalid uid index");
2529                     continue;
2530                 }
2531                 pgp_userid_t &uid = get_uid(sig.uid);
2532                 if (uid.revoked) {
2533                     continue;
2534                 }
2535                 uid.revoked = true;
2536                 uid.revocation = pgp_revoke_t(sig);
2537             }
2538         } catch (const std::exception &e) {
2539             RNP_LOG("%s", e.what());
2540             return false;
2541         }
2542     }
2543     /* valid till */
2544     valid_till_ = valid_till_common(expired());
2545     /* userid validities */
2546     for (size_t i = 0; i < uid_count(); i++) {
2547         get_uid(i).valid = false;
2548     }
2549     for (size_t i = 0; i < sig_count(); i++) {
2550         pgp_subsig_t &sig = get_sig(i);
2551         /* consider userid as valid if it has at least one non-expired self-sig */
2552         if (!sig.valid() || !sig.is_cert() || !is_signer(sig) || sig.expired()) {
2553             continue;
2554         }
2555         if (sig.uid >= uid_count()) {
2556             continue;
2557         }
2558         get_uid(sig.uid).valid = true;
2559     }
2560     /* check whether uid is revoked */
2561     for (size_t i = 0; i < uid_count(); i++) {
2562         pgp_userid_t &uid = get_uid(i);
2563         if (uid.revoked) {
2564             uid.valid = false;
2565         }
2566     }
2567     /* primary userid: use latest one which is not overriden by later non-primary selfsig */
2568     uid0_set_ = false;
2569     if (prisig && get_uid(prisig->uid).valid) {
2570         uid0_ = prisig->uid;
2571         uid0_set_ = true;
2572     }
2573     return true;
2574 }
2575 
2576 bool
refresh_data(pgp_key_t * primary,const rnp::SecurityContext & ctx)2577 pgp_key_t::refresh_data(pgp_key_t *primary, const rnp::SecurityContext &ctx)
2578 {
2579     /* validate self-signatures if not done yet */
2580     if (primary) {
2581         validate_self_signatures(*primary, ctx);
2582     }
2583     pgp_subsig_t *sig = latest_binding(primary);
2584     /* subkey expiration */
2585     expiration_ = sig ? sig->sig.key_expiration() : 0;
2586     /* subkey flags */
2587     if (sig && sig->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
2588         flags_ = sig->key_flags;
2589     } else {
2590         flags_ = pgp_pk_alg_capabilities(alg());
2591     }
2592     /* revocation */
2593     clear_revokes();
2594     for (size_t i = 0; i < sig_count(); i++) {
2595         pgp_subsig_t &sig = get_sig(i);
2596         if (!sig.valid() || !is_revocation(sig)) {
2597             continue;
2598         }
2599         revoked_ = true;
2600         try {
2601             revocation_ = pgp_revoke_t(sig);
2602         } catch (const std::exception &e) {
2603             RNP_LOG("%s", e.what());
2604             return false;
2605         }
2606         break;
2607     }
2608     /* valid till */
2609     if (primary) {
2610         valid_till_ =
2611           std::min(primary->valid_till(), valid_till_common(expired() || primary->expired()));
2612     } else {
2613         valid_till_ = valid_till_common(expired());
2614     }
2615     return true;
2616 }
2617 
2618 void
merge_validity(const pgp_validity_t & src)2619 pgp_key_t::merge_validity(const pgp_validity_t &src)
2620 {
2621     validity_.valid = validity_.valid && src.valid;
2622     /* We may safely leave validated status only if both merged keys are valid && validated.
2623      * Otherwise we'll need to revalidate. For instance, one validated but invalid key may add
2624      * revocation signature, or valid key may add certification to the invalid one. */
2625     validity_.validated = validity_.valid && validity_.validated && src.validated;
2626     /* if expired is true at least in one case then valid and validated are false */
2627     validity_.expired = false;
2628 }
2629 
2630 bool
merge(const pgp_key_t & src)2631 pgp_key_t::merge(const pgp_key_t &src)
2632 {
2633     if (is_subkey() || src.is_subkey()) {
2634         RNP_LOG("wrong key merge call");
2635         return false;
2636     }
2637 
2638     pgp_transferable_key_t dstkey;
2639     if (transferable_key_from_key(dstkey, *this)) {
2640         RNP_LOG("failed to get transferable key from dstkey");
2641         return false;
2642     }
2643 
2644     pgp_transferable_key_t srckey;
2645     if (transferable_key_from_key(srckey, src)) {
2646         RNP_LOG("failed to get transferable key from srckey");
2647         return false;
2648     }
2649 
2650     /* if src is secret key then merged key will become secret as well. */
2651     if (is_secret_key_pkt(srckey.key.tag) && !is_secret_key_pkt(dstkey.key.tag)) {
2652         pgp_key_pkt_t tmp = dstkey.key;
2653         dstkey.key = srckey.key;
2654         srckey.key = tmp;
2655         /* no subkey processing here - they are separated from the main key */
2656     }
2657 
2658     if (transferable_key_merge(dstkey, srckey)) {
2659         RNP_LOG("failed to merge transferable keys");
2660         return false;
2661     }
2662 
2663     pgp_key_t tmpkey;
2664     try {
2665         tmpkey = std::move(dstkey);
2666         for (auto &fp : subkey_fps()) {
2667             tmpkey.add_subkey_fp(fp);
2668         }
2669         for (auto &fp : src.subkey_fps()) {
2670             tmpkey.add_subkey_fp(fp);
2671         }
2672     } catch (const std::exception &e) {
2673         RNP_LOG("failed to process key/add subkey fps: %s", e.what());
2674         return false;
2675     }
2676     /* check whether key was unlocked and assign secret key data */
2677     if (is_secret() && !is_locked()) {
2678         /* we may do thing below only because key material is opaque structure without
2679          * pointers! */
2680         tmpkey.pkt().material = pkt().material;
2681     } else if (src.is_secret() && !src.is_locked()) {
2682         tmpkey.pkt().material = src.pkt().material;
2683     }
2684     /* copy validity status */
2685     tmpkey.validity_ = validity_;
2686     tmpkey.merge_validity(src.validity_);
2687 
2688     *this = std::move(tmpkey);
2689     return true;
2690 }
2691 
2692 bool
merge(const pgp_key_t & src,pgp_key_t * primary)2693 pgp_key_t::merge(const pgp_key_t &src, pgp_key_t *primary)
2694 {
2695     if (!is_subkey() || !src.is_subkey()) {
2696         RNP_LOG("wrong subkey merge call");
2697         return false;
2698     }
2699 
2700     pgp_transferable_subkey_t dstkey;
2701     if (transferable_subkey_from_key(dstkey, *this)) {
2702         RNP_LOG("failed to get transferable key from dstkey");
2703         return false;
2704     }
2705 
2706     pgp_transferable_subkey_t srckey;
2707     if (transferable_subkey_from_key(srckey, src)) {
2708         RNP_LOG("failed to get transferable key from srckey");
2709         return false;
2710     }
2711 
2712     /* if src is secret key then merged key will become secret as well. */
2713     if (is_secret_key_pkt(srckey.subkey.tag) && !is_secret_key_pkt(dstkey.subkey.tag)) {
2714         pgp_key_pkt_t tmp = dstkey.subkey;
2715         dstkey.subkey = srckey.subkey;
2716         srckey.subkey = tmp;
2717     }
2718 
2719     if (transferable_subkey_merge(dstkey, srckey)) {
2720         RNP_LOG("failed to merge transferable subkeys");
2721         return false;
2722     }
2723 
2724     pgp_key_t tmpkey;
2725     try {
2726         tmpkey = pgp_key_t(dstkey, primary);
2727     } catch (const std::exception &e) {
2728         RNP_LOG("failed to process subkey: %s", e.what());
2729         return false;
2730     }
2731 
2732     /* check whether key was unlocked and assign secret key data */
2733     if (is_secret() && !is_locked()) {
2734         /* we may do thing below only because key material is opaque structure without
2735          * pointers! */
2736         tmpkey.pkt().material = pkt().material;
2737     } else if (src.is_secret() && !src.is_locked()) {
2738         tmpkey.pkt().material = src.pkt().material;
2739     }
2740     /* copy validity status */
2741     tmpkey.validity_ = validity_;
2742     tmpkey.merge_validity(src.validity_);
2743 
2744     *this = std::move(tmpkey);
2745     return true;
2746 }
2747 
2748 size_t
bits() const2749 pgp_key_material_t::bits() const
2750 {
2751     switch (alg) {
2752     case PGP_PKA_RSA:
2753     case PGP_PKA_RSA_ENCRYPT_ONLY:
2754     case PGP_PKA_RSA_SIGN_ONLY:
2755         return 8 * mpi_bytes(&rsa.n);
2756     case PGP_PKA_DSA:
2757         return 8 * mpi_bytes(&dsa.p);
2758     case PGP_PKA_ELGAMAL:
2759     case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
2760         return 8 * mpi_bytes(&eg.y);
2761     case PGP_PKA_ECDH:
2762     case PGP_PKA_ECDSA:
2763     case PGP_PKA_EDDSA:
2764     case PGP_PKA_SM2: {
2765         // bn_num_bytes returns value <= curve order
2766         const ec_curve_desc_t *curve = get_curve_desc(ec.curve);
2767         return curve ? curve->bitlen : 0;
2768     }
2769     default:
2770         RNP_LOG("Unknown public key alg: %d", (int) alg);
2771         return 0;
2772     }
2773 }
2774 
2775 size_t
qbits() const2776 pgp_key_material_t::qbits() const
2777 {
2778     if (alg != PGP_PKA_DSA) {
2779         return 0;
2780     }
2781     return 8 * mpi_bytes(&dsa.q);
2782 }
2783 
2784 void
validate(rnp::SecurityContext & ctx,bool reset)2785 pgp_key_material_t::validate(rnp::SecurityContext &ctx, bool reset)
2786 {
2787     if (!reset && validity.validated) {
2788         return;
2789     }
2790     validity.reset();
2791     validity.valid = !validate_pgp_key_material(this, &ctx.rng);
2792     validity.validated = true;
2793 }
2794 
2795 bool
valid() const2796 pgp_key_material_t::valid() const
2797 {
2798     return validity.validated && validity.valid;
2799 }
2800