mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
g10: Move enum_secret_keys to skclist.c.
* g10/getkey.c (enum_secret_keys): Move to... * g10/skclist.c (enum_secret_keys): ... here. -- The function enum_secret_keys is not used by gpgv.c, but it is in getkey.c. Extending enum_secret_keys will require change of gpgv.c, so moving the function to the file for gpg is better. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
6bb93fc295
commit
03a8de7def
197
g10/getkey.c
197
g10/getkey.c
@ -3947,203 +3947,6 @@ lookup (ctrl_t ctrl, getkey_ctx_t ctx, int want_secret,
|
||||
}
|
||||
|
||||
|
||||
/* Enumerate some secret keys (specifically, those specified with
|
||||
* --default-key and --try-secret-key). Use the following procedure:
|
||||
*
|
||||
* 1) Initialize a void pointer to NULL
|
||||
* 2) Pass a reference to this pointer to this function (content)
|
||||
* and provide space for the secret key (sk)
|
||||
* 3) Call this function as long as it does not return an error (or
|
||||
* until you are done). The error code GPG_ERR_EOF indicates the
|
||||
* end of the listing.
|
||||
* 4) Call this function a last time with SK set to NULL,
|
||||
* so that can free it's context.
|
||||
*
|
||||
* In pseudo-code:
|
||||
*
|
||||
* void *ctx = NULL;
|
||||
* PKT_public_key *sk = xmalloc_clear (sizeof (*sk));
|
||||
*
|
||||
* while ((err = enum_secret_keys (&ctx, sk)))
|
||||
* { // Process SK.
|
||||
* if (done)
|
||||
* break;
|
||||
* sk = xmalloc_clear (sizeof (*sk));
|
||||
* }
|
||||
*
|
||||
* // Release any resources used by CTX.
|
||||
* enum_secret_keys (&ctx, NULL);
|
||||
*
|
||||
* if (gpg_err_code (err) != GPG_ERR_EOF)
|
||||
* ; // An error occurred.
|
||||
*/
|
||||
gpg_error_t
|
||||
enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
const char *name;
|
||||
kbnode_t keyblock;
|
||||
struct
|
||||
{
|
||||
int eof;
|
||||
int state;
|
||||
strlist_t sl;
|
||||
kbnode_t keyblock;
|
||||
kbnode_t node;
|
||||
getkey_ctx_t ctx;
|
||||
pubkey_t results;
|
||||
} *c = *context;
|
||||
|
||||
if (!c)
|
||||
{
|
||||
/* Make a new context. */
|
||||
c = xtrycalloc (1, sizeof *c);
|
||||
if (!c)
|
||||
return gpg_error_from_syserror ();
|
||||
*context = c;
|
||||
}
|
||||
|
||||
if (!sk)
|
||||
{
|
||||
/* Free the context. */
|
||||
pubkeys_free (c->results);
|
||||
release_kbnode (c->keyblock);
|
||||
getkey_end (ctrl, c->ctx);
|
||||
xfree (c);
|
||||
*context = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c->eof)
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Loop until we have a keyblock. */
|
||||
while (!c->keyblock)
|
||||
{
|
||||
/* Loop over the list of secret keys. */
|
||||
do
|
||||
{
|
||||
name = NULL;
|
||||
keyblock = NULL;
|
||||
switch (c->state)
|
||||
{
|
||||
case 0: /* First try to use the --default-key. */
|
||||
name = parse_def_secret_key (ctrl);
|
||||
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;
|
||||
|
||||
case 3: /* Init search context to enum all secret keys. */
|
||||
err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1,
|
||||
&keyblock);
|
||||
if (err)
|
||||
{
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
getkey_end (ctrl, c->ctx);
|
||||
c->ctx = NULL;
|
||||
}
|
||||
c->state++;
|
||||
break;
|
||||
|
||||
case 4: /* Get next item from the context. */
|
||||
if (c->ctx)
|
||||
{
|
||||
err = getkey_next (ctrl, c->ctx, NULL, &keyblock);
|
||||
if (err)
|
||||
{
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
getkey_end (ctrl, c->ctx);
|
||||
c->ctx = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
c->state++;
|
||||
break;
|
||||
|
||||
default: /* No more names to check - stop. */
|
||||
c->eof = 1;
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
}
|
||||
}
|
||||
while ((!name || !*name) && !keyblock);
|
||||
|
||||
if (keyblock)
|
||||
c->node = c->keyblock = keyblock;
|
||||
else
|
||||
{
|
||||
err = getkey_byname (ctrl, 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_PUBLIC_KEY
|
||||
|| c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
pubkey_t r;
|
||||
|
||||
/* Skip this candidate if it's already enumerated. */
|
||||
for (r = c->results; r; r = r->next)
|
||||
if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key))
|
||||
break;
|
||||
if (r)
|
||||
continue;
|
||||
|
||||
copy_public_key (sk, c->node->pkt->pkt.public_key);
|
||||
c->node = c->node->next;
|
||||
|
||||
r = xtrycalloc (1, sizeof (*r));
|
||||
if (!r)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
free_public_key (sk);
|
||||
return err;
|
||||
}
|
||||
|
||||
r->pk = sk;
|
||||
r->keyblock = NULL;
|
||||
r->next = c->results;
|
||||
c->results = r;
|
||||
|
||||
return 0; /* Found. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispose the keyblock and continue. */
|
||||
release_kbnode (c->keyblock);
|
||||
c->keyblock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gpg_error_t
|
||||
get_seckey_default_or_card (ctrl_t ctrl, PKT_public_key *pk,
|
||||
const byte *fpr_card, size_t fpr_len)
|
||||
|
198
g10/skclist.c
198
g10/skclist.c
@ -286,3 +286,201 @@ build_sk_list (ctrl_t ctrl,
|
||||
*ret_sk_list = sk_list;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Enumerate some secret keys (specifically, those specified with
|
||||
* --default-key and --try-secret-key). Use the following procedure:
|
||||
*
|
||||
* 1) Initialize a void pointer to NULL
|
||||
* 2) Pass a reference to this pointer to this function (content)
|
||||
* and provide space for the secret key (sk)
|
||||
* 3) Call this function as long as it does not return an error (or
|
||||
* until you are done). The error code GPG_ERR_EOF indicates the
|
||||
* end of the listing.
|
||||
* 4) Call this function a last time with SK set to NULL,
|
||||
* so that can free it's context.
|
||||
*
|
||||
* In pseudo-code:
|
||||
*
|
||||
* void *ctx = NULL;
|
||||
* PKT_public_key *sk = xmalloc_clear (sizeof (*sk));
|
||||
*
|
||||
* while ((err = enum_secret_keys (&ctx, sk)))
|
||||
* { // Process SK.
|
||||
* if (done)
|
||||
* break;
|
||||
* sk = xmalloc_clear (sizeof (*sk));
|
||||
* }
|
||||
*
|
||||
* // Release any resources used by CTX.
|
||||
* enum_secret_keys (&ctx, NULL);
|
||||
*
|
||||
* if (gpg_err_code (err) != GPG_ERR_EOF)
|
||||
* ; // An error occurred.
|
||||
*/
|
||||
gpg_error_t
|
||||
enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
const char *name;
|
||||
kbnode_t keyblock;
|
||||
struct
|
||||
{
|
||||
int eof;
|
||||
int state;
|
||||
strlist_t sl;
|
||||
kbnode_t keyblock;
|
||||
kbnode_t node;
|
||||
getkey_ctx_t ctx;
|
||||
pubkey_t results;
|
||||
} *c = *context;
|
||||
|
||||
if (!c)
|
||||
{
|
||||
/* Make a new context. */
|
||||
c = xtrycalloc (1, sizeof *c);
|
||||
if (!c)
|
||||
return gpg_error_from_syserror ();
|
||||
*context = c;
|
||||
}
|
||||
|
||||
if (!sk)
|
||||
{
|
||||
/* Free the context. */
|
||||
pubkeys_free (c->results);
|
||||
release_kbnode (c->keyblock);
|
||||
getkey_end (ctrl, c->ctx);
|
||||
xfree (c);
|
||||
*context = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c->eof)
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Loop until we have a keyblock. */
|
||||
while (!c->keyblock)
|
||||
{
|
||||
/* Loop over the list of secret keys. */
|
||||
do
|
||||
{
|
||||
name = NULL;
|
||||
keyblock = NULL;
|
||||
switch (c->state)
|
||||
{
|
||||
case 0: /* First try to use the --default-key. */
|
||||
name = parse_def_secret_key (ctrl);
|
||||
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;
|
||||
|
||||
case 3: /* Init search context to enum all secret keys. */
|
||||
err = getkey_bynames (ctrl, &c->ctx, NULL, NULL, 1,
|
||||
&keyblock);
|
||||
if (err)
|
||||
{
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
getkey_end (ctrl, c->ctx);
|
||||
c->ctx = NULL;
|
||||
}
|
||||
c->state++;
|
||||
break;
|
||||
|
||||
case 4: /* Get next item from the context. */
|
||||
if (c->ctx)
|
||||
{
|
||||
err = getkey_next (ctrl, c->ctx, NULL, &keyblock);
|
||||
if (err)
|
||||
{
|
||||
release_kbnode (keyblock);
|
||||
keyblock = NULL;
|
||||
getkey_end (ctrl, c->ctx);
|
||||
c->ctx = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
c->state++;
|
||||
break;
|
||||
|
||||
default: /* No more names to check - stop. */
|
||||
c->eof = 1;
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
}
|
||||
}
|
||||
while ((!name || !*name) && !keyblock);
|
||||
|
||||
if (keyblock)
|
||||
c->node = c->keyblock = keyblock;
|
||||
else
|
||||
{
|
||||
err = getkey_byname (ctrl, 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_PUBLIC_KEY
|
||||
|| c->node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
{
|
||||
pubkey_t r;
|
||||
|
||||
/* Skip this candidate if it's already enumerated. */
|
||||
for (r = c->results; r; r = r->next)
|
||||
if (!cmp_public_keys (r->pk, c->node->pkt->pkt.public_key))
|
||||
break;
|
||||
if (r)
|
||||
continue;
|
||||
|
||||
copy_public_key (sk, c->node->pkt->pkt.public_key);
|
||||
c->node = c->node->next;
|
||||
|
||||
r = xtrycalloc (1, sizeof (*r));
|
||||
if (!r)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
free_public_key (sk);
|
||||
return err;
|
||||
}
|
||||
|
||||
r->pk = sk;
|
||||
r->keyblock = NULL;
|
||||
r->next = c->results;
|
||||
c->results = r;
|
||||
|
||||
return 0; /* Found. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispose the keyblock and continue. */
|
||||
release_kbnode (c->keyblock);
|
||||
c->keyblock = NULL;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user