1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

More agent support for gpg.

This commit is contained in:
Werner Koch 2010-10-13 15:57:08 +00:00
parent 5a679857ef
commit 54591341a4
33 changed files with 496 additions and 311 deletions

View file

@ -1,3 +1,33 @@
2010-10-13 Werner Koch <wk@g10code.com>
* call-agent.c (start_agent): Send option agent-awareness.
(status_sc_op_failure): Take care of GPG_ERR_FULLY_CANCELED.
* passphrase.c (passphrase_get): Ditto.
* import.c (transfer_secret_keys): Ditto.
* card-util.c (write_sc_op_status): Ditto.
* getkey.c (enum_secret_keys): Rewrite.
* pubkey-enc.c (get_session_key): Skip keys without an encryption
capability. Handle GPG_ERR_FULLY_CANCELED.
* gpg.c: Add option --try-secret-key.
* options.h (struct opt): Add field secret_keys_to_try.
* passphrase.c (next_to_last_passphrase): Remove.
2010-10-12 Werner Koch <wk@g10code.com>
* keygen.c (generate_subkeypair): Check availibility of secret parts.
* keylist.c (print_card_serialno): Change to take a hexified serialno.
(list_keyblock_print): Print serialno and stub key indicators.
(list_keyblock_colon): Ditto.
* getkey.c (have_any_secret_key): Remove. Replace all calls by
agent_probe_any_secret_key.
* gpgv.c (agent_probe_any_secret_key): New.
(agent_get_keyinfo): New.
2010-10-08 Werner Koch <wk@g10code.com>
* gpg.c: Add option --with-keygrip.

View file

@ -99,6 +99,7 @@ status_sc_op_failure (int rc)
case 0:
break;
case GPG_ERR_CANCELED:
case GPG_ERR_FULLY_CANCELED:
write_status_text (STATUS_SC_OP_FAILURE, "1");
break;
case GPG_ERR_BAD_PIN:
@ -142,6 +143,11 @@ start_agent (ctrl_t ctrl, int for_card)
agents. */
assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
NULL, NULL, NULL, NULL, NULL, NULL);
/* Tell the agent about what version we are aware. This is
here used to indirectly enable GPG_ERR_FULLY_CANCELED. */
assuan_transact (agent_ctx, "OPTION agent-awareness=2.1.0",
NULL, NULL, NULL, NULL, NULL, NULL);
}
}

View file

@ -58,6 +58,7 @@ write_sc_op_status (gpg_error_t err)
break;
#if GNUPG_MAJOR_VERSION != 1
case GPG_ERR_CANCELED:
case GPG_ERR_FULLY_CANCELED:
write_status_text (STATUS_SC_OP_FAILURE, "1");
break;
case GPG_ERR_BAD_PIN:

View file

