avoid use of freed pointer
[gnupg.git] / g10 / revoke.c
1 /* revoke.c
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
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 #include <ctype.h>
28
29 #include "gpg.h"
30 #include "options.h"
31 #include "packet.h"
32 #include "status.h"
33 #include "keydb.h"
34 #include "util.h"
35 #include "main.h"
36 #include "ttyio.h"
37 #include "status.h"
38 #include "i18n.h"
39 #include "call-agent.h"
40
41 struct revocation_reason_info {
42     int code;
43     char *desc;
44 };
45
46
47 int
48 revocation_reason_build_cb( PKT_signature *sig, void *opaque )
49 {
50     struct revocation_reason_info *reason = opaque;
51     char *ud = NULL;
52     byte *buffer;
53     size_t buflen = 1;
54
55     if(!reason)
56       return 0;
57
58     if( reason->desc ) {
59         ud = native_to_utf8( reason->desc );
60         buflen += strlen(ud);
61     }
62     buffer = xmalloc( buflen );
63     *buffer = reason->code;
64     if( ud ) {
65         memcpy(buffer+1, ud, strlen(ud) );
66         xfree( ud );
67     }
68
69     build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
70     xfree( buffer );
71     return 0;
72 }
73
74 /* Outputs a minimal pk (as defined by 2440) from a keyblock.  A
75    minimal pk consists of the public key packet and a user ID.  We try
76    and pick a user ID that has a uid signature, and include it if
77    possible. */
78 static int
79 export_minimal_pk(IOBUF out,KBNODE keyblock,
80                   PKT_signature *revsig,PKT_signature *revkey)
81 {
82   KBNODE node;
83   PACKET pkt;
84   PKT_user_id *uid=NULL;
85   PKT_signature *selfsig=NULL;
86   u32 keyid[2];
87   int rc;
88
89   node=find_kbnode(keyblock,PKT_PUBLIC_KEY);
90   if(!node)
91     {
92       log_error("key incomplete\n");
93       return G10ERR_GENERAL;
94     }
95
96   keyid_from_pk(node->pkt->pkt.public_key,keyid);
97
98   pkt=*node->pkt;
99   rc=build_packet(out,&pkt);
100   if(rc)
101     {
102       log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
103       return rc;
104     }
105
106   init_packet(&pkt);
107   pkt.pkttype=PKT_SIGNATURE;
108
109   /* the revocation itself, if any.  2440 likes this to come first. */
110   if(revsig)
111     {
112       pkt.pkt.signature=revsig;
113       rc=build_packet(out,&pkt);
114       if(rc)
115         {
116           log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
117           return rc;
118         }
119     }
120
121   /* If a revkey in a 1F sig is present, include it too */
122   if(revkey)
123     {
124       pkt.pkt.signature=revkey;
125       rc=build_packet(out,&pkt);
126       if(rc)
127         {
128           log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
129           return rc;
130         }
131     }
132
133   while(!selfsig)
134     {
135       KBNODE signode;
136
137       node=find_next_kbnode(node,PKT_USER_ID);
138       if(!node)
139         {
140           /* We're out of user IDs - none were self-signed. */
141           if(uid)
142             break;
143           else
144             {
145               log_error(_("key %s has no user IDs\n"),keystr(keyid));
146               return G10ERR_GENERAL;
147             }
148         }
149
150       if(node->pkt->pkt.user_id->attrib_data)
151         continue;
152
153       uid=node->pkt->pkt.user_id;
154       signode=node;
155
156       while((signode=find_next_kbnode(signode,PKT_SIGNATURE)))
157         {
158           if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
159              keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
160              IS_UID_SIG(signode->pkt->pkt.signature))
161             {
162               selfsig=signode->pkt->pkt.signature;
163               break;
164             }
165         }
166     }
167
168   pkt.pkttype=PKT_USER_ID;
169   pkt.pkt.user_id=uid;
170
171   rc=build_packet(out,&pkt);
172   if(rc)
173     {
174       log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
175       return rc;
176     }
177
178   if(selfsig)
179     {
180       pkt.pkttype=PKT_SIGNATURE;
181       pkt.pkt.signature=selfsig;
182
183       rc=build_packet(out,&pkt);
184       if(rc)
185         {
186           log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
187           return rc;
188         }
189     }
190
191   return 0;
192 }
193
194 /****************
195  * Generate a revocation certificate for UNAME via a designated revoker
196  */
197 int
198 gen_desig_revoke( const char *uname, strlist_t locusr )
199 {
200     int rc = 0;
201     armor_filter_context_t *afx;
202     PKT_public_key *pk = NULL;
203     PKT_public_key *pk2 = NULL;
204     PKT_signature *sig = NULL;
205     IOBUF out = NULL;
206     struct revocation_reason_info *reason = NULL;
207     KEYDB_HANDLE kdbhd;
208     KEYDB_SEARCH_DESC desc;
209     KBNODE keyblock=NULL,node;
210     u32 keyid[2];
211     int i,any=0;
212     SK_LIST sk_list=NULL;
213
214     if( opt.batch )
215       {
216         log_error(_("can't do this in batch mode\n"));
217         return G10ERR_GENERAL;
218       }
219
220     afx = new_armor_context ();
221
222     kdbhd = keydb_new ();
223     rc = classify_user_id (uname, &desc, 1);
224     if (!rc)
225       rc = keydb_search (kdbhd, &desc, 1);
226     if (rc) {
227         log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
228         goto leave;
229     }
230
231     rc = keydb_get_keyblock (kdbhd, &keyblock );
232     if( rc ) {
233         log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
234         goto leave;
235     }
236
237     /* To parse the revkeys */
238     merge_keys_and_selfsig(keyblock);
239
240     /* get the key from the keyblock */
241     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
242     if( !node )
243       BUG ();
244
245     pk=node->pkt->pkt.public_key;
246
247     keyid_from_pk(pk,keyid);
248
249     if(locusr)
250       {
251         rc=build_sk_list(locusr, &sk_list, PUBKEY_USAGE_CERT);
252         if(rc)
253           goto leave;
254       }
255
256     /* Are we a designated revoker for this key? */
257
258     if(!pk->revkey && pk->numrevkeys)
259       BUG();
260
261     for(i=0;i<pk->numrevkeys;i++)
262       {
263         SK_LIST list;
264
265         if (pk2)
266           {
267             free_public_key (pk2);
268             pk2 = NULL;
269           }
270
271         if(sk_list)
272           {
273             for(list=sk_list;list;list=list->next)
274               {
275                 byte fpr[MAX_FINGERPRINT_LEN];
276                 size_t fprlen;
277
278                 fingerprint_from_pk (list->pk, fpr, &fprlen);
279
280                 /* Don't get involved with keys that don't have 160
281                    bit fingerprints */
282                 if(fprlen!=20)
283                   continue;
284
285                 if(memcmp(fpr,pk->revkey[i].fpr,20)==0)
286                   break;
287               }
288
289             if (list)
290               pk2 = copy_public_key (NULL, list->pk);
291             else
292               continue;
293           }
294         else
295           {
296             pk2 = xmalloc_clear (sizeof *pk2);
297             rc = get_pubkey_byfprint (pk2,
298                                       pk->revkey[i].fpr, MAX_FINGERPRINT_LEN);
299           }
300
301         /* We have the revocation key.  */
302         if(!rc)
303           {
304             PKT_signature *revkey = NULL;
305
306             any = 1;
307
308             print_pubkey_info (NULL, pk);
309             tty_printf ("\n");
310
311             tty_printf (_("To be revoked by:\n"));
312             print_seckey_info (pk2);
313
314             if(pk->revkey[i].class&0x40)
315               tty_printf(_("(This is a sensitive revocation key)\n"));
316             tty_printf("\n");
317
318             if( !cpr_get_answer_is_yes("gen_desig_revoke.okay",
319          _("Create a designated revocation certificate for this key? (y/N) ")))
320               continue;
321
322             /* get the reason for the revocation (this is always v4) */
323             reason = ask_revocation_reason( 1, 0, 1 );
324             if( !reason )
325               continue;
326
327             rc = -1;/*FIXME: check_secret_key (pk2, 0 );*/
328             if (rc)
329               continue;
330
331             if( !opt.armor )
332               tty_printf(_("ASCII armored output forced.\n"));
333
334             if( (rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out )) )
335               goto leave;
336
337             afx->what = 1;
338             afx->hdrlines = "Comment: A designated revocation certificate"
339               " should follow\n";
340             push_armor_filter (afx, out);
341
342             /* create it */
343             rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
344                                      0, 0, 0,
345                                      revocation_reason_build_cb, reason,
346                                      NULL);
347             if( rc ) {
348               log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
349               goto leave;
350             }
351
352             /* Spit out a minimal pk as well, since otherwise there is
353                no way to know which key to attach this revocation to.
354                Also include the direct key signature that contains
355                this revocation key.  We're allowed to include
356                sensitive revocation keys along with a revocation, as
357                this may be the only time the recipient has seen it.
358                Note that this means that if we have multiple different
359                sensitive revocation keys in a given direct key
360                signature, we're going to include them all here.  This
361                is annoying, but the good outweighs the bad, since
362                without including this a sensitive revoker can't really
363                do their job.  People should not include multiple
364                sensitive revocation keys in one signature: 2440 says
365                "Note that it may be appropriate to isolate this
366                subpacket within a separate signature so that it is not
367                combined with other subpackets that need to be
368                exported." -dms */
369
370             while(!revkey)
371               {
372                 KBNODE signode;
373
374                 signode=find_next_kbnode(node,PKT_SIGNATURE);
375                 if(!signode)
376                   break;
377
378                 node=signode;
379
380                 if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
381                    keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
382                    IS_KEY_SIG(signode->pkt->pkt.signature))
383                   {
384                     int j;
385
386                     for(j=0;j<signode->pkt->pkt.signature->numrevkeys;j++)
387                       {
388                         if(pk->revkey[i].class==
389                            signode->pkt->pkt.signature->revkey[j]->class &&
390                            pk->revkey[i].algid==
391                            signode->pkt->pkt.signature->revkey[j]->algid &&
392                            memcmp(pk->revkey[i].fpr,
393                                   signode->pkt->pkt.signature->revkey[j]->fpr,
394                                   MAX_FINGERPRINT_LEN)==0)
395                           {
396                             revkey=signode->pkt->pkt.signature;
397                             break;
398                           }
399                       }
400                   }
401               }
402
403             if(!revkey)
404               BUG();
405
406             rc=export_minimal_pk(out,keyblock,sig,revkey);
407             if(rc)
408               goto leave;
409
410             /* and issue a usage notice */
411             tty_printf(_("Revocation certificate created.\n"));
412             break;
413           }
414       }
415
416     if(!any)
417       log_error(_("no revocation keys found for \"%s\"\n"),uname);
418
419   leave:
420     if( pk )
421         free_public_key( pk );
422     if (pk2)
423         free_public_key (pk2);
424     if( sig )
425         free_seckey_enc( sig );
426
427     release_sk_list(sk_list);
428
429     if( rc )
430         iobuf_cancel(out);
431     else
432         iobuf_close(out);
433     release_revocation_reason_info( reason );
434     release_armor_context (afx);
435     return rc;
436 }
437
438
439 /****************
440  * Generate a revocation certificate for UNAME
441  */
442 int
443 gen_revoke (const char *uname)
444 {
445   int rc = 0;
446   armor_filter_context_t *afx;
447   PACKET pkt;
448   PKT_public_key *psk;
449   PKT_signature *sig = NULL;
450   u32 keyid[2];
451   iobuf_t out = NULL;
452   kbnode_t keyblock = NULL;
453   kbnode_t node;
454   KEYDB_HANDLE kdbhd;
455   struct revocation_reason_info *reason = NULL;
456   KEYDB_SEARCH_DESC desc;
457
458   if( opt.batch )
459     {
460       log_error(_("can't do this in batch mode\n"));
461       return G10ERR_GENERAL;
462     }
463
464   afx = new_armor_context ();
465   init_packet( &pkt );
466
467   /* Search the userid; we don't want the whole getkey stuff here.  */
468   kdbhd = keydb_new ();
469   rc = classify_user_id (uname, &desc, 1);
470   if (!rc)
471     rc = keydb_search (kdbhd, &desc, 1);
472   if (rc)
473     {
474       log_error (_("secret key \"%s\" not found: %s\n"),
475                  uname, g10_errstr (rc));
476       goto leave;
477     }
478
479   rc = keydb_get_keyblock (kdbhd, &keyblock );
480   if (rc)
481     {
482       log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
483       goto leave;
484     }
485
486   /* Get the keyid from the keyblock.  */
487   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
488   if (!node)
489     BUG ();
490
491   psk = node->pkt->pkt.public_key;
492   rc = agent_probe_secret_key (NULL, psk);
493   if (rc)
494     {
495       log_error (_("secret key \"%s\" not found: %s\n"),
496                  uname, gpg_strerror (rc));
497       goto leave;
498     }
499
500   keyid_from_pk (psk, keyid );
501   print_seckey_info (psk);
502
503   tty_printf("\n");
504   if (!cpr_get_answer_is_yes ("gen_revoke.okay",
505                 _("Create a revocation certificate for this key? (y/N) ")))
506     {
507       rc = 0;
508       goto leave;
509     }
510
511   if (psk->version >= 4 || opt.force_v4_certs)
512     {
513       /* Get the reason for the revocation.  */
514       reason = ask_revocation_reason (1, 0, 1);
515       if (!reason)
516         {
517           /* user decided to cancel */
518           rc = 0;
519           goto leave;
520         }
521     }
522
523   if (!opt.armor)
524     tty_printf (_("ASCII armored output forced.\n"));
525
526   if ((rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out )))
527     goto leave;
528
529   afx->what = 1;
530   afx->hdrlines = "Comment: A revocation certificate should follow\n";
531   push_armor_filter (afx, out);
532
533   /* create it */
534   rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
535                            opt.force_v4_certs?4:0, 0, 0,
536                            revocation_reason_build_cb, reason, NULL);
537   if (rc)
538     {
539       log_error (_("make_keysig_packet failed: %s\n"), g10_errstr (rc));
540       goto leave;
541     }
542
543   if (PGP2 || PGP6 || PGP7 || PGP8)
544     {
545       /* Use a minimal pk for PGPx mode, since PGP can't import bare
546          revocation certificates. */
547       rc = export_minimal_pk (out, keyblock, sig, NULL);
548       if(rc)
549         goto leave;
550     }
551   else
552     {
553       init_packet( &pkt );
554       pkt.pkttype = PKT_SIGNATURE;
555       pkt.pkt.signature = sig;
556
557       rc = build_packet (out, &pkt);
558       if (rc)
559         {
560           log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
561           goto leave;
562         }
563     }
564
565   /* and issue a usage notice */
566   tty_printf (_(
567 "Revocation certificate created.\n\n"
568 "Please move it to a medium which you can hide away; if Mallory gets\n"
569 "access to this certificate he can use it to make your key unusable.\n"
570 "It is smart to print this certificate and store it away, just in case\n"
571 "your media become unreadable.  But have some caution:  The print system of\n"
572 "your machine might store the data and make it available to others!\n"));
573
574  leave:
575   if (sig)
576     free_seckey_enc (sig);
577   release_kbnode (keyblock);
578   keydb_release (kdbhd);
579   if (rc)
580     iobuf_cancel(out);
581   else
582     iobuf_close(out);
583   release_revocation_reason_info( reason );
584   release_armor_context (afx);
585   return rc;
586 }
587
588
589
590 struct revocation_reason_info *
591 ask_revocation_reason( int key_rev, int cert_rev, int hint )
592 {
593     int code=-1;
594     char *description = NULL;
595     struct revocation_reason_info *reason;
596     const char *text_0 = _("No reason specified");
597     const char *text_1 = _("Key has been compromised");
598     const char *text_2 = _("Key is superseded");
599     const char *text_3 = _("Key is no longer used");
600     const char *text_4 = _("User ID is no longer valid");
601     const char *code_text = NULL;
602
603     do {
604         code=-1;
605         xfree(description);
606         description = NULL;
607
608         tty_printf(_("Please select the reason for the revocation:\n"));
609         tty_printf(    "  0 = %s\n", text_0 );
610         if( key_rev )
611             tty_printf("  1 = %s\n", text_1 );
612         if( key_rev )
613             tty_printf("  2 = %s\n", text_2 );
614         if( key_rev )
615             tty_printf("  3 = %s\n", text_3 );
616         if( cert_rev )
617             tty_printf("  4 = %s\n", text_4 );
618         tty_printf(    "  Q = %s\n", _("Cancel") );
619         if( hint )
620             tty_printf(_("(Probably you want to select %d here)\n"), hint );
621
622         while(code==-1) {
623             int n;
624             char *answer = cpr_get("ask_revocation_reason.code",
625                                                 _("Your decision? "));
626             trim_spaces( answer );
627             cpr_kill_prompt();
628             if( *answer == 'q' || *answer == 'Q')
629               return NULL; /* cancel */
630             if( hint && !*answer )
631                 n = hint;
632             else if(!digitp( answer ) )
633                 n = -1;
634             else
635                 n = atoi(answer);
636             xfree(answer);
637             if( n == 0 ) {
638                 code = 0x00; /* no particular reason */
639                 code_text = text_0;
640             }
641             else if( key_rev && n == 1 ) {
642                 code = 0x02; /* key has been compromised */
643                 code_text = text_1;
644             }
645             else if( key_rev && n == 2 ) {
646                 code = 0x01; /* key is superseded */
647                 code_text = text_2;
648             }
649             else if( key_rev && n == 3 ) {
650                 code = 0x03; /* key is no longer used */
651                 code_text = text_3;
652             }
653             else if( cert_rev && n == 4 ) {
654                 code = 0x20; /* uid is no longer valid */
655                 code_text = text_4;
656             }
657             else
658                 tty_printf(_("Invalid selection.\n"));
659         }
660
661         tty_printf(_("Enter an optional description; "
662                      "end it with an empty line:\n") );
663         for(;;) {
664             char *answer = cpr_get("ask_revocation_reason.text", "> " );
665             trim_trailing_ws( answer, strlen(answer) );
666             cpr_kill_prompt();
667             if( !*answer ) {
668                 xfree(answer);
669                 break;
670             }
671
672             {
673                 char *p = make_printable_string( answer, strlen(answer), 0 );
674                 xfree(answer);
675                 answer = p;
676             }
677
678             if( !description )
679                 description = xstrdup(answer);
680             else {
681                 char *p = xmalloc( strlen(description) + strlen(answer) + 2 );
682                 strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
683                 xfree(description);
684                 description = p;
685             }
686             xfree(answer);
687         }
688
689         tty_printf(_("Reason for revocation: %s\n"), code_text );
690         if( !description )
691             tty_printf(_("(No description given)\n") );
692         else
693             tty_printf("%s\n", description );
694
695     } while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
696                                             _("Is this okay? (y/N) "))  );
697
698     reason = xmalloc( sizeof *reason );
699     reason->code = code;
700     reason->desc = description;
701     return reason;
702 }
703
704 void
705 release_revocation_reason_info( struct revocation_reason_info *reason )
706 {
707     if( reason ) {
708         xfree( reason->desc );
709         xfree( reason );
710     }
711 }