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