See ChangeLog: Mon Sep 18 16:35:45 CEST 2000 Werner Koch
[gnupg.git] / g10 / import.c
1 /* import.c
2  *      Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "options.h"
29 #include "packet.h"
30 #include "errors.h"
31 #include "keydb.h"
32 #include <gcrypt.h>
33 #include "util.h"
34 #include "trustdb.h"
35 #include "main.h"
36 #include "i18n.h"
37 #include "status.h"
38
39
40 static struct {
41     ulong count;
42     ulong no_user_id;
43     ulong imported;
44     ulong imported_rsa;
45     ulong n_uids;
46     ulong n_sigs;
47     ulong n_subk;
48     ulong unchanged;
49     ulong n_revoc;
50     ulong secret_read;
51     ulong secret_imported;
52     ulong secret_dups;
53     ulong skipped_new_keys;
54 } stats;
55
56
57 static int import( IOBUF inp, int fast, const char* fname );
58 static void print_stats(void);
59 static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
60 static int import_one( const char *fname, KBNODE keyblock, int fast );
61 static int import_secret_one( const char *fname, KBNODE keyblock );
62 static int import_revoke_cert( const char *fname, KBNODE node );
63 static int chk_self_sigs( const char *fname, KBNODE keyblock,
64                           PKT_public_key *pk, u32 *keyid );
65 static void mark_non_selfsigned_uids_valid( KBNODE keyblock, u32 *kid );
66 static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid );
67 static int merge_blocks( const char *fname, KBNODE keyblock_orig,
68                          KBNODE keyblock, u32 *keyid,
69                          int *n_uids, int *n_sigs, int *n_subk );
70 static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
71                              const char *fname, u32 *keyid );
72 static int append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
73                              const char *fname, u32 *keyid );
74 static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
75                              const char *fname, u32 *keyid );
76 static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
77                              const char *fname, u32 *keyid );
78
79
80 /****************
81  * Import the public keys from the given filename. Input may be armored.
82  * This function rejects all keys which are not validly self signed on at
83  * least one userid. Only user ids which are self signed will be imported.
84  * Other signatures are not checked.
85  *
86  * Actually this function does a merge. It works like this:
87  *
88  *  - get the keyblock
89  *  - check self-signatures and remove all userids and their signatures
90  *    without/invalid self-signatures.
91  *  - reject the keyblock, if we have no valid userid.
92  *  - See whether we have this key already in one of our pubrings.
93  *    If not, simply add it to the default keyring.
94  *  - Compare the key and the self-signatures of the new and the one in
95  *    our keyring.  If they are different something weird is going on;
96  *    ask what to do.
97  *  - See whether we have only non-self-signature on one user id; if not
98  *    ask the user what to do.
99  *  - compare the signatures: If we already have this signature, check
100  *    that they compare okay; if not, issue a warning and ask the user.
101  *    (consider looking at the timestamp and use the newest?)
102  *  - Simply add the signature.  Can't verify here because we may not have
103  *    the signature's public key yet; verification is done when putting it
104  *    into the trustdb, which is done automagically as soon as this pubkey
105  *    is used.
106  *  - Proceed with next signature.
107  *
108  *  Key revocation certificates have special handling.
109  *
110  */
111 void
112 import_keys( char **fnames, int nnames, int fast )
113 {
114     int i;
115
116     /* fixme: don't use static variables */
117     memset( &stats, 0, sizeof( stats ) );
118
119     if( !fnames && !nnames )
120         nnames = 1;  /* Ohh what a ugly hack to jump into the loop */
121
122     for(i=0; i < nnames; i++ ) {
123         const char *fname = fnames? fnames[i] : NULL;
124         IOBUF inp = iobuf_open(fname);
125         if( !fname )
126             fname = "[stdin]";
127         if( !inp )
128             log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
129         else {
130             int rc = import( inp, fast, fname );
131             iobuf_close(inp);
132             if( rc )
133                 log_error("import from `%s' failed: %s\n", fname,
134                                                            gpg_errstr(rc) );
135         }
136         if( !fname )
137             break;
138     }
139     print_stats();
140     if( !fast )
141         sync_trustdb();
142 }
143
144 int
145 import_keys_stream( IOBUF inp, int fast )
146 {
147     int rc = 0;
148
149     /* fixme: don't use static variables */
150     memset( &stats, 0, sizeof( stats ) );
151     rc = import( inp, fast, "[stream]" );
152     print_stats();
153     if( !fast )
154         sync_trustdb();
155     return rc;
156 }
157
158 static int
159 import( IOBUF inp, int fast, const char* fname )
160 {
161     PACKET *pending_pkt = NULL;
162     KBNODE keyblock;
163     int rc = 0;
164
165     getkey_disable_caches();
166
167     if( !opt.no_armor ) { /* armored reading is not disabled */
168         armor_filter_context_t *afx = gcry_xcalloc( 1, sizeof *afx );
169         afx->only_keyblocks = 1;
170         iobuf_push_filter2( inp, armor_filter, afx, 1 );
171     }
172
173     while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
174         if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
175             rc = import_one( fname, keyblock, fast );
176         else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
177             rc = import_secret_one( fname, keyblock );
178         else if( keyblock->pkt->pkttype == PKT_SIGNATURE
179                  && keyblock->pkt->pkt.signature->sig_class == 0x20 )
180             rc = import_revoke_cert( fname, keyblock );
181         else {
182             log_info( _("skipping block of type %d\n"),
183                                             keyblock->pkt->pkttype );
184         }
185         release_kbnode(keyblock);
186         if( rc )
187             break;
188         if( !(++stats.count % 100) && !opt.quiet )
189             log_info(_("%lu keys so far processed\n"), stats.count );
190     }
191     if( rc == -1 )
192         rc = 0;
193     else if( rc && rc != GPGERR_INV_KEYRING )
194         log_error( _("error reading `%s': %s\n"), fname, gpg_errstr(rc));
195
196     return rc;
197 }
198
199
200 static void
201 print_stats()
202 {
203     if( !opt.quiet ) {
204         log_info(_("Total number processed: %lu\n"), stats.count );
205         if( stats.skipped_new_keys )
206             log_info(_("      skipped new keys: %lu\n"),
207                                                 stats.skipped_new_keys );
208         if( stats.no_user_id )
209             log_info(_("          w/o user IDs: %lu\n"), stats.no_user_id );
210         if( stats.imported || stats.imported_rsa ) {
211             log_info(_("              imported: %lu"), stats.imported );
212             if( stats.imported_rsa )
213                 fprintf(stderr, "  (RSA: %lu)", stats.imported_rsa );
214             putc('\n', stderr);
215         }
216         if( stats.unchanged )
217             log_info(_("             unchanged: %lu\n"), stats.unchanged );
218         if( stats.n_uids )
219             log_info(_("          new user IDs: %lu\n"), stats.n_uids );
220         if( stats.n_subk )
221             log_info(_("           new subkeys: %lu\n"), stats.n_subk );
222         if( stats.n_sigs )
223             log_info(_("        new signatures: %lu\n"), stats.n_sigs );
224         if( stats.n_revoc )
225             log_info(_("   new key revocations: %lu\n"), stats.n_revoc );
226         if( stats.secret_read )
227             log_info(_("      secret keys read: %lu\n"), stats.secret_read );
228         if( stats.secret_imported )
229             log_info(_("  secret keys imported: %lu\n"), stats.secret_imported );
230         if( stats.secret_dups )
231             log_info(_(" secret keys unchanged: %lu\n"), stats.secret_dups );
232     }
233
234     if( is_status_enabled() ) {
235         char buf[12*20];
236         sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
237                 stats.count,
238                 stats.no_user_id,
239                 stats.imported,
240                 stats.imported_rsa,
241                 stats.unchanged,
242                 stats.n_uids,
243                 stats.n_subk,
244                 stats.n_sigs,
245                 stats.n_revoc,
246                 stats.secret_read,
247                 stats.secret_imported,
248                 stats.secret_dups);
249         write_status_text( STATUS_IMPORT_RES, buf );
250     }
251 }
252
253
254 /****************
255  * Read the next keyblock from stream A.
256  * PENDING_PKT should be initialzed to NULL
257  * and not chnaged form the caller.
258  * Retunr: 0 = okay, -1 no more blocks or another errorcode.
259  */
260 static int
261 read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root )
262 {
263     int rc;
264     PACKET *pkt;
265     KBNODE root = NULL;
266     int in_cert;
267
268     if( *pending_pkt ) {
269         root = new_kbnode( *pending_pkt );
270         *pending_pkt = NULL;
271         in_cert = 1;
272     }
273     else
274         in_cert = 0;
275     pkt = gcry_xmalloc( sizeof *pkt );
276     init_packet(pkt);
277     while( (rc=parse_packet(a, pkt)) != -1 ) {
278         if( rc ) {  /* ignore errors */
279             if( rc != GPGERR_UNKNOWN_PACKET ) {
280                 log_error("read_block: read error: %s\n", gpg_errstr(rc) );
281                 rc = GPGERR_INV_KEYRING;
282                 goto ready;
283             }
284             free_packet( pkt );
285             init_packet(pkt);
286             continue;
287         }
288
289         if( !root && pkt->pkttype == PKT_SIGNATURE
290                   && pkt->pkt.signature->sig_class == 0x20 ) {
291             /* this is a revocation certificate which is handled
292              * in a special way */
293             root = new_kbnode( pkt );
294             pkt = NULL;
295             goto ready;
296         }
297
298         /* make a linked list of all packets */
299         switch( pkt->pkttype ) {
300           case PKT_COMPRESSED:
301             if( pkt->pkt.compressed->algorithm < 1
302                 || pkt->pkt.compressed->algorithm > 2 ) {
303                 rc = GPGERR_COMPR_ALGO;
304                 goto ready;
305             }
306             {
307                 compress_filter_context_t *cfx = gcry_xcalloc( 1, sizeof *cfx );
308                 cfx->algo = pkt->pkt.compressed->algorithm;
309                 pkt->pkt.compressed->buf = NULL;
310                 iobuf_push_filter2( a, compress_filter, cfx, 1 );
311             }
312             free_packet( pkt );
313             init_packet(pkt);
314             break;
315
316
317           case PKT_PUBLIC_KEY:
318           case PKT_SECRET_KEY:
319             if( in_cert ) { /* store this packet */
320                 *pending_pkt = pkt;
321                 pkt = NULL;
322                 goto ready;
323             }
324             in_cert = 1;
325           default:
326             if( in_cert ) {
327                 if( !root )
328                     root = new_kbnode( pkt );
329                 else
330                     add_kbnode( root, new_kbnode( pkt ) );
331                 pkt = gcry_xmalloc( sizeof *pkt );
332             }
333             init_packet(pkt);
334             break;
335         }
336     }
337   ready:
338     if( rc == -1 && root )
339         rc = 0;
340
341     if( rc )
342         release_kbnode( root );
343     else
344         *ret_root = root;
345     free_packet( pkt );
346     gcry_free( pkt );
347     return rc;
348 }
349
350
351 /****************
352  * Try to import one keyblock.  Return an error only in serious cases, but
353  * never for an invalid keyblock.  It uses log_error to increase the
354  * internal errorcount, so that invalid input can be detected by programs
355  * which called gpg.
356  */
357 static int
358 import_one( const char *fname, KBNODE keyblock, int fast )
359 {
360     PKT_public_key *pk;
361     PKT_public_key *pk_orig;
362     KBNODE node, uidnode;
363     KBNODE keyblock_orig = NULL;
364     KBPOS kbpos;
365     u32 keyid[2];
366     int rc = 0;
367     int new_key = 0;
368     int mod_key = 0;
369
370     /* get the key and print some info about it */
371     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
372     if( !node )
373         BUG();
374
375     pk = node->pkt->pkt.public_key;
376     keyid_from_pk( pk, keyid );
377     uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
378
379     if( opt.verbose ) {
380         log_info( "pub  %4u%c/%08lX %s   ",
381                   nbits_from_pk( pk ),
382                   pubkey_letter( pk->pubkey_algo ),
383                   (ulong)keyid[1], datestr_from_pk(pk) );
384         if( uidnode )
385             print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
386                                        uidnode->pkt->pkt.user_id->len );
387         putc('\n', stderr);
388     }
389     if( !uidnode ) {
390         log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]);
391         return 0;
392     }
393
394     clear_kbnode_flags( keyblock );
395     rc = chk_self_sigs( fname, keyblock , pk, keyid );
396     if( rc )
397         return rc== -1? 0:rc;
398
399     if( opt.allow_non_selfsigned_uid )
400         mark_non_selfsigned_uids_valid( keyblock, keyid );
401
402     if( !delete_inv_parts( fname, keyblock, keyid ) ) {
403         if( !opt.quiet ) {
404             log_info( _("key %08lX: no valid user IDs\n"),
405                                                         (ulong)keyid[1]);
406             log_info(_("this may be caused by a missing self-signature\n"));
407         }
408         stats.no_user_id++;
409         return 0;
410     }
411
412
413     /* do we have this key already in one of our pubrings ? */
414     pk_orig = gcry_xcalloc( 1, sizeof *pk_orig );
415     rc = get_pubkey( pk_orig, keyid );
416     if( rc && rc != GPGERR_NO_PUBKEY ) {
417         log_error( _("key %08lX: public key not found: %s\n"),
418                                 (ulong)keyid[1], gpg_errstr(rc));
419     }
420     else if ( rc && opt.merge_only ) {
421         if( opt.verbose )
422             log_info( _("key %08lX: new key - skipped\n"), (ulong)keyid[1] );
423         rc = 0;
424         fast = 1; /* so that we don't get into the trustdb update */
425         stats.skipped_new_keys++;
426     }
427     else if( rc ) { /* insert this key */
428         /* get default resource */
429         if( get_keyblock_handle( NULL, 0, &kbpos ) ) {
430             log_error(_("no default public keyring\n"));
431             return GPGERR_GENERAL;
432         }
433         if( opt.verbose > 1 )
434             log_info( _("writing to `%s'\n"),
435                                 keyblock_resource_name(&kbpos) );
436         if( (rc=lock_keyblock( &kbpos )) )
437            log_error(_("can't lock keyring `%s': %s\n"),
438                        keyblock_resource_name(&kbpos), gpg_errstr(rc) );
439         else if( (rc=insert_keyblock( &kbpos, keyblock )) )
440            log_error( _("error writing keyring `%s': %s\n"),
441                        keyblock_resource_name(&kbpos), gpg_errstr(rc) );
442         unlock_keyblock( &kbpos );
443         /* we are ready */
444         if( !opt.quiet )
445             log_info( _("key %08lX: public key imported\n"), (ulong)keyid[1]);
446         if( is_status_enabled() ) {
447             char *us = get_long_user_id_string( keyid );
448             write_status_text( STATUS_IMPORTED, us );
449             gcry_free(us);
450         }
451         stats.imported++;
452         if( is_RSA( pk->pubkey_algo ) )
453             stats.imported_rsa++;
454         new_key = 1;
455     }
456     else { /* merge */
457         int n_uids, n_sigs, n_subk;
458
459         /* Compare the original against the new key; just to be sure nothing
460          * weird is going on */
461         if( cmp_public_keys( pk_orig, pk ) ) {
462             log_error( _("key %08lX: doesn't match our copy\n"),
463                                                           (ulong)keyid[1]);
464             rc = GPGERR_GENERAL;
465             goto leave;
466         }
467
468         /* now read the original keyblock */
469         rc = find_keyblock_bypk( &kbpos, pk_orig );
470         if( rc ) {
471             log_error( _("key %08lX: can't locate original keyblock: %s\n"),
472                                      (ulong)keyid[1], gpg_errstr(rc));
473             goto leave;
474         }
475         rc = read_keyblock( &kbpos, &keyblock_orig );
476         if( rc ) {
477             log_error( _("key %08lX: can't read original keyblock: %s\n"),
478                                             (ulong)keyid[1], gpg_errstr(rc));
479             goto leave;
480         }
481
482         collapse_uids( &keyblock );
483         /* and try to merge the block */
484         clear_kbnode_flags( keyblock_orig );
485         clear_kbnode_flags( keyblock );
486         n_uids = n_sigs = n_subk = 0;
487         rc = merge_blocks( fname, keyblock_orig, keyblock,
488                                 keyid, &n_uids, &n_sigs, &n_subk );
489         if( rc )
490             goto leave;
491         if( n_uids || n_sigs || n_subk ) {
492             mod_key = 1;
493             /* keyblock_orig has been updated; write */
494             if( (rc=lock_keyblock( &kbpos )) )
495                log_error( _("can't lock keyring `%s': %s\n"),
496                           keyblock_resource_name(&kbpos), gpg_errstr(rc) );
497             else if( (rc=update_keyblock( &kbpos, keyblock_orig )) )
498                 log_error( _("error writing keyring `%s': %s\n"),
499                              keyblock_resource_name(&kbpos), gpg_errstr(rc) );
500             unlock_keyblock( &kbpos );
501             /* we are ready */
502             if( !opt.quiet ) {
503                 if( n_uids == 1 )
504                     log_info( _("key %08lX: 1 new user ID\n"),
505                                              (ulong)keyid[1]);
506                 else if( n_uids )
507                     log_info( _("key %08lX: %d new user IDs\n"),
508                                              (ulong)keyid[1], n_uids );
509                 if( n_sigs == 1 )
510                     log_info( _("key %08lX: 1 new signature\n"),
511                                              (ulong)keyid[1]);
512                 else if( n_sigs )
513                     log_info( _("key %08lX: %d new signatures\n"),
514                                              (ulong)keyid[1], n_sigs );
515                 if( n_subk == 1 )
516                     log_info( _("key %08lX: 1 new subkey\n"),
517                                              (ulong)keyid[1]);
518                 else if( n_subk )
519                     log_info( _("key %08lX: %d new subkeys\n"),
520                                              (ulong)keyid[1], n_subk );
521             }
522
523             stats.n_uids +=n_uids;
524             stats.n_sigs +=n_sigs;
525             stats.n_subk +=n_subk;
526         }
527         else {
528             if( !opt.quiet )
529                 log_info( _("key %08lX: not changed\n"), (ulong)keyid[1] );
530             stats.unchanged++;
531         }
532     }
533     if( !rc && !fast ) {
534         rc = query_trust_record( new_key? pk : pk_orig );
535         if( rc && rc != -1 )
536             log_error("trustdb error: %s\n", gpg_errstr(rc) );
537         else if( rc == -1 ) { /* not found trustdb */
538             rc = insert_trust_record( new_key? keyblock : keyblock_orig );
539             if( rc )
540                 log_error("key %08lX: trustdb insert failed: %s\n",
541                                         (ulong)keyid[1], gpg_errstr(rc) );
542         }
543         else if( mod_key )
544             rc = update_trust_record( keyblock_orig, 1, NULL );
545         else
546             rc = clear_trust_checked_flag( new_key? pk : pk_orig );
547     }
548
549   leave:
550     release_kbnode( keyblock_orig );
551     free_public_key( pk_orig );
552     return rc;
553 }
554
555
556 /****************
557  * Ditto for secret keys.  Handling is simpler than for public keys.
558  */
559 static int
560 import_secret_one( const char *fname, KBNODE keyblock )
561 {
562     PKT_secret_key *sk;
563     KBNODE node, uidnode;
564     KBPOS kbpos;
565     u32 keyid[2];
566     int rc = 0;
567
568     /* get the key and print some info about it */
569     node = find_kbnode( keyblock, PKT_SECRET_KEY );
570     if( !node )
571         BUG();
572
573     sk = node->pkt->pkt.secret_key;
574     keyid_from_sk( sk, keyid );
575     uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
576
577     if( opt.verbose ) {
578         log_info( "sec  %4u%c/%08lX %s   ",
579                   nbits_from_sk( sk ),
580                   pubkey_letter( sk->pubkey_algo ),
581                   (ulong)keyid[1], datestr_from_sk(sk) );
582         if( uidnode )
583             print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
584                                        uidnode->pkt->pkt.user_id->len );
585         putc('\n', stderr);
586     }
587     stats.secret_read++;
588     if( !uidnode ) {
589         log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]);
590         return 0;
591     }
592
593     clear_kbnode_flags( keyblock );
594
595     /* do we have this key already in one of our secrings ? */
596     rc = seckey_available( keyid );
597     if( rc == GPGERR_NO_SECKEY && !opt.merge_only ) { /* simply insert this key */
598         /* get default resource */
599         if( get_keyblock_handle( NULL, 1, &kbpos ) ) {
600             log_error("no default secret keyring\n");
601             return GPGERR_GENERAL;
602         }
603         if( (rc=lock_keyblock( &kbpos )) )
604             log_error( _("can't lock keyring `%s': %s\n"),
605                          keyblock_resource_name(&kbpos), gpg_errstr(rc) );
606         else if( (rc=insert_keyblock( &kbpos, keyblock )) )
607             log_error( _("error writing keyring `%s': %s\n"),
608                       keyblock_resource_name(&kbpos), gpg_errstr(rc) );
609         unlock_keyblock( &kbpos );
610         /* we are ready */
611         if( !opt.quiet )
612             log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]);
613         stats.secret_imported++;
614     }
615     else if( !rc ) { /* we can't merge secret keys */
616         log_error( _("key %08lX: already in secret keyring\n"),
617                                                         (ulong)keyid[1]);
618         stats.secret_dups++;
619     }
620     else
621         log_error( _("key %08lX: secret key not found: %s\n"),
622                                 (ulong)keyid[1], gpg_errstr(rc));
623
624     return rc;
625 }
626
627
628 /****************
629  * Import a revocation certificate; this is a single signature packet.
630  */
631 static int
632 import_revoke_cert( const char *fname, KBNODE node )
633 {
634     PKT_public_key *pk=NULL;
635     KBNODE onode, keyblock = NULL;
636     KBPOS kbpos;
637     u32 keyid[2];
638     int rc = 0;
639
640     assert( !node->next );
641     assert( node->pkt->pkttype == PKT_SIGNATURE );
642     assert( node->pkt->pkt.signature->sig_class == 0x20 );
643
644     keyid[0] = node->pkt->pkt.signature->keyid[0];
645     keyid[1] = node->pkt->pkt.signature->keyid[1];
646
647     pk = gcry_xcalloc( 1, sizeof *pk );
648     rc = get_pubkey( pk, keyid );
649     if( rc == GPGERR_NO_PUBKEY ) {
650         log_info( _("key %08lX: no public key - "
651                  "can't apply revocation certificate\n"), (ulong)keyid[1]);
652         rc = 0;
653         goto leave;
654     }
655     else if( rc ) {
656         log_error( _("key %08lX: public key not found: %s\n"),
657                                        (ulong)keyid[1], gpg_errstr(rc));
658         goto leave;
659     }
660
661     /* read the original keyblock */
662     rc = find_keyblock_bypk( &kbpos, pk );
663     if( rc ) {
664         log_error( _("key %08lX: can't locate original keyblock: %s\n"),
665                                         (ulong)keyid[1], gpg_errstr(rc));
666         goto leave;
667     }
668     rc = read_keyblock( &kbpos, &keyblock );
669     if( rc ) {
670         log_error( _("key %08lX: can't read original keyblock: %s\n"),
671                                         (ulong)keyid[1], gpg_errstr(rc));
672         goto leave;
673     }
674
675
676     /* it is okay, that node is not in keyblock because
677      * check_key_signature works fine for sig_class 0x20 in this
678      * special case. */
679     rc = check_key_signature( keyblock, node, NULL);
680     if( rc ) {
681         log_error( _("key %08lX: invalid revocation certificate"
682                   ": %s - rejected\n"), (ulong)keyid[1], gpg_errstr(rc));
683     }
684
685
686     /* check whether we already have this */
687     for(onode=keyblock->next; onode; onode=onode->next ) {
688         if( onode->pkt->pkttype == PKT_USER_ID )
689             break;
690         else if( onode->pkt->pkttype == PKT_SIGNATURE
691                  && onode->pkt->pkt.signature->sig_class == 0x20
692                  && keyid[0] == onode->pkt->pkt.signature->keyid[0]
693                  && keyid[1] == onode->pkt->pkt.signature->keyid[1] ) {
694             rc = 0;
695             goto leave; /* yes, we already know about it */
696         }
697     }
698
699
700     /* insert it */
701     insert_kbnode( keyblock, clone_kbnode(node), 0 );
702
703     /* and write the keyblock back */
704     if( (rc=lock_keyblock( &kbpos )) )
705         log_error( _("can't lock keyring `%s': %s\n"),
706                    keyblock_resource_name(&kbpos), gpg_errstr(rc) );
707     else if( (rc=update_keyblock( &kbpos, keyblock )) )
708         log_error( _("error writing keyring `%s': %s\n"),
709                     keyblock_resource_name(&kbpos), gpg_errstr(rc) );
710     unlock_keyblock( &kbpos );
711     /* we are ready */
712     if( !opt.quiet )
713         log_info( _("key %08lX: revocation certificate imported\n"),
714                                         (ulong)keyid[1]);
715     stats.n_revoc++;
716     if( clear_trust_checked_flag( pk ) ) {
717         /* seems that we have to insert the record first */
718         rc = insert_trust_record( keyblock );
719         if( rc )
720             log_error("key %08lX: trustdb insert failed: %s\n",
721                                         (ulong)keyid[1], gpg_errstr(rc) );
722         else
723             rc = clear_trust_checked_flag( pk );
724     }
725
726   leave:
727     release_kbnode( keyblock );
728     free_public_key( pk );
729     return rc;
730 }
731
732
733 /****************
734  * loop over the keyblock and check all self signatures.
735  * Mark all user-ids with a self-signature by setting flag bit 0.
736  * Mark all user-ids with an invalid self-signature by setting bit 1.
737  * This works also for subkeys, here the subkey is marked.
738  */
739 static int
740 chk_self_sigs( const char *fname, KBNODE keyblock,
741                PKT_public_key *pk, u32 *keyid )
742 {
743     KBNODE n;
744     PKT_signature *sig;
745     int rc;
746
747     for( n=keyblock; (n = find_next_kbnode(n, 0)); ) {
748         if( n->pkt->pkttype != PKT_SIGNATURE )
749             continue;
750         sig = n->pkt->pkt.signature;
751         if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
752             if( (sig->sig_class&~3) == 0x10 ) {
753                 KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID );
754                 if( !unode )  {
755                     log_error( _("key %08lX: no user ID for signature\n"),
756                                             (ulong)keyid[1]);
757                     return -1;  /* the complete keyblock is invalid */
758                 }
759                 rc = check_key_signature( keyblock, n, NULL);
760                 if( rc ) {
761                     log_info( rc == GPGERR_PUBKEY_ALGO ?
762                          _("key %08lX: unsupported public key algorithm\n"):
763                          _("key %08lX: invalid self-signature\n"),
764                                      (ulong)keyid[1]);
765
766                     unode->flag |= 2; /* mark as invalid */
767                 }
768                 unode->flag |= 1; /* mark that signature checked */
769             }
770             else if( sig->sig_class == 0x18 ) {
771                 KBNODE knode = find_prev_kbnode( keyblock,
772                                                  n, PKT_PUBLIC_SUBKEY );
773                 if( !knode )
774                     knode = find_prev_kbnode( keyblock,
775                                                  n, PKT_SECRET_SUBKEY );
776
777                 if( !knode ) {
778                     log_info( _("key %08lX: no subkey for key binding\n"),
779                                             (ulong)keyid[1]);
780                     n->flag |= 4; /* delete this */
781                 }
782                 else {
783                     rc = check_key_signature( keyblock, n, NULL);
784                     if( rc ) {
785                         log_info(  rc == GPGERR_PUBKEY_ALGO ?
786                            _("key %08lX: unsupported public key algorithm\n"):
787                            _("key %08lX: invalid subkey binding\n"),
788                                          (ulong)keyid[1]);
789
790                         knode->flag |= 2; /* mark as invalid */
791                     }
792                     knode->flag |= 1; /* mark that signature checked */
793                 }
794             }
795         }
796     }
797     return 0;
798 }
799
800
801
802 /****************
803  * If a user ID has at least one signature, mark it as valid
804  */
805 static void
806 mark_non_selfsigned_uids_valid( KBNODE keyblock, u32 *kid )
807 {
808     KBNODE node;
809     for(node=keyblock->next; node; node = node->next ) {
810         if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) ) {
811             if( (node->next && node->next->pkt->pkttype == PKT_SIGNATURE)
812                 || !node->next ) {
813                 node->flag |= 1;
814                 log_info( _("key %08lX: accepted non self-signed user ID '"),
815                                                          (ulong)kid[1]);
816                 print_string( log_stream(), node->pkt->pkt.user_id->name,
817                                             node->pkt->pkt.user_id->len, 0 );
818                 fputs("'\n", log_stream() );
819             }
820         }
821     }
822 }
823
824 /****************
825  * delete all parts which are invalid and those signatures whose
826  * public key algorithm is not available in this implemenation;
827  * but consider RSA as valid, because parse/build_packets knows
828  * about it.
829  * returns: true if at least one valid user-id is left over.
830  */
831 static int
832 delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
833 {
834     KBNODE node;
835     int nvalid=0, uid_seen=0;
836     const char *p;
837
838     for(node=keyblock->next; node; node = node->next ) {
839         if( node->pkt->pkttype == PKT_USER_ID ) {
840             uid_seen = 1;
841             if( (node->flag & 2) || !(node->flag & 1) ) {
842                 if( opt.verbose ) {
843                     log_info( _("key %08lX: skipped user ID '"),
844                                                          (ulong)keyid[1]);
845                     print_utf8_string( stderr, node->pkt->pkt.user_id->name,
846                                        node->pkt->pkt.user_id->len );
847                     fputs("'\n", stderr );
848                 }
849                 delete_kbnode( node ); /* the user-id */
850                 /* and all following packets up to the next user-id */
851                 while( node->next
852                        && node->next->pkt->pkttype != PKT_USER_ID
853                        && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY
854                        && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ){
855                     delete_kbnode( node->next );
856                     node = node->next;
857                 }
858             }
859             else
860                 nvalid++;
861         }
862         else if(    node->pkt->pkttype == PKT_PUBLIC_SUBKEY
863                  || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
864             if( (node->flag & 2) || !(node->flag & 1) ) {
865                 if( opt.verbose ) {
866                     log_info( _("key %08lX: skipped subkey\n"),
867                                                          (ulong)keyid[1]);
868                 }
869                 delete_kbnode( node ); /* the subkey */
870                 /* and all following signature packets */
871                 while( node->next
872                        && node->next->pkt->pkttype == PKT_SIGNATURE ) {
873                     delete_kbnode( node->next );
874                     node = node->next;
875                 }
876             }
877         }
878         else if( node->pkt->pkttype == PKT_SIGNATURE
879                  && openpgp_pk_test_algo( node->pkt->pkt.signature->pubkey_algo, 0 )
880                  && node->pkt->pkt.signature->pubkey_algo != GCRY_PK_RSA )
881             delete_kbnode( node ); /* build_packet() can't handle this */
882         else if( node->pkt->pkttype == PKT_SIGNATURE
883                  && (p = parse_sig_subpkt2( node->pkt->pkt.signature,
884                                             SIGSUBPKT_EXPORTABLE, NULL ))
885                  && !*p
886                  && seckey_available( node->pkt->pkt.signature->keyid ) ) {
887             /* here we violate the rfc a bit by still allowing
888              * to import non-exportable signature when we have the
889              * the secret key used to create this signature - it
890              * seems that this makes sense */
891             log_info( _("key %08lX: non exportable signature "
892                                     "(class %02x) - skipped\n"),
893                                     (ulong)keyid[1],
894                                      node->pkt->pkt.signature->sig_class );
895             delete_kbnode( node );
896         }
897         else if( node->pkt->pkttype == PKT_SIGNATURE
898                  && node->pkt->pkt.signature->sig_class == 0x20 )  {
899             if( uid_seen ) {
900                 log_error( _("key %08lX: revocation certificate "
901                                      "at wrong place - skipped\n"),
902                                     (ulong)keyid[1]);
903                 delete_kbnode( node );
904             }
905             else {
906                 int rc = check_key_signature( keyblock, node, NULL);
907                 if( rc ) {
908                     log_error( _("key %08lX: invalid revocation "
909                               "certificate: %s - skipped\n"),
910                               (ulong)keyid[1], gpg_errstr(rc));
911                     delete_kbnode( node );
912                 }
913             }
914         }
915         else if( (node->flag & 4) ) /* marked for deletion */
916             delete_kbnode( node );
917     }
918
919     /* note: because keyblock is the public key, it is never marked
920      * for deletion and so keyblock cannot change */
921     commit_kbnode( &keyblock );
922     return nvalid;
923 }
924
925
926 /****************
927  * It may happen that the imported keyblock has duplicated user IDs.
928  * We check this here and collapse those user IDs together with their
929  * sigs into one.
930  * Returns: True if the keyblock hash changed.
931  */
932 int
933 collapse_uids( KBNODE *keyblock )
934 {
935     KBNODE n, n2;
936     int in_uid;
937     int any=0;
938     u32 kid1;
939
940   restart:
941     for( n = *keyblock; n; n = n->next ) {
942         if( n->pkt->pkttype != PKT_USER_ID )
943             continue;
944         for( n2 = n->next; n2; n2 = n2->next ) {
945             if( n2->pkt->pkttype == PKT_USER_ID
946                 && !cmp_user_ids( n->pkt->pkt.user_id,
947                                   n2->pkt->pkt.user_id ) ) {
948                 /* found a duplicate */
949                 any = 1;
950                 if( !n2->next
951                     || n2->next->pkt->pkttype == PKT_USER_ID
952                     || n2->next->pkt->pkttype == PKT_PUBLIC_SUBKEY
953                     || n2->next->pkt->pkttype == PKT_SECRET_SUBKEY  ) {
954                     /* no more signatures: delete the user ID
955                      * and start over */
956                     remove_kbnode( keyblock, n2 );
957                 }
958                 else {
959                     /* The simple approach: Move one signature and
960                      * then start over to delete the next one :-( */
961                     move_kbnode( keyblock, n2->next, n->next );
962                 }
963                 goto restart;
964             }
965         }
966     }
967     if( !any )
968         return 0;
969
970   restart_sig:
971     /* now we may have duplicate signatures on one user ID: fix this */
972     for( in_uid = 0, n = *keyblock; n; n = n->next ) {
973         if( n->pkt->pkttype == PKT_USER_ID )
974             in_uid = 1;
975         else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
976                  || n->pkt->pkttype == PKT_SECRET_SUBKEY )
977             in_uid = 0;
978         else if( in_uid ) {
979             n2 = n;
980             do {
981                 KBNODE ncmp = NULL;
982                 for( ; n2; n2 = n2->next ) {
983                     if(    n2->pkt->pkttype == PKT_USER_ID
984                         || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
985                         || n2->pkt->pkttype == PKT_SECRET_SUBKEY )
986                         break;
987                     if( n2->pkt->pkttype != PKT_SIGNATURE )
988                         ;
989                     else if( !ncmp )
990                         ncmp = n2;
991                     else if( !cmp_signatures( ncmp->pkt->pkt.signature,
992                                                 n2->pkt->pkt.signature )) {
993                         remove_kbnode( keyblock, n2 );
994                         goto restart_sig;
995                     }
996                 }
997                 n2 = ncmp? ncmp->next : NULL;
998             } while( n2 );
999         }
1000     }
1001
1002     if( (n = find_kbnode( *keyblock, PKT_PUBLIC_KEY )) )
1003         kid1 = keyid_from_pk( n->pkt->pkt.public_key, NULL );
1004     else if( (n = find_kbnode( *keyblock, PKT_SECRET_KEY )) )
1005         kid1 = keyid_from_sk( n->pkt->pkt.secret_key, NULL );
1006     else
1007         kid1 = 0;
1008     log_info(_("key %08lX: duplicated user ID detected - merged\n"),
1009                                                                  (ulong)kid1);
1010
1011     return 1;
1012 }
1013
1014
1015
1016 /****************
1017  * compare and merge the blocks
1018  *
1019  * o compare the signatures: If we already have this signature, check
1020  *   that they compare okay; if not, issue a warning and ask the user.
1021  * o Simply add the signature.  Can't verify here because we may not have
1022  *   the signature's public key yet; verification is done when putting it
1023  *   into the trustdb, which is done automagically as soon as this pubkey
1024  *   is used.
1025  * Note: We indicate newly inserted packets with flag bit 0
1026  */
1027 static int
1028 merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
1029               u32 *keyid, int *n_uids, int *n_sigs, int *n_subk )
1030 {
1031     KBNODE onode, node;
1032     int rc, found;
1033
1034     /* 1st: handle revocation certificates */
1035     for(node=keyblock->next; node; node=node->next ) {
1036         if( node->pkt->pkttype == PKT_USER_ID )
1037             break;
1038         else if( node->pkt->pkttype == PKT_SIGNATURE
1039                  && node->pkt->pkt.signature->sig_class == 0x20 )  {
1040             /* check whether we already have this */
1041             found = 0;
1042             for(onode=keyblock_orig->next; onode; onode=onode->next ) {
1043                 if( onode->pkt->pkttype == PKT_USER_ID )
1044                     break;
1045                 else if( onode->pkt->pkttype == PKT_SIGNATURE
1046                          && onode->pkt->pkt.signature->sig_class == 0x20
1047                          && node->pkt->pkt.signature->keyid[0]
1048                             == onode->pkt->pkt.signature->keyid[0]
1049                          && node->pkt->pkt.signature->keyid[1]
1050                             == onode->pkt->pkt.signature->keyid[1] ) {
1051                     found = 1;
1052                     break;
1053                 }
1054             }
1055             if( !found ) {
1056                 KBNODE n2 = clone_kbnode(node);
1057                 insert_kbnode( keyblock_orig, n2, 0 );
1058                 n2->flag |= 1;
1059                 log_info( _("key %08lX: revocation certificate added\n"),
1060                                          (ulong)keyid[1]);
1061             }
1062         }
1063     }
1064
1065     /* 2nd: try to merge new certificates in */
1066     for(onode=keyblock_orig->next; onode; onode=onode->next ) {
1067         if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) {
1068             /* find the user id in the imported keyblock */
1069             for(node=keyblock->next; node; node=node->next )
1070                 if( node->pkt->pkttype == PKT_USER_ID
1071                     && !cmp_user_ids( onode->pkt->pkt.user_id,
1072                                           node->pkt->pkt.user_id ) )
1073                     break;
1074             if( node ) { /* found: merge */
1075                 rc = merge_sigs( onode, node, n_sigs, fname, keyid );
1076                 if( rc )
1077                     return rc;
1078             }
1079         }
1080     }
1081
1082     /* 3rd: add new user-ids */
1083     for(node=keyblock->next; node; node=node->next ) {
1084         if( node->pkt->pkttype == PKT_USER_ID) {
1085             /* do we have this in the original keyblock */
1086             for(onode=keyblock_orig->next; onode; onode=onode->next )
1087                 if( onode->pkt->pkttype == PKT_USER_ID
1088                     && !cmp_user_ids( onode->pkt->pkt.user_id,
1089                                       node->pkt->pkt.user_id ) )
1090                     break;
1091             if( !onode ) { /* this is a new user id: append */
1092                 rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid);
1093                 if( rc )
1094                     return rc;
1095                 ++*n_uids;
1096             }
1097         }
1098     }
1099
1100     /*  add new subkeys */
1101     for(node=keyblock->next; node; node=node->next ) {
1102         onode = NULL;
1103         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
1104             /* do we have this in the original keyblock? */
1105             for(onode=keyblock_orig->next; onode; onode=onode->next )
1106                 if( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
1107                     && !cmp_public_keys( onode->pkt->pkt.public_key,
1108                                          node->pkt->pkt.public_key ) )
1109                     break;
1110             if( !onode ) { /* this is a new subkey: append */
1111                 rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
1112                 if( rc )
1113                     return rc;
1114                 ++*n_subk;
1115             }
1116         }
1117         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1118             /* do we have this in the original keyblock? */
1119             for(onode=keyblock_orig->next; onode; onode=onode->next )
1120                 if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
1121                     && !cmp_secret_keys( onode->pkt->pkt.secret_key,
1122                                          node->pkt->pkt.secret_key ) )
1123                     break;
1124             if( !onode ) { /* this is a new subkey: append */
1125                 rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
1126                 if( rc )
1127                     return rc;
1128                 ++*n_subk;
1129             }
1130         }
1131     }
1132
1133     /* merge subkey certificates */
1134     for(onode=keyblock_orig->next; onode; onode=onode->next ) {
1135         if( !(onode->flag & 1)
1136             &&  (   onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
1137                  || onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
1138             /* find the subkey in the imported keyblock */
1139             for(node=keyblock->next; node; node=node->next ) {
1140                 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1141                     && !cmp_public_keys( onode->pkt->pkt.public_key,
1142                                           node->pkt->pkt.public_key ) )
1143                     break;
1144                 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
1145                     && !cmp_secret_keys( onode->pkt->pkt.secret_key,
1146                                           node->pkt->pkt.secret_key ) )
1147                     break;
1148             }
1149             if( node ) { /* found: merge */
1150                 rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
1151                 if( rc )
1152                     return rc;
1153             }
1154         }
1155     }
1156
1157
1158     return 0;
1159 }
1160
1161
1162 /****************
1163  * append the userid starting with NODE and all signatures to KEYBLOCK.
1164  */
1165 static int
1166 append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
1167                                           const char *fname, u32 *keyid )
1168 {
1169     KBNODE n, n_where=NULL;
1170
1171     assert(node->pkt->pkttype == PKT_USER_ID );
1172     if( !node->next || node->next->pkt->pkttype == PKT_USER_ID ) {
1173         log_error( _("key %08lX: our copy has no self-signature\n"),
1174                                                   (ulong)keyid[1]);
1175         return GPGERR_GENERAL;
1176     }
1177
1178     /* find the position */
1179     for( n = keyblock; n; n_where = n, n = n->next ) {
1180         if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
1181             || n->pkt->pkttype == PKT_SECRET_SUBKEY )
1182             break;
1183     }
1184     if( !n )
1185         n_where = NULL;
1186
1187     /* and append/insert */
1188     while( node ) {
1189         /* we add a clone to the original keyblock, because this
1190          * one is released first */
1191         n = clone_kbnode(node);
1192         if( n_where ) {
1193             insert_kbnode( n_where, n, 0 );
1194             n_where = n;
1195         }
1196         else
1197             add_kbnode( keyblock, n );
1198         n->flag |= 1;
1199         node->flag |= 1;
1200         if( n->pkt->pkttype == PKT_SIGNATURE )
1201             ++*n_sigs;
1202
1203         node = node->next;
1204         if( node && node->pkt->pkttype != PKT_SIGNATURE )
1205             break;
1206     }
1207
1208     return 0;
1209 }
1210
1211
1212 /****************
1213  * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID.
1214  * (how should we handle comment packets here?)
1215  */
1216 static int
1217 merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
1218                                     const char *fname, u32 *keyid )
1219 {
1220     KBNODE n, n2;
1221     int found=0;
1222
1223     assert(dst->pkt->pkttype == PKT_USER_ID );
1224     assert(src->pkt->pkttype == PKT_USER_ID );
1225     if( !dst->next || dst->next->pkt->pkttype == PKT_USER_ID ) {
1226         log_error( _("key %08lX: our copy has no self-signature\n"),
1227                                                   (ulong)keyid[1]);
1228         return 0;
1229     }
1230
1231
1232     for(n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next ) {
1233         if( n->pkt->pkttype != PKT_SIGNATURE )
1234             continue;
1235         if( n->pkt->pkt.signature->sig_class == 0x18
1236             || n->pkt->pkt.signature->sig_class == 0x28 )
1237             continue; /* skip signatures which are only valid on subkeys */
1238         found = 0;
1239         for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next){
1240             if( n2->pkt->pkttype == PKT_SIGNATURE
1241                 && n->pkt->pkt.signature->keyid[0]
1242                    == n2->pkt->pkt.signature->keyid[0]
1243                 && n->pkt->pkt.signature->keyid[1]
1244                    == n2->pkt->pkt.signature->keyid[1]
1245                 && n->pkt->pkt.signature->timestamp
1246                    <= n2->pkt->pkt.signature->timestamp
1247                 && n->pkt->pkt.signature->sig_class
1248                    == n2->pkt->pkt.signature->sig_class ) {
1249                 found++;
1250                 break;
1251             }
1252         }
1253         if( !found ) {
1254             /* This signature is new or newer, append N to DST.
1255              * We add a clone to the original keyblock, because this
1256              * one is released first */
1257             n2 = clone_kbnode(n);
1258             insert_kbnode( dst, n2, PKT_SIGNATURE );
1259             n2->flag |= 1;
1260             n->flag |= 1;
1261             ++*n_sigs;
1262         }
1263     }
1264
1265     return 0;
1266 }
1267
1268 /****************
1269  * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
1270  */
1271 static int
1272 merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
1273                                     const char *fname, u32 *keyid )
1274 {
1275     KBNODE n, n2;
1276     int found=0;
1277
1278     assert(   dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
1279            || dst->pkt->pkttype == PKT_SECRET_SUBKEY );
1280
1281     for(n=src->next; n ; n = n->next ) {
1282         if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
1283             || n->pkt->pkttype == PKT_PUBLIC_KEY )
1284             break;
1285         if( n->pkt->pkttype != PKT_SIGNATURE )
1286             continue;
1287         found = 0;
1288         for(n2=dst->next; n2; n2 = n2->next){
1289             if( n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
1290                 || n2->pkt->pkttype == PKT_PUBLIC_KEY )
1291                 break;
1292             if( n2->pkt->pkttype == PKT_SIGNATURE
1293                 && n->pkt->pkt.signature->keyid[0]
1294                    == n2->pkt->pkt.signature->keyid[0]
1295                 && n->pkt->pkt.signature->keyid[1]
1296                    == n2->pkt->pkt.signature->keyid[1]
1297                 && n->pkt->pkt.signature->timestamp
1298                    <= n2->pkt->pkt.signature->timestamp
1299                 && n->pkt->pkt.signature->sig_class
1300                    == n2->pkt->pkt.signature->sig_class ) {
1301                 found++;
1302                 break;
1303             }
1304         }
1305         if( !found ) {
1306             /* This signature is new or newer, append N to DST.
1307              * We add a clone to the original keyblock, because this
1308              * one is released first */
1309             n2 = clone_kbnode(n);
1310             insert_kbnode( dst, n2, PKT_SIGNATURE );
1311             n2->flag |= 1;
1312             n->flag |= 1;
1313             ++*n_sigs;
1314         }
1315     }
1316
1317     return 0;
1318 }
1319
1320 /****************
1321  * append the subkey starting with NODE and all signatures to KEYBLOCK.
1322  * Mark all new and copied packets by setting flag bit 0.
1323  */
1324 static int
1325 append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
1326                                           const char *fname, u32 *keyid )
1327 {
1328     KBNODE n;
1329
1330     assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1331            || node->pkt->pkttype == PKT_SECRET_SUBKEY );
1332
1333     while(  node ) {
1334         /* we add a clone to the original keyblock, because this
1335          * one is released first */
1336         n = clone_kbnode(node);
1337         add_kbnode( keyblock, n );
1338         n->flag |= 1;
1339         node->flag |= 1;
1340         if( n->pkt->pkttype == PKT_SIGNATURE )
1341             ++*n_sigs;
1342
1343         node = node->next;
1344         if( node && node->pkt->pkttype != PKT_SIGNATURE )
1345             break;
1346     }
1347
1348     return 0;
1349 }
1350