@ -568,8 +568,9 @@ leave:
* first pubkey certificate which has the given name in a user_id. If
* PK has the pubkey algo set, the function will only return a pubkey
* with that algo. If NAMELIST is NULL, the first key is returned.
* The caller should provide storage for the PK. If RET_KB is not
* NULL the function will return the keyblock there. */
* The caller should provide storage for the PK or pass NULL if it is
* not needed. If RET_KB is not NULL the function stores the entire
* keyblock at that address. */
static int
key_byname (GETKEY_CTX *retctx, strlist_t namelist,
PKT_public_key *pk,
@ -1146,12 +1147,13 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
}
/* Get a key by name and store it into PK. If RETCTX is not NULL
* return the search context which needs to be released by the caller
* using getkey_end. If NAME is NULL use the default key (see below).
* On success and if RET_KEYBLOCK is not NULL the found keyblock is
* stored at this address. WANT_SECRET passed as true requires that a
* secret key is available for the selected key.
/* Get a key by name and store it into PK if that is not NULL. If
* RETCTX is not NULL return the search context which needs to be
* released by the caller using getkey_end. If NAME is NULL use the
* default key (see below). On success and if RET_KEYBLOCK is not
* NULL the found keyblock is stored at this address. WANT_SECRET
* passed as true requires that a secret key is available for the
* selected key.
*
* If WANT_SECRET is true and NAME is NULL and a default key has been
* defined that defined key is used. In all other cases the first
@ -2459,7 +2461,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
goto skip;
}
if (want_secret && !have_any_secret_key (NULL, ctx->keyblock))
if (want_secret && agent_probe_any_secret_key (NULL, ctx->keyblock))
goto skip; /* No secret key available. */
/* Warning: node flag bits 0 and 1 should be preserved by
@ -2504,57 +2506,42 @@ found:
/****************
* FIXME: Replace by the generic function
* It does not work as it is right now - it is used at
* one place: to get the key for an anonymous recipient.
*
* set with_subkeys true to include subkeys
* set with_spm true to include secret-parts-missing keys
*
* Enumerate all primary secret keys. Caller must use these procedure:
/*
* Enumerate certain secret keys. Caller must use these procedure:
* 1) create a void pointer and initialize it to NULL
* 2) pass this void pointer by reference to this function
* and provide space for the secret key (pass a buffer for sk)
* 3) call this function as long as it does not return -1
* to indicate EOF.
* 3) call this function as long as it does not return an error.
* The error code GPG_ERR_EOF indicates the end of the listing.
* 4) Always call this function a last time with SK set to NULL,
* so that can free it's context.
*/
int
enum_secret_keys (void **context, PKT_public_key * sk,
int with_subkeys, int with_spm)
gpg_error_t
enum_secret_keys (void **context, PKT_public_key *sk)
{
log_debug ("FIXME: Anonymous recipient does not yet work\n");
return -1;
#if 0
int rc = 0;
gpg_error_t err = 0;
const char *name;
struct
{
int eof;
int first;
KEYDB_HANDLE hd;
KBNODE keyblock;
KBNODE node;
int state;
strlist_t sl;
kbnode_t keyblock;
kbnode_t node;
} *c = *context;
if (!c)
{
/* Make a new context. */
c = xmalloc_clear (sizeof *c);
c = xtrycalloc (1, sizeof *c);
if (!c)
return gpg_error_from_syserror ();
*context = c;
c->hd = keydb_new (1); /*FIXME*/
c->first = 1;
c->keyblock = NULL;
c->node = NULL;
}
if (!sk)
{
/* Free the context. */
keydb_release (c->hd);
release_kbnode (c->keyblock);
xfree (c);
*context = NULL;
@ -2562,48 +2549,79 @@ enum_secret_keys (void **context, PKT_public_key * sk,
}
if (c->eof)
return -1;
return gpg_error (GPG_ERR_EOF);
do
for (;;)
{
/* Get the next secret key from the current keyblock. */
/* Loop until we have a keyblock. */
while (!c->keyblock)
{
/* Loop over the list of secret keys. */
do
{
name = NULL;
switch (c->state)
{
case 0: /* First try to use the --default-key. */
if (opt.def_secret_key && *opt.def_secret_key)
name = opt.def_secret_key;
c->state = 1;
break;
case 1: /* Init list of keys to try. */
c->sl = opt.secret_keys_to_try;
c->state++;
break;
case 2: /* Get next item from list. */
if (c->sl)
{
name = c->sl->d;
c->sl = c->sl->next;
}
else
c->state++;
break;
default: /* No more names to check - stop. */
c->eof = 1;
return gpg_error (GPG_ERR_EOF);
}
}
while (!name || !*name);
err = getkey_byname (NULL, NULL, name, 1, &c->keyblock);
if (err)
{
/* getkey_byname might return a keyblock even in the
error case - I have not checked. Thus better release
it. */
release_kbnode (c->keyblock);
c->keyblock = NULL;
}
else
c->node = c->keyblock;
}
/* Get the next key from the current keyblock. */
for (; c->node; c->node = c->node->next)
{
if ((c->node->pkt->pkttype == PKT_SECRET_KEY
|| (with_subkeys
&& c->node->pkt->pkttype == PKT_SECRET_SUBKEY))
&& !(c->node->pkt->pkt.secret_key->protect.s2k.mode == 1001
&& !with_spm))
if (c->node->pkt->pkttype == PKT_PUBLIC_KEY
|| c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
copy_secret_key (sk, c->node->pkt->pkt.secret_key);
copy_public_key (sk, c->node->pkt->pkt.public_key);
c->node = c->node->next;
return 0; /* Found. */
}
}
}
/* Dispose the keyblock and continue. */
release_kbnode (c->keyblock);
c->keyblock = c->node = NULL;
rc = c->first ? keydb_search_first (c->hd) : keydb_search_next (c->hd);
c->first = 0;
if (rc)
{
keydb_release (c->hd);
c->hd = NULL;
c->eof = 1;
return -1; /* eof */
}
rc = keydb_get_keyblock (c->hd, &c->keyblock);
c->node = c->keyblock;
c->keyblock = NULL;
}
while (!rc);
return rc; /* Error. */
#endif
}
/*********************************************
*********** User ID printing helpers *******
*********************************************/

