mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Update head to match stable 1.0
This commit is contained in:
parent
151ee2f47b
commit
3f51f7db3d
155 changed files with 83872 additions and 37585 deletions
374
g10/revoke.c
374
g10/revoke.c
|
@ -1,5 +1,5 @@
|
|||
/* revoke.c
|
||||
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "keydb.h"
|
||||
#include <gcrypt.h>
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "ttyio.h"
|
||||
|
@ -52,24 +52,273 @@ revocation_reason_build_cb( PKT_signature *sig, void *opaque )
|
|||
byte *buffer;
|
||||
size_t buflen = 1;
|
||||
|
||||
if(!reason)
|
||||
return 0;
|
||||
|
||||
if( reason->desc ) {
|
||||
ud = native_to_utf8( reason->desc );
|
||||
buflen += strlen(ud);
|
||||
}
|
||||
buffer = gcry_xmalloc( buflen );
|
||||
buffer = m_alloc( buflen );
|
||||
*buffer = reason->code;
|
||||
if( ud ) {
|
||||
memcpy(buffer+1, ud, strlen(ud) );
|
||||
gcry_free( ud );
|
||||
m_free( ud );
|
||||
}
|
||||
|
||||
build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
|
||||
gcry_free( buffer );
|
||||
m_free( buffer );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a revocation certificate for UNAME via a designated revoker
|
||||
*/
|
||||
int
|
||||
gen_desig_revoke( const char *uname )
|
||||
{
|
||||
int rc = 0;
|
||||
armor_filter_context_t afx;
|
||||
PACKET pkt;
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
PKT_signature *sig = NULL;
|
||||
IOBUF out = NULL;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
KEYDB_HANDLE kdbhd;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
KBNODE keyblock=NULL,node;
|
||||
u32 keyid[2];
|
||||
int i,any=0;
|
||||
|
||||
if( opt.batch ) {
|
||||
log_error(_("sorry, can't do this in batch mode\n"));
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
|
||||
kdbhd = keydb_new (0);
|
||||
classify_user_id (uname, &desc);
|
||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
||||
if (rc) {
|
||||
log_error (_("key `%s' not found: %s\n"),uname, g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||
if( rc ) {
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* To parse the revkeys */
|
||||
merge_keys_and_selfsig(keyblock);
|
||||
|
||||
/* get the key from the keyblock */
|
||||
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
if( !node )
|
||||
BUG ();
|
||||
|
||||
pk=node->pkt->pkt.public_key;
|
||||
|
||||
keyid_from_pk(pk,keyid);
|
||||
|
||||
/* Are we a designated revoker for this key? */
|
||||
|
||||
if(!pk->revkey && pk->numrevkeys)
|
||||
BUG();
|
||||
|
||||
for(i=0;i<pk->numrevkeys;i++)
|
||||
{
|
||||
if(sk)
|
||||
free_secret_key(sk);
|
||||
|
||||
sk=m_alloc_clear(sizeof(*sk));
|
||||
|
||||
rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
|
||||
|
||||
/* We have the revocation key */
|
||||
if(!rc)
|
||||
{
|
||||
size_t n;
|
||||
char *p;
|
||||
u32 sk_keyid[2];
|
||||
PKT_user_id *uid=NULL;
|
||||
PKT_signature *selfsig=NULL;
|
||||
|
||||
any=1;
|
||||
keyid_from_sk(sk,sk_keyid);
|
||||
|
||||
tty_printf("\npub %4u%c/%08lX %s ",
|
||||
nbits_from_pk( pk ),
|
||||
pubkey_letter( pk->pubkey_algo ),
|
||||
(ulong)keyid[1], datestr_from_pk(pk) );
|
||||
|
||||
p = get_user_id( keyid, &n );
|
||||
tty_print_utf8_string( p, n );
|
||||
m_free(p);
|
||||
tty_printf("\n\n");
|
||||
|
||||
tty_printf(_("To be revoked by:\n"));
|
||||
|
||||
tty_printf("\nsec %4u%c/%08lX %s ",
|
||||
nbits_from_sk( sk ),
|
||||
pubkey_letter( sk->pubkey_algo ),
|
||||
(ulong)sk_keyid[1], datestr_from_sk(sk) );
|
||||
|
||||
p = get_user_id( sk_keyid, &n );
|
||||
tty_print_utf8_string( p, n );
|
||||
m_free(p);
|
||||
tty_printf("\n\n");
|
||||
|
||||
if( !cpr_get_answer_is_yes("gen_desig_revoke.okay",
|
||||
_("Create a revocation certificate for this key? ")) )
|
||||
continue;
|
||||
|
||||
/* get the reason for the revocation (this is always v4) */
|
||||
reason = ask_revocation_reason( 1, 0, 1 );
|
||||
if( !reason )
|
||||
continue;
|
||||
|
||||
rc = check_secret_key( sk, 0 );
|
||||
if( rc )
|
||||
continue;
|
||||
|
||||
if( !opt.armor )
|
||||
tty_printf(_("ASCII armored output forced.\n"));
|
||||
|
||||
if( (rc = open_outfile( NULL, 0, &out )) )
|
||||
goto leave;
|
||||
|
||||
afx.what = 1;
|
||||
afx.hdrlines = "Comment: A revocation certificate should follow\n";
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
|
||||
0, 0, 0,
|
||||
revocation_reason_build_cb, reason );
|
||||
if( rc ) {
|
||||
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Spit out a minimal pk as well, since otherwise there is
|
||||
no way to know which key to attach this revocation
|
||||
to. */
|
||||
|
||||
node=find_kbnode(keyblock,PKT_PUBLIC_KEY);
|
||||
if(!node)
|
||||
{
|
||||
rc=G10ERR_GENERAL;
|
||||
log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
pkt = *node->pkt;
|
||||
rc=build_packet(out,&pkt);
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
while(!selfsig)
|
||||
{
|
||||
KBNODE signode;
|
||||
|
||||
node=find_next_kbnode(node,PKT_USER_ID);
|
||||
if(!node)
|
||||
{
|
||||
/* We're out of user IDs - none were
|
||||
self-signed. */
|
||||
if(uid)
|
||||
break;
|
||||
else
|
||||
{
|
||||
rc=G10ERR_GENERAL;
|
||||
log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if(node->pkt->pkt.user_id->attrib_data)
|
||||
continue;
|
||||
|
||||
uid=node->pkt->pkt.user_id;
|
||||
signode=node;
|
||||
|
||||
while((signode=find_next_kbnode(signode,PKT_SIGNATURE)))
|
||||
{
|
||||
if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
|
||||
keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
|
||||
IS_UID_SIG(signode->pkt->pkt.signature))
|
||||
{
|
||||
selfsig=signode->pkt->pkt.signature;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pkt.pkttype = PKT_USER_ID;
|
||||
pkt.pkt.user_id = uid;
|
||||
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if(selfsig)
|
||||
{
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = selfsig;
|
||||
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
/* and issue a usage notice */
|
||||
tty_printf(_("Revocation certificate created.\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!any)
|
||||
log_error(_("no revocation keys found for `%s'\n"),uname);
|
||||
|
||||
leave:
|
||||
if( pk )
|
||||
free_public_key( pk );
|
||||
if( sk )
|
||||
free_secret_key( sk );
|
||||
if( sig )
|
||||
free_seckey_enc( sig );
|
||||
|
||||
if( rc )
|
||||
iobuf_cancel(out);
|
||||
else
|
||||
iobuf_close(out);
|
||||
release_revocation_reason_info( reason );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a revocation certificate for UNAME
|
||||
*/
|
||||
|
@ -78,7 +327,6 @@ gen_revoke( const char *uname )
|
|||
{
|
||||
int rc = 0;
|
||||
armor_filter_context_t afx;
|
||||
compress_filter_context_t zfx;
|
||||
PACKET pkt;
|
||||
PKT_secret_key *sk; /* used as pointer into a kbnode */
|
||||
PKT_public_key *pk = NULL;
|
||||
|
@ -87,34 +335,40 @@ gen_revoke( const char *uname )
|
|||
IOBUF out = NULL;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE node;
|
||||
KEYDB_HANDLE kdbhd;
|
||||
struct revocation_reason_info *reason = NULL;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
|
||||
if( opt.batch ) {
|
||||
log_error(_("sorry, can't do this in batch mode\n"));
|
||||
return GPGERR_GENERAL;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
init_packet( &pkt );
|
||||
|
||||
/* search the userid:
|
||||
* We don't want the whole getkey stuff here but the entire keyblock
|
||||
*/
|
||||
kdbhd = keydb_new (1);
|
||||
classify_user_id (uname, &desc);
|
||||
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
||||
if (rc) {
|
||||
log_error (_("secret key `%s' not found: %s\n"),
|
||||
uname, g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* search the userid */
|
||||
rc = find_secret_keyblock_byname( &keyblock, uname );
|
||||
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||
if( rc ) {
|
||||
log_error(_("secret key for user `%s' not found: %s\n"),
|
||||
uname, gpg_errstr(rc) );
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode( keyblock, PKT_SECRET_KEY );
|
||||
if( !node ) { /* maybe better to use log_bug ? */
|
||||
log_error(_("Oops; secret key not found anymore!\n"));
|
||||
rc = GPGERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
if( !node )
|
||||
BUG ();
|
||||
|
||||
/* fixme: should make a function out of this stuff,
|
||||
* it's used all over the source */
|
||||
|
@ -123,23 +377,25 @@ gen_revoke( const char *uname )
|
|||
tty_printf("\nsec %4u%c/%08lX %s ",
|
||||
nbits_from_sk( sk ),
|
||||
pubkey_letter( sk->pubkey_algo ),
|
||||
sk_keyid[1], datestr_from_sk(sk) );
|
||||
(ulong)sk_keyid[1], datestr_from_sk(sk) );
|
||||
{
|
||||
size_t n;
|
||||
char *p = get_user_id( sk_keyid, &n );
|
||||
tty_print_utf8_string( p, n );
|
||||
gcry_free(p);
|
||||
m_free(p);
|
||||
tty_printf("\n");
|
||||
}
|
||||
pk = gcry_xcalloc( 1, sizeof *pk );
|
||||
pk = m_alloc_clear( sizeof *pk );
|
||||
|
||||
/* FIXME: We should get the public key direct from the secret one */
|
||||
rc = get_pubkey( pk, sk_keyid );
|
||||
if( rc ) {
|
||||
log_error(_("no corresponding public key: %s\n"), gpg_errstr(rc) );
|
||||
log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
if( cmp_public_secret_key( pk, sk ) ) {
|
||||
log_error(_("public key does not match secret key!\n") );
|
||||
rc = GPGERR_GENERAL;
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -150,17 +406,19 @@ gen_revoke( const char *uname )
|
|||
goto leave;
|
||||
}
|
||||
|
||||
/* get the reason for the revocation */
|
||||
reason = ask_revocation_reason( 1, 0, 1 );
|
||||
if( !reason ) { /* user decided to cancel */
|
||||
if(sk->version>=4 || opt.force_v4_certs) {
|
||||
/* get the reason for the revocation */
|
||||
reason = ask_revocation_reason( 1, 0, 1 );
|
||||
if( !reason ) { /* user decided to cancel */
|
||||
rc = 0;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
switch( is_secret_key_protected( sk ) ) {
|
||||
case -1:
|
||||
log_error(_("unknown protection algorithm\n"));
|
||||
rc = GPGERR_PUBKEY_ALGO;
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
break;
|
||||
case 0:
|
||||
tty_printf(_("NOTE: This key is not protected!\n"));
|
||||
|
@ -185,10 +443,10 @@ gen_revoke( const char *uname )
|
|||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
|
||||
revocation_reason_build_cb,
|
||||
reason );
|
||||
opt.force_v4_certs?4:0, 0, 0,
|
||||
revocation_reason_build_cb, reason );
|
||||
if( rc ) {
|
||||
log_error(_("make_keysig_packet failed: %s\n"), gpg_errstr(rc));
|
||||
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
|
||||
goto leave;
|
||||
}
|
||||
init_packet( &pkt );
|
||||
|
@ -197,7 +455,7 @@ gen_revoke( const char *uname )
|
|||
|
||||
rc = build_packet( out, &pkt );
|
||||
if( rc ) {
|
||||
log_error(_("build_packet failed: %s\n"), gpg_errstr(rc) );
|
||||
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
@ -217,6 +475,7 @@ gen_revoke( const char *uname )
|
|||
if( sig )
|
||||
free_seckey_enc( sig );
|
||||
release_kbnode( keyblock );
|
||||
keydb_release (kdbhd);
|
||||
if( rc )
|
||||
iobuf_cancel(out);
|
||||
else
|
||||
|
@ -230,20 +489,22 @@ gen_revoke( const char *uname )
|
|||
struct revocation_reason_info *
|
||||
ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
||||
{
|
||||
int code;
|
||||
int code=-1;
|
||||
char *description = NULL;
|
||||
struct revocation_reason_info *reason;
|
||||
const char *text_0 = _("No reason specified");
|
||||
const char *text_1 = _("Key has been compromised");
|
||||
const char *text_2 = _("Key is superseded");
|
||||
const char *text_3 = _("Key is no longer used");
|
||||
const char *text_4 = _("User ID is non longer valid");
|
||||
const char *text_4 = _("User ID is no longer valid");
|
||||
const char *code_text = NULL;
|
||||
|
||||
do {
|
||||
gcry_free(description);
|
||||
m_free(description);
|
||||
description = NULL;
|
||||
|
||||
tty_printf(_("Please select the reason for the revocation:\n"));
|
||||
tty_printf( " 0 = %s\n", text_0 );
|
||||
if( key_rev )
|
||||
tty_printf(" 1 = %s\n", text_1 );
|
||||
if( key_rev )
|
||||
|
@ -252,29 +513,31 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
|||
tty_printf(" 3 = %s\n", text_3 );
|
||||
if( cert_rev )
|
||||
tty_printf(" 4 = %s\n", text_4 );
|
||||
tty_printf( " 0 = %s\n", _("Cancel") );
|
||||
tty_printf( " Q = %s\n", _("Cancel") );
|
||||
if( hint )
|
||||
tty_printf(_("(Probably you want to select %d here)\n"), hint );
|
||||
|
||||
for(code = 0; !code;) {
|
||||
while(code==-1) {
|
||||
int n;
|
||||
char *answer = cpr_get("ask_revocation_reason.code",
|
||||
_("Your decision? "));
|
||||
trim_spaces( answer );
|
||||
cpr_kill_prompt();
|
||||
if( *answer == 'q' || *answer == 'Q' )
|
||||
n = 0;
|
||||
else if( !isdigit( *answer ) )
|
||||
n = -1;
|
||||
else if( hint && !*answer )
|
||||
if( *answer == 'q' || *answer == 'Q')
|
||||
return NULL; /* cancel */
|
||||
if( hint && !*answer )
|
||||
n = hint;
|
||||
else if(!isdigit( *answer ) )
|
||||
n = -1;
|
||||
else
|
||||
n = atoi(answer);
|
||||
gcry_free(answer);
|
||||
if( !n )
|
||||
return NULL; /* cancel */
|
||||
m_free(answer);
|
||||
if( n == 0 ) {
|
||||
code = 0x00; /* no particular reason */
|
||||
code_text = text_0;
|
||||
}
|
||||
else if( key_rev && n == 1 ) {
|
||||
code = 0x02; /* key has been compromised */
|
||||
code = 0x02; /* key has been compromised */
|
||||
code_text = text_1;
|
||||
}
|
||||
else if( key_rev && n == 2 ) {
|
||||
|
@ -286,7 +549,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
|||
code_text = text_3;
|
||||
}
|
||||
else if( cert_rev && n == 4 ) {
|
||||
code = 0x20; /* uid is non longer valid */
|
||||
code = 0x20; /* uid is no longer valid */
|
||||
code_text = text_4;
|
||||
}
|
||||
else
|
||||
|
@ -300,25 +563,25 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
|||
trim_trailing_ws( answer, strlen(answer) );
|
||||
cpr_kill_prompt();
|
||||
if( !*answer ) {
|
||||
gcry_free(answer);
|
||||
m_free(answer);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
char *p = make_printable_string( answer, strlen(answer), 0 );
|
||||
gcry_free(answer);
|
||||
m_free(answer);
|
||||
answer = p;
|
||||
}
|
||||
|
||||
if( !description )
|
||||
description = gcry_xstrdup(answer);
|
||||
description = m_strdup(answer);
|
||||
else {
|
||||
char *p = gcry_xmalloc( strlen(description) + strlen(answer) + 2 );
|
||||
char *p = m_alloc( strlen(description) + strlen(answer) + 2 );
|
||||
strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
|
||||
gcry_free(description);
|
||||
m_free(description);
|
||||
description = p;
|
||||
}
|
||||
gcry_free(answer);
|
||||
m_free(answer);
|
||||
}
|
||||
|
||||
tty_printf(_("Reason for revocation: %s\n"), code_text );
|
||||
|
@ -330,7 +593,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
|
|||
} while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
|
||||
_("Is this okay? ")) );
|
||||
|
||||
reason = gcry_xmalloc( sizeof *reason );
|
||||
reason = m_alloc( sizeof *reason );
|
||||
reason->code = code;
|
||||
reason->desc = description;
|
||||
return reason;
|
||||
|
@ -340,8 +603,7 @@ void
|
|||
release_revocation_reason_info( struct revocation_reason_info *reason )
|
||||
{
|
||||
if( reason ) {
|
||||
gcry_free( reason->desc );
|
||||
gcry_free( reason );
|
||||
m_free( reason->desc );
|
||||
m_free( reason );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue