~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-security

« back to all changes in this revision

Viewing changes to g10/revoke.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* revoke.c
2
 
 * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
 
3
 *               2004 Free Software Foundation, Inc.
3
4
 *
4
5
 * This file is part of GnuPG.
5
6
 *
6
7
 * GnuPG is free software; you can redistribute it and/or modify
7
8
 * 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
 * the Free Software Foundation; either version 3 of the License, or
9
10
 * (at your option) any later version.
10
11
 *
11
12
 * GnuPG is distributed in the hope that it will be useful,
14
15
 * GNU General Public License for more details.
15
16
 *
16
17
 * 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
 
18
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
19
 */
20
20
 
21
21
#include <config.h>
26
26
#include <assert.h>
27
27
#include <ctype.h>
28
28
 
 
29
#include "gpg.h"
29
30
#include "options.h"
30
31
#include "packet.h"
31
 
#include "errors.h"
 
32
#include "status.h"
32
33
#include "keydb.h"
33
 
#include "memory.h"
34
34
#include "util.h"
35
35
#include "main.h"
36
36
#include "ttyio.h"
59
59
        ud = native_to_utf8( reason->desc );
60
60
        buflen += strlen(ud);
61
61
    }
62
 
    buffer = xmalloc ( buflen );
 
62
    buffer = xmalloc( buflen );
63
63
    *buffer = reason->code;
64
64
    if( ud ) {
65
65
        memcpy(buffer+1, ud, strlen(ud) );
66
 
        xfree ( ud );
 
66
        xfree( ud );
67
67
    }
68
68
 
69
69
    build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
70
 
    xfree ( buffer );
 
70
    xfree( buffer );
71
71
    return 0;
72
72
}
73
73
 
76
76
   and pick a user ID that has a uid signature, and include it if
77
77
   possible. */
78
78
static int
79
 
export_minimal_pk(iobuf_t out,KBNODE keyblock,
 
79
export_minimal_pk(IOBUF out,KBNODE keyblock,
80
80
                  PKT_signature *revsig,PKT_signature *revkey)
81
81
{
82
82
  KBNODE node;
89
89
  node=find_kbnode(keyblock,PKT_PUBLIC_KEY);
90
90
  if(!node)
91
91
    {
92
 
      log_error(_("key incomplete\n"));
93
 
      return GPG_ERR_GENERAL;
 
92
      log_error("key incomplete\n");
 
93
      return G10ERR_GENERAL;
94
94
    }
95
95
 
96
96
  keyid_from_pk(node->pkt->pkt.public_key,keyid);
99
99
  rc=build_packet(out,&pkt);
100
100
  if(rc)
101
101
    {
102
 
      log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
 
102
      log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
103
103
      return rc;
104
104
    }
105
105
 
113
113
      rc=build_packet(out,&pkt);
114
114
      if(rc)
115
115
        {
116
 
          log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
 
116
          log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
117
117
          return rc;
118
118
        }
119
119
    }
125
125
      rc=build_packet(out,&pkt);
126
126
      if(rc)
127
127
        {
128
 
          log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
 
128
          log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
129
129
          return rc;
130
130
        }
131
131
    }
142
142
            break;
143
143
          else
144
144
            {
145
 
              log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]);
146
 
              return GPG_ERR_GENERAL;
 
145
              log_error(_("key %s has no user IDs\n"),keystr(keyid));
 
146
              return G10ERR_GENERAL;
147
147
            }
148
148
        }
149
149
 
171
171
  rc=build_packet(out,&pkt);
172
172
  if(rc)
173
173
    {
174
 
      log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
 
174
      log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
175
175
      return rc;
176
176
    }
177
177
 
183
183
      rc=build_packet(out,&pkt);
184
184
      if(rc)
185
185
        {
186
 
          log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
 
186
          log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
187
187
          return rc;
188
188
        }
189
189
    }
195
195
 * Generate a revocation certificate for UNAME via a designated revoker
196
196
 */
197
197
int
198
 
gen_desig_revoke( const char *uname )
 
198
gen_desig_revoke( const char *uname, strlist_t locusr )
199
199
{
200
200
    int rc = 0;
201
 
    armor_filter_context_t afx;
 
201
    armor_filter_context_t *afx;
202
202
    PKT_public_key *pk = NULL;
203
203
    PKT_secret_key *sk = NULL;
204
204
    PKT_signature *sig = NULL;
205
 
    iobuf_t out = NULL;
 
205
    IOBUF out = NULL;
206
206
    struct revocation_reason_info *reason = NULL;
207
207
    KEYDB_HANDLE kdbhd;
208
208
    KEYDB_SEARCH_DESC desc;
209
209
    KBNODE keyblock=NULL,node;
210
210
    u32 keyid[2];
211
211
    int i,any=0;
212
 
 
213
 
    if( opt.batch ) {
214
 
        log_error(_("sorry, can't do this in batch mode\n"));
215
 
        return GPG_ERR_GENERAL;
216
 
    }
217
 
 
218
 
    memset( &afx, 0, sizeof afx);
 
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 ();
219
221
 
220
222
    kdbhd = keydb_new (0);
221
223
    classify_user_id (uname, &desc);
222
 
    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID;
 
224
    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
223
225
    if (rc) {
224
 
        log_error (_("key `%s' not found: %s\n"),uname, gpg_strerror (rc));
 
226
        log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
225
227
        goto leave;
226
228
    }
227
229
 
228
230
    rc = keydb_get_keyblock (kdbhd, &keyblock );
229
231
    if( rc ) {
230
 
        log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
 
232
        log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
231
233
        goto leave;
232
234
    }
233
235
 
243
245
 
244
246
    keyid_from_pk(pk,keyid);
245
247
 
 
248
    if(locusr)
 
249
      {
 
250
        rc=build_sk_list(locusr,&sk_list,0,PUBKEY_USAGE_CERT);
 
251
        if(rc)
 
252
          goto leave;
 
253
      }
 
254
 
246
255
    /* Are we a designated revoker for this key? */
247
256
 
248
257
    if(!pk->revkey && pk->numrevkeys)
250
259
 
251
260
    for(i=0;i<pk->numrevkeys;i++)
252
261
      {
 
262
        SK_LIST list;
 
263
 
253
264
        if(sk)
254
265
          free_secret_key(sk);
255
266
 
256
 
        sk=xcalloc (1,sizeof(*sk));
257
 
 
258
 
        rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
 
267
        if(sk_list)
 
268
          {
 
269
            for(list=sk_list;list;list=list->next)
 
270
              {
 
271
                byte fpr[MAX_FINGERPRINT_LEN];
 
272
                size_t fprlen;
 
273
 
 
274
                fingerprint_from_sk(list->sk,fpr,&fprlen);
 
275
 
 
276
                /* Don't get involved with keys that don't have 160
 
277
                   bit fingerprints */
 
278
                if(fprlen!=20)
 
279
                  continue;
 
280
 
 
281
                if(memcmp(fpr,pk->revkey[i].fpr,20)==0)
 
282
                  break;
 
283
              }
 
284
 
 
285
            if(list)
 
286
              sk=copy_secret_key(NULL,list->sk);
 
287
            else
 
288
              continue;
 
289
          }
 
290
        else
 
291
          {
 
292
            sk=xmalloc_secure_clear(sizeof(*sk));
 
293
            rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
 
294
          }
259
295
 
260
296
        /* We have the revocation key */
261
297
        if(!rc)
275
311
            tty_printf("\n");
276
312
 
277
313
            if( !cpr_get_answer_is_yes("gen_desig_revoke.okay",
278
 
                       _("Create a revocation certificate for this key? ")) )
 
314
         _("Create a designated revocation certificate for this key? (y/N) ")))
279
315
              continue;
280
316
 
281
317
            /* get the reason for the revocation (this is always v4) */
293
329
            if( (rc = open_outfile( NULL, 0, &out )) )
294
330
              goto leave;
295
331
 
296
 
            afx.what = 1;
297
 
            afx.hdrlines = "Comment: A revocation certificate should follow\n";
298
 
            iobuf_push_filter( out, armor_filter, &afx );
 
332
            afx->what = 1;
 
333
            afx->hdrlines = "Comment: A designated revocation certificate"
 
334
              " should follow\n";
 
335
            push_armor_filter (afx, out);
299
336
 
300
337
            /* create it */
301
338
            rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
302
339
                                     0, 0, 0,
303
340
                                     revocation_reason_build_cb, reason );
304
341
            if( rc ) {
305
 
              log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
 
342
              log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
306
343
              goto leave;
307
344
            }
308
345
 
371
408
      }
372
409
 