View file

@ -177,6 +177,7 @@ enum cmd_and_opt_values
oDefRecipient,
oDefRecipientSelf,
oNoDefRecipient,
oTrySecretKey,
oOptions,
oDebug,
oDebugLevel,
@ -460,6 +461,8 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oLocalUser, "local-user",
N_("|USER-ID|use USER-ID to sign or decrypt")),
ARGPARSE_s_s (oTrySecretKey, "try-secret-key", "@"),
ARGPARSE_s_i (oCompress, NULL,
N_("|N|set compress level to N (0 disables)")),
ARGPARSE_s_i (oCompressLevel, "compress-level", "@"),
@ -1622,6 +1625,7 @@ gpgconf_list (const char *configfile)
es_printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
es_printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
es_printf ("try-secret-key:%lu:\n", GC_OPT_FLAG_NONE);
es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
@ -2526,6 +2530,12 @@ main (int argc, char **argv)
sl->flags = 2;
any_explicit_recipient = 1;
break;
case oTrySecretKey:
add_to_strlist2 (&opt.secret_keys_to_try,
pargs.r.ret_str, utf8_strings);
break;
case oTextmodeShort: opt.textmode = 2; break;
case oTextmode: opt.textmode=1; break;
case oNoTextmode: opt.textmode=0; break;

View file

@ -546,3 +546,21 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
(void)pk;
return gpg_error (GPG_ERR_NO_SECKEY);
}
gpg_error_t
agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
{
(void)ctrl;
(void)keyblock;
return gpg_error (GPG_ERR_NO_SECKEY);
}
gpg_error_t
agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
{
(void)ctrl;
(void)hexkeygrip;
*r_serialno = NULL;
return gpg_error (GPG_ERR_NO_SECKEY);
}

View file

@ -362,7 +362,7 @@ import_print_stats (void *hd)
* Read the next keyblock from stream A.
* PENDING_PKT should be initialzed to NULL
* and not chnaged form the caller.
* Retunr: 0 = okay, -1 no more blocks or another errorcode.
* Return: 0 = okay, -1 no more blocks or another errorcode.
*/
static int
read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root )
@ -1142,8 +1142,15 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
stats->count++;
stats->secret_read++;
/* For now we ignore the stub keys becuase we don't have real
support for them in gpg-agent. */
/* We ignore stub keys. The way we handle them in other parts
of the code is by asking the agent whether any secret key is
available for a given keyblock and then concluding that we
have a secret key; all secret (sub)keys of the keyblock the
agent does not know of are then stub keys. This works also
for card stub keys. The learn command or the card-status
command may be used to check with the agent whether a card
has been inserted and a stub key is in turn generated by the
agent. */
if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
continue;
@ -1288,7 +1295,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
write_status (STATUS_RSA_OR_IDEA);
idea_cipher_warn (0);
}
if (gpg_err_code (err) == GPG_ERR_CANCELED)
if (gpg_err_code (err) == GPG_ERR_CANCELED
|| gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
break; /* Don't try the other subkeys. */
}
}

View file

@ -241,11 +241,8 @@ gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk,
kbnode_t *ret_keyblock);
void getkey_end (getkey_ctx_t ctx);
int have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk);
//int enum_secret_keys( void **context, PKT_secret_key *sk,
// int with_subkeys, int with_spm );
void merge_keys_and_selfsig( KBNODE keyblock );
char*get_user_id_string( u32 *keyid );
char*get_user_id_string_native( u32 *keyid );

View file

@ -1638,7 +1638,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
/* See whether we have a matching secret key. */
if (seckey_check)
{
have_seckey = have_any_secret_key (ctrl, keyblock);
have_seckey = !agent_probe_any_secret_key (ctrl, keyblock);
if (have_seckey && !quiet)
tty_printf (_("Secret key is available.\n"));
}

View file

@ -3441,6 +3441,8 @@ generate_subkeypair (KBNODE keyblock)
u32 expire;
unsigned int nbits;
u32 cur_time;
char *hexgrip = NULL;
char *serialno = NULL;
/* Break out the primary key. */
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
@ -3476,37 +3478,16 @@ generate_subkeypair (KBNODE keyblock)
goto leave;
}
#warning ask gpg-agent on the availibility of the secret key
/* if (pri_sk->is_protected && pri_sk->protect.s2k.mode == 1001) */
/* { */
/* tty_printf (_("Secret parts of primary key are not available.\n")); */
/* err = G10ERR_NO_SECKEY; */
/* goto leave; */
/* } */
/* /\* Unprotect to get the passphrase. *\/ */
/* switch (is_secret_key_protected (pri_sk) ) */
/* { */
/* case -1: */
/* err = G10ERR_PUBKEY_ALGO; */
/* break; */
/* case 0: */
/* tty_printf (_("This key is not protected.\n")); */
/* break; */
/* case -2: */
/* tty_printf (_("Secret parts of primary key are stored on-card.\n")); */
/* ask_pass = 1; */
/* break; */
/* default: */
/* tty_printf (_("Key is protected.\n")); */
/* err = check_secret_key ( pri_sk, 0 ); */
/* if (!err) */
/* passphrase = get_last_passphrase(); */
/* break; */
/* } */
/* if (err) */
/* goto leave; */
err = hexkeygrip_from_pk (pri_psk, &hexgrip);
if (err)
goto leave;
if (agent_get_keyinfo (NULL, hexgrip, &serialno))
{
tty_printf (_("Secret parts of primary key are not available.\n"));
goto leave;
}
if (serialno)
tty_printf (_("Secret parts of primary key are stored on-card.\n"));
algo = ask_algo (1, NULL, &use);
assert (algo);
@ -3536,6 +3517,8 @@ generate_subkeypair (KBNODE keyblock)
write_status_text (STATUS_KEY_CREATED, "S");
leave:
xfree (hexgrip);
xfree (serialno);
if (err)
log_error (_("Key generation failed: %s\n"), g10_errstr (err) );
return err;

View file

