diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 18 | ||||
-rw-r--r-- | g10/keyedit.c | 2 | ||||
-rw-r--r-- | g10/mainproc.c | 151 | ||||
-rw-r--r-- | g10/parse-packet.c | 1 | ||||
-rw-r--r-- | g10/status.c | 18 | ||||
-rw-r--r-- | g10/status.h | 1 |
6 files changed, 155 insertions, 36 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index b4cf1cd7f..c3561d9f5 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,21 @@ +2000-12-19 Werner Koch <[email protected]> + + * status.c, status.h (cpr_get_no_help): New. + * keyedit.c (keyedit_menu): Use it here because we have our own + help list here. + +2000-12-18 Werner Koch <[email protected]> + + * mainproc.c (print_failed_pkenc): Don't print the sometimes + confusing message about unavailabe secret key. Renamed ... + (print_pkenc_list): ... to this and introduced failed arg. + (proc_encrypted): Print the failed encryption keys and then + the one to be used. + (proc_pubkey_enc): Store also the key we are going to use. + + * mainproc.c (check_sig_and_print): Don't list revoked user IDs. + (is_uid_revoked): New. + 2000-12-08 Werner Koch <[email protected]> * pipemode.c: Made the command work. Currently only for diff --git a/g10/keyedit.c b/g10/keyedit.c index 30302fa74..8faf141d5 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -695,7 +695,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, have_commands = 0; } if( !have_commands ) { - answer = cpr_get("keyedit.prompt", _("Command> ")); + answer = cpr_get_no_help("keyedit.prompt", _("Command> ")); cpr_kill_prompt(); } trim_spaces(answer); diff --git a/g10/mainproc.c b/g10/mainproc.c index 3b1670094..884fc94a3 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -70,8 +70,7 @@ struct mainproc_context { IOBUF iobuf; /* used to get the filename etc. */ int trustletter; /* temp usage in list_node */ ulong local_id; /* ditto */ - struct kidlist_item *failed_pkenc; /* list of packets for which - we do not have a secret key */ + struct kidlist_item *pkenc_list; /* list of encryption packets */ struct { int op; int stop_now; @@ -92,12 +91,12 @@ release_list( CTX c ) return; proc_tree(c, c->list ); release_kbnode( c->list ); - while( c->failed_pkenc ) { - struct kidlist_item *tmp = c->failed_pkenc->next; - m_free( c->failed_pkenc ); - c->failed_pkenc = tmp; + while( c->pkenc_list ) { + struct kidlist_item *tmp = c->pkenc_list->next; + m_free( c->pkenc_list ); + c->pkenc_list = tmp; } - c->failed_pkenc = NULL; + c->pkenc_list = NULL; c->list = NULL; c->have_data = 0; c->last_was_session_key = 0; @@ -310,27 +309,30 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) if( result == -1 ) ; - else if( !result ) { - if( opt.verbose > 1 ) - log_info( _("public key encrypted data: good DEK\n") ); - if ( opt.show_session_key ) { - int i; - char *buf = m_alloc ( c->dek->keylen*2 + 20 ); - sprintf ( buf, "%d:", c->dek->algo ); - for(i=0; i < c->dek->keylen; i++ ) - sprintf(buf+strlen(buf), "%02X", c->dek->key[i] ); - log_info( "session key: \"%s\"\n", buf ); - write_status_text ( STATUS_SESSION_KEY, buf ); - } - } - else { /* store it for later display */ - struct kidlist_item *x = m_alloc( sizeof *x ); - x->kid[0] = enc->keyid[0]; - x->kid[1] = enc->keyid[1]; - x->pubkey_algo = enc->pubkey_algo; - x->reason = result; - x->next = c->failed_pkenc; - c->failed_pkenc = x; + else { + if( !result ) { + if( opt.verbose > 1 ) + log_info( _("public key encrypted data: good DEK\n") ); + if ( opt.show_session_key ) { + int i; + char *buf = m_alloc ( c->dek->keylen*2 + 20 ); + sprintf ( buf, "%d:", c->dek->algo ); + for(i=0; i < c->dek->keylen; i++ ) + sprintf(buf+strlen(buf), "%02X", c->dek->key[i] ); + log_info( "session key: \"%s\"\n", buf ); + write_status_text ( STATUS_SESSION_KEY, buf ); + } + } + /* store it for later display */ + { + struct kidlist_item *x = m_alloc( sizeof *x ); + x->kid[0] = enc->keyid[0]; + x->kid[1] = enc->keyid[1]; + x->pubkey_algo = enc->pubkey_algo; + x->reason = result; + x->next = c->pkenc_list; + c->pkenc_list = x; + } } free_packet(pkt); } @@ -342,11 +344,19 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) * not decrypt. */ static void -print_failed_pkenc( struct kidlist_item *list ) +print_pkenc_list( struct kidlist_item *list, int failed ) { for( ; list; list = list->next ) { - PKT_public_key *pk = m_alloc_clear( sizeof *pk ); - const char *algstr = pubkey_algo_to_string( list->pubkey_algo ); + PKT_public_key *pk; + const char *algstr; + + if ( failed && !list->reason ) + continue; + if ( !failed && list->reason ) + continue; + + algstr = pubkey_algo_to_string( list->pubkey_algo ); + pk = m_alloc_clear( sizeof *pk ); if( !algstr ) algstr = "[?]"; @@ -370,7 +380,6 @@ print_failed_pkenc( struct kidlist_item *list ) free_public_key( pk ); if( list->reason == G10ERR_NO_SECKEY ) { - log_info(_("no secret key for decryption available\n")); if( is_status_enabled() ) { char buf[20]; sprintf(buf,"%08lX%08lX", (ulong)list->kid[0], @@ -378,7 +387,7 @@ print_failed_pkenc( struct kidlist_item *list ) write_status_text( STATUS_NO_SECKEY, buf ); } } - else + else if (list->reason) log_error(_("public key decryption failed: %s\n"), g10_errstr(list->reason)); } @@ -390,7 +399,8 @@ proc_encrypted( CTX c, PACKET *pkt ) { int result = 0; - print_failed_pkenc( c->failed_pkenc ); + print_pkenc_list( c->pkenc_list, 1 ); + print_pkenc_list( c->pkenc_list, 0 ); write_status( STATUS_BEGIN_DECRYPTION ); @@ -1150,6 +1160,68 @@ do_proc_packets( CTX c, IOBUF a ) } +/* fixme: This code is a duplicate fro keylist.c and should be replaced + * by flags set in getkey.c. gpg 1.1 already does this */ +static int +is_uid_revoked ( KBNODE keyblock, KBNODE uidnode, u32 *mainkid ) +{ + KBNODE node; + PKT_signature *selfsig = NULL; /* the latest valid self signature */ + + assert ( uidnode->pkt->pkttype == PKT_USER_ID ); + + /* first find out about the latest valid self-signature */ + for ( node = uidnode->next; node; node = node->next ) { + PKT_signature *sig; + + if ( node->pkt->pkttype == PKT_USER_ID + || node->pkt->pkttype == PKT_PHOTO_ID + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY ) + break; + if ( node->pkt->pkttype != PKT_SIGNATURE ) + continue; + sig = node->pkt->pkt.signature; + if ( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] ) + continue; /* we only care about self-signatures for now */ + + if ( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */ + if ( !check_key_signature( keyblock, node, NULL ) ) { + if ( !selfsig ) + selfsig = sig; /* use the first valid sig */ + else if ( sig->timestamp > selfsig->timestamp + && sig->sig_class >= selfsig->sig_class ) + selfsig = sig; /* but this one is newer */ + } + } + } + + /* watch out for a newer revocation */ + for ( node = uidnode->next; node; node = node->next ) { + PKT_signature *sig; + + if ( node->pkt->pkttype == PKT_USER_ID + || node->pkt->pkttype == PKT_PHOTO_ID + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY ) + break; + if ( node->pkt->pkttype != PKT_SIGNATURE ) + continue; + sig = node->pkt->pkt.signature; + if ( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] ) + continue; /* we only care about self-signatures */ + + if ( sig->sig_class == 0x30 + && (!selfsig || sig->timestamp >= selfsig->timestamp) ) { + if ( !check_key_signature( keyblock, node, NULL ) ) + return 1; + } + } + return 0; +} + + + static int check_sig_and_print( CTX c, KBNODE node ) { @@ -1207,6 +1279,8 @@ check_sig_and_print( CTX c, KBNODE node ) KBNODE un, keyblock; char *us; int count=0; + u32 mainkid[2]; + int mainkid_ok = 0; keyblock = get_pubkeyblock( sig->keyid ); @@ -1218,8 +1292,15 @@ check_sig_and_print( CTX c, KBNODE node ) * about the trustworthiness of each user id, sort them. * Integrate this with check_signatures_trust(). */ for( un=keyblock; un; un = un->next ) { - if( un->pkt->pkttype != PKT_USER_ID ) + if ( !mainkid_ok && un->pkt->pkttype == PKT_PUBLIC_KEY ) { + keyid_from_pk( un->pkt->pkt.public_key, mainkid ); + mainkid_ok = 1; + } + if( !mainkid_ok || un->pkt->pkttype != PKT_USER_ID ) continue; + if ( is_uid_revoked (keyblock, un, mainkid ) ) + continue; + if( !count++ ) log_info(rc? _("BAD signature from \"") : _("Good signature from \"")); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index dbaca3822..7ae91cb09 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1734,6 +1734,7 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, /* fixme: add some pktlen sanity checks */ int version; +#warning decrementing pktlen here is bad as it gives a bad valie in the listing version = iobuf_get_noeof(inp); pktlen--; if( version != 1 ) { log_error("encrypted_mdc packet with unknown version %d\n", diff --git a/g10/status.c b/g10/status.c index 8979be979..18a2ed2f5 100644 --- a/g10/status.c +++ b/g10/status.c @@ -507,6 +507,23 @@ cpr_enabled() } char * +cpr_get_no_help( const char *keyword, const char *prompt ) +{ + char *p; + + if( opt.command_fd != -1 ) + return do_get_from_fd ( keyword, 0, 0 ); + #ifdef USE_SHM_COPROCESSING + if( opt.shm_coprocess ) + return do_shm_get( keyword, 0, 0 ); + #endif + for(;;) { + p = tty_get( prompt ); + return p; + } +} + +char * cpr_get( const char *keyword, const char *prompt ) { char *p; @@ -528,6 +545,7 @@ cpr_get( const char *keyword, const char *prompt ) } } + char * cpr_get_utf8( const char *keyword, const char *prompt ) { diff --git a/g10/status.h b/g10/status.h index e3cd95a5a..cccc33400 100644 --- a/g10/status.h +++ b/g10/status.h @@ -103,6 +103,7 @@ void write_status_buffer ( int no, int cpr_enabled(void); char *cpr_get( const char *keyword, const char *prompt ); +char *cpr_get_no_help( const char *keyword, const char *prompt ); char *cpr_get_utf8( const char *keyword, const char *prompt ); char *cpr_get_hidden( const char *keyword, const char *prompt ); void cpr_kill_prompt(void); |