aboutsummaryrefslogtreecommitdiffstats
path: root/g10/mainproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/mainproc.c')
-rw-r--r--g10/mainproc.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/g10/mainproc.c b/g10/mainproc.c
index edd393a1e..1e06a78c8 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -39,6 +39,16 @@
#include "trustdb.h"
#include "hkp.h"
+
+struct kidlist_item {
+ struct kidlist_item *next;
+ u32 kid[2];
+ int pubkey_algo;
+ int reason;
+};
+
+
+
/****************
* Structure to hold the context
*/
@@ -60,6 +70,8 @@ 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 */
};
@@ -76,6 +88,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;
+ }
+ c->failed_pkenc = NULL;
c->list = NULL;
}
@@ -213,6 +231,8 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
m_free(c->dek); c->dek = NULL;
}
}
+ else
+ result = G10ERR_NO_SECKEY;
}
else
result = G10ERR_PUBKEY_ALGO;
@@ -223,22 +243,66 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
if( opt.verbose > 1 )
log_info( _("public key encrypted data: good DEK\n") );
}
- else {
- /* fixme: defer this message until we have parsed all packets of
- * this type - do this by building a list of keys with their stati
- * and store it with the context. do_proc_packets can then use
- * this list to display some information */
- log_error(_("public key decryption failed: %s\n"), g10_errstr(result));
+ 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;
}
free_packet(pkt);
}
+
+/****************
+ * Print the list of public key encrypted packets which we could
+ * not decrypt.
+ */
+static void
+print_failed_pkenc( struct kidlist_item *list )
+{
+ for( ; list; list = list->next ) {
+ PKT_public_key *pk = m_alloc_clear( sizeof *pk );
+ const char *algstr = pubkey_algo_to_string( list->pubkey_algo );
+
+ pk->pubkey_algo = list->pubkey_algo;
+ if( !get_pubkey( pk, list->kid ) ) {
+ size_t n;
+ char *p;
+ log_info( _("encrypted with %u-bit %s key, ID %08lX, created %s\n"),
+ nbits_from_pk( pk ), algstr, (ulong)list->kid[1],
+ strtimestamp(pk->timestamp) );
+ fputs(" \"", log_stream() );
+ p = get_user_id( list->kid, &n );
+ print_string( log_stream(), p, n, '"' );
+ m_free(p);
+ fputs("\"\n", log_stream() );
+ }
+ else {
+ log_info(_("encrypted with %s key, ID %08lX\n"),
+ algstr, (ulong) list->kid[1] );
+ }
+ free_public_key( pk );
+
+ if( list->reason == G10ERR_NO_SECKEY )
+ log_info(_("no secret key for decryption available\n"));
+ else
+ log_error(_("public key decryption failed: %s\n"),
+ g10_errstr(list->reason));
+ }
+}
+
+
static void
proc_encrypted( CTX c, PACKET *pkt )
{
int result = 0;
+ print_failed_pkenc( c->failed_pkenc );
+
/*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
if( !c->dek && !c->last_was_session_key ) {
/* assume this is old conventional encrypted data */
@@ -267,8 +331,8 @@ proc_encrypted( CTX c, PACKET *pkt )
else {
write_status( STATUS_DECRYPTION_FAILED );
log_error(_("decryption failed: %s\n"), g10_errstr(result));
- /* FIXME: if this is secret key not available, try with
- * other keys */
+ /* Hmmm: does this work when we have encrypted using a multiple
+ * ways to specify the session key (symmmetric and PK)*/
}
free_packet(pkt);
c->last_was_session_key = 0;
@@ -452,7 +516,6 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
}
-
static void
print_userid( PACKET *pkt )
{
@@ -544,6 +607,7 @@ print_notation_data( PKT_signature *sig )
/* TODO */
}
+
/****************
* List the certificate in a user friendly way
*/