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