373
410
    if(!any)
374
 
      log_error(_("no revocation keys found for `%s'\n"),uname);
 
411
      log_error(_("no revocation keys found for \"%s\"\n"),uname);
375
412
 
376
413
  leave:
377
414
    if( pk )
381
418
    if( sig )
382
419
        free_seckey_enc( sig );
383
420
 
 
421
    release_sk_list(sk_list);
 
422
 
384
423
    if( rc )
385
424
        iobuf_cancel(out);
386
425
    else
387
426
        iobuf_close(out);
388
427
    release_revocation_reason_info( reason );
 
428
    release_armor_context (afx);
389
429
    return rc;
390
430
}
391
431
 
397
437
gen_revoke( const char *uname )
398
438
{
399
439
    int rc = 0;
400
 
    armor_filter_context_t afx;
 
440
    armor_filter_context_t *afx;
401
441
    PACKET pkt;
402
442
    PKT_secret_key *sk; /* used as pointer into a kbnode */
403
443
    PKT_public_key *pk = NULL;
404
444
    PKT_signature *sig = NULL;
405
445
    u32 sk_keyid[2];
406
 
    iobuf_t out = NULL;
 
446
    IOBUF out = NULL;
407
447
    KBNODE keyblock = NULL, pub_keyblock = NULL;
408
448
    KBNODE node;
409
449
    KEYDB_HANDLE kdbhd;
410
450
    struct revocation_reason_info *reason = NULL;
411
451
    KEYDB_SEARCH_DESC desc;
412
452
 
413
 
    if( opt.batch ) {
414
 
        log_error(_("sorry, can't do this in batch mode\n"));
415
 
        return GPG_ERR_GENERAL;
416
 
    }
 
453
    if( opt.batch )
 
454
      {
 
455
        log_error(_("can't do this in batch mode\n"));
 
456
        return G10ERR_GENERAL;
 
457
      }
417
458
 
418
 
    memset( &afx, 0, sizeof afx);
 
459
    afx = new_armor_context ();
419
460
    init_packet( &pkt );
420
461
 
421
462
    /* search the userid: 
423
464
     */
424
465
    kdbhd = keydb_new (1);
425
466
    classify_user_id (uname, &desc);
426
 
    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID;
427
 
    if (rc) {
428
 
        log_error (_("secret key `%s' not found: %s\n"),
429
 
                   uname, gpg_strerror (rc));
 
467
    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
 
468
    if (rc)
 
469
      {
 
470
        log_error (_("secret key \"%s\" not found: %s\n"),
 
471
                   uname, g10_errstr (rc));
430
472
        goto leave;
431
 
    }
 
473
      }
432
474
 
433
475
    rc = keydb_get_keyblock (kdbhd, &keyblock );
434
476
    if( rc ) {
435
 
        log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
 
477
        log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
436
478
        goto leave;
437
479
    }
438
480
 
447
489
    keyid_from_sk( sk, sk_keyid );
448
490
    print_seckey_info (sk);
449
491
 
450
 
    pk = xcalloc (1, sizeof *pk );
 
492
    pk = xmalloc_clear( sizeof *pk );
451
493
 
452
494
    /* FIXME: We should get the public key direct from the secret one */
453
495
 
454
496
    pub_keyblock=get_pubkeyblock(sk_keyid);
455
497
    if(!pub_keyblock)
456
498
      {
457
 
        log_error(_("no corresponding public key: %s\n"), gpg_strerror (rc) );
 
499
        log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
458
500
        goto leave;
459
501
      }
460
502
 
466
508
 
467
509
    if( cmp_public_secret_key( pk, sk ) ) {
468
510
        log_error(_("public key does not match secret key!\n") );
469
 
        rc = GPG_ERR_GENERAL;
 
511
        rc = G10ERR_GENERAL;
470
512
        goto leave;
471
513
    }
472
514
 
473
515
    tty_printf("\n");
474
516
    if( !cpr_get_answer_is_yes("gen_revoke.okay",
475
 
                        _("Create a revocation certificate for this key? ")) ){
 
517
                  _("Create a revocation certificate for this key? (y/N) ")) )
 
518
      {
476
519
        rc = 0;
477
520
        goto leave;
478
 
    }
 
521
      }
479
522
 
