aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--VERSION2
-rw-r--r--cipher/Makefile.am1
-rw-r--r--cipher/Makefile.in5
-rw-r--r--cipher/md.c10
-rw-r--r--cipher/misc.c152
-rw-r--r--config.h.in7
-rw-r--r--configure.in2
-rw-r--r--g10/OPTIONS3
-rw-r--r--g10/cipher.c9
-rw-r--r--g10/encode.c6
-rw-r--r--g10/encr-data.c3
-rw-r--r--g10/g10.c39
-rw-r--r--g10/keygen.c102
-rw-r--r--g10/keyid.c127
-rw-r--r--g10/main.h4
-rw-r--r--g10/mainproc.c2
-rw-r--r--g10/options.h6
-rw-r--r--g10/pubkey-enc.c5
-rw-r--r--g10/seskey.c4
-rw-r--r--include/cipher.h8
-rw-r--r--include/util.h6
-rw-r--r--util/iobuf.c2
-rw-r--r--util/strgutil.c48
24 files changed, 475 insertions, 81 deletions
diff --git a/TODO b/TODO
index 41065cf28..bcd64edd7 100644
--- a/TODO
+++ b/TODO
@@ -35,3 +35,6 @@
* armor has now some problems.
+ * add g10 stuff to Mutt's pgpinvoke.c
+
+
diff --git a/VERSION b/VERSION
index 17e51c385..d917d3e26 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.1
+0.1.2
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 2f0792cb9..0855d7da9 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -23,6 +23,7 @@ cipher_SOURCES = blowfish.c \
dsa.h \
dsa.c \
md.c \
+ misc.c \
smallprime.c
cipher_LIBADD = @CIPHER_EXTRA_OBJS@
diff --git a/cipher/Makefile.in b/cipher/Makefile.in
index f71937966..7bd7691f8 100644
--- a/cipher/Makefile.in
+++ b/cipher/Makefile.in
@@ -60,6 +60,7 @@ cipher_SOURCES = blowfish.c \
dsa.h \
dsa.c \
md.c \
+ misc.c \
smallprime.c
cipher_LIBADD = @CIPHER_EXTRA_OBJS@
@@ -82,7 +83,7 @@ LIBS = @LIBS@
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(LDFLAGS) -o $@
cipher_OBJECTS = blowfish.o elgamal.o gost.o md5.o primegen.o random.o \
-rmd160.o sha1.o dsa.o md.o smallprime.o
+rmd160.o sha1.o dsa.o md.o misc.o smallprime.o
EXTRA_cipher_SOURCES =
LIBFILES = libcipher.a
AR = ar
@@ -101,7 +102,7 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
TAR = tar
DEP_FILES = $(srcdir)/.deps/blowfish.P $(srcdir)/.deps/dsa.P \
$(srcdir)/.deps/elgamal.P $(srcdir)/.deps/gost.P $(srcdir)/.deps/md.P \
-$(srcdir)/.deps/md5.P $(srcdir)/.deps/primegen.P \
+$(srcdir)/.deps/md5.P $(srcdir)/.deps/misc.P $(srcdir)/.deps/primegen.P \
$(srcdir)/.deps/random.P $(srcdir)/.deps/rmd160.P \
$(srcdir)/.deps/sha1.P $(srcdir)/.deps/smallprime.P
SOURCES = $(cipher_SOURCES)
diff --git a/cipher/md.c b/cipher/md.c
index 71403c8c9..67f5356a8 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -26,17 +26,11 @@
#include "cipher.h"
#include "errors.h"
+
int
md_okay( int algo )
{
- switch( algo ) {
- case DIGEST_ALGO_MD5:
- case DIGEST_ALGO_RMD160:
- case DIGEST_ALGO_SHA1:
- return 0;
- default:
- return G10ERR_DIGEST_ALGO;
- }
+ return check_digest_algo( algo );
}
diff --git a/cipher/misc.c b/cipher/misc.c
new file mode 100644
index 000000000..cd0d31a49
--- /dev/null
+++ b/cipher/misc.c
@@ -0,0 +1,152 @@
+/* misc.c - utility functions
+ * Copyright (c) 1997 by Werner Koch (dd9jn)
+ *
+ * This file is part of G10.
+ *
+ * G10 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * G10 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "util.h"
+#include "cipher.h"
+
+
+static struct { const char *name; int algo;} cipher_names[] = {
+ { "IDEA", CIPHER_ALGO_IDEA },
+ { "3DES", CIPHER_ALGO_3DES },
+ { "CAST", CIPHER_ALGO_CAST },
+ { "BLOWFISH128", CIPHER_ALGO_BLOWFISH128 },
+ { "ROT_N", CIPHER_ALGO_ROT_N },
+ { "SAFER_SK128", CIPHER_ALGO_SAFER_SK128 },
+ { "DES_SK", CIPHER_ALGO_DES_SK },
+ { "BLOWFISH", CIPHER_ALGO_BLOWFISH },
+ { "GOST", CIPHER_ALGO_GOST },
+ {NULL} };
+
+static struct { const char *name; int algo;} pubkey_names[] = {
+ { "RSA", PUBKEY_ALGO_RSA },
+ { "RSA-E", PUBKEY_ALGO_RSA_E },
+ { "RSA-S", PUBKEY_ALGO_RSA_S },
+ { "ELGAMAL", PUBKEY_ALGO_ELGAMAL },
+ { "ELG", PUBKEY_ALGO_ELGAMAL },
+ { "DSA", PUBKEY_ALGO_DSA },
+ {NULL} };
+
+static struct { const char *name; int algo;} digest_names[] = {
+ { "MD5", DIGEST_ALGO_MD5 },
+ { "SHA1", DIGEST_ALGO_SHA1 },
+ { "SHA-1", DIGEST_ALGO_SHA1 },
+ { "RMD160", DIGEST_ALGO_RMD160 },
+ { "RMD-160", DIGEST_ALGO_RMD160 },
+ { "RIPE-MD-160", DIGEST_ALGO_RMD160 },
+ {NULL} };
+
+
+/****************
+ * Map a string to the cipher algo
+ */
+int
+string_to_cipher_algo( const char *string )
+{
+ int i;
+ const char *s;
+
+ for(i=0; s=cipher_names[i].name; i++ )
+ if( !stricmp( s, string ) )
+ return cipher_names[i].algo;
+ return 0;
+}
+
+
+/****************
+ * Map a string to the pubkey algo
+ */
+int
+string_to_pubkey_algo( const char *string )
+{
+ int i;
+ const char *s;
+
+ for(i=0; s=pubkey_names[i].name; i++ )
+ if( !stricmp( s, string ) )
+ return pubkey_names[i].algo;
+ return 0;
+}
+
+/****************
+ * Map a string to the digest algo
+ */
+int
+string_to_digest_algo( const char *string )
+{
+ int i;
+ const char *s;
+
+ for(i=0; s=digest_names[i].name; i++ )
+ if( !stricmp( s, string ) )
+ return digest_names[i].algo;
+ return 0;
+}
+
+/****************
+ * Return 0 if the cipher algo is available
+ */
+int
+check_cipher_algo( int algo )
+{
+ switch( algo ) {
+ case CIPHER_ALGO_BLOWFISH128:
+ case CIPHER_ALGO_BLOWFISH:
+ return 0;
+ default:
+ return G10ERR_CIPHER_ALGO;
+ }
+}
+
+
+int
+check_pubkey_algo( int algo )
+{
+ switch( algo ) {
+ case PUBKEY_ALGO_ELGAMAL:
+ #ifdef HAVE_RSA_CIPHER
+ case PUBKEY_ALGO_RSA:
+ #endif
+ return 0;
+ default:
+ return G10ERR_PUBKEY_ALGO;
+ }
+}
+
+
+int
+check_digest_algo( int algo )
+{
+ switch( algo ) {
+ case DIGEST_ALGO_MD5:
+ case DIGEST_ALGO_RMD160:
+ case DIGEST_ALGO_SHA1:
+ return 0;
+ default:
+ return G10ERR_DIGEST_ALGO;
+ }
+}
+
+
+
diff --git a/config.h.in b/config.h.in
index 93f0acb96..2a3bd36e4 100644
--- a/config.h.in
+++ b/config.h.in
@@ -78,11 +78,8 @@
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
-/* Define if you have the strtol function. */
-#undef HAVE_STRTOL
-
-/* Define if you have the strtoul function. */
-#undef HAVE_STRTOUL
+/* Define if you have the strlwr function. */
+#undef HAVE_STRLWR
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
diff --git a/configure.in b/configure.in
index 65ae82e27..f01033baf 100644
--- a/configure.in
+++ b/configure.in
@@ -155,7 +155,7 @@ AC_CHECK_SIZEOF(unsigned long, 4)
dnl Checks for library functions.
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(strerror strtol strtoul stpcpy tcgetattr)
+AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr)
dnl check wether we have a random device
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
diff --git a/g10/OPTIONS b/g10/OPTIONS
index a5961763b..684abd2d9 100644
--- a/g10/OPTIONS
+++ b/g10/OPTIONS
@@ -165,6 +165,9 @@ no-default-keyring
no-greeting
# suppress the initial copyright etc. messages but do not enter batch mode.
+no-verbose
+# set verbose level to 0
+
options filename
# Ignored in option files.
diff --git a/g10/cipher.c b/g10/cipher.c
index 6900e896c..37bba3458 100644
--- a/g10/cipher.c
+++ b/g10/cipher.c
@@ -67,7 +67,8 @@ cipher_filter( void *opaque, int control,
randomize_buffer( temp, 8, 1 );
temp[8] = temp[6];
temp[9] = temp[7];
- if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH ) {
+ if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
+ || cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 ) {
cfx->bf_ctx = m_alloc_secure( sizeof *cfx->bf_ctx );
blowfish_setkey( cfx->bf_ctx, cfx->dek->key, cfx->dek->keylen );
blowfish_setiv( cfx->bf_ctx, NULL );
@@ -80,13 +81,15 @@ cipher_filter( void *opaque, int control,
cfx->header=1;
}
- if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH )
+ if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
+ || cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 )
blowfish_encode_cfb( cfx->bf_ctx, buf, buf, size);
if( iobuf_write( a, buf, size ) )
rc = G10ERR_WRITE_FILE;
}
else if( control == IOBUFCTRL_FREE ) {
- if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH )
+ if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
+ || cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 )
m_free(cfx->bf_ctx);
}
else if( control == IOBUFCTRL_DESC ) {
diff --git a/g10/encode.c b/g10/encode.c
index b0b148dd1..688cbfc08 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -88,7 +88,7 @@ encode_simple( const char *filename, int mode )
cfx.dek = NULL;
if( mode ) {
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
- cfx.dek->algo = DEFAULT_CIPHER_ALGO;
+ cfx.dek->algo = opt.def_cipher_algo;
if( (rc = make_dek_from_passphrase( cfx.dek , 2 )) ) {
m_free(cfx.dek);
iobuf_close(inp);
@@ -199,7 +199,7 @@ encode_crypt( const char *filename, STRLIST remusr )
/* create a session key */
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
- cfx.dek->algo = DEFAULT_CIPHER_ALGO;
+ cfx.dek->algo = opt.def_cipher_algo;
make_session_key( cfx.dek );
if( DBG_CIPHER )
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
@@ -269,7 +269,7 @@ encrypt_filter( void *opaque, int control,
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
if( !efx->header_okay ) {
efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
- efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
+ efx->cfx.dek->algo = opt.def_cipher_algo;
make_session_key( efx->cfx.dek );
if( DBG_CIPHER )
log_hexdump("DEK is: ",
diff --git a/g10/encr-data.c b/g10/encr-data.c
index aed1890a6..43e48a96d 100644
--- a/g10/encr-data.c
+++ b/g10/encr-data.c
@@ -51,7 +51,8 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
byte temp[16];
- if( dek->algo != CIPHER_ALGO_BLOWFISH )
+ if( dek->algo != CIPHER_ALGO_BLOWFISH
+ && dek->algo != CIPHER_ALGO_BLOWFISH128 )
return G10ERR_CIPHER_ALGO;
if( ed->len && ed->len < 10 )
log_bug("Nanu\n"); /* oops: found a bug */
diff --git a/g10/g10.c b/g10/g10.c
index ac12d52db..30776cc80 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -169,6 +169,10 @@ main( int argc, char **argv )
{ 523, "passphrase-fd",1, "\r" },
{ 524, "edit-sig" ,0, "edit a key signature" },
{ 525, "change-passphrase", 0, "change the passphrase of your secret keyring"},
+ { 526, "no-verbose", 0, "\r"},
+ { 527, "cipher-algo", 2 , "select default cipher algorithm" },
+ { 528, "pubkey-algo", 2 , "select default puplic key algorithm" },
+ { 529, "digest-algo", 2 , "select default message digest algorithm" },
{0} };
ARGPARSE_ARGS pargs;
@@ -194,6 +198,9 @@ main( int argc, char **argv )
opt.compress = -1; /* defaults to standard compress level */
+ opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
+ opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL;
+ opt.def_digest_algo = DIGEST_ALGO_RMD160;
/* check wether we have a config file on the commandline */
orig_argc = argc;
@@ -298,6 +305,19 @@ main( int argc, char **argv )
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
case 524: set_cmd( &cmd, aEditSig); break;
case 525: set_cmd( &cmd, aChangePass); break;
+ case 526: opt.verbose = 0; opt.list_sigs=0; break;
+ case 527:
+ opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str);
+ break;
+ case 528:
+ opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str);
+ break;
+ case 529:
+ opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str);
+ break;
+
+
+ break;
default : errors++; pargs.err = configfp? 1:2; break;
}
}
@@ -308,6 +328,18 @@ main( int argc, char **argv )
goto next_pass;
}
m_free( configname ); configname = NULL;
+ if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) {
+ log_error("selected cipher algorithm is invalid\n");
+ errors++;
+ }
+ if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) {
+ log_error("selected pubkey algorithm is invalid\n");
+ errors++;
+ }
+ if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) ) {
+ log_error("selected digest algorithm is invalid\n");
+ errors++;
+ }
if( errors )
exit(2);
@@ -351,6 +383,13 @@ main( int argc, char **argv )
else {
fname_print = "[stdin]";
fname = NULL;
+ if( get_passphrase_fd() == 0 ) {
+ /* reading data and passphrase form stdin:
+ * we assume the first line is the passphrase, so
+ * we read it now
+ */
+ /* FIXME: doit */
+ }
}
switch( cmd ) {
diff --git a/g10/keygen.c b/g10/keygen.c
index 958be3af4..fddeedbbc 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -305,6 +305,7 @@ generate_keypair()
int rc;
int algo;
const char *algo_name;
+ char *aname, *acomment, *amail;
#ifndef TEST_ALGO
if( opt.batch || opt.answer_yes || opt.answer_no )
@@ -404,27 +405,102 @@ generate_keypair()
uid = m_alloc(strlen(TEST_UID)+1);
strcpy(uid, TEST_UID);
#else
- tty_printf( "\nYou need a User-ID to identify your key; please use your name and your\n"
- "email address in this suggested format:\n"
- " \"Heinrich Heine <[email protected]>\n" );
+ tty_printf( "\n"
+"You need a User-ID to identify your key; the software constructs the user id\n"
+"from Real Name, Comment and Email Address in this form:\n"
+" \"Heinrich Heine (Der Dichter) <[email protected]>\"\n" );
uid = NULL;
+ aname=acomment=amail=NULL;
for(;;) {
+ char *p;
+
+ if( !aname ) {
+ for(;;) {
+ m_free(aname);
+ aname = tty_get("Real name: ");
+ trim_spaces(aname);
+ tty_kill_prompt();
+ if( strpbrk( aname, "<([])>" ) )
+ tty_printf("Invalid character in name\n");
+ else if( strlen(aname) < 5 )
+ tty_printf("Name must be at least 5 characters long\n");
+ else
+ break;
+ }
+ }
+ if( !amail ) {
+ for(;;) {
+ m_free(amail);
+ amail = tty_get("Email address: ");
+ trim_spaces(amail);
+ strlwr(amail);
+ tty_kill_prompt();
+ if( !*amail )
+ break; /* no email address is okay */
+ else if( strcspn( amail, "abcdefghijklmnopqrstuvwxyz_-.@" )
+ || string_count_chr(amail,'@') != 1
+ || *amail == '@'
+ || amail[strlen(amail)-1] == '@'
+ || amail[strlen(amail)-1] == '.'
+ || strstr(amail, "..") )
+ tty_printf("Not a valid email address\n");
+ else
+ break;
+ }
+ }
+ if( !acomment ) {
+ for(;;) {
+ m_free(acomment);
+ acomment = tty_get("Comment: ");
+ trim_spaces(acomment);
+ tty_kill_prompt();
+ if( !*acomment )
+ break; /* no comment is okay */
+ else if( strpbrk( acomment, "()" ) )
+ tty_printf("Invalid character in comment\n");
+ else
+ break;
+ }
+ }
+
m_free(uid);
- tty_printf("\n");
- uid = tty_get("Your User-ID: ");
- tty_kill_prompt();
- if( strlen(uid) < 5 )
- tty_printf("Please enter a string of at least 5 characters\n");
- else {
- tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
- answer = tty_get("Is this correct? ");
+ uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+10);
+ p = stpcpy(p, aname );
+ if( *acomment )
+ p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
+ if( *amail )
+ p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
+
+ tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
+ for(;;) {
+ answer = tty_get("Edit (N)ame, (C)omment, (E)mail or (O)kay? ");
tty_kill_prompt();
- if( answer_is_yes(answer) ) {
- m_free(answer);
+ if( strlen(answer) > 1 )
+ ;
+ else if( *answer == 'N' || *answer == 'n' ) {
+ m_free(aname); aname = NULL;
+ break;
+ }
+ else if( *answer == 'C' || *answer == 'c' ) {
+ m_free(acomment); acomment = NULL;
+ break;
+ }
+ else if( *answer == 'E' || *answer == 'e' ) {
+ m_free(amail); amail = NULL;
+ break;
+ }
+ else if( *answer == 'O' || *answer == 'o' ) {
+ m_free(aname); aname = NULL;
+ m_free(acomment); acomment = NULL;
+ m_free(amail); amail = NULL;
break;
}
m_free(answer);
}
+ m_free(answer);
+ if( !amail && !acomment && !amail )
+ break;
+ m_free(uid); uid = NULL;
}
#endif
diff --git a/g10/keyid.c b/g10/keyid.c
index 5848459c8..43413e083 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -46,6 +46,77 @@ pubkey_letter( int algo )
}
}
+/* this is special code for V3 which uses ElGamal and
+ * calculates a fingerprint like V4, but with rmd160
+ * and a version byte of 3. Returns an rmd160 handle, caller must
+ * do rmd160_final()
+ */
+
+static RMDHANDLE
+v3_elg_fingerprint_md( PKT_public_cert *pkc )
+{
+ RMDHANDLE md;
+ byte *buf1, *buf2, *buf3;
+ byte *p1, *p2, *p3;
+ unsigned n1, n2, n3;
+ unsigned n;
+
+ p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
+ for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
+ ;
+ p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
+ for( ; !*p2 && n2; p2++, n2-- ) /* skip leading null bytes */
+ ;
+ p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
+ for( ; !*p3 && n3; p3++, n3-- ) /* skip leading null bytes */
+ ;
+
+ /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
+ n = 14 + n1 + n2 + n3;
+ md = rmd160_open(0);
+
+ rmd160_putchar( md, 0x99 ); /* ctb */
+ rmd160_putchar( md, n >> 8 ); /* 2 byte length header */
+ rmd160_putchar( md, n );
+ rmd160_putchar( md, 3 ); /* version */
+ { u32 a = pkc->timestamp;
+ rmd160_putchar( md, a >> 24 );
+ rmd160_putchar( md, a >> 16 );
+ rmd160_putchar( md, a >> 8 );
+ rmd160_putchar( md, a );
+ }
+ { u16 a = pkc->valid_days;
+ rmd160_putchar( md, a >> 8 );
+ rmd160_putchar( md, a );
+ }
+ rmd160_putchar( md, pkc->pubkey_algo );
+ rmd160_putchar( md, n1>>8); rmd160_putchar( md, n1 ); rmd160_write( md, p1, n1 );
+ rmd160_putchar( md, n2>>8); rmd160_putchar( md, n2 ); rmd160_write( md, p2, n2 );
+ rmd160_putchar( md, n3>>8); rmd160_putchar( md, n3 ); rmd160_write( md, p3, n3 );
+ m_free(buf1);
+ m_free(buf2);
+ m_free(buf3);
+
+ return md;
+}
+
+
+static RMDHANDLE
+v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
+{
+ PKT_public_cert pkc;
+ byte *p;
+
+ pkc.pubkey_algo = skc->pubkey_algo;
+ pkc.timestamp = skc->timestamp;
+ pkc.valid_days = skc->valid_days;
+ pkc.pubkey_algo = skc->pubkey_algo;
+ pkc.d.elg.p = skc->d.elg.p;
+ pkc.d.elg.g = skc->d.elg.g;
+ pkc.d.elg.y = skc->d.elg.y;
+ return v3_elg_fingerprint_md( &pkc );
+}
+
/****************
* Get the keyid from the secret key certificate and put it into keyid
@@ -61,7 +132,14 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
keyid = dummy_keyid;
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
- lowbits = mpi_get_keyid( skc->d.elg.y, keyid );
+ const byte *dp;
+ RMDHANDLE md;
+ md = v3_elg_fingerprint_md_skc(skc);
+ dp = rmd160_final( md );
+ keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+ keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
+ lowbits = keyid[1];
+ rmd160_close(md);
}
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
@@ -87,7 +165,14 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
keyid = dummy_keyid;
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
- lowbits = mpi_get_keyid( pkc->d.elg.y, keyid );
+ const byte *dp;
+ RMDHANDLE md;
+ md = v3_elg_fingerprint_md(pkc);
+ dp = rmd160_final( md );
+ keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+ keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
+ lowbits = keyid[1];
+ rmd160_close(md);
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
@@ -213,47 +298,21 @@ fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
return p;
}
+
+
+
byte *
fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
{
byte *p, *buf, *array;
+ const char *dp;
size_t len;
unsigned n;
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
RMDHANDLE md;
- const char *dp;
-
- md = rmd160_open(0);
-
- { u32 a = pkc->timestamp;
- rmd160_putchar( md, a >> 24 );
- rmd160_putchar( md, a >> 16 );
- rmd160_putchar( md, a >> 8 );
- rmd160_putchar( md, a );
- }
- { u16 a = pkc->valid_days;
- rmd160_putchar( md, a >> 8 );
- rmd160_putchar( md, a );
- }
- rmd160_putchar( md, pkc->pubkey_algo );
- p = buf = mpi_get_buffer( pkc->d.elg.p, &n, NULL );
- for( ; !*p && n; p++, n-- )
- ;
- rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
- m_free(buf);
- p = buf = mpi_get_buffer( pkc->d.elg.g, &n, NULL );
- for( ; !*p && n; p++, n-- )
- ;
- rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
- m_free(buf);
- p = buf = mpi_get_buffer( pkc->d.elg.y, &n, NULL );
- for( ; !*p && n; p++, n-- )
- ;
- rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
- m_free(buf);
-
- dp = rmd160_final(md);
+ md = v3_elg_fingerprint_md(pkc);
+ dp = rmd160_final( md );
array = m_alloc( 20 );
len = 20;
memcpy(array, dp, 20 );
diff --git a/g10/main.h b/g10/main.h
index 02b0a277c..747ab70a8 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -24,10 +24,6 @@
#include "cipher.h"
#include "keydb.h"
-#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_BLOWFISH
-#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
-#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_RMD160
-
typedef struct {
int header_okay;
diff --git a/g10/mainproc.c b/g10/mainproc.c
index b46cb1344..a99c975fd 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -232,7 +232,7 @@ proc_encrypted( CTX c, PACKET *pkt )
if( !c->dek && !c->last_was_pubkey_enc ) {
/* assume this is conventional encrypted data */
c->dek = m_alloc_secure( sizeof *c->dek );
- c->dek->algo = DEFAULT_CIPHER_ALGO;
+ c->dek->algo = opt.def_cipher_algo;
result = make_dek_from_passphrase( c->dek, 0 );
}
else if( !c->dek )
diff --git a/g10/options.h b/g10/options.h
index 31aa95522..0df1f41ea 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -36,9 +36,9 @@ struct {
int list_sigs; /* list signatures */
int no_armor;
int list_packets; /* list-packets mode */
- int reserved6;
- int reserved7;
- int reserved8;
+ int def_cipher_algo;
+ int def_pubkey_algo;
+ int def_digest_algo;
int reserved9;
int reserved10;
int reserved11;
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index f3f02abde..2f8fb45f4 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -131,6 +131,11 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
dek->algo = CIPHER_ALGO_BLOWFISH;
break;
+ case CIPHER_ALGO_BLOWFISH128:
+ if( i != 18 ) /* length of blowfish-128 is 16 (+2 bytes checksum) */
+ { rc = G10ERR_WRONG_SECKEY; goto leave; }
+ dek->algo = CIPHER_ALGO_BLOWFISH128;
+ break;
default:
rc = G10ERR_CIPHER_ALGO;
goto leave;
diff --git a/g10/seskey.c b/g10/seskey.c
index 7d3cba27b..2698c73c7 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -41,6 +41,10 @@ make_session_key( DEK *dek )
dek->keylen = 20;
randomize_buffer( dek->key, dek->keylen, 1 );
break;
+ case CIPHER_ALGO_BLOWFISH128:
+ dek->keylen = 16;
+ randomize_buffer( dek->key, dek->keylen, 1 );
+ break;
default: log_bug("invalid algo %d in make_session_key()\n");
}
diff --git a/include/cipher.h b/include/cipher.h
index ed553dcb2..fd7886c90 100644
--- a/include/cipher.h
+++ b/include/cipher.h
@@ -88,7 +88,13 @@ int cipher_debug_mode;
#define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL )
#endif
-
+/*-- misc.c --*/
+int string_to_cipher_algo( const char *string );
+int string_to_pubkey_algo( const char *string );
+int string_to_digest_algo( const char *string );
+int check_cipher_algo( int algo );
+int check_pubkey_algo( int algo );
+int check_digest_algo( int algo );
/*-- md.c --*/
int md_okay( int algo );
diff --git a/include/util.h b/include/util.h
index 46f337955..34015ffe6 100644
--- a/include/util.h
+++ b/include/util.h
@@ -92,10 +92,16 @@ int answer_is_yes( const char *s );
void free_strlist( STRLIST sl );
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
char *memistr( char *buf, size_t buflen, const char *sub );
+char *trim_spaces( char *string );
+int string_count_chr( const char *string, int c );
+
#define stricmp(a,b) strcasecmp((a),(b))
#ifndef HAVE_STPCPY
char *stpcpy(char *a,const char *b);
#endif
+#ifndef HAVE_STRLWR
+char *strlwr(char *a);
+#endif
/******** some macros ************/
diff --git a/util/iobuf.c b/util/iobuf.c
index 981fb2efb..ad9821972 100644
--- a/util/iobuf.c
+++ b/util/iobuf.c
@@ -350,7 +350,7 @@ iobuf_create( const char *fname )
file_filter_ctx_t *fcx;
size_t len;
- if( !fname ) {
+ if( !fname || (*fname=='-' && !fname[1]) ) {
fp = stdout;
fname = "[stdout]";
}
diff --git a/util/strgutil.c b/util/strgutil.c
index daeefe8ae..ecdcb750c 100644
--- a/util/strgutil.c
+++ b/util/strgutil.c
@@ -62,6 +62,43 @@ memistr( char *buf, size_t buflen, const char *sub )
}
+/****************
+ * remove leading and trailing white spaces
+ */
+char *
+trim_spaces( char *str )
+{
+ char *string, *p, *mark;
+
+ string = str;
+ /* find first non space character */
+ for( p=string; *p && isspace( *(byte*)p ) ; p++ )
+ ;
+ /* move characters */
+ for( (mark = NULL); (*string = *p); string++, p++ )
+ if( isspace( *(byte*)p ) ) {
+ if( !mark )
+ mark = string ;
+ }
+ else
+ mark = NULL ;
+ if( mark )
+ *mark = '\0' ; /* remove trailing spaces */
+
+ return str ;
+}
+
+
+int
+string_count_chr( const char *string, int c )
+{
+ int count;
+ for(count=0; *string; string++ )
+ if( *string == c )
+ count++;
+ return count;
+}
+
/*********************************************
********** missing string functions *********
*********************************************/
@@ -78,3 +115,14 @@ stpcpy(char *a,const char *b)
}
#endif
+#ifndef HAVE_STRLWR
+char *
+strlwr(char *s)
+{
+ char *p;
+ for(p=s; *p; p++ )
+ *p = tolower(*p);
+ return s;
+}
+#endif
+