From 03a8de7def4195b9accde47c1dcb84279361936d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 12 Jun 2018 10:36:59 +0900 Subject: [PATCH] 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 --- g10/getkey.c | 197 ------------------------------------------------- g10/skclist.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 197 deletions(-) diff --git a/g10/getkey.c b/g10/getkey.c index e9e98b1fc..41afeb9e8 100644 --- a/g10/getkey.c +++ b/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) diff --git a/g10/skclist.c b/g10/skclist.c index 78890dc42..f8c8cadf8 100644 --- a/g10/skclist.c +++ b/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; + } +}