* passphrase.c (agent_get_passphrase): Add new arg CACHEID.
[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.  If CACHEID is not NULL, it will be used as the cacheID
429  * for the gpg-agent; if is NULL and a key fingerprint can be
430  * computed, this will be used as the cacheid.
431  */
432 static char *
433 agent_get_passphrase ( u32 *keyid, int mode, const char *cacheid,
434                        const char *tryagain_text,
435                        const char *custom_description,
436                        const char *custom_prompt, int *canceled)
437 {
438 #ifdef ENABLE_AGENT_SUPPORT
439   char *atext = NULL;
440   assuan_context_t ctx = NULL;
441   char *pw = NULL;
442   PKT_public_key *pk = m_alloc_clear( sizeof *pk );
443   byte fpr[MAX_FINGERPRINT_LEN];
444   int have_fpr = 0;
445   char *orig_codeset = NULL;
446
447   if (canceled)
448     *canceled = 0;
449
450 #if MAX_FINGERPRINT_LEN < 20
451 #error agent needs a 20 byte fingerprint
452 #endif
453
454   memset (fpr, 0, MAX_FINGERPRINT_LEN );
455   if( keyid && get_pubkey( pk, keyid ) )
456     {
457       if (pk)
458         free_public_key( pk );      
459       pk = NULL; /* oops: no key for some reason */
460     }
461   
462 #ifdef ENABLE_NLS
463   /* The Assuan agent protocol requires us to transmit utf-8 strings */
464   orig_codeset = bind_textdomain_codeset (PACKAGE, NULL);
465 #ifdef HAVE_LANGINFO_CODESET
466   if (!orig_codeset)
467     orig_codeset = nl_langinfo (CODESET);
468 #endif
469   if (orig_codeset)
470     { /* We only switch when we are able to restore the codeset later. */
471       orig_codeset = m_strdup (orig_codeset);
472       if (!bind_textdomain_codeset (PACKAGE, "utf-8"))
473         orig_codeset = NULL; 
474     }
475 #endif
476
477   if ( !(ctx = agent_open ()) ) 
478     goto failure;
479
480   if (custom_description)
481     atext = native_to_utf8 (custom_description);
482   else if ( !mode && pk && keyid )
483     { 
484       char *uid;
485       size_t uidlen;
486       const char *algo_name = pubkey_algo_to_string ( pk->pubkey_algo );
487       const char *timestr;
488       char *maink;
489       
490       if ( !algo_name )
491         algo_name = "?";
492
493 #define KEYIDSTRING _(" (main key ID %s)")
494
495       maink = m_alloc ( strlen (KEYIDSTRING) + keystrlen() + 20 );
496       if( keyid[2] && keyid[3] && keyid[0] != keyid[2] 
497           && keyid[1] != keyid[3] )
498         sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) );
499       else
500         *maink = 0;
501       
502       uid = get_user_id ( keyid, &uidlen ); 
503       timestr = strtimestamp (pk->timestamp);
504
505 #undef KEYIDSTRING
506
507 #define PROMPTSTRING _("You need a passphrase to unlock the secret" \
508                        " key for user:\n" \
509                        "\"%.*s\"\n" \
510                        "%u-bit %s key, ID %s, created %s%s\n" )
511
512       atext = m_alloc ( 100 + strlen (PROMPTSTRING)  
513                         + uidlen + 15 + strlen(algo_name) + keystrlen()
514                         + strlen (timestr) + strlen (maink) );
515       sprintf (atext, PROMPTSTRING,
516                (int)uidlen, uid,
517                nbits_from_pk (pk), algo_name, keystr(&keyid[0]), timestr,
518                maink  );
519       m_free (uid);
520       m_free (maink);
521
522 #undef PROMPTSTRING
523
524       { 
525         size_t dummy;
526         fingerprint_from_pk( pk, fpr, &dummy );
527         have_fpr = 1;
528       }
529       
530     }
531   else if (mode == 2 ) 
532     atext = m_strdup ( _("Repeat passphrase\n") );
533   else
534     atext = m_strdup ( _("Enter passphrase\n") );
535                 
536   { 
537       char *line, *p;
538       int i, rc; 
539       struct agent_okay_cb_s okay_cb_parm;
540
541       if (!tryagain_text)
542         tryagain_text = "X";
543       else
544         tryagain_text = _(tryagain_text);
545
546       /* We allocate 23 times the needed space for thye texts so that
547          there is enough space for escaping. */
548       line = xmalloc (15 + 46 
549                       + 3*strlen (atext)
550                       + 3*strlen (custom_prompt? custom_prompt:"")
551                       + (cacheid? (3*strlen (cacheid)): 0)
552                       + 3*strlen (tryagain_text)
553                       + 1);
554       strcpy (line, "GET_PASSPHRASE ");
555       p = line+15;
556       if (!mode && cacheid)
557         {
558           p = percent_plus_escape (p, cacheid);
559         }
560       else if (!mode && have_fpr)
561         {
562           for (i=0; i < 20; i++, p +=2 )
563             sprintf (p, "%02X", fpr[i]);
564         }
565       else
566         *p++ = 'X'; /* No caching. */
567       *p++ = ' ';
568
569       p = percent_plus_escape (p, tryagain_text);
570       *p++ = ' ';
571
572       /* The prompt.  */
573       if (custom_prompt)
574         {
575           char *tmp = native_to_utf8 (custom_prompt);
576           p = percent_plus_escape (p, tmp);
577           xfree (tmp);
578         }
579       else
580         *p++ = 'X'; /* Use the standard prompt. */
581       *p++ = ' ';
582
583       /* Copy description. */
584       percent_plus_escape (p, atext);
585
586       /* Call gpg-agent.  */
587       memset (&okay_cb_parm, 0, sizeof okay_cb_parm);
588       rc = assuan_transact2 (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL,
589                              agent_okay_cb, &okay_cb_parm);
590
591       xfree (line);
592       xfree (atext); atext = NULL;
593       if (!rc)
594         {
595           assert (okay_cb_parm.pw);
596           pw = okay_cb_parm.pw;
597           agent_close (ctx);
598           if (pk)
599             free_public_key( pk );
600 #ifdef ENABLE_NLS
601           if (orig_codeset)
602             bind_textdomain_codeset (PACKAGE, orig_codeset);
603 #endif
604           xfree (orig_codeset);
605           return pw;
606         }
607       else if (rc && (rc & 0xffff) == 99)
608         {
609           /* 99 is GPG_ERR_CANCELED. */
610           log_info (_("cancelled by user\n") );
611           if (canceled)
612             *canceled = 1;
613         }
614       else 
615         {
616           log_error (_("problem with the agent - disabling agent use\n"));
617           opt.use_agent = 0;
618         }
619   }
620       
621         
622  failure:
623 #ifdef ENABLE_NLS
624   if (orig_codeset)
625     bind_textdomain_codeset (PACKAGE, orig_codeset);
626 #endif
627   xfree (atext);
628   agent_close (ctx);
629   xfree (pw );
630   if (pk)
631     free_public_key( pk );
632
633 #endif /*ENABLE_AGENT_SUPPORT*/
634
635   return NULL;
636 }
637
638
639 /*
640  * Clear the cached passphrase.  If CACHEID is not NULL, it will be
641  * used instead of a cache ID derived from KEYID.
642  */
643 void
644 passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
645 {
646 #ifdef ENABLE_AGENT_SUPPORT
647   assuan_context_t ctx = NULL;
648   PKT_public_key *pk;
649   byte fpr[MAX_FINGERPRINT_LEN];
650   
651 #if MAX_FINGERPRINT_LEN < 20
652 #error agent needs a 20 byte fingerprint
653 #endif
654     
655   if (!opt.use_agent)
656     return;
657   
658   if (!cacheid)
659     {
660       pk = xcalloc (1, sizeof *pk);
661       memset (fpr, 0, MAX_FINGERPRINT_LEN );
662       if( !keyid || get_pubkey( pk, keyid ) )
663         {
664           goto failure; /* oops: no key for some reason */
665         }
666   
667       {
668         size_t dummy;
669         fingerprint_from_pk( pk, fpr, &dummy );
670       }
671     }
672   else
673     pk = NULL;
674     
675   if ( !(ctx = agent_open ()) ) 
676     goto failure;
677
678   { 
679       char *line, *p;
680       int i, rc; 
681
682       if (cacheid)
683         {
684           line = xmalloc (17 + 3*strlen (cacheid) + 2);
685           strcpy (line, "CLEAR_PASSPHRASE ");
686           p = line+17;
687           p = percent_plus_escape (p, cacheid);
688         }
689       else
690         {
691           line = xmalloc (17 + 40 + 2);
692           strcpy (line, "CLEAR_PASSPHRASE ");
693           p = line+17;
694           for (i=0; i < 20; i++, p +=2 )
695             sprintf (p, "%02X", fpr[i]);
696         }
697       *p = 0;
698
699       rc = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
700       xfree (line);
701       if (rc)
702         {
703           log_error (_("problem with the agent - disabling agent use\n"));
704           opt.use_agent = 0;
705         }
706     }
707         
708  failure:
709   agent_close (ctx);
710   if (pk)
711     free_public_key( pk );
712 #endif /*ENABLE_AGENT_SUPPORT*/
713 }
714
715
716 /****************
717  * Ask for a passphrase and return that string.
718  */
719 char *
720 ask_passphrase (const char *description,
721                 const char *tryagain_text,
722                 const char *promptid,
723                 const char *prompt,
724                 const char *cacheid, int *canceled)
725 {
726   char *pw = NULL;
727   
728   if (canceled)
729     *canceled = 0;
730
731   if (!opt.batch && description)
732     tty_printf ("\n%s\n",description);
733                
734  agent_died:
735   if ( opt.use_agent ) 
736     {
737       pw = agent_get_passphrase (NULL, 0, cacheid,
738                                  tryagain_text, description, prompt,
739                                  canceled );
740       if (!pw)
741         {
742           if (!opt.use_agent)
743             goto agent_died;
744           pw = NULL;
745         }
746     }
747   else if (fd_passwd) 
748     {
749       pw = m_alloc_secure (strlen(fd_passwd)+1);
750       strcpy (pw, fd_passwd);
751     }
752   else if (opt.batch)
753     {
754       log_error(_("can't query passphrase in batch mode\n"));
755       pw = NULL;
756     }
757   else {
758     if (tryagain_text)
759       tty_printf(_("%s.\n"), tryagain_text);
760     pw = cpr_get_hidden(promptid? promptid : "passphrase.ask",
761                         prompt?prompt : _("Enter passphrase: ") );
762     tty_kill_prompt();
763   }
764
765   if (!pw || !*pw)
766     write_status( STATUS_MISSING_PASSPHRASE );
767
768   return pw;
769 }
770
771
772 /* Return a new DEK object Using the string-to-key sepcifier S2K.  Use
773  * KEYID and PUBKEY_ALGO to prompt the user.
774
775    MODE 0:  Allow cached passphrase
776         1:  Ignore cached passphrase 
777         2:  Ditto, but change the text to "repeat entry"
778 */
779 DEK *
780 passphrase_to_dek( u32 *keyid, int pubkey_algo,
781                    int cipher_algo, STRING2KEY *s2k, int mode,
782                    const char *tryagain_text, int *canceled)
783 {
784     char *pw = NULL;
785     DEK *dek;
786     STRING2KEY help_s2k;
787
788     if (canceled)
789       *canceled = 0;
790
791     if( !s2k ) {
792         /* This is used for the old rfc1991 mode 
793          * Note: This must match the code in encode.c with opt.rfc1991 set */
794         s2k = &help_s2k;
795         s2k->mode = 0;
796         s2k->hash_algo = S2K_DIGEST_ALGO;
797     }
798
799     /* If we do not have a passphrase available in NEXT_PW and status
800        information are request, we print them now. */
801     if( !next_pw && is_status_enabled() ) {
802         char buf[50];
803  
804         if( keyid ) {
805             u32 used_kid[2];
806             char *us;
807
808             if( keyid[2] && keyid[3] ) {
809                 used_kid[0] = keyid[2];
810                 used_kid[1] = keyid[3];
811             }
812             else {
813                 used_kid[0] = keyid[0];
814                 used_kid[1] = keyid[1];
815             }
816
817             us = get_long_user_id_string( keyid );
818             write_status_text( STATUS_USERID_HINT, us );
819             m_free(us);
820
821             sprintf( buf, "%08lX%08lX %08lX%08lX %d 0",
822                      (ulong)keyid[0], (ulong)keyid[1],
823                      (ulong)used_kid[0], (ulong)used_kid[1],
824                      pubkey_algo );
825                      
826             write_status_text( STATUS_NEED_PASSPHRASE, buf );
827         }
828         else {
829             sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo );
830             write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf );
831         }
832     }
833
834     /* If we do have a keyID, we do not have a passphrase available in
835        NEXT_PW, we are not running in batch mode and we do not want to
836        ignore the passphrase cache (mode!=1), print a prompt with
837        information on that key. */
838     if( keyid && !opt.batch && !next_pw && mode!=1 ) {
839         PKT_public_key *pk = m_alloc_clear( sizeof *pk );
840         char *p;
841
842         p=get_user_id_native(keyid);
843         tty_printf("\n");
844         tty_printf(_("You need a passphrase to unlock the secret key for\n"
845                      "user: \"%s\"\n"),p);
846         m_free(p);
847
848         if( !get_pubkey( pk, keyid ) ) {
849             const char *s = pubkey_algo_to_string( pk->pubkey_algo );
850             tty_printf( _("%u-bit %s key, ID %s, created %s"),
851                        nbits_from_pk( pk ), s?s:"?", keystr(keyid),
852                        strtimestamp(pk->timestamp) );
853             if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
854                                      && keyid[1] != keyid[3] )
855               {
856                 if(keystrlen()>10)
857                   {
858                     tty_printf("\n");
859                     tty_printf(_("         (subkey on main key ID %s)"),
860                                keystr(&keyid[2]) );
861                   }
862                 else
863                   tty_printf( _(" (main key ID %s)"), keystr(&keyid[2]) );
864               }
865             tty_printf("\n");
866         }
867
868         tty_printf("\n");
869         if (pk)
870           free_public_key( pk );
871     }
872
873  agent_died:
874     if( next_pw ) {
875         /* Simply return the passphrase we already have in NEXT_PW. */
876         pw = next_pw;
877         next_pw = NULL;
878     }
879     else if ( opt.use_agent ) {
880       /* Divert to the gpg-agent. */
881         pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, NULL,
882                                     tryagain_text, NULL, NULL, canceled );
883         if (!pw)
884           {
885             if (!opt.use_agent)
886               goto agent_died;
887             pw = m_strdup ("");
888           }
889         if( *pw && mode == 2 ) {
890             char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL, NULL,
891                                                NULL, canceled );
892             if (!pw2)
893               {
894                 if (!opt.use_agent)
895                   {
896                     m_free (pw);
897                     pw = NULL;
898                     goto agent_died;
899                   }
900                 pw2 = m_strdup ("");
901               }
902             if( strcmp(pw, pw2) ) {
903                 m_free(pw2);
904                 m_free(pw);
905                 return NULL;
906             }
907             m_free(pw2);
908         }
909     }
910     else if( fd_passwd ) {
911         /* Return the passphrase we have store in FD_PASSWD. */
912         pw = m_alloc_secure( strlen(fd_passwd)+1 );
913         strcpy( pw, fd_passwd );
914     }
915     else if( opt.batch )
916       {
917         log_error(_("can't query passphrase in batch mode\n"));
918         pw = m_strdup( "" ); /* return an empty passphrase */
919       }
920     else {
921         /* Read the passphrase from the tty or the command-fd. */
922         pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") );
923         tty_kill_prompt();
924         if( mode == 2 && !cpr_enabled() ) {
925             char *pw2 = cpr_get_hidden("passphrase.repeat",
926                                        _("Repeat passphrase: ") );
927             tty_kill_prompt();
928             if( strcmp(pw, pw2) ) {
929                 m_free(pw2);
930                 m_free(pw);
931                 return NULL;
932             }
933             m_free(pw2);
934         }
935     }
936
937     if( !pw || !*pw )
938         write_status( STATUS_MISSING_PASSPHRASE );
939
940     /* Hash the passphrase and store it in a newly allocated DEK
941        object.  Keep a copy of the passphrase in LAST_PW for use by
942        get_last_passphrase(). */
943     dek = m_alloc_secure_clear ( sizeof *dek );
944     dek->algo = cipher_algo;
945     if( !*pw && mode == 2 )
946         dek->keylen = 0;
947     else
948         hash_passphrase( dek, pw, s2k, mode==2 );
949     m_free(last_pw);
950     last_pw = pw;
951     return dek;
952 }
953
954
955 /****************
956  * Hash a passphrase using the supplied s2k. If create is true, create
957  * a new salt or what else must be filled into the s2k for a new key.
958  * always needs: dek->algo, s2k->mode, s2k->hash_algo.
959  */
960 static void
961 hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
962 {
963     MD_HANDLE md;
964     int pass, i;
965     int used = 0;
966     int pwlen = strlen(pw);
967
968     assert( s2k->hash_algo );
969     dek->keylen = cipher_get_keylen( dek->algo ) / 8;
970     if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
971         BUG();
972
973     md = md_open( s2k->hash_algo, 1);
974     for(pass=0; used < dek->keylen ; pass++ ) {
975         if( pass ) {
976             md_reset(md);
977             for(i=0; i < pass; i++ ) /* preset the hash context */
978                 md_putc(md, 0 );
979         }
980
981         if( s2k->mode == 1 || s2k->mode == 3 ) {
982             int len2 = pwlen + 8;
983             ulong count = len2;
984
985             if( create && !pass ) {
986                 randomize_buffer(s2k->salt, 8, 1);
987                 if( s2k->mode == 3 )
988                     s2k->count = 96; /* 65536 iterations */
989             }
990
991             if( s2k->mode == 3 ) {
992                 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
993                 if( count < len2 )
994                     count = len2;
995             }
996             /* a little bit complicated because we need a ulong for count */
997             while( count > len2 ) { /* maybe iterated+salted */
998                 md_write( md, s2k->salt, 8 );
999                 md_write( md, pw, pwlen );
1000                 count -= len2;
1001             }
1002             if( count < 8 )
1003                 md_write( md, s2k->salt, count );
1004             else {
1005                 md_write( md, s2k->salt, 8 );
1006                 count -= 8;
1007                 md_write( md, pw, count );
1008             }
1009         }
1010         else
1011             md_write( md, pw, pwlen );
1012         md_final( md );
1013         i = md_digest_length( s2k->hash_algo );
1014         if( i > dek->keylen - used )
1015             i = dek->keylen - used;
1016         memcpy( dek->key+used, md_read(md, s2k->hash_algo), i );
1017         used += i;
1018     }
1019     md_close(md);
1020 }
1021