de4ca6cf19ef9b049943e4f121bce513ab754ad7
[gnupg.git] / g10 / passphrase.c
1 /* passphrase.c -  Get a passphrase
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3  *               2006 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 #if !defined(HAVE_DOSISH_SYSTEM) && !defined(__riscos__)
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #endif
32 #if defined (_WIN32)
33 #include <windows.h>
34 #endif
35 #include <errno.h>
36 #ifdef HAVE_LOCALE_H
37 #include <locale.h>
38 #endif
39 #ifdef HAVE_LANGINFO_CODESET
40 #include <langinfo.h>
41 #endif
42
43 #include "util.h"
44 #include "memory.h"
45 #include "options.h"
46 #include "ttyio.h"
47 #include "cipher.h"
48 #include "keydb.h"
49 #include "main.h"
50 #include "i18n.h"
51 #include "status.h"
52 #ifdef ENABLE_AGENT_SUPPORT
53 #include "assuan.h"
54 #endif /*ENABLE_AGENT_SUPPORT*/
55
56 static char *fd_passwd = NULL;
57 static char *next_pw = NULL;
58 static char *last_pw = NULL;
59
60 static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create );
61
62 int
63 have_static_passphrase()
64 {
65     if ( opt.use_agent )
66         return 0;
67     return !!fd_passwd;
68 }
69
70 /****************
71  * Set the passphrase to be used for the next query and only for the next
72  * one.
73  */
74 void
75 set_next_passphrase( const char *s )
76 {
77     xfree(next_pw);
78     next_pw = NULL;
79     if( s ) {
80         next_pw = xmalloc_secure( strlen(s)+1 );
81         strcpy(next_pw, s );
82     }
83 }
84
85 /****************
86  * Get the last passphrase used in passphrase_to_dek.
87  * Note: This removes the passphrase from this modules and
88  * the caller must free the result.  May return NULL:
89  */
90 char *
91 get_last_passphrase()
92 {
93     char *p = last_pw;
94     last_pw = NULL;
95     return p;
96 }
97
98 /* As if we had used the passphrase - make it the last_pw. */
99 void
100 next_to_last_passphrase(void)
101 {
102   if(next_pw)
103     {
104       last_pw=next_pw;
105       next_pw=NULL;
106     }
107 }
108
109 /* Here's an interesting question: since this passphrase was passed in
110    on the command line, is there really any point in using secure
111    memory for it?  I'm going with 'yes', since it doesn't hurt, and
112    might help in some small way (swapping). */
113
114 void
115 set_passphrase_from_string(const char *pass)
116 {
117   xfree( fd_passwd );
118   fd_passwd = xmalloc_secure(strlen(pass)+1);
119   strcpy(fd_passwd,pass);
120 }
121
122
123 void
124 read_passphrase_from_fd( int fd )
125 {
126   int i, len;
127   char *pw;
128   
129   if ( opt.use_agent ) 
130     { /* Not used but we have to do a dummy read, so that it won't end
131          up at the begin of the message if the quite usual trick to
132          prepend the passphtrase to the message is used. */
133       char buf[1];
134
135       while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
136         ;
137       *buf = 0;
138       return; 
139     }
140
141   if (!opt.batch )
142         tty_printf("Reading passphrase from file descriptor %d ...", fd );
143   for (pw = NULL, i = len = 100; ; i++ ) 
144     {
145       if (i >= len-1 ) 
146         {
147           char *pw2 = pw;
148           len += 100;
149           pw = xmalloc_secure( len );
150           if( pw2 )
151             {
152               memcpy(pw, pw2, i );
153               xfree (pw2);
154             }
155           else
156             i=0;
157         }
158       if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
159         break;
160     }
161   pw[i] = 0;
162   if (!opt.batch)
163     tty_printf("\b\b\b   \n" );
164
165   xfree( fd_passwd );
166   fd_passwd = pw;
167 }
168
169
170
171 #ifdef ENABLE_AGENT_SUPPORT
172 /* Send one option to the gpg-agent.  */
173 static int
174 agent_send_option (assuan_context_t ctx, const char *name, const char *value)
175 {
176   char *line;
177   int rc; 
178   
179   if (!value || !*value)
180     return 0; /* Avoid sending empty option values. */
181
182   line = xmalloc (7 + strlen (name) + 1 + strlen (value) + 1);
183   strcpy (stpcpy (stpcpy (stpcpy (line, "OPTION "), name), "="), value);
184   rc = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
185   xfree (line);
186   return rc? -1 : 0;
187 }
188
189 /* Send all required options to the gpg-agent.  */
190 static int 
191 agent_send_all_options (assuan_context_t ctx)
192 {
193   char *dft_display = NULL;
194   const char *dft_ttyname = NULL;
195   char *dft_ttytype = NULL;
196   char *old_lc = NULL;
197   char *dft_lc = NULL;
198   int rc = 0;
199
200   dft_display = getenv ("DISPLAY");
201   if (opt.display || dft_display)
202     {
203       if (agent_send_option (ctx, "display",
204                              opt.display ? opt.display : dft_display))
205         return -1;
206     }
207
208   if (!opt.ttyname)
209     {
210       const char *tmp;
211
212       dft_ttyname = getenv ("GPG_TTY");
213       if ((!dft_ttyname || !*dft_ttyname) && (tmp=ttyname (0)))
214         dft_ttyname = tmp;
215       if ((!dft_ttyname || !*dft_ttyname) && (tmp=tty_get_ttyname ()))
216         dft_ttyname = tmp;
217     }
218   if (opt.ttyname || dft_ttyname)
219     {
220       if (agent_send_option (ctx, "ttyname",
221                              opt.ttyname ? opt.ttyname : dft_ttyname))
222         return -1;
223     }
224
225   dft_ttytype = getenv ("TERM");
226   if (opt.ttytype || (dft_ttyname && dft_ttytype))
227     {
228       if (agent_send_option (ctx, "ttytype",
229                              opt.ttyname ? opt.ttytype : dft_ttytype))
230         return -1;
231     }
232
233 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
234   old_lc = setlocale (LC_CTYPE, NULL);
235   if (old_lc)
236     old_lc = xstrdup (old_lc);
237   dft_lc = setlocale (LC_CTYPE, "");
238 #endif
239   if (opt.lc_ctype || (dft_ttyname && dft_lc))
240     {
241       rc = agent_send_option (ctx, "lc-ctype",
242                               opt.lc_ctype ? opt.lc_ctype : dft_lc);
243     }
244 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
245   if (old_lc)
246     {
247       setlocale (LC_CTYPE, old_lc);
248       xfree (old_lc);
249     }
250 #endif
251   if (rc)
252     return rc;
253
254 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
255   old_lc = setlocale (LC_MESSAGES, NULL);
256   if (old_lc)
257     old_lc = xstrdup (old_lc);
258   dft_lc = setlocale (LC_MESSAGES, "");
259 #endif
260   if (opt.lc_messages || (dft_ttyname && dft_lc))
261     {
262       rc = agent_send_option (ctx, "lc-messages",
263                               opt.lc_messages ? opt.lc_messages : dft_lc);
264     }
265 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
266   if (old_lc)
267     {
268       setlocale (LC_MESSAGES, old_lc);
269       xfree (old_lc);
270     }
271 #endif
272   return rc;
273 }
274 #endif /*ENABLE_AGENT_SUPPORT*/
275
276
277 /*
278  * Open a connection to the agent and initializes the connection.
279  * Returns: -1 on error; on success an Assuan context for that
280  * connection is returned.  With TRY set to true, no error messages
281  * are printed and the use of the agent won't get disabled on failure.
282  * If ORIG_CODESET is not NULL, the function will swithc the codeset
283  * back to that one before printing error messages.
284  */
285 #ifdef ENABLE_AGENT_SUPPORT
286 assuan_context_t
287 agent_open (int try, const char *orig_codeset)
288 {
289   int rc;
290   assuan_context_t ctx;
291   char *infostr, *p;
292   int prot;
293   int pid;
294
295   if (opt.gpg_agent_info)
296     infostr = xstrdup (opt.gpg_agent_info);
297   else
298     {
299       infostr = getenv ( "GPG_AGENT_INFO" );
300       if (!infostr || !*infostr) 
301         {
302           if (!try)
303             {
304 #ifdef ENABLE_NLS
305               if (orig_codeset)
306                 bind_textdomain_codeset (PACKAGE, orig_codeset);
307 #endif /*ENABLE_NLS*/
308               log_info (_("gpg-agent is not available in this session\n"));
309               opt.use_agent = 0;
310             }
311           return NULL;
312         }
313       infostr = xstrdup ( infostr );
314     }
315   
316   if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
317     {
318       if (!try)
319         {
320 #ifdef ENABLE_NLS
321           if (orig_codeset)
322             bind_textdomain_codeset (PACKAGE, orig_codeset);
323 #endif /*ENABLE_NLS*/
324           log_error ( _("malformed GPG_AGENT_INFO environment variable\n"));
325           opt.use_agent = 0;
326         }
327       xfree (infostr);
328       return NULL;
329     }
330   *p++ = 0;
331   pid = atoi (p);
332   while (*p && *p != PATHSEP_C)
333     p++;
334   prot = *p? atoi (p+1) : 0;
335   if (prot != 1)
336     {
337       if (!try)
338         {
339 #ifdef ENABLE_NLS
340           if (orig_codeset)
341             bind_textdomain_codeset (PACKAGE, orig_codeset);
342 #endif /*ENABLE_NLS*/
343           log_error (_("gpg-agent protocol version %d is not supported\n"),
344                      prot);
345           opt.use_agent = 0;
346         }
347       xfree (infostr);
348       return NULL;
349     }
350      
351   rc = assuan_socket_connect (&ctx, infostr, pid);
352   if (rc)
353     {
354       if (!try)
355         {
356 #ifdef ENABLE_NLS
357           if (orig_codeset)
358             bind_textdomain_codeset (PACKAGE, orig_codeset);
359 #endif /*ENABLE_NLS*/
360           log_info ( _("can't connect to `%s': %s\n"), 
361                       infostr, assuan_strerror (rc));
362           opt.use_agent = 0;
363         }
364       xfree (infostr );
365       return NULL;
366     }
367   xfree (infostr);
368
369   if (agent_send_all_options (ctx))
370     {
371       if (!try)
372         {
373 #ifdef ENABLE_NLS
374           if (orig_codeset)
375             bind_textdomain_codeset (PACKAGE, orig_codeset);
376 #endif /*ENABLE_NLS*/
377           log_error (_("problem with the agent - disabling agent use\n"));
378           opt.use_agent = 0;
379         }
380       assuan_disconnect (ctx);
381       return NULL;
382     }
383
384   return ctx;
385 }
386 #endif/*ENABLE_AGENT_SUPPORT*/
387
388
389 #ifdef ENABLE_AGENT_SUPPORT
390 void
391 agent_close (assuan_context_t ctx)
392 {
393   assuan_disconnect (ctx);
394 }
395 #endif /*ENABLE_AGENT_SUPPORT*/
396
397
398 /* Copy the text ATEXT into the buffer P and do plus '+' and percent
399    escaping.  Note that the provided buffer needs to be 3 times the
400    size of ATEXT plus 1.  Returns a pointer to the leading Nul in P. */
401 #ifdef ENABLE_AGENT_SUPPORT
402 static char *
403 percent_plus_escape (char *p, const char *atext)
404 {
405   const unsigned char *s;
406
407   for (s=atext; *s; s++)
408     {
409       if (*s < ' ' || *s == '+')
410         {
411           sprintf (p, "%%%02X", *s);
412           p += 3;
413         }
414       else if (*s == ' ')
415         *p++ = '+';
416       else
417         *p++ = *s;
418     }
419   *p = 0;
420   return p;
421 }
422 #endif /*ENABLE_AGENT_SUPPORT*/
423
424
425 #ifdef ENABLE_AGENT_SUPPORT
426
427 /* Object for the agent_okay_cb function.  */
428 struct agent_okay_cb_s {
429   char *pw;
430 };
431
432 /* A callback used to get the passphrase from the okay line.  See
433    agent-get_passphrase for details.  LINE is the rest of the OK
434    status line without leading white spaces. */
435 static assuan_error_t
436 agent_okay_cb (void *opaque, const char *line)
437
438   struct agent_okay_cb_s *parm = opaque;
439   int i;
440
441   /* Note: If the malloc below fails we won't be able to wipe the
442      memory at LINE given the current implementation of the Assuan
443      code. There is no easy ay around this w/o adding a lot of more
444      memory function code to allow wiping arbitrary stuff on memory
445      failure. */
446   parm->pw = xmalloc_secure (strlen (line)/2+2);
447   
448   for (i=0; hexdigitp (line) && hexdigitp (line+1); line += 2)
449     parm->pw[i++] = xtoi_2 (line);
450   parm->pw[i] = 0; 
451   return 0;
452 }
453 #endif /*ENABLE_AGENT_SUPPORT*/
454
455
456
457 /*
458  * Ask the GPG Agent for the passphrase.
459  * Mode 0:  Allow cached passphrase
460  *      1:  No cached passphrase FIXME: Not really implemented
461  *      2:  Ditto, but change the text to "repeat entry"
462  *
463  * Note that TRYAGAIN_TEXT must not be translated.  If canceled is not
464  * NULL, the function does set it to 1 if the user canceled the
465  * operation.  If CACHEID is not NULL, it will be used as the cacheID
466  * for the gpg-agent; if is NULL and a key fingerprint can be
467  * computed, this will be used as the cacheid.
468  */
469 static char *
470 agent_get_passphrase ( u32 *keyid, int mode, const char *cacheid,
471                        const char *tryagain_text,
472                        const char *custom_description,
473                        const char *custom_prompt, int *canceled)
474 {
475 #ifdef ENABLE_AGENT_SUPPORT
476   char *atext = NULL;
477   assuan_context_t ctx = NULL;
478   char *pw = NULL;
479   PKT_public_key *pk = xmalloc_clear( sizeof *pk );
480   byte fpr[MAX_FINGERPRINT_LEN];
481   int have_fpr = 0;
482   char *orig_codeset = NULL;
483
484   if (canceled)
485     *canceled = 0;
486
487 #if MAX_FINGERPRINT_LEN < 20
488 #error agent needs a 20 byte fingerprint
489 #endif
490
491   memset (fpr, 0, MAX_FINGERPRINT_LEN );
492   if( keyid && get_pubkey( pk, keyid ) )
493     {
494       if (pk)
495         free_public_key( pk );      
496       pk = NULL; /* oops: no key for some reason */
497     }
498   
499 #ifdef ENABLE_NLS
500   /* The Assuan agent protocol requires us to transmit utf-8 strings */
501   orig_codeset = bind_textdomain_codeset (PACKAGE, NULL);
502 #ifdef HAVE_LANGINFO_CODESET
503   if (!orig_codeset)
504     orig_codeset = nl_langinfo (CODESET);
505 #endif
506   if (orig_codeset)
507     { /* We only switch when we are able to restore the codeset later. */
508       orig_codeset = xstrdup (orig_codeset);
509       if (!bind_textdomain_codeset (PACKAGE, "utf-8"))
510         orig_codeset = NULL; 
511     }
512 #endif
513
514   if ( !(ctx = agent_open (0, orig_codeset)) ) 
515     goto failure;
516
517   if (custom_description)
518     atext = native_to_utf8 (custom_description);
519   else if ( !mode && pk && keyid )
520     { 
521       char *uid;
522       size_t uidlen;
523       const char *algo_name = pubkey_algo_to_string ( pk->pubkey_algo );
524       const char *timestr;
525       char *maink;
526       
527       if ( !algo_name )
528         algo_name = "?";
529
530 #define KEYIDSTRING _(" (main key ID %s)")
531
532       maink = xmalloc ( strlen (KEYIDSTRING) + keystrlen() + 20 );
533       if( keyid[2] && keyid[3] && keyid[0] != keyid[2] 
534           && keyid[1] != keyid[3] )
535         sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) );
536       else
537         *maink = 0;
538       
539       uid = get_user_id ( keyid, &uidlen ); 
540       timestr = strtimestamp (pk->timestamp);
541
542 #undef KEYIDSTRING
543
544 #define PROMPTSTRING _("You need a passphrase to unlock the secret" \
545                        " key for user:\n" \
546                        "\"%.*s\"\n" \
547                        "%u-bit %s key, ID %s, created %s%s\n" )
548
549       atext = xmalloc ( 100 + strlen (PROMPTSTRING)  
550                         + uidlen + 15 + strlen(algo_name) + keystrlen()
551                         + strlen (timestr) + strlen (maink) );
552       sprintf (atext, PROMPTSTRING,
553                (int)uidlen, uid,
554                nbits_from_pk (pk), algo_name, keystr(&keyid[0]), timestr,
555                maink  );
556       xfree (uid);
557       xfree (maink);
558
559 #undef PROMPTSTRING
560
561       { 
562         size_t dummy;
563         fingerprint_from_pk( pk, fpr, &dummy );
564         have_fpr = 1;
565       }
566       
567     }
568   else if (mode == 2 ) 
569     atext = xstrdup ( _("Repeat passphrase\n") );
570   else
571     atext = xstrdup ( _("Enter passphrase\n") );
572                 
573   { 
574       char *line, *p;
575       int i, rc; 
576       struct agent_okay_cb_s okay_cb_parm;
577
578       if (!tryagain_text)
579         tryagain_text = "X";
580       else
581         tryagain_text = _(tryagain_text);
582
583       /* We allocate 23 times the needed space for thye texts so that
584          there is enough space for escaping. */
585       line = xmalloc (15 + 46 
586                       + 3*strlen (atext)
587                       + 3*strlen (custom_prompt? custom_prompt:"")
588                       + (cacheid? (3*strlen (cacheid)): 0)
589                       + 3*strlen (tryagain_text)
590                       + 1);
591       strcpy (line, "GET_PASSPHRASE ");
592       p = line+15;
593       if (!mode && cacheid)
594         {
595           p = percent_plus_escape (p, cacheid);
596         }
597       else if (!mode && have_fpr)
598         {
599           for (i=0; i < 20; i++, p +=2 )
600             sprintf (p, "%02X", fpr[i]);
601         }
602       else
603         *p++ = 'X'; /* No caching. */
604       *p++ = ' ';
605
606       p = percent_plus_escape (p, tryagain_text);
607       *p++ = ' ';
608
609       /* The prompt.  */
610       if (custom_prompt)
611         {
612           char *tmp = native_to_utf8 (custom_prompt);
613           p = percent_plus_escape (p, tmp);
614           xfree (tmp);
615         }
616       else
617         *p++ = 'X'; /* Use the standard prompt. */
618       *p++ = ' ';
619
620       /* Copy description. */
621       percent_plus_escape (p, atext);
622
623       /* Call gpg-agent.  */
624       memset (&okay_cb_parm, 0, sizeof okay_cb_parm);
625       rc = assuan_transact2 (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL,
626                              agent_okay_cb, &okay_cb_parm);
627
628       xfree (line);
629       xfree (atext); atext = NULL;
630       if (!rc)
631         {
632           assert (okay_cb_parm.pw);
633           pw = okay_cb_parm.pw;
634           agent_close (ctx);
635           if (pk)
636             free_public_key( pk );
637 #ifdef ENABLE_NLS
638           if (orig_codeset)
639             bind_textdomain_codeset (PACKAGE, orig_codeset);
640 #endif
641           xfree (orig_codeset);
642           return pw;
643         }
644       else if (rc && (rc & 0xffff) == 99)
645         {
646           /* 99 is GPG_ERR_CANCELED. */
647           log_info (_("cancelled by user\n") );
648           if (canceled)
649             *canceled = 1;
650         }
651       else 
652         {
653           log_error (_("problem with the agent - disabling agent use\n"));
654           opt.use_agent = 0;
655         }
656   }
657       
658         
659  failure:
660 #ifdef ENABLE_NLS
661   if (orig_codeset)
662     {
663       bind_textdomain_codeset (PACKAGE, orig_codeset);
664       xfree (orig_codeset);
665     }
666 #endif
667   xfree (atext);
668   agent_close (ctx);
669   xfree (pw );
670   if (pk)
671     free_public_key( pk );
672
673 #endif /*ENABLE_AGENT_SUPPORT*/
674
675   return NULL;
676 }
677
678
679 /*
680  * Clear the cached passphrase.  If CACHEID is not NULL, it will be
681  * used instead of a cache ID derived from KEYID.
682  */
683 void
684 passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
685 {
686 #ifdef ENABLE_AGENT_SUPPORT
687   assuan_context_t ctx = NULL;
688   PKT_public_key *pk;
689   byte fpr[MAX_FINGERPRINT_LEN];
690   
691 #if MAX_FINGERPRINT_LEN < 20
692 #error agent needs a 20 byte fingerprint
693 #endif
694     
695   if (!opt.use_agent)
696     return;
697   
698   if (!cacheid)
699     {
700       pk = xcalloc (1, sizeof *pk);
701       memset (fpr, 0, MAX_FINGERPRINT_LEN );
702       if( !keyid || get_pubkey( pk, keyid ) )
703         {
704           goto failure; /* oops: no key for some reason */
705         }
706   
707       {
708         size_t dummy;
709         fingerprint_from_pk( pk, fpr, &dummy );
710       }
711     }
712   else
713     pk = NULL;
714     
715   if ( !(ctx = agent_open (0, NULL)) ) 
716     goto failure;
717
718   { 
719       char *line, *p;
720       int i, rc; 
721
722       if (cacheid)
723         {
724           line = xmalloc (17 + 3*strlen (cacheid) + 2);
725           strcpy (line, "CLEAR_PASSPHRASE ");
726           p = line+17;
727           p = percent_plus_escape (p, cacheid);
728         }
729       else
730         {
731           line = xmalloc (17 + 40 + 2);
732           strcpy (line, "CLEAR_PASSPHRASE ");
733           p = line+17;
734           for (i=0; i < 20; i++, p +=2 )
735             sprintf (p, "%02X", fpr[i]);
736         }
737       *p = 0;
738
739       rc = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
740       xfree (line);
741       if (rc)
742         {
743           log_error (_("problem with the agent - disabling agent use\n"));
744           opt.use_agent = 0;
745         }
746     }
747         
748  failure:
749   agent_close (ctx);
750   if (pk)
751     free_public_key( pk );
752 #endif /*ENABLE_AGENT_SUPPORT*/
753 }
754
755
756 /****************
757  * Ask for a passphrase and return that string.
758  */
759 char *
760 ask_passphrase (const char *description,
761                 const char *tryagain_text,
762                 const char *promptid,
763                 const char *prompt,
764                 const char *cacheid, int *canceled)
765 {
766   char *pw = NULL;
767   
768   if (canceled)
769     *canceled = 0;
770
771   if (!opt.batch && description)
772     {
773       if (strchr (description, '%'))
774         {
775           char *tmp = unescape_percent_string (description);
776           tty_printf ("\n%s\n", tmp);
777           xfree (tmp);
778         }
779       else
780         tty_printf ("\n%s\n",description);
781     }
782                
783  agent_died:
784   if ( opt.use_agent ) 
785     {
786       pw = agent_get_passphrase (NULL, 0, cacheid,
787                                  tryagain_text, description, prompt,
788                                  canceled );
789       if (!pw)
790         {
791           if (!opt.use_agent)
792             goto agent_died;
793           pw = NULL;
794         }
795     }
796   else if (fd_passwd) 
797     {
798       pw = xmalloc_secure (strlen(fd_passwd)+1);
799       strcpy (pw, fd_passwd);
800     }
801   else if (opt.batch)
802     {
803       log_error(_("can't query passphrase in batch mode\n"));
804       pw = NULL;
805     }
806   else {
807     if (tryagain_text)
808       tty_printf(_("%s.\n"), tryagain_text);
809     pw = cpr_get_hidden(promptid? promptid : "passphrase.ask",
810                         prompt?prompt : _("Enter passphrase: ") );
811     tty_kill_prompt();
812   }
813
814   if (!pw || !*pw)
815     write_status( STATUS_MISSING_PASSPHRASE );
816
817   return pw;
818 }
819
820
821 /* Return a new DEK object Using the string-to-key sepcifier S2K.  Use
822  * KEYID and PUBKEY_ALGO to prompt the user.
823
824    MODE 0:  Allow cached passphrase
825         1:  Ignore cached passphrase 
826         2:  Ditto, but change the text to "repeat entry"
827 */
828 DEK *
829 passphrase_to_dek( u32 *keyid, int pubkey_algo,
830                    int cipher_algo, STRING2KEY *s2k, int mode,
831                    const char *tryagain_text, int *canceled)
832 {
833     char *pw = NULL;
834     DEK *dek;
835     STRING2KEY help_s2k;
836
837     if (canceled)
838       *canceled = 0;
839
840     if( !s2k ) {
841         /* This is used for the old rfc1991 mode 
842          * Note: This must match the code in encode.c with opt.rfc1991 set */
843         s2k = &help_s2k;
844         s2k->mode = 0;
845         s2k->hash_algo = S2K_DIGEST_ALGO;
846     }
847
848     /* If we do not have a passphrase available in NEXT_PW and status
849        information are request, we print them now. */
850     if( !next_pw && is_status_enabled() ) {
851         char buf[50];
852  
853         if( keyid ) {
854             u32 used_kid[2];
855             char *us;
856
857             if( keyid[2] && keyid[3] ) {
858                 used_kid[0] = keyid[2];
859                 used_kid[1] = keyid[3];
860             }
861             else {
862                 used_kid[0] = keyid[0];
863                 used_kid[1] = keyid[1];
864             }
865
866             us = get_long_user_id_string( keyid );
867             write_status_text( STATUS_USERID_HINT, us );
868             xfree(us);
869
870             sprintf( buf, "%08lX%08lX %08lX%08lX %d 0",
871                      (ulong)keyid[0], (ulong)keyid[1],
872                      (ulong)used_kid[0], (ulong)used_kid[1],
873                      pubkey_algo );
874                      
875             write_status_text( STATUS_NEED_PASSPHRASE, buf );
876         }
877         else {
878             sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo );
879             write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf );
880         }
881     }
882
883     /* If we do have a keyID, we do not have a passphrase available in
884        NEXT_PW, we are not running in batch mode and we do not want to
885        ignore the passphrase cache (mode!=1), print a prompt with
886        information on that key. */
887     if( keyid && !opt.batch && !next_pw && mode!=1 ) {
888         PKT_public_key *pk = xmalloc_clear( sizeof *pk );
889         char *p;
890
891         p=get_user_id_native(keyid);
892         tty_printf("\n");
893         tty_printf(_("You need a passphrase to unlock the secret key for\n"
894                      "user: \"%s\"\n"),p);
895         xfree(p);
896
897         if( !get_pubkey( pk, keyid ) ) {
898             const char *s = pubkey_algo_to_string( pk->pubkey_algo );
899             tty_printf( _("%u-bit %s key, ID %s, created %s"),
900                        nbits_from_pk( pk ), s?s:"?", keystr(keyid),
901                        strtimestamp(pk->timestamp) );
902             if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
903                                      && keyid[1] != keyid[3] )
904               {
905                 if(keystrlen()>10)
906                   {
907                     tty_printf("\n");
908                     tty_printf(_("         (subkey on main key ID %s)"),
909                                keystr(&keyid[2]) );
910                   }
911                 else
912                   tty_printf( _(" (main key ID %s)"), keystr(&keyid[2]) );
913               }
914             tty_printf("\n");
915         }
916
917         tty_printf("\n");
918         if (pk)
919           free_public_key( pk );
920     }
921
922  agent_died:
923     if( next_pw ) {
924         /* Simply return the passphrase we already have in NEXT_PW. */
925         pw = next_pw;
926         next_pw = NULL;
927     }
928     else if ( opt.use_agent ) {
929       /* Divert to the gpg-agent. */
930         pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, NULL,
931                                     tryagain_text, NULL, NULL, canceled );
932         if (!pw)
933           {
934             if (!opt.use_agent)
935               goto agent_died;
936             pw = xstrdup ("");
937           }
938         if( *pw && mode == 2 )
939           {
940             int i;
941             for(i=0;i<opt.passwd_repeat;i++)
942               {
943                 char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL, NULL,
944                                                    NULL, canceled );
945                 if (!pw2)
946                   {
947                     if (!opt.use_agent)
948                       {
949                         xfree (pw);
950                         pw = NULL;
951                         goto agent_died;
952                       }
953                     pw2 = xstrdup ("");
954                   }
955                 if( strcmp(pw, pw2) )
956                   {
957                     xfree(pw2);
958                     xfree(pw);
959                     return NULL;
960                   }
961                 xfree(pw2);
962               }
963           }
964     }
965     else if( fd_passwd ) {
966         /* Return the passphrase we have store in FD_PASSWD. */
967         pw = xmalloc_secure( strlen(fd_passwd)+1 );
968         strcpy( pw, fd_passwd );
969     }
970     else if( opt.batch )
971       {
972         log_error(_("can't query passphrase in batch mode\n"));
973         pw = xstrdup( "" ); /* return an empty passphrase */
974       }
975     else {
976         /* Read the passphrase from the tty or the command-fd. */
977         pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") );
978         tty_kill_prompt();
979         if( mode == 2 && !cpr_enabled() )
980           {
981             int i;
982             for(i=0;i<opt.passwd_repeat;i++)
983               {
984                 char *pw2 = cpr_get_hidden("passphrase.repeat",
985                                            _("Repeat passphrase: ") );
986                 tty_kill_prompt();
987                 if( strcmp(pw, pw2) )
988                   {
989                     xfree(pw2);
990                     xfree(pw);
991                     return NULL;
992                   }
993                 xfree(pw2);
994               }
995           }
996     }
997
998     if( !pw || !*pw )
999         write_status( STATUS_MISSING_PASSPHRASE );
1000
1001     /* Hash the passphrase and store it in a newly allocated DEK
1002        object.  Keep a copy of the passphrase in LAST_PW for use by
1003        get_last_passphrase(). */
1004     dek = xmalloc_secure_clear ( sizeof *dek );
1005     dek->algo = cipher_algo;
1006     if( !*pw && mode == 2 )
1007         dek->keylen = 0;
1008     else
1009         hash_passphrase( dek, pw, s2k, mode==2 );
1010     xfree(last_pw);
1011     last_pw = pw;
1012     return dek;
1013 }
1014
1015
1016 /****************
1017  * Hash a passphrase using the supplied s2k. If create is true, create
1018  * a new salt or what else must be filled into the s2k for a new key.
1019  * always needs: dek->algo, s2k->mode, s2k->hash_algo.
1020  */
1021 static void
1022 hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
1023 {
1024     MD_HANDLE md;
1025     int pass, i;
1026     int used = 0;
1027     int pwlen = strlen(pw);
1028
1029     assert( s2k->hash_algo );
1030     dek->keylen = cipher_get_keylen( dek->algo ) / 8;
1031     if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
1032         BUG();
1033
1034     md = md_open( s2k->hash_algo, 1);
1035     for(pass=0; used < dek->keylen ; pass++ ) {
1036         if( pass ) {
1037             md_reset(md);
1038             for(i=0; i < pass; i++ ) /* preset the hash context */
1039                 md_putc(md, 0 );
1040         }
1041
1042         if( s2k->mode == 1 || s2k->mode == 3 ) {
1043             int len2 = pwlen + 8;
1044             ulong count = len2;
1045
1046             if( create && !pass ) {
1047                 randomize_buffer(s2k->salt, 8, 1);
1048                 if( s2k->mode == 3 )
1049                     s2k->count = opt.s2k_count;
1050             }
1051
1052             if( s2k->mode == 3 ) {
1053                 count = S2K_DECODE_COUNT(s2k->count);
1054                 if( count < len2 )
1055                     count = len2;
1056             }
1057             /* a little bit complicated because we need a ulong for count */
1058             while( count > len2 ) { /* maybe iterated+salted */
1059                 md_write( md, s2k->salt, 8 );
1060                 md_write( md, pw, pwlen );
1061                 count -= len2;
1062             }
1063             if( count < 8 )
1064                 md_write( md, s2k->salt, count );
1065             else {
1066                 md_write( md, s2k->salt, 8 );
1067                 count -= 8;
1068                 md_write( md, pw, count );
1069             }
1070         }
1071         else
1072             md_write( md, pw, pwlen );
1073         md_final( md );
1074         i = md_digest_length( s2k->hash_algo );
1075         if( i > dek->keylen - used )
1076             i = dek->keylen - used;
1077         memcpy( dek->key+used, md_read(md, s2k->hash_algo), i );
1078         used += i;
1079     }
1080     md_close(md);
1081 }
1082