c95b27bbd1c6ec52f1fd2ae7a508312518b34672
[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 <assert.h>
26 #include "util.h"
27 #include "memory.h"
28 #include "ttyio.h"
29 #include "cipher.h"
30
31
32 static int hash_passphrase( DEK *dek, char *pw );
33
34
35 /****************
36  * Get a passphrase for the secret key with KEYID, display TEXT
37  * if the user needs to enter the passphrase.
38  * Returns: m_alloced md5 passphrase hash; caller must free
39  */
40 DEK *
41 get_passphrase_hash( u32 *keyid, char *text )
42 {
43     char *p=NULL, *pw;
44     DEK *dek;
45
46     if( keyid ) {
47         tty_printf("Need a pass phrase to unlock the secret key!\n");
48         tty_printf("KeyID: %08lX\n\n",  keyid[1] );
49     }
50     if( keyid && (p=getenv("PGPPATHPHRASE")) ) {
51         pw = m_alloc_secure(strlen(p)+1);
52         strcpy(pw,p);
53         tty_printf("Taking it from $PGPPATHPHRASE !\n",  keyid[1] );
54     }
55     else
56         pw = tty_get_hidden("Enter pass phrase: " );
57     dek = m_alloc_secure( sizeof *dek );
58     dek->algo = CIPHER_ALGO_BLOWFISH;
59     if( hash_passphrase( dek, pw ) )
60         log_bug("get_passphrase_hash\n");
61     m_free(pw); /* is allocated in secure memory, so it will be burned */
62     if( !p ) {
63         tty_kill_prompt();
64         tty_printf("\n\n");
65     }
66     return dek;
67 }
68
69
70 /****************
71  * This function is used to construct a DEK from a user input.
72  * It uses the default CIPHER
73  */
74 int
75 make_dek_from_passphrase( DEK *dek, int mode )
76 {
77     char *pw, *pw2;
78     int rc=0;
79
80     pw = tty_get_hidden("Enter pass phrase: " );
81     tty_kill_prompt();
82     if( mode == 2 ) {
83         pw2 = tty_get_hidden("Repeat pass phrase: " );
84         if( strcmp(pw, pw2) ) {
85             m_free(pw2);
86             m_free(pw);
87             return G10ERR_PASSPHRASE;
88         }
89         m_free(pw2);
90     }
91     rc = hash_passphrase( dek, pw );
92     m_free(pw);
93     return rc;
94 }
95
96
97 static int
98 hash_passphrase( DEK *dek, char *pw )
99 {
100     int rc = 0;
101
102     dek->keylen = 0;
103     if( dek->algo == CIPHER_ALGO_IDEA ) {
104         MD5HANDLE md5;
105
106         md5 = md5_open(1);
107         md5_write( md5, pw, strlen(pw) );
108         md5_final( md5 );
109         dek->keylen = 16;
110         memcpy( dek->key, md5_read(md5), dek->keylen );
111         md5_close(md5);
112     }
113     else if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
114         RMDHANDLE rmd;
115
116         rmd = rmd160_open(1);
117         rmd160_write( rmd, pw, strlen(pw) );
118         dek->keylen = 20;
119         memcpy( dek->key, rmd160_final(rmd), dek->keylen );
120         rmd160_close(rmd);
121     }
122     else
123         rc = G10ERR_UNSUPPORTED;
124     return rc;
125 }
126