diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/Makefile.am | 1 | ||||
-rw-r--r-- | g10/Makefile.in | 1 | ||||
-rw-r--r-- | g10/build-packet.c | 4 | ||||
-rw-r--r-- | g10/elg.c | 7 | ||||
-rw-r--r-- | g10/filter.h | 4 | ||||
-rw-r--r-- | g10/free-packet.c | 6 | ||||
-rw-r--r-- | g10/g10.c | 37 | ||||
-rw-r--r-- | g10/keygen.c | 10 | ||||
-rw-r--r-- | g10/keyid.c | 73 | ||||
-rw-r--r-- | g10/main.h | 6 | ||||
-rw-r--r-- | g10/mainproc.c | 10 | ||||
-rw-r--r-- | g10/mdfilter.c | 16 | ||||
-rw-r--r-- | g10/packet.h | 4 | ||||
-rw-r--r-- | g10/parse-packet.c | 8 | ||||
-rw-r--r-- | g10/passphrase.c | 11 | ||||
-rw-r--r-- | g10/pkclist.c | 44 | ||||
-rw-r--r-- | g10/plaintext.c | 18 | ||||
-rw-r--r-- | g10/rsa.c | 7 | ||||
-rw-r--r-- | g10/seskey.c | 19 | ||||
-rw-r--r-- | g10/sig-check.c | 45 | ||||
-rw-r--r-- | g10/sign.c | 39 | ||||
-rw-r--r-- | g10/skclist.c | 4 | ||||
-rw-r--r-- | g10/trustdb.c | 210 | ||||
-rw-r--r-- | g10/trustdb.h | 28 |
24 files changed, 436 insertions, 176 deletions
diff --git a/g10/Makefile.am b/g10/Makefile.am index 901370ffb..b6b9ce572 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -31,6 +31,7 @@ g10_SOURCES = g10.c \ openfile.c \ keyid.c \ trustdb.c \ + trustdb.h \ packet.h \ parse-packet.c \ passphrase.c \ diff --git a/g10/Makefile.in b/g10/Makefile.in index 531b1b8e9..7e5ef73ac 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -69,6 +69,7 @@ g10_SOURCES = g10.c \ openfile.c \ keyid.c \ trustdb.c \ + trustdb.h \ packet.h \ parse-packet.c \ passphrase.c \ diff --git a/g10/build-packet.c b/g10/build-packet.c index 6c526e346..5bacf3f86 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -196,7 +196,7 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc ) * Make a hash value from the public key certificate */ void -hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc ) +hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc ) { PACKET pkt; int rc = 0; @@ -210,7 +210,7 @@ hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc ) if( (rc = build_packet( a, &pkt )) ) log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc)); while( (c=iobuf_get(a)) != -1 ) - md_putchar( md, c ); + md_putc( md, c ); iobuf_cancel(a); } @@ -66,7 +66,7 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ) void -g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md ) +g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ) { ELG_secret_key skey; MPI frame; @@ -74,9 +74,10 @@ g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md ) assert( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ); - dp = md_final( md ); + md_final( md ); + dp = md_read( md, 0 ); keyid_from_skc( skc, sig->keyid ); - sig->d.elg.digest_algo = md->algo; + sig->d.elg.digest_algo = md_get_algo(md); sig->d.elg.digest_start[0] = dp[0]; sig->d.elg.digest_start[1] = dp[1]; sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) ); diff --git a/g10/filter.h b/g10/filter.h index 83ed3d153..bedacf9b6 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -23,9 +23,7 @@ #include "cipher.h" typedef struct { - MD_HANDLE *md; /* catch all */ - MD5HANDLE md5; /* if !NULL create md5 */ - RMDHANDLE rmd160; /* if !NULL create rmd160 */ + MD_HANDLE md; /* catch all */ size_t maxbuf_size; } md_filter_context_t; diff --git a/g10/free-packet.c b/g10/free-packet.c index dfd6f4b08..fb5949a8f 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -68,8 +68,7 @@ free_public_cert( PKT_public_cert *cert ) mpi_free( cert->d.rsa.rsa_n ); mpi_free( cert->d.rsa.rsa_e ); } - md5_close( cert->mfx.md5 ); - rmd160_close( cert->mfx.rmd160 ); + md_close( cert->mfx.md ); m_free(cert); } @@ -88,8 +87,7 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s ) d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n ); d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e ); } - d->mfx.md5 = NULL; - d->mfx.rmd160 =NULL; + d->mfx.md = NULL; return d; } @@ -34,6 +34,7 @@ #include "mpi.h" #include "cipher.h" #include "filter.h" +#include "trustdb.h" enum cmd_values { aNull = 0, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr, @@ -392,6 +393,13 @@ main( int argc, char **argv ) } } + if( cmd != aPrimegen && cmd != aPrintMDs ) { + rc = check_trustdb(0); + if( rc ) + log_error("failed to initialize the TrustDB: %s\n", g10_errstr(rc)); + } + + switch( cmd ) { case aStore: /* only store the file */ if( argc > 1 ) @@ -582,9 +590,7 @@ print_mds( const char *fname ) FILE *fp; char buf[1024]; size_t n; - MD5HANDLE md5; - RMDHANDLE rmd160; - SHA1HANDLE sha1; + MD_HANDLE md; if( !fname ) { fp = stdin; @@ -597,31 +603,26 @@ print_mds( const char *fname ) return; } - md5 = md5_open(0); - rmd160 = rmd160_open(0); - sha1 = sha1_open(0); + md = md_open( DIGEST_ALGO_MD5, 0 ); + md_enable( md, DIGEST_ALGO_RMD160 ); + md_enable( md, DIGEST_ALGO_SHA1 ); - while( (n=fread( buf, 1, DIM(buf), fp )) ) { - md5_write( md5, buf, n ); - rmd160_write( rmd160, buf, n ); - sha1_write( sha1, buf, n ); - } + while( (n=fread( buf, 1, DIM(buf), fp )) ) + md_write( md, buf, n ); if( ferror(fp) ) log_error("%s: %s\n", fname, strerror(errno) ); else { byte *p; - md5_final(md5); - printf( "%s: MD5 =", fname ); print_hex(md5_read(md5), 16 ); - printf("\n%s: RMD160 =", fname ); print_hex(rmd160_final(rmd160), 20 ); - printf("\n%s: SHA1 =", fname ); print_hex(sha1_final(sha1), 20 ); + md_final(md); + printf( "%s: MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 ); + printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 ); + printf("\n%s: SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 ); putchar('\n'); } - md5_close(md5); - rmd160_close(rmd160); - sha1_close(sha1); + md_close(md); if( fp != stdin ) fclose(fp); diff --git a/g10/keygen.c b/g10/keygen.c index fddeedbbc..c83d8660a 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #include <errno.h> #include <assert.h> #include "util.h" @@ -408,7 +409,7 @@ generate_keypair() tty_printf( "\n" "You need a User-ID to identify your key; the software constructs the user id\n" "from Real Name, Comment and Email Address in this form:\n" -" \"Heinrich Heine (Der Dichter) <[email protected]>\"\n" ); +" \"Heinrich Heine (Der Dichter) <[email protected]>\"\n\n" ); uid = NULL; aname=acomment=amail=NULL; for(;;) { @@ -422,6 +423,8 @@ generate_keypair() tty_kill_prompt(); if( strpbrk( aname, "<([])>" ) ) tty_printf("Invalid character in name\n"); + else if( isdigit(*aname) ) + tty_printf("Name may not start with a digit\n"); else if( strlen(aname) < 5 ) tty_printf("Name must be at least 5 characters long\n"); else @@ -464,12 +467,15 @@ generate_keypair() } m_free(uid); - uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+10); + uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+12+10); p = stpcpy(p, aname ); if( *acomment ) p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")"); if( *amail ) p = stpcpy(stpcpy(stpcpy(p," <"), amail),">"); + #ifndef HAVE_DEV_RANDOM + strcpy(p, " (INSECURE!)" ); + #endif tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid); for(;;) { diff --git a/g10/keyid.c b/g10/keyid.c index 43413e083..01604dfe1 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -48,14 +48,14 @@ pubkey_letter( int algo ) /* this is special code for V3 which uses ElGamal and * calculates a fingerprint like V4, but with rmd160 - * and a version byte of 3. Returns an rmd160 handle, caller must - * do rmd160_final() + * and a version byte of 3. Returns an md handle, caller must + * do md_close() */ -static RMDHANDLE +static MD_HANDLE v3_elg_fingerprint_md( PKT_public_cert *pkc ) { - RMDHANDLE md; + MD_HANDLE md; byte *buf1, *buf2, *buf3; byte *p1, *p2, *p3; unsigned n1, n2, n3; @@ -73,35 +73,36 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc ) /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */ n = 14 + n1 + n2 + n3; - md = rmd160_open(0); + md = md_open( DIGEST_ALGO_RMD160, 0); - rmd160_putchar( md, 0x99 ); /* ctb */ - rmd160_putchar( md, n >> 8 ); /* 2 byte length header */ - rmd160_putchar( md, n ); - rmd160_putchar( md, 3 ); /* version */ + md_putc( md, 0x99 ); /* ctb */ + md_putc( md, n >> 8 ); /* 2 byte length header */ + md_putc( md, n ); + md_putc( md, 3 ); /* version */ { u32 a = pkc->timestamp; - rmd160_putchar( md, a >> 24 ); - rmd160_putchar( md, a >> 16 ); - rmd160_putchar( md, a >> 8 ); - rmd160_putchar( md, a ); + md_putc( md, a >> 24 ); + md_putc( md, a >> 16 ); + md_putc( md, a >> 8 ); + md_putc( md, a ); } { u16 a = pkc->valid_days; - rmd160_putchar( md, a >> 8 ); - rmd160_putchar( md, a ); + md_putc( md, a >> 8 ); + md_putc( md, a ); } - rmd160_putchar( md, pkc->pubkey_algo ); - rmd160_putchar( md, n1>>8); rmd160_putchar( md, n1 ); rmd160_write( md, p1, n1 ); - rmd160_putchar( md, n2>>8); rmd160_putchar( md, n2 ); rmd160_write( md, p2, n2 ); - rmd160_putchar( md, n3>>8); rmd160_putchar( md, n3 ); rmd160_write( md, p3, n3 ); + md_putc( md, pkc->pubkey_algo ); + md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 ); + md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 ); + md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 ); m_free(buf1); m_free(buf2); m_free(buf3); + md_final( md ); return md; } -static RMDHANDLE +static MD_HANDLE v3_elg_fingerprint_md_skc( PKT_secret_cert *skc ) { PKT_public_cert pkc; @@ -133,13 +134,13 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid ) if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { const byte *dp; - RMDHANDLE md; + MD_HANDLE md; md = v3_elg_fingerprint_md_skc(skc); - dp = rmd160_final( md ); + dp = md_read( md, DIGEST_ALGO_RMD160 ); keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; lowbits = keyid[1]; - rmd160_close(md); + md_close(md); } else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid ); @@ -166,13 +167,13 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid ) if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { const byte *dp; - RMDHANDLE md; + MD_HANDLE md; md = v3_elg_fingerprint_md(pkc); - dp = rmd160_final( md ); + dp = md_read( md, DIGEST_ALGO_RMD160 ); keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; lowbits = keyid[1]; - rmd160_close(md); + md_close(md); } else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid ); @@ -310,33 +311,33 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ) unsigned n; if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { - RMDHANDLE md; + MD_HANDLE md; md = v3_elg_fingerprint_md(pkc); - dp = rmd160_final( md ); + dp = md_read( md, DIGEST_ALGO_RMD160 ); array = m_alloc( 20 ); len = 20; memcpy(array, dp, 20 ); - rmd160_close(md); + md_close(md); } else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { - MD5HANDLE md; + MD_HANDLE md; - md = md5_open(0); + md = md_open( DIGEST_ALGO_MD5, 0); p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL ); for( ; !*p && n; p++, n-- ) ; - md5_write( md, p, n ); + md_write( md, p, n ); m_free(buf); p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL ); for( ; !*p && n; p++, n-- ) ; - md5_write( md, p, n ); + md_write( md, p, n ); m_free(buf); - md5_final(md); + md_final(md); array = m_alloc( 16 ); len = 16; - memcpy(array, md5_read(md), 16 ); - md5_close(md); + memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 ); + md_close(md); } else { array = m_alloc(1); diff --git a/g10/main.h b/g10/main.h index 747ab70a8..a10ce4ba3 100644 --- a/g10/main.h +++ b/g10/main.h @@ -64,18 +64,18 @@ MPI encode_session_key( DEK *dek, unsigned nbits ); MPI encode_sha1_value( byte *md, unsigned len, 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 ); +MPI encode_md_value( MD_HANDLE md, unsigned nbits ); /*-- comment.c --*/ KBNODE make_comment_node( const char *s ); /*-- elg.c --*/ void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ); -void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md ); +void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ); /*-- rsa.c --*/ void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ); -void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md ); +void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ); #endif /*G10_MAIN_H*/ diff --git a/g10/mainproc.c b/g10/mainproc.c index a99c975fd..f64a2cda5 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -268,7 +268,7 @@ proc_plaintext( CTX c, PACKET *pkt ) * And look at the sigclass to check wether we should use the * textmode filter (sigclass 0x01) */ - c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0); + c->mfx.md = md_open( DIGEST_ALGO_RMD160, 0); rc = handle_plaintext( pt, &c->mfx ); if( rc ) log_error( "handle plaintext failed: %s\n", g10_errstr(rc)); @@ -302,7 +302,7 @@ static int do_check_sig( CTX c, KBNODE node ) { PKT_signature *sig; - MD_HANDLE *md; + MD_HANDLE md; int algo, rc; assert( node->pkt->pkttype == PKT_SIGNATURE ); @@ -314,7 +314,7 @@ do_check_sig( CTX c, KBNODE node ) algo = sig->d.rsa.digest_algo; else return G10ERR_PUBKEY_ALGO; - if( (rc=md_okay(algo)) ) + if( (rc=check_digest_algo(algo)) ) return rc; if( sig->sig_class == 0x00 ) { @@ -328,10 +328,6 @@ do_check_sig( CTX c, KBNODE node ) 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); diff --git a/g10/mdfilter.c b/g10/mdfilter.c index 5a77c9012..17cf259eb 100644 --- a/g10/mdfilter.c +++ b/g10/mdfilter.c @@ -53,12 +53,8 @@ md_filter( void *opaque, int control, buf[i] = c; } - if( i ) { - if( mfx->md5 ) - md5_write(mfx->md5, buf, i ); - if( mfx->rmd160 ) - rmd160_write(mfx->rmd160, buf, i ); - } + if( i ) + md_write(mfx->md, buf, i ); else rc = -1; /* eof */ *ret_len = i; @@ -72,12 +68,8 @@ md_filter( void *opaque, int control, void free_md_filter_context( md_filter_context_t *mfx ) { - if( mfx->md5 ) - md5_close(mfx->md5); - mfx->md5 = NULL; - if( mfx->rmd160 ) - rmd160_close(mfx->rmd160); - mfx->rmd160 = NULL; + md_close(mfx->md); + mfx->md = NULL; mfx->maxbuf_size = 0; } diff --git a/g10/packet.h b/g10/packet.h index 03a7f328f..e82248a85 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -220,7 +220,7 @@ int parse_packet( IOBUF inp, PACKET *ret_pkt); /*-- build-packet.c --*/ int build_packet( IOBUF inp, PACKET *pkt ); u32 calc_packet_length( PACKET *pkt ); -void hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc ); +void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc ); /*-- free-packet.c --*/ void free_pubkey_enc( PKT_pubkey_enc *enc ); @@ -235,7 +235,7 @@ 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 is_secret_key_protected( PKT_secret_cert *cert ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 70eef4007..1d056d8ea 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -438,11 +438,11 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, int is_v4=0; 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.md = md_open(DIGEST_ALGO_MD5, 0); + md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_RMD160); + md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_SHA1); 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); + md_write(pkt->pkt.public_cert->mfx.md, hdr, hdrlen); iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx ); } diff --git a/g10/passphrase.c b/g10/passphrase.c index df8ac7176..462c7c752 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -143,13 +143,14 @@ hash_passphrase( DEK *dek, char *pw ) dek->keylen = 0; if( dek->algo == CIPHER_ALGO_BLOWFISH ) { - RMDHANDLE rmd; + MD_HANDLE md; - rmd = rmd160_open(1); - rmd160_write( rmd, pw, strlen(pw) ); + md = md_open(DIGEST_ALGO_RMD160, 1); + md_write( md, pw, strlen(pw) ); + md_final( md ); dek->keylen = 20; - memcpy( dek->key, rmd160_final(rmd), dek->keylen ); - rmd160_close(rmd); + memcpy( dek->key, md_read(md,0), dek->keylen ); + md_close(md); } else rc = G10ERR_UNSUPPORTED; diff --git a/g10/pkclist.c b/g10/pkclist.c index 1356a06f9..f753eb6fc 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -31,6 +31,22 @@ #include "keydb.h" #include "memory.h" #include "util.h" +#include "trustdb.h" + + +/**************** + * Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL + * Returns: true if we trust. + */ +static int +do_we_trust( PKT_public_cert *pkc, int trustlevel ) +{ + /* Eventuell fragen falls der trustlevel nicht ausreichend ist */ + + + return 1; /* yes */ +} + void @@ -64,13 +80,27 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list ) free_public_cert( pkc ); pkc = NULL; log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) ); } - else if( is_valid_pubkey_algo(pkc->pubkey_algo) ) { - PKC_LIST r; - r = m_alloc( sizeof *r ); - r->pkc = pkc; pkc = NULL; - r->next = pkc_list; - r->mark = 0; - pkc_list = r; + else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) { + int trustlevel; + + rc = check_pkc_trust( pkc, &trustlevel ); + if( rc ) { + free_public_cert( pkc ); pkc = NULL; + log_error("error checking pkc of '%s': %s\n", + remusr->d, g10_errstr(rc) ); + } + else if( do_we_trust( pkc, trustlevel ) ) { + PKC_LIST r; + + r = m_alloc( sizeof *r ); + r->pkc = pkc; pkc = NULL; + r->next = pkc_list; + r->mark = 0; + pkc_list = r; + } + else { /* we don't trust this pkc */ + free_public_cert( pkc ); pkc = NULL; + } } else { free_public_cert( pkc ); pkc = NULL; diff --git a/g10/plaintext.c b/g10/plaintext.c index 114db1df0..ea43a1e6f 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -79,11 +79,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) goto leave; } if( mfx->md ) - md_putchar(mfx->md, c ); - if( mfx->rmd160 ) - rmd160_putchar(mfx->rmd160, c ); - if( mfx->md5 ) - md5_putchar(mfx->md5, c ); + md_putc(mfx->md, c ); if( putc( c, fp ) == EOF ) { log_error("Error writing to '%s': %s\n", fname, strerror(errno) ); rc = G10ERR_WRITE_FILE; @@ -93,10 +89,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) } else { while( (c = iobuf_get(pt->buf)) != -1 ) { - if( mfx->rmd160 ) - rmd160_putchar(mfx->rmd160, c ); - if( mfx->md5 ) - md5_putchar(mfx->md5, c ); + if( mfx->md ) + md_putc(mfx->md, c ); if( putc( c, fp ) == EOF ) { log_error("Error writing to '%s': %s\n", fname, strerror(errno) ); @@ -162,11 +156,7 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ) while( (c = iobuf_get(fp)) != -1 ) { if( mfx->md ) - md_putchar(mfx->md, c ); - if( mfx->rmd160 ) - rmd160_putchar(mfx->rmd160, c ); - if( mfx->md5 ) - md5_putchar(mfx->md5, c ); + md_putc(mfx->md, c ); } iobuf_close(fp); @@ -64,7 +64,7 @@ g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ) void -g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md ) +g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md ) { #ifdef HAVE_RSA_CIPHER RSA_secret_key skey; @@ -72,10 +72,11 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md ) assert( sig->pubkey_algo == PUBKEY_ALGO_RSA ); - dp = md_final( md ); + md_final( md ); + dp = md_read( md, 0 ); keyid_from_skc( skc, sig->keyid ); - sig->d.rsa.digest_algo = md->algo; + sig->d.rsa.digest_algo = md_get_algo( md ); sig->d.rsa.digest_start[0] = dp[0]; sig->d.rsa.digest_start[1] = dp[1]; sig->d.rsa.rsa_integer = diff --git a/g10/seskey.c b/g10/seskey.c index 2698c73c7..c99bed598 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -226,16 +226,17 @@ encode_md5_value( byte *md, unsigned len, unsigned nbits ) } MPI -encode_md_value( MD_HANDLE *md, unsigned nbits ) +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 if( md->algo == DIGEST_ALGO_SHA1 ) - return encode_sha1_value( p, 20, nbits ); - else + switch( md_get_algo( md ) ) { + case DIGEST_ALGO_MD5: + return encode_md5_value( md_read(md, DIGEST_ALGO_MD5), 16, nbits ); + case DIGEST_ALGO_RMD160: + return encode_rmd160_value( md_read(md, DIGEST_ALGO_RMD160), 20, nbits ); + case DIGEST_ALGO_SHA1: + return encode_sha1_value( md_read(md, DIGEST_ALGO_SHA1), 20, nbits ); + default: log_bug(NULL); + } } diff --git a/g10/sig-check.c b/g10/sig-check.c index 856d57daa..74517507e 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -38,7 +38,7 @@ * 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_public_cert *pkc = m_alloc_clear( sizeof *pkc ); MPI result = NULL; @@ -54,16 +54,17 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest ) if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { ELG_public_key pkey; - if( (rc=md_okay(sig->d.elg.digest_algo)) ) + if( (rc=check_digest_algo(sig->d.elg.digest_algo)) ) goto leave; /* complete the digest */ - md_putchar( digest, sig->sig_class ); + md_putc( 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 ); + md_putc( digest, (a >> 24) & 0xff ); + md_putc( digest, (a >> 16) & 0xff ); + md_putc( digest, (a >> 8) & 0xff ); + md_putc( digest, a & 0xff ); } + md_final( digest ); result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p)); pkey.p = pkc->d.elg.p; pkey.g = pkc->d.elg.g; @@ -134,14 +135,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest ) } /* complete the digest */ - md_putchar( digest, sig->sig_class ); + md_putc( 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 ); + md_putc( digest, (a >> 24) & 0xff ); + md_putc( digest, (a >> 16) & 0xff ); + md_putc( digest, (a >> 8) & 0xff ); + md_putc( digest, a & 0xff ); } - dp = md_final( digest ); + md_final( digest ); + dp = md_read( digest, 0 ); for(i=19; i >= 0; i--, dp++ ) if( mpi_getbyte( result, i ) != *dp ) { rc = G10ERR_BAD_SIGN; @@ -177,14 +179,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest ) } /* complete the digest */ - md_putchar( digest, sig->sig_class ); + md_putc( 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 ); + md_putc( digest, (a >> 24) & 0xff ); + md_putc( digest, (a >> 16) & 0xff ); + md_putc( digest, (a >> 8) & 0xff ); + md_putc( digest, a & 0xff ); } - dp = md_final( digest ); + md_final( digest ); + dp = md_read( digest, 0 ); for(i=15; i >= 0; i--, dp++ ) if( mpi_getbyte( result, i ) != *dp ) { rc = G10ERR_BAD_SIGN; @@ -220,7 +223,7 @@ int check_key_signature( KBNODE root, KBNODE node ) { KBNODE unode; - MD_HANDLE *md; + MD_HANDLE md; PKT_public_cert *pkc; PKT_signature *sig; int algo; @@ -239,7 +242,7 @@ check_key_signature( KBNODE root, KBNODE node ) algo = sig->d.rsa.digest_algo; else return G10ERR_PUBKEY_ALGO; - if( (rc=md_okay(algo)) ) + if( (rc=check_digest_algo(algo)) ) return rc; unode = find_kbparent( root, node ); diff --git a/g10/sign.c b/g10/sign.c index d0596d669..04ae72a2f 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -41,7 +41,7 @@ static int -complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE *md ) +complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md ) { int rc=0; @@ -119,7 +119,7 @@ sign_file( const char *filename, int detached, STRLIST locusr, /* prepare to calculate the MD over the input */ if( opt.textmode && opt.armor ) iobuf_push_filter( inp, text_filter, &tfx ); - mfx.rmd160 = rmd160_open(0); + mfx.md = md_open(DIGEST_ALGO_RMD160, 0); iobuf_push_filter( inp, md_filter, &mfx ); if( opt.armor ) @@ -194,7 +194,7 @@ sign_file( const char *filename, int detached, STRLIST locusr, for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) { PKT_secret_cert *skc; PKT_signature *sig; - RMDHANDLE rmd; + MD_HANDLE md; byte *dp; skc = skc_rover->skc; @@ -205,15 +205,16 @@ sign_file( const char *filename, int detached, STRLIST locusr, sig->timestamp = make_timestamp(); sig->sig_class = opt.textmode? 0x01 : 0x00; - rmd = rmd160_copy( mfx.rmd160 ); - rmd160_putchar( rmd, sig->sig_class ); + md = md_copy( mfx.md ); + md_putc( md, sig->sig_class ); { u32 a = sig->timestamp; - rmd160_putchar( rmd, (a >> 24) & 0xff ); - rmd160_putchar( rmd, (a >> 16) & 0xff ); - rmd160_putchar( rmd, (a >> 8) & 0xff ); - rmd160_putchar( rmd, a & 0xff ); + md_putc( md, (a >> 24) & 0xff ); + md_putc( md, (a >> 16) & 0xff ); + md_putc( md, (a >> 8) & 0xff ); + md_putc( md, a & 0xff ); } - dp = rmd160_final( rmd ); + md_final( md ); + dp = md_read( md, DIGEST_ALGO_RMD160 ); if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { ELG_secret_key skey; @@ -268,7 +269,7 @@ sign_file( const char *filename, int detached, STRLIST locusr, else log_bug(NULL); - rmd160_close( rmd ); + md_close( md ); /* and write it */ init_packet(&pkt); @@ -289,7 +290,7 @@ sign_file( const char *filename, int detached, STRLIST locusr, else iobuf_close(out); iobuf_close(inp); - rmd160_close( mfx.rmd160 ); + md_close( mfx.md ); release_skc_list( skc_list ); release_pkc_list( pkc_list ); return rc; @@ -621,7 +622,7 @@ sign_key( const char *username, STRLIST locusr ) leave: release_kbnode( keyblock ); release_skc_list( skc_list ); - rmd160_close( mfx.rmd160 ); + md_close( mfx.md ); return rc; } @@ -830,7 +831,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, { PKT_signature *sig; int rc=0; - MD_HANDLE *md; + MD_HANDLE md; assert( sigclass >= 0x10 && sigclass <= 0x13 ); md = md_open( digest_algo, 0 ); @@ -843,12 +844,12 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, sig->timestamp = make_timestamp(); sig->sig_class = sigclass; - md_putchar( md, sig->sig_class ); + md_putc( md, sig->sig_class ); { u32 a = sig->timestamp; - md_putchar( md, (a >> 24) & 0xff ); - md_putchar( md, (a >> 16) & 0xff ); - md_putchar( md, (a >> 8) & 0xff ); - md_putchar( md, a & 0xff ); + md_putc( md, (a >> 24) & 0xff ); + md_putc( md, (a >> 16) & 0xff ); + md_putc( md, (a >> 8) & 0xff ); + md_putc( md, a & 0xff ); } rc = complete_sig( sig, skc, md ); diff --git a/g10/skclist.c b/g10/skclist.c index 75e547ffb..e7c9071d6 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -60,7 +60,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock ) free_secret_cert( skc ); skc = NULL; log_error("no default secret key: %s\n", g10_errstr(rc) ); } - else if( is_valid_pubkey_algo(skc->pubkey_algo) ) { + else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) { SKC_LIST r; r = m_alloc( sizeof *r ); r->skc = skc; skc = NULL; @@ -82,7 +82,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock ) free_secret_cert( skc ); skc = NULL; log_error("skipped '%s': %s\n", locusr->d, g10_errstr(rc) ); } - else if ( is_valid_pubkey_algo(skc->pubkey_algo) ) { + else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) { SKC_LIST r; r = m_alloc( sizeof *r ); r->skc = skc; skc = NULL; diff --git a/g10/trustdb.c b/g10/trustdb.c index 00774f572..46c950021 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include <errno.h> #include <assert.h> @@ -30,6 +31,215 @@ #include "keydb.h" #include "memory.h" #include "util.h" +#include "trustdb.h" +#include "options.h" +#define TRUST_RECORD_LEN 40 + +struct trust_record { + byte rectype; + byte reserved; + union { + byte raw[TRUST_RECORD_LEN-2]; + struct { /* version record: */ + byte magic[2]; + byte version; /* should be 1 */ + byte reserved[3]; + u32 locked; /* pid of process which holds a lock */ + u32 created; /* timestamp of trustdb creation */ + u32 modified; /* timestamp of last modification */ + u32 validated; /* timestamp of last validation */ + u32 local_id_counter; + byte marginals_needed; + byte completes_needed; + byte max_cert_depth; + } version; + struct { /* public key record */ + u32 local_id; + u32 keyid[2]; + byte algo; + byte reserved; + byte fingerprint[20]; + byte ownertrust; + } pubkey; + struct { /* cache record */ + u32 local_id; + u32 keyid[2]; + byte valid; + byte reserved; + byte blockhash[20]; + byte n_untrusted; + byte n_marginal; + byte n_fully; + byte trustlevel; + } cache; + } r; +}; + + + +static char *db_name; + +/************************************************** + ************** read and write helpers ************ + **************************************************/ + +static void +fwrite_8(FILE *fp, byte a) +{ + if( putc( a & 0xff, fp ) == EOF ) + log_fatal("error writing byte to trustdb: %s\n", strerror(errno) ); +} + +static void +fwrite_16(FILE *fp, u16 a) +{ + putc( (a>>8) & 0x0ff , fp ); + if( putc( a & 0xff, fp ) == EOF ) + log_fatal("error writing u16 to trustdb: %s\n", strerror(errno) ); +} + +static int +fwrite_32( FILE*fp, u32 a) +{ + putc( (a>>24) & 0xff, fp ); + putc( (a>>16) & 0xff, fp ); + putc( (a>> 8) & 0xff, fp ); + if( putc( a & 0xff, fp ) == EOF ) + log_fatal("error writing u32 to trustdb: %s\n", strerror(errno) ); +} + +static int +fwrite_zeros( FILE *fp, size_t n) +{ + while( n-- ) + if( putc( 0, fp ) == EOF ) + log_fatal("error writing zeros to trustdb: %s\n", strerror(errno) ); +} + + +/************************************************** + ************** read and write stuff ************** + **************************************************/ + + +/**************** + * Create a new trustdb + */ +static void +create_db( const char *fname ) +{ + FILE *fp; + u32 along; + u16 ashort; + + fp =fopen( fname, "w" ); + if( !fp ) + log_fatal("can't create %s: %s\n", fname, strerror(errno) ); + fwrite_8( fp, 1 ); + fwrite_8( fp, 'g' ); + fwrite_8( fp, '1' ); + fwrite_8( fp, '0' ); + fwrite_8( fp, 1 ); /* version */ + fwrite_zeros( fp, 3 ); /* reserved */ + fwrite_32( fp, 0 ); /* not locked */ + fwrite_32( fp, make_timestamp() ); /* created */ + fwrite_32( fp, 0 ); /* not yet modified */ + fwrite_32( fp, 0 ); /* not yet validated*/ + fwrite_32( fp, 0 ); /* local-id-counter */ + fwrite_8( fp, 3 ); /* marginals needed */ + fwrite_8( fp, 1 ); /* completes needed */ + fwrite_8( fp, 4 ); /* max_cet_depth */ + fwrite_zeros( fp, 9 ); /* filler */ + fclose(fp); +} + + + + + + + + + + + + + +/*********************************************** + ************* trust logic ******************* + ***********************************************/ + + + + + +/********************************************************* + **************** API Interface ************************ + *********************************************************/ + +/**************** + * Perform some checks over the trustdb + * level 0: used on initial program startup + */ +int +check_trustdb( int level ) +{ + if( !level ) { + char *fname = make_filename("~/.g10", "trustDB", NULL ); + if( access( fname, R_OK ) ) { + if( errno != ENOENT ) { + log_error("can't access %s: %s\n", fname, strerror(errno) ); + m_free(fname); + return G10ERR_TRUSTDB; + } + create_db( fname ); + } + m_free(db_name); + db_name = fname; + + /* we can verify a signature about our local data (secring and trustdb) + * in ~/.g10/ here + */ + } + else + log_bug(NULL); + + return 0; +} + + +/**************** + * Get the trustlevel for this PKC. + * Note: This does not ask any questions + * Returns: 0 okay of an errorcode + * + * It operates this way: + * locate the pkc in the trustdb + * found: + * Do we have a valid cache record for it? + * yes: return trustlevel from cache + * no: make a cache record + * not found: + * Return with a trustlevel, saying that we do not have + * a trust record for it. The caller may use insert_trust_record() + * and then call this function here again. + * + * Problems: How do we get the complete keyblock to check that the + * cache record is actually valid? Think we need a clever + * cache in getkey.c to keep track of this stuff. Maybe it + * is not necessary to check this if we use a local pubring. Hmmmm. + */ +int +check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel ) +{ + int trustlevel = 0; + + if( opt.verbose ) + log_info("check_pkc_trust() called.\n"); + + *r_trustlevel = trustlevel; + return 0; +} diff --git a/g10/trustdb.h b/g10/trustdb.h new file mode 100644 index 000000000..01f126808 --- /dev/null +++ b/g10/trustdb.h @@ -0,0 +1,28 @@ +/* trustdb.h - Trust database + * 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 + */ + +#ifndef G10_TRUSTDB_H +#define G10_TRUSTDB_H + +/*-- trustdb.c --*/ +int check_trustdb( int level ); +int check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel ); + +#endif /*G10_TRUSTDB_H*/ |