@ -40,11 +40,12 @@
#include "main.h"
#include "i18n.h"
#include "status.h"
#include "call-agent.h"
static void list_all (int);
static void list_one (strlist_t names, int secret);
static void locate_one (ctrl_t ctrl, strlist_t names);
static void print_card_serialno (PKT_public_key *sk);
static void print_card_serialno (const char *serialno);
struct sig_stats
{
@ -175,6 +176,7 @@ print_pubkey_info (estream_t fp, PKT_public_key * pk)
/* Print basic information of a secret key including the card serial
number information. */
#ifdef ENABLE_CARD_SUPPORT
void
print_card_key_info (estream_t fp, kbnode_t keyblock)
{
@ -224,7 +226,7 @@ print_card_key_info (estream_t fp, kbnode_t keyblock)
/* } */
/* } */
}
#endif /*ENABLE_CARD_SUPPORT*/
/* Flags = 0x01 hashed 0x02 critical. */
@ -444,7 +446,7 @@ list_all (int secret)
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
goto leave;
}
if (secret && !have_any_secret_key (NULL, keyblock))
if (secret && agent_probe_any_secret_key (NULL, keyblock))
; /* Secret key listing requested but this isn't one. */
else
{
@ -757,13 +759,15 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
static void
list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
{
int rc = 0;
int rc;
KBNODE kbctx;
KBNODE node;
PKT_public_key *pk;
struct sig_stats *stats = opaque;
int skip_sigs = 0;
int s2k_char;
char *hexgrip = NULL;
char *serialno = NULL;
/* Get the keyid from the keyblock. */
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
@ -775,10 +779,23 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
}
pk = node->pkt->pkt.public_key;
/* Fixme: Get s2k mode from the agent. */
s2k_char = (/*(sk->protect.s2k.mode == 1001)? '#' :
(sk->protect.s2k.mode == 1002)? '>' : */' ');
if (secret || opt.with_keygrip)
{
rc = hexkeygrip_from_pk (pk, &hexgrip);
if (rc)
log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
}
if (secret)
{
if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
s2k_char = serialno? '>':' ';
else
s2k_char = '#'; /* Key not found. */
}
else
s2k_char = ' ';
check_trustdb_stale ();
@ -822,19 +839,11 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
if (fpr)
print_fingerprint (pk, 0);
if (opt.with_keygrip)
{
char *p;
if (opt.with_keygrip && hexgrip)
es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
if (!hexkeygrip_from_pk (pk, &p))
{
es_fprintf (es_stdout, " Keygrip = %s\n", p);
xfree (p);
}
}
/* FIXME: Change this function to take a PK and ask the agent: */
/* if (secret) print_card_serialno (sk); */
if (serialno)
print_card_serialno (serialno);
if (opt.with_key_data)
print_key_data (pk);
@ -895,10 +904,25 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
else
skip_sigs = 0;
/* Fixme: Get s2k mode from the agent. */
s2k_char = (/*(sk->protect.s2k.mode == 1001)? '#' :
(sk->protect.s2k.mode == 1002)? '>' : */' ');
xfree (serialno); serialno = NULL;
xfree (hexgrip); hexgrip = NULL;
if (secret || opt.with_keygrip)
{
rc = hexkeygrip_from_pk (pk2, &hexgrip);
if (rc)
log_error ("error computing a keygrip: %s\n",
gpg_strerror (rc));
}
if (secret)
{
if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
s2k_char = serialno? '>':' ';
else
s2k_char = '#'; /* Key not found. */
}
else
s2k_char = ' ';
es_fprintf (es_stdout, "%s%c %4u%c/%s %s",
secret? "ssb":"sub",
s2k_char,
@ -926,20 +950,11 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
if (fpr > 1)
{
print_fingerprint (pk2, 0);
/* FIXME: (see above) */
/* if (secret) */
/* print_card_serialno (sk2); */
}
if (opt.with_keygrip)
{
char *p;
if (!hexkeygrip_from_pk (pk2, &p))
{
es_fprintf (es_stdout, " Keygrip = %s\n", p);
xfree (p);
}
if (serialno)
print_card_serialno (serialno);
}
if (opt.with_keygrip && hexgrip)
es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
if (opt.with_key_data)
print_key_data (pk2);
}
@ -1050,6 +1065,8 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
}
}
es_putc ('\n', es_stdout);
xfree (serialno);
xfree (hexgrip);
}
void
@ -1079,7 +1096,7 @@ print_revokers (PKT_public_key * pk)
static void
list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
{
int rc = 0;
int rc;
KBNODE kbctx;
KBNODE node;
PKT_public_key *pk;
@ -1088,6 +1105,9 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
int ulti_hack = 0;
int i;
char *p;
char *hexgrip = NULL;
char *serialno = NULL;
int stubkey;
/* Get the keyid from the keyblock. */
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
@ -1099,6 +1119,15 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
}
pk = node->pkt->pkt.public_key;
if (secret || opt.with_keygrip || opt.with_key_data)
{
rc = hexkeygrip_from_pk (pk, &hexgrip);
if (rc)
log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
}
stubkey = 0;
if (secret && agent_get_keyinfo (NULL, hexgrip, &serialno))
stubkey = 1; /* Key not found. */
keyid_from_pk (pk, keyid);
es_fputs (secret? "sec:":"pub:", es_stdout);
@ -1135,16 +1164,10 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
{
es_putc (':', es_stdout); /* End of field 13. */
es_putc (':', es_stdout); /* End of field 14. */
if (/*FIXME sk->protect.s2k.mode*/1 == 1001)
es_putc ('#', es_stdout); /* Key is just a stub. */
else if (/*FIXME sk->protect.s2k.mode*/1 == 1002)
{
/* Key is stored on an external token (card) or handled by
the gpg-agent. Print the serial number of that token
here. */
/* FIXME: for (i = 0; i < sk->protect.ivlen; i++) */
/* es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
}
if (stubkey)
es_putc ('#', es_stdout);
else if (serialno)
es_fputs(serialno, es_stdout);
es_putc (':', es_stdout); /* End of field 15. */
}
es_putc ('\n', es_stdout);
@ -1154,11 +1177,8 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
print_fingerprint (pk, 0);
if (opt.with_key_data || opt.with_keygrip)
{
if (!hexkeygrip_from_pk (pk, &p))
{
es_fprintf (es_stdout, "grp:::::::::%s:\n", p);
xfree (p);
}
if (hexgrip)
es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
if (opt.with_key_data)
print_key_data (pk);
}
@ -1213,7 +1233,21 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
{
u32 keyid2[2];
PKT_public_key *pk2 = node->pkt->pkt.public_key;
PKT_public_key *pk2;
pk2 = node->pkt->pkt.public_key;
xfree (hexgrip); hexgrip = NULL;
xfree (serialno); serialno = NULL;
if (secret || opt.with_keygrip || opt.with_key_data)
{
rc = hexkeygrip_from_pk (pk2, &hexgrip);
if (rc)
log_error ("error computing a keygrip: %s\n",
gpg_strerror (rc));
}
stubkey = 0;
if (secret && agent_get_keyinfo (NULL, hexgrip, &serialno))
stubkey = 1; /* Key not found. */
keyid_from_pk (pk2, keyid2);
es_fputs (secret? "ssb:":"sub:", es_stdout);
@ -1243,16 +1277,10 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
{
es_putc (':', es_stdout); /* End of field 13. */
es_putc (':', es_stdout); /* End of field 14. */
if (/*FIXME:sk2->protect.s2k.mode*/1 == 1001)
es_putc ('#', es_stdout); /* Key is just a stub. */
else if (/*FIXME: sk2->protect.s2k.mode*/1 == 1002)
{
/* Key is stored on an external token (card) or
handled by the gpg-agent. Print the serial
number of that token here. */
/* FIXME: for (i = 0; i < sk2->protect.ivlen; i++)
es_fprintf (es_stdout, "%02X", sk2->protect.iv[i]); */
}
if (stubkey)
es_putc ('#', es_stdout);
else if (serialno)
es_fputs (serialno, es_stdout);
es_putc (':', es_stdout); /* End of field 15. */
}
es_putc ('\n', es_stdout);
@ -1260,11 +1288,8 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
print_fingerprint (pk2, 0);
if (opt.with_key_data || opt.with_keygrip)
{
if (!hexkeygrip_from_pk (pk2, &p))
{
es_fprintf (es_stdout, "grp:::::::::%s:\n", p);
xfree (p);
}
if (hexgrip)
es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
if (opt.with_key_data)
print_key_data (pk2);
}
@ -1385,6 +1410,9 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
/* fixme: check or list other sigs here */
}
}
xfree (hexgrip);
xfree (serialno);
}
/*
@ -1550,38 +1578,25 @@ print_fingerprint (PKT_public_key *pk, int mode)
/* Print the serial number of an OpenPGP card if available. */
static void
print_card_serialno (PKT_public_key *pk)
print_card_serialno (const char *serialno)
{
log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
/* int i; */
if (!serialno)
return;
if (opt.with_colons)
return; /* Handled elsewhere. */
/* if (!sk) */
/* return; */
/* if (!sk->is_protected || sk->protect.s2k.mode != 1002) */
/* return; /\* Not a card. *\/ */
/* if (opt.with_colons) */
/* return; /\* Handled elsewhere. *\/ */
/* es_fputs (_(" Card serial no. ="), es_stdout); */
/* es_putc (' ', es_stdout); */
/* if (sk->protect.ivlen == 16 */
/* && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6)) */
/* { */
/* /\* This is an OpenPGP card. Just print the relevant part. *\/ */
/* for (i = 8; i < 14; i++) */
/* { */
/* if (i == 10) */
/* es_putc (' ', es_stdout); */
/* es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
/* } */
/* } */
/* else */
/* { */
/* /\* Something is wrong: Print all. *\/ */
/* for (i = 0; i < sk->protect.ivlen; i++) */
/* es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
/* } */
/* es_putc ('\n', es_stdout); */
es_fputs (_(" Card serial no. ="), es_stdout);
es_putc (' ', es_stdout);
if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
{
/* This is an OpenPGP card. Print the relevant part. */
/* Example: D2760001240101010001000003470000 */
/* xxxxyyyyyyyy */
es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
}
else
es_fputs (serialno, es_stdout);
es_putc ('\n', es_stdout);
}

