intermediate release
[gnupg.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
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 "iobuf.h"
32 #include "keydb.h"
33 #include "memory.h"
34 #include "util.h"
35 #include "main.h"
36 #include "filter.h"
37 #include "ttyio.h"
38 #include "i18n.h"
39
40
41
42 static void
43 show_fingerprint( PKT_public_key *pk )
44 {
45     byte *array, *p;
46     size_t i, n;
47
48     p = array = fingerprint_from_pk( pk, &n );
49     tty_printf("             Fingerprint:");
50     if( n == 20 ) {
51         for(i=0; i < n ; i++, i++, p += 2 ) {
52             if( i == 10 )
53                 tty_printf(" ");
54             tty_printf(" %02X%02X", *p, p[1] );
55         }
56     }
57     else {
58         for(i=0; i < n ; i++, p++ ) {
59             if( i && !(i%8) )
60                 tty_printf(" ");
61             tty_printf(" %02X", *p );
62         }
63     }
64     tty_printf("\n");
65     m_free(array);
66 }
67
68
69 /****************
70  * Ask whether the user is willing to sign the key. Return true if so.
71  */
72 static int
73 sign_it_p( PKT_public_key *pk, PKT_user_id *uid )
74 {
75     char *answer;
76     int yes;
77
78     tty_printf("\n");
79     tty_printf(_("Are you really sure that you want to sign this key:\n\n"));
80     tty_printf("pub  %4u%c/%08lX %s ",
81               nbits_from_pk( pk ),
82               pubkey_letter( pk->pubkey_algo ),
83               (ulong)keyid_from_pk( pk, NULL ),
84               datestr_from_pk( pk )               );
85     tty_print_string( uid->name, uid->len );
86     tty_printf("\n");
87     show_fingerprint(pk);
88     tty_printf("\n");
89     answer = tty_get(_("Sign this key? "));
90     tty_kill_prompt();
91     yes = answer_is_yes(answer);
92     m_free(answer);
93     return yes;
94 }
95
96
97 /****************
98  * Check the keysigs and set the flags to indicate errors.
99  * Usage of nodes flag bits:
100  * Bit  0 = bad signature
101  *      1 = no public key
102  *      2 = other error
103  * Returns true if error found.
104  */
105 static int
106 check_all_keysigs( KBNODE keyblock )
107 {
108     KBNODE kbctx;
109     KBNODE node;
110     int rc;
111     int inv_sigs = 0;
112     int no_key = 0;
113     int oth_err = 0;
114
115     for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
116         if( node->pkt->pkttype == PKT_SIGNATURE
117             && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
118             PKT_signature *sig = node->pkt->pkt.signature;
119             int sigrc;
120
121             tty_printf("sig");
122             switch( (rc = check_key_signature( keyblock, node,NULL)) ) {
123               case 0:                node->flag = 0; sigrc = '!'; break;
124               case G10ERR_BAD_SIGN:  inv_sigs++; node->flag = 1; sigrc = '-'; break;
125               case G10ERR_NO_PUBKEY: no_key++;   node->flag = 2; sigrc = '?'; break;
126               default:               oth_err++;  node->flag = 4; sigrc = '%'; break;
127             }
128             tty_printf("%c       %08lX %s   ",
129                     sigrc, sig->keyid[1], datestr_from_sig(sig));
130             if( sigrc == '%' )
131                 tty_printf("[%s] ", g10_errstr(rc) );
132             else if( sigrc == '?' )
133                 ;
134             else {
135                 size_t n;
136                 char *p = get_user_id( sig->keyid, &n );
137                 tty_print_string( p, n > 40? 40 : n );
138                 m_free(p);
139             }
140             tty_printf("\n");
141             /* FIXME: update the trustdb */
142         }
143     }
144     if( inv_sigs )
145         tty_printf(_("%d bad signatures\n"), inv_sigs );
146     if( no_key )
147         tty_printf(_("No public key for %d signatures\n"), no_key );
148     if( oth_err )
149         tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
150     return inv_sigs || no_key || oth_err;
151 }
152
153
154 /****************
155  * Ask and remove invalid signatures that are to be removed.
156  */
157 static int
158 remove_keysigs( KBNODE keyblock, u32 *keyid, int all )
159 {
160     KBNODE kbctx;
161     KBNODE node;
162     char *answer;
163     int yes;
164     int count;
165
166     count = 0;
167     for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
168         if( ((node->flag & 7) || all )
169             && node->pkt->pkttype == PKT_SIGNATURE
170             && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
171             PKT_signature *sig = node->pkt->pkt.signature;
172
173             tty_printf("\n \"%08lX %s   ",
174                         sig->keyid[1], datestr_from_sig(sig));
175             if( node->flag & 6 )
176                 tty_printf(_("[User name not available] "));
177             else {
178                 size_t n;
179                 char *p = get_user_id( sig->keyid, &n );
180                 tty_print_string( p, n );
181                 m_free(p);
182             }
183             tty_printf("\"\n");
184             if( node->flag & 1 )
185                 tty_printf(_("This is a BAD signature!\n"));
186             else if( node->flag & 2 )
187                 tty_printf(_("Public key not available.\n"));
188             else if( node->flag & 4 )
189                 tty_printf(_("The signature could not be checked!\n"));
190
191             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
192                 tty_printf(_("Skipped self-signature\n"));
193                 continue; /* do not remove self-signatures */
194             }
195
196             tty_printf("\n");
197             answer = tty_get(_("Remove this signature? "));
198             tty_kill_prompt();
199             if( answer_is_yes(answer) ) {
200                 node->flag |= 128;     /* use bit 7 to mark this node */
201                 count++;
202             }
203             m_free(answer);
204         }
205     }
206
207     if( !count )
208         return 0; /* nothing to remove */
209     answer = tty_get(_("Do you really want to remove the selected signatures? "));
210     tty_kill_prompt();
211     yes = answer_is_yes(answer);
212     m_free(answer);
213     if( !yes )
214         return 0;
215
216     for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 1)) ; ) {
217         if( node->flag & 128)
218             delete_kbnode(node );
219     }
220
221     return 1;
222 }
223
224
225 /****************
226  * This function signs the key of USERNAME with all users listed in
227  * LOCUSR. If LOCUSR is NULL the default secret certificate will
228  * be used.  This works on all keyrings, so there is no armor or
229  * compress stuff here.
230  */
231 int
232 sign_key( const char *username, STRLIST locusr )
233 {
234     md_filter_context_t mfx;
235     int rc = 0;
236     SK_LIST sk_list = NULL;
237     SK_LIST sk_rover = NULL;
238     KBNODE keyblock = NULL;
239     KBNODE kbctx, node;
240     KBPOS kbpos;
241     PKT_public_key *pk;
242     u32 pk_keyid[2];
243     char *answer;
244
245     memset( &mfx, 0, sizeof mfx);
246
247     /* search the userid */
248     rc = find_keyblock_byname( &kbpos, username );
249     if( rc ) {
250         log_error(_("%s: user not found\n"), username );
251         goto leave;
252     }
253
254     /* build a list of all signators */
255     rc=build_sk_list( locusr, &sk_list, 0, 1 );
256     if( rc )
257         goto leave;
258
259
260     /* read the keyblock */
261     rc = read_keyblock( &kbpos, &keyblock );
262     if( rc ) {
263         log_error("error reading the certificate: %s\n", g10_errstr(rc) );
264         goto leave;
265     }
266
267     /* get the keyid from the keyblock */
268     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
269     if( !node ) {
270         log_error("Oops; public key not found anymore!\n");
271         rc = G10ERR_GENERAL;
272         goto leave;
273     }
274
275     pk = node->pkt->pkt.public_key;
276     keyid_from_pk( pk, pk_keyid );
277     tty_printf(_("Checking signatures of this public key certificate:\n"));
278     tty_printf("pub  %4u%c/%08lX %s   ",
279               nbits_from_pk( pk ),
280               pubkey_letter( pk->pubkey_algo ),
281               pk_keyid[1], datestr_from_pk(pk) );
282     {
283         size_t n;
284         char *p = get_user_id( pk_keyid, &n );
285         tty_print_string( p, n > 40? 40 : n );
286         m_free(p);
287         tty_printf("\n");
288     }
289
290     clear_kbnode_flags( keyblock );
291     if( check_all_keysigs( keyblock ) ) {
292         if( !opt.batch ) {
293             /* ask whether we really should do anything */
294             answer = tty_get(
295                         _("To you want to remove some of the invalid sigs? "));
296             tty_kill_prompt();
297             if( answer_is_yes(answer) )
298                 remove_keysigs( keyblock, pk_keyid, 0 );
299             m_free(answer);
300         }
301     }
302
303     /* check whether we it is possible to sign this key */
304     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
305         u32 akeyid[2];
306
307         keyid_from_sk( sk_rover->sk, akeyid );
308         for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
309             if( node->pkt->pkttype == PKT_USER_ID )
310                 sk_rover->mark = 1;
311             else if( node->pkt->pkttype == PKT_SIGNATURE
312                 && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
313                 if( akeyid[0] == node->pkt->pkt.signature->keyid[0]
314                     && akeyid[1] == node->pkt->pkt.signature->keyid[1] ) {
315                     log_info(_("Already signed by keyid %08lX\n"),
316                                                         (ulong)akeyid[1] );
317                     sk_rover->mark = 0;
318                 }
319             }
320         }
321     }
322     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
323         if( sk_rover->mark )
324             break;
325     }
326     if( !sk_rover ) {
327         log_info(_("Nothing to sign\n"));
328         goto leave;
329     }
330
331     /* Loop over all signers and all user ids and sign */
332     /* FIXME: we have to change it: Present all user-ids and
333      * then ask whether all those ids shall be signed if the user
334      * answers yes, go and make a 0x14 sign class packet and remove
335      * old one-user-id-only-sigs (user should be noted of this
336      * condition while presenting the user-ids); if he had answered
337      * no, present each user-id in turn and ask which one should be signed
338      * (only one) - if there is already a single-user-sig, do nothing.
339      * (this is propably already out in the world) */
340     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
341         if( !sk_rover->mark )
342             continue;
343         for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
344             if( node->pkt->pkttype == PKT_USER_ID ) {
345                 if( sign_it_p( pk, node->pkt->pkt.user_id ) ) {
346                     PACKET *pkt;
347                     PKT_signature *sig;
348
349                     rc = make_keysig_packet( &sig, pk,
350                                                    node->pkt->pkt.user_id,
351                                                    NULL,
352                                                    sk_rover->sk,
353                                                    0x10, 0, NULL, NULL );
354                     if( rc ) {
355                         log_error("make_keysig_packet failed: %s\n", g10_errstr(rc));
356                         goto leave;
357                     }
358
359                     pkt = m_alloc_clear( sizeof *pkt );
360                     pkt->pkttype = PKT_SIGNATURE;
361                     pkt->pkt.signature = sig;
362                     insert_kbnode( node, new_kbnode(pkt), PKT_USER_ID );
363                 }
364             }
365         }
366     }
367
368     rc = update_keyblock( &kbpos, keyblock );
369     if( rc ) {
370         log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
371         goto leave;
372     }
373
374   leave:
375     release_kbnode( keyblock );
376     release_sk_list( sk_list );
377     md_close( mfx.md );
378     return rc;
379 }
380
381
382
383 int
384 edit_keysigs( const char *username )
385 {
386     int rc = 0;
387     KBNODE keyblock = NULL;
388     KBNODE node;
389     KBPOS kbpos;
390     PKT_public_key *pk;
391     u32 pk_keyid[2];
392
393     /* search the userid */
394     rc = find_keyblock_byname( &kbpos, username );
395     if( rc ) {
396         log_error(_("%s: user not found\n"), username );
397         goto leave;
398     }
399
400     /* read the keyblock */
401     rc = read_keyblock( &kbpos, &keyblock );
402     if( rc ) {
403         log_error("%s: certificate read problem: %s\n", username, g10_errstr(rc) );
404         goto leave;
405     }
406
407     /* get the keyid from the keyblock */
408     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
409     if( !node ) {
410         log_error("Oops; public key not found anymore!\n");
411         rc = G10ERR_GENERAL;
412         goto leave;
413     }
414
415     pk = node->pkt->pkt.public_key;
416     keyid_from_pk( pk, pk_keyid );
417     tty_printf(_("Checking signatures of this public key certificate:\n"));
418     tty_printf("pub  %4u%c/%08lX %s   ",
419               nbits_from_pk( pk ),
420               pubkey_letter( pk->pubkey_algo ),
421               pk_keyid[1], datestr_from_pk(pk) );
422     {
423         size_t n;
424         char *p = get_user_id( pk_keyid, &n );
425         tty_print_string( p, n > 40? 40 : n );
426         m_free(p);
427         tty_printf("\n");
428     }
429
430     clear_kbnode_flags( keyblock );
431     check_all_keysigs( keyblock );
432     if( remove_keysigs( keyblock, pk_keyid, 1 ) ) {
433         rc = update_keyblock( &kbpos, keyblock );
434         if( rc ) {
435             log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
436             goto leave;
437         }
438     }
439
440   leave:
441     release_kbnode( keyblock );
442     return rc;
443 }
444
445
446 /****************
447  * Delete a public or secret key from a keyring.
448  */
449 int
450 delete_key( const char *username, int secret )
451 {
452     int rc = 0;
453     KBNODE keyblock = NULL;
454     KBNODE node;
455     KBPOS kbpos;
456     PKT_public_key *pk = NULL;
457     PKT_secret_key *sk = NULL;
458     u32 keyid[2];
459     int okay=0;
460
461     /* search the userid */
462     rc = secret? find_secret_keyblock_byname( &kbpos, username )
463                : find_keyblock_byname( &kbpos, username );
464     if( rc ) {
465         log_error(_("%s: user not found\n"), username );
466         goto leave;
467     }
468
469     /* read the keyblock */
470     rc = read_keyblock( &kbpos, &keyblock );
471     if( rc ) {
472         log_error("%s: read problem: %s\n", username, g10_errstr(rc) );
473         goto leave;
474     }
475
476     /* get the keyid from the keyblock */
477     node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
478     if( !node ) {
479         log_error("Oops; key not found anymore!\n");
480         rc = G10ERR_GENERAL;
481         goto leave;
482     }
483
484     if( secret ) {
485         sk = node->pkt->pkt.secret_key;
486         keyid_from_sk( sk, keyid );
487     }
488     else {
489         pk = node->pkt->pkt.public_key;
490         keyid_from_pk( pk, keyid );
491         rc = seckey_available( keyid );
492         if( !rc ) {
493             log_error(_(
494             "there is a secret key for this public key!\n"));
495             log_info(_(
496             "use option \"--delete-secret-key\" to delete it first.\n"));
497             rc = -1;
498         }
499         else if( rc != G10ERR_NO_SECKEY )
500             log_error("%s: get secret key: %s\n", username, g10_errstr(rc) );
501         else
502             rc = 0;
503     }
504
505     if( rc )
506         rc = 0;
507     else if( opt.batch && secret )
508         log_error(_("can't do that in batch-mode\n"));
509     else if( opt.batch && opt.answer_yes )
510         okay++;
511     else if( opt.batch )
512         log_error(_("can't do that in batch-mode without \"--yes\"\n"));
513     else {
514         char *p;
515         size_t n;
516
517         if( secret )
518             tty_printf("sec  %4u%c/%08lX %s   ",
519                       nbits_from_sk( sk ),
520                       pubkey_letter( sk->pubkey_algo ),
521                       keyid[1], datestr_from_sk(sk) );
522         else
523             tty_printf("pub  %4u%c/%08lX %s   ",
524                       nbits_from_pk( pk ),
525                       pubkey_letter( pk->pubkey_algo ),
526                       keyid[1], datestr_from_pk(pk) );
527         p = get_user_id( keyid, &n );
528         tty_print_string( p, n );
529         m_free(p);
530         tty_printf("\n\n");
531
532         p = tty_get(_("Delete this key from the keyring? "));
533         tty_kill_prompt();
534         if( secret && answer_is_yes(p)) {
535             /* I think it is not required to check a passphrase; if
536              * the user is so stupid as to let others access his secret keyring
537              * (and has no backup) - it is up him to read some very
538              * basic texts about security.
539              */
540             m_free(p);
541             p = tty_get(_("This is a secret key! - really delete? "));
542         }
543         if( answer_is_yes(p) )
544             okay++;
545         m_free(p);
546     }
547
548
549     if( okay ) {
550         rc = delete_keyblock( &kbpos );
551         if( rc ) {
552             log_error("delete_keyblock failed: %s\n", g10_errstr(rc) );
553             goto leave;
554         }
555     }
556
557   leave:
558     release_kbnode( keyblock );
559     return rc;
560 }
561
562
563 int
564 change_passphrase( const char *username )
565 {
566     int rc = 0;
567     KBNODE keyblock = NULL;
568     KBNODE node;
569     KBPOS kbpos;
570     PKT_secret_key *sk;
571     u32 keyid[2];
572     char *answer;
573     int changed=0;
574     char *passphrase = NULL;
575
576     /* find the userid */
577     rc = find_secret_keyblock_byname( &kbpos, username );
578     if( rc ) {
579         log_error("secret key for user '%s' not found\n", username );
580         goto leave;
581     }
582
583     /* read the keyblock */
584     rc = read_keyblock( &kbpos, &keyblock );
585     if( rc ) {
586         log_error("error reading the certificate: %s\n", g10_errstr(rc) );
587         goto leave;
588     }
589
590     /* get the keyid from the keyblock */
591     node = find_kbnode( keyblock, PKT_SECRET_KEY );
592     if( !node ) {
593         log_error("Oops; secret key not found anymore!\n");
594         rc = G10ERR_GENERAL;
595         goto leave;
596     }
597
598     sk = node->pkt->pkt.secret_key;
599     keyid_from_sk( sk, keyid );
600     tty_printf("sec  %4u%c/%08lX %s   ",
601               nbits_from_sk( sk ),
602               pubkey_letter( sk->pubkey_algo ),
603               keyid[1], datestr_from_sk(sk) );
604     {
605         size_t n;
606         char *p = get_user_id( keyid, &n );
607         tty_print_string( p, n );
608         m_free(p);
609         tty_printf("\n");
610     }
611     for(node=keyblock; node; node = node->next ) {
612         if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
613             PKT_secret_key *subsk = node->pkt->pkt.secret_key;
614             keyid_from_sk( subsk, keyid );
615             tty_printf("sub  %4u%c/%08lX %s\n",
616                       nbits_from_sk( subsk ),
617                       pubkey_letter( subsk->pubkey_algo ),
618                       keyid[1], datestr_from_sk(subsk) );
619         }
620     }
621
622     clear_kbnode_flags( keyblock );
623     switch( is_secret_key_protected( sk ) ) {
624       case -1:
625         rc = G10ERR_PUBKEY_ALGO;
626         break;
627       case 0:
628         tty_printf(_("This key is not protected.\n"));
629         break;
630       default:
631         tty_printf(_("Key is protected.\n"));
632         rc = check_secret_key( sk );
633         if( !rc )
634             passphrase = get_last_passphrase();
635         break;
636     }
637
638     /* unprotect all subkeys (use the supplied passphrase or ask)*/
639     for(node=keyblock; node; node = node->next ) {
640         if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
641             PKT_secret_key *subsk = node->pkt->pkt.secret_key;
642             set_next_passphrase( passphrase );
643             rc = check_secret_key( subsk );
644             if( rc )
645                 break;
646         }
647     }
648
649     if( rc )
650         tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
651     else {
652         DEK *dek = NULL;
653         STRING2KEY *s2k = m_alloc_secure( sizeof *s2k );
654
655         tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
656
657         set_next_passphrase( NULL );
658         for(;;) {
659             s2k->mode = 1;
660             s2k->hash_algo = DIGEST_ALGO_RMD160;
661             dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 );
662             if( !dek ) {
663                 tty_printf(_("passphrase not correctly repeated; try again.\n"));
664             }
665             else if( !dek->keylen ) {
666                 rc = 0;
667                 tty_printf(_( "You don't want a passphrase -"
668                             " this is probably a *bad* idea!\n\n"));
669                 answer = tty_get(_("Do you really want to do this? "));
670                 tty_kill_prompt();
671                 if( answer_is_yes(answer) )
672                     changed++;
673                 m_free(answer);
674                 break;
675             }
676             else { /* okay */
677                 sk->protect.algo = dek->algo;
678                 sk->protect.s2k = *s2k;
679                 rc = protect_secret_key( sk, dek );
680                 for(node=keyblock; !rc && node; node = node->next ) {
681                     if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
682                         PKT_secret_key *subsk = node->pkt->pkt.secret_key;
683                         subsk->protect.algo = dek->algo;
684                         subsk->protect.s2k = *s2k;
685                         rc = protect_secret_key( subsk, dek );
686                     }
687                 }
688                 if( rc )
689                     log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
690                 else
691                     changed++;
692                 break;
693             }
694         }
695         m_free(s2k);
696         m_free(dek);
697     }
698
699
700     if( changed ) {
701         rc = update_keyblock( &kbpos, keyblock );
702         if( rc ) {
703             log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
704             goto leave;
705         }
706     }
707
708   leave:
709     m_free( passphrase );
710     release_kbnode( keyblock );
711     set_next_passphrase( NULL );
712     return rc;
713 }
714
715
716 /****************
717  * Create a signature packet for the given public key certificate
718  * and the user id and return it in ret_sig. User signature class SIGCLASS
719  * user-id is not used (and may be NULL if sigclass is 0x20)
720  * If digest_algo is 0 the function selects an appropriate one.
721  */
722 int
723 make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
724                     PKT_user_id *uid, PKT_public_key *subpk,
725                     PKT_secret_key *sk,
726                     int sigclass, int digest_algo,
727                     int (*mksubpkt)(PKT_signature *, void *), void *opaque
728                    )
729 {
730     PKT_signature *sig;
731     int rc=0;
732     MD_HANDLE md;
733
734     assert( (sigclass >= 0x10 && sigclass <= 0x13)
735             || sigclass == 0x20 || sigclass == 0x18 );
736     if( !digest_algo ) {
737         switch( sk->pubkey_algo ) {
738           case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break;
739           case PUBKEY_ALGO_RSA_S:
740           case PUBKEY_ALGO_RSA: digest_algo = DIGEST_ALGO_MD5; break;
741           default:              digest_algo = DIGEST_ALGO_RMD160; break;
742         }
743     }
744     md = md_open( digest_algo, 0 );
745
746     /* hash the public key certificate and the user id */
747     hash_public_key( md, pk );
748     if( sigclass == 0x18 ) { /* subkey binding */
749         hash_public_key( md, subpk );
750     }
751     else if( sigclass != 0x20 ) {
752         if( sk->version >=4 ) {
753             byte buf[5];
754             buf[0] = 0xb4;            /* indicates a userid packet */
755             buf[1] = uid->len >> 24;  /* always use 4 length bytes */
756             buf[2] = uid->len >> 16;
757             buf[3] = uid->len >>  8;
758             buf[4] = uid->len;
759             md_write( md, buf, 5 );
760         }
761         md_write( md, uid->name, uid->len );
762     }
763     /* and make the signature packet */
764     sig = m_alloc_clear( sizeof *sig );
765     sig->version = sk->version;
766     keyid_from_sk( sk, sig->keyid );
767     sig->pubkey_algo = sk->pubkey_algo;
768     sig->digest_algo = digest_algo;
769     sig->timestamp = make_timestamp();
770     sig->sig_class = sigclass;
771     if( sig->version >= 4 )
772         build_sig_subpkt_from_sig( sig );
773
774     if( sig->version >= 4 && mksubpkt )
775         rc = (*mksubpkt)( sig, opaque );
776
777     if( !rc ) {
778         if( sig->version >= 4 )
779             md_putc( md, sig->version );
780         md_putc( md, sig->sig_class );
781         if( sig->version < 4 ) {
782             u32 a = sig->timestamp;
783             md_putc( md, (a >> 24) & 0xff );
784             md_putc( md, (a >> 16) & 0xff );
785             md_putc( md, (a >>  8) & 0xff );
786             md_putc( md,  a        & 0xff );
787         }
788         else {
789             byte buf[6];
790             size_t n;
791
792             md_putc( md, sig->pubkey_algo );
793             md_putc( md, sig->digest_algo );
794             if( sig->hashed_data ) {
795                 n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
796                 md_write( md, sig->hashed_data, n+2 );
797                 n += 6;
798             }
799             else
800                 n = 6;
801             /* add some magic */
802             buf[0] = sig->version;
803             buf[1] = 0xff;
804             buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
805             buf[3] = n >> 16;
806             buf[4] = n >>  8;
807             buf[5] = n;
808             md_write( md, buf, 6 );
809
810         }
811         md_final(md);
812
813         rc = complete_sig( sig, sk, md );
814     }
815
816     md_close( md );
817     if( rc )
818         free_seckey_enc( sig );
819     else
820         *ret_sig = sig;
821     return rc;
822 }
823