See ChangeLog: Mon Jan 31 16:37:34 CET 2000 Werner Koch
[gnupg.git] / g10 / passphrase.c
1 /* passphrase.c -  Get a passphrase
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <assert.h>
27 #include "util.h"
28 #include <gcrypt.h>
29 #include "options.h"
30 #include "ttyio.h"
31 #include "keydb.h"
32 #include "main.h"
33 #include "i18n.h"
34 #include "status.h"
35
36 static char *fd_passwd = NULL;
37 static char *next_pw = NULL;
38 static char *last_pw = NULL;
39
40 static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create );
41
42 int
43 have_static_passphrase()
44 {
45     return !!fd_passwd;
46 }
47
48 /****************
49  * Set the passphrase to be used for the next query and only for the next
50  * one.
51  */
52 void
53 set_next_passphrase( const char *s )
54 {
55     gcry_free(next_pw);
56     next_pw = NULL;
57     if( s ) {
58         next_pw = gcry_xmalloc_secure( strlen(s)+1 );
59         strcpy(next_pw, s );
60     }
61 }
62
63 /****************
64  * Get the last passphrase used in passphrase_to_dek.
65  * Note: This removes the passphrase from this modules and
66  * the caller must free the result.  May return NULL:
67  */
68 char *
69 get_last_passphrase()
70 {
71     char *p = last_pw;
72     last_pw = NULL;
73     return p;
74 }
75
76
77 void
78 read_passphrase_from_fd( int fd )
79 {
80     int i, len;
81     char *pw;
82
83     if( !opt.batch )
84         tty_printf("Reading passphrase from file descriptor %d ...", fd );
85     for( pw = NULL, i = len = 100; ; i++ ) {
86         if( i >= len-1 ) {
87             char *pw2 = pw;
88             len += 100;
89             pw = gcry_xmalloc_secure( len );
90             if( pw2 )
91                 memcpy(pw, pw2, i );
92             else
93                 i=0;
94         }
95         if( read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
96             break;
97     }
98     pw[i] = 0;
99     if( !opt.batch )
100         tty_printf("\b\b\b   \n" );
101
102     gcry_free( fd_passwd );
103     fd_passwd = pw;
104 }
105
106
107 /****************
108  * Get a passphrase for the secret key with KEYID, display TEXT
109  * if the user needs to enter the passphrase.
110  * mode 0 = standard, 2 = create new passphrase
111  * Returns: a DEK with a session key; caller must free
112  *          or NULL if the passphrase was not correctly repeated.
113  *          (only for mode 2)
114  *          a dek->keylen of 0 means: no passphrase entered.
115  *          (only for mode 2)
116  * pubkey_algo is only informational.
117  */
118 DEK *
119 passphrase_to_dek( u32 *keyid, int pubkey_algo,
120                    int cipher_algo, STRING2KEY *s2k, int mode )
121 {
122     char *pw = NULL;
123     DEK *dek;
124     STRING2KEY help_s2k;
125
126     if( !s2k ) {
127         s2k = &help_s2k;
128         s2k->mode = 0;
129         /* this should be MD5 if cipher is IDEA, but because we do
130          * not have IDEA, we use the default one, the user
131          * can select it from the commandline
132          */
133         s2k->hash_algo = opt.def_digest_algo?opt.def_digest_algo
134                                             :DEFAULT_DIGEST_ALGO;
135     }
136
137     if( !next_pw && is_status_enabled() ) {
138         char buf[50];
139         if( keyid ) {
140             sprintf( buf, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1] );
141             if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
142                                      && keyid[1] != keyid[3] )
143                 sprintf( buf+strlen(buf), " %08lX%08lX %d 0",
144                            (ulong)keyid[2], (ulong)keyid[3], pubkey_algo );
145             write_status_text( STATUS_NEED_PASSPHRASE, buf );
146         }
147         else {
148             sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo );
149             write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf );
150         }
151     }
152
153     if( keyid && !opt.batch && !next_pw ) {
154         PKT_public_key *pk = gcry_xcalloc( 1, sizeof *pk );
155         size_t n;
156         char *p;
157
158         tty_printf(_("\nYou need a passphrase to unlock the secret key for\n"
159                      "user: \"") );
160         p = get_user_id( keyid, &n );
161         tty_print_utf8_string( p, n );
162         gcry_free(p);
163         tty_printf("\"\n");
164
165         if( !get_pubkey( pk, keyid ) ) {
166             tty_printf( _("%u-bit %s key, ID %08lX, created %s"),
167                        nbits_from_pk( pk ),
168                        gcry_pk_algo_name( pk->pubkey_algo ), (ulong)keyid[1],
169                        strtimestamp(pk->timestamp) );
170             if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
171                                      && keyid[1] != keyid[3] )
172                 tty_printf( _(" (main key ID %08lX)"), (ulong)keyid[3] );
173             tty_printf("\n");
174         }
175
176         tty_printf("\n");
177         free_public_key( pk );
178     }
179
180     if( next_pw ) {
181         pw = next_pw;
182         next_pw = NULL;
183     }
184     else if( fd_passwd ) {
185         pw = gcry_xmalloc_secure( strlen(fd_passwd)+1 );
186         strcpy( pw, fd_passwd );
187     }
188     else if( opt.batch ) {
189         log_error(_("can't query password in batchmode\n"));
190         pw = gcry_xstrdup( "" ); /* return an empty passphrase */
191     }
192     else {
193         pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") );
194         tty_kill_prompt();
195         if( mode == 2 && !cpr_enabled() ) {
196             char *pw2 = cpr_get_hidden("passphrase.repeat",
197                                        _("Repeat passphrase: ") );
198             tty_kill_prompt();
199             if( strcmp(pw, pw2) ) {
200                 gcry_free(pw2);
201                 gcry_free(pw);
202                 return NULL;
203             }
204             gcry_free(pw2);
205         }
206     }
207
208     if( !pw || !*pw )
209         write_status( STATUS_MISSING_PASSPHRASE );
210
211     dek = gcry_xmalloc_secure( sizeof *dek );
212     dek->algo = cipher_algo;
213     if( !*pw && mode == 2 )
214         dek->keylen = 0;
215     else
216         hash_passphrase( dek, pw, s2k, mode==2 );
217     gcry_free(last_pw);
218     last_pw = pw;
219     return dek;
220 }
221
222
223 /****************
224  * Hash a passphrase using the supplied s2k. If create is true, create
225  * a new salt or what else must be filled into the s2k for a new key.
226  * always needs: dek->algo, s2k->mode, s2k->hash_algo.
227  */
228 static void
229 hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
230 {
231     GCRY_MD_HD md;
232     int pass, i;
233     int used = 0;
234     int pwlen = strlen(pw);
235
236     assert( s2k->hash_algo );
237     dek->keylen = gcry_cipher_get_algo_keylen( dek->algo );
238     if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
239         BUG();
240
241     if( !(md = gcry_md_open( s2k->hash_algo, GCRY_MD_FLAG_SECURE )) )
242         BUG();
243
244     for(pass=0; used < dek->keylen ; pass++ ) {
245         if( pass ) {
246             gcry_md_reset(md);
247             for(i=0; i < pass; i++ ) /* preset the hash context */
248                 gcry_md_putc(md, 0 );
249         }
250
251         if( s2k->mode == 1 || s2k->mode == 3 ) {
252             int len2 = pwlen + 8;
253             ulong count = len2;
254
255             if( create && !pass ) {
256                 gcry_randomize(s2k->salt, 8, GCRY_STRONG_RANDOM );
257                 if( s2k->mode == 3 )
258                     s2k->count = 96; /* 65536 iterations */
259             }
260
261             if( s2k->mode == 3 ) {
262                 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
263                 if( count < len2 )
264                     count = len2;
265             }
266             /* a little bit complicated because we need a ulong for count */
267             while( count > len2 ) { /* maybe iterated+salted */
268                 gcry_md_write( md, s2k->salt, 8 );
269                 gcry_md_write( md, pw, pwlen );
270                 count -= len2;
271             }
272             if( count < 8 )
273                 gcry_md_write( md, s2k->salt, count );
274             else {
275                 gcry_md_write( md, s2k->salt, 8 );
276                 count -= 8;
277                 assert( count >= 0 );
278                 gcry_md_write( md, pw, count );
279             }
280         }
281         else
282             gcry_md_write( md, pw, pwlen );
283         gcry_md_final( md );
284         i = gcry_md_get_algo_dlen( s2k->hash_algo );
285         if( i > dek->keylen - used )
286             i = dek->keylen - used;
287         memcpy( dek->key+used, gcry_md_read(md, s2k->hash_algo), i );
288         used += i;
289     }
290     gcry_md_close(md);
291 }
292