List and check sigs works

This commit is contained in:
Werner Koch 1997-12-01 10:33:23 +00:00
parent 649eae8f1b
commit 5c1cca042e
35 changed files with 1007 additions and 793 deletions

3
TODO
View File

@ -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

View File

@ -18,6 +18,7 @@ cipher_SOURCES = blowfish.c \
random.c \
rmd.h \
rmd160.c \
md.c \
smallprime.c
cipher_LIBADD = rsa.o

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);

158
cipher/md.c Normal file
View File

@ -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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#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);
}

View File

@ -55,6 +55,7 @@
#include <assert.h>
#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)
{

View File

@ -25,6 +25,7 @@
#include <assert.h>
#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)
{

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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 ) {

View File

@ -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;

View File

@ -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;

View File

@ -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 );

View File

@ -21,6 +21,7 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#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");

View File

@ -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;
}

View File

@ -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 );

View File

@ -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;
}

View File

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <assert.h>
#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;
}

View File

@ -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*/

View File

@ -21,6 +21,7 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#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

View File

@ -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;

View File

@ -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 );

View File

@ -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 ) {

View File

@ -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;
}

View File

@ -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 );

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 );

View File

@ -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*/

View File

@ -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 );

View File

@ -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;
}

View File

@ -21,6 +21,7 @@
#include <config.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#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);
}