added some trust model stuff
[gnupg.git] / g10 / passphrase.c
1 /* passphrase.c -  Get a passphrase
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 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  * G10 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 "memory.h"
29 #include "options.h"
30 #include "ttyio.h"
31 #include "cipher.h"
32 #include "keydb.h"
33
34 static int pwfd = -1;
35
36 static int hash_passphrase( DEK *dek, char *pw );
37
38 void
39 set_passphrase_fd( int fd )
40 {
41     pwfd = fd;
42 }
43
44 int
45 get_passphrase_fd()
46 {
47     return pwfd;
48 }
49
50
51 /****************
52  * Get a passphrase for the secret key with KEYID, display TEXT
53  * if the user needs to enter the passphrase.
54  * Returns: m_alloced md5 passphrase hash; caller must free
55  */
56 DEK *
57 get_passphrase_hash( u32 *keyid, char *text )
58 {
59     char *pw;
60     DEK *dek;
61
62     if( keyid && !opt.batch ) {
63         char *ustr;
64         tty_printf("Need a pass phrase to unlock the secret key for:\n");
65         tty_printf("  \"" );
66         ustr = get_user_id_string( keyid );
67         tty_print_string( ustr, strlen(ustr) );
68         m_free(ustr);
69         tty_printf("\"\n\n");
70
71     }
72     if( pwfd != -1 ) { /* read the passphrase from the given descriptor */
73         int i, len;
74
75         if( !opt.batch )
76             tty_printf("Reading from file descriptor %d ...", pwfd );
77         for( pw = NULL, i = len = 100; ; i++ ) {
78             if( i >= len-1 ) {
79                 char *pw2 = pw;
80                 len += 100;
81                 pw = m_alloc_secure( len );
82                 if( pw2 )
83                     memcpy(pw, pw2, i );
84                 i=0;
85             }
86             if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' )
87                 break;
88         }
89         pw[i] = 0;
90         if( !opt.batch )
91             tty_printf("\b\b\b   \n" );
92     }
93     else if( opt.batch )
94         log_fatal("Can't query password in batchmode\n");
95     else {
96         pw = tty_get_hidden("Enter pass phrase: " );
97         tty_kill_prompt();
98     }
99     dek = m_alloc_secure( sizeof *dek );
100     dek->algo = CIPHER_ALGO_BLOWFISH;
101     if( hash_passphrase( dek, pw ) )
102         log_bug("get_passphrase_hash\n");
103     m_free(pw); /* is allocated in secure memory, so it will be burned */
104     return dek;
105 }
106
107
108 /****************
109  * This function is used to construct a DEK from a user input.
110  * It uses the default CIPHER
111  * Returns: 0 = okay, -1 No passphrase entered, > 0 error
112  */
113 int
114 make_dek_from_passphrase( DEK *dek, int mode )
115 {
116     char *pw, *pw2;
117     int rc=0;
118
119     pw = tty_get_hidden("Enter pass phrase: " );
120     tty_kill_prompt();
121     if( mode == 2 ) {
122         pw2 = tty_get_hidden("Repeat pass phrase: " );
123         tty_kill_prompt();
124         if( strcmp(pw, pw2) ) {
125             m_free(pw2);
126             m_free(pw);
127             return G10ERR_PASSPHRASE;
128         }
129         m_free(pw2);
130     }
131     if( !*pw )
132         rc = -1;
133     else
134         rc = hash_passphrase( dek, pw );
135     m_free(pw);
136     return rc;
137 }
138
139
140 static int
141 hash_passphrase( DEK *dek, char *pw )
142 {
143     int rc = 0;
144
145     dek->keylen = 0;
146     if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
147         MD_HANDLE md;
148
149         md = md_open(DIGEST_ALGO_RMD160, 1);
150         md_write( md, pw, strlen(pw) );
151         md_final( md );
152         dek->keylen = 20;
153         memcpy( dek->key, md_read(md,0), dek->keylen );
154         md_close(md);
155     }
156     else
157         rc = G10ERR_UNSUPPORTED;
158     return rc;
159 }
160