diff --git a/g10/g10.c b/g10/g10.c index 345ccd5ae..747cba196 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -66,7 +66,7 @@ strusage( int level ) #endif #ifdef HAVE_RSA_CIPHER "WARNING: This version has RSA support! Your are not allowed to\n" - " use it inside the Unites States until Sep 30, 2000!\n" + " use it inside the Unites States before Sep 30, 2000!\n" #endif ; break; diff --git a/g10/getkey.c b/g10/getkey.c index c978cb9fd..c7ea1686a 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -275,6 +275,7 @@ get_seckey( PKT_secret_cert *skc, u32 *keyid ) /**************** * Get a secret key by name and store it into skc + * If NAME is NULL use the default certificate */ int get_seckey_by_name( PKT_secret_cert *skc, const char *name ) @@ -432,8 +433,12 @@ scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid, int save_mode; u32 akeyid[2]; PKT_secret_cert *last_pk = NULL; + int get_first; + u32 dummy_keyid[2]; - assert( !keyid || !name ); + get_first = !keyid && !name; + if( get_first ) + keyid = dummy_keyid; if( !(a = iobuf_open( filename ) ) ) { log_debug("scan_secret_keyring: can't open '%s'\n", filename ); @@ -453,11 +458,17 @@ scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid, switch( pkt.pkt.secret_cert->pubkey_algo ) { case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_RSA: - keyid_from_skc( pkt.pkt.secret_cert, akeyid ); - if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) { + if( get_first ) { copy_secret_cert( skc, pkt.pkt.secret_cert ); found++; } + else { + keyid_from_skc( pkt.pkt.secret_cert, akeyid ); + if( (akeyid[0] == keyid[0] && akeyid[1] == keyid[1]) ) { + copy_secret_cert( skc, pkt.pkt.secret_cert ); + found++; + } + } break; default: log_error("cannot handle pubkey algo %d\n", diff --git a/g10/mainproc.c b/g10/mainproc.c index 8004c3803..9418da4e4 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -67,6 +67,7 @@ typedef struct { int last_was_pubkey_enc; int opt_list; NODE cert; /* the current certificate */ + int have_data; } *CTX; @@ -152,8 +153,9 @@ release_cert( CTX c ) static int add_onepass_sig( CTX c, PACKET *pkt ) { + NODE node; + if( c->cert ) { /* add another packet */ - NODE node; if( c->cert->pkt->pkttype != PKT_ONEPASS_SIG ) { log_error("add_onepass_sig: another packet is in the way\n"); @@ -164,7 +166,8 @@ add_onepass_sig( CTX c, PACKET *pkt ) c->cert = node; } else /* insert the first one */ - c->cert = new_node( pkt ); + c->cert = node = new_node( pkt ); + return 1; } @@ -338,6 +341,8 @@ proc_plaintext( CTX c, PACKET *pkt ) printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name); free_md_filter_context( &c->mfx ); + /* fixme: take the digest algo to use from the + * onpass_sig packet (if we have these) */ c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0); result = handle_plaintext( pt, &c->mfx ); if( !result ) @@ -393,8 +398,9 @@ do_check_sig( CTX c, NODE node ) if( (rc=md_okay(algo)) ) return rc; - if( sig->sig_class == 0x00 ) + 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 ); @@ -568,6 +574,9 @@ proc_packets( IOBUF a ) case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break; default: newpkt = 0; break; } + if( pkt->pkttype != PKT_SIGNATURE ) + c->have_data = pkt->pkttype == PKT_PLAINTEXT; + if( newpkt == -1 ) ; else if( newpkt ) { @@ -615,7 +624,19 @@ proc_tree( CTX c, NODE node ) log_error("proc_tree: onepass_sig without followin data\n"); else if( node->child->pkt->pkttype != PKT_SIGNATURE ) log_error("proc_tree: onepass_sig not followed by signature\n"); - else { /* check all signature */ + else { /* check all signatures */ + if( !c->have_data ) { + free_md_filter_context( &c->mfx ); + /* fixme: take the digest algo to use from the + * onepass_sig packet (if we have these) */ + c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0); + rc = ask_for_detached_datafile( &c->mfx ); + if( rc ) { + log_error("can't hash datafile: %s\n", g10_errstr(rc)); + return; + } + } + for(n1=node->child; n1; n1 = n1->next ) { PKT_signature *sig = n1->pkt->pkt.signature; diff --git a/g10/packet.h b/g10/packet.h index 63626307e..5694c8a5b 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -251,6 +251,7 @@ int encrypt_data( PKT_encrypted *ed, DEK *dek ); /*-- plaintext.c --*/ int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ); +int ask_for_detached_datafile( md_filter_context_t *mfx ); /*-- comment.c --*/ int write_comment( IOBUF out, const char *s ); diff --git a/g10/plaintext.c b/g10/plaintext.c index d317fd789..edd12891c 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -82,6 +82,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) rc = G10ERR_READ_FILE; goto leave; } + if( mfx->md ) + md_putchar(mfx->md, c ); if( mfx->rmd160 ) rmd160_putchar(mfx->rmd160, c ); if( mfx->md5 ) @@ -124,3 +126,42 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) return rc; } + +/**************** + * Ask for the detached datafile and calculate the digest from it. + */ +int +ask_for_detached_datafile( md_filter_context_t *mfx ) +{ + char *answer; + FILE *fp; + int rc = 0; + int c; + + tty_printf("Detached signature.\n"); + answer = tty_get("Please enter name of data file: "); + tty_kill_prompt(); + + fp = fopen(answer,"rb"); + if( !fp ) { + log_error("can't open '%s': %s\n", answer, strerror(errno) ); + rc = G10ERR_READ_FILE; + goto leave; + } + + while( (c = getc(fp)) != EOF ) { + if( mfx->md ) + md_putchar(mfx->md, c ); + if( mfx->rmd160 ) + rmd160_putchar(mfx->rmd160, c ); + if( mfx->md5 ) + md5_putchar(mfx->md5, c ); + } + fclose(fp); + + leave: + m_free(answer); + return rc; +} + + diff --git a/include/cipher.h b/include/cipher.h index e8bbbd490..f918dcf08 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -79,6 +79,15 @@ typedef struct { int cipher_debug_mode; +#ifdef HAVE_RSA_CIPHER + #define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL \ + || (a) == PUBKEY_ALGO_RSA ) +#else + #define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL ) +#endif + + + /*-- md.c --*/ int md_okay( int algo ); MD_HANDLE *md_open( int algo, int secure );