480
523
    if(sk->version>=4 || opt.force_v4_certs) {
481
524
      /* get the reason for the revocation */
489
532
    switch( is_secret_key_protected( sk ) ) {
490
533
      case -1:
491
534
        log_error(_("unknown protection algorithm\n"));
492
 
        rc = GPG_ERR_PUBKEY_ALGO;
 
535
        rc = G10ERR_PUBKEY_ALGO;
493
536
        break;
 
537
      case -3:
 
538
        tty_printf (_("Secret parts of primary key are not available.\n"));
 
539
        rc = G10ERR_NO_SECKEY;
 
540
        break;
494
541
      case 0:
495
542
        tty_printf(_("NOTE: This key is not protected!\n"));
496
543
        break;
497
544
      default:
498
 
        rc = check_secret_key( sk, 0 );
 
545
        rc = check_secret_key( sk, 0 );
499
546
        break;
500
547
    }
501
548
    if( rc )
508
555
    if( (rc = open_outfile( NULL, 0, &out )) )
509
556
        goto leave;
510
557
 
511
 
    afx.what = 1;
512
 
    afx.hdrlines = "Comment: A revocation certificate should follow\n";
513
 
    iobuf_push_filter( out, armor_filter, &afx );
 
558
    afx->what = 1;
 
559
    afx->hdrlines = "Comment: A revocation certificate should follow\n";
 
560
    push_armor_filter (afx, out);
514
561
 
515
562
    /* create it */
516
563
    rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
517
564
                             opt.force_v4_certs?4:0, 0, 0,
518
565
                             revocation_reason_build_cb, reason );
519
566
    if( rc ) {
520
 
        log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
 
567
        log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
521
568
        goto leave;
522
569
    }
523
570
 
537
584
 
538
585
        rc = build_packet( out, &pkt );
539
586
        if( rc ) {
540
 
          log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
 
587
          log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
541
588
          goto leave;
542
589
        }
543
590
      }
561
608
    else
562
609
        iobuf_close(out);
563
610
    release_revocation_reason_info( reason );
 
611
    release_armor_context (afx);
564
612
    return rc;
565
613
}
566
614
 
581
629
 
582
630
    do {
583
631
        code=-1;
584
 
        xfree (description);
 
632
        xfree(description);
585
633
        description = NULL;
586
634
 
587
635
        tty_printf(_("Please select the reason for the revocation:\n"));
612
660
                n = -1;
613
661
            else
614
662
                n = atoi(answer);
615
 
            xfree (answer);
 
663
            xfree(answer);
616
664
            if( n == 0 ) {
617
665
                code = 0x00; /* no particular reason */
618
666
                code_text = text_0;
644
692
            trim_trailing_ws( answer, strlen(answer) );
645
693
            cpr_kill_prompt();
646
694
            if( !*answer ) {
647
 
                xfree (answer);
 
695
                xfree(answer);
648
696
                break;
649
697
            }
650
698
 
651
699
            {
652
700
                char *p = make_printable_string( answer, strlen(answer), 0 );
653
 
                xfree (answer);
 
701
                xfree(answer);
654
702
                answer = p;
655
703
            }
656
704
 
657
705
            if( !description )
658
 
                description = xstrdup (answer);
 
706
                description = xstrdup(answer);
659
707
            else {
660
 
                char *p = xmalloc ( strlen(description) + strlen(answer) + 2 );
 
708
                char *p = xmalloc( strlen(description) + strlen(answer) + 2 );
661
709
                strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
662
 
                xfree (description);
 
710
                xfree(description);
663
711
                description = p;
664
712
            }
665
 
            xfree (answer);
 
713
            xfree(answer);
666
714
        }
667
715
 
668
716
        tty_printf(_("Reason for revocation: %s\n"), code_text );
672
720
            tty_printf("%s\n", description );
673
721
 
674
722
    } while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
675
 
                                            _("Is this okay? "))  );
 
723
                                            _("Is this okay? (y/N) "))  );
676
724
 
677
 
    reason = xmalloc ( sizeof *reason );
 
725
    reason = xmalloc( sizeof *reason );
678
726
    reason->code = code;
679
727
    reason->desc = description;
680
728
    return reason;
684
732
release_revocation_reason_info( struct revocation_reason_info *reason )
685
733
{
686
734
    if( reason ) {
687
 
        xfree ( reason->desc );
688
 
        xfree ( reason );
 
735
        xfree( reason->desc );
 
736
        xfree( reason );
689
737
    }
690
738
}