LCOV - code coverage report
Current view: top level - g10 - passphrase.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 92 277 33.2 %
Date: 2015-11-05 17:10:59 Functions: 6 13 46.2 %

          Line data    Source code
       1             : /* passphrase.c -  Get a passphrase
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
       3             :  *               2005, 2006, 2007, 2009, 2011 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 <stddef.h>
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <unistd.h>
      27             : #include <assert.h>
      28             : #include <errno.h>
      29             : #ifdef HAVE_LOCALE_H
      30             : #include <locale.h>
      31             : #endif
      32             : #ifdef HAVE_LANGINFO_CODESET
      33             : #include <langinfo.h>
      34             : #endif
      35             : 
      36             : #include "gpg.h"
      37             : #include "util.h"
      38             : #include "options.h"
      39             : #include "ttyio.h"
      40             : #include "keydb.h"
      41             : #include "main.h"
      42             : #include "i18n.h"
      43             : #include "status.h"
      44             : #include "call-agent.h"
      45             : #include "../common/shareddefs.h"
      46             : 
      47             : static char *fd_passwd = NULL;
      48             : static char *next_pw = NULL;
      49             : static char *last_pw = NULL;
      50             : 
      51             : 
      52             : 
      53             : /* Pack an s2k iteration count into the form specified in 2440.  If
      54             :    we're in between valid values, round up.  With value 0 return the
      55             :    old default.  */
      56             : unsigned char
      57         436 : encode_s2k_iterations (int iterations)
      58             : {
      59             :   gpg_error_t err;
      60         436 :   unsigned char c=0;
      61             :   unsigned char result;
      62             :   unsigned int count;
      63             : 
      64         436 :   if (!iterations)
      65             :     {
      66             :       unsigned long mycnt;
      67             : 
      68             :       /* Ask the gpg-agent for a useful iteration count.  */
      69           0 :       err = agent_get_s2k_count (&mycnt);
      70           0 :       if (err || mycnt < 65536)
      71             :         {
      72             :           /* Don't print an error if an older agent is used.  */
      73           0 :           if (err && gpg_err_code (err) != GPG_ERR_ASS_PARAMETER)
      74           0 :             log_error (_("problem with the agent: %s\n"), gpg_strerror (err));
      75             :           /* Default to 65536 which we used up to 2.0.13.  */
      76           0 :           return 96;
      77             :         }
      78           0 :       else if (mycnt >= 65011712)
      79           0 :         return 255; /* Largest possible value.  */
      80             :       else
      81           0 :         return encode_s2k_iterations ((int)mycnt);
      82             :     }
      83             : 
      84         436 :   if (iterations <= 1024)
      85           0 :     return 0;  /* Command line arg compatibility.  */
      86             : 
      87         436 :   if (iterations >= 65011712)
      88           0 :     return 255;
      89             : 
      90             :   /* Need count to be in the range 16-31 */
      91        3052 :   for (count=iterations>>6; count>=32; count>>=1)
      92        2616 :     c++;
      93             : 
      94         436 :   result = (c<<4)|(count-16);
      95             : 
      96         436 :   if (S2K_DECODE_COUNT(result) < iterations)
      97           0 :     result++;
      98             : 
      99         436 :   return result;
     100             : }
     101             : 
     102             : 
     103             : int
     104         436 : have_static_passphrase()
     105             : {
     106         872 :   return (!!fd_passwd
     107         436 :           && (opt.batch || opt.pinentry_mode == PINENTRY_MODE_LOOPBACK));
     108             : }
     109             : 
     110             : /* Return a static passphrase.  The returned value is only valid as
     111             :    long as no other passphrase related function is called.  NULL may
     112             :    be returned if no passphrase has been set; better use
     113             :    have_static_passphrase first.  */
     114             : const char *
     115           0 : get_static_passphrase (void)
     116             : {
     117           0 :   return fd_passwd;
     118             : }
     119             : 
     120             : 
     121             : /****************
     122             :  * Set the passphrase to be used for the next query and only for the next
     123             :  * one.
     124             :  */
     125             : void
     126           0 : set_next_passphrase( const char *s )
     127             : {
     128           0 :   xfree(next_pw);
     129           0 :   next_pw = NULL;
     130           0 :   if ( s )
     131             :     {
     132           0 :       next_pw = xmalloc_secure( strlen(s)+1 );
     133           0 :       strcpy (next_pw, s );
     134             :     }
     135           0 : }
     136             : 
     137             : /****************
     138             :  * Get the last passphrase used in passphrase_to_dek.
     139             :  * Note: This removes the passphrase from this modules and
     140             :  * the caller must free the result.  May return NULL:
     141             :  */
     142             : char *
     143           0 : get_last_passphrase()
     144             : {
     145           0 :   char *p = last_pw;
     146           0 :   last_pw = NULL;
     147           0 :   return p;
     148             : }
     149             : 
     150             : /* Here's an interesting question: since this passphrase was passed in
     151             :    on the command line, is there really any point in using secure
     152             :    memory for it?  I'm going with 'yes', since it doesn't hurt, and
     153             :    might help in some small way (swapping). */
     154             : 
     155             : void
     156           0 : set_passphrase_from_string(const char *pass)
     157             : {
     158           0 :   xfree (fd_passwd);
     159           0 :   fd_passwd = xmalloc_secure(strlen(pass)+1);
     160           0 :   strcpy (fd_passwd, pass);
     161           0 : }
     162             : 
     163             : 
     164             : void
     165         493 : read_passphrase_from_fd( int fd )
     166             : {
     167             :   int i, len;
     168             :   char *pw;
     169             : 
     170         493 :   if ( !opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
     171             :     { /* Not used but we have to do a dummy read, so that it won't end
     172             :          up at the begin of the message if the quite usual trick to
     173             :          prepend the passphtrase to the message is used. */
     174             :       char buf[1];
     175             : 
     176           0 :       while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
     177             :         ;
     178           0 :       *buf = 0;
     179         493 :       return;
     180             :     }
     181             : 
     182        7640 :   for (pw = NULL, i = len = 100; ; i++ )
     183             :     {
     184        7640 :       if (i >= len-1 )
     185             :         {
     186         493 :           char *pw2 = pw;
     187         493 :           len += 100;
     188         493 :           pw = xmalloc_secure( len );
     189         493 :           if( pw2 )
     190             :             {
     191           0 :               memcpy(pw, pw2, i );
     192           0 :               xfree (pw2);
     193             :             }
     194             :           else
     195         493 :             i=0;
     196             :         }
     197        7640 :       if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
     198             :         break;
     199        7147 :     }
     200         493 :   pw[i] = 0;
     201         493 :   if (!opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
     202           0 :     tty_printf("\b\b\b   \n" );
     203             : 
     204         493 :   xfree ( fd_passwd );
     205         493 :   fd_passwd = pw;
     206             : }
     207             : 
     208             : 
     209             : /*
     210             :  * Ask the GPG Agent for the passphrase.
     211             :  * Mode 0:  Allow cached passphrase
     212             :  *      1:  No cached passphrase; that is we are asking for a new passphrase
     213             :  *          FIXME: Only partially implemented
     214             :  *
     215             :  * Note that TRYAGAIN_TEXT must not be translated.  If CANCELED is not
     216             :  * NULL, the function does set it to 1 if the user canceled the
     217             :  * operation.  If CACHEID is not NULL, it will be used as the cacheID
     218             :  * for the gpg-agent; if is NULL and a key fingerprint can be
     219             :  * computed, this will be used as the cacheid.
     220             :  */
     221             : static char *
     222           0 : passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
     223             :                  const char *tryagain_text,
     224             :                  const char *custom_description,
     225             :                  const char *custom_prompt, int *canceled)
     226             : {
     227             :   int rc;
     228           0 :   char *atext = NULL;
     229           0 :   char *pw = NULL;
     230           0 :   PKT_public_key *pk = xmalloc_clear( sizeof *pk );
     231             :   byte fpr[MAX_FINGERPRINT_LEN];
     232           0 :   int have_fpr = 0;
     233             :   char *orig_codeset;
     234             :   char *my_prompt;
     235             :   char hexfprbuf[20*2+1];
     236             :   const char *my_cacheid;
     237           0 :   int check = (mode == 1);
     238             : 
     239           0 :   if (canceled)
     240           0 :     *canceled = 0;
     241             : 
     242             : #if MAX_FINGERPRINT_LEN < 20
     243             : #error agent needs a 20 byte fingerprint
     244             : #endif
     245             : 
     246           0 :   memset (fpr, 0, MAX_FINGERPRINT_LEN );
     247           0 :   if( keyid && get_pubkey( pk, keyid ) )
     248             :     {
     249           0 :       free_public_key (pk);
     250           0 :       pk = NULL; /* oops: no key for some reason */
     251             :     }
     252             : 
     253           0 :   orig_codeset = i18n_switchto_utf8 ();
     254             : 
     255           0 :   if (custom_description)
     256           0 :     atext = native_to_utf8 (custom_description);
     257           0 :   else if ( !mode && pk && keyid )
     258           0 :     {
     259             :       char *uid;
     260             :       size_t uidlen;
     261           0 :       const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo );
     262             :       const char *timestr;
     263             :       char *maink;
     264             : 
     265           0 :       if ( !algo_name )
     266           0 :         algo_name = "?";
     267             : 
     268           0 :       if (keyid[2] && keyid[3]
     269           0 :           && keyid[0] != keyid[2]
     270           0 :           && keyid[1] != keyid[3] )
     271           0 :         maink = xasprintf (_(" (main key ID %s)"), keystr (&keyid[2]));
     272             :       else
     273           0 :         maink = xstrdup ("");
     274             : 
     275           0 :       uid = get_user_id ( keyid, &uidlen );
     276           0 :       timestr = strtimestamp (pk->timestamp);
     277             : 
     278           0 :       atext = xasprintf (_("Please enter the passphrase to unlock the"
     279             :                            " secret key for the OpenPGP certificate:\n"
     280             :                            "\"%.*s\"\n"
     281             :                            "%u-bit %s key, ID %s,\n"
     282             :                            "created %s%s.\n"),
     283             :                          (int)uidlen, uid,
     284             :                          nbits_from_pk (pk), algo_name, keystr(&keyid[0]),
     285             :                          timestr, maink);
     286           0 :       xfree (uid);
     287           0 :       xfree (maink);
     288             : 
     289             :       {
     290             :         size_t dummy;
     291           0 :         fingerprint_from_pk( pk, fpr, &dummy );
     292           0 :         have_fpr = 1;
     293             :       }
     294             : 
     295             :     }
     296             :   else
     297           0 :     atext = xstrdup ( _("Enter passphrase\n") );
     298             : 
     299             : 
     300           0 :   if (!mode && cacheid)
     301           0 :     my_cacheid = cacheid;
     302           0 :   else if (!mode && have_fpr)
     303           0 :     my_cacheid = bin2hex (fpr, 20, hexfprbuf);
     304             :   else
     305           0 :     my_cacheid = NULL;
     306             : 
     307           0 :   if (tryagain_text)
     308           0 :     tryagain_text = _(tryagain_text);
     309             : 
     310           0 :   my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL;
     311             : 
     312           0 :   rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext,
     313             :                              repeat, check, &pw);
     314             : 
     315           0 :   xfree (my_prompt);
     316           0 :   xfree (atext); atext = NULL;
     317             : 
     318           0 :   i18n_switchback (orig_codeset);
     319             : 
     320             : 
     321           0 :   if (!rc)
     322             :     ;
     323           0 :   else if (gpg_err_code (rc) == GPG_ERR_CANCELED
     324           0 :             || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
     325             :     {
     326           0 :       log_info (_("cancelled by user\n") );
     327           0 :       if (canceled)
     328           0 :         *canceled = 1;
     329             :     }
     330             :   else
     331             :     {
     332           0 :       log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
     333             :       /* Due to limitations in the API of the upper layers they
     334             :          consider an error as no passphrase entered.  This works in
     335             :          most cases but not during key creation where this should
     336             :          definitely not happen and let it continue without requiring a
     337             :          passphrase.  Given that now all the upper layers handle a
     338             :          cancel correctly, we simply set the cancel flag now for all
     339             :          errors from the agent.  */
     340           0 :       if (canceled)
     341           0 :         *canceled = 1;
     342             : 
     343           0 :       write_status_errcode ("get_passphrase", rc);
     344             :     }
     345             : 
     346           0 :   free_public_key (pk);
     347           0 :   if (rc)
     348             :     {
     349           0 :       xfree (pw);
     350           0 :       return NULL;
     351             :     }
     352           0 :   return pw;
     353             : }
     354             : 
     355             : 
     356             : /*
     357             :  * Clear the cached passphrase.  If CACHEID is not NULL, it will be
     358             :  * used instead of a cache ID derived from KEYID.
     359             :  */
     360             : void
     361           0 : passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
     362             : {
     363             :   int rc;
     364             : 
     365             :   (void)algo;
     366             : 
     367           0 :   if (!cacheid)
     368             :     {
     369             :       PKT_public_key *pk;
     370             : #     if MAX_FINGERPRINT_LEN < 20
     371             : #       error agent needs a 20 byte fingerprint
     372             : #     endif
     373             :       byte fpr[MAX_FINGERPRINT_LEN];
     374             :       char hexfprbuf[2*20+1];
     375             :       size_t dummy;
     376             : 
     377           0 :       pk = xcalloc (1, sizeof *pk);
     378           0 :       if ( !keyid || get_pubkey( pk, keyid ) )
     379             :         {
     380           0 :           log_error ("key not found in passphrase_clear_cache\n");
     381           0 :           free_public_key (pk);
     382           0 :           return;
     383             :         }
     384           0 :       memset (fpr, 0, MAX_FINGERPRINT_LEN );
     385           0 :       fingerprint_from_pk ( pk, fpr, &dummy );
     386           0 :       bin2hex (fpr, 20, hexfprbuf);
     387           0 :       rc = agent_clear_passphrase (hexfprbuf);
     388           0 :       free_public_key ( pk );
     389             :     }
     390             :   else
     391           0 :     rc = agent_clear_passphrase (cacheid);
     392             : 
     393           0 :   if (rc)
     394           0 :     log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
     395             : }
     396             : 
     397             : 
     398             : /* Return a new DEK object using the string-to-key specifier S2K.  Use
     399             :    KEYID and PUBKEY_ALGO to prompt the user.  Returns NULL is the user
     400             :    selected to cancel the passphrase entry and if CANCELED is not
     401             :    NULL, sets it to true.
     402             : 
     403             :    MODE 0:  Allow cached passphrase
     404             :         1:  Ignore cached passphrase
     405             :         2:  Ditto, but create a new key
     406             :         3:  Allow cached passphrase; use the S2K salt as the cache ID
     407             :         4:  Ditto, but create a new key
     408             : */
     409             : DEK *
     410         436 : passphrase_to_dek_ext (u32 *keyid, int pubkey_algo,
     411             :                        int cipher_algo, STRING2KEY *s2k, int mode,
     412             :                        const char *tryagain_text,
     413             :                        const char *custdesc, const char *custprompt,
     414             :                        int *canceled)
     415             : {
     416         436 :   char *pw = NULL;
     417             :   DEK *dek;
     418             :   STRING2KEY help_s2k;
     419             :   int dummy_canceled;
     420         436 :   char s2k_cacheidbuf[1+16+1], *s2k_cacheid = NULL;
     421             : 
     422         436 :   if (!canceled)
     423         218 :     canceled = &dummy_canceled;
     424         436 :   *canceled = 0;
     425             : 
     426         436 :   if ( !s2k )
     427             :     {
     428           0 :       assert (mode != 3 && mode != 4);
     429             :       /* This is used for the old rfc1991 mode
     430             :        * Note: This must match the code in encode.c with opt.rfc1991 set */
     431           0 :       s2k = &help_s2k;
     432           0 :       s2k->mode = 0;
     433           0 :       s2k->hash_algo = S2K_DIGEST_ALGO;
     434             :     }
     435             : 
     436             :   /* Create a new salt or what else to be filled into the s2k for a
     437             :      new key.  */
     438         436 :   if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
     439             :     {
     440         218 :       gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
     441         218 :       if ( s2k->mode == 3 )
     442             :         {
     443             :           /* We delay the encoding until it is really needed.  This is
     444             :              if we are going to dynamically calibrate it, we need to
     445             :              call out to gpg-agent and that should not be done during
     446             :              option processing in main().  */
     447         218 :           if (!opt.s2k_count)
     448           0 :             opt.s2k_count = encode_s2k_iterations (0);
     449         218 :           s2k->count = opt.s2k_count;
     450             :         }
     451             :     }
     452             : 
     453             :   /* If we do not have a passphrase available in NEXT_PW and status
     454             :      information are request, we print them now. */
     455         436 :   if ( !next_pw && is_status_enabled() )
     456             :     {
     457             :       char buf[50];
     458             : 
     459           0 :       if ( keyid )
     460             :         {
     461           0 :           emit_status_need_passphrase (keyid,
     462           0 :                                        keyid[2] && keyid[3]? keyid+2:NULL,
     463             :                                        pubkey_algo);
     464             :         }
     465             :       else
     466             :         {
     467           0 :           snprintf (buf, sizeof buf -1, "%d %d %d",
     468           0 :                     cipher_algo, s2k->mode, s2k->hash_algo );
     469           0 :           write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf );
     470             :         }
     471             :     }
     472             : 
     473             :   /* If we do have a keyID, we do not have a passphrase available in
     474             :      NEXT_PW, we are not running in batch mode and we do not want to
     475             :      ignore the passphrase cache (mode!=1), print a prompt with
     476             :      information on that key. */
     477         436 :   if ( keyid && !opt.batch && !next_pw && mode!=1 )
     478             :     {
     479           0 :       PKT_public_key *pk = xmalloc_clear( sizeof *pk );
     480             :       char *p;
     481             : 
     482           0 :       p = get_user_id_native(keyid);
     483           0 :       tty_printf ("\n");
     484           0 :       tty_printf (_("You need a passphrase to unlock the secret key for\n"
     485             :                     "user: \"%s\"\n"),p);
     486           0 :       xfree(p);
     487             : 
     488           0 :       if ( !get_pubkey( pk, keyid ) )
     489             :         {
     490           0 :           const char *s = openpgp_pk_algo_name ( pk->pubkey_algo );
     491             : 
     492           0 :           tty_printf (_("%u-bit %s key, ID %s, created %s"),
     493             :                       nbits_from_pk( pk ), s?s:"?", keystr(keyid),
     494             :                       strtimestamp(pk->timestamp) );
     495           0 :           if ( keyid[2] && keyid[3]
     496           0 :                && keyid[0] != keyid[2] && keyid[1] != keyid[3] )
     497             :             {
     498           0 :               if ( keystrlen () > 10 )
     499             :                 {
     500           0 :                   tty_printf ("\n");
     501           0 :                   tty_printf (_("         (subkey on main key ID %s)"),
     502             :                               keystr(&keyid[2]) );
     503             :                 }
     504             :               else
     505           0 :                 tty_printf ( _(" (main key ID %s)"), keystr(&keyid[2]) );
     506             :             }
     507           0 :           tty_printf("\n");
     508             :         }
     509             : 
     510           0 :       tty_printf("\n");
     511           0 :       free_public_key (pk);
     512             :     }
     513             : 
     514         436 :   if ( next_pw )
     515             :     {
     516             :       /* Simply return the passphrase we already have in NEXT_PW. */
     517           0 :       pw = next_pw;
     518           0 :       next_pw = NULL;
     519             :     }
     520         436 :   else if ( have_static_passphrase () )
     521             :     {
     522             :       /* Return the passphrase we have stored in FD_PASSWD. */
     523         436 :       pw = xmalloc_secure ( strlen(fd_passwd)+1 );
     524         436 :       strcpy ( pw, fd_passwd );
     525             :     }
     526             :   else
     527             :     {
     528           0 :       if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3))
     529             :         {
     530           0 :           memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf);
     531           0 :           *s2k_cacheidbuf = 'S';
     532           0 :           bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1);
     533           0 :           s2k_cacheid = s2k_cacheidbuf;
     534             :         }
     535             : 
     536           0 :       if (opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
     537             :         {
     538             :           char buf[32];
     539             : 
     540           0 :           snprintf (buf, sizeof (buf), "%u", 100);
     541           0 :           write_status_text (STATUS_INQUIRE_MAXLEN, buf);
     542             :         }
     543             : 
     544             :       /* Divert to the gpg-agent. */
     545           0 :       pw = passphrase_get (keyid, mode == 2, s2k_cacheid,
     546           0 :                            (mode == 2 || mode == 4)? opt.passphrase_repeat : 0,
     547             :                            tryagain_text, custdesc, custprompt, canceled);
     548           0 :       if (*canceled)
     549             :         {
     550           0 :           xfree (pw);
     551           0 :           write_status( STATUS_MISSING_PASSPHRASE );
     552           0 :           return NULL;
     553             :         }
     554             :     }
     555             : 
     556         436 :   if ( !pw || !*pw )
     557           0 :     write_status( STATUS_MISSING_PASSPHRASE );
     558             : 
     559             :   /* Hash the passphrase and store it in a newly allocated DEK object.
     560             :      Keep a copy of the passphrase in LAST_PW for use by
     561             :      get_last_passphrase(). */
     562         436 :   dek = xmalloc_secure_clear ( sizeof *dek );
     563         436 :   dek->algo = cipher_algo;
     564         436 :   if ( (!pw || !*pw) && (mode == 2 || mode == 4))
     565           0 :     dek->keylen = 0;
     566             :   else
     567             :     {
     568             :       gpg_error_t err;
     569             : 
     570         436 :       dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
     571         436 :       if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
     572           0 :         BUG ();
     573        1744 :       err = gcry_kdf_derive (pw, strlen (pw),
     574         436 :                              s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
     575           0 :                              s2k->mode == 1? GCRY_KDF_SALTED_S2K :
     576             :                              /* */           GCRY_KDF_SIMPLE_S2K,
     577         436 :                              s2k->hash_algo, s2k->salt, 8,
     578         436 :                              S2K_DECODE_COUNT(s2k->count),
     579         436 :                              dek->keylen, dek->key);
     580         436 :       if (err)
     581             :         {
     582           0 :           log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err));
     583           0 :           xfree (pw);
     584           0 :           xfree (dek);
     585           0 :           write_status( STATUS_MISSING_PASSPHRASE );
     586           0 :           return NULL;
     587             :         }
     588             :     }
     589         436 :   if (s2k_cacheid)
     590           0 :     memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid);
     591         436 :   xfree(last_pw);
     592         436 :   last_pw = pw;
     593         436 :   return dek;
     594             : }
     595             : 
     596             : 
     597             : DEK *
     598         436 : passphrase_to_dek (u32 *keyid, int pubkey_algo,
     599             :                    int cipher_algo, STRING2KEY *s2k, int mode,
     600             :                    const char *tryagain_text, int *canceled)
     601             : {
     602         436 :   return passphrase_to_dek_ext (keyid, pubkey_algo, cipher_algo,
     603             :                                 s2k, mode, tryagain_text, NULL, NULL,
     604             :                                 canceled);
     605             : }
     606             : 
     607             : 
     608             : /* Emit the USERID_HINT and the NEED_PASSPHRASE status messages.
     609             :    MAINKEYID may be NULL. */
     610             : void
     611           0 : emit_status_need_passphrase (u32 *keyid, u32 *mainkeyid, int pubkey_algo)
     612             : {
     613             :   char buf[50];
     614             :   char *us;
     615             : 
     616           0 :   us = get_long_user_id_string (keyid);
     617           0 :   write_status_text (STATUS_USERID_HINT, us);
     618           0 :   xfree (us);
     619             : 
     620           0 :   snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0",
     621           0 :             (ulong)keyid[0],
     622           0 :             (ulong)keyid[1],
     623           0 :             (ulong)(mainkeyid? mainkeyid[0]:keyid[0]),
     624           0 :             (ulong)(mainkeyid? mainkeyid[1]:keyid[1]),
     625             :             pubkey_algo);
     626             : 
     627           0 :   write_status_text (STATUS_NEED_PASSPHRASE, buf);
     628           0 : }
     629             : 
     630             : 
     631             : /* Return an allocated utf-8 string describing the key PK.  If ESCAPED
     632             :    is true spaces and control characters are percent or plus escaped.
     633             :    MODE describes the use of the key description; use one of the
     634             :    FORMAT_KEYDESC_ macros. */
     635             : char *
     636         386 : gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
     637             : {
     638             :   char *uid;
     639             :   size_t uidlen;
     640             :   const char *algo_name;
     641             :   const char *timestr;
     642             :   char *orig_codeset;
     643             :   char *maink;
     644             :   char *desc;
     645             :   const char *prompt;
     646         386 :   const char *trailer = "";
     647             :   int is_subkey;
     648             : 
     649        1155 :   is_subkey = (pk->main_keyid[0] && pk->main_keyid[1]
     650         383 :                && pk->keyid[0] != pk->main_keyid[0]
     651         645 :                && pk->keyid[1] != pk->main_keyid[1]);
     652         386 :   algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
     653         386 :   timestr = strtimestamp (pk->timestamp);
     654         386 :   uid = get_user_id (is_subkey? pk->main_keyid:pk->keyid, &uidlen);
     655             : 
     656         386 :   orig_codeset = i18n_switchto_utf8 ();
     657             : 
     658         386 :   if (is_subkey)
     659         259 :     maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
     660             :   else
     661         127 :     maink = NULL;
     662             : 
     663         386 :   switch (mode)
     664             :     {
     665             :     case FORMAT_KEYDESC_NORMAL:
     666         372 :       prompt = _("Please enter the passphrase to unlock the"
     667             :                  " OpenPGP secret key:");
     668         372 :       break;
     669             :     case FORMAT_KEYDESC_IMPORT:
     670          14 :       prompt = _("Please enter the passphrase to import the"
     671             :                  " OpenPGP secret key:");
     672          14 :       break;
     673             :     case FORMAT_KEYDESC_EXPORT:
     674           0 :       if (is_subkey)
     675           0 :         prompt = _("Please enter the passphrase to export the"
     676             :                    " OpenPGP secret subkey:");
     677             :       else
     678           0 :         prompt = _("Please enter the passphrase to export the"
     679             :                    " OpenPGP secret key:");
     680           0 :       break;
     681             :     case FORMAT_KEYDESC_DELKEY:
     682           0 :       if (is_subkey)
     683           0 :         prompt = _("Do you really want to permanently delete the"
     684             :                    " OpenPGP secret subkey key:");
     685             :       else
     686           0 :         prompt = _("Do you really want to permanently delete the"
     687             :                    " OpenPGP secret key:");
     688           0 :       trailer = "?";
     689           0 :       break;
     690             :     default:
     691           0 :       prompt = "?";
     692           0 :       break;
     693             :     }
     694             : 
     695         772 :   desc = xtryasprintf (_("%s\n"
     696             :                          "\"%.*s\"\n"
     697             :                          "%u-bit %s key, ID %s,\n"
     698             :                          "created %s%s.\n%s"),
     699             :                        prompt,
     700             :                        (int)uidlen, uid,
     701             :                        nbits_from_pk (pk), algo_name,
     702         386 :                        keystr (pk->keyid), timestr,
     703             :                        maink?maink:"", trailer);
     704         386 :   xfree (maink);
     705         386 :   xfree (uid);
     706             : 
     707         386 :   i18n_switchback (orig_codeset);
     708             : 
     709         386 :   if (escaped)
     710             :     {
     711         386 :       char *tmp = percent_plus_escape (desc);
     712         386 :       xfree (desc);
     713         386 :       desc = tmp;
     714             :     }
     715             : 
     716         386 :   return desc;
     717             : }

Generated by: LCOV version 1.11