View file

@ -555,11 +555,10 @@ get_signature_count (PKT_public_key *pk)
/* if(agent_scd_getattr("SIG-COUNTER",&info)==0) */
/* return info.sig_counter; */
/* } */
#endif
/* How to do this without a card? */
#else
(void)pk;
return 0;
#endif
}
/* Expand %-strings. Returns a string which must be xfreed. Returns

View file

@ -79,6 +79,8 @@ struct
const char *def_secret_key;
char *def_recipient;
int def_recipient_self;
strlist_t secret_keys_to_try;
int def_cert_level;
int min_cert_level;
int ask_cert_level;

View file

@ -211,17 +211,6 @@ get_last_passphrase()
return p;
}
/* As if we had used the passphrase - make it the last_pw. */
void
next_to_last_passphrase(void)
{
if (next_pw)
{
last_pw=next_pw;
next_pw=NULL;
}
}
/* Here's an interesting question: since this passphrase was passed in
on the command line, is there really any point in using secure
memory for it? I'm going with 'yes', since it doesn't hurt, and
@ -407,7 +396,8 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat,
if (!rc)
;
else if ( gpg_err_code (rc) == GPG_ERR_CANCELED )
else if (gpg_err_code (rc) == GPG_ERR_CANCELED
|| gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
{
log_info (_("cancelled by user\n") );
if (canceled)

View file

@ -94,14 +94,13 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek)
{
void *enum_context = NULL;
u32 keyid[2];
char *p;
for (;;)
{
if (sk)
free_public_key (sk);
sk = xmalloc_clear (sizeof *sk);
rc = -1; /* FIXME:enum_secret_keys (&enum_context, sk, 1, 0);*/
rc = enum_secret_keys (&enum_context, sk);
if (rc)
{
rc = G10ERR_NO_SECKEY;
@ -109,42 +108,22 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek)
}
if (sk->pubkey_algo != k->pubkey_algo)
continue;
if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
continue;
keyid_from_pk (sk, keyid);
log_info (_("anonymous recipient; trying secret key %s ...\n"),
keystr (keyid));
if (!opt.try_all_secrets && !is_status_enabled ())
{
p = get_last_passphrase ();
set_next_passphrase (p);
xfree (p);
}
/* rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /\* ask */
/* only */
/* once *\/ */
/* if( !rc ) */
{
rc = get_it (k, dek, sk, keyid);
/* Successfully checked the secret key (either it was a
card, had no passphrase, or had the right passphrase)
but couldn't decrypt the session key, so thus that key
is not the anonymous recipient. Move the next
passphrase into last for the next round. We only do
this if the secret key was successfully checked as in
the normal case, check_secret_key handles this for us
via passphrase_to_dek. */
if (rc)
next_to_last_passphrase ();
}
rc = get_it (k, dek, sk, keyid);
if (!rc)
{
log_info (_("okay, we are the anonymous recipient.\n"));
break;
}
else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
break; /* Don't try any more secret keys. */
}
enum_secret_keys (&enum_context, NULL, 0, 0); /* free context */
enum_secret_keys (&enum_context, NULL); /* free context */
}
leave: