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