From 5c1cca042e6bc0de22c7913f08457c7b8a46e592 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 1 Dec 1997 10:33:23 +0000 Subject: [PATCH] List and check sigs works --- TODO | 3 +- cipher/Makefile.am | 1 + cipher/Makefile.in | 9 +- cipher/blowfish.c | 36 +- cipher/elgamal.c | 32 +- cipher/elgamal.h | 4 +- cipher/md.c | 158 +++++++++ cipher/md5.c | 12 + cipher/rmd160.c | 13 + g10/build-packet.c | 34 +- g10/cipher.c | 10 +- g10/compress.c | 4 +- g10/encode.c | 12 +- g10/encr-data.c | 2 +- g10/filter.h | 1 + g10/free-packet.c | 28 +- g10/g10.c | 19 +- g10/getkey.c | 122 ++++--- g10/keydb.h | 21 +- g10/keygen.c | 32 +- g10/keyid.c | 99 +++++- g10/main.h | 1 + g10/mainproc.c | 833 +++++++++++++++++++-------------------------- g10/options.h | 2 +- g10/packet.h | 80 ++--- g10/parse-packet.c | 84 ++--- g10/pubkey-enc.c | 8 +- g10/seckey-cert.c | 8 +- g10/seskey.c | 12 + g10/sig-check.c | 71 ++-- include/cipher.h | 25 +- include/errors.h | 1 + include/util.h | 1 + util/errors.c | 1 + util/miscutil.c | 21 ++ 35 files changed, 1007 insertions(+), 793 deletions(-) create mode 100644 cipher/md.c diff --git a/TODO b/TODO index 7021c4e38..2076d25f5 100644 --- a/TODO +++ b/TODO @@ -6,7 +6,6 @@ function of iobuf. * filter all output read from the input when displaying it to the user. * keyring editing - * improve the prime number generator * remove some debugging stuff (e.g. the listing mode in mainproc) * add trust stuff * make ttyio.c work (hide passwords etc..) @@ -19,7 +18,7 @@ * look for a way to reuse RSA signatures * find a way to remove the armor filter after it has detected, that the data is not armored. - * Use the Chines Remainder Theorem to speed up RSA calculations. + * Use the Chinese Remainder Theorem to speed up RSA calculations. * remove all "Fixmes" * speed up the RIPE-MD-160 * add signal handling diff --git a/cipher/Makefile.am b/cipher/Makefile.am index b994cbe0e..939a48303 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -18,6 +18,7 @@ cipher_SOURCES = blowfish.c \ random.c \ rmd.h \ rmd160.c \ + md.c \ smallprime.c cipher_LIBADD = rsa.o diff --git a/cipher/Makefile.in b/cipher/Makefile.in index 0daff112c..96081b73f 100644 --- a/cipher/Makefile.in +++ b/cipher/Makefile.in @@ -55,6 +55,7 @@ cipher_SOURCES = blowfish.c \ random.c \ rmd.h \ rmd160.c \ + md.c \ smallprime.c cipher_LIBADD = rsa.o @@ -77,7 +78,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 smallprime.o +rmd160.o md.o smallprime.o EXTRA_cipher_SOURCES = LIBFILES = libcipher.a AR = ar @@ -95,9 +96,9 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \ TAR = tar DEP_FILES = $(srcdir)/.deps/blowfish.P $(srcdir)/.deps/elgamal.P \ -$(srcdir)/.deps/gost.P $(srcdir)/.deps/md5.P $(srcdir)/.deps/primegen.P \ -$(srcdir)/.deps/random.P $(srcdir)/.deps/rmd160.P \ -$(srcdir)/.deps/smallprime.P +$(srcdir)/.deps/gost.P $(srcdir)/.deps/md.P $(srcdir)/.deps/md5.P \ +$(srcdir)/.deps/primegen.P $(srcdir)/.deps/random.P \ +$(srcdir)/.deps/rmd160.P $(srcdir)/.deps/smallprime.P SOURCES = $(cipher_SOURCES) OBJECTS = $(cipher_OBJECTS) diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 59f1afa8c..97817e33d 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -242,7 +242,7 @@ function_F( BLOWFISH_context *bc, u32 x ) static void -encipher( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) +encrypted( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { u32 xl, xr, temp; int i; @@ -270,7 +270,7 @@ encipher( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) } static void -decipher( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) +decrypted( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) { u32 xl, xr, temp; int i; @@ -298,25 +298,25 @@ decipher( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) } static void -encipher_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) +encrypted_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) { u32 d1, d2; d1 = ((u32*)inbuf)[0]; d2 = ((u32*)inbuf)[1]; - encipher( bc, &d1, &d2 ); + encrypted( bc, &d1, &d2 ); ((u32*)outbuf)[0] = d1; ((u32*)outbuf)[1] = d2; } static void -decipher_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) +decrypted_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) { u32 d1, d2; d1 = ((u32*)inbuf)[0]; d2 = ((u32*)inbuf)[1]; - decipher( bc, &d1, &d2 ); + decrypted( bc, &d1, &d2 ); ((u32*)outbuf)[0] = d1; ((u32*)outbuf)[1] = d2; } @@ -349,27 +349,27 @@ blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) datal = datar = 0; for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 ) { - encipher( c, &datal, &datar ); + encrypted( c, &datal, &datar ); c->p[i] = datal; c->p[i+1] = datar; } for(i=0; i < 256; i += 2 ) { - encipher( c, &datal, &datar ); + encrypted( c, &datal, &datar ); c->s0[i] = datal; c->s0[i+1] = datar; } for(i=0; i < 256; i += 2 ) { - encipher( c, &datal, &datar ); + encrypted( c, &datal, &datar ); c->s1[i] = datal; c->s1[i+1] = datar; } for(i=0; i < 256; i += 2 ) { - encipher( c, &datal, &datar ); + encrypted( c, &datal, &datar ); c->s2[i] = datal; c->s2[i+1] = datar; } for(i=0; i < 256; i += 2 ) { - encipher( c, &datal, &datar ); + encrypted( c, &datal, &datar ); c->s3[i] = datal; c->s3[i+1] = datar; } @@ -384,7 +384,7 @@ blowfish_setiv( BLOWFISH_context *c, byte *iv ) else memset( c->iv, 0, BLOWFISH_BLOCKSIZE ); c->count = 0; - encipher_block( c, c->eniv, c->iv ); + encrypted_block( c, c->eniv, c->iv ); } @@ -395,7 +395,7 @@ blowfish_encode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, unsigned n; for(n=0; n < nblocks; n++ ) { - encipher_block( c, outbuf, inbuf ); + encrypted_block( c, outbuf, inbuf ); inbuf += BLOWFISH_BLOCKSIZE;; outbuf += BLOWFISH_BLOCKSIZE; } @@ -408,7 +408,7 @@ blowfish_decode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, unsigned n; for(n=0; n < nblocks; n++ ) { - decipher_block( c, outbuf, inbuf ); + decrypted_block( c, outbuf, inbuf ); inbuf += BLOWFISH_BLOCKSIZE;; outbuf += BLOWFISH_BLOCKSIZE; } @@ -451,7 +451,7 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf, outbuf += n; assert( c->count <= BLOWFISH_BLOCKSIZE); if( c->count == BLOWFISH_BLOCKSIZE ) { - encipher_block( c, c->eniv, c->iv ); + encrypted_block( c, c->eniv, c->iv ); c->count = 0; } else @@ -461,7 +461,7 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf, while( nbytes >= BLOWFISH_BLOCKSIZE ) { xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE); memcpy( c->iv, outbuf, BLOWFISH_BLOCKSIZE); - encipher_block( c, c->eniv, c->iv ); + encrypted_block( c, c->eniv, c->iv ); nbytes -= BLOWFISH_BLOCKSIZE; inbuf += BLOWFISH_BLOCKSIZE; outbuf += BLOWFISH_BLOCKSIZE; @@ -495,7 +495,7 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf, outbuf += n; assert( c->count <= BLOWFISH_BLOCKSIZE); if( c->count == BLOWFISH_BLOCKSIZE ) { - encipher_block( c, c->eniv, c->iv ); + encrypted_block( c, c->eniv, c->iv ); c->count = 0; } else @@ -506,7 +506,7 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf, while( nbytes >= BLOWFISH_BLOCKSIZE ) { memcpy( c->iv, inbuf, BLOWFISH_BLOCKSIZE); xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE); - encipher_block( c, c->eniv, c->iv ); + encrypted_block( c, c->eniv, c->iv ); nbytes -= BLOWFISH_BLOCKSIZE; inbuf += BLOWFISH_BLOCKSIZE; outbuf += BLOWFISH_BLOCKSIZE; diff --git a/cipher/elgamal.c b/cipher/elgamal.c index b1239732d..a7450e068 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -60,10 +60,10 @@ test_keys( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits ) mpi_set_bytes( test, nbits, get_random_byte, 0 ); - elg_encipher( out1_a, out1_b, test, pk ); - elg_decipher( out2, out1_a, out1_b, sk ); + elg_encrypted( out1_a, out1_b, test, pk ); + elg_decrypted( out2, out1_a, out1_b, sk ); if( mpi_cmp( test, out2 ) ) - log_fatal("ElGamal operation: encipher, decipher failed\n"); + log_fatal("ElGamal operation: encrypted, decrypted failed\n"); elg_sign( out1_a, out1_b, test, sk ); if( !elg_verify( out1_a, out1_b, test, pk ) ) @@ -182,7 +182,7 @@ elg_check_secret_key( ELG_secret_key *sk ) void -elg_encipher(MPI a, MPI b, MPI input, ELG_public_key *pkey ) +elg_encrypted(MPI a, MPI b, MPI input, ELG_public_key *pkey ) { MPI k; @@ -197,12 +197,12 @@ elg_encipher(MPI a, MPI b, MPI input, ELG_public_key *pkey ) mpi_mulm( b, b, input, pkey->p ); #if 0 if( DBG_CIPHER ) { - log_mpidump("elg encipher y= ", pkey->y); - log_mpidump("elg encipher p= ", pkey->p); - log_mpidump("elg encipher k= ", k); - log_mpidump("elg encipher M= ", input); - log_mpidump("elg encipher a= ", a); - log_mpidump("elg encipher b= ", b); + log_mpidump("elg encrypted y= ", pkey->y); + log_mpidump("elg encrypted p= ", pkey->p); + log_mpidump("elg encrypted k= ", k); + log_mpidump("elg encrypted M= ", input); + log_mpidump("elg encrypted a= ", a); + log_mpidump("elg encrypted b= ", b); } #endif mpi_free(k); @@ -212,7 +212,7 @@ elg_encipher(MPI a, MPI b, MPI input, ELG_public_key *pkey ) void -elg_decipher(MPI output, MPI a, MPI b, ELG_secret_key *skey ) +elg_decrypted(MPI output, MPI a, MPI b, ELG_secret_key *skey ) { MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); @@ -223,11 +223,11 @@ elg_decipher(MPI output, MPI a, MPI b, ELG_secret_key *skey ) mpi_mulm( output, b, t1, skey->p ); #if 0 if( DBG_CIPHER ) { - log_mpidump("elg decipher x= ", skey->x); - log_mpidump("elg decipher p= ", skey->p); - log_mpidump("elg decipher a= ", a); - log_mpidump("elg decipher b= ", b); - log_mpidump("elg decipher M= ", output); + log_mpidump("elg decrypted x= ", skey->x); + log_mpidump("elg decrypted p= ", skey->p); + log_mpidump("elg decrypted a= ", a); + log_mpidump("elg decrypted b= ", b); + log_mpidump("elg decrypted M= ", output); } #endif mpi_free(t1); diff --git a/cipher/elgamal.h b/cipher/elgamal.h index e93b49e59..4086a8fc5 100644 --- a/cipher/elgamal.h +++ b/cipher/elgamal.h @@ -41,8 +41,8 @@ void elg_free_public_key( ELG_public_key *pk ); void elg_free_secret_key( ELG_secret_key *sk ); void elg_generate( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits ); int elg_check_secret_key( ELG_secret_key *sk ); -void elg_encipher(MPI a, MPI b, MPI input, ELG_public_key *pkey ); -void elg_decipher(MPI output, MPI a, MPI b, ELG_secret_key *skey ); +void elg_encrypted(MPI a, MPI b, MPI input, ELG_public_key *pkey ); +void elg_decrypted(MPI output, MPI a, MPI b, ELG_secret_key *skey ); void elg_sign(MPI a, MPI b, MPI input, ELG_secret_key *skey); int elg_verify(MPI a, MPI b, MPI input, ELG_public_key *pkey); diff --git a/cipher/md.c b/cipher/md.c new file mode 100644 index 000000000..a14d62f32 --- /dev/null +++ b/cipher/md.c @@ -0,0 +1,158 @@ +/* md.c - message digest dispatcher + * 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 +#include +#include +#include +#include "util.h" +#include "cipher.h" +#include "errors.h" + +int +md_okay( int algo ) +{ + switch( algo ) { + case DIGEST_ALGO_MD5: + case DIGEST_ALGO_RMD160: + return 0; + default: + return G10ERR_DIGEST_ALGO; + } +} + + +MD_HANDLE * +md_open( int algo, int secure ) +{ + MD_HANDLE *hd; + + hd = m_alloc( sizeof *hd + 19 ); + hd->algo = algo; + hd->datalen = 0; + if( algo == DIGEST_ALGO_MD5 ) + hd->u.md5 = md5_open( secure ); + else if( algo == DIGEST_ALGO_RMD160 ) + hd->u.rmd= rmd160_open( secure ); + else + return NULL; + + return hd; +} + + +MD_HANDLE * +md_copy( MD_HANDLE *a ) +{ + MD_HANDLE *hd; + + hd = m_alloc( sizeof *hd + 19 ); + hd->algo = a->algo; + hd->datalen = 0; + if( a->algo == DIGEST_ALGO_MD5 ) + hd->u.md5 = md5_copy( a->u.md5 ); + else if( a->algo == DIGEST_ALGO_RMD160 ) + hd->u.rmd= rmd160_copy( a->u.rmd ); + else + log_bug(NULL); + return hd; +} + + +/* used for a BAD Kludge in rmd160.c, md5.c */ +MD_HANDLE * +md_makecontainer( int algo ) +{ + MD_HANDLE *hd; + + hd = m_alloc( sizeof *hd + 19 ); + hd->algo = algo; + hd->datalen = 0; + if( algo == DIGEST_ALGO_MD5 ) + ; + else if( algo == DIGEST_ALGO_RMD160 ) + ; + else + log_bug(NULL); + return hd; +} + +void +md_close(MD_HANDLE *a) +{ + if( !a ) + return; + if( a->algo == DIGEST_ALGO_MD5 ) + md5_close( a->u.md5 ); + else if( a->algo == DIGEST_ALGO_RMD160 ) + rmd160_close( a->u.rmd ); + else + log_bug(NULL); + m_free(a); +} + + +void +md_write( MD_HANDLE *a, byte *inbuf, size_t inlen) +{ + if( a->algo == DIGEST_ALGO_MD5 ) + md5_write( a->u.md5, inbuf, inlen ); + else if( a->algo == DIGEST_ALGO_RMD160 ) + rmd160_write( a->u.rmd, inbuf, inlen ); + else + log_bug(NULL); +} + + +void +md_putchar( MD_HANDLE *a, int c ) +{ + if( a->algo == DIGEST_ALGO_MD5 ) + md5_putchar( a->u.md5, c ); + else if( a->algo == DIGEST_ALGO_RMD160 ) + rmd160_putchar( a->u.rmd, c ); + else + log_bug(NULL); +} + + +byte * +md_final(MD_HANDLE *a) +{ + if( a->algo == DIGEST_ALGO_MD5 ) { + if( !a->datalen ) { + md5_final( a->u.md5 ); + memcpy(a->data, md5_read( a->u.md5 ), 16); + a->datalen = 16; + } + return a->data; + } + else if( a->algo == DIGEST_ALGO_RMD160 ) { + if( !a->datalen ) { + memcpy(a->data, rmd160_final( a->u.rmd ), 20 ); + a->datalen = 20; + } + return a->data; + } + else + log_bug(NULL); +} + + diff --git a/cipher/md5.c b/cipher/md5.c index 98429ab77..06e3a88f4 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -55,6 +55,7 @@ #include #include "util.h" #include "md5.h" +#include "cipher.h" /* kludge for md5_copy2md() */ #include "memory.h" @@ -142,6 +143,17 @@ md5_copy( MD5HANDLE a ) return mdContext; } + +/* BAD Kludge!!! */ +MD_HANDLE * +md5_copy2md( MD5HANDLE a ) +{ + MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_MD5 ); + md->u.md5 = md5_copy( a ); + return md; +} + + void md5_close(MD5HANDLE hd) { diff --git a/cipher/rmd160.c b/cipher/rmd160.c index 9a882fc5e..2c583d576 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -25,6 +25,7 @@ #include #include "util.h" #include "memory.h" +#include "cipher.h" /* grrrr */ #include "rmd.h" /********************************* @@ -261,6 +262,18 @@ rmd160_copy( RMDHANDLE a ) return b; } + +/* BAD Kludge!!! */ +MD_HANDLE * +rmd160_copy2md( RMDHANDLE a ) +{ + MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_RMD160 ); + md->u.rmd = rmd160_copy( a ); + return md; +} + + + void rmd160_close(RMDHANDLE hd) { diff --git a/g10/build-packet.c b/g10/build-packet.c index c0ddb9e24..910929658 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -36,12 +36,12 @@ static int do_comment( IOBUF out, int ctb, PKT_comment *rem ); static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid ); -static int do_pubkey_cert( IOBUF out, int ctb, PKT_pubkey_cert *pk ); -static int do_seckey_cert( IOBUF out, int ctb, PKT_seckey_cert *pk ); +static int do_public_cert( IOBUF out, int ctb, PKT_public_cert *pk ); +static int do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *pk ); static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ); static u32 calc_plaintext( PKT_plaintext *pt ); static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ); -static int do_encr_data( IOBUF out, int ctb, PKT_encr_data *ed ); +static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ); static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd ); static int do_signature( IOBUF out, int ctb, PKT_signature *sig ); @@ -74,11 +74,11 @@ build_packet( IOBUF out, PACKET *pkt ) case PKT_COMMENT: rc = do_comment( out, ctb, pkt->pkt.comment ); break; - case PKT_PUBKEY_CERT: - rc = do_pubkey_cert( out, ctb, pkt->pkt.pubkey_cert ); + case PKT_PUBLIC_CERT: + rc = do_public_cert( out, ctb, pkt->pkt.public_cert ); break; - case PKT_SECKEY_CERT: - rc = do_seckey_cert( out, ctb, pkt->pkt.seckey_cert ); + case PKT_SECRET_CERT: + rc = do_secret_cert( out, ctb, pkt->pkt.secret_cert ); break; case PKT_PUBKEY_ENC: rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc ); @@ -86,10 +86,10 @@ build_packet( IOBUF out, PACKET *pkt ) case PKT_PLAINTEXT: rc = do_plaintext( out, ctb, pkt->pkt.plaintext ); break; - case PKT_ENCR_DATA: - rc = do_encr_data( out, ctb, pkt->pkt.encr_data ); + case PKT_ENCRYPTED: + rc = do_encrypted( out, ctb, pkt->pkt.encrypted ); break; - case PKT_COMPR_DATA: + case PKT_COMPRESSED: rc = do_compressed( out, ctb, pkt->pkt.compressed ); break; case PKT_SIGNATURE: @@ -119,13 +119,13 @@ calc_packet_length( PACKET *pkt ) break; case PKT_USER_ID: case PKT_COMMENT: - case PKT_PUBKEY_CERT: - case PKT_SECKEY_CERT: + case PKT_PUBLIC_CERT: + case PKT_SECRET_CERT: case PKT_PUBKEY_ENC: - case PKT_ENCR_DATA: + case PKT_ENCRYPTED: case PKT_SIGNATURE: case PKT_RING_TRUST: - case PKT_COMPR_DATA: + case PKT_COMPRESSED: default: log_bug("invalid packet type in calc_packet_length()"); break; @@ -154,7 +154,7 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid ) } static int -do_pubkey_cert( IOBUF out, int ctb, PKT_pubkey_cert *pkc ) +do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc ) { int rc = 0; IOBUF a = iobuf_temp(); @@ -187,7 +187,7 @@ do_pubkey_cert( IOBUF out, int ctb, PKT_pubkey_cert *pkc ) } static int -do_seckey_cert( IOBUF out, int ctb, PKT_seckey_cert *skc ) +do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc ) { int rc = 0; IOBUF a = iobuf_temp(); @@ -329,7 +329,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) static int -do_encr_data( IOBUF out, int ctb, PKT_encr_data *ed ) +do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ) { int rc = 0; u32 n; diff --git a/g10/cipher.c b/g10/cipher.c index 562579a43..dedc52efe 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -47,21 +47,21 @@ cipher_filter( void *opaque, int control, cipher_filter_context_t *cfx = opaque; int rc=0; - if( control == IOBUFCTRL_UNDERFLOW ) { /* decipher */ + if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypted */ rc = -1; /* FIXME:*/ } - else if( control == IOBUFCTRL_FLUSH ) { /* encipher */ + else if( control == IOBUFCTRL_FLUSH ) { /* encrypted */ assert(a); if( !cfx->header ) { PACKET pkt; - PKT_encr_data ed; + PKT_encrypted ed; byte temp[10]; memset( &ed, 0, sizeof ed ); ed.len = cfx->datalen; init_packet( &pkt ); - pkt.pkttype = PKT_ENCR_DATA; - pkt.pkt.encr_data = &ed; + pkt.pkttype = PKT_ENCRYPTED; + pkt.pkt.encrypted = &ed; if( build_packet( a, &pkt )) log_bug("build_packet(ENCR_DATA) failed\n"); randomize_buffer( temp, 8, 1 ); diff --git a/g10/compress.c b/g10/compress.c index 38d23adf8..d0e2bc539 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -192,10 +192,10 @@ compress_filter( void *opaque, int control, cd.len = 0; cd.algorithm = 2; /* zlib */ init_packet( &pkt ); - pkt.pkttype = PKT_COMPR_DATA; + pkt.pkttype = PKT_COMPRESSED; pkt.pkt.compressed = &cd; if( build_packet( a, &pkt )) - log_bug("build_packet(COMPRESSED) failed\n"); + log_bug("build_packet(PKT_COMPRESSED) failed\n"); zs = zfx->opaque = m_alloc_clear( sizeof *zs ); init_compress( zfx, zs ); zfx->status = 2; diff --git a/g10/encode.c b/g10/encode.c index 75764fe1a..99c9adfa2 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -160,7 +160,7 @@ encode_crypt( const char *filename, STRLIST remusr ) IOBUF inp, out; PACKET pkt; PKT_plaintext *pt; - PKT_pubkey_cert *pkc = NULL; + PKT_public_cert *pkc = NULL; PKT_pubkey_enc *enc = NULL; int last_rc, rc = 0; u32 filesize; @@ -214,7 +214,7 @@ encode_crypt( const char *filename, STRLIST remusr ) /* loop over all user ids and build public key packets for each */ for(last_rc=0 ; remusr; remusr = remusr->next ) { if( pkc ) - free_pubkey_cert( pkc ); + free_public_cert( pkc ); pkc = m_alloc_clear( sizeof *pkc ); pkc->pubkey_algo = DEFAULT_PUBKEY_ALGO; @@ -239,7 +239,7 @@ encode_crypt( const char *filename, STRLIST remusr ) pkey.y = pkc->d.elg.y; if( DBG_CIPHER ) log_mpidump("Plain DEK frame: ", frame); - elg_encipher( enc->d.elg.a, enc->d.elg.b, frame, &pkey); + elg_encrypted( enc->d.elg.a, enc->d.elg.b, frame, &pkey); mpi_free( frame ); if( DBG_CIPHER ) { log_mpidump("Encry DEK a: ", enc->d.elg.a ); @@ -247,7 +247,7 @@ encode_crypt( const char *filename, STRLIST remusr ) } if( opt.verbose ) { ustr = get_user_id_string( enc->keyid ); - log_info("ElGamal enciphered for: %s\n", ustr ); + log_info("ElGamal encrypteded for: %s\n", ustr ); m_free(ustr); } } @@ -267,7 +267,7 @@ encode_crypt( const char *filename, STRLIST remusr ) log_mpidump("Encry DEK frame: ", enc->d.rsa.rsa_integer); if( opt.verbose ) { ustr = get_user_id_string( enc->keyid ); - log_info("RSA enciphered for: %s\n", ustr ); + log_info("RSA encrypteded for: %s\n", ustr ); m_free(ustr); } } @@ -293,7 +293,7 @@ encode_crypt( const char *filename, STRLIST remusr ) any_names = 1; } if( pkc ) { - free_pubkey_cert( pkc ); + free_public_cert( pkc ); pkc = NULL; } if( !any_names ) { diff --git a/g10/encr-data.c b/g10/encr-data.c index 5c047e90d..aed1890a6 100644 --- a/g10/encr-data.c +++ b/g10/encr-data.c @@ -43,7 +43,7 @@ typedef struct { * Decrypt the data, specified by ED with the key DEK. */ int -decrypt_data( PKT_encr_data *ed, DEK *dek ) +decrypt_data( PKT_encrypted *ed, DEK *dek ) { decode_filter_ctx_t dfx; byte *p; diff --git a/g10/filter.h b/g10/filter.h index acbb4ca25..ec34696a4 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -23,6 +23,7 @@ #include "cipher.h" typedef struct { + MD_HANDLE *md; /* catch all */ MD5HANDLE md5; /* if !NULL create md5 */ RMDHANDLE rmd160; /* if !NULL create rmd160 */ size_t maxbuf_size; diff --git a/g10/free-packet.c b/g10/free-packet.c index 3103ee49e..fa116ba62 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -57,7 +57,7 @@ free_seckey_enc( PKT_signature *enc ) } void -free_pubkey_cert( PKT_pubkey_cert *cert ) +free_public_cert( PKT_public_cert *cert ) { if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { mpi_free( cert->d.elg.p ); @@ -73,8 +73,8 @@ free_pubkey_cert( PKT_pubkey_cert *cert ) m_free(cert); } -PKT_pubkey_cert * -copy_pubkey_cert( PKT_pubkey_cert *d, PKT_pubkey_cert *s ) +PKT_public_cert * +copy_public_cert( PKT_public_cert *d, PKT_public_cert *s ) { if( !d ) d = m_alloc(sizeof *d); @@ -94,7 +94,7 @@ copy_pubkey_cert( PKT_pubkey_cert *d, PKT_pubkey_cert *s ) } void -free_seckey_cert( PKT_seckey_cert *cert ) +free_secret_cert( PKT_secret_cert *cert ) { if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { mpi_free( cert->d.elg.p ); @@ -124,8 +124,8 @@ free_seckey_cert( PKT_seckey_cert *cert ) m_free(cert); } -PKT_seckey_cert * -copy_seckey_cert( PKT_seckey_cert *d, PKT_seckey_cert *s ) +PKT_secret_cert * +copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s ) { if( !d ) d = m_alloc(sizeof *d); @@ -172,7 +172,7 @@ free_compressed( PKT_compressed *zd ) } void -free_encr_data( PKT_encr_data *ed ) +free_encrypted( PKT_encrypted *ed ) { if( ed->buf ) { /* have to skip some bytes */ if( iobuf_in_block_mode(ed->buf) ) { @@ -225,11 +225,11 @@ free_packet( PACKET *pkt ) case PKT_PUBKEY_ENC: free_pubkey_enc( pkt->pkt.pubkey_enc ); break; - case PKT_PUBKEY_CERT: - free_pubkey_cert( pkt->pkt.pubkey_cert ); + case PKT_PUBLIC_CERT: + free_public_cert( pkt->pkt.public_cert ); break; - case PKT_SECKEY_CERT: - free_seckey_cert( pkt->pkt.seckey_cert ); + case PKT_SECRET_CERT: + free_secret_cert( pkt->pkt.secret_cert ); break; case PKT_COMMENT: free_comment( pkt->pkt.comment ); @@ -237,11 +237,11 @@ free_packet( PACKET *pkt ) case PKT_USER_ID: free_user_id( pkt->pkt.user_id ); break; - case PKT_COMPR_DATA: + case PKT_COMPRESSED: free_compressed( pkt->pkt.compressed); break; - case PKT_ENCR_DATA: - free_encr_data( pkt->pkt.encr_data ); + case PKT_ENCRYPTED: + free_encrypted( pkt->pkt.encrypted ); break; case PKT_PLAINTEXT: free_plaintext( pkt->pkt.plaintext ); diff --git a/g10/g10.c b/g10/g10.c index f3be29575..a27bd19b6 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "packet.h" #include "iobuf.h" @@ -98,10 +99,10 @@ main( int argc, char **argv ) { 'a', "armor", 0, "create ascii armored output"}, { 'v', "verbose", 0, "verbose" }, { 'z', NULL, 1, "set compress level (0 disables)" }, - { 'b', "batch", 0, "batch mode: never ask" }, { 'n', "dry-run", 0, "don't make any changes" }, { 'c', "symmetric", 0, "do only a symmetric encryption" }, { 'o', "output", 2, "use as output file" }, + { 500, "batch", 0, "batch mode: never ask" }, { 501, "yes", 0, "assume yes on most questions"}, { 502, "no", 0, "assume no on most questions"}, { 503, "gen-key", 0, "generate a new key pair" }, @@ -112,6 +113,7 @@ main( int argc, char **argv ) { 508, "check-key" ,0, "check signatures on a key in the keyring" }, { 509, "keyring" ,2, "add this keyring to the list of keyrings" }, { 's', "sign", 0, "make a signature"}, + { 'b', "detach-sign", 0, "make a detached signature"}, { 'e', "encrypt", 0, "encrypt data" }, { 'd', "decrypt", 0, "decrypt data (default)" }, /*{ 'c', "check", 0, "check a signature (default)" }, */ @@ -143,13 +145,14 @@ main( int argc, char **argv ) opt.compress = pargs.r.ret_int; break; case 'a': opt.armor = 1; break; - case 'b': opt.batch = 1; break; case 'c': action = aSym; break; case 'o': opt.outfile = pargs.r.ret_str; if( opt.outfile[0] == '-' && !opt.outfile[1] ) opt.outfile_is_stdout = 1; break; case 'e': action = action == aSign? aSignEncr : aEncr; break; + case 'b': opt.detached_sig = 1; + /* fall trough */ case 's': action = action == aEncr? aSignEncr : aSign; break; case 'l': /* store the local users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); @@ -163,6 +166,7 @@ main( int argc, char **argv ) sl->next = remusr; remusr = sl; break; + case 500: opt.batch = 1; break; case 501: opt.answer_yes = 1; break; case 502: opt.answer_no = 1; break; case 503: action = aKeygen; break; @@ -180,11 +184,12 @@ main( int argc, char **argv ) set_debug(); if( opt.verbose > 1 ) set_packet_list_mode(1); - if( !opt.batch && *(s=strusage(10)) ) - fputs(s, stderr); - if( !opt.batch && *(s=strusage(30)) ) - fputs(s, stderr); - + if( !opt.batch && isatty(fileno(stdin)) ) { + if( *(s=strusage(10)) ) + fputs(s, stderr); + if( *(s=strusage(30)) ) + fputs(s, stderr); + } if( !nrings ) { /* add default rings */ add_keyring("../keys/ring.pgp"); diff --git a/g10/getkey.c b/g10/getkey.c index 4aea8e7ca..c978cb9fd 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -48,7 +48,7 @@ typedef struct user_id_db { typedef struct pkc_cache_entry { struct pkc_cache_entry *next; u32 keyid[2]; - PKT_pubkey_cert *pkc; + PKT_public_cert *pkc; } *pkc_cache_entry_t; static STRLIST keyrings; @@ -59,9 +59,9 @@ static pkc_cache_entry_t pkc_cache; static int pkc_cache_entries; /* number of entries in pkc cache */ -static int scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, +static int scan_keyring( PKT_public_cert *pkc, u32 *keyid, const char *name, const char *filename ); -static int scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid, +static int scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid, const char *name, const char *filename); @@ -80,7 +80,7 @@ add_keyring( const char *name ) void -cache_pubkey_cert( PKT_pubkey_cert *pkc ) +cache_public_cert( PKT_public_cert *pkc ) { pkc_cache_entry_t ce; u32 keyid[2]; @@ -95,7 +95,7 @@ cache_pubkey_cert( PKT_pubkey_cert *pkc ) for( ce = pkc_cache; ce; ce = ce->next ) if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) { if( DBG_CACHE ) - log_debug("cache_pubkey_cert: already in cache\n"); + log_debug("cache_public_cert: already in cache\n"); return; } @@ -106,7 +106,7 @@ cache_pubkey_cert( PKT_pubkey_cert *pkc ) log_info("too many entries in pkc cache - disabled\n"); } ce = pkc_cache; - free_pubkey_cert( ce->pkc ); + free_public_cert( ce->pkc ); } else { pkc_cache_entries++; @@ -114,7 +114,7 @@ cache_pubkey_cert( PKT_pubkey_cert *pkc ) ce->next = pkc_cache; pkc_cache = ce; } - ce->pkc = copy_pubkey_cert( NULL, pkc ); + ce->pkc = copy_public_cert( NULL, pkc ); ce->keyid[0] = keyid[0]; ce->keyid[1] = keyid[1]; } @@ -152,7 +152,7 @@ cache_user_id( PKT_user_id *uid, u32 *keyid ) * internal structures. */ int -get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid ) +get_pubkey( PKT_public_cert *pkc, u32 *keyid ) { keyid_list_t kl; int internal = 0; @@ -179,7 +179,7 @@ get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid ) for( ce = pkc_cache; ce; ce = ce->next ) if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) { if( pkc ) - copy_pubkey_cert( pkc, ce->pkc ); + copy_public_cert( pkc, ce->pkc ); return 0; } @@ -207,7 +207,7 @@ get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid ) leave: if( !rc ) - cache_pubkey_cert( pkc ); + cache_public_cert( pkc ); if( internal ) m_free(pkc); return rc; @@ -221,7 +221,7 @@ get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid ) * a pubkey with that algo. */ int -get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name ) +get_pubkey_by_name( PKT_public_cert *pkc, const char *name ) { int internal = 0; int rc = 0; @@ -253,7 +253,7 @@ get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name ) * Get a secret key and store it into skey */ int -get_seckey( PKT_seckey_cert *skc, u32 *keyid ) +get_seckey( PKT_secret_cert *skc, u32 *keyid ) { int rc=0; @@ -277,7 +277,7 @@ get_seckey( PKT_seckey_cert *skc, u32 *keyid ) * Get a secret key by name and store it into skc */ int -get_seckey_by_name( PKT_seckey_cert *skc, const char *name ) +get_seckey_by_name( PKT_secret_cert *skc, const char *name ) { int rc=0; @@ -302,7 +302,7 @@ get_seckey_by_name( PKT_seckey_cert *skc, const char *name ) * scan the keyring and look for either the keyid or the name. */ static int -scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, +scan_keyring( PKT_public_cert *pkc, u32 *keyid, const char *name, const char *filename ) { int rc=0; @@ -311,7 +311,7 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, PACKET pkt; int save_mode; u32 akeyid[2]; - PKT_pubkey_cert *last_pk = NULL; + PKT_public_cert *last_pk = NULL; assert( !keyid || !name ); @@ -338,34 +338,34 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, while( (rc=parse_packet(a, &pkt)) != -1 ) { if( rc ) ; /* e.g. unknown packet */ - else if( keyid && found && pkt.pkttype == PKT_PUBKEY_CERT ) { + else if( keyid && found && pkt.pkttype == PKT_PUBLIC_CERT ) { log_error("Hmmm, pubkey without an user id in '%s'\n", filename); goto leave; } - else if( keyid && pkt.pkttype == PKT_PUBKEY_CERT ) { - switch( pkt.pkt.pubkey_cert->pubkey_algo ) { + else if( keyid && pkt.pkttype == PKT_PUBLIC_CERT ) { + switch( pkt.pkt.public_cert->pubkey_algo ) { case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_RSA: - keyid_from_pkc( pkt.pkt.pubkey_cert, akeyid ); + keyid_from_pkc( pkt.pkt.public_cert, akeyid ); if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) { - copy_pubkey_cert( pkc, pkt.pkt.pubkey_cert ); + copy_public_cert( pkc, pkt.pkt.public_cert ); found++; } break; default: log_error("cannot handle pubkey algo %d\n", - pkt.pkt.pubkey_cert->pubkey_algo); + pkt.pkt.public_cert->pubkey_algo); } } else if( keyid && found && pkt.pkttype == PKT_USER_ID ) { cache_user_id( pkt.pkt.user_id, keyid ); goto leave; } - else if( name && pkt.pkttype == PKT_PUBKEY_CERT ) { + else if( name && pkt.pkttype == PKT_PUBLIC_CERT ) { if( last_pk ) - free_pubkey_cert(last_pk); - last_pk = pkt.pkt.pubkey_cert; - pkt.pkt.pubkey_cert = NULL; + free_public_cert(last_pk); + last_pk = pkt.pkt.public_cert; + pkt.pkt.public_cert = NULL; } else if( name && pkt.pkttype == PKT_USER_ID ) { if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) { @@ -378,16 +378,16 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, pkt.pkt.user_id->len, pkt.pkt.user_id->name, pkc->pubkey_algo, last_pk->pubkey_algo ); else { - copy_pubkey_cert( pkc, last_pk ); + copy_public_cert( pkc, last_pk ); goto leave; } } } - else if( !keyid && !name && pkt.pkttype == PKT_PUBKEY_CERT ) { + else if( !keyid && !name && pkt.pkttype == PKT_PUBLIC_CERT ) { if( last_pk ) - free_pubkey_cert(last_pk); - last_pk = pkt.pkt.pubkey_cert; - pkt.pkt.pubkey_cert = NULL; + free_public_cert(last_pk); + last_pk = pkt.pkt.public_cert; + pkt.pkt.public_cert = NULL; } else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) { if( !last_pk ) @@ -399,7 +399,7 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, keyid_from_pkc( last_pk, akeyid ); cache_user_id( pkt.pkt.user_id, akeyid ); } - cache_pubkey_cert( last_pk ); + cache_public_cert( last_pk ); } } free_packet(&pkt); @@ -408,7 +408,7 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, leave: if( last_pk ) - free_pubkey_cert(last_pk); + free_public_cert(last_pk); free_packet(&pkt); iobuf_close(a); set_packet_list_mode(save_mode); @@ -422,7 +422,7 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid, * PKT returns the secret key certificate. */ static int -scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid, +scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid, const char *name, const char *filename ) { int rc=0; @@ -431,7 +431,7 @@ scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid, PACKET pkt; int save_mode; u32 akeyid[2]; - PKT_seckey_cert *last_pk = NULL; + PKT_secret_cert *last_pk = NULL; assert( !keyid || !name ); @@ -445,33 +445,33 @@ scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid, while( (rc=parse_packet(a, &pkt)) != -1 ) { if( rc ) ; /* e.g. unknown packet */ - else if( keyid && found && pkt.pkttype == PKT_SECKEY_CERT ) { + else if( keyid && found && pkt.pkttype == PKT_SECRET_CERT ) { log_error("Hmmm, seckey without an user id in '%s'\n", filename); goto leave; } - else if( keyid && pkt.pkttype == PKT_SECKEY_CERT ) { - switch( pkt.pkt.seckey_cert->pubkey_algo ) { + else if( keyid && pkt.pkttype == PKT_SECRET_CERT ) { + switch( pkt.pkt.secret_cert->pubkey_algo ) { case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_RSA: - keyid_from_skc( pkt.pkt.seckey_cert, akeyid ); + keyid_from_skc( pkt.pkt.secret_cert, akeyid ); if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) { - copy_seckey_cert( skc, pkt.pkt.seckey_cert ); + copy_secret_cert( skc, pkt.pkt.secret_cert ); found++; } break; default: log_error("cannot handle pubkey algo %d\n", - pkt.pkt.seckey_cert->pubkey_algo); + pkt.pkt.secret_cert->pubkey_algo); } } else if( keyid && found && pkt.pkttype == PKT_USER_ID ) { goto leave; } - else if( name && pkt.pkttype == PKT_SECKEY_CERT ) { + else if( name && pkt.pkttype == PKT_SECRET_CERT ) { if( last_pk ) - free_seckey_cert(last_pk); - last_pk = pkt.pkt.seckey_cert; - pkt.pkt.seckey_cert = NULL; + free_secret_cert(last_pk); + last_pk = pkt.pkt.secret_cert; + pkt.pkt.secret_cert = NULL; } else if( name && pkt.pkttype == PKT_USER_ID ) { if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) { @@ -484,16 +484,16 @@ scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid, pkt.pkt.user_id->len, pkt.pkt.user_id->name, skc->pubkey_algo, last_pk->pubkey_algo ); else { - copy_seckey_cert( skc, last_pk ); + copy_secret_cert( skc, last_pk ); goto leave; } } } - else if( !keyid && !name && pkt.pkttype == PKT_SECKEY_CERT ) { + else if( !keyid && !name && pkt.pkttype == PKT_SECRET_CERT ) { if( last_pk ) - free_seckey_cert(last_pk); - last_pk = pkt.pkt.seckey_cert; - pkt.pkt.seckey_cert = NULL; + free_secret_cert(last_pk); + last_pk = pkt.pkt.secret_cert; + pkt.pkt.secret_cert = NULL; } else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) { if( !last_pk ) @@ -513,7 +513,7 @@ scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid, leave: if( last_pk ) - free_seckey_cert(last_pk); + free_secret_cert(last_pk); free_packet(&pkt); iobuf_close(a); set_packet_list_mode(save_mode); @@ -545,4 +545,26 @@ get_user_id_string( u32 *keyid ) return p; } +char* +get_user_id( u32 *keyid, size_t *rn ) +{ + user_id_db_t r; + char *p; + int pass=0; + /* try it two times; second pass reads from keyrings */ + do { + for(r=user_id_db; r; r = r->next ) + if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) { + p = m_alloc( r->len ); + memcpy(p, r->name, r->len ); + *rn = r->len; + return p; + } + } while( ++pass < 2 && !get_pubkey( NULL, keyid ) ); + p = m_alloc( 19 ); + memcpy(p, "[User id not found]", 19 ); + *rn = 19; + return p; +} + diff --git a/g10/keydb.h b/g10/keydb.h index ae3aeb83f..21423cfbb 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -32,17 +32,24 @@ int make_dek_from_passphrase( DEK *dek, int mode ); /*-- getkey.c --*/ void add_keyring( const char *name ); -void cache_pubkey_cert( PKT_pubkey_cert *pkc ); +void cache_public_cert( PKT_public_cert *pkc ); void cache_user_id( PKT_user_id *uid, u32 *keyid ); -int get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid ); -int get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name ); -int get_seckey( PKT_seckey_cert *skc, u32 *keyid ); -int get_seckey_by_name( PKT_seckey_cert *skc, const char *name ); +int get_pubkey( PKT_public_cert *pkc, u32 *keyid ); +int get_pubkey_by_name( PKT_public_cert *pkc, const char *name ); +int get_seckey( PKT_secret_cert *skc, u32 *keyid ); +int get_seckey_by_name( PKT_secret_cert *skc, const char *name ); char*get_user_id_string( u32 *keyid ); +char*get_user_id( u32 *keyid, size_t *rn ); /*-- keyid.c --*/ -u32 keyid_from_skc( PKT_seckey_cert *skc, u32 *keyid ); -u32 keyid_from_pkc( PKT_pubkey_cert *pkc, u32 *keyid ); +u32 keyid_from_skc( PKT_secret_cert *skc, u32 *keyid ); +u32 keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid ); +u32 keyid_from_sig( PKT_signature *sig, u32 *keyid ); +unsigned nbits_from_pkc( PKT_public_cert *pkc ); +unsigned nbits_from_skc( PKT_secret_cert *skc ); +const char *datestr_from_pkc( PKT_public_cert *pkc ); +const char *datestr_from_skc( PKT_secret_cert *skc ); +const char *datestr_from_sig( PKT_signature *sig ); diff --git a/g10/keygen.c b/g10/keygen.c index ff3715999..3cbbf89e1 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -75,8 +75,8 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io) { int rc; PACKET pkt1, pkt2; - PKT_seckey_cert *skc; - PKT_pubkey_cert *pkc; + PKT_secret_cert *skc; + PKT_public_cert *pkc; RSA_public_key pk; RSA_secret_key sk; @@ -102,18 +102,18 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io) /*memcpy(skc->d.rsa.protect.blowfish.iv,"12345678", 8);*/ init_packet(&pkt1); - pkt1.pkttype = PKT_PUBKEY_CERT; - pkt1.pkt.pubkey_cert = pkc; + pkt1.pkttype = PKT_PUBLIC_CERT; + pkt1.pkt.public_cert = pkc; init_packet(&pkt2); - pkt2.pkttype = PKT_SECKEY_CERT; - pkt2.pkt.seckey_cert = skc; + pkt2.pkttype = PKT_SECRET_CERT; + pkt2.pkt.secret_cert = skc; if( (rc = build_packet( pub_io, &pkt1 )) ) { - log_error("build pubkey_cert packet failed: %s\n", g10_errstr(rc) ); + log_error("build public_cert packet failed: %s\n", g10_errstr(rc) ); goto leave; } if( (rc = build_packet( sec_io, &pkt2 )) ) { - log_error("build seckey_cert packet failed: %s\n", g10_errstr(rc) ); + log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) ); goto leave; } @@ -129,8 +129,8 @@ gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io) { int rc; PACKET pkt1, pkt2; - PKT_seckey_cert *skc; - PKT_pubkey_cert *pkc; + PKT_secret_cert *skc; + PKT_public_cert *pkc; ELG_public_key pk; ELG_secret_key sk; @@ -156,18 +156,18 @@ gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io) /*memcpy(skc->d.elg.protect.blowfish.iv,"12345678", 8);*/ init_packet(&pkt1); - pkt1.pkttype = PKT_PUBKEY_CERT; - pkt1.pkt.pubkey_cert = pkc; + pkt1.pkttype = PKT_PUBLIC_CERT; + pkt1.pkt.public_cert = pkc; init_packet(&pkt2); - pkt2.pkttype = PKT_SECKEY_CERT; - pkt2.pkt.seckey_cert = skc; + pkt2.pkttype = PKT_SECRET_CERT; + pkt2.pkt.secret_cert = skc; if( (rc = build_packet( pub_io, &pkt1 )) ) { - log_error("build pubkey_cert packet failed: %s\n", g10_errstr(rc) ); + log_error("build public_cert packet failed: %s\n", g10_errstr(rc) ); goto leave; } if( (rc = build_packet( sec_io, &pkt2 )) ) { - log_error("build seckey_cert packet failed: %s\n", g10_errstr(rc) ); + log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) ); goto leave; } diff --git a/g10/keyid.c b/g10/keyid.c index 0e2dad93b..7453754a2 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "util.h" #include "main.h" @@ -39,7 +40,7 @@ * if this is not NULL. Return the 32 low bits of the keyid. */ u32 -keyid_from_skc( PKT_seckey_cert *skc, u32 *keyid ) +keyid_from_skc( PKT_secret_cert *skc, u32 *keyid ) { u32 lowbits; u32 dummy_keyid[2]; @@ -53,9 +54,9 @@ keyid_from_skc( PKT_seckey_cert *skc, u32 *keyid ) else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid ); } - else - log_bug(NULL); - + else { + keyid[0] = keyid[1] = lowbits = 0; + } return lowbits; } @@ -65,7 +66,7 @@ keyid_from_skc( PKT_seckey_cert *skc, u32 *keyid ) * if this is not NULL. Return the 32 low bits of the keyid. */ u32 -keyid_from_pkc( PKT_pubkey_cert *pkc, u32 *keyid ) +keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid ) { u32 lowbits; u32 dummy_keyid[2]; @@ -79,10 +80,94 @@ keyid_from_pkc( PKT_pubkey_cert *pkc, u32 *keyid ) else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid ); } - else - log_bug(NULL); + else { + keyid[0] = keyid[1] = lowbits = 0; + } return lowbits; } +u32 +keyid_from_sig( PKT_signature *sig, u32 *keyid ) +{ + if( keyid ) { + keyid[0] = sig->keyid[0]; + keyid[1] = sig->keyid[1]; + } + return sig->keyid[1]; +} + +/**************** + * return the number of bits used in the pkc + */ +unsigned +nbits_from_pkc( PKT_public_cert *pkc ) +{ + if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { + return mpi_get_nbits( pkc->d.elg.p ); + } + else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { + return mpi_get_nbits( pkc->d.rsa.rsa_n ); + } + else + return 0; +} + +/**************** + * return the number of bits used in the skc + */ +unsigned +nbits_from_skc( PKT_secret_cert *skc ) +{ + if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { + return mpi_get_nbits( skc->d.elg.p ); + } + else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { + return mpi_get_nbits( skc->d.rsa.rsa_n ); + } + else + return 0; +} + +/**************** + * return a string with the creation date of the pkc + * Note: this is alloced in a static buffer. + * Format is: yyyy-mm-dd + */ +const char * +datestr_from_pkc( PKT_public_cert *pkc ) +{ + static char buffer[11+5]; + struct tm *tp; + time_t atime = pkc->timestamp; + + tp = gmtime( &atime ); + sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday ); + return buffer; +} + +const char * +datestr_from_skc( PKT_secret_cert *skc ) +{ + static char buffer[11+5]; + struct tm *tp; + time_t atime = skc->timestamp; + + tp = gmtime( &atime ); + sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday ); + return buffer; +} + +const char * +datestr_from_sig( PKT_signature *sig ) +{ + static char buffer[11+5]; + struct tm *tp; + time_t atime = sig->timestamp; + + tp = gmtime( &atime ); + sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday ); + return buffer; +} + diff --git a/g10/main.h b/g10/main.h index 708563427..8be922b8a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -47,6 +47,7 @@ void make_session_key( DEK *dek ); MPI encode_session_key( DEK *dek, unsigned nbits ); MPI encode_rmd160_value( byte *md, unsigned len, unsigned nbits ); MPI encode_md5_value( byte *md, unsigned len, unsigned nbits ); +MPI encode_md_value( MD_HANDLE *md, unsigned nbits ); #endif /*G10_MAIN_H*/ diff --git a/g10/mainproc.c b/g10/mainproc.c index 9e34fbd0e..fd814cc80 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "packet.h" #include "iobuf.h" @@ -30,218 +31,206 @@ #include "cipher.h" #include "keydb.h" #include "filter.h" +#include "cipher.h" #include "main.h" +/**************** + * We need to glue the packets together. This done by a + * tree of packets, which will released whenever a new start packet + * is encounterd. Start packets are: [FIXME] + * + * pubkey + * userid userid + * sig, sig, sig sig, sig + * + */ + +typedef struct node_struct *NODE; +struct node_struct { + PACKET *pkt; + NODE next; /* used to form a link list */ + NODE child; +}; + + +/**************** + * Structure to hold the context + */ + typedef struct { - PKT_pubkey_cert *last_pubkey; - PKT_seckey_cert *last_seckey; + PKT_public_cert *last_pubkey; + PKT_secret_cert *last_seckey; PKT_user_id *last_user_id; md_filter_context_t mfx; DEK *dek; int last_was_pubkey_enc; + int opt_list; + NODE cert; /* the current certificate */ } *CTX; -static int opt_list=1; /* and list the data packets to stdout */ -#if 1 -static void -do_free_last_user_id( CTX c ) + + +static void list_node( CTX c, NODE node ); + +static int +pubkey_letter( int algo ) { - if( c->last_user_id ) { - free_user_id( c->last_user_id ); - c->last_user_id = NULL; - } -} -static void -do_free_last_pubkey( CTX c ) -{ - if( c->last_pubkey ) { - free_pubkey_cert( c->last_pubkey ); - c->last_pubkey = NULL; - } -} -static void -do_free_last_seckey( CTX c ) -{ - if( c->last_seckey ) { - free_seckey_cert( c->last_seckey ); - c->last_seckey = NULL; + switch( algo ) { + case PUBKEY_ALGO_RSA: return 'R' ; + case PUBKEY_ALGO_RSA_E: return 'r' ; + case PUBKEY_ALGO_RSA_S: return 's' ; + case PUBKEY_ALGO_ELGAMAL: return 'G' ; + case PUBKEY_ALGO_DSA: return 'D' ; + default: return '?'; } } + + +static NODE +new_node( PACKET *pkt ) +{ + NODE n = m_alloc( sizeof *n ); + n->next = NULL; + n->pkt = pkt; + n->child = NULL; + return n; +} + + static void -proc_pubkey_cert( CTX c, PACKET *pkt ) +release_node( NODE n ) +{ + NODE n2; + + while( n ) { + n2 = n->next; + release_node( n->child ); + free_packet( n->pkt ); + m_free( n ); + n = n2; + } +} + + +/**************** + * Return the parent node of NODE from the tree with ROOT + */ +static NODE +find_parent( NODE root, NODE node ) +{ + NODE n, n2; + + for( ; root; root = root->child) { + for( n = root; n; n = n->next) { + for( n2 = n->child; n2; n2 = n2->next ) { + if( n2 == node ) + return n; + } + } + } + log_bug(NULL); +} + + +static void +release_cert( CTX c ) +{ + if( !c->cert ) + return; + list_node(c, c->cert ); + release_node( c->cert ); + c->cert = NULL; +} + + + +static int +add_public_cert( CTX c, PACKET *pkt ) +{ + release_cert( c ); + c->cert = new_node( pkt ); + return 1; +} + +static int +add_secret_cert( CTX c, PACKET *pkt ) +{ + release_cert( c ); + c->cert = new_node( pkt ); + return 1; +} + + +static int +add_user_id( CTX c, PACKET *pkt ) { u32 keyid[2]; - char *ustr; - int lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */ + NODE node, n1, n2; - do_free_last_user_id( c ); - do_free_last_seckey( c ); - if( opt.check_sigs ) { - keyid_from_pkc( pkt->pkt.pubkey_cert, keyid ); - ustr = get_user_id_string(keyid); - printstr(lvl0, "pub: %s\n", ustr ); - m_free(ustr); + if( !c->cert ) { + log_error("orphaned user id\n" ); + return 0; } - else - fputs( "pub: [Public Key Cerificate]\n", stdout ); - c->last_pubkey = pkt->pkt.pubkey_cert; - pkt->pkt.pubkey_cert = NULL; - free_packet(pkt); - pkt->pkc_parent = c->last_pubkey; /* set this as parent */ + /* goto the last certificate (currently ther is only one) */ + for(n1=c->cert; n1->next; n1 = n1->next ) + ; + assert( n1->pkt ); + if( n1->pkt->pkttype != PKT_PUBLIC_CERT + && n1->pkt->pkttype != PKT_SECRET_CERT ) { + log_error("invalid parent type %d for userid\n", n1->pkt->pkttype ); + return 0; + } + /* add a new user id node at the end */ + node = new_node( pkt ); + if( !(n2=n1->child) ) + n1->child = node; + else { + for( ; n2->next; n2 = n2->next) + ; + n2->next = node; + } + return 1; } -static void -proc_seckey_cert( CTX c, PACKET *pkt ) -{ - int rc; - - do_free_last_user_id( c ); - do_free_last_pubkey( c ); - if( opt_list ) - fputs( "sec: (secret key certificate)\n", stdout ); - rc = check_secret_key( pkt->pkt.seckey_cert ); - if( opt_list ) { - if( !rc ) - fputs( " Secret key is good", stdout ); - else - fputs( g10_errstr(rc), stdout); - putchar('\n'); - } - else if( rc ) - log_error("secret key certificate error: %s\n", g10_errstr(rc)); - c->last_seckey = pkt->pkt.seckey_cert; - pkt->pkt.seckey_cert = NULL; - free_packet(pkt); - pkt->skc_parent = c->last_seckey; /* set this as parent */ -} - - -static void -proc_user_id( CTX c, PACKET *pkt ) +static int +add_signature( CTX c, PACKET *pkt ) { u32 keyid[2]; + NODE node, n1, n2; - do_free_last_user_id( c ); - if( opt_list ) { - printf("uid: '%.*s'\n", pkt->pkt.user_id->len, - pkt->pkt.user_id->name ); - if( !pkt->pkc_parent && !pkt->skc_parent ) - puts(" (orphaned)"); + if( !c->cert ) { + log_error("orphaned signature (no certificate)\n" ); + return 0; } - if( pkt->pkc_parent ) { - if( pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_ELGAMAL - || pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_RSA ) { - keyid_from_pkc( pkt->pkc_parent, keyid ); - cache_user_id( pkt->pkt.user_id, keyid ); - } + assert( c->cert->pkt ); + if( !c->cert->child ) { + log_error("orphaned signature (no userid)\n" ); + return 0; } - - c->last_user_id = pkt->pkt.user_id; /* save */ - pkt->pkt.user_id = NULL; - free_packet(pkt); - pkt->user_parent = c->last_user_id; /* and set this as user */ -} - - -static void -proc_signature( CTX c, PACKET *pkt ) -{ - PKT_signature *sig; - MD_HANDLE md_handle; /* union to pass handles down */ - char *ustr; - int result = -1; - int lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */ - int lvl1 = opt.check_sigs? 1:3; /* stdout or error */ - - sig = pkt->pkt.signature; - ustr = get_user_id_string(sig->keyid); - if( sig->sig_class == 0x00 ) { - if( c->mfx.rmd160 ) - result = 0; - else - printstr(lvl1,"sig?: %s: no plaintext for signature\n", ustr); - } - else if( sig->sig_class != 0x10 ) - printstr(lvl1,"sig?: %s: unknown signature class %02x\n", - ustr, sig->sig_class); - else if( !pkt->pkc_parent || !pkt->user_parent ) - printstr(lvl1,"sig?: %s: orphaned encoded packet\n", ustr); - else - result = 0; - - if( result ) + /* goto the last user id */ + for(n1=c->cert->child; n1->next; n1 = n1->next ) ; - else if( !opt.check_sigs && sig->sig_class != 0x00 ) { - result = -1; - printstr(lvl0, "sig: from %s\n", ustr ); + assert( n1->pkt ); + if( n1->pkt->pkttype != PKT_USER_ID ) { + log_error("invalid parent type %d for sig\n", n1->pkt->pkttype); + return 0; } - else if(sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { - md_handle.algo = sig->d.elg.digest_algo; - if( sig->d.elg.digest_algo == DIGEST_ALGO_RMD160 ) { - if( sig->sig_class == 0x00 ) - md_handle.u.rmd = rmd160_copy( c->mfx.rmd160 ); - else { - md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160); - rmd160_write(md_handle.u.rmd, pkt->user_parent->name, - pkt->user_parent->len); - } - result = signature_check( sig, md_handle ); - rmd160_close(md_handle.u.rmd); - } - else if( sig->d.elg.digest_algo == DIGEST_ALGO_MD5 - && sig->sig_class != 0x00 ) { - md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5); - md5_write(md_handle.u.md5, pkt->user_parent->name, - pkt->user_parent->len); - result = signature_check( sig, md_handle ); - md5_close(md_handle.u.md5); - } - else - result = G10ERR_DIGEST_ALGO; + /* and add a new signature node id at the end */ + node = new_node( pkt ); + if( !(n2=n1->child) ) + n1->child = node; + else { + for( ; n2->next; n2 = n2->next) + ; + n2->next = node; } - else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) { - md_handle.algo = sig->d.rsa.digest_algo; - if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) { - if( sig->sig_class == 0x00 ) - md_handle.u.rmd = rmd160_copy( c->mfx.rmd160 ); - else { - md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160); - rmd160_write(md_handle.u.rmd, pkt->user_parent->name, - pkt->user_parent->len); - } - result = signature_check( sig, md_handle ); - rmd160_close(md_handle.u.rmd); - } - else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5 - && sig->sig_class != 0x00 ) { - md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5); - md5_write(md_handle.u.md5, pkt->user_parent->name, - pkt->user_parent->len); - result = signature_check( sig, md_handle ); - md5_close(md_handle.u.md5); - } - else - result = G10ERR_DIGEST_ALGO; - } - else - result = G10ERR_PUBKEY_ALGO; - - if( result == -1 ) - ; - else if( !result && sig->sig_class == 0x00 ) - printstr(1, "sig: good signature from %s\n", ustr ); - else if( !result ) - printstr(lvl0, "sig: good signature from %s\n", ustr ); - else - printstr(lvl1, "sig? %s: %s\n", ustr, g10_errstr(result)); - free_packet(pkt); - m_free(ustr); + return 1; } @@ -279,7 +268,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) static void -proc_encr_data( CTX c, PACKET *pkt ) +proc_encrypted( CTX c, PACKET *pkt ) { int result = 0; @@ -293,7 +282,7 @@ proc_encr_data( CTX c, PACKET *pkt ) else if( !c->dek ) result = G10ERR_NO_SECKEY; if( !result ) - result = decrypt_data( pkt->pkt.encr_data, c->dek ); + result = decrypt_data( pkt->pkt.encrypted, c->dek ); m_free(c->dek); c->dek = NULL; if( result == -1 ) ; @@ -315,7 +304,7 @@ proc_plaintext( CTX c, PACKET *pkt ) printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name); free_md_filter_context( &c->mfx ); - c->mfx.rmd160 = rmd160_open(0); + c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0); result = handle_plaintext( pt, &c->mfx ); if( !result ) fputs( " okay", stdout); @@ -328,7 +317,7 @@ proc_plaintext( CTX c, PACKET *pkt ) static void -proc_compr_data( CTX c, PACKET *pkt ) +proc_compressed( CTX c, PACKET *pkt ) { PKT_compressed *zd = pkt->pkt.compressed; int result; @@ -346,6 +335,168 @@ proc_compr_data( CTX c, PACKET *pkt ) + +/**************** + * check the signature + * Returns: 0 = valid signature or an error code + */ +static int +do_check_sig( CTX c, NODE node ) +{ + PKT_signature *sig; + MD_HANDLE *md; + int algo, rc; + + assert( node->pkt->pkttype == PKT_SIGNATURE ); + sig = node->pkt->pkt.signature; + + if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) + algo = sig->d.elg.digest_algo; + else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) + algo = sig->d.rsa.digest_algo; + else + return G10ERR_PUBKEY_ALGO; + if( (rc=md_okay(algo)) ) + return rc; + + if( sig->sig_class == 0x00 ) + md = md_copy( c->mfx.md ); + else if( (sig->sig_class&~3) == 0x10 ) { /* classes 0x10 .. 0x13 */ + if( c->cert->pkt->pkttype == PKT_PUBLIC_CERT ) { + NODE n1 = find_parent( c->cert, node ); + + if( n1 && n1->pkt->pkttype == PKT_USER_ID ) { + + if( c->cert->pkt->pkt.public_cert->mfx.md ) + md = md_copy( c->cert->pkt->pkt.public_cert->mfx.md ); + else if( algo == DIGEST_ALGO_RMD160 ) + md = rmd160_copy2md( c->cert->pkt->pkt.public_cert->mfx.rmd160 ); + else if( algo == DIGEST_ALGO_MD5 ) + md = md5_copy2md( c->cert->pkt->pkt.public_cert->mfx.md5 ); + else + log_bug(NULL); + md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len); + } + else { + log_error("invalid parent packet for sigclass 0x10\n"); + return G10ERR_SIG_CLASS; + } + } + else { + log_error("invalid root packet for sigclass 0x10\n"); + return G10ERR_SIG_CLASS; + } + } + else + return G10ERR_SIG_CLASS; + rc = signature_check( sig, md ); + md_close(md); + + return rc; +} + + + +static void +print_userid( PACKET *pkt ) +{ + if( !pkt ) + log_bug(NULL); + if( pkt->pkttype != PKT_USER_ID ) { + printf("ERROR: unexpected packet type %d", pkt->pkttype ); + return; + } + print_string( stdout, pkt->pkt.user_id->name, pkt->pkt.user_id->len ); +} + + +/**************** + * List the certificate in a user friendly way + */ + +static void +list_node( CTX c, NODE node ) +{ + register NODE n2; + + if( !node ) + ; + else if( node->pkt->pkttype == PKT_PUBLIC_CERT ) { + PKT_public_cert *pkc = node->pkt->pkt.public_cert; + + printf("pub %4u%c/%08lX %s ", nbits_from_pkc( pkc ), + pubkey_letter( pkc->pubkey_algo ), + (ulong)keyid_from_pkc( pkc, NULL ), + datestr_from_pkc( pkc ) ); + n2 = node->child; + if( !n2 ) + printf("ERROR: no user id!\n"); + else { + /* and now list all userids with their signatures */ + for( ; n2; n2 = n2->next ) { + if( n2 != node->child ) + printf( "%*s", 31, "" ); + print_userid( n2->pkt ); + putchar('\n'); + list_node(c, n2 ); + } + } + } + else if( node->pkt->pkttype == PKT_SECRET_CERT ) { + PKT_secret_cert *skc = node->pkt->pkt.secret_cert; + + printf("sec %4u%c/%08lX %s ", nbits_from_skc( skc ), + pubkey_letter( skc->pubkey_algo ), + (ulong)keyid_from_skc( skc, NULL ), + datestr_from_skc( skc ) ); + n2 = node->child; + if( !n2 ) + printf("ERROR: no user id!"); + else { + print_userid( n2->pkt ); + } + putchar('\n'); + } + else if( node->pkt->pkttype == PKT_USER_ID ) { + /* list everything under this user id */ + for(n2=node->child; n2; n2 = n2->next ) + list_node(c, n2 ); + } + else if( node->pkt->pkttype == PKT_SIGNATURE ) { + PKT_signature *sig = node->pkt->pkt.signature; + int rc2; + size_t n; + char *p; + int sigrc = ' '; + + assert( !node->child ); + if( opt.check_sigs ) { + + switch( (rc2=do_check_sig( c, node )) ) { + case 0: sigrc = '!'; break; + case G10ERR_BAD_SIGN: sigrc = '-'; break; + case G10ERR_NO_PUBKEY: sigrc = '?'; break; + default: sigrc = '%'; break; + } + } + printf("sig%c %08lX %s ", + sigrc, sig->keyid[1], datestr_from_sig(sig)); + if( sigrc == '%' ) + printf("[%s] ", g10_errstr(rc2) ); + else if( sigrc == '?' ) + ; + else { + p = get_user_id( sig->keyid, &n ); + print_string( stdout, p, n ); + m_free(p); + } + putchar('\n'); + } + else + log_error("invalid node with packet of type %d\n", node->pkt->pkttype); +} + + int proc_packets( IOBUF a ) { @@ -355,11 +506,13 @@ proc_packets( IOBUF a ) char *ustr; int lvl0, lvl1; u32 keyid[2]; + int newpkt; + c->opt_list = 1; init_packet(pkt); while( (rc=parse_packet(a, pkt)) != -1 ) { /* cleanup if we have an illegal data structure */ - if( c->dek && pkt->pkttype != PKT_ENCR_DATA ) { + if( c->dek && pkt->pkttype != PKT_ENCRYPTED ) { log_error("oops: valid pubkey enc packet not followed by data\n"); m_free(c->dek); c->dek = NULL; /* burn it */ } @@ -368,22 +521,29 @@ proc_packets( IOBUF a ) free_packet(pkt); continue; } + newpkt = -1; switch( pkt->pkttype ) { - case PKT_PUBKEY_CERT: proc_pubkey_cert( c, pkt ); break; - case PKT_SECKEY_CERT: proc_seckey_cert( c, pkt ); break; - case PKT_USER_ID: proc_user_id( c, pkt ); break; - case PKT_SIGNATURE: proc_signature( c, pkt ); break; + case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break; + case PKT_SECRET_CERT: newpkt = add_secret_cert( c, pkt ); break; + case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break; + case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break; case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break; - case PKT_ENCR_DATA: proc_encr_data( c, pkt ); break; + case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break; case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break; - case PKT_COMPR_DATA: proc_compr_data( c, pkt ); break; - default: free_packet(pkt); + case PKT_COMPRESSED: proc_compressed( c, pkt ); break; + default: newpkt = 0; break; } + if( newpkt == -1 ) + ; + else if( newpkt ) { + pkt = m_alloc( sizeof *pkt ); + init_packet(pkt); + } + else + free_packet(pkt); } - do_free_last_user_id( c ); - do_free_last_seckey( c ); - do_free_last_pubkey( c ); + release_cert( c ); m_free(c->dek); free_packet( pkt ); m_free( pkt ); @@ -392,289 +552,4 @@ proc_packets( IOBUF a ) return 0; } -#else /* old */ -int -proc_packets( IOBUF a ) -{ - PACKET *pkt; - PKT_pubkey_cert *last_pubkey = NULL; - PKT_seckey_cert *last_seckey = NULL; - PKT_user_id *last_user_id = NULL; - DEK *dek = NULL; - PKT_signature *sig; /* CHECK: "might be used uninitialied" */ - int rc, result; - MD_HANDLE md_handle; /* union to pass handles */ - char *ustr; - int lvl0, lvl1; - int last_was_pubkey_enc = 0; - u32 keyid[2]; - md_filter_context_t mfx; - - memset( &mfx, 0, sizeof mfx ); - lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */ - lvl1 = opt.check_sigs? 1:3; /* stdout or error */ - pkt = m_alloc( sizeof *pkt ); - init_packet(pkt); - while( (rc=parse_packet(a, pkt)) != -1 ) { - if( dek && pkt->pkttype != PKT_ENCR_DATA ) { - log_error("oops: valid pubkey enc packet not followed by data\n"); - m_free(dek); dek = NULL; /* burn it */ - } - - if( rc ) - free_packet(pkt); - else if( pkt->pkttype == PKT_PUBKEY_CERT ) { - if( last_user_id ) { - free_user_id( last_user_id ); - last_user_id = NULL; - } - if( last_pubkey ) { - free_pubkey_cert( last_pubkey ); - last_pubkey = NULL; - } - if( opt.check_sigs ) { - ustr = get_user_id_string(sig->keyid); - printstr(lvl0, "pub: %s\n", ustr ); - m_free(ustr); - } - else - fputs( "pub: [Public Key Cerificate]\n", stdout ); - last_pubkey = pkt->pkt.pubkey_cert; - pkt->pkt.pubkey_cert = NULL; - free_packet(pkt); - pkt->pkc_parent = last_pubkey; /* set this as parent */ - } - else if( pkt->pkttype == PKT_SECKEY_CERT ) { - if( last_user_id ) { - free_user_id( last_user_id ); - last_user_id = NULL; - } - if( last_seckey ) { - free_seckey_cert( last_seckey ); - last_seckey = NULL; - } - if( opt_list ) - fputs( "sec: (secret key certificate)\n", stdout ); - rc = check_secret_key( pkt->pkt.seckey_cert ); - if( opt_list ) { - if( !rc ) - fputs( " Secret key is good", stdout ); - else - fputs( g10_errstr(rc), stdout); - putchar('\n'); - } - else if( rc ) - log_error("secret key certificate error: %s\n", g10_errstr(rc)); - last_seckey = pkt->pkt.seckey_cert; - pkt->pkt.seckey_cert = NULL; - free_packet(pkt); - pkt->skc_parent = last_seckey; /* set this as parent */ - } - else if( pkt->pkttype == PKT_USER_ID ) { - if( last_user_id ) { - free_user_id( last_user_id ); - last_user_id = NULL; - } - if( opt_list ) { - printf("uid: '%.*s'\n", pkt->pkt.user_id->len, - pkt->pkt.user_id->name ); - if( !pkt->pkc_parent && !pkt->skc_parent ) - puts(" (orphaned)"); - } - if( pkt->pkc_parent ) { - if( pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_ELGAMAL - || pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_RSA ) { - keyid_from_pkc( pkt->pkc_parent, keyid ); - cache_user_id( pkt->pkt.user_id, keyid ); - } - } - - last_user_id = pkt->pkt.user_id; /* save */ - pkt->pkt.user_id = NULL; - free_packet(pkt); /* fixme: free_packet is not a good name */ - pkt->user_parent = last_user_id; /* and set this as user */ - } - else if( pkt->pkttype == PKT_SIGNATURE ) { - sig = pkt->pkt.signature; - ustr = get_user_id_string(sig->keyid); - result = -1; - if( sig->sig_class == 0x00 ) { - if( mfx.rmd160 ) - result = 0; - else - printstr(lvl1,"sig?: %s: no plaintext for signature\n", - ustr); - } - else if( sig->sig_class != 0x10 ) - printstr(lvl1,"sig?: %s: unknown signature class %02x\n", - ustr, sig->sig_class); - else if( !pkt->pkc_parent || !pkt->user_parent ) - printstr(lvl1,"sig?: %s: orphaned encoded packet\n", ustr); - else - result = 0; - - if( result ) - ; - else if( !opt.check_sigs && sig->sig_class != 0x00 ) { - result = -1; - printstr(lvl0, "sig: from %s\n", ustr ); - } - else if(sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { - md_handle.algo = sig->d.elg.digest_algo; - if( sig->d.elg.digest_algo == DIGEST_ALGO_RMD160 ) { - if( sig->sig_class == 0x00 ) - md_handle.u.rmd = rmd160_copy( mfx.rmd160 ); - else { - md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160); - rmd160_write(md_handle.u.rmd, pkt->user_parent->name, - pkt->user_parent->len); - } - result = signature_check( sig, md_handle ); - rmd160_close(md_handle.u.rmd); - } - else if( sig->d.elg.digest_algo == DIGEST_ALGO_MD5 - && sig->sig_class != 0x00 ) { - md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5); - md5_write(md_handle.u.md5, pkt->user_parent->name, - pkt->user_parent->len); - result = signature_check( sig, md_handle ); - md5_close(md_handle.u.md5); - } - else - result = G10ERR_DIGEST_ALGO; - } - else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) { - md_handle.algo = sig->d.rsa.digest_algo; - if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) { - if( sig->sig_class == 0x00 ) - md_handle.u.rmd = rmd160_copy( mfx.rmd160 ); - else { - md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160); - rmd160_write(md_handle.u.rmd, pkt->user_parent->name, - pkt->user_parent->len); - } - result = signature_check( sig, md_handle ); - rmd160_close(md_handle.u.rmd); - } - else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5 - && sig->sig_class != 0x00 ) { - md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5); - md5_write(md_handle.u.md5, pkt->user_parent->name, - pkt->user_parent->len); - result = signature_check( sig, md_handle ); - md5_close(md_handle.u.md5); - } - else - result = G10ERR_DIGEST_ALGO; - } - else - result = G10ERR_PUBKEY_ALGO; - - if( result == -1 ) - ; - else if( !result && sig->sig_class == 0x00 ) - printstr(1, "sig: good signature from %s\n", ustr ); - else if( !result ) - printstr(lvl0, "sig: good signature from %s\n", ustr ); - else - printstr(lvl1, "sig? %s: %s\n", ustr, g10_errstr(result)); - free_packet(pkt); - m_free(ustr); - } - else if( pkt->pkttype == PKT_PUBKEY_ENC ) { - PKT_pubkey_enc *enc; - - last_was_pubkey_enc = 1; - result = 0; - enc = pkt->pkt.pubkey_enc; - printf("enc: encrypted by a pubkey with keyid %08lX\n", - enc->keyid[1] ); - if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL - || enc->pubkey_algo == PUBKEY_ALGO_RSA ) { - m_free(dek ); /* paranoid: delete a pending DEK */ - dek = m_alloc_secure( sizeof *dek ); - if( (result = get_session_key( enc, dek )) ) { - /* error: delete the DEK */ - m_free(dek); dek = NULL; - } - } - else - result = G10ERR_PUBKEY_ALGO; - - if( result == -1 ) - ; - else if( !result ) - fputs( " DEK is good", stdout ); - else - printf( " %s", g10_errstr(result)); - putchar('\n'); - free_packet(pkt); - } - else if( pkt->pkttype == PKT_ENCR_DATA ) { - result = 0; - printf("dat: %sencrypted data\n", dek?"":"conventional "); - if( !dek && !last_was_pubkey_enc ) { - /* assume this is conventional encrypted data */ - dek = m_alloc_secure( sizeof *dek ); - dek->algo = DEFAULT_CIPHER_ALGO; - result = make_dek_from_passphrase( dek, 0 ); - } - else if( !dek ) - result = G10ERR_NO_SECKEY; - if( !result ) - result = decrypt_data( pkt->pkt.encr_data, dek ); - m_free(dek); dek = NULL; - if( result == -1 ) - ; - else if( !result ) - fputs( " encryption okay",stdout); - else - printf( " %s", g10_errstr(result)); - putchar('\n'); - free_packet(pkt); - last_was_pubkey_enc = 0; - } - else if( pkt->pkttype == PKT_PLAINTEXT ) { - PKT_plaintext *pt = pkt->pkt.plaintext; - printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name); - free_md_filter_context( &mfx ); - mfx.rmd160 = rmd160_open(0); - result = handle_plaintext( pt, &mfx ); - if( !result ) - fputs( " okay",stdout); - else - printf( " %s", g10_errstr(result)); - putchar('\n'); - free_packet(pkt); - last_was_pubkey_enc = 0; - } - else if( pkt->pkttype == PKT_COMPR_DATA ) { - PKT_compressed *zd = pkt->pkt.compressed; - printf("zip: compressed data packet\n"); - result = handle_compressed( zd ); - if( !result ) - fputs( " okay",stdout); - else - printf( " %s", g10_errstr(result)); - putchar('\n'); - free_packet(pkt); - last_was_pubkey_enc = 0; - } - else - free_packet(pkt); - } - - if( last_user_id ) - free_user_id( last_user_id ); - if( last_seckey ) - free_seckey_cert( last_seckey ); - if( last_pubkey ) - free_pubkey_cert( last_pubkey ); - m_free(dek); - free_packet( pkt ); - m_free( pkt ); - free_md_filter_context( &mfx ); - return 0; -} -#endif diff --git a/g10/options.h b/g10/options.h index f2a17de85..2b65db20c 100644 --- a/g10/options.h +++ b/g10/options.h @@ -32,7 +32,7 @@ struct { int answer_no; /* answer no on most questions */ int check_sigs; /* check key signatures */ int cache_all; - int reserved2; + int detached_sig; int reserved3; int reserved4; int reserved5; diff --git a/g10/packet.h b/g10/packet.h index 480fb54db..bef97a41f 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -27,23 +27,25 @@ #include "cipher.h" #include "filter.h" - -#define PKT_PUBKEY_ENC 1 /* public key encrypted packet */ -#define PKT_SIGNATURE 2 /* secret key encrypted packet */ -#define PKT_SESSION_KEY 3 /* session key packet (OpenPGP)*/ -#define PKT_ONEPASS_SIG 4 /* one pass sig packet (OpenPGP)*/ -#define PKT_SECKEY_CERT 5 /* secret key certificate */ -#define PKT_PUBKEY_CERT 6 /* public key certificate */ -#define PKT_SECKEY_SUBCERT 7 /* secret subkey certificate (OpenPGP) */ -#define PKT_COMPR_DATA 8 /* compressed data packet */ -#define PKT_ENCR_DATA 9 /* conventional encrypted data */ -#define PKT_MARKER 10 /* marker packet (OpenPGP) */ -#define PKT_PLAINTEXT 11 /* plaintext data with filename and mode */ -#define PKT_RING_TRUST 12 /* keyring trust packet */ -#define PKT_USER_ID 13 /* user id packet */ -#define PKT_COMMENT 14 /* comment packet */ -#define PKT_PUBKEY_SUBCERT 14 /* subkey certificate (OpenPGP) */ -#define PKT_NEW_COMMENT 16 /* new comment packet (OpenPGP) */ +typedef enum { + PKT_NONE =0, + PKT_PUBKEY_ENC =1, /* public key encrypted packet */ + PKT_SIGNATURE =2, /* secret key encrypted packet */ + PKT_SESSION_KEY =3, /* session key packet (OpenPGP)*/ + PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/ + PKT_SECRET_CERT =5, /* secret key certificate */ + PKT_PUBLIC_CERT =6, /* public key certificate */ + PKT_SECKEY_SUBCERT =7, /* secret subkey certificate (OpenPGP) */ + PKT_COMPRESSED =8, /* compressed data packet */ + PKT_ENCRYPTED =9, /* conventional encrypted data */ + PKT_MARKER =10, /* marker packet (OpenPGP) */ + PKT_PLAINTEXT =11, /* plaintext data with filename and mode */ + PKT_RING_TRUST =12, /* keyring trust packet */ + PKT_USER_ID =13, /* user id packet */ + PKT_COMMENT =14, /* comment packet */ + PKT_PUBKEY_SUBCERT=14, /* subkey certificate (OpenPGP) */ + PKT_NEW_COMMENT =16 /* new comment packet (OpenPGP) */ +} pkttype_t; typedef struct packet_struct PACKET; @@ -55,7 +57,7 @@ typedef struct { MPI rsa_integer; /* integer containing the DEK */ } rsa; struct { - MPI a, b; /* integers with the enciphered DEK */ + MPI a, b; /* integers with the encrypteded DEK */ } elg; } d; } PKT_pubkey_enc; @@ -98,7 +100,7 @@ typedef struct { MPI y; /* g^x mod p */ } elg; } d; -} PKT_pubkey_cert; +} PKT_public_cert; typedef struct { u32 timestamp; /* certificate made */ @@ -115,7 +117,7 @@ typedef struct { u16 csum; /* checksum */ u16 calc_csum; /* and a place to store the calculated csum */ byte is_protected; /* The above infos are protected and must */ - /* be deciphered before use */ + /* be decrypteded before use */ byte protect_algo; /* cipher used to protect the secret informations*/ union { /* information for the protection */ struct { @@ -133,7 +135,7 @@ typedef struct { u16 csum; /* checksum */ u16 calc_csum; /* and a place to store the calculated csum */ byte is_protected; /* The above infos are protected and must */ - /* be deciphered before use */ + /* be decrypteded before use */ byte protect_algo; /* cipher used to protect the secret informations*/ union { /* information for the protection */ struct { @@ -144,7 +146,7 @@ typedef struct { } protect; } elg; } d; -} PKT_seckey_cert; +} PKT_secret_cert; typedef struct { @@ -166,7 +168,7 @@ typedef struct { typedef struct { u32 len; /* length of encrypted data */ IOBUF buf; /* IOBUF reference */ -} PKT_encr_data; +} PKT_encrypted; typedef struct { u32 len; /* length of encrypted data */ @@ -179,20 +181,20 @@ typedef struct { /* combine all packets into a union */ struct packet_struct { - int pkttype; - PKT_pubkey_cert *pkc_parent; /* the pubkey to which it belongs */ - PKT_seckey_cert *skc_parent; /* the seckey to which it belongs */ + pkttype_t pkttype; + PKT_public_cert *pkc_parent; /* the pubkey to which it belongs */ + PKT_secret_cert *skc_parent; /* the seckey to which it belongs */ PKT_user_id *user_parent; /* the user_id to which it belongs */ union { void *generic; - PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */ - PKT_signature *signature; /* PKT_SIGNATURE */ - PKT_pubkey_cert *pubkey_cert; /* PKT_PUBKEY_CERT */ - PKT_seckey_cert *seckey_cert; /* PKT_SECKEY_CERT */ + PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */ + PKT_signature *signature; /* PKT_SIGNATURE */ + PKT_public_cert *public_cert; /* PKT_PUBLIC_CERT */ + PKT_secret_cert *secret_cert; /* PKT_SECRET_CERT */ PKT_comment *comment; /* PKT_COMMENT */ PKT_user_id *user_id; /* PKT_USER_ID */ PKT_compressed *compressed; /* PKT_COMPRESSED */ - PKT_encr_data *encr_data; /* PKT_ENCR_DATA */ + PKT_encrypted *encrypted; /* PKT_ENCRYPTED */ PKT_plaintext *plaintext; /* PKT_PLAINTEXT */ } pkt; }; @@ -218,20 +220,20 @@ u32 calc_packet_length( PACKET *pkt ); /*-- free-packet.c --*/ void free_pubkey_enc( PKT_pubkey_enc *enc ); void free_seckey_enc( PKT_signature *enc ); -void free_pubkey_cert( PKT_pubkey_cert *cert ); -void free_seckey_cert( PKT_seckey_cert *cert ); +void free_public_cert( PKT_public_cert *cert ); +void free_secret_cert( PKT_secret_cert *cert ); void free_user_id( PKT_user_id *uid ); void free_comment( PKT_comment *rem ); void free_packet( PACKET *pkt ); -PKT_pubkey_cert *copy_pubkey_cert( PKT_pubkey_cert *d, PKT_pubkey_cert *s ); -PKT_seckey_cert *copy_seckey_cert( PKT_seckey_cert *d, PKT_seckey_cert *s ); +PKT_public_cert *copy_public_cert( PKT_public_cert *d, PKT_public_cert *s ); +PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s ); /*-- sig-check.c --*/ -int signature_check( PKT_signature *sig, MD_HANDLE digest ); +int signature_check( PKT_signature *sig, MD_HANDLE *digest ); /*-- seckey-cert.c --*/ -int check_secret_key( PKT_seckey_cert *cert ); +int check_secret_key( PKT_secret_cert *cert ); /*-- pubkey-enc.c --*/ int get_session_key( PKT_pubkey_enc *k, DEK *dek ); @@ -240,8 +242,8 @@ int get_session_key( PKT_pubkey_enc *k, DEK *dek ); int handle_compressed( PKT_compressed *zd ); /*-- encr-data.c --*/ -int decrypt_data( PKT_encr_data *ed, DEK *dek ); -int encrypt_data( PKT_encr_data *ed, DEK *dek ); +int decrypt_data( PKT_encrypted *ed, DEK *dek ); +int encrypt_data( PKT_encrypted *ed, DEK *dek ); /*-- plaintext.c --*/ int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 569657c29..dd049406b 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -127,7 +127,7 @@ parse_packet( IOBUF inp, PACKET *pkt ) pktlen = 0; if( !lenbytes ) { pktlen = 0; /* don't know the value */ - if( pkttype != PKT_COMPR_DATA ) + if( pkttype != PKT_COMPRESSED ) iobuf_set_block_mode(inp, 1); } else { @@ -143,13 +143,13 @@ parse_packet( IOBUF inp, PACKET *pkt ) pkt->pkttype = pkttype; rc = G10ERR_UNKNOWN_PACKET; /* default to no error */ switch( pkttype ) { - case PKT_PUBKEY_CERT: - pkt->pkt.pubkey_cert = m_alloc_clear(sizeof *pkt->pkt.pubkey_cert ); + case PKT_PUBLIC_CERT: + pkt->pkt.public_cert = m_alloc_clear(sizeof *pkt->pkt.public_cert ); rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt ); break; - case PKT_SECKEY_CERT: + case PKT_SECRET_CERT: case PKT_SECKEY_SUBCERT: - pkt->pkt.seckey_cert = m_alloc_clear(sizeof *pkt->pkt.seckey_cert ); + pkt->pkt.secret_cert = m_alloc_clear(sizeof *pkt->pkt.secret_cert ); rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt ); break; case PKT_PUBKEY_ENC: @@ -171,10 +171,10 @@ parse_packet( IOBUF inp, PACKET *pkt ) case PKT_PLAINTEXT: rc = parse_plaintext(inp, pkttype, pktlen, pkt ); break; - case PKT_COMPR_DATA: + case PKT_COMPRESSED: rc = parse_compressed(inp, pkttype, pktlen, pkt ); break; - case PKT_ENCR_DATA: + case PKT_ENCRYPTED: rc = parse_encrypted(inp, pkttype, pktlen, pkt ); break; default: @@ -352,13 +352,13 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, unsigned short valid_period; int is_v4=0; - if( pkttype == PKT_PUBKEY_CERT ) { - pkt->pkt.pubkey_cert->mfx.md5 = md5_open(0); - pkt->pkt.pubkey_cert->mfx.rmd160 = rmd160_open(0); - pkt->pkt.pubkey_cert->mfx.maxbuf_size = 1; - md5_write(pkt->pkt.pubkey_cert->mfx.md5, hdr, hdrlen); - rmd160_write(pkt->pkt.pubkey_cert->mfx.rmd160, hdr, hdrlen); - iobuf_push_filter( inp, md_filter, &pkt->pkt.pubkey_cert->mfx ); + if( pkttype == PKT_PUBLIC_CERT ) { + pkt->pkt.public_cert->mfx.md5 = md5_open(0); + pkt->pkt.public_cert->mfx.rmd160 = rmd160_open(0); + pkt->pkt.public_cert->mfx.maxbuf_size = 1; + md5_write(pkt->pkt.public_cert->mfx.md5, hdr, hdrlen); + rmd160_write(pkt->pkt.public_cert->mfx.rmd160, hdr, hdrlen); + iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx ); } if( pktlen < 12 ) { @@ -382,17 +382,17 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, if( list_mode ) printf(":%s key certification packet:\n" "\tversion %d, created %lu, valid for %hu days\n", - pkttype == PKT_PUBKEY_CERT? "public": "secret", + pkttype == PKT_PUBLIC_CERT? "public": "secret", version, timestamp, valid_period ); - if( pkttype == PKT_SECKEY_CERT ) { - pkt->pkt.seckey_cert->timestamp = timestamp; - pkt->pkt.seckey_cert->valid_days = valid_period; - pkt->pkt.seckey_cert->pubkey_algo = algorithm; + if( pkttype == PKT_SECRET_CERT ) { + pkt->pkt.secret_cert->timestamp = timestamp; + pkt->pkt.secret_cert->valid_days = valid_period; + pkt->pkt.secret_cert->pubkey_algo = algorithm; } else { - pkt->pkt.pubkey_cert->timestamp = timestamp; - pkt->pkt.pubkey_cert->valid_days = valid_period; - pkt->pkt.pubkey_cert->pubkey_algo = algorithm; + pkt->pkt.public_cert->timestamp = timestamp; + pkt->pkt.public_cert->valid_days = valid_period; + pkt->pkt.public_cert->pubkey_algo = algorithm; } if( algorithm == PUBKEY_ALGO_ELGAMAL ) { @@ -409,19 +409,19 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, mpi_print(stdout, elg_y, mpi_print_mode ); putchar('\n'); } - if( pkttype == PKT_PUBKEY_CERT ) { - pkt->pkt.pubkey_cert->d.elg.p = elg_p; - pkt->pkt.pubkey_cert->d.elg.g = elg_g; - pkt->pkt.pubkey_cert->d.elg.y = elg_y; + if( pkttype == PKT_PUBLIC_CERT ) { + pkt->pkt.public_cert->d.elg.p = elg_p; + pkt->pkt.public_cert->d.elg.g = elg_g; + pkt->pkt.public_cert->d.elg.y = elg_y; } else { - PKT_seckey_cert *cert = pkt->pkt.seckey_cert; + PKT_secret_cert *cert = pkt->pkt.secret_cert; byte temp[8]; byte *mpibuf; - pkt->pkt.seckey_cert->d.elg.p = elg_p; - pkt->pkt.seckey_cert->d.elg.g = elg_g; - pkt->pkt.seckey_cert->d.elg.y = elg_y; + pkt->pkt.secret_cert->d.elg.p = elg_p; + pkt->pkt.secret_cert->d.elg.g = elg_g; + pkt->pkt.secret_cert->d.elg.y = elg_y; cert->d.elg.protect_algo = iobuf_get_noeof(inp); pktlen--; if( list_mode ) printf( "\tprotect algo: %d\n", cert->d.elg.protect_algo); @@ -455,10 +455,10 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, cert->d.elg.calc_csum += checksum( mpibuf ); cert->d.elg.x = mpi_decode_buffer( mpibuf ); m_free( mpibuf ); - log_mpidump("elg p=", cert->d.elg.p ); + /*log_mpidump("elg p=", cert->d.elg.p ); log_mpidump("elg g=", cert->d.elg.g ); log_mpidump("elg y=", cert->d.elg.y ); - log_mpidump("elg x=", cert->d.elg.x ); + log_mpidump("elg x=", cert->d.elg.x ); */ } } } @@ -474,17 +474,17 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, mpi_print(stdout, rsa_pub_exp, mpi_print_mode ); putchar('\n'); } - if( pkttype == PKT_PUBKEY_CERT ) { - pkt->pkt.pubkey_cert->d.rsa.rsa_n = rsa_pub_mod; - pkt->pkt.pubkey_cert->d.rsa.rsa_e = rsa_pub_exp; + if( pkttype == PKT_PUBLIC_CERT ) { + pkt->pkt.public_cert->d.rsa.rsa_n = rsa_pub_mod; + pkt->pkt.public_cert->d.rsa.rsa_e = rsa_pub_exp; } else { - PKT_seckey_cert *cert = pkt->pkt.seckey_cert; + PKT_secret_cert *cert = pkt->pkt.secret_cert; byte temp[8]; byte *mpibuf; - pkt->pkt.seckey_cert->d.rsa.rsa_n = rsa_pub_mod; - pkt->pkt.seckey_cert->d.rsa.rsa_e = rsa_pub_exp; + pkt->pkt.secret_cert->d.rsa.rsa_n = rsa_pub_mod; + pkt->pkt.secret_cert->d.rsa.rsa_e = rsa_pub_exp; cert->d.rsa.protect_algo = iobuf_get_noeof(inp); pktlen--; if( list_mode ) printf( "\tprotect algo: %d\n", cert->d.rsa.protect_algo); @@ -548,8 +548,8 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, leave: - if( pkttype == PKT_PUBKEY_CERT ) - iobuf_pop_filter( inp, md_filter, &pkt->pkt.pubkey_cert->mfx ); + if( pkttype == PKT_PUBLIC_CERT ) + iobuf_pop_filter( inp, md_filter, &pkt->pkt.public_cert->mfx ); skip_rest(inp, pktlen); return 0; } @@ -737,9 +737,9 @@ parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) { - PKT_encr_data *ed; + PKT_encrypted *ed; - ed = pkt->pkt.encr_data = m_alloc(sizeof *pkt->pkt.encr_data ); + ed = pkt->pkt.encrypted = m_alloc(sizeof *pkt->pkt.encrypted ); ed->len = pktlen; ed->buf = NULL; if( pktlen && pktlen < 10 ) { diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 183d91936..ba6a6f15a 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -41,7 +41,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) int i, j, c, rc = 0; MPI dek_frame = mpi_alloc_secure(40); u16 csum, csum2; - PKT_seckey_cert *skc = m_alloc_clear( sizeof *skc ); + PKT_secret_cert *skc = m_alloc_clear( sizeof *skc ); skc->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/ if( (rc = get_seckey( skc, k->keyid )) ) @@ -58,7 +58,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) skey.g = skc->d.elg.g; skey.y = skc->d.elg.y; skey.x = skc->d.elg.x; - elg_decipher( dek_frame, k->d.elg.a, k->d.elg.b, &skey ); + elg_decrypted( dek_frame, k->d.elg.a, k->d.elg.b, &skey ); memset( &skey, 0, sizeof skey ); } #ifdef HAVE_RSA_CIPHER @@ -82,7 +82,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) rc = G10ERR_PUBKEY_ALGO; /* unsupported algorithm */ goto leave; } - free_seckey_cert( skc ); skc = NULL; + free_secret_cert( skc ); skc = NULL; /* Now get the DEK (data encryption key) from the dek_frame @@ -151,7 +151,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) leave: mpi_free(dek_frame); if( skc ) - free_seckey_cert( skc ); + free_secret_cert( skc ); return rc; } diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 4e1a384c2..689f473c9 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -49,7 +49,7 @@ checksum( byte *p ) static int -check_elg( PKT_seckey_cert *cert ) +check_elg( PKT_secret_cert *cert ) { byte iv[8]; byte *mpibuf; @@ -116,7 +116,7 @@ check_elg( PKT_seckey_cert *cert ) #ifdef HAVE_RSA_CIPHER static int -check_rsa( PKT_seckey_cert *cert ) +check_rsa( PKT_secret_cert *cert ) { byte iv[8]; byte *mpibuf; @@ -131,7 +131,7 @@ check_rsa( PKT_seckey_cert *cert ) switch( cert->d.rsa.protect_algo ) { case CIPHER_ALGO_NONE: - log_bug("unprotect seckey_cert is flagged protected\n"); + log_bug("unprotect secret_cert is flagged protected\n"); break; case CIPHER_ALGO_BLOWFISH: keyid_from_skc( cert, keyid ); @@ -203,7 +203,7 @@ check_rsa( PKT_seckey_cert *cert ) * Check the secret key certificate */ int -check_secret_key( PKT_seckey_cert *cert ) +check_secret_key( PKT_secret_cert *cert ) { if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) return check_elg( cert ); diff --git a/g10/seskey.c b/g10/seskey.c index 5e944760d..cf34295e5 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -179,3 +179,15 @@ encode_md5_value( byte *md, unsigned len, unsigned nbits ) return frame; } +MPI +encode_md_value( MD_HANDLE *md, unsigned nbits ) +{ + byte *p = md_final( md ); + if( md->algo == DIGEST_ALGO_MD5 ) + return encode_md5_value( p, 16, nbits ); + else if( md->algo == DIGEST_ALGO_RMD160 ) + return encode_rmd160_value( p, 20, nbits ); + else + log_bug(NULL); +} + diff --git a/g10/sig-check.c b/g10/sig-check.c index fb3b409cf..841423878 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -38,9 +38,9 @@ * is able to append some data, before getting the digest. */ int -signature_check( PKT_signature *sig, MD_HANDLE digest ) +signature_check( PKT_signature *sig, MD_HANDLE *digest ) { - PKT_pubkey_cert *pkc = m_alloc_clear( sizeof *pkc ); + PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc ); MPI result = NULL; int rc=0, i, j, c, old_enc; byte *dp; @@ -54,35 +54,17 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { ELG_public_key pkey; - if( sig->d.elg.digest_algo == DIGEST_ALGO_RMD160 ) { - /* complete the digest */ - rmd160_putchar( digest.u.rmd, sig->sig_class ); - { u32 a = sig->timestamp; - rmd160_putchar( digest.u.rmd, (a >> 24) & 0xff ); - rmd160_putchar( digest.u.rmd, (a >> 16) & 0xff ); - rmd160_putchar( digest.u.rmd, (a >> 8) & 0xff ); - rmd160_putchar( digest.u.rmd, a & 0xff ); - } - dp = rmd160_final( digest.u.rmd ); - result = encode_rmd160_value( dp, 20, mpi_get_nbits(pkc->d.elg.p)); - } - else if( sig->d.elg.digest_algo == DIGEST_ALGO_MD5 ) { - md5_putchar( digest.u.md5, sig->sig_class ); - { u32 a = sig->timestamp; - md5_putchar( digest.u.md5, (a >> 24) & 0xff ); - md5_putchar( digest.u.md5, (a >> 16) & 0xff ); - md5_putchar( digest.u.md5, (a >> 8) & 0xff ); - md5_putchar( digest.u.md5, a & 0xff ); - } - md5_final( digest.u.md5 ); - dp = md5_read( digest.u.md5 ); - result = encode_md5_value( dp, 16, mpi_get_nbits(pkc->d.elg.p)); - } - else { - rc = G10ERR_DIGEST_ALGO; + if( (rc=md_okay(sig->d.elg.digest_algo)) ) goto leave; + /* complete the digest */ + md_putchar( digest, sig->sig_class ); + { u32 a = sig->timestamp; + md_putchar( digest, (a >> 24) & 0xff ); + md_putchar( digest, (a >> 16) & 0xff ); + md_putchar( digest, (a >> 8) & 0xff ); + md_putchar( digest, a & 0xff ); } - + result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p)); pkey.p = pkc->d.elg.p; pkey.g = pkc->d.elg.g; pkey.y = pkc->d.elg.y; @@ -131,7 +113,7 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) for(i=20,j=0; (c=mpi_getbyte(result, i)) != -1 && j < 18; i++, j++ ) if( asn[j] != c ) break; - if( j != 18 || c ) { /* ASN is wrong */ + if( j != 18 || mpi_getbyte(result, i) ) { /* ASN is wrong */ rc = G10ERR_BAD_PUBKEY; goto leave; } @@ -152,14 +134,14 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) } /* complete the digest */ - rmd160_putchar( digest.u.rmd, sig->sig_class ); + md_putchar( digest, sig->sig_class ); { u32 a = sig->timestamp; - rmd160_putchar( digest.u.rmd, (a >> 24) & 0xff ); - rmd160_putchar( digest.u.rmd, (a >> 16) & 0xff ); - rmd160_putchar( digest.u.rmd, (a >> 8) & 0xff ); - rmd160_putchar( digest.u.rmd, a & 0xff ); + md_putchar( digest, (a >> 24) & 0xff ); + md_putchar( digest, (a >> 16) & 0xff ); + md_putchar( digest, (a >> 8) & 0xff ); + md_putchar( digest, a & 0xff ); } - dp = rmd160_final( digest.u.rmd ); + dp = md_final( digest ); for(i=19; i >= 0; i--, dp++ ) if( mpi_getbyte( result, i ) != *dp ) { rc = G10ERR_BAD_SIGN; @@ -174,7 +156,7 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) for(i=16,j=0; j < 18 && (c=mpi_getbyte(result, i)) != -1; i++, j++ ) if( asn[j] != c ) break; - if( j != 18 || c ) { /* ASN is wrong */ + if( j != 18 || mpi_getbyte(result, i) ) { /* ASN is wrong */ rc = G10ERR_BAD_PUBKEY; goto leave; } @@ -195,15 +177,14 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) } /* complete the digest */ - md5_putchar( digest.u.md5, sig->sig_class ); + md_putchar( digest, sig->sig_class ); { u32 a = sig->timestamp; - md5_putchar( digest.u.md5, (a >> 24) & 0xff ); - md5_putchar( digest.u.md5, (a >> 16) & 0xff ); - md5_putchar( digest.u.md5, (a >> 8) & 0xff ); - md5_putchar( digest.u.md5, a & 0xff ); + md_putchar( digest, (a >> 24) & 0xff ); + md_putchar( digest, (a >> 16) & 0xff ); + md_putchar( digest, (a >> 8) & 0xff ); + md_putchar( digest, a & 0xff ); } - md5_final( digest.u.md5 ); - dp = md5_read( digest.u.md5 ); + dp = md_final( digest ); for(i=15; i >= 0; i--, dp++ ) if( mpi_getbyte( result, i ) != *dp ) { rc = G10ERR_BAD_SIGN; @@ -226,7 +207,7 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) leave: if( pkc ) - free_pubkey_cert( pkc ); + free_public_cert( pkc ); mpi_free( result ); return rc; } diff --git a/include/cipher.h b/include/cipher.h index e3280428f..e8bbbd490 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -49,11 +49,11 @@ #define CIPHER_ALGO_BLOWFISH 42 /* blowfish 160 bit key (not in OpenPGP)*/ #define CIPHER_ALGO_GOST 43 /* (Not in OpenPGP) */ -#define PUBKEY_ALGO_RSA 1 -#define PUBKEY_ALGO_RSA_E 2 /* RSA encrypt only */ -#define PUBKEY_ALGO_RSA_S 3 /* RSA sign only */ -#define PUBKEY_ALGO_ELGAMAL 16 -#define PUBKEY_ALGO_DSA 17 +#define PUBKEY_ALGO_RSA 1 +#define PUBKEY_ALGO_RSA_E 2 /* RSA encrypt only */ +#define PUBKEY_ALGO_RSA_S 3 /* RSA sign only */ +#define PUBKEY_ALGO_ELGAMAL 16 +#define PUBKEY_ALGO_DSA 17 #define DIGEST_ALGO_MD5 1 #define DIGEST_ALGO_SHA1 2 @@ -72,11 +72,26 @@ typedef struct { MD5HANDLE md5; RMDHANDLE rmd; } u; + int datalen; + char data[1]; } MD_HANDLE; int cipher_debug_mode; +/*-- md.c --*/ +int md_okay( int algo ); +MD_HANDLE *md_open( int algo, int secure ); +MD_HANDLE *md_copy( MD_HANDLE *a ); +MD_HANDLE *md_makecontainer( int algo ); /* used for a bad kludge */ +void md_write( MD_HANDLE *a, byte *inbuf, size_t inlen); +void md_putchar( MD_HANDLE *a, int c ); +byte *md_final(MD_HANDLE *a); +void md_close(MD_HANDLE *a); + +MD_HANDLE *md5_copy2md( MD5HANDLE a ); /* (in md5.c) */ +MD_HANDLE *rmd160_copy2md( RMDHANDLE a ); /* (in rmd160.c) */ + /*-- random.c --*/ void randomize_buffer( byte *buffer, size_t length, int level ); byte get_random_byte( int level ); diff --git a/include/errors.h b/include/errors.h index f2e7570cc..7ad3181c4 100644 --- a/include/errors.h +++ b/include/errors.h @@ -48,5 +48,6 @@ #define G10ERR_PASSPHRASE 26 /* invalid passphrase */ #define G10ERR_NI_PUBKEY 27 #define G10ERR_NI_CIPHER 28 +#define G10ERR_SIG_CLASS 29 #endif /*G10_ERRORS_H*/ diff --git a/include/util.h b/include/util.h index f71275cb9..0b6d4e9bc 100644 --- a/include/util.h +++ b/include/util.h @@ -82,6 +82,7 @@ const char *strusage( int level ); /*-- miscutil.c --*/ u32 make_timestamp(void); +void print_string( FILE *fp, byte *p, size_t n ); /*-- strgutil.c --*/ void free_strlist( STRLIST sl ); diff --git a/util/errors.c b/util/errors.c index 1e4579fc4..46797df3b 100644 --- a/util/errors.c +++ b/util/errors.c @@ -60,6 +60,7 @@ g10_errstr( int err ) X(PASSPHRASE ,"Invalid passphrase") X(NI_PUBKEY ,"Unimplemented pubkey algorithm") X(NI_CIPHER ,"Unimplemented cipher algorithm") + X(SIG_CLASS ,"Unknown signature class") default: p = buf; sprintf(buf, "Error code %d", err); break; } diff --git a/util/miscutil.c b/util/miscutil.c index 9fecf4488..18fff2c08 100644 --- a/util/miscutil.c +++ b/util/miscutil.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -31,3 +32,23 @@ make_timestamp() } +/**************** + * Print a string to FP, but filter all control characters out. + */ +void +print_string( FILE *fp, byte *p, size_t n ) +{ + for( ; n; n--, p++ ) + if( iscntrl( *p ) ) { + putc('\\', fp); + if( *p == '\n' ) + putc('n', fp); + else if( !*p ) + putc('0', fp); + else + printf("x%02x", *p ); + } + else + putc(*p, fp); +} +