release 0.2.14
[gnupg.git] / g10 / import.c
1 /* import.c
2  *      Copyright (C) 1998 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 "memory.h"
33 #include "util.h"
34 #include "trustdb.h"
35 #include "main.h"
36
37
38 static int read_block( IOBUF a, compress_filter_context_t *cfx,
39                              PACKET **pending_pkt, KBNODE *ret_root );
40 static int import_one( const char *fname, KBNODE keyblock );
41 static int import_revoke_cert( const char *fname, KBNODE node );
42 static int chk_self_sigs( const char *fname, KBNODE keyblock,
43                           PKT_public_cert *pkc, u32 *keyid );
44 static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid );
45 static int merge_blocks( const char *fname, KBNODE keyblock_orig,
46                        KBNODE keyblock, u32 *keyid, int *n_uids, int *n_sigs );
47 static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
48                              const char *fname, u32 *keyid );
49 static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
50                              const char *fname, u32 *keyid );
51
52
53 /****************
54  * Import the public keys from the given filename. Input may be armored.
55  * This function rejects alls keys which are not valid self signed on at
56  * least one userid. Only user ids which are self signed will be imported.
57  * Other signatures are not not checked.
58  *
59  * Actually this functtion does a merge. It works like this:
60  *
61  *  - get the keyblock
62  *  - check self-signatures and remove all userids and their signatures
63  *    without/invalid self-signatures.
64  *  - reject the keyblock, if we have no valid userid.
65  *  - See wether we have this key already in one of our pubrings.
66  *    If not, simply add it to the default keyring.
67  *  - Compare the key and the self-signatures of the new and the one in
68  *    our keyring.  If they are differen something weird is going on;
69  *    ask what to do.
70  *  - See wether we have only non-self-signature on one user id; if not
71  *    ask the user what to do.
72  *  - compare the signatures: If we already have this signature, check
73  *    that they compare okay; if not, issue a warning and ask the user.
74  *    (consider to look at the timestamp and use the newest?)
75  *  - Simply add the signature.  Can't verify here because we may not have
76  *    the signatures public key yet; verification is done when putting it
77  *    into the trustdb, which is done automagically as soon as this pubkey
78  *    is used.
79  *  - Proceed with next signature.
80  *
81  *  Key revocation certificates have a special handling.
82  *
83  */
84 int
85 import_pubkeys( const char *fname )
86 {
87     armor_filter_context_t afx;
88     compress_filter_context_t cfx;
89     PACKET *pending_pkt = NULL;
90     IOBUF inp = NULL;
91     KBNODE keyblock;
92     int rc = 0;
93
94     memset( &afx, 0, sizeof afx);
95     memset( &cfx, 0, sizeof cfx);
96
97     /* open file */
98     inp = iobuf_open(fname);
99     if( !fname )
100         fname = "[stdin]";
101     if( !inp ) {
102         log_error("%s: can't open file: %s\n", fname, strerror(errno) );
103         return G10ERR_OPEN_FILE;
104     }
105
106     if( !opt.no_armor ) /* armored reading is not diabled */
107         iobuf_push_filter( inp, armor_filter, &afx );
108
109     while( !(rc = read_block( inp, &cfx, &pending_pkt, &keyblock) )) {
110         if( keyblock->pkt->pkttype == PKT_PUBLIC_CERT )
111             rc = import_one( fname, keyblock );
112         else if( keyblock->pkt->pkttype == PKT_SIGNATURE
113                  && keyblock->pkt->pkt.signature->sig_class == 0x20 )
114             rc = import_revoke_cert( fname, keyblock );
115         else
116             log_info("%s: skipping block of type %d\n",
117                                             fname, keyblock->pkt->pkttype );
118         release_kbnode(keyblock);
119         if( rc )
120             break;
121     }
122     if( rc == -1 )
123         rc = 0;
124     else if( rc )
125         log_error("%s: read error: %s\n", fname, g10_errstr(rc));
126
127     iobuf_close(inp);
128     return rc;
129 }
130
131
132 /****************
133  * Read the next keyblock from stream A, CFX is used to handle
134  * compressed keyblocks. PENDING_PKT should be initialzed to NULL
135  * and not chnaged form the caller.
136  * Retunr: 0 = okay, -1 no more blocks or another errorcode.
137  */
138 static int
139 read_block( IOBUF a, compress_filter_context_t *cfx,
140             PACKET **pending_pkt, KBNODE *ret_root )
141 {
142     int rc;
143     PACKET *pkt;
144     KBNODE root = NULL;
145     int in_cert;
146
147     if( *pending_pkt ) {
148         root = new_kbnode( *pending_pkt );
149         *pending_pkt = NULL;
150         in_cert = 1;
151     }
152     else
153         in_cert = 0;
154     pkt = m_alloc( sizeof *pkt );
155     init_packet(pkt);
156     while( (rc=parse_packet(a, pkt)) != -1 ) {
157         if( rc ) {  /* ignore errors */
158             if( rc != G10ERR_UNKNOWN_PACKET ) {
159                 log_error("read_block: read error: %s\n", g10_errstr(rc) );
160                 rc = G10ERR_INV_KEYRING;
161                 goto ready;
162             }
163             free_packet( pkt );
164             init_packet(pkt);
165             continue;
166         }
167
168         if( !root && pkt->pkttype == PKT_SIGNATURE
169                   && pkt->pkt.signature->sig_class == 0x20 ) {
170             /* this is a revocation certificate which is handled
171              * in a special way */
172             root = new_kbnode( pkt );
173             pkt = NULL;
174             goto ready;
175         }
176
177         /* make a linked list of all packets */
178         switch( pkt->pkttype ) {
179           case PKT_COMPRESSED:
180             if( pkt->pkt.compressed->algorithm == 1 )
181                 cfx->pgpmode = 1;
182             else if( pkt->pkt.compressed->algorithm != 2  ){
183                 rc = G10ERR_COMPR_ALGO;
184                 goto ready;
185             }
186             pkt->pkt.compressed->buf = NULL;
187             iobuf_push_filter( a, compress_filter, cfx );
188             free_packet( pkt );
189             init_packet(pkt);
190             break;
191
192
193           case PKT_PUBLIC_CERT:
194           case PKT_SECRET_CERT:
195             if( in_cert ) { /* store this packet */
196                 *pending_pkt = pkt;
197                 pkt = NULL;
198                 goto ready;
199             }
200             in_cert = 1;
201           default:
202             if( in_cert ) {
203                 if( !root )
204                     root = new_kbnode( pkt );
205                 else
206                     add_kbnode( root, new_kbnode( pkt ) );
207                 pkt = m_alloc( sizeof *pkt );
208             }
209             init_packet(pkt);
210             break;
211         }
212     }
213   ready:
214     if( rc == -1 && root )
215         rc = 0;
216
217     if( rc )
218         release_kbnode( root );
219     else
220         *ret_root = root;
221     free_packet( pkt );
222     m_free( pkt );
223     return rc;
224 }
225
226
227 /****************
228  * Try to import one keyblock.  Return an error only in serious cases, but
229  * never for an invalid keyblock.  It uses log_error to increase the
230  * internal errorcount, so that invalid input can be detected by programs
231  * which called g10.
232  */
233 static int
234 import_one( const char *fname, KBNODE keyblock )
235 {
236     PKT_public_cert *pkc;
237     PKT_public_cert *pkc_orig;
238     KBNODE node, uidnode;
239     KBNODE keyblock_orig = NULL;
240     KBPOS kbpos;
241     u32 keyid[2];
242     int rc = 0;
243
244     /* get the key and print some infos about it */
245     node = find_kbnode( keyblock, PKT_PUBLIC_CERT );
246     if( !node ) {
247         log_error("%s: Oops; public key not found anymore!\n", fname);
248         return G10ERR_GENERAL; /* really serious */
249     }
250
251     pkc = node->pkt->pkt.public_cert;
252     keyid_from_pkc( pkc, keyid );
253     uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
254
255     if( opt.verbose ) {
256         log_info("%s: pub  %4u%c/%08lX %s   ", fname,
257                   nbits_from_pkc( pkc ),
258                   pubkey_letter( pkc->pubkey_algo ),
259                   (ulong)keyid[1], datestr_from_pkc(pkc) );
260         if( uidnode )
261             print_string( stderr, uidnode->pkt->pkt.user_id->name,
262                                   uidnode->pkt->pkt.user_id->len, 0 );
263         putc('\n', stderr);
264     }
265     if( !uidnode ) {
266         log_error("%s: No user id for key %08lX\n", fname, (ulong)keyid[1]);
267         return 0;
268     }
269
270     clear_kbnode_flags( keyblock );
271     rc = chk_self_sigs( fname, keyblock , pkc, keyid );
272     if( rc )
273         return rc== -1? 0:rc;
274
275     if( !delete_inv_parts( fname, keyblock, keyid ) ) {
276         log_info("%s: key %08lX, no valid user ids\n",
277                                                     fname, (ulong)keyid[1]);
278         return 0;
279     }
280
281     /* do we have this key already in one of our pubrings ? */
282     pkc_orig = m_alloc_clear( sizeof *pkc_orig );
283     rc = get_pubkey( pkc_orig, keyid );
284     if( rc && rc != G10ERR_NO_PUBKEY ) {
285         log_error("%s: key %08lX, public key not found: %s\n",
286                                 fname, (ulong)keyid[1], g10_errstr(rc));
287     }
288     else if( rc ) { /* insert this key */
289         /* get default resource */
290         if( get_keyblock_handle( NULL, 0, &kbpos ) ) {
291             log_error("no default public keyring\n");
292             return G10ERR_GENERAL;
293         }
294         if( opt.verbose > 1 )
295             log_info("%s: writing to '%s'\n",
296                                 fname, keyblock_resource_name(&kbpos) );
297         if( (rc=lock_keyblock( &kbpos )) )
298             log_error("can't lock public keyring '%s': %s\n",
299                              keyblock_resource_name(&kbpos), g10_errstr(rc) );
300         else if( (rc=insert_keyblock( &kbpos, keyblock )) )
301             log_error("%s: can't write to '%s': %s\n", fname,
302                              keyblock_resource_name(&kbpos), g10_errstr(rc) );
303         unlock_keyblock( &kbpos );
304         /* we are ready */
305         log_info("%s: key %08lX imported\n", fname, (ulong)keyid[1]);
306     }
307     else { /* merge */
308         int n_uids, n_sigs;
309
310         /* Compare the original against the new key; just to be sure nothing
311          * weird is going on */
312         if( cmp_public_certs( pkc_orig, pkc ) ) {
313             log_error("%s: key %08lX, doesn't match our copy\n",
314                                                     fname, (ulong)keyid[1]);
315             rc = G10ERR_GENERAL;
316             goto leave;
317         }
318
319         /* See wether we have only non-self-signature on one user id; if not
320          * ask the user what to do. <--- fixme */
321
322         /* now read the original keyblock */
323         rc = find_keyblock_bypkc( &kbpos, pkc_orig );
324         if( rc ) {
325             log_error("%s: key %08lX, can't locate original keyblock: %s\n",
326                                      fname, (ulong)keyid[1], g10_errstr(rc));
327             goto leave;
328         }
329         rc = read_keyblock( &kbpos, &keyblock_orig );
330         if( rc ) {
331             log_error("%s: key %08lX, can't read original keyblock: %s\n",
332                                      fname, (ulong)keyid[1], g10_errstr(rc));
333             goto leave;
334         }
335         /* and try to merge the block */
336         clear_kbnode_flags( keyblock_orig );
337         clear_kbnode_flags( keyblock );
338         n_uids = n_sigs = 0;
339         rc = merge_blocks( fname, keyblock_orig, keyblock,
340                                 keyid, &n_uids, &n_sigs );
341         if( rc )
342             goto leave;
343         if( n_uids || n_sigs ) { /* keyblock_orig has been updated; write */
344             if( opt.verbose > 1 )
345                 log_info("%s: writing to '%s'\n",
346                                     fname, keyblock_resource_name(&kbpos) );
347             if( (rc=lock_keyblock( &kbpos )) )
348                 log_error("can't lock public keyring '%s': %s\n",
349                                  keyblock_resource_name(&kbpos), g10_errstr(rc) );
350             else if( (rc=update_keyblock( &kbpos, keyblock )) )
351                 log_error("%s: can't write to '%s': %s\n", fname,
352                                  keyblock_resource_name(&kbpos), g10_errstr(rc) );
353             unlock_keyblock( &kbpos );
354             /* we are ready */
355             if( n_uids == 1 )
356                 log_info("%s: key %08lX, 1 new user-id\n",
357                                          fname, (ulong)keyid[1]);
358             else if( n_uids )
359                 log_info("%s: key %08lX, %d new user-ids\n",
360                                          fname, (ulong)keyid[1], n_uids );
361             if( n_sigs == 1 )
362                 log_info("%s: key %08lX, 1 new signature\n",
363                                          fname, (ulong)keyid[1]);
364             else if( n_sigs )
365                 log_info("%s: key %08lX, %d new signatures\n",
366                                          fname, (ulong)keyid[1], n_sigs );
367         }
368         else
369             log_info("%s: key %08lX, not changed\n", fname, (ulong)keyid[1] );
370     }
371
372   leave:
373     release_kbnode( keyblock_orig );
374     free_public_cert( pkc_orig );
375     return rc;
376 }
377
378
379 /****************
380  * Import a revocation certificate, this is a single signature packet.
381  */
382 static int
383 import_revoke_cert( const char *fname, KBNODE node )
384 {
385     PKT_public_cert *pkc=NULL;
386     KBNODE onode, keyblock = NULL;
387     KBPOS kbpos;
388     u32 keyid[2];
389     int rc = 0;
390
391     assert( !node->next );
392     assert( node->pkt->pkttype == PKT_SIGNATURE );
393     assert( node->pkt->pkt.signature->sig_class == 0x20 );
394
395     keyid[0] = node->pkt->pkt.signature->keyid[0];
396     keyid[1] = node->pkt->pkt.signature->keyid[1];
397
398     pkc = m_alloc_clear( sizeof *pkc );
399     rc = get_pubkey( pkc, keyid );
400     if( rc == G10ERR_NO_PUBKEY ) {
401         log_info("%s: key %08lX, no public key - "
402                  "can't apply revocation certificate\n",
403                                 fname, (ulong)keyid[1]);
404         rc = 0;
405         goto leave;
406     }
407     else if( rc ) {
408         log_error("%s: key %08lX, public key not found: %s\n",
409                                 fname, (ulong)keyid[1], g10_errstr(rc));
410         goto leave;
411     }
412
413     /* read the original keyblock */
414     rc = find_keyblock_bypkc( &kbpos, pkc );
415     if( rc ) {
416         log_error("%s: key %08lX, can't locate original keyblock: %s\n",
417                                  fname, (ulong)keyid[1], g10_errstr(rc));
418         goto leave;
419     }
420     rc = read_keyblock( &kbpos, &keyblock );
421     if( rc ) {
422         log_error("%s: key %08lX, can't read original keyblock: %s\n",
423                                  fname, (ulong)keyid[1], g10_errstr(rc));
424         goto leave;
425     }
426
427
428     /* it is okay, that node is not in keyblock because
429      * check_key_signature works fine for sig_class 0x20 in this
430      * special case. */
431     rc = check_key_signature( keyblock, node, NULL);
432     if( rc ) {
433         log_error("%s: key %08lX, invalid revocation certificate"
434                   ": %s - rejected\n",
435                   fname, (ulong)keyid[1], g10_errstr(rc));
436     }
437
438
439     /* check wether we already have this */
440     for(onode=keyblock->next; onode; onode=onode->next ) {
441         if( onode->pkt->pkttype == PKT_USER_ID )
442             break;
443         else if( onode->pkt->pkttype == PKT_SIGNATURE
444                  && onode->pkt->pkt.signature->sig_class == 0x20
445                  && keyid[0] == onode->pkt->pkt.signature->keyid[0]
446                  && keyid[1] == onode->pkt->pkt.signature->keyid[1] ) {
447             rc = 0;
448             goto leave; /* yes, we already know about it */
449         }
450     }
451
452
453     /* insert it */
454     insert_kbnode( keyblock, clone_kbnode(node), 0 );
455
456     /* and write the keyblock back */
457     if( opt.verbose > 1 )
458         log_info("%s: writing to '%s'\n",
459                             fname, keyblock_resource_name(&kbpos) );
460     if( (rc=lock_keyblock( &kbpos )) )
461         log_error("can't lock public keyring '%s': %s\n",
462                          keyblock_resource_name(&kbpos), g10_errstr(rc) );
463     else if( (rc=update_keyblock( &kbpos, keyblock )) )
464         log_error("%s: can't write to '%s': %s\n", fname,
465                          keyblock_resource_name(&kbpos), g10_errstr(rc) );
466     unlock_keyblock( &kbpos );
467     /* we are ready */
468     log_info("%s: key %08lX, added revocation certificate\n",
469                                  fname, (ulong)keyid[1]);
470
471   leave:
472     release_kbnode( keyblock );
473     free_public_cert( pkc );
474     return rc;
475 }
476
477
478 /****************
479  * loop over the keyblock an check all self signatures.
480  * Mark all user-ids with a self-signature by setting flag bit 0.
481  * Mark all user-ids with an invalid self-signature by setting bit 1.
482  */
483 static int
484 chk_self_sigs( const char *fname, KBNODE keyblock,
485                PKT_public_cert *pkc, u32 *keyid )
486 {
487     KBNODE n, unode;
488     PKT_signature *sig;
489     int rc;
490
491     for( n=keyblock; (n = find_next_kbnode(n, 0)); ) {
492         if( n->pkt->pkttype != PKT_SIGNATURE )
493             continue;
494         sig = n->pkt->pkt.signature;
495         if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
496             unode = find_prev_kbnode( keyblock, n, PKT_USER_ID );
497             if( !unode )  {
498                 log_error("%s: key %08lX, no user-id for signature\n",
499                                         fname, (ulong)keyid[1]);
500                 return -1;  /* the complete keyblock is invalid */
501             }
502             rc = check_key_signature( keyblock, n, NULL);
503             if( rc ) {
504                 log_error("%s: key %08lX, invalid self-signature\n",
505                                         fname, (ulong)keyid[1]);
506                 unode->flag |= 2; /* mark as invalid */
507             }
508             unode->flag |= 1; /* mark that user-id checked */
509         }
510     }
511     return 0;
512 }
513
514 /****************
515  * delete all parts which are invalidand those signatures whos
516  * public key algorithm is not availabe in this implemenation;
517  * but consider RSA as valid, because parse/build_packets knows
518  * about it.
519  * returns: true if at least one valid user-id is left over.
520  */
521 static int
522 delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
523 {
524     KBNODE node;
525     int nvalid=0, uid_seen=0;
526
527     for(node=keyblock->next; node; node = node->next ) {
528         if( node->pkt->pkttype == PKT_USER_ID ) {
529             uid_seen = 1;
530             if( (node->flag & 2) || !(node->flag & 1) ) {
531                 if( opt.verbose ) {
532                     log_info("%s: key %08lX, removed userid '",
533                                                   fname, (ulong)keyid[1]);
534                     print_string( stderr, node->pkt->pkt.user_id->name,
535                                       node->pkt->pkt.user_id->len, 0 );
536                     fputs("'\n", stderr );
537                 }
538                 delete_kbnode( node ); /* the user-id */
539                 /* and all following packets up to the next user-id */
540                 while( node->next && node->next->pkt->pkttype != PKT_USER_ID ){
541                     delete_kbnode( node->next );
542                     node = node->next;
543                 }
544             }
545             else
546                 nvalid++;
547         }
548         else if( node->pkt->pkttype == PKT_SIGNATURE
549                  && check_pubkey_algo( node->pkt->pkt.signature->pubkey_algo)
550                  && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA )
551             delete_kbnode( node ); /* build_packet() can't handle this */
552         else if( node->pkt->pkttype == PKT_SIGNATURE
553                  && node->pkt->pkt.signature->sig_class == 0x20 )  {
554             if( uid_seen ) {
555                 log_error("%s: key %08lX, revocation certificate at wrong "
556                            "place - removed\n", fname, (ulong)keyid[1]);
557                 delete_kbnode( node );
558             }
559             else {
560                 int rc = check_key_signature( keyblock, node, NULL);
561                 if( rc ) {
562                     log_error("%s: key %08lX, invalid revocation certificate"
563                               ": %s - removed\n",
564                               fname, (ulong)keyid[1], g10_errstr(rc));
565                     delete_kbnode( node );
566                 }
567             }
568         }
569     }
570
571     /* note: because keyblock is the public key, it is never marked
572      * for deletion and so keyblock cannot change */
573     commit_kbnode( &keyblock );
574     return nvalid;
575 }
576
577
578 /****************
579  * compare and merge the blocks
580  *
581  * o compare the signatures: If we already have this signature, check
582  *   that they compare okay; if not, issue a warning and ask the user.
583  *   FIXME: add the check, that we don't have duplicate signatures and the
584  *   warning in cases that the old/new signatures don't match.
585  * o Simply add the signature.  Can't verify here because we may not have
586  *   the signatures public key yet; verification is done when putting it
587  *   into the trustdb, which is done automagically as soon as this pubkey
588  *   is used.
589  * Note: We indicate newly inserted packets with flag bit 0
590  */
591 static int
592 merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
593                                    u32 *keyid, int *n_uids, int *n_sigs )
594 {
595     KBNODE onode, node;
596     int rc, found;
597
598     /* 1st: handle revocation certificates */
599     for(node=keyblock->next; node; node=node->next ) {
600         if( node->pkt->pkttype == PKT_USER_ID )
601             break;
602         else if( node->pkt->pkttype == PKT_SIGNATURE
603                  && node->pkt->pkt.signature->sig_class == 0x20 )  {
604             /* check wether we already have this */
605             found = 0;
606             for(onode=keyblock_orig->next; onode; onode=onode->next ) {
607                 if( onode->pkt->pkttype == PKT_USER_ID )
608                     break;
609                 else if( onode->pkt->pkttype == PKT_SIGNATURE
610                          && onode->pkt->pkt.signature->sig_class == 0x20
611                          && node->pkt->pkt.signature->keyid[0]
612                             == onode->pkt->pkt.signature->keyid[0]
613                          && node->pkt->pkt.signature->keyid[1]
614                             == onode->pkt->pkt.signature->keyid[1] ) {
615                     found = 1;
616                     break;
617                 }
618             }
619             if( !found ) {
620                 KBNODE n2 = clone_kbnode(node);
621                 insert_kbnode( keyblock_orig, n2, 0 );
622                 n2->flag |= 1;
623                 node->flag |= 1;
624                 log_info("%s: key %08lX, added revocation certificate\n",
625                                          fname, (ulong)keyid[1]);
626             }
627         }
628     }
629
630     /* 2nd: try to merge new ones in */
631     for(onode=keyblock_orig->next; onode; onode=onode->next ) {
632         if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) {
633             /* find the user id in the imported keyblock */
634             for(node=keyblock->next; node; node=node->next )
635                 if( !(node->flag & 1)
636                     && node->pkt->pkttype == PKT_USER_ID
637                     && !cmp_user_ids( onode->pkt->pkt.user_id,
638                                           node->pkt->pkt.user_id ) )
639                     break;
640             if( node ) { /* found: merge */
641                 rc = merge_sigs( onode, node, n_sigs, fname, keyid );
642                 if( rc )
643                     return rc;
644             }
645         }
646     }
647
648     /* 3rd: add new user-ids */
649     for(node=keyblock->next; node; node=node->next ) {
650         if( !(node->flag & 1) && node->pkt->pkttype == PKT_USER_ID) {
651             /* do we have this in the original keyblock */
652             for(onode=keyblock_orig->next; onode; onode=onode->next )
653                 if( !(onode->flag & 1)
654                     && onode->pkt->pkttype == PKT_USER_ID
655                     && cmp_user_ids( onode->pkt->pkt.user_id,
656                                      node->pkt->pkt.user_id ) )
657                     break;
658             if( !node ) { /* this is a new user id: append */
659                 rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid);
660                 if( rc )
661                     return rc;
662                 ++*n_uids;
663             }
664         }
665     }
666
667     return 0;
668 }
669
670
671 /****************
672  * append the userid starting with NODE and all signatures to KEYBLOCK.
673  * Mark all new and copied packets by setting flag bit 0.
674  */
675 static int
676 append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
677                                           const char *fname, u32 *keyid )
678 {
679     KBNODE n;
680
681     assert(node->pkt->pkttype == PKT_USER_ID );
682     /* at lease a self signature comes next to the user-id */
683     if( node->next->pkt->pkttype == PKT_USER_ID ) {
684         log_error("%s: key %08lX, our copy has no self-signature\n",
685                                                   fname, (ulong)keyid[1]);
686         return G10ERR_GENERAL;
687     }
688
689     for( ;node && node->pkt->pkttype != PKT_USER_ID; node = node->next ) {
690         /* we add a clone to the original keyblock, because this
691          * one is released first */
692         n = clone_kbnode(node);
693         add_kbnode( keyblock, n );
694         node->flag |= 1;
695         n->flag |= 1;
696         if( n->pkt->pkttype == PKT_SIGNATURE )
697             ++*n_sigs;
698     }
699
700     return 0;
701 }
702
703
704 /****************
705  * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID.
706  * (how should we handle comment packets here?)
707  */
708 static int
709 merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
710                                     const char *fname, u32 *keyid )
711 {
712     KBNODE n, n2;
713     int found=0;
714
715     assert(dst->pkt->pkttype == PKT_USER_ID );
716     assert(src->pkt->pkttype == PKT_USER_ID );
717     /* at least a self signature comes next to the user-ids */
718     assert(src->next->pkt->pkttype != PKT_USER_ID );
719     if( dst->next->pkt->pkttype == PKT_USER_ID ) {
720         log_error("%s: key %08lX, our copy has no self-signature\n",
721                                                   fname, (ulong)keyid[1]);
722         return 0;
723     }
724
725
726     for(n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next ) {
727         if( n->pkt->pkttype != PKT_SIGNATURE )
728             continue;
729         found = 0;
730         for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next)
731             if( n2->pkt->pkttype == PKT_SIGNATURE
732                 && n->pkt->pkt.signature->keyid[0]
733                    == n2->pkt->pkt.signature->keyid[0]
734                 && n->pkt->pkt.signature->keyid[1]
735                    == n2->pkt->pkt.signature->keyid[1] ) {
736             found++;
737             break;
738         }
739
740         if( found ) { /* we already have this signature */
741             /* Hmmm: should we compare the timestamp etc?
742              * but then we have first to see wether this signature is valid
743              * - or - simply add it in such a case and let trustdb logic
744              * decide wether to remove the old one
745              */
746             continue;
747         }
748
749         /* This signature is new, append N to DST it.
750          * We add a clone to the original keyblock, because this
751          * one is released first */
752         n2 = clone_kbnode(n);
753         insert_kbnode( dst, n2, PKT_USER_ID );
754         n2->flag |= 1;
755         n->flag |= 1;
756         ++*n_sigs;
757     }
758
759     return 0;
760 }
761