~ubuntu-branches/ubuntu/raring/gnupg2/raring-proposed

« back to all changes in this revision

Viewing changes to g10/passphrase.c

  • Committer: Bazaar Package Importer
  • Author(s): Eric Dorland
  • Date: 2009-08-23 20:48:11 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090823204811-cajik24rci4xszia
Tags: 2.0.12-1
* New upstream release. (Closes: #499569, #463270, #446494, #314068, 
  #519375, #514587)
* debian/control: Change build dependency on gs to ghoscript, since
  ghoscript has been replaced.
* debian/compat: Use debhelper v7.
* debian/control: Update Standards-Version to 3.8.2.
* debian/control: Use ${misc:Depends}.
* configure.ac: Override pkgdatadir so that it points to
  /usr/share/gnupg2. (Closes: #528734)
* debian/rules: No longer need to specify pkgdatadir at make install
  time.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* passphrase.c -  Get a passphrase
2
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
 
 *               2005, 2006, 2007 Free Software Foundation, Inc.
 
3
 *               2005, 2006, 2007, 2009 Free Software Foundation, Inc.
4
4
 *
5
5
 * This file is part of GnuPG.
6
6
 *
50
50
static char *last_pw = NULL;
51
51
 
52
52
 
53
 
/* Hash a passphrase using the supplied s2k. If create is true, create
54
 
   a new salt or what else must be filled into the s2k for a new key.
55
 
   always needs: dek->algo, s2k->mode, s2k->hash_algo.  */
 
53
/* Hash a passphrase using the supplied s2k. 
 
54
   Always needs: dek->algo, s2k->mode, s2k->hash_algo.  */
56
55
static void
57
 
hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k, int create )
 
56
hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k)
58
57
{
59
58
  gcry_md_hd_t md;
60
59
  int pass, i;
62
61
  int pwlen = strlen(pw);
63
62
 
64
63
  assert ( s2k->hash_algo );
65
 
  dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
 
64
  dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
66
65
  if ( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
67
66
    BUG();
68
67
 
82
81
          int len2 = pwlen + 8;
83
82
          ulong count = len2;
84
83
          
85
 
          if ( create && !pass )
86
 
            {
87
 
              gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
88
 
              if ( s2k->mode == 3 )
89
 
                s2k->count = opt.s2k_count;
90
 
            }
91
 
 
92
84
          if ( s2k->mode == 3 )
93
85
            {
94
86
              count = S2K_DECODE_COUNT(s2k->count);
236
228
/*
237
229
 * Ask the GPG Agent for the passphrase.
238
230
 * Mode 0:  Allow cached passphrase
239
 
 *      1:  No cached passphrase FIXME: Not really implemented
240
 
 *      2:  Ditto, but change the text to "repeat entry"
 
231
 *      1:  No cached passphrase; that is we are asking for a new passphrase
 
232
 *          FIXME: Only partially implemented
241
233
 *
242
234
 * Note that TRYAGAIN_TEXT must not be translated.  If CANCELED is not
243
235
 * NULL, the function does set it to 1 if the user canceled the
246
238
 * computed, this will be used as the cacheid.
247
239
 */
248
240
static char *
249
 
passphrase_get ( u32 *keyid, int mode, const char *cacheid,
 
241
passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
250
242
                 const char *tryagain_text,
251
243
                 const char *custom_description,
252
244
                 const char *custom_prompt, int *canceled)
261
253
  char *my_prompt;
262
254
  char hexfprbuf[20*2+1];
263
255
  const char *my_cacheid;
 
256
  int check = (mode == 1);
264
257
 
265
258
  if (canceled)
266
259
    *canceled = 0;
331
324
      }
332
325
      
333
326
    }
334
 
  else if (mode == 2 ) 
335
 
    atext = xstrdup ( _("Repeat passphrase\n") );
336
327
  else
337
328
    atext = xstrdup ( _("Enter passphrase\n") );
338
329
                
349
340
 
350
341
  my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL;
351
342
 
352
 
  rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, &pw);
 
343
  rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
 
344
                             repeat, check, &pw);
353
345
  
354
346
  xfree (my_prompt);
355
347
  xfree (atext); atext = NULL;
434
426
}
435
427
 
436
428
 
437
 
/****************
438
 
 * Ask for a passphrase and return that string.
439
 
 */
440
 
char *
441
 
ask_passphrase (const char *description,
442
 
                const char *tryagain_text,
443
 
                const char *promptid,
444
 
                const char *prompt,
445
 
                const char *cacheid, int *canceled)
446
 
{
447
 
  char *pw = NULL;
448
 
 
449
 
  (void)promptid;
450
 
  
451
 
  if (canceled)
452
 
    *canceled = 0;
453
 
 
454
 
  if (!opt.batch && description)
455
 
    {
456
 
      if (strchr (description, '%'))
457
 
        {
458
 
          char *tmp = unescape_percent_string
459
 
            ((const unsigned char*)description);
460
 
          tty_printf ("\n%s\n", tmp);
461
 
          xfree (tmp);
462
 
        }
463
 
      else
464
 
        tty_printf ("\n%s\n",description);
465
 
    }
466
 
               
467
 
  if (have_static_passphrase ()) 
468
 
    {
469
 
      pw = xmalloc_secure (strlen(fd_passwd)+1);
470
 
      strcpy (pw, fd_passwd);
471
 
    }
472
 
  else
473
 
    pw = passphrase_get (NULL, 0, cacheid,
474
 
                         tryagain_text, description, prompt,
475
 
                         canceled );
476
 
 
477
 
  if (!pw || !*pw)
478
 
    write_status( STATUS_MISSING_PASSPHRASE );
479
 
 
480
 
  return pw;
481
 
}
482
 
 
483
 
 
484
429
/* Return a new DEK object Using the string-to-key sepcifier S2K.  Use
485
430
   KEYID and PUBKEY_ALGO to prompt the user.  Returns NULL is the user
486
431
   selected to cancel the passphrase entry and if CANCELED is not
488
433
 
489
434
   MODE 0:  Allow cached passphrase
490
435
        1:  Ignore cached passphrase 
491
 
        2:  Ditto, but change the text to "repeat entry"
 
436
        2:  Ditto, but create a new key
 
437
        3:  Allow cached passphrase; use the S2K salt as the cache ID
 
438
        4:  Ditto, but create a new key
492
439
*/
493
440
DEK *
494
 
