Line | Count | Source |
1 | | /* import.c - import a key into our key storage. |
2 | | * Copyright (C) 1998-2007, 2010-2011 Free Software Foundation, Inc. |
3 | | * Copyright (C) 2014, 2016, 2017, 2019 Werner Koch |
4 | | * |
5 | | * This file is part of GnuPG. |
6 | | * |
7 | | * GnuPG is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * GnuPG is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #include <config.h> |
22 | | #include <stdio.h> |
23 | | #include <stdlib.h> |
24 | | #include <string.h> |
25 | | #include <errno.h> |
26 | | |
27 | | #include "gpg.h" |
28 | | #include "options.h" |
29 | | #include "packet.h" |
30 | | #include "../common/status.h" |
31 | | #include "keydb.h" |
32 | | #include "../common/util.h" |
33 | | #include "trustdb.h" |
34 | | #include "main.h" |
35 | | #include "../common/i18n.h" |
36 | | #include "../common/ttyio.h" |
37 | | #include "../common/recsel.h" |
38 | | #include "keyserver-internal.h" |
39 | | #include "call-agent.h" |
40 | | #include "../common/membuf.h" |
41 | | #include "../common/init.h" |
42 | | #include "../common/mbox-util.h" |
43 | | #include "key-check.h" |
44 | | #include "key-clean.h" |
45 | | |
46 | | |
47 | | struct import_stats_s |
48 | | { |
49 | | ulong count; |
50 | | ulong no_user_id; |
51 | | ulong imported; |
52 | | ulong n_uids; |
53 | | ulong n_sigs; |
54 | | ulong n_subk; |
55 | | ulong unchanged; |
56 | | ulong n_revoc; |
57 | | ulong secret_read; |
58 | | ulong secret_imported; |
59 | | ulong secret_dups; |
60 | | ulong skipped_new_keys; |
61 | | ulong not_imported; |
62 | | ulong n_sigs_cleaned; |
63 | | ulong n_uids_cleaned; |
64 | | ulong v3keys; /* Number of V3 keys seen. */ |
65 | | }; |
66 | | |
67 | | |
68 | | /* Node flag to indicate that a user ID or a subkey has a |
69 | | * valid self-signature. */ |
70 | 41.6k | #define NODE_GOOD_SELFSIG 1 |
71 | | /* Node flag to indicate that a user ID or subkey has |
72 | | * an invalid self-signature. */ |
73 | 33.0k | #define NODE_BAD_SELFSIG 2 |
74 | | /* Node flag to indicate that the node shall be deleted. */ |
75 | 7.84k | #define NODE_DELETION_MARK 4 |
76 | | /* A node flag used to temporary mark a node. */ |
77 | 12.9M | #define NODE_FLAG_A 8 |
78 | | /* A flag used by transfer_secret_keys. */ |
79 | 161 | #define NODE_TRANSFER_SECKEY 16 |
80 | | |
81 | | |
82 | | /* An object and a global instance to store selectors created from |
83 | | * --import-filter keep-uid=EXPR. |
84 | | * --import-filter drop-sig=EXPR. |
85 | | * |
86 | | * FIXME: We should put this into the CTRL object but that requires a |
87 | | * lot more changes right now. For now we use save and restore |
88 | | * function to temporary change them. |
89 | | */ |
90 | | /* Definition of the import filters. */ |
91 | | struct import_filter_s |
92 | | { |
93 | | recsel_expr_t keep_uid; |
94 | | recsel_expr_t drop_sig; |
95 | | }; |
96 | | /* The current instance. */ |
97 | | struct import_filter_s import_filter; |
98 | | |
99 | | |
100 | | static int import (ctrl_t ctrl, |
101 | | IOBUF inp, const char* fname, struct import_stats_s *stats, |
102 | | unsigned char **fpr, size_t *fpr_len, unsigned int options, |
103 | | import_screener_t screener, void *screener_arg, |
104 | | int origin, const char *url); |
105 | | static int read_block (IOBUF a, unsigned int options, |
106 | | PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys); |
107 | | static void revocation_present (ctrl_t ctrl, kbnode_t keyblock); |
108 | | static gpg_error_t import_one (ctrl_t ctrl, |
109 | | kbnode_t keyblock, |
110 | | struct import_stats_s *stats, |
111 | | unsigned char **fpr, size_t *fpr_len, |
112 | | unsigned int options, int from_sk, int silent, |
113 | | import_screener_t screener, void *screener_arg, |
114 | | int origin, const char *url, int *r_valid); |
115 | | static gpg_error_t import_matching_seckeys ( |
116 | | ctrl_t ctrl, kbnode_t seckeys, |
117 | | const byte *mainfpr, size_t mainfprlen, |
118 | | struct import_stats_s *stats, int batch); |
119 | | static gpg_error_t import_secret_one (ctrl_t ctrl, kbnode_t keyblock, |
120 | | struct import_stats_s *stats, int batch, |
121 | | unsigned int options, int for_migration, |
122 | | import_screener_t screener, void *screener_arg, |
123 | | kbnode_t *r_secattic); |
124 | | static int import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, |
125 | | struct import_stats_s *stats); |
126 | | static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, |
127 | | int *non_self); |
128 | | static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, |
129 | | u32 *keyid, unsigned int options, |
130 | | kbnode_t *r_otherrevsigs); |
131 | | static int any_uid_left (kbnode_t keyblock); |
132 | | static void remove_all_non_self_sigs (kbnode_t *keyblock, u32 *keyid); |
133 | | static int merge_blocks (ctrl_t ctrl, unsigned int options, |
134 | | kbnode_t keyblock_orig, |
135 | | kbnode_t keyblock, u32 *keyid, |
136 | | u32 curtime, int origin, const char *url, |
137 | | int *n_uids, int *n_sigs, int *n_subk ); |
138 | | static gpg_error_t append_new_uid (unsigned int options, |
139 | | kbnode_t keyblock, kbnode_t node, |
140 | | u32 curtime, int origin, const char *url, |
141 | | int *n_sigs); |
142 | | static int append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs); |
143 | | static int merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs); |
144 | | static int merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs); |
145 | | |
146 | | |
147 | | |
148 | | static void |
149 | | release_import_filter (import_filter_t filt) |
150 | 0 | { |
151 | 0 | recsel_release (filt->keep_uid); |
152 | 0 | filt->keep_uid = NULL; |
153 | 0 | recsel_release (filt->drop_sig); |
154 | 0 | filt->drop_sig = NULL; |
155 | 0 | } |
156 | | |
157 | | static void |
158 | | cleanup_import_globals (void) |
159 | 0 | { |
160 | 0 | release_import_filter (&import_filter); |
161 | 0 | } |
162 | | |
163 | | |
164 | | int |
165 | | parse_import_options(char *str,unsigned int *options,int noisy) |
166 | 0 | { |
167 | 0 | struct parse_options import_opts[]= |
168 | 0 | { |
169 | 0 | {"import-local-sigs",IMPORT_LOCAL_SIGS,NULL, |
170 | 0 | N_("import signatures that are marked as local-only")}, |
171 | |
|
172 | 0 | {"repair-pks-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL, |
173 | 0 | N_("repair damage from the pks keyserver during import")}, |
174 | |
|
175 | 0 | {"keep-ownertrust", IMPORT_KEEP_OWNERTTRUST, NULL, |
176 | 0 | N_("do not clear the ownertrust values during import")}, |
177 | |
|
178 | 0 | {"fast-import",IMPORT_FAST,NULL, |
179 | 0 | N_("do not update the trustdb after import")}, |
180 | |
|
181 | 0 | {"bulk-import",IMPORT_BULK, NULL, |
182 | 0 | N_("enable bulk import mode")}, |
183 | |
|
184 | 0 | {"import-show",IMPORT_SHOW,NULL, |
185 | 0 | N_("show key during import")}, |
186 | |
|
187 | 0 | {"show-only", (IMPORT_SHOW | IMPORT_DRY_RUN), NULL, |
188 | 0 | N_("show key but do not actually import") }, |
189 | |
|
190 | 0 | {"merge-only",IMPORT_MERGE_ONLY,NULL, |
191 | 0 | N_("only accept updates to existing keys")}, |
192 | |
|
193 | 0 | {"import-clean",IMPORT_CLEAN,NULL, |
194 | 0 | N_("remove unusable parts from key after import")}, |
195 | |
|
196 | 0 | {"import-minimal",IMPORT_MINIMAL|IMPORT_CLEAN,NULL, |
197 | 0 | N_("remove as much as possible from key after import")}, |
198 | |
|
199 | 0 | {"self-sigs-only", IMPORT_SELF_SIGS_ONLY, NULL, |
200 | 0 | N_("ignore key-signatures which are not self-signatures")}, |
201 | |
|
202 | 0 | {"import-export", IMPORT_EXPORT, NULL, |
203 | 0 | N_("run import filters and export key immediately")}, |
204 | |
|
205 | 0 | {"restore", IMPORT_RESTORE, NULL, |
206 | 0 | N_("assume the GnuPG key backup format")}, |
207 | 0 | {"import-restore", IMPORT_RESTORE, NULL, NULL}, |
208 | |
|
209 | 0 | {"repair-keys", IMPORT_REPAIR_KEYS, NULL, |
210 | 0 | N_("repair keys on import")}, |
211 | |
|
212 | 0 | {"force-update", IMPORT_FORCE_UPDATE, NULL, |
213 | 0 | N_("update even unchanged keys")}, |
214 | | |
215 | | /* New options. Right now, without description string. */ |
216 | 0 | {"ignore-attributes", IMPORT_IGNORE_ATTRIBUTES, NULL, NULL}, |
217 | |
|
218 | 0 | {"only-pubkeys", IMPORT_ONLY_PUBKEYS, NULL, |
219 | 0 | N_("do not import secret keys")}, |
220 | | |
221 | | /* Hidden options which are enabled by default and are provided |
222 | | * in case of problems with the respective implementation. */ |
223 | 0 | {"collapse-uids", IMPORT_COLLAPSE_UIDS, NULL, NULL}, |
224 | 0 | {"collapse-subkeys", IMPORT_COLLAPSE_SUBKEYS, NULL, NULL}, |
225 | | |
226 | | /* Debug only options used for regression testings. */ |
227 | 0 | {"debug-accept-no-uid", IMPORT_DEBUG_ACCEPT_NO_UID, NULL, NULL }, |
228 | | |
229 | | /* Aliases for backward compatibility */ |
230 | 0 | {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL}, |
231 | 0 | {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL}, |
232 | | /* dummy */ |
233 | 0 | {"import-unusable-sigs",0,NULL,NULL}, |
234 | 0 | {"import-clean-sigs",0,NULL,NULL}, |
235 | 0 | {"import-clean-uids",0,NULL,NULL}, |
236 | 0 | {"convert-sk-to-pk",0, NULL,NULL}, /* Not anymore needed due to |
237 | | the new design. */ |
238 | 0 | {NULL,0,NULL,NULL} |
239 | 0 | }; |
240 | 0 | int rc; |
241 | 0 | int saved_self_sigs_only, saved_import_clean; |
242 | | |
243 | | /* We need to set flags indicating whether the user has set certain |
244 | | * options or if they came from the default. */ |
245 | 0 | saved_self_sigs_only = (*options & IMPORT_SELF_SIGS_ONLY); |
246 | 0 | saved_self_sigs_only &= ~IMPORT_SELF_SIGS_ONLY; |
247 | 0 | saved_import_clean = (*options & IMPORT_CLEAN); |
248 | 0 | saved_import_clean &= ~IMPORT_CLEAN; |
249 | |
|
250 | 0 | rc = parse_options (str, options, import_opts, noisy); |
251 | |
|
252 | 0 | if (rc && (*options & IMPORT_SELF_SIGS_ONLY)) |
253 | 0 | opt.flags.expl_import_self_sigs_only = 1; |
254 | 0 | else |
255 | 0 | *options |= saved_self_sigs_only; |
256 | |
|
257 | 0 | if (rc && (*options & IMPORT_CLEAN)) |
258 | 0 | opt.flags.expl_import_clean = 1; |
259 | 0 | else |
260 | 0 | *options |= saved_import_clean; |
261 | | |
262 | |
|
263 | 0 | if (rc && (*options & IMPORT_RESTORE)) |
264 | 0 | { |
265 | | /* Alter other options we want or don't want for restore. */ |
266 | 0 | *options |= (IMPORT_LOCAL_SIGS | IMPORT_KEEP_OWNERTTRUST); |
267 | 0 | *options &= ~(IMPORT_MINIMAL | IMPORT_CLEAN |
268 | 0 | | IMPORT_REPAIR_PKS_SUBKEY_BUG |
269 | 0 | | IMPORT_MERGE_ONLY); |
270 | 0 | } |
271 | 0 | return rc; |
272 | 0 | } |
273 | | |
274 | | |
275 | | /* Parse and set an import filter from string. STRING has the format |
276 | | * "NAME=EXPR" with NAME being the name of the filter. Spaces before |
277 | | * and after NAME are not allowed. If this function is all called |
278 | | * several times all expressions for the same NAME are concatenated. |
279 | | * Supported filter names are: |
280 | | * |
281 | | * - keep-uid :: If the expression evaluates to true for a certain |
282 | | * user ID packet, that packet and all it dependencies |
283 | | * will be imported. The expression may use these |
284 | | * variables: |
285 | | * |
286 | | * - uid :: The entire user ID. |
287 | | * - mbox :: The mail box part of the user ID. |
288 | | * - primary :: Evaluate to true for the primary user ID. |
289 | | */ |
290 | | gpg_error_t |
291 | | parse_and_set_import_filter (const char *string) |
292 | 0 | { |
293 | 0 | gpg_error_t err; |
294 | | |
295 | | /* Auto register the cleanup function. */ |
296 | 0 | register_mem_cleanup_func (cleanup_import_globals); |
297 | |
|
298 | 0 | if (!strncmp (string, "keep-uid=", 9)) |
299 | 0 | err = recsel_parse_expr (&import_filter.keep_uid, string+9); |
300 | 0 | else if (!strncmp (string, "drop-sig=", 9)) |
301 | 0 | err = recsel_parse_expr (&import_filter.drop_sig, string+9); |
302 | 0 | else |
303 | 0 | err = gpg_error (GPG_ERR_INV_NAME); |
304 | |
|
305 | 0 | return err; |
306 | 0 | } |
307 | | |
308 | | |
309 | | /* Save the current import filters, return them, and clear the current |
310 | | * filters. Returns NULL on error and sets ERRNO. */ |
311 | | import_filter_t |
312 | | save_and_clear_import_filter (void) |
313 | 0 | { |
314 | 0 | import_filter_t filt; |
315 | |
|
316 | 0 | filt = xtrycalloc (1, sizeof *filt); |
317 | 0 | if (!filt) |
318 | 0 | return NULL; |
319 | 0 | *filt = import_filter; |
320 | 0 | memset (&import_filter, 0, sizeof import_filter); |
321 | |
|
322 | 0 | return filt; |
323 | 0 | } |
324 | | |
325 | | |
326 | | /* Release the current import filters and restore them from NEWFILT. |
327 | | * Ownership of NEWFILT is moved to this function. */ |
328 | | void |
329 | | restore_import_filter (import_filter_t filt) |
330 | 0 | { |
331 | 0 | if (filt) |
332 | 0 | { |
333 | 0 | release_import_filter (&import_filter); |
334 | 0 | import_filter = *filt; |
335 | 0 | xfree (filt); |
336 | 0 | } |
337 | 0 | } |
338 | | |
339 | | |
340 | | import_stats_t |
341 | | import_new_stats_handle (void) |
342 | 7.62k | { |
343 | 7.62k | return xmalloc_clear ( sizeof (struct import_stats_s) ); |
344 | 7.62k | } |
345 | | |
346 | | |
347 | | void |
348 | | import_release_stats_handle (import_stats_t p) |
349 | 7.62k | { |
350 | 7.62k | xfree (p); |
351 | 7.62k | } |
352 | | |
353 | | |
354 | | /* Read a key from a file. Only the first key in the file is |
355 | | * considered and stored at R_KEYBLOCK. FNAME is the name of the |
356 | | * file. |
357 | | */ |
358 | | gpg_error_t |
359 | | read_key_from_file_or_buffer (ctrl_t ctrl, const char *fname, |
360 | | const void *buffer, size_t buflen, |
361 | | kbnode_t *r_keyblock) |
362 | 0 | { |
363 | 0 | gpg_error_t err; |
364 | 0 | iobuf_t inp; |
365 | 0 | PACKET *pending_pkt = NULL; |
366 | 0 | kbnode_t keyblock = NULL; |
367 | 0 | u32 keyid[2]; |
368 | 0 | int v3keys; /* Dummy */ |
369 | 0 | int non_self; /* Dummy */ |
370 | |
|
371 | 0 | (void)ctrl; |
372 | |
|
373 | 0 | *r_keyblock = NULL; |
374 | |
|
375 | 0 | log_assert (!!fname ^ !!buffer); |
376 | | |
377 | 0 | if (fname) |
378 | 0 | { |
379 | 0 | inp = iobuf_open (fname); |
380 | 0 | if (!inp) |
381 | 0 | err = gpg_error_from_syserror (); |
382 | 0 | else if (is_secured_file (iobuf_get_fd (inp))) |
383 | 0 | { |
384 | 0 | iobuf_close (inp); |
385 | 0 | inp = NULL; |
386 | 0 | err = gpg_error (GPG_ERR_EPERM); |
387 | 0 | } |
388 | 0 | else |
389 | 0 | err = 0; |
390 | 0 | if (err) |
391 | 0 | { |
392 | 0 | log_error (_("can't open '%s': %s\n"), |
393 | 0 | iobuf_is_pipe_filename (fname)? "[stdin]": fname, |
394 | 0 | gpg_strerror (err)); |
395 | 0 | if (gpg_err_code (err) == GPG_ERR_ENOENT) |
396 | 0 | err = gpg_error (GPG_ERR_NO_PUBKEY); |
397 | 0 | goto leave; |
398 | 0 | } |
399 | | |
400 | | /* Push the armor filter. */ |
401 | 0 | { |
402 | 0 | armor_filter_context_t *afx; |
403 | 0 | afx = new_armor_context (); |
404 | 0 | afx->only_keyblocks = 1; |
405 | 0 | push_armor_filter (afx, inp); |
406 | 0 | release_armor_context (afx); |
407 | 0 | } |
408 | |
|
409 | 0 | } |
410 | 0 | else /* Read from buffer (No armor expected). */ |
411 | 0 | { |
412 | 0 | inp = iobuf_temp_with_content (buffer, buflen); |
413 | 0 | } |
414 | | |
415 | | /* Read the first non-v3 keyblock. */ |
416 | 0 | while (!(err = read_block (inp, 0, &pending_pkt, &keyblock, &v3keys))) |
417 | 0 | { |
418 | 0 | if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) |
419 | 0 | break; |
420 | 0 | log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); |
421 | 0 | release_kbnode (keyblock); |
422 | 0 | keyblock = NULL; |
423 | 0 | } |
424 | 0 | if (err) |
425 | 0 | { |
426 | 0 | if (gpg_err_code (err) != GPG_ERR_INV_KEYRING) |
427 | 0 | log_error (_("error reading '%s': %s\n"), |
428 | 0 | fname? (iobuf_is_pipe_filename (fname)? "[stdin]": fname) |
429 | 0 | /* */ : "[buffer]", |
430 | 0 | gpg_strerror (err)); |
431 | 0 | goto leave; |
432 | 0 | } |
433 | | |
434 | 0 | keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); |
435 | |
|
436 | 0 | if (!find_next_kbnode (keyblock, PKT_USER_ID)) |
437 | 0 | { |
438 | 0 | err = gpg_error (GPG_ERR_NO_USER_ID); |
439 | 0 | goto leave; |
440 | 0 | } |
441 | | |
442 | | /* We do the collapsing unconditionally although it is expected that |
443 | | * clean keys are provided here. */ |
444 | 0 | collapse_uids (&keyblock); |
445 | 0 | collapse_subkeys (&keyblock); |
446 | |
|
447 | 0 | clear_kbnode_flags (keyblock); |
448 | 0 | if (chk_self_sigs (ctrl, keyblock, keyid, &non_self)) |
449 | 0 | { |
450 | 0 | err = gpg_error (GPG_ERR_INV_KEYRING); |
451 | 0 | goto leave; |
452 | 0 | } |
453 | | |
454 | 0 | if (!delete_inv_parts (ctrl, keyblock, keyid, 0, NULL) ) |
455 | 0 | { |
456 | 0 | err = gpg_error (GPG_ERR_NO_USER_ID); |
457 | 0 | goto leave; |
458 | 0 | } |
459 | | |
460 | 0 | *r_keyblock = keyblock; |
461 | 0 | keyblock = NULL; |
462 | |
|
463 | 0 | leave: |
464 | 0 | if (inp) |
465 | 0 | { |
466 | 0 | iobuf_close (inp); |
467 | | /* Must invalidate that ugly cache to actually close the file. */ |
468 | 0 | if (fname) |
469 | 0 | iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); |
470 | 0 | } |
471 | 0 | release_kbnode (keyblock); |
472 | | /* FIXME: Do we need to free PENDING_PKT ? */ |
473 | 0 | return err; |
474 | 0 | } |
475 | | |
476 | | |
477 | | /* Import an already checked public key which was included in a |
478 | | * signature and the signature verified out using this key. */ |
479 | | gpg_error_t |
480 | | import_included_key_block (ctrl_t ctrl, kbnode_t keyblock) |
481 | 0 | { |
482 | 0 | gpg_error_t err; |
483 | 0 | struct import_stats_s *stats; |
484 | 0 | import_filter_t save_filt; |
485 | 0 | int save_armor = opt.armor; |
486 | |
|
487 | 0 | opt.armor = 0; |
488 | 0 | stats = import_new_stats_handle (); |
489 | 0 | save_filt = save_and_clear_import_filter (); |
490 | 0 | if (!save_filt) |
491 | 0 | { |
492 | 0 | err = gpg_error_from_syserror (); |
493 | 0 | goto leave; |
494 | 0 | } |
495 | | |
496 | | /* FIXME: Should we introduce a dedicated KEYORG ? */ |
497 | 0 | err = import_one (ctrl, keyblock, |
498 | 0 | stats, NULL, 0, 0, 0, 0, |
499 | 0 | NULL, NULL, KEYORG_UNKNOWN, NULL, NULL); |
500 | |
|
501 | 0 | leave: |
502 | 0 | restore_import_filter (save_filt); |
503 | 0 | import_release_stats_handle (stats); |
504 | 0 | opt.armor = save_armor; |
505 | 0 | return err; |
506 | 0 | } |
507 | | |
508 | | |
509 | | |
510 | | /* |
511 | | * Import the public keys from the given filename. Input may be armored. |
512 | | * This function rejects all keys which are not validly self signed on at |
513 | | * least one userid. Only user ids which are self signed will be imported. |
514 | | * Other signatures are not checked. |
515 | | * |
516 | | * Actually this function does a merge. It works like this: |
517 | | * |
518 | | * - get the keyblock |
519 | | * - check self-signatures and remove all userids and their signatures |
520 | | * without/invalid self-signatures. |
521 | | * - reject the keyblock, if we have no valid userid. |
522 | | * - See whether we have this key already in one of our pubrings. |
523 | | * If not, simply add it to the default keyring. |
524 | | * - Compare the key and the self-signatures of the new and the one in |
525 | | * our keyring. If they are different something weird is going on; |
526 | | * ask what to do. |
527 | | * - See whether we have only non-self-signature on one user id; if not |
528 | | * ask the user what to do. |
529 | | * - compare the signatures: If we already have this signature, check |
530 | | * that they compare okay; if not, issue a warning and ask the user. |
531 | | * (consider looking at the timestamp and use the newest?) |
532 | | * - Simply add the signature. Can't verify here because we may not have |
533 | | * the signature's public key yet; verification is done when putting it |
534 | | * into the trustdb, which is done automagically as soon as this pubkey |
535 | | * is used. |
536 | | * - Proceed with next signature. |
537 | | * |
538 | | * Key revocation certificates have special handling. |
539 | | */ |
540 | | static gpg_error_t |
541 | | import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, |
542 | | import_stats_t stats_handle, |
543 | | unsigned char **fpr, size_t *fpr_len, |
544 | | unsigned int options, |
545 | | import_screener_t screener, void *screener_arg, |
546 | | int origin, const char *url) |
547 | 7.62k | { |
548 | 7.62k | int i; |
549 | 7.62k | gpg_error_t err = 0; |
550 | 7.62k | struct import_stats_s *stats = stats_handle; |
551 | | |
552 | 7.62k | if (!stats) |
553 | 7.62k | stats = import_new_stats_handle (); |
554 | | |
555 | 7.62k | if (inp) |
556 | 0 | { |
557 | 0 | err = import (ctrl, inp, "[stream]", stats, fpr, fpr_len, options, |
558 | 0 | screener, screener_arg, origin, url); |
559 | 0 | } |
560 | 7.62k | else |
561 | 7.62k | { |
562 | 7.62k | if (!fnames && !nnames) |
563 | 0 | nnames = 1; /* Ohh what a ugly hack to jump into the loop */ |
564 | | |
565 | 15.2k | for (i=0; i < nnames; i++) |
566 | 7.62k | { |
567 | 7.62k | const char *fname = fnames? fnames[i] : NULL; |
568 | 7.62k | IOBUF inp2 = iobuf_open(fname); |
569 | | |
570 | 7.62k | if (!fname) |
571 | 0 | fname = "[stdin]"; |
572 | 7.62k | if (inp2 && is_secured_file (iobuf_get_fd (inp2))) |
573 | 0 | { |
574 | 0 | iobuf_close (inp2); |
575 | 0 | inp2 = NULL; |
576 | 0 | gpg_err_set_errno (EPERM); |
577 | 0 | } |
578 | 7.62k | if (!inp2) |
579 | 7.62k | log_error (_("can't open '%s': %s\n"), fname, strerror (errno)); |
580 | 7.62k | else |
581 | 7.62k | { |
582 | 7.62k | err = import (ctrl, inp2, fname, stats, fpr, fpr_len, options, |
583 | 7.62k | screener, screener_arg, origin, url); |
584 | 7.62k | iobuf_close (inp2); |
585 | | /* Must invalidate that ugly cache to actually close it. */ |
586 | 7.62k | iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); |
587 | 7.62k | if (err) |
588 | 7.62k | log_error ("import from '%s' failed: %s\n", |
589 | 3.10k | fname, gpg_strerror (err) ); |
590 | 7.62k | } |
591 | 7.62k | if (!fname) |
592 | 0 | break; |
593 | 7.62k | } |
594 | 7.62k | } |
595 | | |
596 | 7.62k | if (!stats_handle) |
597 | 7.62k | { |
598 | 7.62k | if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN)) |
599 | 7.62k | != (IMPORT_SHOW | IMPORT_DRY_RUN)) |
600 | 7.62k | import_print_stats (stats); |
601 | 7.62k | import_release_stats_handle (stats); |
602 | 7.62k | } |
603 | | |
604 | | /* If no fast import and the trustdb is dirty (i.e. we added a key |
605 | | or userID that had something other than a selfsig, a signature |
606 | | that was other than a selfsig, or any revocation), then |
607 | | update/check the trustdb if the user specified by setting |
608 | | interactive or by not setting no-auto-check-trustdb */ |
609 | | |
610 | 7.62k | if (!(options & IMPORT_FAST)) |
611 | 7.62k | check_or_update_trustdb (ctrl); |
612 | | |
613 | 7.62k | return err; |
614 | 7.62k | } |
615 | | |
616 | | |
617 | | void |
618 | | import_keys (ctrl_t ctrl, char **fnames, int nnames, |
619 | | import_stats_t stats_handle, unsigned int options, |
620 | | int origin, const char *url) |
621 | 7.62k | { |
622 | 7.62k | import_keys_internal (ctrl, NULL, fnames, nnames, stats_handle, |
623 | 7.62k | NULL, NULL, options, NULL, NULL, origin, url); |
624 | 7.62k | } |
625 | | |
626 | | |
627 | | gpg_error_t |
628 | | import_keys_es_stream (ctrl_t ctrl, estream_t fp, |
629 | | import_stats_t stats_handle, |
630 | | unsigned char **fpr, size_t *fpr_len, |
631 | | unsigned int options, |
632 | | import_screener_t screener, void *screener_arg, |
633 | | int origin, const char *url) |
634 | 0 | { |
635 | 0 | gpg_error_t err; |
636 | 0 | iobuf_t inp; |
637 | |
|
638 | 0 | inp = iobuf_esopen (fp, "rb", 1, 0); |
639 | 0 | if (!inp) |
640 | 0 | { |
641 | 0 | err = gpg_error_from_syserror (); |
642 | 0 | log_error ("iobuf_esopen failed: %s\n", gpg_strerror (err)); |
643 | 0 | return err; |
644 | 0 | } |
645 | | |
646 | 0 | err = import_keys_internal (ctrl, inp, NULL, 0, stats_handle, |
647 | 0 | fpr, fpr_len, options, |
648 | 0 | screener, screener_arg, origin, url); |
649 | |
|
650 | 0 | iobuf_close (inp); |
651 | 0 | return err; |
652 | 0 | } |
653 | | |
654 | | |
655 | | static int |
656 | | import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, |
657 | | unsigned char **fpr,size_t *fpr_len, unsigned int options, |
658 | | import_screener_t screener, void *screener_arg, |
659 | | int origin, const char *url) |
660 | 7.62k | { |
661 | 7.62k | PACKET *pending_pkt = NULL; |
662 | 7.62k | kbnode_t keyblock = NULL; /* Need to initialize because gcc can't |
663 | | grasp the return semantics of |
664 | | read_block. */ |
665 | 7.62k | kbnode_t secattic = NULL; /* Kludge for PGP desktop percularity */ |
666 | 7.62k | int rc = 0; |
667 | 7.62k | int v3keys; |
668 | | |
669 | 7.62k | getkey_disable_caches (); |
670 | | |
671 | 7.62k | if (!opt.no_armor) /* Armored reading is not disabled. */ |
672 | 7.62k | { |
673 | 7.62k | armor_filter_context_t *afx; |
674 | | |
675 | 7.62k | afx = new_armor_context (); |
676 | 7.62k | afx->only_keyblocks = 1; |
677 | 7.62k | push_armor_filter (afx, inp); |
678 | 7.62k | release_armor_context (afx); |
679 | 7.62k | } |
680 | | |
681 | 24.4k | while (!(rc = read_block (inp, options, &pending_pkt, &keyblock, &v3keys))) |
682 | 16.8k | { |
683 | 16.8k | stats->v3keys += v3keys; |
684 | 16.8k | if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) |
685 | 13.2k | { |
686 | 13.2k | rc = import_one (ctrl, keyblock, |
687 | 13.2k | stats, fpr, fpr_len, options, 0, 0, |
688 | 13.2k | screener, screener_arg, origin, url, NULL); |
689 | 13.2k | if (secattic) |
690 | 25 | { |
691 | 25 | byte tmpfpr[MAX_FINGERPRINT_LEN]; |
692 | 25 | size_t tmpfprlen; |
693 | | |
694 | 25 | if (!rc && !(opt.dry_run || (options & IMPORT_DRY_RUN))) |
695 | 25 | { |
696 | | /* Kudge for PGP desktop - see below. */ |
697 | 25 | fingerprint_from_pk (keyblock->pkt->pkt.public_key, |
698 | 25 | tmpfpr, &tmpfprlen); |
699 | 25 | rc = import_matching_seckeys (ctrl, secattic, |
700 | 25 | tmpfpr, tmpfprlen, |
701 | 25 | stats, opt.batch); |
702 | 25 | } |
703 | 25 | release_kbnode (secattic); |
704 | 25 | secattic = NULL; |
705 | 25 | } |
706 | 13.2k | } |
707 | 3.61k | else if (keyblock->pkt->pkttype == PKT_SECRET_KEY) |
708 | 3.30k | { |
709 | 3.30k | release_kbnode (secattic); |
710 | 3.30k | secattic = NULL; |
711 | 3.30k | rc = import_secret_one (ctrl, keyblock, stats, |
712 | 3.30k | opt.batch, options, 0, |
713 | 3.30k | screener, screener_arg, &secattic); |
714 | 3.30k | keyblock = NULL; /* Ownership was transferred. */ |
715 | 3.30k | if (secattic) |
716 | 1.11k | { |
717 | 1.11k | if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY) |
718 | 1.09k | rc = 0; /* Try import after the next pubkey. */ |
719 | | |
720 | | /* The attic is a workaround for the peculiar PGP |
721 | | * Desktop method of exporting a secret key: The |
722 | | * exported file is the concatenation of two armored |
723 | | * keyblocks; first the private one and then the public |
724 | | * one. The strange thing is that the secret one has no |
725 | | * binding signatures at all and thus we have not |
726 | | * imported it. The attic stores that secret keys and |
727 | | * we try to import it once after the very next public |
728 | | * keyblock. */ |
729 | 1.11k | } |
730 | 3.30k | } |
731 | 307 | else if (keyblock->pkt->pkttype == PKT_SIGNATURE |
732 | 307 | && IS_KEY_REV (keyblock->pkt->pkt.signature) ) |
733 | 307 | { |
734 | 307 | release_kbnode (secattic); |
735 | 307 | secattic = NULL; |
736 | 307 | rc = import_revoke_cert (ctrl, keyblock, options, stats); |
737 | 307 | } |
738 | 0 | else |
739 | 0 | { |
740 | 0 | release_kbnode (secattic); |
741 | 0 | secattic = NULL; |
742 | 0 | log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); |
743 | 0 | } |
744 | 16.8k | release_kbnode (keyblock); |
745 | | |
746 | | /* fixme: we should increment the not imported counter but |
747 | | this does only make sense if we keep on going despite of |
748 | | errors. For now we do this only if the imported key is too |
749 | | large. */ |
750 | 16.8k | if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE |
751 | 0 | && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX) |
752 | 0 | { |
753 | 0 | stats->not_imported++; |
754 | 0 | } |
755 | 16.8k | else if (rc) |
756 | 96 | break; |
757 | | |
758 | 16.8k | if (!(++stats->count % 100) && !opt.quiet) |
759 | 16.8k | log_info (_("%lu keys processed so far\n"), stats->count ); |
760 | | |
761 | 16.8k | if (origin == KEYORG_WKD && stats->count >= 5) |
762 | 0 | { |
763 | | /* We limit the number of keys _received_ from the WKD to 5. |
764 | | * In fact there should be only one key but some sites want |
765 | | * to store a few expired keys there also. gpg's key |
766 | | * selection will later figure out which key to use. Note |
767 | | * that for WKD we always return the fingerprint of the |
768 | | * first imported key. */ |
769 | 0 | log_info ("import from WKD stopped after %d keys\n", 5); |
770 | 0 | break; |
771 | 0 | } |
772 | 16.8k | } |
773 | 7.62k | stats->v3keys += v3keys; |
774 | 7.62k | if (rc == -1) |
775 | 4.51k | rc = 0; |
776 | 3.10k | else if (rc && gpg_err_code (rc) != GPG_ERR_INV_KEYRING) |
777 | 3.10k | log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (rc)); |
778 | | |
779 | 7.62k | release_kbnode (secattic); |
780 | | |
781 | | /* When read_block loop was stopped by error, we have PENDING_PKT left. */ |
782 | 7.62k | if (pending_pkt) |
783 | 3 | { |
784 | 3 | free_packet (pending_pkt, NULL); |
785 | 3 | xfree (pending_pkt); |
786 | 3 | } |
787 | 7.62k | return rc; |
788 | 7.62k | } |
789 | | |
790 | | |
791 | | /* Helper to migrate secring.gpg to GnuPG 2.1. */ |
792 | | gpg_error_t |
793 | | import_old_secring (ctrl_t ctrl, const char *fname) |
794 | 0 | { |
795 | 0 | gpg_error_t err; |
796 | 0 | iobuf_t inp; |
797 | 0 | PACKET *pending_pkt = NULL; |
798 | 0 | kbnode_t keyblock = NULL; /* Need to initialize because gcc can't |
799 | | grasp the return semantics of |
800 | | read_block. */ |
801 | 0 | struct import_stats_s *stats; |
802 | 0 | int v3keys; |
803 | |
|
804 | 0 | inp = iobuf_open (fname); |
805 | 0 | if (inp && is_secured_file (iobuf_get_fd (inp))) |
806 | 0 | { |
807 | 0 | iobuf_close (inp); |
808 | 0 | inp = NULL; |
809 | 0 | gpg_err_set_errno (EPERM); |
810 | 0 | } |
811 | 0 | if (!inp) |
812 | 0 | { |
813 | 0 | err = gpg_error_from_syserror (); |
814 | 0 | log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); |
815 | 0 | return err; |
816 | 0 | } |
817 | | |
818 | 0 | getkey_disable_caches(); |
819 | 0 | stats = import_new_stats_handle (); |
820 | 0 | while (!(err = read_block (inp, 0, &pending_pkt, &keyblock, &v3keys))) |
821 | 0 | { |
822 | 0 | if (keyblock->pkt->pkttype == PKT_SECRET_KEY) |
823 | 0 | { |
824 | 0 | err = import_secret_one (ctrl, keyblock, stats, 1, 0, 1, |
825 | 0 | NULL, NULL, NULL); |
826 | 0 | keyblock = NULL; /* Ownership was transferred. */ |
827 | 0 | } |
828 | 0 | release_kbnode (keyblock); |
829 | 0 | if (err) |
830 | 0 | break; |
831 | 0 | } |
832 | 0 | import_release_stats_handle (stats); |
833 | 0 | if (err == -1) |
834 | 0 | err = 0; |
835 | 0 | else if (err && gpg_err_code (err) != GPG_ERR_INV_KEYRING) |
836 | 0 | log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err)); |
837 | 0 | else if (err) |
838 | 0 | log_error ("import from '%s' failed: %s\n", fname, gpg_strerror (err)); |
839 | |
|
840 | 0 | iobuf_close (inp); |
841 | 0 | iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); |
842 | |
|
843 | 0 | return err; |
844 | 0 | } |
845 | | |
846 | | |
847 | | void |
848 | | import_print_stats (import_stats_t stats) |
849 | 7.62k | { |
850 | 7.62k | if (!opt.quiet) |
851 | 7.62k | { |
852 | 7.62k | log_info(_("Total number processed: %lu\n"), |
853 | 7.62k | stats->count + stats->v3keys); |
854 | 7.62k | if (stats->v3keys) |
855 | 7.62k | log_info(_(" skipped PGP-2 keys: %lu\n"), stats->v3keys); |
856 | 7.62k | if (stats->skipped_new_keys ) |
857 | 7.62k | log_info(_(" skipped new keys: %lu\n"), |
858 | 0 | stats->skipped_new_keys ); |
859 | 7.62k | if (stats->no_user_id ) |
860 | 7.62k | log_info(_(" w/o user IDs: %lu\n"), stats->no_user_id ); |
861 | 7.62k | if (stats->imported) |
862 | 27 | { |
863 | 27 | log_info(_(" imported: %lu"), stats->imported ); |
864 | 27 | log_printf ("\n"); |
865 | 27 | } |
866 | 7.62k | if (stats->unchanged ) |
867 | 7.62k | log_info(_(" unchanged: %lu\n"), stats->unchanged ); |
868 | 7.62k | if (stats->n_uids ) |
869 | 7.62k | log_info(_(" new user IDs: %lu\n"), stats->n_uids ); |
870 | 7.62k | if (stats->n_subk ) |
871 | 7.62k | log_info(_(" new subkeys: %lu\n"), stats->n_subk ); |
872 | 7.62k | if (stats->n_sigs ) |
873 | 7.62k | log_info(_(" new signatures: %lu\n"), stats->n_sigs ); |
874 | 7.62k | if (stats->n_revoc ) |
875 | 7.62k | log_info(_(" new key revocations: %lu\n"), stats->n_revoc ); |
876 | 7.62k | if (stats->secret_read ) |
877 | 7.62k | log_info(_(" secret keys read: %lu\n"), stats->secret_read ); |
878 | 7.62k | if (stats->secret_imported ) |
879 | 7.62k | log_info(_(" secret keys imported: %lu\n"), stats->secret_imported ); |
880 | 7.62k | if (stats->secret_dups ) |
881 | 7.62k | log_info(_(" secret keys unchanged: %lu\n"), stats->secret_dups ); |
882 | 7.62k | if (stats->not_imported ) |
883 | 7.62k | log_info(_(" not imported: %lu\n"), stats->not_imported ); |
884 | 7.62k | if (stats->n_sigs_cleaned) |
885 | 7.62k | log_info(_(" signatures cleaned: %lu\n"),stats->n_sigs_cleaned); |
886 | 7.62k | if (stats->n_uids_cleaned) |
887 | 7.62k | log_info(_(" user IDs cleaned: %lu\n"),stats->n_uids_cleaned); |
888 | 7.62k | } |
889 | | |
890 | 7.62k | if (is_status_enabled ()) |
891 | 0 | { |
892 | 0 | char buf[15*20]; |
893 | |
|
894 | 0 | snprintf (buf, sizeof buf, |
895 | 0 | "%lu %lu %lu 0 %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", |
896 | 0 | stats->count + stats->v3keys, |
897 | 0 | stats->no_user_id, |
898 | 0 | stats->imported, |
899 | 0 | stats->unchanged, |
900 | 0 | stats->n_uids, |
901 | 0 | stats->n_subk, |
902 | 0 | stats->n_sigs, |
903 | 0 | stats->n_revoc, |
904 | 0 | stats->secret_read, |
905 | 0 | stats->secret_imported, |
906 | 0 | stats->secret_dups, |
907 | 0 | stats->skipped_new_keys, |
908 | 0 | stats->not_imported, |
909 | 0 | stats->v3keys ); |
910 | 0 | write_status_text (STATUS_IMPORT_RES, buf); |
911 | 0 | } |
912 | 7.62k | } |
913 | | |
914 | | |
915 | | /* Return true if PKTTYPE is valid in a keyblock. */ |
916 | | static int |
917 | | valid_keyblock_packet (int pkttype) |
918 | 66.4k | { |
919 | 66.4k | switch (pkttype) |
920 | 66.4k | { |
921 | 2.12k | case PKT_PUBLIC_KEY: |
922 | 5.12k | case PKT_PUBLIC_SUBKEY: |
923 | 5.70k | case PKT_SECRET_KEY: |
924 | 8.62k | case PKT_SECRET_SUBKEY: |
925 | 33.4k | case PKT_SIGNATURE: |
926 | 62.5k | case PKT_USER_ID: |
927 | 62.5k | case PKT_ATTRIBUTE: |
928 | 62.5k | case PKT_RING_TRUST: |
929 | 62.5k | return 1; |
930 | 3.83k | default: |
931 | 3.83k | return 0; |
932 | 66.4k | } |
933 | 66.4k | } |
934 | | |
935 | | |
936 | | /* Read the next keyblock from stream A. Meta data (ring trust |
937 | | * packets) are only considered if OPTIONS has the IMPORT_RESTORE flag |
938 | | * set. PENDING_PKT should be initialized to NULL and not changed by |
939 | | * the caller. |
940 | | * |
941 | | * Returns 0 for okay, -1 no more blocks, or any other errorcode. The |
942 | | * integer at R_V3KEY counts the number of unsupported v3 keyblocks. |
943 | | */ |
944 | | static int |
945 | | read_block( IOBUF a, unsigned int options, |
946 | | PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys) |
947 | 24.4k | { |
948 | 24.4k | int rc; |
949 | 24.4k | struct parse_packet_ctx_s parsectx; |
950 | 24.4k | PACKET *pkt; |
951 | 24.4k | kbnode_t root = NULL; |
952 | 24.4k | kbnode_t lastnode = NULL; |
953 | 24.4k | int in_cert, in_v3key, skip_sigs; |
954 | 24.4k | u32 keyid[2]; |
955 | 24.4k | int got_keyid = 0; |
956 | 24.4k | unsigned int dropped_nonselfsigs = 0; |
957 | | |
958 | 24.4k | *r_v3keys = 0; |
959 | | |
960 | 24.4k | if (*pending_pkt) |
961 | 14.5k | { |
962 | 14.5k | root = lastnode = new_kbnode( *pending_pkt ); |
963 | 14.5k | *pending_pkt = NULL; |
964 | 14.5k | log_assert (root->pkt->pkttype == PKT_PUBLIC_KEY |
965 | 14.5k | || root->pkt->pkttype == PKT_SECRET_KEY); |
966 | 14.5k | in_cert = 1; |
967 | 14.5k | keyid_from_pk (root->pkt->pkt.public_key, keyid); |
968 | 14.5k | got_keyid = 1; |
969 | 14.5k | } |
970 | 9.87k | else |
971 | 9.87k | in_cert = 0; |
972 | | |
973 | 24.4k | pkt = xmalloc (sizeof *pkt); |
974 | 24.4k | init_packet (pkt); |
975 | 24.4k | init_parse_packet (&parsectx, a); |
976 | 24.4k | if (!(options & IMPORT_RESTORE)) |
977 | 24.4k | parsectx.skip_meta = 1; |
978 | 24.4k | in_v3key = 0; |
979 | 24.4k | skip_sigs = 0; |
980 | 127k | while ((rc=parse_packet (&parsectx, pkt)) != -1) |
981 | 121k | { |
982 | 121k | if (rc && (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY |
983 | 709 | && (pkt->pkttype == PKT_PUBLIC_KEY |
984 | 388 | || pkt->pkttype == PKT_SECRET_KEY))) |
985 | 708 | { |
986 | 708 | in_v3key = 1; |
987 | 708 | ++*r_v3keys; |
988 | 708 | free_packet (pkt, &parsectx); |
989 | 708 | init_packet (pkt); |
990 | 708 | continue; |
991 | 708 | } |
992 | 120k | else if (rc ) /* (ignore errors) */ |
993 | 5.42k | { |
994 | 5.42k | skip_sigs = 0; |
995 | 5.42k | if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) |
996 | 2.40k | ; /* Do not show a diagnostic. */ |
997 | 3.01k | else if (gpg_err_code (rc) == GPG_ERR_INV_PACKET |
998 | 2.78k | && (pkt->pkttype == PKT_USER_ID |
999 | 2.72k | || pkt->pkttype == PKT_ATTRIBUTE)) |
1000 | 60 | { |
1001 | | /* This indicates a too large user id or attribute |
1002 | | * packet. We skip this packet and all following |
1003 | | * signatures. Sure, this won't allow to repair a |
1004 | | * garbled keyring in case one of the signatures belong |
1005 | | * to another user id. However, this better mitigates |
1006 | | * DoS using inserted user ids. */ |
1007 | 60 | skip_sigs = 1; |
1008 | 60 | } |
1009 | 2.95k | else if (gpg_err_code (rc) == GPG_ERR_INV_PACKET |
1010 | 2.72k | && (pkt->pkttype == PKT_OLD_COMMENT |
1011 | 2.71k | || pkt->pkttype == PKT_COMMENT)) |
1012 | 14 | ; /* Ignore too large comment packets. */ |
1013 | 2.93k | else |
1014 | 2.93k | { |
1015 | 2.93k | log_error("read_block: read error: %s\n", gpg_strerror (rc) ); |
1016 | 2.93k | rc = GPG_ERR_INV_KEYRING; |
1017 | 2.93k | goto ready; |
1018 | 2.93k | } |
1019 | 2.48k | free_packet (pkt, &parsectx); |
1020 | 2.48k | init_packet(pkt); |
1021 | 2.48k | continue; |
1022 | 5.42k | } |
1023 | 115k | else if ((opt.import_options & IMPORT_IGNORE_ATTRIBUTES) |
1024 | 0 | && (pkt->pkttype == PKT_USER_ID || pkt->pkttype == PKT_ATTRIBUTE) |
1025 | 0 | && pkt->pkt.user_id->attrib_data) |
1026 | 0 | { |
1027 | 0 | skip_sigs = 1; |
1028 | 0 | free_packet (pkt, &parsectx); |
1029 | 0 | init_packet (pkt); |
1030 | 0 | continue; |
1031 | 0 | } |
1032 | | |
1033 | 115k | if (skip_sigs) |
1034 | 134 | { |
1035 | 134 | if (pkt->pkttype == PKT_SIGNATURE) |
1036 | 127 | { |
1037 | 127 | free_packet (pkt, &parsectx); |
1038 | 127 | init_packet (pkt); |
1039 | 127 | continue; |
1040 | 127 | } |
1041 | 7 | skip_sigs = 0; |
1042 | 7 | } |
1043 | | |
1044 | 114k | if (in_v3key && !(pkt->pkttype == PKT_PUBLIC_KEY |
1045 | 1.00k | || pkt->pkttype == PKT_SECRET_KEY)) |
1046 | 899 | { |
1047 | 899 | free_packet (pkt, &parsectx); |
1048 | 899 | init_packet(pkt); |
1049 | 899 | continue; |
1050 | 899 | } |
1051 | 114k | in_v3key = 0; |
1052 | | |
1053 | 114k | if (!root && pkt->pkttype == PKT_SIGNATURE |
1054 | 9.82k | && IS_KEY_REV (pkt->pkt.signature) ) |
1055 | 307 | { |
1056 | | /* This is a revocation certificate which is handled in a |
1057 | | * special way. */ |
1058 | 307 | root = new_kbnode( pkt ); |
1059 | 307 | pkt = NULL; |
1060 | 307 | goto ready; |
1061 | 307 | } |
1062 | | |
1063 | | /* Make a linked list of all packets. */ |
1064 | 113k | switch (pkt->pkttype) |
1065 | 113k | { |
1066 | 71 | case PKT_COMPRESSED: |
1067 | 71 | if (!(opt.compat_flags & COMPAT_COMPR_KEYS)) |
1068 | 71 | { |
1069 | 71 | rc = GPG_ERR_UNEXPECTED_PACKET; |
1070 | 71 | goto ready; |
1071 | 71 | } |
1072 | 0 | else if (check_compress_algo (pkt->pkt.compressed->algorithm)) |
1073 | 0 | { |
1074 | 0 | rc = GPG_ERR_COMPR_ALGO; |
1075 | 0 | goto ready; |
1076 | 0 | } |
1077 | 0 | else |
1078 | 0 | { |
1079 | 0 | compress_filter_context_t *cfx = xmalloc_clear( sizeof *cfx ); |
1080 | 0 | pkt->pkt.compressed->buf = NULL; |
1081 | 0 | if (push_compress_filter2 (a, cfx, |
1082 | 0 | pkt->pkt.compressed->algorithm, 1)) |
1083 | 0 | xfree (cfx); /* e.g. in case of compression_algo NONE. */ |
1084 | 0 | } |
1085 | 0 | free_packet (pkt, &parsectx); |
1086 | 0 | init_packet(pkt); |
1087 | 0 | break; |
1088 | | |
1089 | 0 | case PKT_RING_TRUST: |
1090 | | /* Skip those packets unless we are in restore mode. */ |
1091 | 0 | if ((opt.import_options & IMPORT_RESTORE)) |
1092 | 0 | goto x_default; |
1093 | 0 | free_packet (pkt, &parsectx); |
1094 | 0 | init_packet(pkt); |
1095 | 0 | break; |
1096 | | |
1097 | 34.3k | case PKT_SIGNATURE: |
1098 | 34.3k | if (!in_cert) |
1099 | 9.51k | goto x_default; |
1100 | 24.8k | if (!(options & IMPORT_SELF_SIGS_ONLY)) |
1101 | 24.8k | goto x_default; |
1102 | 24.8k | log_assert (got_keyid); |
1103 | 0 | if (pkt->pkt.signature->keyid[0] == keyid[0] |
1104 | 0 | && pkt->pkt.signature->keyid[1] == keyid[1]) |
1105 | 0 | { /* This is likely a self-signature. We import this one. |
1106 | | * Eventually we should use the ISSUER_FPR to compare |
1107 | | * self-signatures, but that will work only for v5 keys |
1108 | | * which are currently not even deployed. |
1109 | | * Note that we do not do any crypto verify here because |
1110 | | * that would defeat this very mitigation of DoS by |
1111 | | * importing a key with a huge amount of faked |
1112 | | * key-signatures. A verification will be done later in |
1113 | | * the processing anyway. Here we want a cheap an early |
1114 | | * way to drop non-self-signatures. */ |
1115 | 0 | goto x_default; |
1116 | 0 | } |
1117 | | /* Skip this signature. */ |
1118 | 0 | dropped_nonselfsigs++; |
1119 | 0 | free_packet (pkt, &parsectx); |
1120 | 0 | init_packet(pkt); |
1121 | 0 | break; |
1122 | | |
1123 | 13.8k | case PKT_PUBLIC_KEY: |
1124 | 17.2k | case PKT_SECRET_KEY: |
1125 | 17.2k | if (!got_keyid) |
1126 | 2.70k | { |
1127 | 2.70k | keyid_from_pk (pkt->pkt.public_key, keyid); |
1128 | 2.70k | got_keyid = 1; |
1129 | 2.70k | } |
1130 | 17.2k | if (in_cert) /* Store this packet. */ |
1131 | 14.5k | { |
1132 | 14.5k | *pending_pkt = pkt; |
1133 | 14.5k | pkt = NULL; |
1134 | 14.5k | goto ready; |
1135 | 14.5k | } |
1136 | 2.70k | in_cert = 1; |
1137 | 2.70k | goto x_default; |
1138 | | |
1139 | 62.0k | default: |
1140 | 99.1k | x_default: |
1141 | 99.1k | if (in_cert && valid_keyblock_packet (pkt->pkttype)) |
1142 | 62.5k | { |
1143 | 62.5k | if (!root ) |
1144 | 2.70k | root = lastnode = new_kbnode (pkt); |
1145 | 59.8k | else |
1146 | 59.8k | { |
1147 | 59.8k | lastnode->next = new_kbnode (pkt); |
1148 | 59.8k | lastnode = lastnode->next; |
1149 | 59.8k | } |
1150 | 62.5k | pkt = xmalloc (sizeof *pkt); |
1151 | 62.5k | } |
1152 | 36.5k | else |
1153 | 36.5k | free_packet (pkt, &parsectx); |
1154 | 99.1k | init_packet(pkt); |
1155 | 99.1k | break; |
1156 | 113k | } |
1157 | 113k | } |
1158 | | |
1159 | 24.4k | ready: |
1160 | 24.4k | if (rc == -1 && root ) |
1161 | 2.03k | rc = 0; |
1162 | | |
1163 | 24.4k | if (rc ) |
1164 | 7.52k | release_kbnode( root ); |
1165 | 16.8k | else |
1166 | 16.8k | *ret_root = root; |
1167 | 24.4k | free_packet (pkt, &parsectx); |
1168 | 24.4k | deinit_parse_packet (&parsectx); |
1169 | 24.4k | xfree( pkt ); |
1170 | 24.4k | if (!rc && dropped_nonselfsigs && opt.verbose) |
1171 | 24.4k | log_info ("key %s: number of dropped non-self-signatures: %u\n", |
1172 | 0 | keystr (keyid), dropped_nonselfsigs); |
1173 | | |
1174 | 24.4k | return rc; |
1175 | 24.4k | } |
1176 | | |
1177 | | |
1178 | | /* Walk through the subkeys on a pk to find if we have the PKS |
1179 | | disease: multiple subkeys with their binding sigs stripped, and the |
1180 | | sig for the first subkey placed after the last subkey. That is, |
1181 | | instead of "pk uid sig sub1 bind1 sub2 bind2 sub3 bind3" we have |
1182 | | "pk uid sig sub1 sub2 sub3 bind1". We can't do anything about sub2 |
1183 | | and sub3, as they are already lost, but we can try and rescue sub1 |
1184 | | by reordering the keyblock so that it reads "pk uid sig sub1 bind1 |
1185 | | sub2 sub3". Returns TRUE if the keyblock was modified. */ |
1186 | | static int |
1187 | | fix_pks_corruption (ctrl_t ctrl, kbnode_t keyblock) |
1188 | 0 | { |
1189 | 0 | int changed = 0; |
1190 | 0 | int keycount = 0; |
1191 | 0 | kbnode_t node; |
1192 | 0 | kbnode_t last = NULL; |
1193 | 0 | kbnode_t sknode=NULL; |
1194 | | |
1195 | | /* First determine if we have the problem at all. Look for 2 or |
1196 | | more subkeys in a row, followed by a single binding sig. */ |
1197 | 0 | for (node=keyblock; node; last=node, node=node->next) |
1198 | 0 | { |
1199 | 0 | if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) |
1200 | 0 | { |
1201 | 0 | keycount++; |
1202 | 0 | if(!sknode) |
1203 | 0 | sknode=node; |
1204 | 0 | } |
1205 | 0 | else if (node->pkt->pkttype == PKT_SIGNATURE |
1206 | 0 | && IS_SUBKEY_SIG (node->pkt->pkt.signature) |
1207 | 0 | && keycount >= 2 |
1208 | 0 | && !node->next) |
1209 | 0 | { |
1210 | | /* We might have the problem, as this key has two subkeys in |
1211 | | a row without any intervening packets. */ |
1212 | | |
1213 | | /* Sanity check */ |
1214 | 0 | if (!last) |
1215 | 0 | break; |
1216 | | |
1217 | | /* Temporarily attach node to sknode. */ |
1218 | 0 | node->next = sknode->next; |
1219 | 0 | sknode->next = node; |
1220 | 0 | last->next = NULL; |
1221 | | |
1222 | | /* Note we aren't checking whether this binding sig is a |
1223 | | selfsig. This is not necessary here as the subkey and |
1224 | | binding sig will be rejected later if that is the |
1225 | | case. */ |
1226 | 0 | if (check_key_signature (ctrl, keyblock,node,NULL)) |
1227 | 0 | { |
1228 | | /* Not a match, so undo the changes. */ |
1229 | 0 | sknode->next = node->next; |
1230 | 0 | last->next = node; |
1231 | 0 | node->next = NULL; |
1232 | 0 | break; |
1233 | 0 | } |
1234 | 0 | else |
1235 | 0 | { |
1236 | | /* Mark it good so we don't need to check it again */ |
1237 | 0 | sknode->flag |= NODE_GOOD_SELFSIG; |
1238 | 0 | changed = 1; |
1239 | 0 | break; |
1240 | 0 | } |
1241 | 0 | } |
1242 | 0 | else |
1243 | 0 | keycount = 0; |
1244 | 0 | } |
1245 | |
|
1246 | 0 | return changed; |
1247 | 0 | } |
1248 | | |
1249 | | |
1250 | | /* Versions of GnuPG before 1.4.11 and 2.0.16 allowed to import bogus |
1251 | | direct key signatures. A side effect of this was that a later |
1252 | | import of the same good direct key signatures was not possible |
1253 | | because the cmp_signature check in merge_blocks considered them |
1254 | | equal. Although direct key signatures are now checked during |
1255 | | import, there might still be bogus signatures sitting in a keyring. |
1256 | | We need to detect and delete them before doing a merge. This |
1257 | | function returns the number of removed sigs. */ |
1258 | | static int |
1259 | | fix_bad_direct_key_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid) |
1260 | 2.99k | { |
1261 | 2.99k | gpg_error_t err; |
1262 | 2.99k | kbnode_t node; |
1263 | 2.99k | int count = 0; |
1264 | | |
1265 | 6.95k | for (node = keyblock->next; node; node=node->next) |
1266 | 6.95k | { |
1267 | 6.95k | if (node->pkt->pkttype == PKT_USER_ID) |
1268 | 2.99k | break; |
1269 | 3.96k | if (node->pkt->pkttype == PKT_SIGNATURE |
1270 | 3.96k | && IS_KEY_SIG (node->pkt->pkt.signature)) |
1271 | 620 | { |
1272 | 620 | err = check_key_signature (ctrl, keyblock, node, NULL); |
1273 | 620 | if (err && gpg_err_code (err) != GPG_ERR_PUBKEY_ALGO ) |
1274 | 602 | { |
1275 | | /* If we don't know the error, we can't decide; this is |
1276 | | not a problem because cmp_signature can't compare the |
1277 | | signature either. */ |
1278 | 602 | log_info ("key %s: invalid direct key signature removed\n", |
1279 | 602 | keystr (keyid)); |
1280 | 602 | delete_kbnode (node); |
1281 | 602 | count++; |
1282 | 602 | } |
1283 | 620 | } |
1284 | 3.96k | } |
1285 | | |
1286 | 2.99k | return count; |
1287 | 2.99k | } |
1288 | | |
1289 | | |
1290 | | static void |
1291 | | print_import_ok (PKT_public_key *pk, unsigned int reason) |
1292 | 0 | { |
1293 | 0 | byte array[MAX_FINGERPRINT_LEN], *s; |
1294 | 0 | char buf[MAX_FINGERPRINT_LEN*2+30], *p; |
1295 | 0 | size_t i, n; |
1296 | |
|
1297 | 0 | snprintf (buf, sizeof buf, "%u ", reason); |
1298 | 0 | p = buf + strlen (buf); |
1299 | |
|
1300 | 0 | fingerprint_from_pk (pk, array, &n); |
1301 | 0 | s = array; |
1302 | 0 | for (i=0; i < n ; i++, s++, p += 2) |
1303 | 0 | sprintf (p, "%02X", *s); |
1304 | |
|
1305 | 0 | write_status_text (STATUS_IMPORT_OK, buf); |
1306 | 0 | } |
1307 | | |
1308 | | |
1309 | | static void |
1310 | | print_import_check (PKT_public_key * pk, PKT_user_id * id) |
1311 | 0 | { |
1312 | 0 | byte hexfpr[2*MAX_FINGERPRINT_LEN+1]; |
1313 | 0 | u32 keyid[2]; |
1314 | |
|
1315 | 0 | keyid_from_pk (pk, keyid); |
1316 | 0 | hexfingerprint (pk, hexfpr, sizeof hexfpr); |
1317 | 0 | write_status_printf (STATUS_IMPORT_CHECK, "%08X%08X %s %s", |
1318 | 0 | keyid[0], keyid[1], hexfpr, id->name); |
1319 | |
|
1320 | 0 | } |
1321 | | |
1322 | | |
1323 | | static void |
1324 | | check_prefs_warning(PKT_public_key *pk) |
1325 | 0 | { |
1326 | 0 | log_info(_("WARNING: key %s contains preferences for unavailable\n" |
1327 | 0 | "algorithms on these user IDs:\n"), keystr_from_pk(pk)); |
1328 | 0 | } |
1329 | | |
1330 | | |
1331 | | static void |
1332 | | check_prefs (ctrl_t ctrl, kbnode_t keyblock) |
1333 | 0 | { |
1334 | 0 | kbnode_t node; |
1335 | 0 | PKT_public_key *pk; |
1336 | 0 | int problem=0; |
1337 | |
|
1338 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
1339 | 0 | pk=keyblock->pkt->pkt.public_key; |
1340 | |
|
1341 | 0 | for(node=keyblock;node;node=node->next) |
1342 | 0 | { |
1343 | 0 | if(node->pkt->pkttype==PKT_USER_ID |
1344 | 0 | && node->pkt->pkt.user_id->created |
1345 | 0 | && node->pkt->pkt.user_id->prefs) |
1346 | 0 | { |
1347 | 0 | PKT_user_id *uid = node->pkt->pkt.user_id; |
1348 | 0 | prefitem_t *prefs = uid->prefs; |
1349 | 0 | char *user = utf8_to_native(uid->name,strlen(uid->name),0); |
1350 | |
|
1351 | 0 | for(;prefs->type;prefs++) |
1352 | 0 | { |
1353 | 0 | char num[10]; /* prefs->value is a byte, so we're over |
1354 | | safe here */ |
1355 | |
|
1356 | 0 | sprintf(num,"%u",prefs->value); |
1357 | |
|
1358 | 0 | if(prefs->type==PREFTYPE_SYM) |
1359 | 0 | { |
1360 | 0 | if (openpgp_cipher_test_algo (prefs->value)) |
1361 | 0 | { |
1362 | 0 | const char *algo = |
1363 | 0 | (openpgp_cipher_test_algo (prefs->value) |
1364 | 0 | ? num |
1365 | 0 | : openpgp_cipher_algo_name (prefs->value)); |
1366 | 0 | if(!problem) |
1367 | 0 | check_prefs_warning(pk); |
1368 | 0 | log_info(_(" \"%s\": preference for cipher" |
1369 | 0 | " algorithm %s\n"), user, algo); |
1370 | 0 | problem=1; |
1371 | 0 | } |
1372 | 0 | } |
1373 | 0 | else if(prefs->type==PREFTYPE_AEAD) |
1374 | 0 | { |
1375 | 0 | if (openpgp_aead_test_algo (prefs->value)) |
1376 | 0 | { |
1377 | | /* FIXME: The test below is wrong. We should |
1378 | | * check if ...algo_name yields a "?" and |
1379 | | * only in that case use NUM. */ |
1380 | 0 | const char *algo = |
1381 | 0 | (openpgp_aead_test_algo (prefs->value) |
1382 | 0 | ? num |
1383 | 0 | : openpgp_aead_algo_name (prefs->value)); |
1384 | 0 | if(!problem) |
1385 | 0 | check_prefs_warning(pk); |
1386 | 0 | log_info(_(" \"%s\": preference for AEAD" |
1387 | 0 | " algorithm %s\n"), user, algo); |
1388 | 0 | problem=1; |
1389 | 0 | } |
1390 | 0 | } |
1391 | 0 | else if(prefs->type==PREFTYPE_HASH) |
1392 | 0 | { |
1393 | 0 | if(openpgp_md_test_algo(prefs->value)) |
1394 | 0 | { |
1395 | 0 | const char *algo = |
1396 | 0 | (gcry_md_test_algo (prefs->value) |
1397 | 0 | ? num |
1398 | 0 | : gcry_md_algo_name (prefs->value)); |
1399 | 0 | if(!problem) |
1400 | 0 | check_prefs_warning(pk); |
1401 | 0 | log_info(_(" \"%s\": preference for digest" |
1402 | 0 | " algorithm %s\n"), user, algo); |
1403 | 0 | problem=1; |
1404 | 0 | } |
1405 | 0 | } |
1406 | 0 | else if(prefs->type==PREFTYPE_ZIP) |
1407 | 0 | { |
1408 | 0 | if(check_compress_algo (prefs->value)) |
1409 | 0 | { |
1410 | 0 | const char *algo=compress_algo_to_string(prefs->value); |
1411 | 0 | if(!problem) |
1412 | 0 | check_prefs_warning(pk); |
1413 | 0 | log_info(_(" \"%s\": preference for compression" |
1414 | 0 | " algorithm %s\n"),user,algo?algo:num); |
1415 | 0 | problem=1; |
1416 | 0 | } |
1417 | 0 | } |
1418 | 0 | } |
1419 | |
|
1420 | 0 | xfree(user); |
1421 | 0 | } |
1422 | 0 | } |
1423 | |
|
1424 | 0 | if(problem) |
1425 | 0 | { |
1426 | 0 | log_info(_("it is strongly suggested that you update" |
1427 | 0 | " your preferences and\n")); |
1428 | 0 | log_info(_("re-distribute this key to avoid potential algorithm" |
1429 | 0 | " mismatch problems\n")); |
1430 | |
|
1431 | 0 | if(!opt.batch) |
1432 | 0 | { |
1433 | 0 | strlist_t sl = NULL; |
1434 | 0 | strlist_t locusr = NULL; |
1435 | 0 | size_t fprlen=0; |
1436 | 0 | byte fpr[MAX_FINGERPRINT_LEN], *p; |
1437 | 0 | char username[(MAX_FINGERPRINT_LEN*2)+1]; |
1438 | 0 | unsigned int i; |
1439 | |
|
1440 | 0 | p = fingerprint_from_pk (pk,fpr,&fprlen); |
1441 | 0 | for(i=0;i<fprlen;i++,p++) |
1442 | 0 | sprintf(username+2*i,"%02X",*p); |
1443 | 0 | add_to_strlist(&locusr,username); |
1444 | |
|
1445 | 0 | append_to_strlist(&sl,"updpref"); |
1446 | 0 | append_to_strlist(&sl,"save"); |
1447 | |
|
1448 | 0 | keyedit_menu (ctrl, username, locusr, sl, 1, 1 ); |
1449 | 0 | free_strlist(sl); |
1450 | 0 | free_strlist(locusr); |
1451 | 0 | } |
1452 | 0 | else if(!opt.quiet) |
1453 | 0 | log_info(_("you can update your preferences with:" |
1454 | 0 | " gpg --edit-key %s updpref save\n"),keystr_from_pk(pk)); |
1455 | 0 | } |
1456 | 0 | } |
1457 | | |
1458 | | |
1459 | | /* Helper for apply_*_filter in import.c and export.c and also used by |
1460 | | * keylist.c. */ |
1461 | | const char * |
1462 | | impex_filter_getval (void *cookie, const char *propname) |
1463 | 0 | { |
1464 | | /* FIXME: Malloc our static buffers and access them via PARM. */ |
1465 | 0 | struct impex_filter_parm_s *parm = cookie; |
1466 | 0 | ctrl_t ctrl = parm->ctrl; |
1467 | 0 | kbnode_t node = parm->node; |
1468 | 0 | static char numbuf[20]; |
1469 | 0 | const char *result; |
1470 | 0 | const char *s; |
1471 | 0 | enum { scpNone = 0, scpPub, scpSub, scpUid, scpSig} scope = 0; |
1472 | |
|
1473 | 0 | log_assert (ctrl && ctrl->magic == SERVER_CONTROL_MAGIC); |
1474 | | |
1475 | | /* We allow a prefix delimited by a slash to limit the scope of the |
1476 | | * keyword. Note that "pub" also includes "sec" and "sub" includes |
1477 | | * "ssb". */ |
1478 | 0 | if (DBG_RECSEL) /* Printing the packet type is useful. */ |
1479 | 0 | log_debug ("%s: pkttype=%s\n", __func__, pkttype_str (node->pkt->pkttype)); |
1480 | 0 | if ((s=strchr (propname, '/')) && s != propname) |
1481 | 0 | { |
1482 | 0 | size_t n = s - propname; |
1483 | 0 | if (!strncmp (propname, "pub", n)) |
1484 | 0 | scope = scpPub; |
1485 | 0 | else if (!strncmp (propname, "sub", n)) |
1486 | 0 | scope = scpSub; |
1487 | 0 | else if (!strncmp (propname, "uid", n)) |
1488 | 0 | scope = scpUid; |
1489 | 0 | else if (!strncmp (propname, "sig", n)) |
1490 | 0 | scope = scpSig; |
1491 | |
|
1492 | 0 | propname = s + 1; |
1493 | 0 | } |
1494 | |
|
1495 | 0 | if ((node->pkt->pkttype == PKT_USER_ID |
1496 | 0 | || node->pkt->pkttype == PKT_ATTRIBUTE) |
1497 | 0 | && (!scope || scope == scpUid)) |
1498 | 0 | { |
1499 | 0 | PKT_user_id *uid = node->pkt->pkt.user_id; |
1500 | |
|
1501 | 0 | if (!strcmp (propname, "uid")) |
1502 | 0 | result = uid->name; |
1503 | 0 | else if (!strcmp (propname, "mbox")) |
1504 | 0 | { |
1505 | 0 | if (!uid->mbox) |
1506 | 0 | { |
1507 | 0 | uid->mbox = mailbox_from_userid (uid->name, 0); |
1508 | 0 | } |
1509 | 0 | result = uid->mbox; |
1510 | 0 | } |
1511 | 0 | else if (!strcmp (propname, "primary")) |
1512 | 0 | { |
1513 | 0 | result = uid->flags.primary? "1":"0"; |
1514 | 0 | } |
1515 | 0 | else if (!strcmp (propname, "expired")) |
1516 | 0 | { |
1517 | 0 | result = uid->flags.expired? "1":"0"; |
1518 | 0 | } |
1519 | 0 | else if (!strcmp (propname, "revoked")) |
1520 | 0 | { |
1521 | 0 | result = uid->flags.revoked? "1":"0"; |
1522 | 0 | } |
1523 | 0 | else |
1524 | 0 | result = NULL; |
1525 | 0 | } |
1526 | 0 | else if (node->pkt->pkttype == PKT_SIGNATURE |
1527 | 0 | && (!scope || scope == scpSig)) |
1528 | 0 | { |
1529 | 0 | PKT_signature *sig = node->pkt->pkt.signature; |
1530 | |
|
1531 | 0 | if (!strcmp (propname, "sig_created")) |
1532 | 0 | { |
1533 | 0 | snprintf (numbuf, sizeof numbuf, "%lu", (ulong)sig->timestamp); |
1534 | 0 | result = numbuf; |
1535 | 0 | } |
1536 | 0 | else if (!strcmp (propname, "sig_created_d")) |
1537 | 0 | { |
1538 | 0 | result = dateonlystr_from_sig (sig); |
1539 | 0 | } |
1540 | 0 | else if (!strcmp (propname, "sig_expires")) |
1541 | 0 | { |
1542 | 0 | snprintf (numbuf, sizeof numbuf, "%lu", (ulong)sig->expiredate); |
1543 | 0 | result = numbuf; |
1544 | 0 | } |
1545 | 0 | else if (!strcmp (propname, "sig_expires_d")) |
1546 | 0 | { |
1547 | 0 | static char exdatestr[MK_DATESTR_SIZE]; |
1548 | |
|
1549 | 0 | if (sig->expiredate) |
1550 | 0 | result = mk_datestr (exdatestr, sizeof exdatestr, sig->expiredate); |
1551 | 0 | else |
1552 | 0 | result = ""; |
1553 | 0 | } |
1554 | 0 | else if (!strcmp (propname, "sig_algo")) |
1555 | 0 | { |
1556 | 0 | snprintf (numbuf, sizeof numbuf, "%d", sig->pubkey_algo); |
1557 | 0 | result = numbuf; |
1558 | 0 | } |
1559 | 0 | else if (!strcmp (propname, "sig_digest_algo")) |
1560 | 0 | { |
1561 | 0 | snprintf (numbuf, sizeof numbuf, "%d", sig->digest_algo); |
1562 | 0 | result = numbuf; |
1563 | 0 | } |
1564 | 0 | else if (!strcmp (propname, "expired")) |
1565 | 0 | { |
1566 | 0 | result = sig->flags.expired? "1":"0"; |
1567 | 0 | } |
1568 | 0 | else |
1569 | 0 | result = NULL; |
1570 | 0 | } |
1571 | 0 | else if (((node->pkt->pkttype == PKT_PUBLIC_KEY |
1572 | 0 | || node->pkt->pkttype == PKT_SECRET_KEY) |
1573 | 0 | && (!scope || scope == scpPub)) |
1574 | 0 | || ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
1575 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
1576 | 0 | && (!scope || scope == scpSub))) |
1577 | 0 | { |
1578 | 0 | PKT_public_key *pk = node->pkt->pkt.public_key; |
1579 | |
|
1580 | 0 | if (!strcmp (propname, "secret")) |
1581 | 0 | { |
1582 | 0 | result = (node->pkt->pkttype == PKT_SECRET_KEY |
1583 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY)? "1":"0"; |
1584 | 0 | } |
1585 | 0 | else if (!strcmp (propname, "key_algo")) |
1586 | 0 | { |
1587 | 0 | snprintf (numbuf, sizeof numbuf, "%d", pk->pubkey_algo); |
1588 | 0 | result = numbuf; |
1589 | 0 | } |
1590 | 0 | else if (!strcmp (propname, "key_size")) |
1591 | 0 | { |
1592 | 0 | snprintf (numbuf, sizeof numbuf, "%u", nbits_from_pk (pk)); |
1593 | 0 | result = numbuf; |
1594 | 0 | } |
1595 | 0 | else if (!strcmp (propname, "algostr")) |
1596 | 0 | { |
1597 | 0 | pubkey_string (pk, parm->hexfpr, sizeof parm->hexfpr); |
1598 | 0 | result = parm->hexfpr; |
1599 | 0 | } |
1600 | 0 | else if (!strcmp (propname, "key_created")) |
1601 | 0 | { |
1602 | 0 | snprintf (numbuf, sizeof numbuf, "%lu", (ulong)pk->timestamp); |
1603 | 0 | result = numbuf; |
1604 | 0 | } |
1605 | 0 | else if (!strcmp (propname, "key_created_d")) |
1606 | 0 | { |
1607 | 0 | result = dateonlystr_from_pk (pk); |
1608 | 0 | } |
1609 | 0 | else if (!strcmp (propname, "key_expires")) |
1610 | 0 | { |
1611 | 0 | snprintf (numbuf, sizeof numbuf, "%lu", (ulong)pk->expiredate); |
1612 | 0 | result = numbuf; |
1613 | 0 | } |
1614 | 0 | else if (!strcmp (propname, "key_expires_d")) |
1615 | 0 | { |
1616 | 0 | static char exdatestr[MK_DATESTR_SIZE]; |
1617 | |
|
1618 | 0 | if (pk->expiredate) |
1619 | 0 | result = mk_datestr (exdatestr, sizeof exdatestr, pk->expiredate); |
1620 | 0 | else |
1621 | 0 | result = ""; |
1622 | 0 | } |
1623 | 0 | else if (!strcmp (propname, "expired")) |
1624 | 0 | { |
1625 | 0 | result = pk->has_expired? "1":"0"; |
1626 | 0 | } |
1627 | 0 | else if (!strcmp (propname, "revoked")) |
1628 | 0 | { |
1629 | 0 | result = pk->flags.revoked? "1":"0"; |
1630 | 0 | } |
1631 | 0 | else if (!strcmp (propname, "disabled")) |
1632 | 0 | { |
1633 | 0 | result = pk_is_disabled (pk)? "1":"0"; |
1634 | 0 | } |
1635 | 0 | else if (!strcmp (propname, "usage")) |
1636 | 0 | { |
1637 | 0 | snprintf (numbuf, sizeof numbuf, "%s%s%s%s%s", |
1638 | 0 | (pk->pubkey_usage & PUBKEY_USAGE_ENC)?"e":"", |
1639 | 0 | (pk->pubkey_usage & PUBKEY_USAGE_SIG)?"s":"", |
1640 | 0 | (pk->pubkey_usage & PUBKEY_USAGE_CERT)?"c":"", |
1641 | 0 | (pk->pubkey_usage & PUBKEY_USAGE_AUTH)?"a":"", |
1642 | 0 | (pk->pubkey_usage & PUBKEY_USAGE_UNKNOWN)?"?":""); |
1643 | 0 | result = numbuf; |
1644 | 0 | } |
1645 | 0 | else if (!strcmp (propname, "fpr")) |
1646 | 0 | { |
1647 | 0 | hexfingerprint (pk, parm->hexfpr, sizeof parm->hexfpr); |
1648 | 0 | result = parm->hexfpr; |
1649 | 0 | } |
1650 | 0 | else if (!strcmp (propname, "origin")) |
1651 | 0 | { |
1652 | 0 | result = key_origin_string (pk->keyorg); |
1653 | 0 | } |
1654 | 0 | else if (!strcmp (propname, "lastupd")) |
1655 | 0 | { |
1656 | 0 | snprintf (numbuf, sizeof numbuf, "%lu", (ulong)pk->keyupdate); |
1657 | 0 | result = numbuf; |
1658 | 0 | } |
1659 | 0 | else if (!strcmp (propname, "url")) |
1660 | 0 | { |
1661 | 0 | if (pk->updateurl && *pk->updateurl) |
1662 | 0 | { |
1663 | | /* Fixme: This might get truncated. */ |
1664 | 0 | mem2str (parm->hexfpr, pk->updateurl, sizeof parm->hexfpr); |
1665 | 0 | result = parm->hexfpr; |
1666 | 0 | } |
1667 | 0 | else |
1668 | 0 | result = ""; |
1669 | 0 | } |
1670 | 0 | else |
1671 | 0 | result = NULL; |
1672 | 0 | } |
1673 | 0 | else |
1674 | 0 | result = NULL; |
1675 | |
|
1676 | 0 | return result; |
1677 | 0 | } |
1678 | | |
1679 | | |
1680 | | /* |
1681 | | * Apply the keep-uid filter to the keyblock. The deleted nodes are |
1682 | | * marked and thus the caller should call commit_kbnode afterwards. |
1683 | | * KEYBLOCK must not have any blocks marked as deleted. |
1684 | | */ |
1685 | | static void |
1686 | | apply_keep_uid_filter (ctrl_t ctrl, kbnode_t keyblock, recsel_expr_t selector) |
1687 | 0 | { |
1688 | 0 | kbnode_t node; |
1689 | 0 | struct impex_filter_parm_s parm; |
1690 | |
|
1691 | 0 | parm.ctrl = ctrl; |
1692 | |
|
1693 | 0 | for (node = keyblock->next; node; node = node->next ) |
1694 | 0 | { |
1695 | 0 | if (node->pkt->pkttype == PKT_USER_ID) |
1696 | 0 | { |
1697 | 0 | parm.node = node; |
1698 | 0 | if (!recsel_select (selector, impex_filter_getval, &parm)) |
1699 | 0 | { |
1700 | | |
1701 | | /* log_debug ("keep-uid: deleting '%s'\n", */ |
1702 | | /* node->pkt->pkt.user_id->name); */ |
1703 | | /* The UID packet and all following packets up to the |
1704 | | * next UID or a subkey. */ |
1705 | 0 | delete_kbnode (node); |
1706 | 0 | for (; node->next |
1707 | 0 | && node->next->pkt->pkttype != PKT_USER_ID |
1708 | 0 | && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY |
1709 | 0 | && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ; |
1710 | 0 | node = node->next) |
1711 | 0 | delete_kbnode (node->next); |
1712 | 0 | } |
1713 | | /* else */ |
1714 | | /* log_debug ("keep-uid: keeping '%s'\n", */ |
1715 | | /* node->pkt->pkt.user_id->name); */ |
1716 | 0 | } |
1717 | 0 | } |
1718 | 0 | } |
1719 | | |
1720 | | |
1721 | | /* |
1722 | | * Apply the drop-sig filter to the keyblock. The deleted nodes are |
1723 | | * marked and thus the caller should call commit_kbnode afterwards. |
1724 | | * KEYBLOCK must not have any blocks marked as deleted. |
1725 | | */ |
1726 | | static void |
1727 | | apply_drop_sig_filter (ctrl_t ctrl, kbnode_t keyblock, recsel_expr_t selector) |
1728 | 0 | { |
1729 | 0 | kbnode_t node; |
1730 | 0 | int active = 0; |
1731 | 0 | u32 main_keyid[2]; |
1732 | 0 | PKT_signature *sig; |
1733 | 0 | struct impex_filter_parm_s parm; |
1734 | |
|
1735 | 0 | parm.ctrl = ctrl; |
1736 | |
|
1737 | 0 | keyid_from_pk (keyblock->pkt->pkt.public_key, main_keyid); |
1738 | | |
1739 | | /* Loop over all signatures for user id and attribute packets which |
1740 | | * are not self signatures. */ |
1741 | 0 | for (node = keyblock->next; node; node = node->next ) |
1742 | 0 | { |
1743 | 0 | if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
1744 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
1745 | 0 | break; /* ready. */ |
1746 | 0 | if (node->pkt->pkttype == PKT_USER_ID |
1747 | 0 | || node->pkt->pkttype == PKT_ATTRIBUTE) |
1748 | 0 | active = 1; |
1749 | 0 | if (!active) |
1750 | 0 | continue; |
1751 | 0 | if (node->pkt->pkttype != PKT_SIGNATURE) |
1752 | 0 | continue; |
1753 | | |
1754 | 0 | sig = node->pkt->pkt.signature; |
1755 | 0 | if (main_keyid[0] == sig->keyid[0] || main_keyid[1] == sig->keyid[1]) |
1756 | 0 | continue; /* Skip self-signatures. */ |
1757 | | |
1758 | 0 | if (IS_UID_SIG(sig) || IS_UID_REV(sig)) |
1759 | 0 | { |
1760 | 0 | parm.node = node; |
1761 | 0 | if (recsel_select (selector, impex_filter_getval, &parm)) |
1762 | 0 | delete_kbnode (node); |
1763 | 0 | } |
1764 | 0 | } |
1765 | 0 | } |
1766 | | |
1767 | | |
1768 | | /* Insert a key origin into a public key packet. */ |
1769 | | static gpg_error_t |
1770 | | insert_key_origin_pk (PKT_public_key *pk, u32 curtime, |
1771 | | int origin, const char *url) |
1772 | 27 | { |
1773 | 27 | if (origin == KEYORG_WKD || origin == KEYORG_DANE) |
1774 | 0 | { |
1775 | | /* For WKD and DANE we insert origin information also for the |
1776 | | * key but we don't record the URL because we have have no use |
1777 | | * for that: An update using a keyserver has higher precedence |
1778 | | * and will thus update this origin info. For refresh using WKD |
1779 | | * or DANE we need to go via the User ID anyway. Recall that we |
1780 | | * are only inserting a new key. */ |
1781 | 0 | pk->keyorg = origin; |
1782 | 0 | pk->keyupdate = curtime; |
1783 | 0 | } |
1784 | 27 | else if (origin == KEYORG_KS && url) |
1785 | 0 | { |
1786 | | /* If the key was retrieved from a keyserver using a fingerprint |
1787 | | * request we add the meta information. Note that the use of a |
1788 | | * fingerprint needs to be enforced by the caller of the import |
1789 | | * function. This is commonly triggered by verifying a modern |
1790 | | * signature which has an Issuer Fingerprint signature |
1791 | | * subpacket. */ |
1792 | 0 | pk->keyorg = origin; |
1793 | 0 | pk->keyupdate = curtime; |
1794 | 0 | xfree (pk->updateurl); |
1795 | 0 | pk->updateurl = xtrystrdup (url); |
1796 | 0 | if (!pk->updateurl) |
1797 | 0 | return gpg_error_from_syserror (); |
1798 | 0 | } |
1799 | 27 | else if (origin == KEYORG_FILE) |
1800 | 0 | { |
1801 | 0 | pk->keyorg = origin; |
1802 | 0 | pk->keyupdate = curtime; |
1803 | 0 | } |
1804 | 27 | else if (origin == KEYORG_URL) |
1805 | 0 | { |
1806 | 0 | pk->keyorg = origin; |
1807 | 0 | pk->keyupdate = curtime; |
1808 | 0 | if (url) |
1809 | 0 | { |
1810 | 0 | xfree (pk->updateurl); |
1811 | 0 | pk->updateurl = xtrystrdup (url); |
1812 | 0 | if (!pk->updateurl) |
1813 | 0 | return gpg_error_from_syserror (); |
1814 | 0 | } |
1815 | 0 | } |
1816 | | |
1817 | 27 | return 0; |
1818 | 27 | } |
1819 | | |
1820 | | |
1821 | | /* Insert a key origin into a user id packet. */ |
1822 | | static gpg_error_t |
1823 | | insert_key_origin_uid (PKT_user_id *uid, u32 curtime, |
1824 | | int origin, const char *url) |
1825 | | |
1826 | 33 | { |
1827 | 33 | if (origin == KEYORG_WKD || origin == KEYORG_DANE) |
1828 | 0 | { |
1829 | | /* We insert origin information on a UID only when we received |
1830 | | * them via the Web Key Directory or a DANE record. The key we |
1831 | | * receive here from the WKD has been filtered to contain only |
1832 | | * the user ID as looked up in the WKD. For a DANE origin |
1833 | | * this should also be the case. Thus we will see here only one |
1834 | | * user id. */ |
1835 | 0 | uid->keyorg = origin; |
1836 | 0 | uid->keyupdate = curtime; |
1837 | 0 | if (url) |
1838 | 0 | { |
1839 | 0 | xfree (uid->updateurl); |
1840 | 0 | uid->updateurl = xtrystrdup (url); |
1841 | 0 | if (!uid->updateurl) |
1842 | 0 | return gpg_error_from_syserror (); |
1843 | 0 | } |
1844 | 0 | } |
1845 | 33 | else if (origin == KEYORG_KS && url) |
1846 | 0 | { |
1847 | | /* If the key was retrieved from a keyserver using a fingerprint |
1848 | | * request we mark that also in the user ID. However we do not |
1849 | | * store the keyserver URL in the UID. A later update (merge) |
1850 | | * from a more trusted source will replace this info. */ |
1851 | 0 | uid->keyorg = origin; |
1852 | 0 | uid->keyupdate = curtime; |
1853 | 0 | } |
1854 | 33 | else if (origin == KEYORG_FILE) |
1855 | 0 | { |
1856 | 0 | uid->keyorg = origin; |
1857 | 0 | uid->keyupdate = curtime; |
1858 | 0 | } |
1859 | 33 | else if (origin == KEYORG_URL) |
1860 | 0 | { |
1861 | 0 | uid->keyorg = origin; |
1862 | 0 | uid->keyupdate = curtime; |
1863 | 0 | } |
1864 | | |
1865 | 33 | return 0; |
1866 | 33 | } |
1867 | | |
1868 | | |
1869 | | /* Apply meta data to KEYBLOCK. This sets the origin of the key to |
1870 | | * ORIGIN and the updateurl to URL. Note that this function is only |
1871 | | * used for a new key, that is not when we are merging keys. */ |
1872 | | static gpg_error_t |
1873 | | insert_key_origin (kbnode_t keyblock, int origin, const char *url) |
1874 | 27 | { |
1875 | 27 | gpg_error_t err; |
1876 | 27 | kbnode_t node; |
1877 | 27 | u32 curtime = make_timestamp (); |
1878 | | |
1879 | 140 | for (node = keyblock; node; node = node->next) |
1880 | 113 | { |
1881 | 113 | if (is_deleted_kbnode (node)) |
1882 | 0 | ; |
1883 | 113 | else if (node->pkt->pkttype == PKT_PUBLIC_KEY) |
1884 | 27 | { |
1885 | 27 | err = insert_key_origin_pk (node->pkt->pkt.public_key, curtime, |
1886 | 27 | origin, url); |
1887 | 27 | if (err) |
1888 | 0 | return err; |
1889 | 27 | } |
1890 | 86 | else if (node->pkt->pkttype == PKT_USER_ID) |
1891 | 30 | { |
1892 | 30 | err = insert_key_origin_uid (node->pkt->pkt.user_id, curtime, |
1893 | 30 | origin, url); |
1894 | 30 | if (err) |
1895 | 0 | return err; |
1896 | 30 | } |
1897 | 113 | } |
1898 | | |
1899 | 27 | return 0; |
1900 | 27 | } |
1901 | | |
1902 | | |
1903 | | /* Update meta data on KEYBLOCK. This updates the key origin on the |
1904 | | * public key according to ORIGIN and URL. The UIDs are already |
1905 | | * updated when this function is called. */ |
1906 | | static gpg_error_t |
1907 | | update_key_origin (kbnode_t keyblock, u32 curtime, int origin, const char *url) |
1908 | 2.68k | { |
1909 | 2.68k | PKT_public_key *pk; |
1910 | | |
1911 | 2.68k | log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); |
1912 | 2.68k | pk = keyblock->pkt->pkt.public_key; |
1913 | | |
1914 | 2.68k | if (pk->keyupdate > curtime) |
1915 | 0 | ; /* Don't do it for a time warp. */ |
1916 | 2.68k | else if (origin == KEYORG_WKD || origin == KEYORG_DANE) |
1917 | 0 | { |
1918 | | /* We only update the origin info if they either have never been |
1919 | | * set or are the origin was the same as the new one. If this |
1920 | | * is WKD we also update the UID to show from which user id this |
1921 | | * was updated. */ |
1922 | 0 | if (!pk->keyorg || pk->keyorg == KEYORG_WKD || pk->keyorg == KEYORG_DANE) |
1923 | 0 | { |
1924 | 0 | pk->keyorg = origin; |
1925 | 0 | pk->keyupdate = curtime; |
1926 | 0 | xfree (pk->updateurl); |
1927 | 0 | pk->updateurl = NULL; |
1928 | 0 | if (origin == KEYORG_WKD && url) |
1929 | 0 | { |
1930 | 0 | pk->updateurl = xtrystrdup (url); |
1931 | 0 | if (!pk->updateurl) |
1932 | 0 | return gpg_error_from_syserror (); |
1933 | 0 | } |
1934 | 0 | } |
1935 | 0 | } |
1936 | 2.68k | else if (origin == KEYORG_KS) |
1937 | 0 | { |
1938 | | /* All updates from a keyserver are considered to have the |
1939 | | * freshed key. Thus we always set the new key origin. */ |
1940 | 0 | pk->keyorg = origin; |
1941 | 0 | pk->keyupdate = curtime; |
1942 | 0 | xfree (pk->updateurl); |
1943 | 0 | pk->updateurl = NULL; |
1944 | 0 | if (url) |
1945 | 0 | { |
1946 | 0 | pk->updateurl = xtrystrdup (url); |
1947 | 0 | if (!pk->updateurl) |
1948 | 0 | return gpg_error_from_syserror (); |
1949 | 0 | } |
1950 | 0 | } |
1951 | 2.68k | else if (origin == KEYORG_FILE) |
1952 | 0 | { |
1953 | | /* Updates from a file are considered to be fresh. */ |
1954 | 0 | pk->keyorg = origin; |
1955 | 0 | pk->keyupdate = curtime; |
1956 | 0 | xfree (pk->updateurl); |
1957 | 0 | pk->updateurl = NULL; |
1958 | 0 | } |
1959 | 2.68k | else if (origin == KEYORG_URL) |
1960 | 0 | { |
1961 | | /* Updates from a URL are considered to be fresh. */ |
1962 | 0 | pk->keyorg = origin; |
1963 | 0 | pk->keyupdate = curtime; |
1964 | 0 | xfree (pk->updateurl); |
1965 | 0 | pk->updateurl = NULL; |
1966 | 0 | if (url) |
1967 | 0 | { |
1968 | 0 | pk->updateurl = xtrystrdup (url); |
1969 | 0 | if (!pk->updateurl) |
1970 | 0 | return gpg_error_from_syserror (); |
1971 | 0 | } |
1972 | 0 | } |
1973 | | |
1974 | 2.68k | return 0; |
1975 | 2.68k | } |
1976 | | |
1977 | | |
1978 | | /* |
1979 | | * Try to import one keyblock. Return an error only in serious cases, |
1980 | | * but never for an invalid keyblock. It uses log_error to increase |
1981 | | * the internal errorcount, so that invalid input can be detected by |
1982 | | * programs which called gpg. If SILENT is no messages are printed - |
1983 | | * even most error messages are suppressed. ORIGIN is the origin of |
1984 | | * the key (0 for unknown) and URL the corresponding URL. FROM_SK |
1985 | | * indicates that the key has been made from a secret key. If R_SAVED |
1986 | | * is not NULL a boolean will be stored indicating whether the |
1987 | | * keyblock has valid parts. Unless OTHERREVSIGS is NULL it is |
1988 | | * updated with encountered new revocation signatures. |
1989 | | */ |
1990 | | static gpg_error_t |
1991 | | import_one_real (ctrl_t ctrl, |
1992 | | kbnode_t keyblock, struct import_stats_s *stats, |
1993 | | unsigned char **fpr, size_t *fpr_len, unsigned int options, |
1994 | | int from_sk, int silent, |
1995 | | import_screener_t screener, void *screener_arg, |
1996 | | int origin, const char *url, int *r_valid, |
1997 | | kbnode_t *otherrevsigs) |
1998 | 14.4k | { |
1999 | 14.4k | gpg_error_t err = 0; |
2000 | 14.4k | PKT_public_key *pk; |
2001 | 14.4k | kbnode_t node, uidnode; |
2002 | 14.4k | kbnode_t keyblock_orig = NULL; |
2003 | 14.4k | byte fpr2[MAX_FINGERPRINT_LEN]; |
2004 | 14.4k | size_t fpr2len; |
2005 | 14.4k | u32 keyid[2]; |
2006 | 14.4k | int new_key = 0; |
2007 | 14.4k | int mod_key = 0; |
2008 | 14.4k | int same_key = 0; |
2009 | 14.4k | int non_self_or_utk = 0; |
2010 | 14.4k | char pkstrbuf[PUBKEY_STRING_SIZE]; |
2011 | 14.4k | int merge_keys_done = 0; |
2012 | 14.4k | int any_filter = 0; |
2013 | 14.4k | KEYDB_HANDLE hd = NULL; |
2014 | | |
2015 | 14.4k | if (r_valid) |
2016 | 1.17k | *r_valid = 0; |
2017 | | |
2018 | | /* If show-only is active we don't won't any extra output. */ |
2019 | 14.4k | if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN))) |
2020 | 0 | silent = 1; |
2021 | | |
2022 | | /* Get the key and print some info about it. */ |
2023 | 14.4k | node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); |
2024 | 14.4k | if (!node ) |
2025 | 0 | BUG(); |
2026 | | |
2027 | 14.4k | pk = node->pkt->pkt.public_key; |
2028 | | |
2029 | 14.4k | fingerprint_from_pk (pk, fpr2, &fpr2len); |
2030 | 14.4k | if (MAX_FINGERPRINT_LEN > fpr2len) |
2031 | 14.2k | memset (fpr2+fpr2len, 0, MAX_FINGERPRINT_LEN - fpr2len); |
2032 | 14.4k | keyid_from_pk( pk, keyid ); |
2033 | 14.4k | uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); |
2034 | | |
2035 | 14.4k | if (opt.verbose && !opt.interactive && !silent && !from_sk) |
2036 | 0 | { |
2037 | | /* Note that we do not print this info in FROM_SK mode |
2038 | | * because import_secret_one already printed that. */ |
2039 | 0 | log_info ("pub %s/%s %s ", |
2040 | 0 | pubkey_string (pk, pkstrbuf, sizeof pkstrbuf), |
2041 | 0 | keystr_from_pk(pk), datestr_from_pk(pk) ); |
2042 | 0 | if (uidnode) |
2043 | 0 | print_utf8_buffer (log_get_stream (), |
2044 | 0 | uidnode->pkt->pkt.user_id->name, |
2045 | 0 | uidnode->pkt->pkt.user_id->len ); |
2046 | 0 | log_printf ("\n"); |
2047 | 0 | } |
2048 | | |
2049 | | |
2050 | 14.4k | if (!uidnode) |
2051 | 4.10k | { |
2052 | 4.10k | if (!silent) |
2053 | 4.10k | log_error( _("key %s: no user ID\n"), keystr_from_pk(pk)); |
2054 | 4.10k | if (!(options & IMPORT_DEBUG_ACCEPT_NO_UID)) |
2055 | 4.10k | return 0; |
2056 | 4.10k | } |
2057 | | |
2058 | 10.3k | if (screener && screener (keyblock, screener_arg)) |
2059 | 0 | { |
2060 | 0 | log_error (_("key %s: %s\n"), keystr_from_pk (pk), |
2061 | 0 | _("rejected by import screener")); |
2062 | 0 | return 0; |
2063 | 0 | } |
2064 | | |
2065 | 10.3k | if (opt.interactive && !silent) |
2066 | 0 | { |
2067 | 0 | if (is_status_enabled()) |
2068 | 0 | print_import_check (pk, uidnode->pkt->pkt.user_id); |
2069 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
2070 | 0 | tty_printf ("\n"); |
2071 | 0 | show_basic_key_info (ctrl, keyblock, from_sk); |
2072 | 0 | tty_printf ("\n"); |
2073 | 0 | if (!cpr_get_answer_is_yes ("import.okay", |
2074 | 0 | "Do you want to import this key? (y/N) ")) |
2075 | 0 | return 0; |
2076 | 0 | } |
2077 | | |
2078 | | /* Remove all non-self-sigs if requested. Note that this is a NOP if |
2079 | | * that option has been globally set but we may also be called |
2080 | | * latter with the already parsed keyblock and a locally changed |
2081 | | * option. This is why we need to remove them here as well. */ |
2082 | 10.3k | if ((options & IMPORT_SELF_SIGS_ONLY)) |
2083 | 0 | remove_all_non_self_sigs (&keyblock, keyid); |
2084 | | |
2085 | | /* Remove or collapse the user ids. */ |
2086 | 10.3k | if ((options & IMPORT_COLLAPSE_UIDS)) |
2087 | 0 | collapse_uids (&keyblock); |
2088 | | |
2089 | 10.3k | if ((options & IMPORT_COLLAPSE_SUBKEYS)) |
2090 | 0 | collapse_subkeys (&keyblock); |
2091 | | |
2092 | | /* Clean the key that we're about to import, to cut down on things |
2093 | | that we have to clean later. This has no practical impact on the |
2094 | | end result, but does result in less logging which might confuse |
2095 | | the user. */ |
2096 | 10.3k | if ((options & IMPORT_CLEAN)) |
2097 | 0 | { |
2098 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
2099 | 0 | clean_all_uids (ctrl, keyblock, |
2100 | 0 | opt.verbose, |
2101 | 0 | (options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0, |
2102 | 0 | NULL, NULL); |
2103 | 0 | clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE, |
2104 | 0 | NULL, NULL); |
2105 | 0 | } |
2106 | | |
2107 | 10.3k | clear_kbnode_flags( keyblock ); |
2108 | | |
2109 | 10.3k | if ((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) |
2110 | 0 | && fix_pks_corruption (ctrl, keyblock) |
2111 | 0 | && opt.verbose) |
2112 | 10.3k | log_info (_("key %s: PKS subkey corruption repaired\n"), |
2113 | 0 | keystr_from_pk(pk)); |
2114 | | |
2115 | 10.3k | if ((options & IMPORT_REPAIR_KEYS)) |
2116 | 10.3k | key_check_all_keysigs (ctrl, 1, keyblock, 0, 0); |
2117 | | |
2118 | 10.3k | if (chk_self_sigs (ctrl, keyblock, keyid, &non_self_or_utk)) |
2119 | 31 | return 0; /* Invalid keyblock - error already printed. */ |
2120 | | |
2121 | | /* If the imported key is marked as ultimately trusted key (using |
2122 | | * --trusted-key), we set the flag so that we can later set the |
2123 | | * revalidation mark. */ |
2124 | 10.3k | if (!non_self_or_utk) |
2125 | 3.10k | { |
2126 | | /* Make sure the trustdb is initialized so that the UTK list is |
2127 | | * available. */ |
2128 | 3.10k | init_trustdb (ctrl, 1); |
2129 | 3.10k | if (tdb_keyid_is_utk (keyid)) |
2130 | 0 | non_self_or_utk = 2; |
2131 | 3.10k | } |
2132 | | |
2133 | | /* If we allow such a thing, mark unsigned uids as valid */ |
2134 | 10.3k | if (opt.allow_non_selfsigned_uid) |
2135 | 0 | { |
2136 | 0 | for (node=keyblock; node; node = node->next ) |
2137 | 0 | if (node->pkt->pkttype == PKT_USER_ID |
2138 | 0 | && !(node->flag & NODE_GOOD_SELFSIG) |
2139 | 0 | && !(node->flag & NODE_BAD_SELFSIG) ) |
2140 | 0 | { |
2141 | 0 | char *user=utf8_to_native(node->pkt->pkt.user_id->name, |
2142 | 0 | node->pkt->pkt.user_id->len,0); |
2143 | | /* Fake a good signature status for the user id. */ |
2144 | 0 | node->flag |= NODE_GOOD_SELFSIG; |
2145 | 0 | log_info( _("key %s: accepted non self-signed user ID \"%s\"\n"), |
2146 | 0 | keystr_from_pk(pk),user); |
2147 | 0 | xfree(user); |
2148 | 0 | } |
2149 | 0 | } |
2150 | | |
2151 | | /* Delete invalid parts and bail out if there are no user ids left. */ |
2152 | 10.3k | if (!delete_inv_parts (ctrl, keyblock, keyid, options, otherrevsigs)) |
2153 | 7.27k | { |
2154 | 7.27k | if (!silent) |
2155 | 7.27k | { |
2156 | 7.27k | log_error ( _("key %s: no valid user IDs\n"), keystr_from_pk(pk)); |
2157 | 7.27k | if (!opt.quiet) |
2158 | 7.27k | log_info(_("this may be caused by a missing self-signature\n")); |
2159 | 7.27k | } |
2160 | 7.27k | stats->no_user_id++; |
2161 | 7.27k | if (!(options & IMPORT_DEBUG_ACCEPT_NO_UID)) |
2162 | 7.27k | return 0; |
2163 | 7.27k | } |
2164 | | |
2165 | | /* Get rid of deleted nodes. */ |
2166 | 3.03k | commit_kbnode (&keyblock); |
2167 | | |
2168 | | /* Apply import filter. */ |
2169 | 3.03k | if (import_filter.keep_uid) |
2170 | 0 | { |
2171 | 0 | apply_keep_uid_filter (ctrl, keyblock, import_filter.keep_uid); |
2172 | 0 | commit_kbnode (&keyblock); |
2173 | 0 | any_filter = 1; |
2174 | 0 | } |
2175 | 3.03k | if (import_filter.drop_sig) |
2176 | 0 | { |
2177 | 0 | apply_drop_sig_filter (ctrl, keyblock, import_filter.drop_sig); |
2178 | 0 | commit_kbnode (&keyblock); |
2179 | 0 | any_filter = 1; |
2180 | 0 | } |
2181 | | |
2182 | | /* If we ran any filter we need to check that at least one user id |
2183 | | * is left in the keyring. Note that we do not use log_error in |
2184 | | * this case. */ |
2185 | 3.03k | if (any_filter && !any_uid_left (keyblock)) |
2186 | 0 | { |
2187 | 0 | if (!opt.quiet ) |
2188 | 0 | log_info ( _("key %s: no valid user IDs\n"), keystr_from_pk (pk)); |
2189 | 0 | stats->no_user_id++; |
2190 | 0 | if (!(options & IMPORT_DEBUG_ACCEPT_NO_UID)) |
2191 | 0 | return 0; |
2192 | 0 | } |
2193 | | |
2194 | | /* The keyblock is valid and ready for real import. */ |
2195 | 3.03k | if (r_valid) |
2196 | 55 | *r_valid = 1; |
2197 | | |
2198 | | /* Show the key in the form it is merged or inserted. We skip this |
2199 | | * if "import-export" is also active without --armor or the output |
2200 | | * file has explicily been given. */ |
2201 | 3.03k | if ((options & IMPORT_SHOW) |
2202 | 0 | && !((options & IMPORT_EXPORT) && !opt.armor && !opt.outfile)) |
2203 | 0 | { |
2204 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
2205 | 0 | merge_keys_done = 1; |
2206 | | /* Note that we do not want to show the validity because the key |
2207 | | * has not yet imported. */ |
2208 | 0 | err = list_keyblock_direct (ctrl, keyblock, from_sk, 0, |
2209 | 0 | opt.fingerprint || opt.with_fingerprint, 1); |
2210 | 0 | es_fflush (es_stdout); |
2211 | 0 | no_usable_encr_subkeys_warning (keyblock); |
2212 | 0 | if (err) |
2213 | 0 | goto leave; |
2214 | 0 | } |
2215 | | |
2216 | | /* Write the keyblock to the output and do not actually import. */ |
2217 | 3.03k | if ((options & IMPORT_EXPORT)) |
2218 | 0 | { |
2219 | 0 | if (!merge_keys_done) |
2220 | 0 | { |
2221 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
2222 | 0 | merge_keys_done = 1; |
2223 | 0 | } |
2224 | 0 | err = write_keyblock_to_output (keyblock, opt.armor, opt.export_options); |
2225 | 0 | goto leave; |
2226 | 0 | } |
2227 | | |
2228 | 3.03k | if (opt.dry_run || (options & IMPORT_DRY_RUN)) |
2229 | 0 | goto leave; |
2230 | | |
2231 | | /* Do we have this key already in one of our pubrings ? */ |
2232 | 3.03k | err = get_keyblock_byfpr_fast (ctrl, &keyblock_orig, &hd, |
2233 | 3.03k | 1 /*primary only */, |
2234 | 3.03k | fpr2, fpr2len, 1/*locked*/); |
2235 | 3.03k | if ((err |
2236 | 27 | && gpg_err_code (err) != GPG_ERR_NO_PUBKEY |
2237 | 0 | && gpg_err_code (err) != GPG_ERR_UNUSABLE_PUBKEY) |
2238 | 3.03k | || !hd) |
2239 | 0 | { |
2240 | | /* The !hd above is to catch a misbehaving function which |
2241 | | * returns NO_PUBKEY for failing to allocate a handle. */ |
2242 | 0 | if (!silent) |
2243 | 0 | log_error (_("key %s: public key not found: %s\n"), |
2244 | 0 | keystr(keyid), gpg_strerror (err)); |
2245 | 0 | } |
2246 | 3.03k | else if (err && ((opt.import_options|options)&IMPORT_MERGE_ONLY) ) |
2247 | 0 | { |
2248 | 0 | if (opt.verbose && !silent ) |
2249 | 0 | log_info( _("key %s: new key - skipped\n"), keystr(keyid)); |
2250 | 0 | err = 0; |
2251 | 0 | stats->skipped_new_keys++; |
2252 | 0 | } |
2253 | 3.03k | else if (err) /* Insert this key. */ |
2254 | 27 | { |
2255 | | /* Note: ERR can only be NO_PUBKEY or UNUSABLE_PUBKEY. */ |
2256 | 27 | int n_sigs_cleaned, n_uids_cleaned; |
2257 | | |
2258 | 27 | err = keydb_locate_writable (hd); |
2259 | 27 | if (err) |
2260 | 0 | { |
2261 | 0 | log_error (_("no writable keyring found: %s\n"), gpg_strerror (err)); |
2262 | 0 | err = gpg_error (GPG_ERR_GENERAL); |
2263 | 0 | goto leave; |
2264 | 0 | } |
2265 | 27 | if (opt.verbose > 1 ) |
2266 | 27 | log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) ); |
2267 | | |
2268 | 27 | if ((options & IMPORT_CLEAN)) |
2269 | 0 | { |
2270 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
2271 | 0 | clean_all_uids (ctrl, keyblock, opt.verbose, |
2272 | 0 | (options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0, |
2273 | 0 | &n_uids_cleaned,&n_sigs_cleaned); |
2274 | 0 | clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE, |
2275 | 0 | NULL, NULL); |
2276 | 0 | } |
2277 | | |
2278 | | /* Unless we are in restore mode apply meta data to the |
2279 | | * keyblock. Note that this will never change the first packet |
2280 | | * and thus the address of KEYBLOCK won't change. */ |
2281 | 27 | if ( !(options & IMPORT_RESTORE) ) |
2282 | 27 | { |
2283 | 27 | err = insert_key_origin (keyblock, origin, url); |
2284 | 27 | if (err) |
2285 | 0 | { |
2286 | 0 | log_error ("insert_key_origin failed: %s\n", gpg_strerror (err)); |
2287 | 0 | err = gpg_error (GPG_ERR_GENERAL); |
2288 | 0 | goto leave; |
2289 | 0 | } |
2290 | 27 | } |
2291 | | |
2292 | 27 | err = keydb_insert_keyblock (hd, keyblock); |
2293 | 27 | if (err) |
2294 | 27 | log_error (_("error writing keyring '%s': %s\n"), |
2295 | 0 | keydb_get_resource_name (hd), gpg_strerror (err)); |
2296 | 27 | else if (!(opt.import_options & IMPORT_KEEP_OWNERTTRUST)) |
2297 | 27 | { |
2298 | | /* This should not be possible since we delete the |
2299 | | ownertrust when a key is deleted, but it can happen if |
2300 | | the keyring and trustdb are out of sync. It can also |
2301 | | be made to happen with the trusted-key command and by |
2302 | | importing and locally exported key. */ |
2303 | | |
2304 | 27 | clear_ownertrusts (ctrl, pk); |
2305 | 27 | if (non_self_or_utk) |
2306 | 4 | revalidation_mark (ctrl); |
2307 | 27 | } |
2308 | | |
2309 | | /* Release the handle and thus unlock the keyring asap. */ |
2310 | 27 | keydb_release (hd); |
2311 | 27 | hd = NULL; |
2312 | | |
2313 | | /* We are ready. */ |
2314 | 27 | if (!err && !opt.quiet && !silent) |
2315 | 27 | { |
2316 | 27 | char *p = get_user_id_byfpr_native (ctrl, fpr2, fpr2len); |
2317 | 27 | log_info (_("key %s: public key \"%s\" imported\n"), |
2318 | 27 | keystr(keyid), p); |
2319 | 27 | xfree(p); |
2320 | 27 | } |
2321 | 27 | if (!err && is_status_enabled()) |
2322 | 0 | { |
2323 | 0 | char *us = get_long_user_id_string (ctrl, keyid); |
2324 | 0 | write_status_text( STATUS_IMPORTED, us ); |
2325 | 0 | xfree(us); |
2326 | 0 | print_import_ok (pk, 1); |
2327 | 0 | } |
2328 | 27 | if (!err) |
2329 | 27 | { |
2330 | 27 | stats->imported++; |
2331 | 27 | new_key = 1; |
2332 | 27 | } |
2333 | 27 | } |
2334 | 3.01k | else /* Key already exists - merge. */ |
2335 | 3.01k | { |
2336 | 3.01k | int n_uids, n_sigs, n_subk, n_sigs_cleaned, n_uids_cleaned; |
2337 | 3.01k | u32 curtime = make_timestamp (); |
2338 | | |
2339 | | /* Compare the original against the new key; just to be sure nothing |
2340 | | * weird is going on */ |
2341 | 3.01k | if (cmp_public_keys (keyblock_orig->pkt->pkt.public_key, pk)) |
2342 | 18 | { |
2343 | 18 | if (!silent) |
2344 | 18 | log_error( _("key %s: doesn't match our copy\n"),keystr(keyid)); |
2345 | 18 | goto leave; |
2346 | 18 | } |
2347 | | |
2348 | | /* Make sure the original direct key sigs are all sane. */ |
2349 | 2.99k | n_sigs_cleaned = fix_bad_direct_key_sigs (ctrl, keyblock_orig, keyid); |
2350 | 2.99k | if (n_sigs_cleaned) |
2351 | 439 | commit_kbnode (&keyblock_orig); |
2352 | | |
2353 | | /* Try to merge KEYBLOCK into KEYBLOCK_ORIG. */ |
2354 | 2.99k | clear_kbnode_flags( keyblock_orig ); |
2355 | 2.99k | clear_kbnode_flags( keyblock ); |
2356 | 2.99k | n_uids = n_sigs = n_subk = n_uids_cleaned = 0; |
2357 | 2.99k | err = merge_blocks (ctrl, options, keyblock_orig, keyblock, keyid, |
2358 | 2.99k | curtime, origin, url, |
2359 | 2.99k | &n_uids, &n_sigs, &n_subk ); |
2360 | 2.99k | if (err) |
2361 | 0 | goto leave; |
2362 | | |
2363 | | /* Clean the final keyblock again if requested. we can't do |
2364 | | * this if only self-signatures are imported; see bug #4628. */ |
2365 | 2.99k | if ((options & IMPORT_CLEAN) |
2366 | 0 | && !(options & IMPORT_SELF_SIGS_ONLY)) |
2367 | 0 | { |
2368 | 0 | merge_keys_and_selfsig (ctrl, keyblock_orig); |
2369 | 0 | clean_all_uids (ctrl, keyblock_orig, opt.verbose, |
2370 | 0 | (options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0, |
2371 | 0 | &n_uids_cleaned,&n_sigs_cleaned); |
2372 | 0 | clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, KEY_CLEAN_NONE, |
2373 | 0 | NULL, NULL); |
2374 | 0 | } |
2375 | | |
2376 | 2.99k | if (n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned |
2377 | 308 | || (options & IMPORT_FORCE_UPDATE)) |
2378 | 2.68k | { |
2379 | | /* Unless we are in restore mode apply meta data to the |
2380 | | * keyblock. Note that this will never change the first packet |
2381 | | * and thus the address of KEYBLOCK won't change. */ |
2382 | 2.68k | if ( !(options & IMPORT_RESTORE) ) |
2383 | 2.68k | { |
2384 | 2.68k | err = update_key_origin (keyblock_orig, curtime, origin, url); |
2385 | 2.68k | if (err) |
2386 | 0 | { |
2387 | 0 | log_error ("update_key_origin failed: %s\n", |
2388 | 0 | gpg_strerror (err)); |
2389 | 0 | goto leave; |
2390 | 0 | } |
2391 | 2.68k | } |
2392 | | |
2393 | 2.68k | mod_key = 1; |
2394 | | /* KEYBLOCK_ORIG has been updated; write */ |
2395 | 2.68k | err = keydb_update_keyblock (ctrl, hd, keyblock_orig); |
2396 | 2.68k | if (err) |
2397 | 2.68k | log_error (_("error writing keyring '%s': %s\n"), |
2398 | 0 | keydb_get_resource_name (hd), gpg_strerror (err)); |
2399 | 2.68k | else if (non_self_or_utk) |
2400 | 1.58k | revalidation_mark (ctrl); |
2401 | | |
2402 | | /* Release the handle and thus unlock the keyring asap. */ |
2403 | 2.68k | keydb_release (hd); |
2404 | 2.68k | hd = NULL; |
2405 | | |
2406 | | /* We are ready. Print and update stats if we got no error. |
2407 | | * An error here comes from writing the keyblock and thus |
2408 | | * very likely means that no update happened. */ |
2409 | 2.68k | if (!err && !opt.quiet && !silent) |
2410 | 2.68k | { |
2411 | 2.68k | char *p = get_user_id_byfpr_native (ctrl, fpr2, fpr2len); |
2412 | 2.68k | if (n_uids == 1 ) |
2413 | 2.68k | log_info( _("key %s: \"%s\" 1 new user ID\n"), |
2414 | 3 | keystr(keyid),p); |
2415 | 2.68k | else if (n_uids ) |
2416 | 2.68k | log_info( _("key %s: \"%s\" %d new user IDs\n"), |
2417 | 0 | keystr(keyid),p,n_uids); |
2418 | 2.68k | if (n_sigs == 1 ) |
2419 | 2.68k | log_info( _("key %s: \"%s\" 1 new signature\n"), |
2420 | 1.97k | keystr(keyid), p); |
2421 | 708 | else if (n_sigs ) |
2422 | 708 | log_info( _("key %s: \"%s\" %d new signatures\n"), |
2423 | 697 | keystr(keyid), p, n_sigs ); |
2424 | 2.68k | if (n_subk == 1 ) |
2425 | 2.68k | log_info( _("key %s: \"%s\" 1 new subkey\n"), |
2426 | 302 | keystr(keyid), p); |
2427 | 2.38k | else if (n_subk ) |
2428 | 2.38k | log_info( _("key %s: \"%s\" %d new subkeys\n"), |
2429 | 0 | keystr(keyid), p, n_subk ); |
2430 | 2.68k | if (n_sigs_cleaned==1) |
2431 | 2.68k | log_info(_("key %s: \"%s\" %d signature cleaned\n"), |
2432 | 363 | keystr(keyid),p,n_sigs_cleaned); |
2433 | 2.32k | else if (n_sigs_cleaned) |
2434 | 2.32k | log_info(_("key %s: \"%s\" %d signatures cleaned\n"), |
2435 | 76 | keystr(keyid),p,n_sigs_cleaned); |
2436 | 2.68k | if (n_uids_cleaned==1) |
2437 | 2.68k | log_info(_("key %s: \"%s\" %d user ID cleaned\n"), |
2438 | 0 | keystr(keyid),p,n_uids_cleaned); |
2439 | 2.68k | else if (n_uids_cleaned) |
2440 | 2.68k | log_info(_("key %s: \"%s\" %d user IDs cleaned\n"), |
2441 | 0 | keystr(keyid),p,n_uids_cleaned); |
2442 | 2.68k | xfree(p); |
2443 | 2.68k | } |
2444 | | |
2445 | 2.68k | if (!err) |
2446 | 2.68k | { |
2447 | 2.68k | stats->n_uids +=n_uids; |
2448 | 2.68k | stats->n_sigs +=n_sigs; |
2449 | 2.68k | stats->n_subk +=n_subk; |
2450 | 2.68k | stats->n_sigs_cleaned +=n_sigs_cleaned; |
2451 | 2.68k | stats->n_uids_cleaned +=n_uids_cleaned; |
2452 | | |
2453 | 2.68k | if (is_status_enabled () && !silent) |
2454 | 0 | print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0))); |
2455 | 2.68k | } |
2456 | 2.68k | } |
2457 | 308 | else |
2458 | 308 | { |
2459 | | /* Release the handle and thus unlock the keyring asap. */ |
2460 | 308 | keydb_release (hd); |
2461 | 308 | hd = NULL; |
2462 | | |
2463 | | /* FIXME: We do not track the time we last checked a key for |
2464 | | * updates. To do this we would need to rewrite even the |
2465 | | * keys which have no changes. Adding this would be useful |
2466 | | * for the automatic update of expired keys via the WKD in |
2467 | | * case the WKD still carries the expired key. See |
2468 | | * get_best_pubkey_byname. */ |
2469 | 308 | same_key = 1; |
2470 | 308 | if (is_status_enabled ()) |
2471 | 0 | print_import_ok (pk, 0); |
2472 | | |
2473 | 308 | if (!opt.quiet && !silent) |
2474 | 308 | { |
2475 | 308 | char *p = get_user_id_byfpr_native (ctrl, fpr2, fpr2len); |
2476 | 308 | log_info( _("key %s: \"%s\" not changed\n"),keystr(keyid),p); |
2477 | 308 | xfree(p); |
2478 | 308 | } |
2479 | | |
2480 | 308 | stats->unchanged++; |
2481 | 308 | } |
2482 | 2.99k | } |
2483 | | |
2484 | 3.03k | leave: |
2485 | 3.03k | keydb_release (hd); |
2486 | 3.03k | if (mod_key || new_key || same_key) |
2487 | 3.02k | { |
2488 | | /* A little explanation for this: we fill in the fingerprint |
2489 | | when importing keys as it can be useful to know the |
2490 | | fingerprint in certain keyserver-related cases (a keyserver |
2491 | | asked for a particular name, but the key doesn't have that |
2492 | | name). However, in cases where we're importing more than |
2493 | | one key at a time, we cannot know which key to fingerprint. |
2494 | | In these cases, rather than guessing, we do not |
2495 | | fingerprinting at all, and we must hope the user ID on the |
2496 | | keys are useful. Note that we need to do this for new |
2497 | | keys, merged keys and even for unchanged keys. This is |
2498 | | required because for example the --auto-key-locate feature |
2499 | | may import an already imported key and needs to know the |
2500 | | fingerprint of the key in all cases. */ |
2501 | 3.02k | if (fpr) |
2502 | 0 | { |
2503 | | /* Note that we need to compare against 0 here because |
2504 | | COUNT gets only incremented after returning from this |
2505 | | function. */ |
2506 | 0 | if (!stats->count) |
2507 | 0 | { |
2508 | 0 | xfree (*fpr); |
2509 | 0 | *fpr = fingerprint_from_pk (pk, NULL, fpr_len); |
2510 | 0 | } |
2511 | 0 | else if (origin != KEYORG_WKD) |
2512 | 0 | { |
2513 | 0 | xfree (*fpr); |
2514 | 0 | *fpr = NULL; |
2515 | 0 | } |
2516 | 0 | } |
2517 | 3.02k | } |
2518 | | |
2519 | | /* Now that the key is definitely incorporated into the keydb, we |
2520 | | need to check if a designated revocation is present or if the |
2521 | | prefs are not rational so we can warn the user. */ |
2522 | | |
2523 | 3.03k | if (mod_key) |
2524 | 2.68k | { |
2525 | 2.68k | revocation_present (ctrl, keyblock_orig); |
2526 | 2.68k | if (!from_sk && have_secret_key_with_kid (ctrl, keyid)) |
2527 | 0 | check_prefs (ctrl, keyblock_orig); |
2528 | 2.68k | } |
2529 | 353 | else if (new_key) |
2530 | 27 | { |
2531 | 27 | revocation_present (ctrl, keyblock); |
2532 | 27 | if (!from_sk && have_secret_key_with_kid (ctrl, keyid)) |
2533 | 0 | check_prefs (ctrl, keyblock); |
2534 | 27 | } |
2535 | | |
2536 | 3.03k | release_kbnode( keyblock_orig ); |
2537 | | |
2538 | 3.03k | return err; |
2539 | 3.03k | } |
2540 | | |
2541 | | |
2542 | | /* Wrapper around import_one_real to retry the import in some cases. */ |
2543 | | static gpg_error_t |
2544 | | import_one (ctrl_t ctrl, |
2545 | | kbnode_t keyblock, struct import_stats_s *stats, |
2546 | | unsigned char **fpr, size_t *fpr_len, unsigned int options, |
2547 | | int from_sk, int silent, |
2548 | | import_screener_t screener, void *screener_arg, |
2549 | | int origin, const char *url, int *r_valid) |
2550 | 14.4k | { |
2551 | 14.4k | gpg_error_t err; |
2552 | 14.4k | kbnode_t otherrevsigs = NULL; |
2553 | 14.4k | kbnode_t node; |
2554 | | |
2555 | 14.4k | err = import_one_real (ctrl, keyblock, stats, fpr, fpr_len, options, |
2556 | 14.4k | from_sk, silent, screener, screener_arg, |
2557 | 14.4k | origin, url, r_valid, &otherrevsigs); |
2558 | 14.4k | if (gpg_err_code (err) == GPG_ERR_TOO_LARGE |
2559 | 0 | && gpg_err_source (err) == GPG_ERR_SOURCE_KEYBOX |
2560 | 0 | && ((options & (IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN)) |
2561 | 0 | != (IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN))) |
2562 | 0 | { |
2563 | | /* We hit the maximum image length. Ask the wrapper to do |
2564 | | * everything again but this time with some extra options. */ |
2565 | 0 | u32 keyid[2]; |
2566 | |
|
2567 | 0 | keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); |
2568 | 0 | log_info ("key %s: keyblock too large, retrying with self-sigs-only\n", |
2569 | 0 | keystr (keyid)); |
2570 | 0 | options |= IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN; |
2571 | 0 | err = import_one_real (ctrl, keyblock, stats, fpr, fpr_len, options, |
2572 | 0 | from_sk, silent, screener, screener_arg, |
2573 | 0 | origin, url, r_valid, &otherrevsigs); |
2574 | 0 | } |
2575 | | |
2576 | | /* Finally try to import other revocation certificates. For example |
2577 | | * those of a former key appended to the current key. */ |
2578 | 14.4k | if (!err) |
2579 | 14.4k | { |
2580 | 17.4k | for (node = otherrevsigs; node; node = node->next) |
2581 | 3.02k | { |
2582 | 3.02k | log_info ("trying to import a revocation\n"); |
2583 | 3.02k | import_revoke_cert (ctrl, node, options, stats); |
2584 | 3.02k | } |
2585 | 14.4k | } |
2586 | 14.4k | release_kbnode (otherrevsigs); |
2587 | 14.4k | return err; |
2588 | 14.4k | } |
2589 | | |
2590 | | |
2591 | | |
2592 | | /* Helper to build an s-expression with a composite key RFC-9980 |
2593 | | * ML-KEM key from the data in PK and the additional information |
2594 | | * MLKNAME and ECCNAME. Returns 0 on success and store the |
2595 | | * s-expression at R_SKEY. */ |
2596 | | static gpg_error_t |
2597 | | build_sexp_from_mlk (gcry_sexp_t *r_skey, PKT_public_key *pk, |
2598 | | const char *mlkname, const char *eccname) |
2599 | 0 | { |
2600 | 0 | gpg_error_t err; |
2601 | 0 | gcry_sexp_t s_kyberparm = NULL; |
2602 | 0 | gcry_sexp_t s_kyberfull = NULL; |
2603 | 0 | gcry_sexp_t s_kyberpriv = NULL; |
2604 | 0 | gcry_mpi_t mpi_p = NULL; |
2605 | |
|
2606 | 0 | *r_skey = NULL; |
2607 | | |
2608 | | /* A quick first check. */ |
2609 | 0 | if (!gcry_mpi_get_flag (pk->pkey[3], GCRYMPI_FLAG_OPAQUE) |
2610 | 0 | || !gcry_mpi_get_opaque (pk->pkey[3], NULL)) |
2611 | 0 | { |
2612 | 0 | err = gpg_error (GPG_ERR_BAD_MPI); |
2613 | 0 | goto leave; |
2614 | 0 | } |
2615 | | |
2616 | | /* Create the full Kyber key from the supplied seed. */ |
2617 | 0 | err = gcry_sexp_build (&s_kyberparm, NULL, |
2618 | 0 | "(genkey(%s(derive-parms(seed%m))))", |
2619 | 0 | mlkname, pk->pkey[3]); |
2620 | 0 | if (!err) |
2621 | 0 | err = gcry_pk_genkey (&s_kyberfull, s_kyberparm); |
2622 | 0 | if (err) |
2623 | 0 | goto leave; |
2624 | 0 | gcry_sexp_release (s_kyberparm); s_kyberparm = NULL; |
2625 | | |
2626 | | /* Extract the private kyber part. */ |
2627 | 0 | s_kyberpriv = gcry_sexp_find_token (s_kyberfull, "private-key", 0); |
2628 | 0 | if (!s_kyberpriv) |
2629 | 0 | { |
2630 | 0 | log_error ("key conversion failed: no private key part\n"); |
2631 | 0 | err = gpg_error (GPG_ERR_INV_DATA); |
2632 | 0 | goto leave; |
2633 | 0 | } |
2634 | | |
2635 | | /* Check that the generated public part as returned by genkey |
2636 | | * matches the supplied public key. */ |
2637 | 0 | err = gcry_sexp_extract_param (s_kyberfull, "public-key", "/p", &mpi_p, NULL); |
2638 | 0 | if (err) |
2639 | 0 | goto leave; |
2640 | 0 | if (gcry_mpi_cmp (pk->pkey[1], mpi_p)) |
2641 | 0 | { |
2642 | 0 | err = gpg_error (GPG_ERR_BAD_PUBKEY); |
2643 | 0 | log_error ("key import failed: public key does not match private key\n"); |
2644 | 0 | goto leave; |
2645 | 0 | } |
2646 | | |
2647 | 0 | gcry_sexp_release (s_kyberfull); s_kyberfull = NULL; |
2648 | | |
2649 | | /* Build the composite s-expression. */ |
2650 | 0 | err = gcry_sexp_build (r_skey, NULL, |
2651 | 0 | "(composite-key" |
2652 | 0 | "(private-key(ecc(curve %s)(q%m)(d%m)))" |
2653 | 0 | "%S" |
2654 | 0 | ")", |
2655 | 0 | eccname, pk->pkey[0], pk->pkey[2], s_kyberpriv); |
2656 | | |
2657 | |
|
2658 | 0 | leave: |
2659 | 0 | gcry_sexp_release (s_kyberpriv); |
2660 | 0 | gcry_sexp_release (s_kyberfull); |
2661 | 0 | gcry_sexp_release (s_kyberparm); |
2662 | 0 | gcry_mpi_release (mpi_p); |
2663 | 0 | return err; |
2664 | 0 | } |
2665 | | |
2666 | | |
2667 | | /* Return a malloced string with the canonical name of the curve |
2668 | | * represented by MPI A. If no canonical name is known the OID in |
2669 | | * dotted-decimal form is returned. On error NULL is returned. */ |
2670 | | static char * |
2671 | | oid_to_canon_curve (gcry_mpi_t a) |
2672 | 0 | { |
2673 | 0 | char *curvestr; |
2674 | |
|
2675 | 0 | curvestr = openpgp_oid_to_str (a); |
2676 | 0 | if (curvestr) |
2677 | 0 | { |
2678 | 0 | const char *curvename = openpgp_oid_to_curve (curvestr, 1); |
2679 | 0 | if (curvename) |
2680 | 0 | { |
2681 | 0 | xfree (curvestr); |
2682 | 0 | curvestr = xtrystrdup (curvename); |
2683 | 0 | } |
2684 | 0 | } |
2685 | 0 | return curvestr; |
2686 | 0 | } |
2687 | | |
2688 | | |
2689 | | /* This function builds a gpg-agent private key format (aka mode1003) |
2690 | | * s-expression from the secret key packet in PK. It currently |
2691 | | * fails for a protected key. The final plan is to use a separate |
2692 | | * helper for re-encrypting a protected key. */ |
2693 | | static gpg_error_t |
2694 | | build_mode1003_sexp (PKT_public_key *pk, gcry_sexp_t *result) |
2695 | 0 | { |
2696 | 0 | gpg_error_t err; |
2697 | 0 | int nskey; |
2698 | 0 | gcry_sexp_t skey = NULL; |
2699 | 0 | char *curvename = NULL; |
2700 | |
|
2701 | 0 | *result = NULL; |
2702 | |
|
2703 | 0 | nskey = pubkey_get_nskey (pk->pubkey_algo); |
2704 | 0 | if (!nskey || nskey > PUBKEY_MAX_NSKEY || !pk->seckey_info) |
2705 | 0 | { |
2706 | 0 | err = gpg_error (GPG_ERR_BAD_SECKEY); |
2707 | 0 | log_error ("%s: internal error: %s\n", __func__, gpg_strerror (err)); |
2708 | 0 | goto leave; |
2709 | 0 | } |
2710 | | |
2711 | 0 | if (pk->seckey_info->is_protected) |
2712 | 0 | { |
2713 | 0 | err = gpg_error (GPG_ERR_INTERNAL); |
2714 | 0 | log_error ("%s: protected seckeys are not yet supported\n", __func__); |
2715 | 0 | goto leave; |
2716 | 0 | } |
2717 | | |
2718 | 0 | switch (pk->pubkey_algo) |
2719 | 0 | { |
2720 | 0 | case GCRY_PK_RSA: |
2721 | 0 | case GCRY_PK_RSA_E: |
2722 | 0 | case GCRY_PK_RSA_S: |
2723 | | /* Check the condition P < Q, since libgcrypt requires that. |
2724 | | * LibrePGP/OpenPGP also requires this condition. */ |
2725 | 0 | if (gcry_mpi_cmp (pk->pkey[3], pk->pkey[4]) >= 0) |
2726 | 0 | err = gpg_error (GPG_ERR_BAD_SECKEY); |
2727 | 0 | else |
2728 | 0 | err = gcry_sexp_build |
2729 | 0 | (&skey, NULL, "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", |
2730 | 0 | pk->pkey[0], pk->pkey[1], |
2731 | 0 | pk->pkey[2], pk->pkey[3], pk->pkey[4], pk->pkey[5]); |
2732 | 0 | break; |
2733 | | |
2734 | 0 | case PUBKEY_ALGO_DSA: |
2735 | 0 | err = gcry_sexp_build (&skey, NULL, |
2736 | 0 | "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", |
2737 | 0 | pk->pkey[0], pk->pkey[1], pk->pkey[2], |
2738 | 0 | pk->pkey[3], pk->pkey[4]); |
2739 | 0 | break; |
2740 | | |
2741 | 0 | case PUBKEY_ALGO_ELGAMAL: |
2742 | 0 | case PUBKEY_ALGO_ELGAMAL_E: |
2743 | 0 | err = gcry_sexp_build (&skey, NULL, |
2744 | 0 | "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", |
2745 | 0 | pk->pkey[0], pk->pkey[1], pk->pkey[2], |
2746 | 0 | pk->pkey[3]); |
2747 | 0 | break; |
2748 | | |
2749 | 0 | case PUBKEY_ALGO_ECDH: |
2750 | | /* Note that pkey[2] conveys the KDF parameters. */ |
2751 | 0 | curvename = oid_to_canon_curve (pk->pkey[0]); |
2752 | 0 | if (!curvename) |
2753 | 0 | err = gpg_error_from_syserror (); |
2754 | 0 | else if (openpgp_oid_is_cv25519 (pk->pkey[0])) |
2755 | 0 | err = gcry_sexp_build |
2756 | 0 | (&skey,NULL,"(private-key(ecc(curve %s)(flags djb-tweak)(q%m)(d%m)))", |
2757 | 0 | curvename, pk->pkey[1], pk->pkey[3]); |
2758 | 0 | else |
2759 | 0 | err = gcry_sexp_build |
2760 | 0 | (&skey,NULL,"(private-key(ecc(curve %s)(q%m)(d%m)))", |
2761 | 0 | curvename, pk->pkey[1], pk->pkey[3]); |
2762 | 0 | break; |
2763 | | |
2764 | 0 | case PUBKEY_ALGO_X25519: |
2765 | 0 | err = gcry_sexp_build |
2766 | 0 | (&skey,NULL,"(private-key(ecc(curve ietf25)(q%m)(d%m)))", |
2767 | 0 | pk->pkey[0], pk->pkey[1]); |
2768 | 0 | break; |
2769 | | |
2770 | 0 | case PUBKEY_ALGO_ECDSA: |
2771 | 0 | curvename = oid_to_canon_curve (pk->pkey[0]); |
2772 | 0 | if (!curvename) |
2773 | 0 | err = gpg_error_from_syserror (); |
2774 | 0 | else |
2775 | 0 | err = gcry_sexp_build |
2776 | 0 | (&skey, NULL, "(private-key(ecc(curve %s)(q%m)(d%m)))", |
2777 | 0 | curvename, pk->pkey[1], pk->pkey[2]); |
2778 | 0 | break; |
2779 | | |
2780 | 0 | case PUBKEY_ALGO_EDDSA: |
2781 | 0 | curvename = oid_to_canon_curve (pk->pkey[0]); |
2782 | 0 | if (!curvename) |
2783 | 0 | err = gpg_error_from_syserror (); |
2784 | 0 | else |
2785 | 0 | err = gcry_sexp_build |
2786 | 0 | (&skey, NULL, "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))", |
2787 | 0 | curvename, pk->pkey[1], pk->pkey[2]); |
2788 | 0 | break; |
2789 | | |
2790 | 0 | case PUBKEY_ALGO_ED25519: |
2791 | 0 | err = gcry_sexp_build |
2792 | 0 | (&skey, NULL,"(private-key(ecc(curve Ed25519)(flags eddsa)(q%m)(d%m)))", |
2793 | 0 | pk->pkey[0], pk->pkey[1]); |
2794 | 0 | break; |
2795 | | |
2796 | 0 | case PUBKEY_ALGO_MLK768_25519: |
2797 | 0 | err = build_sexp_from_mlk (&skey, pk, "kyber768", "ietf25"); |
2798 | 0 | break; |
2799 | | |
2800 | 0 | case PUBKEY_ALGO_MLK768_NP384: |
2801 | 0 | err = build_sexp_from_mlk (&skey, pk, "kyber768", "nistp384"); |
2802 | 0 | break; |
2803 | | |
2804 | 0 | case PUBKEY_ALGO_MLK768_BP384: |
2805 | 0 | err = build_sexp_from_mlk (&skey, pk, "kyber768", "brainpoolP384r1"); |
2806 | 0 | break; |
2807 | | |
2808 | 0 | case PUBKEY_ALGO_MLK1024_448: |
2809 | 0 | err = build_sexp_from_mlk (&skey, pk, "kyber1024", "X448"); |
2810 | 0 | break; |
2811 | | |
2812 | 0 | case PUBKEY_ALGO_MLK1024_NP521: |
2813 | 0 | err = build_sexp_from_mlk (&skey, pk, "kyber1024", "nistp521"); |
2814 | 0 | break; |
2815 | | |
2816 | 0 | case PUBKEY_ALGO_MLK1024_BP512: |
2817 | 0 | err = build_sexp_from_mlk (&skey, pk, "kyber1024", "brainpoolP512r1"); |
2818 | 0 | break; |
2819 | | |
2820 | 0 | default: |
2821 | 0 | err = gpg_error (GPG_ERR_PUBKEY_ALGO); |
2822 | 0 | break; |
2823 | 0 | } |
2824 | | |
2825 | 0 | if (!err) |
2826 | 0 | { |
2827 | 0 | *result = skey; |
2828 | 0 | skey = NULL; |
2829 | 0 | } |
2830 | |
|
2831 | 0 | leave: |
2832 | 0 | gcry_sexp_release (skey); |
2833 | 0 | xfree (curvename); |
2834 | 0 | return err; |
2835 | 0 | } |
2836 | | |
2837 | | |
2838 | | /* Convert our internal secret key object into an S-expression. PK is |
2839 | | * the public key. R_CURVE received an sexp with the name of the |
2840 | | * curve; caller must free this. R_SKEY will receive the result; |
2841 | | * caller must of course also free this. |
2842 | | * |
2843 | | * Note that this SEXP is only intended to be transferred to |
2844 | | * gpg-agent, which is not in actual use by any public key computation |
2845 | | * with libgcrypt. For transfer, it omits (flags ...) part in the |
2846 | | * expression. It is the gpg-agent which will composes the SEXP in |
2847 | | * use, adding required (flags ...) part. |
2848 | | */ |
2849 | | static gpg_error_t |
2850 | | internal_skey_object_to_sexp (PKT_public_key *pk, gcry_sexp_t *r_curve, |
2851 | | gcry_sexp_t *r_skey) |
2852 | 0 | { |
2853 | 0 | gpg_error_t err; |
2854 | 0 | int nskey; |
2855 | 0 | int i, j; |
2856 | 0 | membuf_t mbuf; |
2857 | 0 | const char *curvename; |
2858 | 0 | char *curvestr = NULL; |
2859 | 0 | void *format_args[2*PUBKEY_MAX_NSKEY]; |
2860 | |
|
2861 | 0 | *r_curve = NULL; |
2862 | 0 | *r_skey = NULL; |
2863 | 0 | init_membuf (&mbuf, 50); |
2864 | |
|
2865 | 0 | nskey = pubkey_get_nskey (pk->pubkey_algo); |
2866 | 0 | if (!nskey || nskey > PUBKEY_MAX_NSKEY) |
2867 | 0 | { |
2868 | 0 | err = gpg_error (GPG_ERR_BAD_SECKEY); |
2869 | 0 | log_error ("internal error: %s\n", gpg_strerror (err)); |
2870 | 0 | goto leave; |
2871 | 0 | } |
2872 | | |
2873 | 0 | put_membuf_str (&mbuf, "(skey"); |
2874 | |
|
2875 | 0 | if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA |
2876 | 0 | || pk->pubkey_algo == PUBKEY_ALGO_EDDSA |
2877 | 0 | || pk->pubkey_algo == PUBKEY_ALGO_ECDH) |
2878 | 0 | { |
2879 | | /* The ECC case. */ |
2880 | 0 | curvestr = openpgp_oid_to_str (pk->pkey[0]); |
2881 | 0 | if (!curvestr) |
2882 | 0 | { |
2883 | 0 | err = gpg_error_from_syserror (); |
2884 | 0 | goto leave; |
2885 | 0 | } |
2886 | | |
2887 | 0 | curvename = openpgp_oid_to_curve (curvestr, 1); |
2888 | 0 | gcry_sexp_release (*r_curve); |
2889 | 0 | err = gcry_sexp_build (r_curve, NULL, "(curve %s)", |
2890 | 0 | curvename?curvename:curvestr); |
2891 | 0 | if (err) |
2892 | 0 | goto leave; |
2893 | | |
2894 | 0 | j = 0; |
2895 | | /* Append the public key element Q. */ |
2896 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2897 | 0 | format_args[j++] = pk->pkey + 1; |
2898 | | |
2899 | | /* Append the secret key element D. For ECDH we skip PKEY[2] |
2900 | | * because this holds the KEK which is not needed by gpg-agent. */ |
2901 | 0 | i = pk->pubkey_algo == PUBKEY_ALGO_ECDH? 3 : 2; |
2902 | 0 | if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER1)) |
2903 | 0 | put_membuf_str (&mbuf, " e %m"); |
2904 | 0 | else |
2905 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2906 | 0 | format_args[j++] = pk->pkey + i; |
2907 | | |
2908 | | /* Simple hack to print a warning for an invalid key in case of |
2909 | | * cv25519. We have only opaque MPIs here. */ |
2910 | 0 | if (pk->pubkey_algo == PUBKEY_ALGO_ECDH |
2911 | 0 | && !strcmp (curvestr, "1.3.6.1.4.1.3029.1.5.1") |
2912 | 0 | && !gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER1) |
2913 | 0 | && gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) |
2914 | 0 | { |
2915 | 0 | const unsigned char *pp; |
2916 | 0 | unsigned int nn; |
2917 | |
|
2918 | 0 | pp = gcry_mpi_get_opaque (pk->pkey[i], &nn); |
2919 | 0 | nn = (nn+7)/8; |
2920 | 0 | if (pp && nn && (pp[nn-1] & 7)) |
2921 | 0 | log_info ("warning: lower 3 bits of the secret key" |
2922 | 0 | " are not cleared\n"); |
2923 | 0 | } |
2924 | 0 | } |
2925 | 0 | else if (RFC9980 && pk->pubkey_algo == PUBKEY_ALGO_ED25519) |
2926 | 0 | { |
2927 | 0 | gcry_sexp_release (*r_curve); |
2928 | 0 | err = gcry_sexp_build (r_curve, NULL, "(curve Ed25519)"); |
2929 | 0 | if (err) |
2930 | 0 | goto leave; |
2931 | | |
2932 | 0 | j = 0; |
2933 | | /* Append the public key element Q. */ |
2934 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2935 | 0 | format_args[j++] = pk->pkey + 0; |
2936 | | |
2937 | | /* Append the secret key element D. */ |
2938 | 0 | if (gcry_mpi_get_flag (pk->pkey[1], GCRYMPI_FLAG_USER1)) |
2939 | 0 | put_membuf_str (&mbuf, " e %m"); |
2940 | 0 | else |
2941 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2942 | 0 | format_args[j++] = pk->pkey + 1; |
2943 | 0 | } |
2944 | 0 | else if (RFC9980 && pk->pubkey_algo == PUBKEY_ALGO_X25519) |
2945 | 0 | { |
2946 | 0 | gcry_sexp_release (*r_curve); |
2947 | 0 | err = gcry_sexp_build (r_curve, NULL, "(curve ietf25)"); |
2948 | 0 | if (err) |
2949 | 0 | goto leave; |
2950 | | |
2951 | 0 | j = 0; |
2952 | | /* Append the public key element Q. */ |
2953 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2954 | 0 | format_args[j++] = pk->pkey + 0; |
2955 | | |
2956 | | /* Append the secret key element D. */ |
2957 | 0 | if (gcry_mpi_get_flag (pk->pkey[1], GCRYMPI_FLAG_USER1)) |
2958 | 0 | put_membuf_str (&mbuf, " e %m"); |
2959 | 0 | else |
2960 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2961 | 0 | format_args[j++] = pk->pkey + 1; |
2962 | 0 | } |
2963 | 0 | else /* Standard case for the old (non-ECC) algorithms. */ |
2964 | 0 | { |
2965 | 0 | for (i=j=0; i < nskey; i++) |
2966 | 0 | { |
2967 | 0 | if (!pk->pkey[i]) |
2968 | 0 | continue; /* Protected keys only have NPKEY+1 elements. */ |
2969 | | |
2970 | 0 | if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER1)) |
2971 | 0 | put_membuf_str (&mbuf, " e %m"); |
2972 | 0 | else |
2973 | 0 | put_membuf_str (&mbuf, " _ %m"); |
2974 | 0 | format_args[j++] = pk->pkey + i; |
2975 | 0 | } |
2976 | 0 | } |
2977 | 0 | put_membuf_str (&mbuf, ")"); |
2978 | 0 | put_membuf (&mbuf, "", 1); |
2979 | | |
2980 | | /* Finally convert to an sexp and store that at R_SKEY. */ |
2981 | 0 | { |
2982 | 0 | char *format = get_membuf (&mbuf, NULL); |
2983 | 0 | if (!format) |
2984 | 0 | err = gpg_error_from_syserror (); |
2985 | 0 | else |
2986 | 0 | err = gcry_sexp_build_array (r_skey, NULL, format, format_args); |
2987 | 0 | xfree (format); |
2988 | 0 | } |
2989 | |
|
2990 | 0 | leave: |
2991 | 0 | xfree (curvestr); |
2992 | 0 | xfree (get_membuf (&mbuf, NULL)); |
2993 | 0 | return err; |
2994 | 0 | } |
2995 | | |
2996 | | |
2997 | | static gpg_error_t |
2998 | | build_classic_transfer_sexp (PKT_public_key *pk, gcry_sexp_t *result) |
2999 | 0 | { |
3000 | 0 | gpg_error_t err; |
3001 | 0 | gcry_sexp_t skey; |
3002 | 0 | gcry_sexp_t prot = NULL; |
3003 | 0 | gcry_sexp_t curve = NULL; |
3004 | 0 | struct seckey_info *ski = pk->seckey_info; |
3005 | |
|
3006 | 0 | *result = NULL; |
3007 | | |
3008 | | /* Convert our internal secret key object into an S-expression. */ |
3009 | 0 | err = internal_skey_object_to_sexp (pk, &curve, &skey); |
3010 | 0 | if (err) |
3011 | 0 | { |
3012 | 0 | log_error ("error building skey array: %s\n", gpg_strerror (err)); |
3013 | 0 | goto leave; |
3014 | 0 | } |
3015 | 0 | log_assert (skey); |
3016 | | |
3017 | 0 | if (ski->is_protected) |
3018 | 0 | { |
3019 | 0 | char countbuf[35]; |
3020 | | |
3021 | | /* FIXME: Support AEAD */ |
3022 | | /* Note that the IVLEN may be zero if we are working on a dummy |
3023 | | * key. We can't express that in an S-expression and thus we |
3024 | | * send dummy data for the IV. */ |
3025 | 0 | snprintf (countbuf, sizeof countbuf, "%lu",(unsigned long)ski->s2k.count); |
3026 | 0 | err = gcry_sexp_build (&prot, NULL, |
3027 | 0 | " (protection %s %s %b %d %s %b %s)\n", |
3028 | 0 | ski->sha1chk? "sha1":"sum", |
3029 | 0 | openpgp_cipher_algo_name (ski->algo), |
3030 | 0 | ski->ivlen? (int)ski->ivlen:1, |
3031 | 0 | ski->ivlen? ski->iv: (const unsigned char*)"X", |
3032 | 0 | ski->s2k.mode, |
3033 | 0 | openpgp_md_algo_name (ski->s2k.hash_algo), |
3034 | 0 | (int)sizeof (ski->s2k.salt), ski->s2k.salt, |
3035 | 0 | countbuf); |
3036 | 0 | } |
3037 | 0 | else |
3038 | 0 | err = gcry_sexp_build (&prot, NULL, " (protection none)\n"); |
3039 | 0 | if (err) |
3040 | 0 | goto leave; |
3041 | | |
3042 | 0 | err = gcry_sexp_build (result, NULL, |
3043 | 0 | "(openpgp-private-key\n" |
3044 | 0 | " (version %d)\n" |
3045 | 0 | " (algo %s)\n" |
3046 | 0 | " %S%S\n" |
3047 | 0 | " (csum %d)\n" |
3048 | 0 | " %S)\n", |
3049 | 0 | pk->version, |
3050 | 0 | openpgp_pk_algo_name (pk->pubkey_algo), |
3051 | 0 | curve, skey, |
3052 | 0 | (int)(unsigned long)ski->csum, prot); |
3053 | |
|
3054 | 0 | leave: |
3055 | 0 | gcry_sexp_release (prot); |
3056 | 0 | gcry_sexp_release (skey); |
3057 | 0 | gcry_sexp_release (curve); |
3058 | 0 | return err; |
3059 | 0 | } |
3060 | | |
3061 | | |
3062 | | /* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The |
3063 | | * function prints diagnostics and returns an error code. If BATCH is |
3064 | | * true the secret keys are stored by gpg-agent in the transfer format |
3065 | | * (i.e. no re-protection and aksing for passphrases). If ONLY_MARKED |
3066 | | * is set, only those nodes with flag NODE_TRANSFER_SECKEY are |
3067 | | * processed. */ |
3068 | | gpg_error_t |
3069 | | transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats, |
3070 | | kbnode_t sec_keyblock, int batch, int force, |
3071 | | int only_marked) |
3072 | 75 | { |
3073 | 75 | gpg_error_t err = 0; |
3074 | 75 | void *kek = NULL; |
3075 | 75 | size_t keklen; |
3076 | 75 | kbnode_t ctx = NULL; |
3077 | 75 | kbnode_t node; |
3078 | 75 | PKT_public_key *main_pk, *pk; |
3079 | 75 | struct seckey_info *ski; |
3080 | 75 | gcry_sexp_t tmpsexp; |
3081 | 75 | unsigned char *transferkey = NULL; |
3082 | 75 | size_t transferkeylen; |
3083 | 75 | gcry_cipher_hd_t cipherhd = NULL; |
3084 | 75 | unsigned char *wrappedkey = NULL; |
3085 | 75 | size_t wrappedkeylen; |
3086 | 75 | char *cache_nonce = NULL; |
3087 | 75 | int stub_key_skipped = 0; |
3088 | 75 | int use_mode1003 = 0; |
3089 | | |
3090 | | /* Get the current KEK. */ |
3091 | 75 | err = agent_keywrap_key (ctrl, 0, &kek, &keklen); |
3092 | 75 | if (err) |
3093 | 75 | { |
3094 | 75 | log_error ("error getting the KEK: %s\n", gpg_strerror (err)); |
3095 | 75 | goto leave; |
3096 | 75 | } |
3097 | | |
3098 | | /* Prepare a cipher context. */ |
3099 | 0 | err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128, |
3100 | 0 | GCRY_CIPHER_MODE_AESWRAP, 0); |
3101 | 0 | if (!err) |
3102 | 0 | err = gcry_cipher_setkey (cipherhd, kek, keklen); |
3103 | 0 | if (err) |
3104 | 0 | goto leave; |
3105 | 0 | xfree (kek); |
3106 | 0 | kek = NULL; |
3107 | | |
3108 | | /* Note: We need to use walk_kbnode so that we skip nodes which are |
3109 | | * marked as deleted. */ |
3110 | 0 | main_pk = NULL; |
3111 | 0 | while ((node = walk_kbnode (sec_keyblock, &ctx, 0))) |
3112 | 0 | { |
3113 | 0 | if (node->pkt->pkttype != PKT_SECRET_KEY |
3114 | 0 | && node->pkt->pkttype != PKT_SECRET_SUBKEY) |
3115 | 0 | continue; |
3116 | 0 | if (only_marked && !(node->flag & NODE_TRANSFER_SECKEY)) |
3117 | 0 | continue; |
3118 | 0 | pk = node->pkt->pkt.public_key; |
3119 | 0 | if (!main_pk) |
3120 | 0 | main_pk = pk; |
3121 | | |
3122 | | /* Make sure the keyids are available. */ |
3123 | 0 | keyid_from_pk (pk, NULL); |
3124 | 0 | if (node->pkt->pkttype == PKT_SECRET_KEY) |
3125 | 0 | { |
3126 | 0 | pk->main_keyid[0] = pk->keyid[0]; |
3127 | 0 | pk->main_keyid[1] = pk->keyid[1]; |
3128 | 0 | } |
3129 | 0 | else |
3130 | 0 | { |
3131 | 0 | pk->main_keyid[0] = main_pk->keyid[0]; |
3132 | 0 | pk->main_keyid[1] = main_pk->keyid[1]; |
3133 | 0 | } |
3134 | | |
3135 | |
|
3136 | 0 | ski = pk->seckey_info; |
3137 | 0 | if (!ski) |
3138 | 0 | BUG (); |
3139 | | |
3140 | 0 | if (stats) |
3141 | 0 | { |
3142 | 0 | stats->count++; |
3143 | 0 | stats->secret_read++; |
3144 | 0 | } |
3145 | | |
3146 | | /* We ignore stub keys. The way we handle them in other parts |
3147 | | of the code is by asking the agent whether any secret key is |
3148 | | available for a given keyblock and then concluding that we |
3149 | | have a secret key; all secret (sub)keys of the keyblock the |
3150 | | agent does not know of are then stub keys. This works also |
3151 | | for card stub keys. The learn command or the card-status |
3152 | | command may be used to check with the agent whether a card |
3153 | | has been inserted and a stub key is in turn generated by the |
3154 | | agent. */ |
3155 | 0 | if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002) |
3156 | 0 | { |
3157 | 0 | stub_key_skipped = 1; |
3158 | 0 | continue; |
3159 | 0 | } |
3160 | | |
3161 | 0 | tmpsexp = NULL; |
3162 | 0 | if (ski->s2k.mode == 1003) |
3163 | 0 | { |
3164 | 0 | const void *tmpbuf; |
3165 | 0 | unsigned int tmpbuflen; |
3166 | 0 | int npkey; |
3167 | | |
3168 | | /* Fixme: Check that the public key parameters in pkey match |
3169 | | * those in the s-expression of the secret key. */ |
3170 | 0 | npkey = pubkey_get_npkey (pk->pubkey_algo); |
3171 | 0 | if (npkey+1 > PUBKEY_MAX_NSKEY) |
3172 | 0 | err = gpg_error (GPG_ERR_BAD_SECKEY); |
3173 | 0 | else if (!pk->pkey[npkey] |
3174 | 0 | || !gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE)) |
3175 | 0 | err = gpg_error (GPG_ERR_BAD_SECKEY); |
3176 | 0 | else |
3177 | 0 | { |
3178 | 0 | tmpbuf = gcry_mpi_get_opaque (pk->pkey[npkey], &tmpbuflen); |
3179 | 0 | tmpbuflen = (tmpbuflen +7)/8; /* Fixup bits to bytes */ |
3180 | 0 | err = gcry_sexp_new (&tmpsexp, tmpbuf, tmpbuflen, 0); |
3181 | 0 | } |
3182 | 0 | use_mode1003 = 1; |
3183 | 0 | } |
3184 | 0 | else if (!ski->is_protected) |
3185 | 0 | { |
3186 | | /* The key is not protected. Build a mode1003 format here. */ |
3187 | 0 | err = build_mode1003_sexp (pk, &tmpsexp); |
3188 | 0 | use_mode1003 = 1; |
3189 | 0 | } |
3190 | 0 | else |
3191 | 0 | err = build_classic_transfer_sexp (pk, &tmpsexp); |
3192 | |
|
3193 | 0 | xfree (transferkey); |
3194 | 0 | transferkey = NULL; |
3195 | 0 | if (!err) |
3196 | 0 | err = make_canon_sexp_pad (tmpsexp, 1, &transferkey, &transferkeylen); |
3197 | 0 | gcry_sexp_release (tmpsexp); |
3198 | 0 | tmpsexp = NULL; |
3199 | 0 | if (err) |
3200 | 0 | { |
3201 | 0 | log_error ("error building transfer key: %s\n", gpg_strerror (err)); |
3202 | 0 | goto leave; |
3203 | 0 | } |
3204 | | |
3205 | | /* Wrap the key. */ |
3206 | 0 | wrappedkeylen = transferkeylen + 8; |
3207 | 0 | xfree (wrappedkey); |
3208 | 0 | wrappedkey = xtrymalloc (wrappedkeylen); |
3209 | 0 | if (!wrappedkey) |
3210 | 0 | err = gpg_error_from_syserror (); |
3211 | 0 | else |
3212 | 0 | err = gcry_cipher_encrypt (cipherhd, wrappedkey, wrappedkeylen, |
3213 | 0 | transferkey, transferkeylen); |
3214 | 0 | if (err) |
3215 | 0 | goto leave; |
3216 | 0 | xfree (transferkey); |
3217 | 0 | transferkey = NULL; |
3218 | | |
3219 | | /* Send the wrapped key to the agent. */ |
3220 | 0 | { |
3221 | 0 | char *desc = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_IMPORT, 1); |
3222 | 0 | err = agent_import_key (ctrl, desc, use_mode1003, |
3223 | 0 | &cache_nonce, |
3224 | 0 | wrappedkey, wrappedkeylen, batch, force, |
3225 | 0 | pk->keyid, pk->main_keyid, pk->pubkey_algo, |
3226 | 0 | pk->timestamp); |
3227 | 0 | xfree (desc); |
3228 | 0 | } |
3229 | 0 | if (!err) |
3230 | 0 | { |
3231 | 0 | if (opt.verbose) |
3232 | 0 | log_info (_("key %s: secret key imported\n"), |
3233 | 0 | keystr_from_pk_with_sub (main_pk, pk)); |
3234 | 0 | if (stats) |
3235 | 0 | stats->secret_imported++; |
3236 | 0 | } |
3237 | 0 | else if ( gpg_err_code (err) == GPG_ERR_EEXIST ) |
3238 | 0 | { |
3239 | 0 | if (opt.verbose) |
3240 | 0 | log_info (_("key %s: secret key already exists\n"), |
3241 | 0 | keystr_from_pk_with_sub (main_pk, pk)); |
3242 | 0 | err = 0; |
3243 | 0 | if (stats) |
3244 | 0 | stats->secret_dups++; |
3245 | 0 | } |
3246 | 0 | else |
3247 | 0 | { |
3248 | 0 | log_error (_("key %s: error sending to agent: %s\n"), |
3249 | 0 | keystr_from_pk_with_sub (main_pk, pk), |
3250 | 0 | gpg_strerror (err)); |
3251 | 0 | if (gpg_err_code (err) == GPG_ERR_CANCELED |
3252 | 0 | || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED) |
3253 | 0 | break; /* Don't try the other subkeys. */ |
3254 | 0 | } |
3255 | 0 | } |
3256 | | |
3257 | 0 | if (!err && stub_key_skipped) |
3258 | | /* We need to notify user how to migrate stub keys. */ |
3259 | 0 | err = gpg_error (GPG_ERR_NOT_PROCESSED); |
3260 | |
|
3261 | 75 | leave: |
3262 | 75 | xfree (cache_nonce); |
3263 | 75 | xfree (wrappedkey); |
3264 | 75 | xfree (transferkey); |
3265 | 75 | gcry_cipher_close (cipherhd); |
3266 | 75 | xfree (kek); |
3267 | 75 | return err; |
3268 | 0 | } |
3269 | | |
3270 | | |
3271 | | /* Create a name-value container from a secret (sub)key packet PK. |
3272 | | * Callers needs to release it. This function can be used to list |
3273 | | * secret keys as s-expression in a format as used for our private |
3274 | | * keys. Works only with unprotected keys. Callers needs to release |
3275 | | * the result. On error NULL is returned. */ |
3276 | | nvc_t |
3277 | | seckey_packet_to_nvc (PKT_public_key *pk) |
3278 | 0 | { |
3279 | 0 | gcry_sexp_t mysexp; |
3280 | 0 | nvc_t result; |
3281 | |
|
3282 | 0 | if (build_mode1003_sexp (pk, &mysexp) || !mysexp) |
3283 | 0 | return NULL; |
3284 | | |
3285 | 0 | result = nvc_new_private_key (); |
3286 | 0 | if (result) |
3287 | 0 | { |
3288 | 0 | if (nvc_set_private_key (result, mysexp)) |
3289 | 0 | { |
3290 | 0 | nvc_release (result); |
3291 | 0 | result = NULL; |
3292 | 0 | } |
3293 | 0 | } |
3294 | 0 | gcry_sexp_release (mysexp); |
3295 | 0 | return result; |
3296 | 0 | } |
3297 | | |
3298 | | |
3299 | | /* Walk a secret keyblock and produce a public keyblock out of it. |
3300 | | * Returns a new node or NULL on error. Modifies the tag field of the |
3301 | | * nodes. */ |
3302 | | static kbnode_t |
3303 | | sec_to_pub_keyblock (kbnode_t sec_keyblock) |
3304 | 1.17k | { |
3305 | 1.17k | kbnode_t pub_keyblock = NULL; |
3306 | 1.17k | kbnode_t ctx = NULL; |
3307 | 1.17k | kbnode_t secnode, pubnode; |
3308 | 1.17k | kbnode_t lastnode = NULL; |
3309 | 1.17k | unsigned int tag = 0; |
3310 | | |
3311 | | /* Set a tag to all nodes. */ |
3312 | 12.2k | for (secnode = sec_keyblock; secnode; secnode = secnode->next) |
3313 | 11.0k | secnode->tag = ++tag; |
3314 | | |
3315 | | /* Copy. */ |
3316 | 12.2k | while ((secnode = walk_kbnode (sec_keyblock, &ctx, 0))) |
3317 | 11.0k | { |
3318 | 11.0k | if (secnode->pkt->pkttype == PKT_SECRET_KEY |
3319 | 9.87k | || secnode->pkt->pkttype == PKT_SECRET_SUBKEY) |
3320 | 2.15k | { |
3321 | | /* Make a public key. */ |
3322 | 2.15k | PACKET *pkt; |
3323 | 2.15k | PKT_public_key *pk; |
3324 | | |
3325 | 2.15k | pkt = xtrycalloc (1, sizeof *pkt); |
3326 | 2.15k | pk = pkt? copy_public_key (NULL, secnode->pkt->pkt.public_key): NULL; |
3327 | 2.15k | if (!pk) |
3328 | 0 | { |
3329 | 0 | xfree (pkt); |
3330 | 0 | release_kbnode (pub_keyblock); |
3331 | 0 | return NULL; |
3332 | 0 | } |
3333 | 2.15k | if (secnode->pkt->pkttype == PKT_SECRET_KEY) |
3334 | 1.17k | pkt->pkttype = PKT_PUBLIC_KEY; |
3335 | 981 | else |
3336 | 981 | pkt->pkttype = PKT_PUBLIC_SUBKEY; |
3337 | 2.15k | pkt->pkt.public_key = pk; |
3338 | | |
3339 | 2.15k | pubnode = new_kbnode (pkt); |
3340 | 2.15k | } |
3341 | 8.89k | else |
3342 | 8.89k | { |
3343 | 8.89k | pubnode = clone_kbnode (secnode); |
3344 | 8.89k | } |
3345 | 11.0k | pubnode->tag = secnode->tag; |
3346 | | |
3347 | 11.0k | if (!pub_keyblock) |
3348 | 1.17k | pub_keyblock = lastnode = pubnode; |
3349 | 9.87k | else |
3350 | 9.87k | { |
3351 | 9.87k | lastnode->next = pubnode; |
3352 | 9.87k | lastnode = pubnode; |
3353 | 9.87k | } |
3354 | 11.0k | } |
3355 | | |
3356 | 1.17k | return pub_keyblock; |
3357 | 1.17k | } |
3358 | | |
3359 | | |
3360 | | /* Delete all notes in the keyblock at R_KEYBLOCK which are not in |
3361 | | * PUB_KEYBLOCK. Modifies the tags of both keyblock's nodes. */ |
3362 | | static gpg_error_t |
3363 | | resync_sec_with_pub_keyblock (kbnode_t *r_keyblock, kbnode_t pub_keyblock, |
3364 | | kbnode_t *r_removedsecs) |
3365 | 1.17k | { |
3366 | 1.17k | kbnode_t sec_keyblock = *r_keyblock; |
3367 | 1.17k | kbnode_t node, prevnode; |
3368 | 1.17k | unsigned int *taglist; |
3369 | 1.17k | unsigned int ntaglist, n; |
3370 | 1.17k | kbnode_t attic = NULL; |
3371 | 1.17k | kbnode_t *attic_head = &attic; |
3372 | | |
3373 | | /* Collect all tags in an array for faster searching. */ |
3374 | 2.76k | for (ntaglist = 0, node = pub_keyblock; node; node = node->next) |
3375 | 1.59k | ntaglist++; |
3376 | 1.17k | taglist = xtrycalloc (ntaglist, sizeof *taglist); |
3377 | 1.17k | if (!taglist) |
3378 | 0 | return gpg_error_from_syserror (); |
3379 | 2.76k | for (ntaglist = 0, node = pub_keyblock; node; node = node->next) |
3380 | 1.59k | taglist[ntaglist++] = node->tag; |
3381 | | |
3382 | | /* Walks over the secret keyblock and delete all nodes which are not |
3383 | | * in the tag list. Those nodes have been deleted in the |
3384 | | * pub_keyblock. Sequential search is a bit lazy and could be |
3385 | | * optimized by sorting and bsearch; however secret keyrings are |
3386 | | * short and there are easier ways to DoS the import. */ |
3387 | 2.14k | again: |
3388 | 15.3k | for (prevnode=NULL, node=sec_keyblock; node; prevnode=node, node=node->next) |
3389 | 14.1k | { |
3390 | 36.8k | for (n=0; n < ntaglist; n++) |
3391 | 25.2k | if (taglist[n] == node->tag) |
3392 | 2.58k | break; |
3393 | 14.1k | if (n == ntaglist) /* Not in public keyblock. */ |
3394 | 11.5k | { |
3395 | 11.5k | if (node->pkt->pkttype == PKT_SECRET_KEY |
3396 | 11.5k | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
3397 | 977 | { |
3398 | 977 | if (!prevnode) |
3399 | 0 | sec_keyblock = node->next; |
3400 | 977 | else |
3401 | 977 | prevnode->next = node->next; |
3402 | 977 | node->next = NULL; |
3403 | 977 | *attic_head = node; |
3404 | 977 | attic_head = &node->next; |
3405 | 977 | goto again; /* That's lame; I know. */ |
3406 | 977 | } |
3407 | 10.5k | else |
3408 | 10.5k | delete_kbnode (node); |
3409 | 11.5k | } |
3410 | 14.1k | } |
3411 | | |
3412 | 1.17k | xfree (taglist); |
3413 | | |
3414 | | /* Commit the as deleted marked nodes and return the possibly |
3415 | | * modified keyblock and a list of removed secret key nodes. */ |
3416 | 1.17k | commit_kbnode (&sec_keyblock); |
3417 | 1.17k | *r_keyblock = sec_keyblock; |
3418 | 1.17k | *r_removedsecs = attic; |
3419 | 1.17k | return 0; |
3420 | 2.14k | } |
3421 | | |
3422 | | |
3423 | | /* Helper for import_secret_one. */ |
3424 | | static gpg_error_t |
3425 | | do_transfer (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *pk, |
3426 | | struct import_stats_s *stats, int batch, int only_marked) |
3427 | | |
3428 | 75 | { |
3429 | 75 | gpg_error_t err; |
3430 | 75 | struct import_stats_s subkey_stats = {0}; |
3431 | 75 | int force = 0; |
3432 | 75 | int already_exist = agent_probe_secret_key (ctrl, pk); |
3433 | | |
3434 | 75 | if (already_exist == 2 || already_exist == 4) |
3435 | 0 | { |
3436 | 0 | if (!opt.quiet) |
3437 | 0 | log_info (_("key %s: card reference is overridden by key material\n"), |
3438 | 0 | keystr_from_pk (pk)); |
3439 | 0 | force = 1; |
3440 | 0 | } |
3441 | | |
3442 | 75 | err = transfer_secret_keys (ctrl, &subkey_stats, keyblock, |
3443 | 75 | batch, force, only_marked); |
3444 | 75 | if (gpg_err_code (err) == GPG_ERR_NOT_PROCESSED) |
3445 | 0 | { |
3446 | | /* TRANSLATORS: For a smartcard, each private key on host has a |
3447 | | * reference (stub) to a smartcard and actual private key data |
3448 | | * is stored on the card. A single smartcard can have up to |
3449 | | * three private key data. Importing private key stub is always |
3450 | | * skipped in 2.1, and it returns GPG_ERR_NOT_PROCESSED. |
3451 | | * Instead, user should be suggested to run 'gpg --card-status', |
3452 | | * then, references to a card will be automatically created |
3453 | | * again. */ |
3454 | 0 | log_info (_("To migrate '%s', with each smartcard, " |
3455 | 0 | "run: %s\n"), "secring.gpg", "gpg --card-status"); |
3456 | 0 | err = 0; |
3457 | 0 | } |
3458 | | |
3459 | 75 | if (!err) |
3460 | 0 | { |
3461 | 0 | int status = 16; |
3462 | |
|
3463 | 0 | if (!opt.quiet) |
3464 | 0 | log_info (_("key %s: secret key imported\n"), keystr_from_pk (pk)); |
3465 | 0 | if (subkey_stats.secret_imported) |
3466 | 0 | { |
3467 | 0 | status |= 1; |
3468 | 0 | stats->secret_imported += 1; |
3469 | 0 | } |
3470 | 0 | if (subkey_stats.secret_dups) |
3471 | 0 | stats->secret_dups += 1; |
3472 | |
|
3473 | 0 | if (is_status_enabled ()) |
3474 | 0 | print_import_ok (pk, status); |
3475 | 0 | } |
3476 | | |
3477 | 75 | return err; |
3478 | 75 | } |
3479 | | |
3480 | | |
3481 | | /* If the secret keys (main or subkey) in SECKEYS have a corresponding |
3482 | | * public key in the public key described by (FPR,FPRLEN) import these |
3483 | | * parts. |
3484 | | */ |
3485 | | static gpg_error_t |
3486 | | import_matching_seckeys (ctrl_t ctrl, kbnode_t seckeys, |
3487 | | const byte *mainfpr, size_t mainfprlen, |
3488 | | struct import_stats_s *stats, int batch) |
3489 | 1.14k | { |
3490 | 1.14k | gpg_error_t err; |
3491 | 1.14k | kbnode_t pub_keyblock = NULL; |
3492 | 1.14k | kbnode_t node; |
3493 | 1.14k | struct { byte fpr[MAX_FINGERPRINT_LEN]; size_t fprlen; } *fprlist = NULL; |
3494 | 1.14k | size_t n, nfprlist; |
3495 | 1.14k | byte fpr[MAX_FINGERPRINT_LEN]; |
3496 | 1.14k | size_t fprlen; |
3497 | 1.14k | PKT_public_key *pk; |
3498 | | |
3499 | | /* Get the entire public key block from our keystore and put all its |
3500 | | * fingerprints into an array. */ |
3501 | 1.14k | err = get_pubkey_byfpr (ctrl, NULL, &pub_keyblock, mainfpr, mainfprlen); |
3502 | 1.14k | if (err) |
3503 | 1.12k | goto leave; |
3504 | 1.14k | log_assert (pub_keyblock && pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY); |
3505 | 20 | pk = pub_keyblock->pkt->pkt.public_key; |
3506 | | |
3507 | 2.74k | for (nfprlist = 0, node = pub_keyblock; node; node = node->next) |
3508 | 2.72k | if (node->pkt->pkttype == PKT_PUBLIC_KEY |
3509 | 2.70k | || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) |
3510 | 220 | nfprlist++; |
3511 | 20 | log_assert (nfprlist); |
3512 | 20 | fprlist = xtrycalloc (nfprlist, sizeof *fprlist); |
3513 | 20 | if (!fprlist) |
3514 | 0 | { |
3515 | 0 | err = gpg_error_from_syserror (); |
3516 | 0 | goto leave; |
3517 | 0 | } |
3518 | 2.74k | for (n = 0, node = pub_keyblock; node; node = node->next) |
3519 | 2.72k | if (node->pkt->pkttype == PKT_PUBLIC_KEY |
3520 | 2.70k | || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) |
3521 | 220 | { |
3522 | 220 | fingerprint_from_pk (node->pkt->pkt.public_key, |
3523 | 220 | fprlist[n].fpr, &fprlist[n].fprlen); |
3524 | 220 | n++; |
3525 | 220 | } |
3526 | 20 | log_assert (n == nfprlist); |
3527 | | |
3528 | | /* for (n=0; n < nfprlist; n++) */ |
3529 | | /* log_printhex (fprlist[n].fpr, fprlist[n].fprlen, "pubkey %zu:", n); */ |
3530 | | |
3531 | | /* Mark all secret keys which have a matching public key part in |
3532 | | * PUB_KEYBLOCK. */ |
3533 | 122 | for (node = seckeys; node; node = node->next) |
3534 | 102 | { |
3535 | 102 | if (node->pkt->pkttype != PKT_SECRET_KEY |
3536 | 82 | && node->pkt->pkttype != PKT_SECRET_SUBKEY) |
3537 | 0 | continue; /* Should not happen. */ |
3538 | 102 | fingerprint_from_pk (node->pkt->pkt.public_key, fpr, &fprlen); |
3539 | 102 | node->flag &= ~NODE_TRANSFER_SECKEY; |
3540 | 432 | for (n=0; n < nfprlist; n++) |
3541 | 389 | if (fprlist[n].fprlen == fprlen && !memcmp (fprlist[n].fpr,fpr,fprlen)) |
3542 | 59 | { |
3543 | 59 | node->flag |= NODE_TRANSFER_SECKEY; |
3544 | | /* log_debug ("found matching seckey\n"); */ |
3545 | 59 | break; |
3546 | 59 | } |
3547 | 102 | } |
3548 | | |
3549 | | /* Transfer all marked keys. */ |
3550 | 20 | err = do_transfer (ctrl, seckeys, pk, stats, batch, 1); |
3551 | | |
3552 | 1.14k | leave: |
3553 | 1.14k | xfree (fprlist); |
3554 | 1.14k | release_kbnode (pub_keyblock); |
3555 | 1.14k | return err; |
3556 | 20 | } |
3557 | | |
3558 | | |
3559 | | /* Import function for a single secret keyblock. Handling is simpler |
3560 | | * than for public keys. We allow secret key importing only when |
3561 | | * allow is true, this is so that a secret key can not be imported |
3562 | | * accidentally and thereby tampering with the trust calculation. |
3563 | | * |
3564 | | * Ownership of KEYBLOCK is transferred to this function! |
3565 | | * |
3566 | | * If R_SECATTIC is not null the last special sec_keyblock is stored |
3567 | | * there. |
3568 | | */ |
3569 | | static gpg_error_t |
3570 | | import_secret_one (ctrl_t ctrl, kbnode_t keyblock, |
3571 | | struct import_stats_s *stats, int batch, |
3572 | | unsigned int options, int for_migration, |
3573 | | import_screener_t screener, void *screener_arg, |
3574 | | kbnode_t *r_secattic) |
3575 | 3.30k | { |
3576 | 3.30k | PKT_public_key *pk; |
3577 | 3.30k | struct seckey_info *ski; |
3578 | 3.30k | kbnode_t node, uidnode; |
3579 | 3.30k | u32 keyid[2]; |
3580 | 3.30k | gpg_error_t err = 0; |
3581 | 3.30k | int nr_prev; |
3582 | 3.30k | kbnode_t pub_keyblock; |
3583 | 3.30k | kbnode_t attic = NULL; |
3584 | 3.30k | byte fpr[MAX_FINGERPRINT_LEN]; |
3585 | 3.30k | size_t fprlen; |
3586 | 3.30k | char pkstrbuf[PUBKEY_STRING_SIZE]; |
3587 | | |
3588 | | /* Get the key and print some info about it */ |
3589 | 3.30k | node = find_kbnode (keyblock, PKT_SECRET_KEY); |
3590 | 3.30k | if (!node) |
3591 | 0 | BUG (); |
3592 | | |
3593 | 3.30k | pk = node->pkt->pkt.public_key; |
3594 | | |
3595 | 3.30k | fingerprint_from_pk (pk, fpr, &fprlen); |
3596 | 3.30k | keyid_from_pk (pk, keyid); |
3597 | 3.30k | uidnode = find_next_kbnode (keyblock, PKT_USER_ID); |
3598 | | |
3599 | 3.30k | if (screener && screener (keyblock, screener_arg)) |
3600 | 0 | { |
3601 | 0 | log_error (_("secret key %s: %s\n"), keystr_from_pk (pk), |
3602 | 0 | _("rejected by import screener")); |
3603 | 0 | release_kbnode (keyblock); |
3604 | 0 | return 0; |
3605 | 0 | } |
3606 | | |
3607 | 3.30k | if (opt.verbose && !for_migration) |
3608 | 0 | { |
3609 | 0 | log_info ("sec %s/%s %s ", |
3610 | 0 | pubkey_string (pk, pkstrbuf, sizeof pkstrbuf), |
3611 | 0 | keystr_from_pk (pk), datestr_from_pk (pk)); |
3612 | 0 | if (uidnode) |
3613 | 0 | print_utf8_buffer (log_get_stream (), uidnode->pkt->pkt.user_id->name, |
3614 | 0 | uidnode->pkt->pkt.user_id->len); |
3615 | 0 | log_printf ("\n"); |
3616 | 0 | } |
3617 | 3.30k | stats->secret_read++; |
3618 | | |
3619 | 3.30k | if ((options & IMPORT_ONLY_PUBKEYS)) |
3620 | 0 | { |
3621 | 0 | if (!for_migration) |
3622 | 0 | log_error (_("importing secret keys not allowed\n")); |
3623 | 0 | release_kbnode (keyblock); |
3624 | 0 | return 0; |
3625 | 0 | } |
3626 | | |
3627 | 3.30k | if (!uidnode) |
3628 | 2.00k | { |
3629 | 2.00k | if (!for_migration) |
3630 | 2.00k | log_error( _("key %s: no user ID\n"), keystr_from_pk (pk)); |
3631 | 2.00k | if (!(options & IMPORT_DEBUG_ACCEPT_NO_UID)) |
3632 | 2.00k | { |
3633 | 2.00k | release_kbnode (keyblock); |
3634 | 2.00k | return 0; |
3635 | 2.00k | } |
3636 | 2.00k | } |
3637 | | |
3638 | 1.30k | ski = pk->seckey_info; |
3639 | 1.30k | if (!ski) |
3640 | 28 | { |
3641 | | /* Actually an internal error. */ |
3642 | 28 | log_error ("key %s: secret key info missing\n", keystr_from_pk (pk)); |
3643 | 28 | release_kbnode (keyblock); |
3644 | 28 | return 0; |
3645 | 28 | } |
3646 | | |
3647 | | /* A quick check to not import keys with an invalid protection |
3648 | | cipher algorithm (only checks the primary key, though). */ |
3649 | 1.27k | if (ski->algo > 110) |
3650 | 103 | { |
3651 | 103 | if (!for_migration) |
3652 | 103 | log_error (_("key %s: secret key with invalid cipher %d" |
3653 | 103 | " - skipped\n"), keystr_from_pk (pk), ski->algo); |
3654 | 103 | release_kbnode (keyblock); |
3655 | 103 | return 0; |
3656 | 103 | } |
3657 | | |
3658 | | #ifdef ENABLE_SELINUX_HACKS |
3659 | | if (1) |
3660 | | { |
3661 | | /* We don't allow importing secret keys because that may be used |
3662 | | to put a secret key into the keyring and the user might later |
3663 | | be tricked into signing stuff with that key. */ |
3664 | | log_error (_("importing secret keys not allowed\n")); |
3665 | | release_kbnode (keyblock); |
3666 | | return 0; |
3667 | | } |
3668 | | #endif |
3669 | | |
3670 | 1.17k | clear_kbnode_flags (keyblock); |
3671 | | |
3672 | 1.17k | nr_prev = stats->skipped_new_keys; |
3673 | | |
3674 | | /* Make a public key out of the key. */ |
3675 | 1.17k | pub_keyblock = sec_to_pub_keyblock (keyblock); |
3676 | 1.17k | if (!pub_keyblock) |
3677 | 0 | { |
3678 | 0 | err = gpg_error_from_syserror (); |
3679 | 0 | log_error ("key %s: failed to create public key from secret key\n", |
3680 | 0 | keystr_from_pk (pk)); |
3681 | 0 | } |
3682 | 1.17k | else |
3683 | 1.17k | { |
3684 | 1.17k | int valid; |
3685 | | |
3686 | | /* Note that this outputs an IMPORT_OK status message for the |
3687 | | public key block, and below we will output another one for |
3688 | | the secret keys. FIXME? */ |
3689 | 1.17k | import_one (ctrl, pub_keyblock, stats, |
3690 | 1.17k | NULL, NULL, options, 1, for_migration, |
3691 | 1.17k | screener, screener_arg, 0, NULL, &valid); |
3692 | | |
3693 | | /* The secret keyblock may not have nodes which are deleted in |
3694 | | * the public keyblock. Otherwise we would import just the |
3695 | | * secret key without having the public key. That would be |
3696 | | * surprising and clutters our private-keys-v1.d. */ |
3697 | 1.17k | err = resync_sec_with_pub_keyblock (&keyblock, pub_keyblock, &attic); |
3698 | 1.17k | if (err) |
3699 | 0 | goto leave; |
3700 | | |
3701 | 1.17k | if (!valid) |
3702 | 1.11k | { |
3703 | | /* If the block was not valid the primary key is left in the |
3704 | | * original keyblock because we require that for the first |
3705 | | * node. Move it to ATTIC. */ |
3706 | 1.11k | if (keyblock && keyblock->pkt->pkttype == PKT_SECRET_KEY) |
3707 | 1.11k | { |
3708 | 1.11k | node = keyblock; |
3709 | 1.11k | keyblock = node->next; |
3710 | 1.11k | node->next = NULL; |
3711 | 1.11k | if (attic) |
3712 | 362 | { |
3713 | 362 | node->next = attic; |
3714 | 362 | attic = node; |
3715 | 362 | } |
3716 | 753 | else |
3717 | 753 | attic = node; |
3718 | 1.11k | } |
3719 | | |
3720 | | /* Try to import the secret key iff we have a public key. */ |
3721 | 1.11k | if (attic && !(opt.dry_run || (options & IMPORT_DRY_RUN))) |
3722 | 1.11k | err = import_matching_seckeys (ctrl, attic, fpr, fprlen, |
3723 | 1.11k | stats, batch); |
3724 | 0 | else |
3725 | 0 | err = gpg_error (GPG_ERR_NO_SECKEY); |
3726 | 1.11k | goto leave; |
3727 | 1.11k | } |
3728 | | |
3729 | | /* log_debug ("attic is:\n"); */ |
3730 | | /* dump_kbnode (attic); */ |
3731 | | |
3732 | | /* Proceed with the valid parts of PUBKEYBLOCK. */ |
3733 | | |
3734 | | /* At least we cancel the secret key import when the public key |
3735 | | import was skipped due to MERGE_ONLY option and a new |
3736 | | key. */ |
3737 | 55 | if (!(opt.dry_run || (options & IMPORT_DRY_RUN)) |
3738 | 55 | && stats->skipped_new_keys <= nr_prev) |
3739 | 55 | { |
3740 | | /* Read the keyblock again to get the effects of a merge for |
3741 | | * the public key. */ |
3742 | 55 | err = get_pubkey_byfpr (ctrl, NULL, &node, fpr, fprlen); |
3743 | 55 | if (err || !node) |
3744 | 55 | log_error ("key %s: failed to re-lookup public key: %s\n", |
3745 | 0 | keystr_from_pk (pk), gpg_strerror (err)); |
3746 | 55 | else |
3747 | 55 | { |
3748 | 55 | err = do_transfer (ctrl, keyblock, pk, stats, batch, 0); |
3749 | 55 | if (!err) |
3750 | 0 | check_prefs (ctrl, node); |
3751 | 55 | release_kbnode (node); |
3752 | | |
3753 | 55 | if (!err && attic) |
3754 | 0 | { |
3755 | | /* Try to import invalid subkeys. This can be the |
3756 | | * case if the primary secret key was imported due |
3757 | | * to --allow-non-selfsigned-uid. */ |
3758 | 0 | err = import_matching_seckeys (ctrl, attic, fpr, fprlen, |
3759 | 0 | stats, batch); |
3760 | 0 | } |
3761 | | |
3762 | 55 | } |
3763 | 55 | } |
3764 | 55 | } |
3765 | | |
3766 | 1.17k | leave: |
3767 | 1.17k | release_kbnode (keyblock); |
3768 | 1.17k | release_kbnode (pub_keyblock); |
3769 | 1.17k | if (r_secattic) |
3770 | 1.17k | *r_secattic = attic; |
3771 | 0 | else |
3772 | 0 | release_kbnode (attic); |
3773 | 1.17k | return err; |
3774 | 1.17k | } |
3775 | | |
3776 | | |
3777 | | /* Return a string for the revocation reason CODE. R_FREEM must be an |
3778 | | * possibly unintialized ptr which should be freed by the caller after |
3779 | | * the return value has been consumed. */ |
3780 | | const char * |
3781 | | revocation_reason_code_to_str (int code, char **freeme) |
3782 | 0 | { |
3783 | | /* Take care: get_revocation_reason has knowledge of the internal |
3784 | | * working of this fucntion. */ |
3785 | 0 | const char *result; |
3786 | |
|
3787 | 0 | *freeme = NULL; |
3788 | 0 | switch (code) |
3789 | 0 | { |
3790 | 0 | case 0x00: result = _("No reason specified"); break; |
3791 | 0 | case 0x01: result = _("Key is superseded"); break; |
3792 | 0 | case 0x02: result = _("Key has been compromised"); break; |
3793 | 0 | case 0x03: result = _("Key is no longer used"); break; |
3794 | 0 | case 0x20: result = _("User ID is no longer valid"); break; |
3795 | 0 | default: |
3796 | 0 | *freeme = xasprintf ("code=%02x", code); |
3797 | 0 | result = *freeme; |
3798 | 0 | break; |
3799 | 0 | } |
3800 | | |
3801 | 0 | return result; |
3802 | 0 | } |
3803 | | |
3804 | | |
3805 | | /* Return the recocation reason from signature SIG. If no revocation |
3806 | | * reason is available 0 is returned, in other cases the reason |
3807 | | * (0..255). If R_REASON is not NULL a malloced textual |
3808 | | * representation of the code is stored there. If R_COMMENT is not |
3809 | | * NULL the comment from the reason is stored there and its length at |
3810 | | * R_COMMENTLEN. Note that the value at R_COMMENT is not filtered but |
3811 | | * user supplied data in UTF8; thus it needs to be escaped for display |
3812 | | * purposes. Both return values are either NULL or a malloced |
3813 | | * string/buffer. */ |
3814 | | int |
3815 | | get_revocation_reason (PKT_signature *sig, char **r_reason, |
3816 | | char **r_comment, size_t *r_commentlen) |
3817 | 0 | { |
3818 | 0 | int reason_seq = 0; |
3819 | 0 | size_t reason_n; |
3820 | 0 | const byte *reason_p; |
3821 | 0 | int reason_code = 0; |
3822 | 0 | const char *reason_string; |
3823 | 0 | char *freeme; |
3824 | |
|
3825 | 0 | if (r_reason) |
3826 | 0 | *r_reason = NULL; |
3827 | 0 | if (r_comment) |
3828 | 0 | *r_comment = NULL; |
3829 | | |
3830 | | /* Skip over empty reason packets. */ |
3831 | 0 | while ((reason_p = enum_sig_subpkt (sig, 1, SIGSUBPKT_REVOC_REASON, |
3832 | 0 | &reason_n, &reason_seq, NULL)) |
3833 | 0 | && !reason_n) |
3834 | 0 | ; |
3835 | 0 | if (reason_p && reason_n) |
3836 | 0 | { |
3837 | 0 | reason_code = *reason_p; |
3838 | 0 | reason_n--; reason_p++; |
3839 | 0 | reason_string = revocation_reason_code_to_str (reason_code, &freeme); |
3840 | 0 | if (r_reason && freeme) |
3841 | 0 | *r_reason = freeme; |
3842 | 0 | else if (r_reason && reason_string) |
3843 | 0 | *r_reason = xstrdup (reason_string); |
3844 | 0 | else |
3845 | 0 | xfree (freeme); |
3846 | |
|
3847 | 0 | if (r_comment && reason_n) |
3848 | 0 | { |
3849 | 0 | *r_comment = xmalloc (reason_n); |
3850 | 0 | memcpy (*r_comment, reason_p, reason_n); |
3851 | 0 | *r_commentlen = reason_n; |
3852 | 0 | } |
3853 | 0 | } |
3854 | |
|
3855 | 0 | return reason_code; |
3856 | 0 | } |
3857 | | |
3858 | | |
3859 | | /* List the recocation signature as a "rvs" record. SIGRC shows the |
3860 | | * character from the signature verification or 0 if no public key was |
3861 | | * found. */ |
3862 | | static void |
3863 | | list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) |
3864 | 0 | { |
3865 | 0 | char *siguid = NULL; |
3866 | 0 | size_t siguidlen = 0; |
3867 | 0 | char *issuer_fpr = NULL; |
3868 | 0 | int reason_code = 0; |
3869 | 0 | char *reason_text = NULL; |
3870 | 0 | char *reason_comment = NULL; |
3871 | 0 | size_t reason_commentlen; |
3872 | |
|
3873 | 0 | if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode) |
3874 | 0 | { |
3875 | 0 | int nouid; |
3876 | 0 | siguid = get_user_id (ctrl, sig->keyid, &siguidlen, &nouid); |
3877 | 0 | if (nouid) |
3878 | 0 | sigrc = '?'; |
3879 | 0 | } |
3880 | |
|
3881 | 0 | reason_code = get_revocation_reason (sig, &reason_text, |
3882 | 0 | &reason_comment, &reason_commentlen); |
3883 | |
|
3884 | 0 | if (opt.with_colons) |
3885 | 0 | { |
3886 | 0 | es_fputs ("rvs:", es_stdout); |
3887 | 0 | if (sigrc) |
3888 | 0 | es_putc (sigrc, es_stdout); |
3889 | 0 | es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:::", |
3890 | 0 | sig->pubkey_algo, |
3891 | 0 | (ulong) sig->keyid[0], (ulong) sig->keyid[1], |
3892 | 0 | colon_datestr_from_sig (sig), |
3893 | 0 | colon_expirestr_from_sig (sig)); |
3894 | |
|
3895 | 0 | if (siguid) |
3896 | 0 | es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL); |
3897 | |
|
3898 | 0 | es_fprintf (es_stdout, ":%02x%c", sig->sig_class, |
3899 | 0 | sig->flags.exportable ? 'x' : 'l'); |
3900 | 0 | if (reason_text) |
3901 | 0 | es_fprintf (es_stdout, ",%02x", reason_code); |
3902 | 0 | es_fputs ("::", es_stdout); |
3903 | |
|
3904 | 0 | if ((issuer_fpr = issuer_fpr_string (sig))) |
3905 | 0 | es_fputs (issuer_fpr, es_stdout); |
3906 | |
|
3907 | 0 | es_fprintf (es_stdout, ":::%d:", sig->digest_algo); |
3908 | |
|
3909 | 0 | if (reason_comment) |
3910 | 0 | { |
3911 | 0 | es_fputs ("::::", es_stdout); |
3912 | 0 | es_write_sanitized (es_stdout, reason_comment, reason_commentlen, |
3913 | 0 | ":", NULL); |
3914 | 0 | es_putc (':', es_stdout); |
3915 | 0 | } |
3916 | 0 | es_putc ('\n', es_stdout); |
3917 | |
|
3918 | 0 | if (opt.show_subpackets) |
3919 | 0 | print_subpackets_colon (sig); |
3920 | 0 | } |
3921 | 0 | else /* Human readable. */ |
3922 | 0 | { |
3923 | 0 | es_fputs ("rvs", es_stdout); |
3924 | 0 | es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s", |
3925 | 0 | sigrc, (sig->sig_class - 0x10 > 0 && |
3926 | 0 | sig->sig_class - 0x10 < |
3927 | 0 | 4) ? '0' + sig->sig_class - 0x10 : ' ', |
3928 | 0 | sig->flags.exportable ? ' ' : 'L', |
3929 | 0 | sig->flags.revocable ? ' ' : 'R', |
3930 | 0 | sig->flags.policy_url ? 'P' : ' ', |
3931 | 0 | sig->flags.notation ? 'N' : ' ', |
3932 | 0 | sig->flags.expired ? 'X' : ' ', |
3933 | 0 | (sig->trust_depth > 9) ? 'T' : (sig->trust_depth > |
3934 | 0 | 0) ? '0' + |
3935 | 0 | sig->trust_depth : ' ', keystr (sig->keyid), |
3936 | 0 | datestr_from_sig (sig)); |
3937 | 0 | if (siguid) |
3938 | 0 | { |
3939 | 0 | es_fprintf (es_stdout, " "); |
3940 | 0 | print_utf8_buffer (es_stdout, siguid, siguidlen); |
3941 | 0 | } |
3942 | 0 | es_putc ('\n', es_stdout); |
3943 | |
|
3944 | 0 | if (sig->flags.policy_url |
3945 | 0 | && (opt.list_options & LIST_SHOW_POLICY_URLS)) |
3946 | 0 | show_policy_url (sig, 3, 0); |
3947 | |
|
3948 | 0 | if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS)) |
3949 | 0 | show_notation (sig, 3, 0, |
3950 | 0 | ((opt.list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) |
3951 | 0 | + |
3952 | 0 | ((opt.list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0) |
3953 | 0 | + |
3954 | 0 | ((opt.list_options & LIST_SHOW_HIDDEN_NOTATIONS) ? 4:0)); |
3955 | |
|
3956 | 0 | if (sig->flags.pref_ks |
3957 | 0 | && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) |
3958 | 0 | show_keyserver_url (sig, 3, 0); |
3959 | |
|
3960 | 0 | if (reason_text) |
3961 | 0 | { |
3962 | 0 | es_fprintf (es_stdout, " %s%s\n", |
3963 | 0 | _("reason for revocation: "), reason_text); |
3964 | 0 | print_revocation_reason_comment (reason_comment, reason_commentlen); |
3965 | 0 | } |
3966 | 0 | } |
3967 | |
|
3968 | 0 | es_fflush (es_stdout); |
3969 | |
|
3970 | 0 | xfree (reason_text); |
3971 | 0 | xfree (reason_comment); |
3972 | 0 | xfree (siguid); |
3973 | 0 | xfree (issuer_fpr); |
3974 | 0 | } |
3975 | | |
3976 | | |
3977 | | /* Import a revocation certificate; only the first packet in the |
3978 | | * NODE-list is considered. */ |
3979 | | static int |
3980 | | import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, |
3981 | | struct import_stats_s *stats) |
3982 | 3.33k | { |
3983 | 3.33k | PKT_public_key *pk = NULL; |
3984 | 3.33k | PKT_public_key *pk_buffer = NULL; |
3985 | 3.33k | PKT_signature *sig = NULL; |
3986 | 3.33k | kbnode_t onode = NULL; |
3987 | 3.33k | kbnode_t keyblock = NULL; |
3988 | 3.33k | KEYDB_HANDLE hd = NULL; |
3989 | 3.33k | u32 keyid[2]; |
3990 | 3.33k | int rc = 0; |
3991 | 3.33k | int sigrc = 0; |
3992 | 3.33k | int silent; |
3993 | | |
3994 | | /* No error output for --show-keys. */ |
3995 | 3.33k | silent = (options & (IMPORT_SHOW | IMPORT_DRY_RUN)); |
3996 | | |
3997 | 3.33k | log_assert (node->pkt->pkttype == PKT_SIGNATURE ); |
3998 | 3.33k | log_assert (IS_KEY_REV (node->pkt->pkt.signature)); |
3999 | | |
4000 | | /* FIXME: We can do better here by using the issuer fingerprint if |
4001 | | * available. We should also make use of get_keyblock_byfprint_fast. */ |
4002 | 3.33k | sig = node->pkt->pkt.signature; |
4003 | | |
4004 | | /* If the revocation signature has an intended recipient fingerprint subpacket |
4005 | | * use the provided fingerprint (stored in REV_SUBJECT_INFO). */ |
4006 | 3.33k | if (sig->rev_subject_info) |
4007 | 0 | { |
4008 | 0 | hd = keydb_new (ctrl); |
4009 | 0 | if (!hd) |
4010 | 0 | { |
4011 | 0 | rc = gpg_error_from_syserror (); |
4012 | 0 | goto leave; |
4013 | 0 | } |
4014 | | |
4015 | 0 | rc = keydb_lock (hd); |
4016 | 0 | if (rc) |
4017 | 0 | goto leave; |
4018 | | |
4019 | 0 | rc = keydb_search_fpr (hd, |
4020 | 0 | sig->rev_subject_info->fpr, |
4021 | 0 | sig->rev_subject_info->fprlen); |
4022 | |
|
4023 | 0 | keyid_from_fingerprint (ctrl, |
4024 | 0 | sig->rev_subject_info->fpr, |
4025 | 0 | sig->rev_subject_info->fprlen, keyid); |
4026 | | |
4027 | | /* The keyblock might not be found if the revocation subject |
4028 | | * is not in the local keyring. This should not be an error. */ |
4029 | 0 | if (rc) |
4030 | 0 | { |
4031 | 0 | if (!silent) |
4032 | 0 | log_error (_("key %s: can't locate keyblock: %s\n"), |
4033 | 0 | keystr (keyid), gpg_strerror (rc)); |
4034 | 0 | rc = 0; |
4035 | 0 | goto leave; |
4036 | 0 | } |
4037 | | |
4038 | 0 | rc = keydb_get_keyblock (hd, &keyblock); |
4039 | 0 | if (rc) |
4040 | 0 | { |
4041 | 0 | log_error (_("key %s: can't read keyblock: %s\n"), |
4042 | 0 | keystr (keyid), gpg_strerror (rc)); |
4043 | 0 | goto leave; |
4044 | 0 | } |
4045 | | |
4046 | 0 | pk = keyblock->pkt->pkt.public_key; |
4047 | 0 | } |
4048 | 3.33k | else |
4049 | 3.33k | { |
4050 | 3.33k | log_info ("we may have an old standalone revocation signature\n"); |
4051 | | |
4052 | | /* Path without intended recipient fingerprint subpacket. */ |
4053 | 3.33k | keyid[0] = node->pkt->pkt.signature->keyid[0]; |
4054 | 3.33k | keyid[1] = node->pkt->pkt.signature->keyid[1]; |
4055 | | |
4056 | 3.33k | pk_buffer = xmalloc_clear( sizeof *pk_buffer ); |
4057 | 3.33k | pk = pk_buffer; |
4058 | | |
4059 | 3.33k | rc = get_pubkey (ctrl, pk, keyid); |
4060 | 3.33k | if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY) |
4061 | 954 | { |
4062 | 954 | if (!silent) |
4063 | 954 | log_error (_("key %s: no public key -" |
4064 | 954 | " can't apply revocation certificate\n"), keystr(keyid)); |
4065 | 954 | rc = 0; |
4066 | 954 | goto leave; |
4067 | 954 | } |
4068 | 2.37k | else if (rc ) |
4069 | 0 | { |
4070 | 0 | log_error (_("key %s: public key not found: %s\n"), |
4071 | 0 | keystr(keyid), gpg_strerror (rc)); |
4072 | 0 | goto leave; |
4073 | 0 | } |
4074 | | |
4075 | | /* Read the original keyblock. */ |
4076 | 2.37k | hd = keydb_new (ctrl); |
4077 | 2.37k | if (!hd) |
4078 | 0 | { |
4079 | 0 | rc = gpg_error_from_syserror (); |
4080 | 0 | goto leave; |
4081 | 0 | } |
4082 | | |
4083 | 2.37k | rc = keydb_lock (hd); |
4084 | 2.37k | if (rc) |
4085 | 0 | goto leave; |
4086 | | |
4087 | 2.37k | { |
4088 | 2.37k | byte afp[MAX_FINGERPRINT_LEN]; |
4089 | 2.37k | size_t an; |
4090 | | |
4091 | 2.37k | fingerprint_from_pk (pk, afp, &an); |
4092 | 2.37k | rc = keydb_search_fpr (hd, afp, an); |
4093 | 2.37k | } |
4094 | 2.37k | if (rc) |
4095 | 0 | { |
4096 | 0 | log_error (_("key %s: can't locate original keyblock: %s\n"), |
4097 | 0 | keystr(keyid), gpg_strerror (rc)); |
4098 | 0 | goto leave; |
4099 | 0 | } |
4100 | 2.37k | rc = keydb_get_keyblock (hd, &keyblock ); |
4101 | 2.37k | if (rc) |
4102 | 0 | { |
4103 | 0 | log_error (_("key %s: can't read original keyblock: %s\n"), |
4104 | 0 | keystr(keyid), gpg_strerror (rc)); |
4105 | 0 | goto leave; |
4106 | 0 | } |
4107 | 2.37k | } |
4108 | | |
4109 | | /* it is okay, that node is not in keyblock because |
4110 | | * check_key_signature works fine for sig_class 0x20 (KEY_REV) in |
4111 | | * this special case. SIGRC is only used for IMPORT_SHOW. */ |
4112 | 2.37k | rc = check_key_signature (ctrl, keyblock, node, NULL); |
4113 | 2.37k | switch (gpg_err_code (rc)) |
4114 | 2.37k | { |
4115 | 181 | case 0: sigrc = '!'; break; |
4116 | 46 | case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break; |
4117 | 0 | case GPG_ERR_NO_PUBKEY: sigrc = '?'; break; |
4118 | 0 | case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break; |
4119 | 2.15k | default: sigrc = '%'; break; |
4120 | 2.37k | } |
4121 | 2.37k | if (gpg_err_code (rc) == GPG_ERR_CERT_REVOKED) |
4122 | 0 | { |
4123 | 0 | log_info ("key %s: already revoked: %s", keystr (keyid), gpg_strerror(rc)); |
4124 | 0 | rc = 0; |
4125 | 0 | goto leave; |
4126 | 0 | } |
4127 | 2.37k | else if (rc) |
4128 | 2.19k | { |
4129 | 2.19k | if (!silent) |
4130 | 2.19k | log_error (_("key %s: invalid revocation certificate" |
4131 | 2.19k | ": %s - rejected\n"), keystr(keyid), gpg_strerror (rc)); |
4132 | 2.19k | goto leave; |
4133 | 2.19k | } |
4134 | | |
4135 | | /* check whether we already have this */ |
4136 | 191 | for(onode=keyblock->next; onode; onode=onode->next ) { |
4137 | 191 | if (onode->pkt->pkttype == PKT_USER_ID ) |
4138 | 6 | break; |
4139 | 185 | else if (onode->pkt->pkttype == PKT_SIGNATURE |
4140 | 185 | && !cmp_signatures(node->pkt->pkt.signature, |
4141 | 185 | onode->pkt->pkt.signature)) |
4142 | 175 | { |
4143 | 175 | rc = 0; |
4144 | 175 | goto leave; /* yes, we already know about it */ |
4145 | 175 | } |
4146 | 191 | } |
4147 | | |
4148 | | /* insert it */ |
4149 | 6 | insert_kbnode( keyblock, clone_kbnode(node), 0 ); |
4150 | | |
4151 | | /* and write the keyblock back unless in dry run mode. */ |
4152 | 6 | if (!(opt.dry_run || (options & IMPORT_DRY_RUN))) |
4153 | 6 | { |
4154 | 6 | rc = keydb_update_keyblock (ctrl, hd, keyblock ); |
4155 | 6 | if (rc) |
4156 | 6 | log_error (_("error writing keyring '%s': %s\n"), |
4157 | 0 | keydb_get_resource_name (hd), gpg_strerror (rc) ); |
4158 | 6 | keydb_release (hd); |
4159 | 6 | hd = NULL; |
4160 | | |
4161 | | /* we are ready */ |
4162 | 6 | if (!opt.quiet ) |
4163 | 6 | { |
4164 | 6 | char *p=get_user_id_native (ctrl, keyid); |
4165 | 6 | log_info( _("key %s: \"%s\" revocation certificate imported\n"), |
4166 | 6 | keystr(keyid),p); |
4167 | 6 | xfree(p); |
4168 | 6 | } |
4169 | | |
4170 | | /* If the key we just revoked was ultimately trusted, remove its |
4171 | | * ultimate trust. This doesn't stop the user from putting the |
4172 | | * ultimate trust back, but is a reasonable solution for now. */ |
4173 | 6 | if (get_ownertrust (ctrl, pk) == TRUST_ULTIMATE) |
4174 | 0 | clear_ownertrusts (ctrl, pk); |
4175 | | |
4176 | 6 | revalidation_mark (ctrl); |
4177 | 6 | } |
4178 | 6 | stats->n_revoc++; |
4179 | | |
4180 | 3.33k | leave: |
4181 | 3.33k | if ((options & IMPORT_SHOW)) |
4182 | 0 | list_standalone_revocation (ctrl, node->pkt->pkt.signature, sigrc); |
4183 | | |
4184 | 3.33k | keydb_release (hd); |
4185 | 3.33k | release_kbnode( keyblock ); |
4186 | 3.33k | free_public_key( pk_buffer ); |
4187 | 3.33k | return rc; |
4188 | 6 | } |
4189 | | |
4190 | | |
4191 | | /* Loop over the KEYBLOCK and check all self signatures. KEYID is the |
4192 | | * keyid of the primary key for reporting purposes. On return the |
4193 | | * following bits in the node flags are set: |
4194 | | * |
4195 | | * - NODE_GOOD_SELFSIG :: User ID or subkey has a self-signature |
4196 | | * - NODE_BAD_SELFSIG :: Used ID or subkey has an invalid self-signature |
4197 | | * - NODE_DELETION_MARK :: This node shall be deleted |
4198 | | * |
4199 | | * NON_SELF is set to true if there are any sigs other than self-sigs |
4200 | | * in this keyblock. |
4201 | | * |
4202 | | * Returns 0 on success or -1 (but not an error code) if the keyblock |
4203 | | * is invalid. |
4204 | | */ |
4205 | | static int |
4206 | | chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) |
4207 | 10.3k | { |
4208 | 10.3k | kbnode_t knode = NULL; /* The node of the current subkey. */ |
4209 | 10.3k | PKT_public_key *subpk = NULL; /* and its packet. */ |
4210 | 10.3k | kbnode_t bsnode = NULL; /* Subkey binding signature node. */ |
4211 | 10.3k | u32 bsdate = 0; /* Timestamp of that node. */ |
4212 | 10.3k | kbnode_t rsnode = NULL; /* Subkey recocation signature node. */ |
4213 | 10.3k | u32 rsdate = 0; /* Timestamp of that node. */ |
4214 | 10.3k | PKT_signature *sig; |
4215 | 10.3k | int rc; |
4216 | 10.3k | kbnode_t n; |
4217 | | |
4218 | 64.9k | for (n=keyblock; (n = find_next_kbnode (n, 0)); ) |
4219 | 54.5k | { |
4220 | 54.5k | if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) |
4221 | 3.88k | { |
4222 | 3.88k | knode = n; |
4223 | 3.88k | subpk = knode->pkt->pkt.public_key; |
4224 | 3.88k | bsdate = 0; |
4225 | 3.88k | rsdate = 0; |
4226 | 3.88k | bsnode = NULL; |
4227 | 3.88k | rsnode = NULL; |
4228 | 3.88k | continue; |
4229 | 3.88k | } |
4230 | | |
4231 | 50.7k | if ( n->pkt->pkttype != PKT_SIGNATURE ) |
4232 | 29.1k | continue; |
4233 | | |
4234 | 21.5k | sig = n->pkt->pkt.signature; |
4235 | 21.5k | if ( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] ) |
4236 | 13.5k | { |
4237 | 13.5k | *non_self = 1; |
4238 | 13.5k | continue; |
4239 | 13.5k | } |
4240 | | |
4241 | | /* This just caches the sigs for later use. That way we |
4242 | | import a fully-cached key which speeds things up. */ |
4243 | 8.03k | if (!opt.no_sig_cache) |
4244 | 8.03k | check_key_signature (ctrl, keyblock, n, NULL); |
4245 | | |
4246 | 8.03k | if ( IS_UID_SIG(sig) || IS_UID_REV(sig) ) |
4247 | 4.94k | { |
4248 | 4.94k | kbnode_t unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); |
4249 | 4.94k | if ( !unode ) |
4250 | 31 | { |
4251 | 31 | log_error( _("key %s: no user ID for signature\n"), |
4252 | 31 | keystr(keyid)); |
4253 | 31 | return -1; /* The complete keyblock is invalid. */ |
4254 | 31 | } |
4255 | | |
4256 | | /* If it hasn't been marked valid yet, keep trying. */ |
4257 | 4.90k | if (!(unode->flag & NODE_GOOD_SELFSIG)) |
4258 | 4.87k | { |
4259 | 4.87k | rc = check_key_signature (ctrl, keyblock, n, NULL); |
4260 | 4.87k | if ( rc ) |
4261 | 1.71k | { |
4262 | 1.71k | if ( opt.verbose ) |
4263 | 0 | { |
4264 | 0 | char *p = utf8_to_native |
4265 | 0 | (unode->pkt->pkt.user_id->name, |
4266 | 0 | strlen (unode->pkt->pkt.user_id->name),0); |
4267 | 0 | log_info (gpg_err_code(rc) == GPG_ERR_PUBKEY_ALGO ? |
4268 | 0 | _("key %s: unsupported public key " |
4269 | 0 | "algorithm on user ID \"%s\"\n"): |
4270 | 0 | _("key %s: invalid self-signature " |
4271 | 0 | "on user ID \"%s\"\n"), |
4272 | 0 | keystr (keyid),p); |
4273 | 0 | xfree (p); |
4274 | 0 | } |
4275 | 1.71k | } |
4276 | 3.16k | else |
4277 | 3.16k | unode->flag |= NODE_GOOD_SELFSIG; |
4278 | 4.87k | } |
4279 | 4.90k | } |
4280 | 3.09k | else if (IS_KEY_SIG (sig)) |
4281 | 388 | { |
4282 | 388 | rc = check_key_signature (ctrl, keyblock, n, NULL); |
4283 | 388 | if ( rc ) |
4284 | 385 | { |
4285 | 385 | if (opt.verbose) |
4286 | 385 | log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? |
4287 | 0 | _("key %s: unsupported public key algorithm\n"): |
4288 | 0 | _("key %s: invalid direct key signature\n"), |
4289 | 0 | keystr (keyid)); |
4290 | 385 | n->flag |= NODE_DELETION_MARK; |
4291 | 385 | } |
4292 | 388 | } |
4293 | 2.70k | else if ( IS_SUBKEY_SIG (sig) ) |
4294 | 1.09k | { |
4295 | | /* Note that this works based solely on the timestamps like |
4296 | | the rest of gpg. If the standard gets revocation |
4297 | | targets, this may need to be revised. */ |
4298 | | |
4299 | 1.09k | if ( !knode ) |
4300 | 20 | { |
4301 | 20 | if (opt.verbose) |
4302 | 20 | log_info (_("key %s: no subkey for key binding\n"), |
4303 | 0 | keystr (keyid)); |
4304 | 20 | n->flag |= NODE_DELETION_MARK; |
4305 | 20 | } |
4306 | 1.07k | else |
4307 | 1.07k | { |
4308 | 1.07k | rc = check_key_signature (ctrl, keyblock, n, NULL); |
4309 | 1.07k | if ( rc ) |
4310 | 510 | { |
4311 | 510 | if (opt.verbose) |
4312 | 0 | { |
4313 | 0 | keyid_from_pk (subpk, NULL); |
4314 | 0 | log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? |
4315 | 0 | _("key %s: unsupported public key" |
4316 | 0 | " algorithm\n"): |
4317 | 0 | _("key %s: invalid subkey binding\n"), |
4318 | 0 | keystr_with_sub (keyid, subpk->keyid)); |
4319 | 0 | } |
4320 | 510 | n->flag |= NODE_DELETION_MARK; |
4321 | 510 | } |
4322 | 566 | else |
4323 | 566 | { |
4324 | | /* It's valid, so is it newer? */ |
4325 | 566 | if (sig->timestamp >= bsdate) |
4326 | 566 | { |
4327 | 566 | knode->flag |= NODE_GOOD_SELFSIG; /* Subkey is valid. */ |
4328 | 566 | if (bsnode) |
4329 | 0 | { |
4330 | | /* Delete the last binding sig since this |
4331 | | one is newer */ |
4332 | 0 | bsnode->flag |= NODE_DELETION_MARK; |
4333 | 0 | if (opt.verbose) |
4334 | 0 | { |
4335 | 0 | keyid_from_pk (subpk, NULL); |
4336 | 0 | log_info (_("key %s: removed multiple subkey" |
4337 | 0 | " binding\n"), |
4338 | 0 | keystr_with_sub (keyid, subpk->keyid)); |
4339 | 0 | } |
4340 | 0 | } |
4341 | | |
4342 | 566 | bsnode = n; |
4343 | 566 | bsdate = sig->timestamp; |
4344 | 566 | } |
4345 | 0 | else |
4346 | 0 | n->flag |= NODE_DELETION_MARK; /* older */ |
4347 | 566 | } |
4348 | 1.07k | } |
4349 | 1.09k | } |
4350 | 1.61k | else if ( IS_SUBKEY_REV (sig) ) |
4351 | 755 | { |
4352 | | /* We don't actually mark the subkey as revoked right now, |
4353 | | so just check that the revocation sig is the most recent |
4354 | | valid one. Note that we don't care if the binding sig is |
4355 | | newer than the revocation sig. See the comment in |
4356 | | getkey.c:merge_selfsigs_subkey for more. */ |
4357 | 755 | if ( !knode ) |
4358 | 70 | { |
4359 | 70 | if (opt.verbose) |
4360 | 70 | log_info (_("key %s: no subkey for key revocation\n"), |
4361 | 0 | keystr(keyid)); |
4362 | 70 | n->flag |= NODE_DELETION_MARK; |
4363 | 70 | } |
4364 | 685 | else |
4365 | 685 | { |
4366 | 685 | rc = check_key_signature (ctrl, keyblock, n, NULL); |
4367 | 685 | if ( rc ) |
4368 | 670 | { |
4369 | 670 | if(opt.verbose) |
4370 | 670 | log_info (gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ? |
4371 | 0 | _("key %s: unsupported public" |
4372 | 0 | " key algorithm\n"): |
4373 | 0 | _("key %s: invalid subkey revocation\n"), |
4374 | 0 | keystr(keyid)); |
4375 | 670 | n->flag |= NODE_DELETION_MARK; |
4376 | 670 | } |
4377 | 15 | else |
4378 | 15 | { |
4379 | | /* It's valid, so is it newer? */ |
4380 | 15 | if (sig->timestamp >= rsdate) |
4381 | 15 | { |
4382 | 15 | if (rsnode) |
4383 | 0 | { |
4384 | | /* Delete the last revocation sig since |
4385 | | this one is newer. */ |
4386 | 0 | rsnode->flag |= NODE_DELETION_MARK; |
4387 | 0 | if (opt.verbose) |
4388 | 0 | log_info (_("key %s: removed multiple subkey" |
4389 | 0 | " revocation\n"),keystr(keyid)); |
4390 | 0 | } |
4391 | | |
4392 | 15 | rsnode = n; |
4393 | 15 | rsdate = sig->timestamp; |
4394 | 15 | } |
4395 | 0 | else |
4396 | 0 | n->flag |= NODE_DELETION_MARK; /* older */ |
4397 | 15 | } |
4398 | 685 | } |
4399 | 755 | } |
4400 | 8.03k | } |
4401 | | |
4402 | 10.3k | return 0; |
4403 | 10.3k | } |
4404 | | |
4405 | | |
4406 | | /* Delete all parts which are invalid and those signatures whose |
4407 | | * public key algorithm is not available in this implementation; but |
4408 | | * consider RSA as valid, because parse/build_packets knows about it. |
4409 | | * If R_OTHERREVSIGS is not NULL, it is used to return a list of |
4410 | | * revocation certificates which have been deleted from KEYBLOCK but |
4411 | | * should be handled later. |
4412 | | * |
4413 | | * Returns: True if at least one valid user-id is left over. |
4414 | | */ |
4415 | | static int |
4416 | | delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, |
4417 | | unsigned int options, kbnode_t *r_otherrevsigs) |
4418 | 10.3k | { |
4419 | 10.3k | kbnode_t node; |
4420 | 10.3k | int nvalid=0, uid_seen=0, subkey_seen=0; |
4421 | 10.3k | PKT_public_key *pk; |
4422 | | |
4423 | 55.3k | for (node=keyblock->next; node; node = node->next ) |
4424 | 45.0k | { |
4425 | 45.0k | if (node->pkt->pkttype == PKT_USER_ID) |
4426 | 28.1k | { |
4427 | 28.1k | uid_seen = 1; |
4428 | 28.1k | if ((node->flag & NODE_BAD_SELFSIG) |
4429 | 28.1k | || !(node->flag & NODE_GOOD_SELFSIG)) |
4430 | 25.0k | { |
4431 | 25.0k | if (opt.verbose ) |
4432 | 0 | { |
4433 | 0 | char *p=utf8_to_native(node->pkt->pkt.user_id->name, |
4434 | 0 | node->pkt->pkt.user_id->len,0); |
4435 | 0 | log_info( _("key %s: skipped user ID \"%s\"\n"), |
4436 | 0 | keystr(keyid),p); |
4437 | 0 | xfree(p); |
4438 | 0 | } |
4439 | 25.0k | delete_kbnode( node ); /* the user-id */ |
4440 | | /* and all following packets up to the next user-id */ |
4441 | 32.7k | while (node->next |
4442 | 25.8k | && node->next->pkt->pkttype != PKT_USER_ID |
4443 | 9.71k | && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY |
4444 | 8.37k | && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ){ |
4445 | 7.71k | delete_kbnode( node->next ); |
4446 | 7.71k | node = node->next; |
4447 | 7.71k | } |
4448 | 25.0k | } |
4449 | 3.16k | else |
4450 | 3.16k | nvalid++; |
4451 | 28.1k | } |
4452 | 16.8k | else if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
4453 | 12.9k | || node->pkt->pkttype == PKT_SECRET_SUBKEY ) |
4454 | 4.81k | { |
4455 | 4.81k | if ((node->flag & NODE_BAD_SELFSIG) |
4456 | 4.81k | || !(node->flag & NODE_GOOD_SELFSIG)) |
4457 | 4.25k | { |
4458 | 4.25k | if (opt.verbose ) |
4459 | 0 | { |
4460 | 0 | pk = node->pkt->pkt.public_key; |
4461 | 0 | keyid_from_pk (pk, NULL); |
4462 | 0 | log_info (_("key %s: skipped subkey\n"), |
4463 | 0 | keystr_with_sub (keyid, pk->keyid)); |
4464 | 0 | } |
4465 | | |
4466 | 4.25k | delete_kbnode( node ); /* the subkey */ |
4467 | | /* and all following signature packets */ |
4468 | 6.08k | while (node->next |
4469 | 5.09k | && node->next->pkt->pkttype == PKT_SIGNATURE ) { |
4470 | 1.82k | delete_kbnode( node->next ); |
4471 | 1.82k | node = node->next; |
4472 | 1.82k | } |
4473 | 4.25k | } |
4474 | 566 | else |
4475 | 566 | subkey_seen = 1; |
4476 | 4.81k | } |
4477 | 12.0k | else if (node->pkt->pkttype == PKT_SIGNATURE |
4478 | 12.0k | && openpgp_pk_test_algo (node->pkt->pkt.signature->pubkey_algo) |
4479 | 1.78k | && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) |
4480 | 1.78k | { |
4481 | 1.78k | delete_kbnode( node ); /* build_packet() can't handle this */ |
4482 | 1.78k | } |
4483 | 10.2k | else if (node->pkt->pkttype == PKT_SIGNATURE |
4484 | 10.2k | && !node->pkt->pkt.signature->flags.exportable |
4485 | 188 | && !(options&IMPORT_LOCAL_SIGS) |
4486 | 188 | && !have_secret_key_with_kid (ctrl, |
4487 | 188 | node->pkt->pkt.signature->keyid)) |
4488 | 188 | { |
4489 | | /* here we violate the rfc a bit by still allowing |
4490 | | * to import non-exportable signature when we have the |
4491 | | * the secret key used to create this signature - it |
4492 | | * seems that this makes sense */ |
4493 | 188 | if(opt.verbose) |
4494 | 188 | log_info( _("key %s: non exportable signature" |
4495 | 0 | " (class 0x%02X) - skipped\n"), |
4496 | 0 | keystr(keyid), node->pkt->pkt.signature->sig_class ); |
4497 | 188 | delete_kbnode( node ); |
4498 | 188 | } |
4499 | 10.0k | else if (node->pkt->pkttype == PKT_SIGNATURE |
4500 | 10.0k | && IS_KEY_REV (node->pkt->pkt.signature)) |
4501 | 3.20k | { |
4502 | 3.20k | if (uid_seen ) |
4503 | 18 | { |
4504 | 18 | if(opt.verbose) |
4505 | 18 | log_info( _("key %s: revocation certificate" |
4506 | 0 | " at wrong place - skipped\n"),keystr(keyid)); |
4507 | 18 | if (r_otherrevsigs) |
4508 | 18 | { |
4509 | 18 | PACKET *pkt; |
4510 | | |
4511 | 18 | pkt = xcalloc (1, sizeof *pkt); |
4512 | 18 | pkt->pkttype = PKT_SIGNATURE; |
4513 | 18 | pkt->pkt.signature = copy_signature |
4514 | 18 | (NULL, node->pkt->pkt.signature); |
4515 | 18 | *r_otherrevsigs = new_kbnode2 (*r_otherrevsigs, pkt); |
4516 | 18 | } |
4517 | 18 | delete_kbnode( node ); |
4518 | 18 | } |
4519 | 3.19k | else |
4520 | 3.19k | { |
4521 | | /* If the revocation cert is from a different key than |
4522 | | the one we're working on don't check it - it's |
4523 | | probably from a revocation key and won't be |
4524 | | verifiable with this key anyway. */ |
4525 | | |
4526 | 3.19k | if(node->pkt->pkt.signature->keyid[0]==keyid[0] |
4527 | 544 | && node->pkt->pkt.signature->keyid[1]==keyid[1]) |
4528 | 185 | { |
4529 | 185 | int rc = check_key_signature (ctrl, keyblock, node, NULL); |
4530 | 185 | if (rc ) |
4531 | 157 | { |
4532 | 157 | if(opt.verbose) |
4533 | 157 | log_info( _("key %s: invalid revocation" |
4534 | 0 | " certificate: %s - skipped\n"), |
4535 | 0 | keystr(keyid), gpg_strerror (rc)); |
4536 | 157 | delete_kbnode( node ); |
4537 | 157 | } |
4538 | 185 | } |
4539 | 3.00k | else if (r_otherrevsigs) |
4540 | 3.00k | { |
4541 | 3.00k | PACKET *pkt; |
4542 | | |
4543 | 3.00k | pkt = xcalloc (1, sizeof *pkt); |
4544 | 3.00k | pkt->pkttype = PKT_SIGNATURE; |
4545 | 3.00k | pkt->pkt.signature = copy_signature |
4546 | 3.00k | (NULL, node->pkt->pkt.signature); |
4547 | 3.00k | *r_otherrevsigs = new_kbnode2 (*r_otherrevsigs, pkt); |
4548 | 3.00k | } |
4549 | 3.19k | } |
4550 | 3.20k | } |
4551 | 6.81k | else if (node->pkt->pkttype == PKT_SIGNATURE |
4552 | 6.81k | && (IS_SUBKEY_SIG (node->pkt->pkt.signature) |
4553 | 6.12k | || IS_SUBKEY_REV (node->pkt->pkt.signature)) |
4554 | 857 | && !subkey_seen ) |
4555 | 148 | { |
4556 | 148 | if(opt.verbose) |
4557 | 148 | log_info( _("key %s: subkey signature" |
4558 | 0 | " in wrong place - skipped\n"), keystr(keyid)); |
4559 | 148 | delete_kbnode( node ); |
4560 | 148 | } |
4561 | 6.66k | else if (node->pkt->pkttype == PKT_SIGNATURE |
4562 | 6.66k | && !IS_CERT(node->pkt->pkt.signature)) |
4563 | 478 | { |
4564 | 478 | if(opt.verbose) |
4565 | 478 | log_info(_("key %s: unexpected signature class (0x%02X) -" |
4566 | 0 | " skipped\n"),keystr(keyid), |
4567 | 0 | node->pkt->pkt.signature->sig_class); |
4568 | 478 | delete_kbnode(node); |
4569 | 478 | } |
4570 | 6.19k | else if ((node->flag & NODE_DELETION_MARK)) |
4571 | 115 | delete_kbnode( node ); |
4572 | 45.0k | } |
4573 | | |
4574 | | /* note: because keyblock is the public key, it is never marked |
4575 | | * for deletion and so keyblock cannot change */ |
4576 | 10.3k | commit_kbnode( &keyblock ); |
4577 | 10.3k | return nvalid; |
4578 | 10.3k | } |
4579 | | |
4580 | | /* This function returns true if any UID is left in the keyring. */ |
4581 | | static int |
4582 | | any_uid_left (kbnode_t keyblock) |
4583 | 0 | { |
4584 | 0 | kbnode_t node; |
4585 | |
|
4586 | 0 | for (node=keyblock->next; node; node = node->next) |
4587 | 0 | if (node->pkt->pkttype == PKT_USER_ID) |
4588 | 0 | return 1; |
4589 | 0 | return 0; |
4590 | 0 | } |
4591 | | |
4592 | | |
4593 | | /* Delete all non-self-sigs from KEYBLOCK. |
4594 | | * Returns: True if the keyblock has changed. */ |
4595 | | static void |
4596 | | remove_all_non_self_sigs (kbnode_t *keyblock, u32 *keyid) |
4597 | 0 | { |
4598 | 0 | kbnode_t node; |
4599 | 0 | unsigned int dropped = 0; |
4600 | |
|
4601 | 0 | for (node = *keyblock; node; node = node->next) |
4602 | 0 | { |
4603 | 0 | if (is_deleted_kbnode (node)) |
4604 | 0 | continue; |
4605 | | |
4606 | 0 | if (node->pkt->pkttype != PKT_SIGNATURE) |
4607 | 0 | continue; |
4608 | | |
4609 | 0 | if (node->pkt->pkt.signature->keyid[0] == keyid[0] |
4610 | 0 | && node->pkt->pkt.signature->keyid[1] == keyid[1]) |
4611 | 0 | continue; |
4612 | 0 | delete_kbnode (node); |
4613 | 0 | dropped++; |
4614 | 0 | } |
4615 | |
|
4616 | 0 | if (dropped) |
4617 | 0 | commit_kbnode (keyblock); |
4618 | |
|
4619 | 0 | if (dropped && opt.verbose) |
4620 | 0 | log_info ("key %s: number of dropped non-self-signatures: %u\n", |
4621 | 0 | keystr (keyid), dropped); |
4622 | 0 | } |
4623 | | |
4624 | | |
4625 | | /* |
4626 | | * It may happen that the imported keyblock has duplicated user IDs. |
4627 | | * We check this here and collapse those user IDs together with their |
4628 | | * sigs into one. |
4629 | | * Returns: True if the keyblock has changed. |
4630 | | */ |
4631 | | int |
4632 | | collapse_uids (kbnode_t *keyblock) |
4633 | 0 | { |
4634 | 0 | kbnode_t uid1; |
4635 | 0 | int any=0; |
4636 | |
|
4637 | 0 | for(uid1=*keyblock;uid1;uid1=uid1->next) |
4638 | 0 | { |
4639 | 0 | kbnode_t uid2; |
4640 | |
|
4641 | 0 | if(is_deleted_kbnode(uid1)) |
4642 | 0 | continue; |
4643 | | |
4644 | 0 | if(uid1->pkt->pkttype!=PKT_USER_ID) |
4645 | 0 | continue; |
4646 | | |
4647 | 0 | for(uid2=uid1->next;uid2;uid2=uid2->next) |
4648 | 0 | { |
4649 | 0 | if(is_deleted_kbnode(uid2)) |
4650 | 0 | continue; |
4651 | | |
4652 | 0 | if(uid2->pkt->pkttype!=PKT_USER_ID) |
4653 | 0 | continue; |
4654 | | |
4655 | 0 | if(cmp_user_ids(uid1->pkt->pkt.user_id, |
4656 | 0 | uid2->pkt->pkt.user_id)==0) |
4657 | 0 | { |
4658 | | /* We have a duplicated uid */ |
4659 | 0 | kbnode_t sig1,last; |
4660 | |
|
4661 | 0 | any=1; |
4662 | | |
4663 | | /* Now take uid2's signatures, and attach them to |
4664 | | uid1 */ |
4665 | 0 | for(last=uid2;last->next;last=last->next) |
4666 | 0 | { |
4667 | 0 | if(is_deleted_kbnode(last)) |
4668 | 0 | continue; |
4669 | | |
4670 | 0 | if(last->next->pkt->pkttype==PKT_USER_ID |
4671 | 0 | || last->next->pkt->pkttype==PKT_PUBLIC_SUBKEY |
4672 | 0 | || last->next->pkt->pkttype==PKT_SECRET_SUBKEY) |
4673 | 0 | break; |
4674 | 0 | } |
4675 | | |
4676 | | /* Snip out uid2 */ |
4677 | 0 | (find_prev_kbnode(*keyblock,uid2,0))->next=last->next; |
4678 | | |
4679 | | /* Now put uid2 in place as part of uid1 */ |
4680 | 0 | last->next=uid1->next; |
4681 | 0 | uid1->next=uid2; |
4682 | 0 | delete_kbnode(uid2); |
4683 | | |
4684 | | /* Now dedupe uid1 */ |
4685 | 0 | for(sig1=uid1->next;sig1;sig1=sig1->next) |
4686 | 0 | { |
4687 | 0 | kbnode_t sig2; |
4688 | |
|
4689 | 0 | if(is_deleted_kbnode(sig1)) |
4690 | 0 | continue; |
4691 | | |
4692 | 0 | if(sig1->pkt->pkttype==PKT_USER_ID |
4693 | 0 | || sig1->pkt->pkttype==PKT_PUBLIC_SUBKEY |
4694 | 0 | || sig1->pkt->pkttype==PKT_SECRET_SUBKEY) |
4695 | 0 | break; |
4696 | | |
4697 | 0 | if(sig1->pkt->pkttype!=PKT_SIGNATURE) |
4698 | 0 | continue; |
4699 | | |
4700 | 0 | for(sig2=sig1->next,last=sig1;sig2;last=sig2,sig2=sig2->next) |
4701 | 0 | { |
4702 | 0 | if(is_deleted_kbnode(sig2)) |
4703 | 0 | continue; |
4704 | | |
4705 | 0 | if(sig2->pkt->pkttype==PKT_USER_ID |
4706 | 0 | || sig2->pkt->pkttype==PKT_PUBLIC_SUBKEY |
4707 | 0 | || sig2->pkt->pkttype==PKT_SECRET_SUBKEY) |
4708 | 0 | break; |
4709 | | |
4710 | 0 | if(sig2->pkt->pkttype!=PKT_SIGNATURE) |
4711 | 0 | continue; |
4712 | | |
4713 | 0 | if(cmp_signatures(sig1->pkt->pkt.signature, |
4714 | 0 | sig2->pkt->pkt.signature)==0) |
4715 | 0 | { |
4716 | | /* We have a match, so delete the second |
4717 | | signature */ |
4718 | 0 | delete_kbnode(sig2); |
4719 | 0 | sig2=last; |
4720 | 0 | } |
4721 | 0 | } |
4722 | 0 | } |
4723 | 0 | } |
4724 | 0 | } |
4725 | 0 | } |
4726 | |
|
4727 | 0 | commit_kbnode(keyblock); |
4728 | |
|
4729 | 0 | if(any && !opt.quiet) |
4730 | 0 | { |
4731 | 0 | const char *key="???"; |
4732 | |
|
4733 | 0 | if ((uid1 = find_kbnode (*keyblock, PKT_PUBLIC_KEY)) ) |
4734 | 0 | key = keystr_from_pk (uid1->pkt->pkt.public_key); |
4735 | 0 | else if ((uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY)) ) |
4736 | 0 | key = keystr_from_pk (uid1->pkt->pkt.public_key); |
4737 | |
|
4738 | 0 | log_info (_("key %s: duplicated user ID detected - merged\n"), key); |
4739 | 0 | } |
4740 | |
|
4741 | 0 | return any; |
4742 | 0 | } |
4743 | | |
4744 | | |
4745 | | /* |
4746 | | * It may happen that the imported keyblock has duplicated subkeys. |
4747 | | * We check this here and collapse those subkeys along with their |
4748 | | * binding self-signatures. |
4749 | | * Returns: True if the keyblock has changed. |
4750 | | */ |
4751 | | int |
4752 | | collapse_subkeys (kbnode_t *keyblock) |
4753 | 0 | { |
4754 | 0 | kbnode_t kb1, kb2, sig1, sig2, last; |
4755 | 0 | int any = 0; |
4756 | |
|
4757 | 0 | for (kb1 = *keyblock; kb1; kb1 = kb1->next) |
4758 | 0 | { |
4759 | 0 | if (is_deleted_kbnode (kb1)) |
4760 | 0 | continue; |
4761 | | |
4762 | 0 | if (kb1->pkt->pkttype != PKT_PUBLIC_SUBKEY |
4763 | 0 | && kb1->pkt->pkttype != PKT_SECRET_SUBKEY) |
4764 | 0 | continue; |
4765 | | |
4766 | | /* We assume just a few duplicates and use a straightforward |
4767 | | * algorithm. */ |
4768 | 0 | for (kb2 = kb1->next; kb2; kb2 = kb2->next) |
4769 | 0 | { |
4770 | 0 | if (is_deleted_kbnode (kb2)) |
4771 | 0 | continue; |
4772 | | |
4773 | 0 | if (kb2->pkt->pkttype != PKT_PUBLIC_SUBKEY |
4774 | 0 | && kb2->pkt->pkttype != PKT_SECRET_SUBKEY) |
4775 | 0 | continue; |
4776 | | |
4777 | 0 | if (cmp_public_keys (kb1->pkt->pkt.public_key, |
4778 | 0 | kb2->pkt->pkt.public_key)) |
4779 | 0 | continue; |
4780 | | |
4781 | | /* We have a duplicated subkey. */ |
4782 | 0 | any = 1; |
4783 | | |
4784 | | /* Take subkey-2's signatures, and attach them to subkey-1. */ |
4785 | 0 | for (last = kb2; last->next; last = last->next) |
4786 | 0 | { |
4787 | 0 | if (is_deleted_kbnode (last)) |
4788 | 0 | continue; |
4789 | | |
4790 | 0 | if (last->next->pkt->pkttype != PKT_SIGNATURE) |
4791 | 0 | break; |
4792 | 0 | } |
4793 | | |
4794 | | /* Snip out subkey-2 */ |
4795 | 0 | find_prev_kbnode (*keyblock, kb2, 0)->next = last->next; |
4796 | | |
4797 | | /* Put subkey-2 in place as part of subkey-1 */ |
4798 | 0 | last->next = kb1->next; |
4799 | 0 | kb1->next = kb2; |
4800 | 0 | delete_kbnode (kb2); |
4801 | | |
4802 | | /* Now dedupe kb1 */ |
4803 | 0 | for (sig1 = kb1->next; sig1; sig1 = sig1->next) |
4804 | 0 | { |
4805 | 0 | if (is_deleted_kbnode (sig1)) |
4806 | 0 | continue; |
4807 | | |
4808 | 0 | if (sig1->pkt->pkttype != PKT_SIGNATURE) |
4809 | 0 | break; |
4810 | | |
4811 | 0 | for (sig2 = sig1->next, last = sig1; |
4812 | 0 | sig2; |
4813 | 0 | last = sig2, sig2 = sig2->next) |
4814 | 0 | { |
4815 | 0 | if (is_deleted_kbnode (sig2)) |
4816 | 0 | continue; |
4817 | | |
4818 | 0 | if (sig2->pkt->pkttype != PKT_SIGNATURE) |
4819 | 0 | break; |
4820 | | |
4821 | 0 | if (!cmp_signatures (sig1->pkt->pkt.signature, |
4822 | 0 | sig2->pkt->pkt.signature)) |
4823 | 0 | { |
4824 | | /* We have a match, so delete the second |
4825 | | signature */ |
4826 | 0 | delete_kbnode (sig2); |
4827 | 0 | sig2 = last; |
4828 | 0 | } |
4829 | 0 | } |
4830 | 0 | } |
4831 | 0 | } |
4832 | 0 | } |
4833 | |
|
4834 | 0 | commit_kbnode (keyblock); |
4835 | |
|
4836 | 0 | if (any && !opt.quiet) |
4837 | 0 | { |
4838 | 0 | const char *key="???"; |
4839 | |
|
4840 | 0 | if ((kb1 = find_kbnode (*keyblock, PKT_PUBLIC_KEY)) ) |
4841 | 0 | key = keystr_from_pk (kb1->pkt->pkt.public_key); |
4842 | 0 | else if ((kb1 = find_kbnode (*keyblock, PKT_SECRET_KEY)) ) |
4843 | 0 | key = keystr_from_pk (kb1->pkt->pkt.public_key); |
4844 | |
|
4845 | 0 | log_info (_("key %s: duplicated subkeys detected - merged\n"), key); |
4846 | 0 | } |
4847 | |
|
4848 | 0 | return any; |
4849 | 0 | } |
4850 | | |
4851 | | |
4852 | | /* Check for a 0x20 revocation from a revocation key that is not |
4853 | | present. This may be called without the benefit of merge_xxxx so |
4854 | | you can't rely on pk->revkey and friends. */ |
4855 | | static void |
4856 | | revocation_present (ctrl_t ctrl, kbnode_t keyblock) |
4857 | 2.71k | { |
4858 | 2.71k | kbnode_t onode, inode; |
4859 | 2.71k | PKT_public_key *pk = keyblock->pkt->pkt.public_key; |
4860 | | |
4861 | 6.55k | for(onode=keyblock->next;onode;onode=onode->next) |
4862 | 6.55k | { |
4863 | | /* If we reach user IDs, we're done. */ |
4864 | 6.55k | if(onode->pkt->pkttype==PKT_USER_ID) |
4865 | 2.71k | break; |
4866 | | |
4867 | 3.84k | if (onode->pkt->pkttype == PKT_SIGNATURE |
4868 | 3.84k | && IS_KEY_SIG (onode->pkt->pkt.signature) |
4869 | 659 | && onode->pkt->pkt.signature->revkey) |
4870 | 32 | { |
4871 | 32 | int idx; |
4872 | 32 | PKT_signature *sig=onode->pkt->pkt.signature; |
4873 | | |
4874 | 64 | for(idx=0;idx<sig->numrevkeys;idx++) |
4875 | 32 | { |
4876 | 32 | u32 keyid[2]; |
4877 | | |
4878 | 32 | keyid_from_fingerprint (ctrl, sig->revkey[idx].fpr, |
4879 | 32 | sig->revkey[idx].fprlen, keyid); |
4880 | | |
4881 | 123 | for(inode=keyblock->next;inode;inode=inode->next) |
4882 | 123 | { |
4883 | | /* If we reach user IDs, we're done. */ |
4884 | 123 | if(inode->pkt->pkttype==PKT_USER_ID) |
4885 | 32 | break; |
4886 | | |
4887 | 91 | if (inode->pkt->pkttype == PKT_SIGNATURE |
4888 | 91 | && IS_KEY_REV (inode->pkt->pkt.signature) |
4889 | 31 | && inode->pkt->pkt.signature->keyid[0]==keyid[0] |
4890 | 0 | && inode->pkt->pkt.signature->keyid[1]==keyid[1]) |
4891 | 0 | { |
4892 | | /* Okay, we have a revocation key, and a |
4893 | | * revocation issued by it. Do we have the key |
4894 | | * itself? */ |
4895 | 0 | gpg_error_t err; |
4896 | |
|
4897 | 0 | err = get_pubkey_byfpr_fast (ctrl, NULL, |
4898 | 0 | sig->revkey[idx].fpr, |
4899 | 0 | sig->revkey[idx].fprlen); |
4900 | 0 | if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY |
4901 | 0 | || gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) |
4902 | 0 | { |
4903 | 0 | char *tempkeystr = xstrdup (keystr_from_pk (pk)); |
4904 | | |
4905 | | /* No, so try and get it */ |
4906 | 0 | if ((opt.keyserver_options.options |
4907 | 0 | & KEYSERVER_AUTO_KEY_RETRIEVE) |
4908 | 0 | && keyserver_any_configured (ctrl)) |
4909 | 0 | { |
4910 | 0 | log_info(_("WARNING: key %s may be revoked:" |
4911 | 0 | " fetching revocation key %s\n"), |
4912 | 0 | tempkeystr,keystr(keyid)); |
4913 | 0 | keyserver_import_fpr (ctrl, |
4914 | 0 | sig->revkey[idx].fpr, |
4915 | 0 | sig->revkey[idx].fprlen, |
4916 | 0 | opt.keyserver, 0); |
4917 | | |
4918 | | /* Do we have it now? */ |
4919 | 0 | err = get_pubkey_byfpr_fast (ctrl, NULL, |
4920 | 0 | sig->revkey[idx].fpr, |
4921 | 0 | sig->revkey[idx].fprlen); |
4922 | 0 | } |
4923 | |
|
4924 | 0 | if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY |
4925 | 0 | || gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) |
4926 | 0 | log_info(_("WARNING: key %s may be revoked:" |
4927 | 0 | " revocation key %s not present.\n"), |
4928 | 0 | tempkeystr,keystr(keyid)); |
4929 | |
|
4930 | 0 | xfree(tempkeystr); |
4931 | 0 | } |
4932 | 0 | } |
4933 | 91 | } |
4934 | 32 | } |
4935 | 32 | } |
4936 | 3.84k | } |
4937 | 2.71k | } |
4938 | | |
4939 | | |
4940 | | /* |
4941 | | * compare and merge the blocks |
4942 | | * |
4943 | | * o compare the signatures: If we already have this signature, check |
4944 | | * that they compare okay; if not, issue a warning and ask the user. |
4945 | | * o Simply add the signature. Can't verify here because we may not have |
4946 | | * the signature's public key yet; verification is done when putting it |
4947 | | * into the trustdb, which is done automagically as soon as this pubkey |
4948 | | * is used. |
4949 | | * Note: We indicate newly inserted packets with NODE_FLAG_A. |
4950 | | */ |
4951 | | static int |
4952 | | merge_blocks (ctrl_t ctrl, unsigned int options, |
4953 | | kbnode_t keyblock_orig, kbnode_t keyblock, |
4954 | | u32 *keyid, u32 curtime, int origin, const char *url, |
4955 | | int *n_uids, int *n_sigs, int *n_subk ) |
4956 | 2.99k | { |
4957 | 2.99k | kbnode_t onode, node; |
4958 | 2.99k | int rc, found; |
4959 | | |
4960 | | /* 1st: handle revocation certificates */ |
4961 | 4.73k | for (node=keyblock->next; node; node=node->next ) |
4962 | 4.73k | { |
4963 | 4.73k | if (node->pkt->pkttype == PKT_USER_ID ) |
4964 | 2.99k | break; |
4965 | 1.73k | else if (node->pkt->pkttype == PKT_SIGNATURE |
4966 | 1.31k | && IS_KEY_REV (node->pkt->pkt.signature)) |
4967 | 113 | { |
4968 | | /* check whether we already have this */ |
4969 | 113 | found = 0; |
4970 | 1.71k | for (onode=keyblock_orig->next; onode; onode=onode->next) |
4971 | 1.71k | { |
4972 | 1.71k | if (onode->pkt->pkttype == PKT_USER_ID ) |
4973 | 56 | break; |
4974 | 1.66k | else if (onode->pkt->pkttype == PKT_SIGNATURE |
4975 | 1.66k | && IS_KEY_REV (onode->pkt->pkt.signature) |
4976 | 1.21k | && !cmp_signatures(onode->pkt->pkt.signature, |
4977 | 1.21k | node->pkt->pkt.signature)) |
4978 | 57 | { |
4979 | 57 | found = 1; |
4980 | 57 | break; |
4981 | 57 | } |
4982 | 1.71k | } |
4983 | 113 | if (!found) |
4984 | 56 | { |
4985 | 56 | kbnode_t n2 = clone_kbnode(node); |
4986 | 56 | insert_kbnode( keyblock_orig, n2, 0 ); |
4987 | 56 | n2->flag |= NODE_FLAG_A; |
4988 | 56 | ++*n_sigs; |
4989 | 56 | if(!opt.quiet) |
4990 | 56 | { |
4991 | 56 | char *p = get_user_id_native (ctrl, keyid); |
4992 | 56 | log_info(_("key %s: \"%s\" revocation" |
4993 | 56 | " certificate added\n"), keystr(keyid),p); |
4994 | 56 | xfree(p); |
4995 | 56 | } |
4996 | 56 | } |
4997 | 113 | } |
4998 | 4.73k | } |
4999 | | |
5000 | | /* 2nd: merge in any direct key (0x1F) sigs */ |
5001 | 4.73k | for(node=keyblock->next; node; node=node->next) |
5002 | 4.73k | { |
5003 | 4.73k | if (node->pkt->pkttype == PKT_USER_ID ) |
5004 | 2.99k | break; |
5005 | 1.73k | else if (node->pkt->pkttype == PKT_SIGNATURE |
5006 | 1.31k | && IS_KEY_SIG (node->pkt->pkt.signature)) |
5007 | 655 | { |
5008 | | /* check whether we already have this */ |
5009 | 655 | found = 0; |
5010 | 5.38k | for (onode=keyblock_orig->next; onode; onode=onode->next) |
5011 | 5.38k | { |
5012 | 5.38k | if (onode->pkt->pkttype == PKT_USER_ID) |
5013 | 643 | break; |
5014 | 4.73k | else if (onode->pkt->pkttype == PKT_SIGNATURE |
5015 | 4.73k | && IS_KEY_SIG (onode->pkt->pkt.signature) |
5016 | 361 | && !cmp_signatures(onode->pkt->pkt.signature, |
5017 | 361 | node->pkt->pkt.signature)) |
5018 | 12 | { |
5019 | 12 | found = 1; |
5020 | 12 | break; |
5021 | 12 | } |
5022 | 5.38k | } |
5023 | 655 | if (!found ) |
5024 | 643 | { |
5025 | 643 | kbnode_t n2 = clone_kbnode(node); |
5026 | 643 | insert_kbnode( keyblock_orig, n2, 0 ); |
5027 | 643 | n2->flag |= NODE_FLAG_A; |
5028 | 643 | ++*n_sigs; |
5029 | 643 | if(!opt.quiet) |
5030 | 643 | log_info( _("key %s: direct key signature added\n"), |
5031 | 643 | keystr(keyid)); |
5032 | 643 | } |
5033 | 655 | } |
5034 | 4.73k | } |
5035 | | |
5036 | | /* 3rd: try to merge new certificates in */ |
5037 | 6.46M | for (onode=keyblock_orig->next; onode; onode=onode->next) |
5038 | 6.45M | { |
5039 | 6.45M | if (!(onode->flag & NODE_FLAG_A) && onode->pkt->pkttype == PKT_USER_ID) |
5040 | 5.52k | { |
5041 | | /* find the user id in the imported keyblock */ |
5042 | 14.5k | for (node=keyblock->next; node; node=node->next) |
5043 | 11.9k | if (node->pkt->pkttype == PKT_USER_ID |
5044 | 5.55k | && !cmp_user_ids( onode->pkt->pkt.user_id, |
5045 | 5.55k | node->pkt->pkt.user_id ) ) |
5046 | 3.00k | break; |
5047 | 5.52k | if (node ) /* found: merge */ |
5048 | 3.00k | { |
5049 | 3.00k | rc = merge_sigs (onode, node, n_sigs); |
5050 | 3.00k | if (rc ) |
5051 | 0 | return rc; |
5052 | 3.00k | } |
5053 | 5.52k | } |
5054 | 6.45M | } |
5055 | | |
5056 | | /* 4th: add new user-ids */ |
5057 | 11.3k | for (node=keyblock->next; node; node=node->next) |
5058 | 8.40k | { |
5059 | 8.40k | if (node->pkt->pkttype == PKT_USER_ID) |
5060 | 3.11k | { |
5061 | | /* do we have this in the original keyblock */ |
5062 | 28.6k | for (onode=keyblock_orig->next; onode; onode=onode->next ) |
5063 | 28.6k | if (onode->pkt->pkttype == PKT_USER_ID |
5064 | 3.21k | && !cmp_user_ids( onode->pkt->pkt.user_id, |
5065 | 3.21k | node->pkt->pkt.user_id ) ) |
5066 | 3.11k | break; |
5067 | 3.11k | if (!onode ) /* this is a new user id: append */ |
5068 | 3 | { |
5069 | 3 | rc = append_new_uid (options, keyblock_orig, node, |
5070 | 3 | curtime, origin, url, n_sigs); |
5071 | 3 | if (rc ) |
5072 | 0 | return rc; |
5073 | 3 | ++*n_uids; |
5074 | 3 | } |
5075 | 3.11k | } |
5076 | 8.40k | } |
5077 | | |
5078 | | /* 5th: add new subkeys */ |
5079 | 11.3k | for (node=keyblock->next; node; node=node->next) |
5080 | 8.40k | { |
5081 | 8.40k | onode = NULL; |
5082 | 8.40k | if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) |
5083 | 484 | { |
5084 | | /* do we have this in the original keyblock? */ |
5085 | 885k | for(onode=keyblock_orig->next; onode; onode=onode->next) |
5086 | 885k | if (onode->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5087 | 42.9k | && !cmp_public_keys( onode->pkt->pkt.public_key, |
5088 | 42.9k | node->pkt->pkt.public_key)) |
5089 | 182 | break; |
5090 | 484 | if (!onode ) /* This is a new subkey: append. */ |
5091 | 302 | { |
5092 | 302 | rc = append_key (keyblock_orig, node, n_sigs); |
5093 | 302 | if (rc) |
5094 | 0 | return rc; |
5095 | 302 | ++*n_subk; |
5096 | 302 | } |
5097 | 484 | } |
5098 | 7.91k | else if (node->pkt->pkttype == PKT_SECRET_SUBKEY) |
5099 | 0 | { |
5100 | | /* do we have this in the original keyblock? */ |
5101 | 0 | for (onode=keyblock_orig->next; onode; onode=onode->next ) |
5102 | 0 | if (onode->pkt->pkttype == PKT_SECRET_SUBKEY |
5103 | 0 | && !cmp_public_keys (onode->pkt->pkt.public_key, |
5104 | 0 | node->pkt->pkt.public_key) ) |
5105 | 0 | break; |
5106 | 0 | if (!onode ) /* This is a new subkey: append. */ |
5107 | 0 | { |
5108 | 0 | rc = append_key (keyblock_orig, node, n_sigs); |
5109 | 0 | if (rc ) |
5110 | 0 | return rc; |
5111 | 0 | ++*n_subk; |
5112 | 0 | } |
5113 | 0 | } |
5114 | 8.40k | } |
5115 | | |
5116 | | /* 6th: merge subkey certificates */ |
5117 | 6.46M | for (onode=keyblock_orig->next; onode; onode=onode->next) |
5118 | 6.46M | { |
5119 | 6.46M | if (!(onode->flag & NODE_FLAG_A) |
5120 | 6.45M | && (onode->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5121 | 6.09M | || onode->pkt->pkttype == PKT_SECRET_SUBKEY)) |
5122 | 357k | { |
5123 | | /* find the subkey in the imported keyblock */ |
5124 | 1.23M | for(node=keyblock->next; node; node=node->next) |
5125 | 887k | { |
5126 | 887k | if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5127 | 832k | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
5128 | 55.6k | && !cmp_public_keys( onode->pkt->pkt.public_key, |
5129 | 55.6k | node->pkt->pkt.public_key ) ) |
5130 | 12.8k | break; |
5131 | 887k | } |
5132 | 357k | if (node) /* Found: merge. */ |
5133 | 12.8k | { |
5134 | 12.8k | rc = merge_keysigs( onode, node, n_sigs); |
5135 | 12.8k | if (rc ) |
5136 | 0 | return rc; |
5137 | 12.8k | } |
5138 | 357k | } |
5139 | 6.46M | } |
5140 | | |
5141 | 2.99k | return 0; |
5142 | 2.99k | } |
5143 | | |
5144 | | |
5145 | | /* Helper function for merge_blocks. |
5146 | | * |
5147 | | * Append the new userid starting with NODE and all signatures to |
5148 | | * KEYBLOCK. ORIGIN and URL conveys the usual key origin info. The |
5149 | | * integer at N_SIGS is updated with the number of new signatures. |
5150 | | */ |
5151 | | static gpg_error_t |
5152 | | append_new_uid (unsigned int options, |
5153 | | kbnode_t keyblock, kbnode_t node, u32 curtime, |
5154 | | int origin, const char *url, int *n_sigs) |
5155 | 3 | { |
5156 | 3 | gpg_error_t err; |
5157 | 3 | kbnode_t n; |
5158 | 3 | kbnode_t n_where = NULL; |
5159 | | |
5160 | 3 | log_assert (node->pkt->pkttype == PKT_USER_ID); |
5161 | | |
5162 | | /* Find the right position for the new user id and its signatures. */ |
5163 | 17 | for (n = keyblock; n; n_where = n, n = n->next) |
5164 | 14 | { |
5165 | 14 | if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5166 | 14 | || n->pkt->pkttype == PKT_SECRET_SUBKEY ) |
5167 | 0 | break; |
5168 | 14 | } |
5169 | 3 | if (!n) |
5170 | 3 | n_where = NULL; |
5171 | | |
5172 | | /* and append/insert */ |
5173 | 8 | while (node) |
5174 | 6 | { |
5175 | | /* we add a clone to the original keyblock, because this |
5176 | | * one is released first. */ |
5177 | 6 | n = clone_kbnode(node); |
5178 | 6 | if (n->pkt->pkttype == PKT_USER_ID |
5179 | 3 | && !(options & IMPORT_RESTORE) ) |
5180 | 3 | { |
5181 | 3 | err = insert_key_origin_uid (n->pkt->pkt.user_id, |
5182 | 3 | curtime, origin, url); |
5183 | 3 | if (err) |
5184 | 0 | { |
5185 | 0 | release_kbnode (n); |
5186 | 0 | return err; |
5187 | 0 | } |
5188 | 3 | } |
5189 | | |
5190 | 6 | if (n_where) |
5191 | 0 | { |
5192 | 0 | insert_kbnode( n_where, n, 0 ); |
5193 | 0 | n_where = n; |
5194 | 0 | } |
5195 | 6 | else |
5196 | 6 | add_kbnode( keyblock, n ); |
5197 | 6 | n->flag |= NODE_FLAG_A; |
5198 | 6 | node->flag |= NODE_FLAG_A; |
5199 | 6 | if (n->pkt->pkttype == PKT_SIGNATURE ) |
5200 | 3 | ++*n_sigs; |
5201 | | |
5202 | 6 | node = node->next; |
5203 | 6 | if (node && node->pkt->pkttype != PKT_SIGNATURE ) |
5204 | 1 | break; |
5205 | 6 | } |
5206 | | |
5207 | 3 | return 0; |
5208 | 3 | } |
5209 | | |
5210 | | |
5211 | | /* Helper function for merge_blocks |
5212 | | * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID. |
5213 | | * (how should we handle comment packets here?) |
5214 | | */ |
5215 | | static int |
5216 | | merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs) |
5217 | 3.00k | { |
5218 | 3.00k | kbnode_t n, n2; |
5219 | 3.00k | int found = 0; |
5220 | | |
5221 | 3.00k | log_assert (dst->pkt->pkttype == PKT_USER_ID); |
5222 | 3.00k | log_assert (src->pkt->pkttype == PKT_USER_ID); |
5223 | | |
5224 | 6.44k | for (n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next) |
5225 | 3.43k | { |
5226 | 3.43k | if (n->pkt->pkttype != PKT_SIGNATURE ) |
5227 | 64 | continue; |
5228 | 3.37k | if (IS_SUBKEY_SIG (n->pkt->pkt.signature) |
5229 | 3.31k | || IS_SUBKEY_REV (n->pkt->pkt.signature) ) |
5230 | 108 | continue; /* skip signatures which are only valid on subkeys */ |
5231 | | |
5232 | 3.26k | found = 0; |
5233 | 3.23M | for (n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next) |
5234 | 3.23M | if (!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature)) |
5235 | 435 | { |
5236 | 435 | found++; |
5237 | 435 | break; |
5238 | 435 | } |
5239 | 3.26k | if (!found ) |
5240 | 2.83k | { |
5241 | | /* This signature is new or newer, append N to DST. |
5242 | | * We add a clone to the original keyblock, because this |
5243 | | * one is released first */ |
5244 | 2.83k | n2 = clone_kbnode(n); |
5245 | 2.83k | insert_kbnode( dst, n2, PKT_SIGNATURE ); |
5246 | 2.83k | n2->flag |= NODE_FLAG_A; |
5247 | 2.83k | n->flag |= NODE_FLAG_A; |
5248 | 2.83k | ++*n_sigs; |
5249 | 2.83k | } |
5250 | 3.26k | } |
5251 | | |
5252 | 3.00k | return 0; |
5253 | 3.00k | } |
5254 | | |
5255 | | |
5256 | | /* Helper function for merge_blocks |
5257 | | * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY. |
5258 | | */ |
5259 | | static int |
5260 | | merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs) |
5261 | 12.8k | { |
5262 | 12.8k | kbnode_t n, n2; |
5263 | 12.8k | int found = 0; |
5264 | | |
5265 | 12.8k | log_assert (dst->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5266 | 12.8k | || dst->pkt->pkttype == PKT_SECRET_SUBKEY); |
5267 | | |
5268 | 64.5k | for (n=src->next; n ; n = n->next) |
5269 | 51.7k | { |
5270 | 51.7k | if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5271 | 51.7k | || n->pkt->pkttype == PKT_PUBLIC_KEY ) |
5272 | 13 | break; |
5273 | 51.7k | if (n->pkt->pkttype != PKT_SIGNATURE ) |
5274 | 12.8k | continue; |
5275 | | |
5276 | 38.8k | found = 0; |
5277 | 146k | for (n2=dst->next; n2; n2 = n2->next) |
5278 | 146k | { |
5279 | 146k | if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5280 | 145k | || n2->pkt->pkttype == PKT_PUBLIC_KEY ) |
5281 | 1.36k | break; |
5282 | 145k | if (n2->pkt->pkttype == PKT_SIGNATURE |
5283 | 145k | && (n->pkt->pkt.signature->keyid[0] |
5284 | 145k | == n2->pkt->pkt.signature->keyid[0]) |
5285 | 53.2k | && (n->pkt->pkt.signature->keyid[1] |
5286 | 53.2k | == n2->pkt->pkt.signature->keyid[1]) |
5287 | 50.5k | && (n->pkt->pkt.signature->timestamp |
5288 | 50.5k | <= n2->pkt->pkt.signature->timestamp) |
5289 | 50.4k | && (n->pkt->pkt.signature->sig_class |
5290 | 50.4k | == n2->pkt->pkt.signature->sig_class)) |
5291 | 37.4k | { |
5292 | 37.4k | found++; |
5293 | 37.4k | break; |
5294 | 37.4k | } |
5295 | 145k | } |
5296 | 38.8k | if (!found ) |
5297 | 1.45k | { |
5298 | | /* This signature is new or newer, append N to DST. |
5299 | | * We add a clone to the original keyblock, because this |
5300 | | * one is released first */ |
5301 | 1.45k | n2 = clone_kbnode(n); |
5302 | 1.45k | insert_kbnode( dst, n2, PKT_SIGNATURE ); |
5303 | 1.45k | n2->flag |= NODE_FLAG_A; |
5304 | 1.45k | n->flag |= NODE_FLAG_A; |
5305 | 1.45k | ++*n_sigs; |
5306 | 1.45k | } |
5307 | 38.8k | } |
5308 | | |
5309 | 12.8k | return 0; |
5310 | 12.8k | } |
5311 | | |
5312 | | |
5313 | | /* Helper function for merge_blocks. |
5314 | | * Append the subkey starting with NODE and all signatures to KEYBLOCK. |
5315 | | * Mark all new and copied packets by setting flag bit 0. |
5316 | | */ |
5317 | | static int |
5318 | | append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs) |
5319 | 302 | { |
5320 | 302 | kbnode_t n; |
5321 | | |
5322 | 302 | log_assert (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
5323 | 302 | || node->pkt->pkttype == PKT_SECRET_SUBKEY); |
5324 | | |
5325 | 1.05k | while (node) |
5326 | 1.02k | { |
5327 | | /* we add a clone to the original keyblock, because this |
5328 | | * one is released first */ |
5329 | 1.02k | n = clone_kbnode(node); |
5330 | 1.02k | add_kbnode( keyblock, n ); |
5331 | 1.02k | n->flag |= NODE_FLAG_A; |
5332 | 1.02k | node->flag |= NODE_FLAG_A; |
5333 | 1.02k | if (n->pkt->pkttype == PKT_SIGNATURE ) |
5334 | 719 | ++*n_sigs; |
5335 | | |
5336 | 1.02k | node = node->next; |
5337 | 1.02k | if (node && node->pkt->pkttype != PKT_SIGNATURE ) |
5338 | 272 | break; |
5339 | 1.02k | } |
5340 | | |
5341 | 302 | return 0; |
5342 | 302 | } |