2006-09-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / passphrase.c
blob1c5cf3b27bd6b2348bf839005ce36a19401ce132
1 /* passphrase.c - Get a passphrase
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 * 2005 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA.
23 #include <config.h>
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <assert.h>
30 #if !defined(HAVE_DOSISH_SYSTEM) && !defined(__riscos__)
31 #include <sys/socket.h>
32 #include <sys/un.h>
33 #endif
34 #if defined (_WIN32)
35 #include <windows.h>
36 #endif
37 #include <errno.h>
38 #ifdef HAVE_LOCALE_H
39 #include <locale.h>
40 #endif
41 #ifdef HAVE_LANGINFO_CODESET
42 #include <langinfo.h>
43 #endif
45 #include "gpg.h"
46 #include "util.h"
47 #include "options.h"
48 #include "ttyio.h"
49 #include "cipher.h"
50 #include "keydb.h"
51 #include "main.h"
52 #include "i18n.h"
53 #include "status.h"
54 #ifdef ENABLE_AGENT_SUPPORT
55 #include "assuan.h"
56 #endif /*ENABLE_AGENT_SUPPORT*/
58 static char *fd_passwd = NULL;
59 static char *next_pw = NULL;
60 static char *last_pw = NULL;
62 static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create );
64 int
65 have_static_passphrase()
67 if ( opt.use_agent )
68 return 0;
69 return !!fd_passwd;
72 /****************
73 * Set the passphrase to be used for the next query and only for the next
74 * one.
76 void
77 set_next_passphrase( const char *s )
79 xfree(next_pw);
80 next_pw = NULL;
81 if( s ) {
82 next_pw = xmalloc_secure( strlen(s)+1 );
83 strcpy(next_pw, s );
87 /****************
88 * Get the last passphrase used in passphrase_to_dek.
89 * Note: This removes the passphrase from this modules and
90 * the caller must free the result. May return NULL:
92 char *
93 get_last_passphrase()
95 char *p = last_pw;
96 last_pw = NULL;
97 return p;
100 /* As if we had used the passphrase - make it the last_pw. */
101 void
102 next_to_last_passphrase(void)
104 if(next_pw)
106 last_pw=next_pw;
107 next_pw=NULL;
111 /* Here's an interesting question: since this passphrase was passed in
112 on the command line, is there really any point in using secure
113 memory for it? I'm going with 'yes', since it doesn't hurt, and
114 might help in some small way (swapping). */
116 void
117 set_passphrase_from_string(const char *pass)
119 xfree( fd_passwd );
120 fd_passwd = xmalloc_secure(strlen(pass)+1);
121 strcpy(fd_passwd,pass);
125 void
126 read_passphrase_from_fd( int fd )
128 int i, len;
129 char *pw;
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];
137 while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
139 *buf = 0;
140 return;
143 if (!opt.batch )
144 tty_printf("Reading passphrase from file descriptor %d ...", fd );
145 for (pw = NULL, i = len = 100; ; i++ )
147 if (i >= len-1 )
149 char *pw2 = pw;
150 len += 100;
151 pw = xmalloc_secure( len );
152 if( pw2 )
154 memcpy(pw, pw2, i );
155 xfree (pw2);
157 else
158 i=0;
160 if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
161 break;
163 pw[i] = 0;
164 if (!opt.batch)
165 tty_printf("\b\b\b \n" );
167 xfree( fd_passwd );
168 fd_passwd = pw;
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)
178 char *line;
179 int rc;
181 if (!value || !*value)
182 return 0; /* Avoid sending empty option values. */
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;
191 /* Send all required options to the gpg-agent. */
192 static int
193 agent_send_all_options (assuan_context_t ctx)
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;
202 dft_display = getenv ("DISPLAY");
203 if (opt.display || dft_display)
205 if (agent_send_option (ctx, "display",
206 opt.display ? opt.display : dft_display))
207 return -1;
210 if (!opt.ttyname)
212 const char *tmp;
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;
220 if (opt.ttyname || dft_ttyname)
222 if (agent_send_option (ctx, "ttyname",
223 opt.ttyname ? opt.ttyname : dft_ttyname))
224 return -1;
227 dft_ttytype = getenv ("TERM");
228 if (opt.ttytype || (dft_ttyname && dft_ttytype))
230 if (agent_send_option (ctx, "ttytype",
231 opt.ttyname ? opt.ttytype : dft_ttytype))
232 return -1;
235 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
236 old_lc = setlocale (LC_CTYPE, NULL);
237 if (old_lc)
238 old_lc = xstrdup (old_lc);
239 dft_lc = setlocale (LC_CTYPE, "");
240 #endif
241 if (opt.lc_ctype || (dft_ttyname && dft_lc))
243 rc = agent_send_option (ctx, "lc-ctype",
244 opt.lc_ctype ? opt.lc_ctype : dft_lc);
246 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
247 if (old_lc)
249 setlocale (LC_CTYPE, old_lc);
250 xfree (old_lc);
252 #endif
253 if (rc)
254 return rc;
256 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
257 old_lc = setlocale (LC_MESSAGES, NULL);
258 if (old_lc)
259 old_lc = xstrdup (old_lc);
260 dft_lc = setlocale (LC_MESSAGES, "");
261 #endif
262 if (opt.lc_messages || (dft_ttyname && dft_lc))
264 rc = agent_send_option (ctx, "lc-messages",
265 opt.lc_messages ? opt.lc_messages : dft_lc);
267 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
268 if (old_lc)
270 setlocale (LC_MESSAGES, old_lc);
271 xfree (old_lc);
273 #endif
274 return rc;
276 #endif /*ENABLE_AGENT_SUPPORT*/
280 * Open a connection to the agent and initializes the connection.
281 * Returns: -1 on error; on success an Assuan context for that
282 * connection is returned. With TRY set to true, no error messages
283 * are printed and the use of the agent won't get disabled on failure.
284 * If ORIG_CODESET is not NULL, the function will swithc the codeset
285 * back to that one before printing error messages.
287 #ifdef ENABLE_AGENT_SUPPORT
288 assuan_context_t
289 agent_open (int try, const char *orig_codeset)
291 int rc;
292 assuan_context_t ctx;
293 char *infostr, *p;
294 int prot;
295 int pid;
297 if (opt.gpg_agent_info)
298 infostr = xstrdup (opt.gpg_agent_info);
299 else
301 infostr = getenv ( "GPG_AGENT_INFO" );
302 if (!infostr || !*infostr)
304 if (!try)
306 #ifdef ENABLE_NLS
307 if (orig_codeset)
308 bind_textdomain_codeset (PACKAGE, orig_codeset);
309 #endif /*ENABLE_NLS*/
310 log_info (_("gpg-agent is not available in this session\n"));
311 opt.use_agent = 0;
313 return NULL;
315 infostr = xstrdup ( infostr );
318 if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
320 if (!try)
322 #ifdef ENABLE_NLS
323 if (orig_codeset)
324 bind_textdomain_codeset (PACKAGE, orig_codeset);
325 #endif /*ENABLE_NLS*/
326 log_error ( _("malformed GPG_AGENT_INFO environment variable\n"));
327 opt.use_agent = 0;
329 xfree (infostr);
330 return NULL;
332 *p++ = 0;
333 pid = atoi (p);
334 while (*p && *p != PATHSEP_C)
335 p++;
336 prot = *p? atoi (p+1) : 0;
337 if (prot != 1)
339 if (!try)
341 #ifdef ENABLE_NLS
342 if (orig_codeset)
343 bind_textdomain_codeset (PACKAGE, orig_codeset);
344 #endif /*ENABLE_NLS*/
345 log_error (_("gpg-agent protocol version %d is not supported\n"),
346 prot);
347 opt.use_agent = 0;
349 xfree (infostr);
350 return NULL;
353 rc = assuan_socket_connect (&ctx, infostr, pid);
354 if (rc)
356 if (!try)
358 #ifdef ENABLE_NLS
359 if (orig_codeset)
360 bind_textdomain_codeset (PACKAGE, orig_codeset);
361 #endif /*ENABLE_NLS*/
362 log_error ( _("can't connect to `%s': %s\n"),
363 infostr, assuan_strerror (rc));
364 opt.use_agent = 0;
366 xfree (infostr );
367 return NULL;
369 xfree (infostr);
371 if (agent_send_all_options (ctx))
373 if (!try)
375 #ifdef ENABLE_NLS
376 if (orig_codeset)
377 bind_textdomain_codeset (PACKAGE, orig_codeset);
378 #endif /*ENABLE_NLS*/
379 log_error (_("problem with the agent - disabling agent use\n"));
380 opt.use_agent = 0;
382 assuan_disconnect (ctx);
383 return NULL;
386 return ctx;
388 #endif/*ENABLE_AGENT_SUPPORT*/
391 #ifdef ENABLE_AGENT_SUPPORT
392 void
393 agent_close (assuan_context_t ctx)
395 assuan_disconnect (ctx);
397 #endif /*ENABLE_AGENT_SUPPORT*/
400 /* Copy the text ATEXT into the buffer P and do plus '+' and percent
401 escaping. Note that the provided buffer needs to be 3 times the
402 size of ATEXT plus 1. Returns a pointer to the leading Nul in P. */
403 #ifdef ENABLE_AGENT_SUPPORT
404 static char *
405 percent_plus_escape (char *p, const char *atext)
407 const unsigned char *s;
409 for (s=atext; *s; s++)
411 if (*s < ' ' || *s == '+')
413 sprintf (p, "%%%02X", *s);
414 p += 3;
416 else if (*s == ' ')
417 *p++ = '+';
418 else
419 *p++ = *s;
421 *p = 0;
422 return p;
424 #endif /*ENABLE_AGENT_SUPPORT*/
427 #ifdef ENABLE_AGENT_SUPPORT
429 /* Object for the agent_okay_cb function. */
430 struct agent_okay_cb_s {
431 char *pw;
434 /* A callback used to get the passphrase from the okay line. See
435 agent-get_passphrase for details. LINE is the rest of the OK
436 status line without leading white spaces. */
437 static assuan_error_t
438 agent_okay_cb (void *opaque, const char *line)
440 struct agent_okay_cb_s *parm = opaque;
441 int i;
443 /* Note: If the malloc below fails we won't be able to wipe the
444 memory at LINE given the current implementation of the Assuan
445 code. There is no easy ay around this w/o adding a lot of more
446 memory function code to allow wiping arbitrary stuff on memory
447 failure. */
448 parm->pw = xmalloc_secure (strlen (line)/2+2);
450 for (i=0; hexdigitp (line) && hexdigitp (line+1); line += 2)
451 parm->pw[i++] = xtoi_2 (line);
452 parm->pw[i] = 0;
453 return 0;
455 #endif /*ENABLE_AGENT_SUPPORT*/
460 * Ask the GPG Agent for the passphrase.
461 * Mode 0: Allow cached passphrase
462 * 1: No cached passphrase FIXME: Not really implemented
463 * 2: Ditto, but change the text to "repeat entry"
465 * Note that TRYAGAIN_TEXT must not be translated. If canceled is not
466 * NULL, the function does set it to 1 if the user canceled the
467 * operation. If CACHEID is not NULL, it will be used as the cacheID
468 * for the gpg-agent; if is NULL and a key fingerprint can be
469 * computed, this will be used as the cacheid.
471 static char *
472 agent_get_passphrase ( u32 *keyid, int mode, const char *cacheid,
473 const char *tryagain_text,
474 const char *custom_description,
475 const char *custom_prompt, int *canceled)
477 #ifdef ENABLE_AGENT_SUPPORT
478 char *atext = NULL;
479 assuan_context_t ctx = NULL;
480 char *pw = NULL;
481 PKT_public_key *pk = xmalloc_clear( sizeof *pk );
482 byte fpr[MAX_FINGERPRINT_LEN];
483 int have_fpr = 0;
484 char *orig_codeset = NULL;
486 if (canceled)
487 *canceled = 0;
489 #if MAX_FINGERPRINT_LEN < 20
490 #error agent needs a 20 byte fingerprint
491 #endif
493 memset (fpr, 0, MAX_FINGERPRINT_LEN );
494 if( keyid && get_pubkey( pk, keyid ) )
496 if (pk)
497 free_public_key( pk );
498 pk = NULL; /* oops: no key for some reason */
501 #ifdef ENABLE_NLS
502 /* The Assuan agent protocol requires us to transmit utf-8 strings */
503 orig_codeset = bind_textdomain_codeset (PACKAGE, NULL);
504 #ifdef HAVE_LANGINFO_CODESET
505 if (!orig_codeset)
506 orig_codeset = nl_langinfo (CODESET);
507 #endif
508 if (orig_codeset)
509 { /* We only switch when we are able to restore the codeset later. */
510 orig_codeset = xstrdup (orig_codeset);
511 if (!bind_textdomain_codeset (PACKAGE, "utf-8"))
512 orig_codeset = NULL;
514 #endif
516 if ( !(ctx = agent_open (0, orig_codeset)) )
517 goto failure;
519 if (custom_description)
520 atext = native_to_utf8 (custom_description);
521 else if ( !mode && pk && keyid )
523 char *uid;
524 size_t uidlen;
525 const char *algo_name = pubkey_algo_to_string ( pk->pubkey_algo );
526 const char *timestr;
527 char *maink;
529 if ( !algo_name )
530 algo_name = "?";
532 #define KEYIDSTRING _(" (main key ID %s)")
534 maink = xmalloc ( strlen (KEYIDSTRING) + keystrlen() + 20 );
535 if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
536 && keyid[1] != keyid[3] )
537 sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) );
538 else
539 *maink = 0;
541 uid = get_user_id ( keyid, &uidlen );
542 timestr = strtimestamp (pk->timestamp);
544 #undef KEYIDSTRING
546 #define PROMPTSTRING _("You need a passphrase to unlock the secret" \
547 " key for user:\n" \
548 "\"%.*s\"\n" \
549 "%u-bit %s key, ID %s, created %s%s\n" )
551 atext = xmalloc ( 100 + strlen (PROMPTSTRING)
552 + uidlen + 15 + strlen(algo_name) + keystrlen()
553 + strlen (timestr) + strlen (maink) );
554 sprintf (atext, PROMPTSTRING,
555 (int)uidlen, uid,
556 nbits_from_pk (pk), algo_name, keystr(&keyid[0]), timestr,
557 maink );
558 xfree (uid);
559 xfree (maink);
561 #undef PROMPTSTRING
564 size_t dummy;
565 fingerprint_from_pk( pk, fpr, &dummy );
566 have_fpr = 1;
570 else if (mode == 2 )
571 atext = xstrdup ( _("Repeat passphrase\n") );
572 else
573 atext = xstrdup ( _("Enter passphrase\n") );
576 char *line, *p;
577 int i, rc;
578 struct agent_okay_cb_s okay_cb_parm;
580 if (!tryagain_text)
581 tryagain_text = "X";
582 else
583 tryagain_text = _(tryagain_text);
585 /* We allocate 23 times the needed space for thye texts so that
586 there is enough space for escaping. */
587 line = xmalloc (15 + 46
588 + 3*strlen (atext)
589 + 3*strlen (custom_prompt? custom_prompt:"")
590 + (cacheid? (3*strlen (cacheid)): 0)
591 + 3*strlen (tryagain_text)
592 + 1);
593 strcpy (line, "GET_PASSPHRASE ");
594 p = line+15;
595 if (!mode && cacheid)
597 p = percent_plus_escape (p, cacheid);
599 else if (!mode && have_fpr)
601 for (i=0; i < 20; i++, p +=2 )
602 sprintf (p, "%02X", fpr[i]);
604 else
605 *p++ = 'X'; /* No caching. */
606 *p++ = ' ';
608 p = percent_plus_escape (p, tryagain_text);
609 *p++ = ' ';
611 /* The prompt. */
612 if (custom_prompt)
614 char *tmp = native_to_utf8 (custom_prompt);
615 p = percent_plus_escape (p, tmp);
616 xfree (tmp);
618 else
619 *p++ = 'X'; /* Use the standard prompt. */
620 *p++ = ' ';
622 /* Copy description. */
623 percent_plus_escape (p, atext);
625 /* Call gpg-agent. */
626 memset (&okay_cb_parm, 0, sizeof okay_cb_parm);
627 rc = assuan_transact2 (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL,
628 agent_okay_cb, &okay_cb_parm);
630 xfree (line);
631 xfree (atext); atext = NULL;
632 if (!rc)
634 assert (okay_cb_parm.pw);
635 pw = okay_cb_parm.pw;
636 agent_close (ctx);
637 if (pk)
638 free_public_key( pk );
639 #ifdef ENABLE_NLS
640 if (orig_codeset)
641 bind_textdomain_codeset (PACKAGE, orig_codeset);
642 #endif
643 xfree (orig_codeset);
644 return pw;
646 else if (rc && (rc & 0xffff) == 99)
648 /* 99 is GPG_ERR_CANCELED. */
649 log_info (_("cancelled by user\n") );
650 if (canceled)
651 *canceled = 1;
653 else
655 log_error (_("problem with the agent - disabling agent use\n"));
656 opt.use_agent = 0;
661 failure:
662 #ifdef ENABLE_NLS
663 if (orig_codeset)
665 bind_textdomain_codeset (PACKAGE, orig_codeset);
666 xfree (orig_codeset);
668 #endif
669 xfree (atext);
670 agent_close (ctx);
671 xfree (pw );
672 if (pk)
673 free_public_key( pk );
675 #endif /*ENABLE_AGENT_SUPPORT*/
677 return NULL;
682 * Clear the cached passphrase. If CACHEID is not NULL, it will be
683 * used instead of a cache ID derived from KEYID.
685 void
686 passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
688 #ifdef ENABLE_AGENT_SUPPORT
689 assuan_context_t ctx = NULL;
690 PKT_public_key *pk;
691 byte fpr[MAX_FINGERPRINT_LEN];
693 #if MAX_FINGERPRINT_LEN < 20
694 #error agent needs a 20 byte fingerprint
695 #endif
697 if (!opt.use_agent)
698 return;
700 if (!cacheid)
702 pk = xcalloc (1, sizeof *pk);
703 memset (fpr, 0, MAX_FINGERPRINT_LEN );
704 if( !keyid || get_pubkey( pk, keyid ) )
706 goto failure; /* oops: no key for some reason */
710 size_t dummy;
711 fingerprint_from_pk( pk, fpr, &dummy );
714 else
715 pk = NULL;
717 if ( !(ctx = agent_open (0, NULL)) )
718 goto failure;
721 char *line, *p;
722 int i, rc;
724 if (cacheid)
726 line = xmalloc (17 + 3*strlen (cacheid) + 2);
727 strcpy (line, "CLEAR_PASSPHRASE ");
728 p = line+17;
729 p = percent_plus_escape (p, cacheid);
731 else
733 line = xmalloc (17 + 40 + 2);
734 strcpy (line, "CLEAR_PASSPHRASE ");
735 p = line+17;
736 for (i=0; i < 20; i++, p +=2 )
737 sprintf (p, "%02X", fpr[i]);
739 *p = 0;
741 rc = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
742 xfree (line);
743 if (rc)
745 log_error (_("problem with the agent - disabling agent use\n"));
746 opt.use_agent = 0;
750 failure:
751 agent_close (ctx);
752 if (pk)
753 free_public_key( pk );
754 #endif /*ENABLE_AGENT_SUPPORT*/
758 /****************
759 * Ask for a passphrase and return that string.
761 char *
762 ask_passphrase (const char *description,
763 const char *tryagain_text,
764 const char *promptid,
765 const char *prompt,
766 const char *cacheid, int *canceled)
768 char *pw = NULL;
770 if (canceled)
771 *canceled = 0;
773 if (!opt.batch && description)
775 if (strchr (description, '%'))
777 char *tmp = unescape_percent_string (description);
778 tty_printf ("\n%s\n", tmp);
779 xfree (tmp);
781 else
782 tty_printf ("\n%s\n",description);
785 agent_died:
786 if ( opt.use_agent )
788 pw = agent_get_passphrase (NULL, 0, cacheid,
789 tryagain_text, description, prompt,
790 canceled );
791 if (!pw)
793 if (!opt.use_agent)
794 goto agent_died;
795 pw = NULL;
798 else if (fd_passwd)
800 pw = xmalloc_secure (strlen(fd_passwd)+1);
801 strcpy (pw, fd_passwd);
803 else if (opt.batch)
805 log_error(_("can't query passphrase in batch mode\n"));
806 pw = NULL;
808 else {
809 if (tryagain_text)
810 tty_printf(_("%s.\n"), tryagain_text);
811 pw = cpr_get_hidden(promptid? promptid : "passphrase.ask",
812 prompt?prompt : _("Enter passphrase: ") );
813 tty_kill_prompt();
816 if (!pw || !*pw)
817 write_status( STATUS_MISSING_PASSPHRASE );
819 return pw;
823 /* Return a new DEK object Using the string-to-key sepcifier S2K. Use
824 * KEYID and PUBKEY_ALGO to prompt the user.
826 MODE 0: Allow cached passphrase
827 1: Ignore cached passphrase
828 2: Ditto, but change the text to "repeat entry"
830 DEK *
831 passphrase_to_dek( u32 *keyid, int pubkey_algo,
832 int cipher_algo, STRING2KEY *s2k, int mode,
833 const char *tryagain_text, int *canceled)
835 char *pw = NULL;
836 DEK *dek;
837 STRING2KEY help_s2k;
839 if (canceled)
840 *canceled = 0;
842 if( !s2k ) {
843 /* This is used for the old rfc1991 mode
844 * Note: This must match the code in encode.c with opt.rfc1991 set */
845 s2k = &help_s2k;
846 s2k->mode = 0;
847 s2k->hash_algo = S2K_DIGEST_ALGO;
850 /* If we do not have a passphrase available in NEXT_PW and status
851 information are request, we print them now. */
852 if( !next_pw && is_status_enabled() ) {
853 char buf[50];
855 if( keyid ) {
856 u32 used_kid[2];
857 char *us;
859 if( keyid[2] && keyid[3] ) {
860 used_kid[0] = keyid[2];
861 used_kid[1] = keyid[3];
863 else {
864 used_kid[0] = keyid[0];
865 used_kid[1] = keyid[1];
868 us = get_long_user_id_string( keyid );
869 write_status_text( STATUS_USERID_HINT, us );
870 xfree(us);
872 sprintf( buf, "%08lX%08lX %08lX%08lX %d 0",
873 (ulong)keyid[0], (ulong)keyid[1],
874 (ulong)used_kid[0], (ulong)used_kid[1],
875 pubkey_algo );
877 write_status_text( STATUS_NEED_PASSPHRASE, buf );
879 else {
880 sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo );
881 write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf );
885 /* If we do have a keyID, we do not have a passphrase available in
886 NEXT_PW, we are not running in batch mode and we do not want to
887 ignore the passphrase cache (mode!=1), print a prompt with
888 information on that key. */
889 if( keyid && !opt.batch && !next_pw && mode!=1 ) {
890 PKT_public_key *pk = xmalloc_clear( sizeof *pk );
891 char *p;
893 p=get_user_id_native(keyid);
894 tty_printf("\n");
895 tty_printf(_("You need a passphrase to unlock the secret key for\n"
896 "user: \"%s\"\n"),p);
897 xfree(p);
899 if( !get_pubkey( pk, keyid ) ) {
900 const char *s = gcry_pk_algo_name ( pk->pubkey_algo );
901 tty_printf( _("%u-bit %s key, ID %s, created %s"),
902 nbits_from_pk( pk ), s?s:"?", keystr(keyid),
903 strtimestamp(pk->timestamp) );
904 if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
905 && keyid[1] != keyid[3] )
907 if(keystrlen()>10)
909 tty_printf("\n");
910 tty_printf(_(" (subkey on main key ID %s)"),
911 keystr(&keyid[2]) );
913 else
914 tty_printf( _(" (main key ID %s)"), keystr(&keyid[2]) );
916 tty_printf("\n");
919 tty_printf("\n");
920 if (pk)
921 free_public_key( pk );
924 agent_died:
925 if( next_pw ) {
926 /* Simply return the passphrase we already have in NEXT_PW. */
927 pw = next_pw;
928 next_pw = NULL;
930 else if ( opt.use_agent ) {
931 /* Divert to the gpg-agent. */
932 pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, NULL,
933 tryagain_text, NULL, NULL, canceled );
934 if (!pw)
936 if (!opt.use_agent)
937 goto agent_died;
938 pw = xstrdup ("");
940 if( *pw && mode == 2 ) {
941 char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL, NULL,
942 NULL, canceled );
943 if (!pw2)
945 if (!opt.use_agent)
947 xfree (pw);
948 pw = NULL;
949 goto agent_died;
951 pw2 = xstrdup ("");
953 if( strcmp(pw, pw2) ) {
954 xfree(pw2);
955 xfree(pw);
956 return NULL;
958 xfree(pw2);
961 else if( fd_passwd ) {
962 /* Return the passphrase we have store in FD_PASSWD. */
963 pw = xmalloc_secure( strlen(fd_passwd)+1 );
964 strcpy( pw, fd_passwd );
966 else if( opt.batch )
968 log_error(_("can't query passphrase in batch mode\n"));
969 pw = xstrdup( "" ); /* return an empty passphrase */
971 else {
972 /* Read the passphrase from the tty or the command-fd. */
973 pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") );
974 tty_kill_prompt();
975 if( mode == 2 && !cpr_enabled() ) {
976 char *pw2 = cpr_get_hidden("passphrase.repeat",
977 _("Repeat passphrase: ") );
978 tty_kill_prompt();
979 if( strcmp(pw, pw2) ) {
980 xfree(pw2);
981 xfree(pw);
982 return NULL;
984 xfree(pw2);
988 if( !pw || !*pw )
989 write_status( STATUS_MISSING_PASSPHRASE );
991 /* Hash the passphrase and store it in a newly allocated DEK
992 object. Keep a copy of the passphrase in LAST_PW for use by
993 get_last_passphrase(). */
994 dek = xmalloc_secure_clear ( sizeof *dek );
995 dek->algo = cipher_algo;
996 if( !*pw && mode == 2 )
997 dek->keylen = 0;
998 else
999 hash_passphrase( dek, pw, s2k, mode==2 );
1000 xfree(last_pw);
1001 last_pw = pw;
1002 return dek;
1006 /****************
1007 * Hash a passphrase using the supplied s2k. If create is true, create
1008 * a new salt or what else must be filled into the s2k for a new key.
1009 * always needs: dek->algo, s2k->mode, s2k->hash_algo.
1011 static void
1012 hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
1014 gcry_md_hd_t md;
1015 int pass, i;
1016 int used = 0;
1017 int pwlen = strlen(pw);
1019 assert( s2k->hash_algo );
1020 dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
1021 if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
1022 BUG();
1024 if (gcry_md_open (&md, s2k->hash_algo, 1))
1025 BUG ();
1026 for(pass=0; used < dek->keylen ; pass++ ) {
1027 if( pass ) {
1028 gcry_md_reset (md);
1029 for(i=0; i < pass; i++ ) /* preset the hash context */
1030 gcry_md_putc (md, 0 );
1033 if( s2k->mode == 1 || s2k->mode == 3 ) {
1034 int len2 = pwlen + 8;
1035 ulong count = len2;
1037 if( create && !pass ) {
1038 gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
1039 if( s2k->mode == 3 )
1040 s2k->count = 96; /* 65536 iterations */
1043 if( s2k->mode == 3 ) {
1044 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
1045 if( count < len2 )
1046 count = len2;
1048 /* a little bit complicated because we need a ulong for count */
1049 while( count > len2 ) { /* maybe iterated+salted */
1050 gcry_md_write ( md, s2k->salt, 8 );
1051 gcry_md_write ( md, pw, pwlen );
1052 count -= len2;
1054 if( count < 8 )
1055 gcry_md_write ( md, s2k->salt, count );
1056 else {
1057 gcry_md_write ( md, s2k->salt, 8 );
1058 count -= 8;
1059 gcry_md_write ( md, pw, count );
1062 else
1063 gcry_md_write ( md, pw, pwlen );
1064 gcry_md_final( md );
1065 i = gcry_md_get_algo_dlen ( s2k->hash_algo );
1066 if( i > dek->keylen - used )
1067 i = dek->keylen - used;
1068 memcpy (dek->key+used, gcry_md_read (md, s2k->hash_algo), i);
1069 used += i;
1071 gcry_md_close(md);