passphrase_to_dek (u32 *keyid, int pubkey_algo,
495
 
                   int cipher_algo, STRING2KEY *s2k, int mode,
496
 
                   const char *tryagain_text, int *canceled)
 
441
passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
 
442
                       int cipher_algo, STRING2KEY *s2k, int mode,
 
443
                       const char *tryagain_text, 
 
444
                       const char *custdesc, const char *custprompt,
 
445
                       int *canceled)
497
446
{
498
447
  char *pw = NULL;
499
448
  DEK *dek;
506
455
  
507
456
  if ( !s2k )
508
457
    {
 
458
      assert (mode != 3 && mode != 4);
509
459
      /* This is used for the old rfc1991 mode 
510
460
       * Note: This must match the code in encode.c with opt.rfc1991 set */
511
461
      s2k = &help_s2k;
513
463
      s2k->hash_algo = S2K_DIGEST_ALGO;
514
464
    }
515
465
 
 
466
  /* Create a new salt or what else to be filled into the s2k for a
 
467
     new key.  */
 
468
  if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
 
469
    {
 
470
      gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
 
471
      if ( s2k->mode == 3 )
 
472
        s2k->count = opt.s2k_count;
 
473
    }
 
474
 
516
475
  /* If we do not have a passphrase available in NEXT_PW and status
517
476
     information are request, we print them now. */
518
477
  if ( !next_pw && is_status_enabled() ) 
610
569
    }
611
570
  else 
612
571
    {
 
572
      char *cacheid = NULL;
 
573
      char buf[1+16+1];
 
574
 
 
575
      if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
 
576
        {
 
577
          memset (buf, 0, sizeof buf);
 
578
          *buf = 'S';
 
579
          bin2hex (s2k->salt, 8, buf + 1);
 
580
          cacheid = buf;
 
581
        }
 
582
 
613
583
      /* Divert to the gpg-agent. */
614
 
      pw = passphrase_get ( keyid, mode == 2? 1: 0, NULL,
615
 
                            tryagain_text, NULL, NULL, canceled );
 
584
      pw = passphrase_get (keyid, mode == 2, cacheid,
 
585
                           (mode == 2 || mode == 4)? opt.passwd_repeat : 0,
 
586
                           tryagain_text, custdesc, custprompt, canceled);
616
587
      if (*canceled)
617
588
        {
618
589
          xfree (pw);
619
590
          write_status( STATUS_MISSING_PASSPHRASE );
620
591
          return NULL;
621
592
        }
622
 
      if (!pw)
623
 
        pw = xstrdup ("");
624
 
      if ( *pw && mode == 2 )
625
 
        {
626
 
          int i;
627
 
          for(i=0;i<opt.passwd_repeat;i++)
628
 
            {
629
 
              char *pw2 = passphrase_get ( keyid, 2, NULL, NULL, NULL,
630
 
                                           NULL, canceled );
631
 
              if (*canceled)
632
 
                {
633
 
                  xfree (pw);
634
 
                  xfree (pw2);
635
 
                  write_status( STATUS_MISSING_PASSPHRASE );
636
 
                  return NULL;
637
 
                }
638
 
              if (!pw2)
639
 
                pw2 = xstrdup ("");
640
 
              if ( strcmp(pw, pw2) )
641
 
                {
642
 
                  xfree(pw2);
643
 
                  xfree(pw);
644
 
                  return NULL;
645
 
                }
646
 
              xfree(pw2);
647
 
            }
648
 
        }
649
593
    }
650
594
    
651
595
  if ( !pw || !*pw )
656
600
     get_last_passphrase(). */
657
601
  dek = xmalloc_secure_clear ( sizeof *dek );
658
602
  dek->algo = cipher_algo;
659
 
  if ( !*pw && mode == 2 )
 
603
  if ( !*pw && (mode == 2 || mode == 4))
660
604
    dek->keylen = 0;
661
605
  else
662
 
    hash_passphrase( dek, pw, s2k, mode==2 );
 
606
    hash_passphrase (dek, pw, s2k);
663
607
  xfree(last_pw);
664
608
  last_pw = pw;
665
609
  return dek;
666
610
}
 
611
 
 
612
 
 
613
DEK *
 
614
passphrase_to_dek (u32 *keyid, int pubkey_algo,
 
615
                   int cipher_algo, STRING2KEY *s2k, int mode,
 
616
                   const char *tryagain_text, int *canceled)
 
617
{
 
618
  return passphrase_to_dek_ext (keyid, pubkey_algo, cipher_algo,
 
619
                                s2k, mode, tryagain_text, NULL, NULL,
 
620
                                canceled);
 
621
}