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