diff options
author | Werner Koch <wk@gnupg.org> | 2000-07-14 19:34:53 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2000-07-14 19:34:53 +0200 |
commit | 92cd25550836198cf1e3a6aac239eef98364359d (patch) | |
tree | 4fad355126fae79c93535e0e7c6afd91e384552a /g10/pkclist.c | |
parent | See ChangeLog: Thu May 25 18:39:11 CEST 2000 Werner Koch (diff) | |
download | gnupg2-92cd25550836198cf1e3a6aac239eef98364359d.tar.xz gnupg2-92cd25550836198cf1e3a6aac239eef98364359d.zip |
See ChangeLog: Fri Jul 14 19:38:23 CEST 2000 Werner Koch
Diffstat (limited to 'g10/pkclist.c')
-rw-r--r-- | g10/pkclist.c | 154 |
1 files changed, 140 insertions, 14 deletions
diff --git a/g10/pkclist.c b/g10/pkclist.c index abd75f9cd..8e61ffdd0 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -1,5 +1,5 @@ /* pkclist.c - * Copyright (C) 1998 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -24,11 +24,10 @@ #include <string.h> #include <errno.h> #include <assert.h> -#include <gcrypt.h> +#include <gcrypt.h> #include "options.h" #include "packet.h" -#include "main.h" #include "errors.h" #include "keydb.h" #include "util.h" @@ -36,6 +35,7 @@ #include "ttyio.h" #include "status.h" #include "i18n.h" +#include "main.h" #define CONTROL_D ('D' - 'A' + 1) @@ -97,6 +97,112 @@ fpr_info( PKT_public_key *pk ) } +/**************** + * Show the revocation reason as it is stored with the given signature + */ +static void +do_show_revocation_reason( PKT_signature *sig ) +{ + size_t n, nn; + const byte *p, *pp; + int seq = 0; + const char *text; + + while( (p = enum_sig_subpkt( sig->hashed_data, SIGSUBPKT_REVOC_REASON, + &n, &seq )) ) { + if( !n ) + continue; /* invalid - just skip it */ + + if( *p == 0 ) + text = _("No reason specified"); + else if( *p == 0x01 ) + text = _("Key is superseeded"); + else if( *p == 0x02 ) + text = _("Key has been compromised"); + else if( *p == 0x03 ) + text = _("Key is no longer used"); + else if( *p == 0x20 ) + text = _("User ID is no longer valid"); + else + text = NULL; + + log_info( _("Reason for revocation: ") ); + if( text ) + fputs( text, log_stream() ); + else + fprintf( log_stream(), "code=%02x", *p ); + putc( '\n', log_stream() ); + n--; p++; + pp = NULL; + do { + /* We don't want any empty lines, so skip them */ + while( n && *p == '\n' ) { + p++; + n--; + } + if( n ) { + pp = memchr( p, '\n', n ); + nn = pp? pp - p : n; + log_info( _("Revocation comment: ") ); + print_string( log_stream(), p, nn, 0 ); + putc( '\n', log_stream() ); + p += nn; n -= nn; + } + } while( pp ); + } +} + + +static void +show_revocation_reason( PKT_public_key *pk ) +{ + /* Hmmm, this is not so easy becuase we have to duplicate the code + * used in the trustbd to calculate the keyflags. We need to find + * a clean way to check revocation certificates on keys and signatures. + * And there should be no duplicate code. Because we enter this function + * only when the trustdb toldus, taht we have a revoked key, we could + * simplylook for a revocation cert and display this one, when there is + * only one. Let's try to do this until we have a better solution. + */ + KBNODE node, keyblock = NULL; + byte fingerprint[MAX_FINGERPRINT_LEN]; + size_t fingerlen; + int rc; + + /* get the keyblock */ + fingerprint_from_pk( pk, fingerprint, &fingerlen ); + rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen ); + if( rc ) { /* that should never happen */ + log_debug( "failed to get the keyblock\n"); + return; + } + + for( node=keyblock; node; node = node->next ) { + if( ( node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) + && !cmp_public_keys( node->pkt->pkt.public_key, pk ) ) + break; + } + if( !node ) { + log_debug("Oops, PK not in keyblock\n"); + release_kbnode( keyblock ); + return; + } + /* now find the revocation certificate */ + for( node = node->next; node ; node = node->next ) { + if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) + break; + if( node->pkt->pkttype == PKT_SIGNATURE + && (node->pkt->pkt.signature->sig_class == 0x20 + || node->pkt->pkt.signature->sig_class == 0x28 ) ) { + /* FIXME: we should check the signature here */ + do_show_revocation_reason ( node->pkt->pkt.signature ); + } + } + + release_kbnode( keyblock ); +} + static void show_paths( ulong lid, int only_first ) @@ -338,38 +444,53 @@ _("Could not find a valid trust path to the key. Let's see whether we\n" /**************** * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL - * Returns: true if we trust. + * Returns: true if we trust. Might change the trustlevel */ static int -do_we_trust( PKT_public_key *pk, int trustlevel ) +do_we_trust( PKT_public_key *pk, int *trustlevel ) { int rc; int did_add = 0; + int trustmask = 0; retry: - if( (trustlevel & TRUST_FLAG_REVOKED) ) { + if( (*trustlevel & TRUST_FLAG_REVOKED) ) { log_info(_("key %08lX: key has been revoked!\n"), (ulong)keyid_from_pk( pk, NULL) ); + show_revocation_reason( pk ); if( opt.batch ) return 0; if( !cpr_get_answer_is_yes("revoked_key.override", _("Use this key anyway? ")) ) return 0; + trustmask |= TRUST_FLAG_REVOKED; } - else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) { + else if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) { log_info(_("key %08lX: subkey has been revoked!\n"), (ulong)keyid_from_pk( pk, NULL) ); + show_revocation_reason( pk ); if( opt.batch ) return 0; if( !cpr_get_answer_is_yes("revoked_key.override", _("Use this key anyway? ")) ) return 0; + trustmask |= TRUST_FLAG_SUB_REVOKED; + } + *trustlevel &= ~trustmask; + + if( opt.always_trust) { + if( opt.verbose ) + log_info("No trust check due to --always-trust option\n"); + /* The problem with this, is that EXPIRE can't be checked as + * this needs to insert a ne key into the trustdb first and + * we don't want that */ + return 1; } - switch( (trustlevel & TRUST_MASK) ) { + switch( (*trustlevel & TRUST_MASK) ) { case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */ rc = insert_trust_record_by_pk( pk ); if( rc ) { @@ -377,11 +498,12 @@ do_we_trust( PKT_public_key *pk, int trustlevel ) gpg_errstr(rc) ); return 0; /* no */ } - rc = check_trust( pk, &trustlevel, NULL, NULL, NULL ); + rc = check_trust( pk, trustlevel, NULL, NULL, NULL ); + *trustlevel &= ~trustmask; if( rc ) log_fatal("trust check after insert failed: %s\n", gpg_errstr(rc) ); - if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) { + if( *trustlevel == TRUST_UNKNOWN || *trustlevel == TRUST_EXPIRED ) { log_debug("do_we_trust: oops at %d\n", __LINE__ ); return 0; } @@ -399,7 +521,8 @@ do_we_trust( PKT_public_key *pk, int trustlevel ) else { int quit; - rc = add_ownertrust( pk, &quit, &trustlevel ); + rc = add_ownertrust( pk, &quit, trustlevel ); + *trustlevel &= ~trustmask; if( !rc && !did_add && !quit ) { did_add = 1; goto retry; @@ -445,7 +568,7 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel ) { int rc; - rc = do_we_trust( pk, trustlevel ); + rc = do_we_trust( pk, &trustlevel ); if( (trustlevel & TRUST_FLAG_REVOKED) && !rc ) return 0; @@ -528,10 +651,12 @@ check_signatures_trust( PKT_signature *sig ) write_status( STATUS_KEYREVOKED ); log_info(_("WARNING: This key has been revoked by its owner!\n")); log_info(_(" This could mean that the signature is forgery.\n")); + show_revocation_reason( pk ); } else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) { write_status( STATUS_KEYREVOKED ); log_info(_("WARNING: This subkey has been revoked by its owner!\n")); + show_revocation_reason( pk ); } @@ -770,7 +895,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) else { int trustlevel; - rc = check_trust( pk, &trustlevel, NULL, NULL, NULL ); + rc = check_trust( pk, &trustlevel, pk->namehash, + NULL, NULL ); if( rc ) { log_error("error checking pk of `%s': %s\n", answer, gpg_errstr(rc) ); @@ -844,7 +970,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) { int trustlevel; - rc = check_trust( pk, &trustlevel, NULL, NULL, NULL ); + rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL ); if( rc ) { free_public_key( pk ); pk = NULL; log_error(_("%s: error checking key: %s\n"), |