aboutsummaryrefslogtreecommitdiffstats
path: root/g10/passphrase.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>1998-09-28 19:25:31 +0000
committerWerner Koch <[email protected]>1998-09-28 19:25:31 +0000
commit41fa8a3345aecf9b85c1eebb33f9b961a558db1c (patch)
tree4f5745dc77207f40dabd7f9a176b7255e8994223 /g10/passphrase.c
parent. (diff)
downloadgnupg-41fa8a3345aecf9b85c1eebb33f9b961a558db1c.tar.gz
gnupg-41fa8a3345aecf9b85c1eebb33f9b961a558db1c.zip
*** empty log message ***
Diffstat (limited to 'g10/passphrase.c')
-rw-r--r--g10/passphrase.c138
1 files changed, 80 insertions, 58 deletions
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 7dbaeb466..2e649119d 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -34,22 +34,16 @@
#include "i18n.h"
#include "status.h"
-static int pwfd = -1;
+static char *fd_passwd = NULL;
static char *next_pw = NULL;
static char *last_pw = NULL;
static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create );
-void
-set_passphrase_fd( int fd )
-{
- pwfd = fd;
-}
-
int
-get_passphrase_fd()
+have_static_passphrase()
{
- return pwfd;
+ return !!fd_passwd;
}
/****************
@@ -81,6 +75,36 @@ get_last_passphrase()
}
+void
+read_passphrase_from_fd( int fd )
+{
+ int i, len;
+ char *pw;
+
+ if( !opt.batch )
+ tty_printf("Reading passphrase from file descriptor %d ...", fd );
+ for( pw = NULL, i = len = 100; ; i++ ) {
+ if( i >= len-1 ) {
+ char *pw2 = pw;
+ len += 100;
+ pw = m_alloc_secure( len );
+ if( pw2 )
+ memcpy(pw, pw2, i );
+ else
+ i=0;
+ }
+ if( read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
+ break;
+ }
+ pw[i] = 0;
+ if( !opt.batch )
+ tty_printf("\b\b\b \n" );
+
+ m_free( fd_passwd );
+ fd_passwd = pw;
+}
+
+
/****************
* Get a passphrase for the secret key with KEYID, display TEXT
* if the user needs to enter the passphrase.
@@ -140,26 +164,9 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
pw = next_pw;
next_pw = NULL;
}
- else if( pwfd != -1 ) { /* read the passphrase from the file */
- int i, len;
-
- if( !opt.batch )
- tty_printf("Reading from file descriptor %d ...", pwfd );
- for( pw = NULL, i = len = 100; ; i++ ) {
- if( i >= len-1 ) {
- char *pw2 = pw;
- len += 100;
- pw = m_alloc_secure( len );
- if( pw2 )
- memcpy(pw, pw2, i );
- i=0;
- }
- if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' )
- break;
- }
- pw[i] = 0;
- if( !opt.batch )
- tty_printf("\b\b\b \n" );
+ else if( fd_passwd ) {
+ pw = m_alloc_secure( strlen(fd_passwd)+1 );
+ strcpy( pw, fd_passwd );
}
else if( opt.batch )
log_fatal("Can't query password in batchmode\n");
@@ -192,54 +199,69 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
/****************
* Hash a passphrase using the supplied s2k. If create is true, create
- * a new salt or whatelse must be filled into the s2k for a new key.
+ * a new salt or what else must be filled into the s2k for a new key.
* always needs: dek->algo, s2k->mode, s2k->hash_algo.
*/
static void
hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
{
MD_HANDLE md;
+ int pass, i;
+ int used = 0;
+ int pwlen = strlen(pw);
assert( s2k->hash_algo );
- dek->keylen = 0;
+ dek->keylen = cipher_get_keylen( dek->algo ) / 8;
+ if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
+ BUG();
+
md = md_open( s2k->hash_algo, 1);
- if( s2k->mode == 1 || s2k->mode == 3 ) {
- ulong count = 0;
- int len = strlen(pw);
- int len2 = len + 8;
+ for(pass=0; used < dek->keylen ; pass++ ) {
+ if( pass ) {
+ md_reset(md);
+ for(i=0; i < pass; i++ ) /* preset the hash context */
+ md_putc(md, 0 );
+ }
- if( create )
- randomize_buffer(s2k->salt, 8, 1);
+ if( s2k->mode == 1 || s2k->mode == 3 ) {
+ int len2 = pwlen + 8;
+ ulong count = len2;
- if( s2k->mode == 3 ) {
- count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
- log_debug("s2k iteration count=%lu\n", count );
- }
- for(;;) {
- md_write( md, s2k->salt, 8 );
- md_write( md, pw, len );
- if( count <= len2 )
- break;
- count -= len2;
- }
- if( count ) {
- if( count < 8 ) {
- md_write( md, s2k->salt, count );
+ if( create && !pass ) {
+ randomize_buffer(s2k->salt, 8, 1);
+ if( s2k->mode == 3 )
+ s2k->count = 96; /* = 56536 */
}
+
+ if( s2k->mode == 3 ) {
+ count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
+ if( count < len2 )
+ count = len2;
+ }
+ /* a little bit complicated because we need a ulong for count */
+ while( count > len2 ) { /* maybe iterated+salted */
+ md_write( md, s2k->salt, 8 );
+ md_write( md, pw, pwlen );
+ count -= len2;
+ }
+ if( count < 8 )
+ md_write( md, s2k->salt, count );
else {
md_write( md, s2k->salt, 8 );
count -= 8;
- assert( count <= len );
+ assert( count >= 0 );
md_write( md, pw, count );
}
}
+ else
+ md_write( md, pw, pwlen );
+ md_final( md );
+ i = md_digest_length( s2k->hash_algo );
+ if( i > dek->keylen - used )
+ i = dek->keylen - used;
+ memcpy( dek->key+used, md_read(md, s2k->hash_algo), i );
+ used += i;
}
- else
- md_write( md, pw, strlen(pw) );
- md_final( md );
- dek->keylen = cipher_get_keylen( dek->algo ) / 8;
- assert(dek->keylen > 0 && dek->keylen <= DIM(dek->key) );
- memcpy( dek->key, md_read(md,0), dek->keylen );
md_close(md);
}