mirror of
git://git.gnupg.org/gnupg.git
synced 2025-06-09 17:41:05 +02:00
g10: Improve documentation and comments for getkey.c.
* g10/getkey.c: Improve documentation and comments for most functions. Move documentation for public functions from here... * g10/keydb.h: ... to here. -- Signed-off-by: Neal H. Walfield <neal@g10code.com>.
This commit is contained in:
parent
7333e704ef
commit
cab581c486
498
g10/getkey.c
498
g10/getkey.c
@ -49,12 +49,39 @@
|
|||||||
|
|
||||||
struct getkey_ctx_s
|
struct getkey_ctx_s
|
||||||
{
|
{
|
||||||
|
/* Part of the search criteria: whether the search is an exact
|
||||||
|
search or not. A search that is exact requires that a key or
|
||||||
|
subkey meet all of the specified criteria. A search that is not
|
||||||
|
exact allows selecting a different key or subkey from the
|
||||||
|
keyblock that matched the critera. Further, an exact search
|
||||||
|
returns the key or subkey that matched whereas a non-exact search
|
||||||
|
typically returns the primary key. See finish_lookup for
|
||||||
|
details. */
|
||||||
int exact;
|
int exact;
|
||||||
int want_secret; /* The caller requested only secret keys. */
|
|
||||||
|
/* Part of the search criteria: Whether the caller only wants keys
|
||||||
|
with an available secret key. This is used by getkey_next to get
|
||||||
|
the next result with the same initial criteria. */
|
||||||
|
int want_secret;
|
||||||
|
|
||||||
|
/* Part of the search criteria: The type of the requested key. A
|
||||||
|
mask of PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT.
|
||||||
|
If non-zero, then for a key to match, it must implement one of
|
||||||
|
the required uses. */
|
||||||
int req_usage;
|
int req_usage;
|
||||||
|
|
||||||
|
/* The database handle. */
|
||||||
KEYDB_HANDLE kr_handle;
|
KEYDB_HANDLE kr_handle;
|
||||||
|
|
||||||
|
/* Whether we should call xfree() on the context when the context is
|
||||||
|
released using getkey_end()). */
|
||||||
int not_allocated;
|
int not_allocated;
|
||||||
|
|
||||||
|
/* Part of the search criteria: The low-level search specification
|
||||||
|
as passed to keydb_search. */
|
||||||
int nitems;
|
int nitems;
|
||||||
|
/* This must be the last element in the structure. When we allocate
|
||||||
|
the structure, we allocate it so that ITEMS can hold NITEMS. */
|
||||||
KEYDB_SEARCH_DESC items[1];
|
KEYDB_SEARCH_DESC items[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,6 +151,7 @@ print_stats ()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
void
|
void
|
||||||
cache_public_key (PKT_public_key * pk)
|
cache_public_key (PKT_public_key * pk)
|
||||||
{
|
{
|
||||||
@ -207,7 +235,7 @@ user_id_not_found_utf8 (void)
|
|||||||
|
|
||||||
/* Return the user ID from the given keyblock.
|
/* Return the user ID from the given keyblock.
|
||||||
* We use the primary uid flag which has been set by the merge_selfsigs
|
* We use the primary uid flag which has been set by the merge_selfsigs
|
||||||
* function. The returned value is only valid as long as then given
|
* function. The returned value is only valid as long as the given
|
||||||
* keyblock is not changed. */
|
* keyblock is not changed. */
|
||||||
static const char *
|
static const char *
|
||||||
get_primary_uid (KBNODE keyblock, size_t * uidlen)
|
get_primary_uid (KBNODE keyblock, size_t * uidlen)
|
||||||
@ -311,6 +339,7 @@ cache_user_id (KBNODE keyblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
void
|
void
|
||||||
getkey_disable_caches ()
|
getkey_disable_caches ()
|
||||||
{
|
{
|
||||||
@ -347,9 +376,8 @@ pk_from_block (GETKEY_CTX ctx, PKT_public_key * pk, KBNODE keyblock,
|
|||||||
copy_public_key (pk, a->pkt->pkt.public_key);
|
copy_public_key (pk, a->pkt->pkt.public_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a public key and store it into the allocated pk can be called
|
|
||||||
* with PK set to NULL to just read it into some internal
|
/* For documentation see keydb.h. */
|
||||||
* structures. */
|
|
||||||
int
|
int
|
||||||
get_pubkey (PKT_public_key * pk, u32 * keyid)
|
get_pubkey (PKT_public_key * pk, u32 * keyid)
|
||||||
{
|
{
|
||||||
@ -366,6 +394,8 @@ get_pubkey (PKT_public_key * pk, u32 * keyid)
|
|||||||
for (ce = pk_cache; ce; ce = ce->next)
|
for (ce = pk_cache; ce; ce = ce->next)
|
||||||
{
|
{
|
||||||
if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
|
if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
|
||||||
|
/* XXX: We don't check PK->REQ_USAGE here, but if we don't
|
||||||
|
read from the cache, we do check it! */
|
||||||
{
|
{
|
||||||
copy_public_key (pk, ce->pk);
|
copy_public_key (pk, ce->pk);
|
||||||
return 0;
|
return 0;
|
||||||
@ -417,10 +447,7 @@ leave:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get a public key and store it into the allocated pk. This function
|
/* For documentation see keydb.h. */
|
||||||
differs from get_pubkey() in that it does not do a check of the key
|
|
||||||
to avoid recursion. It should be used only in very certain cases.
|
|
||||||
It will only retrieve primary keys. */
|
|
||||||
int
|
int
|
||||||
get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
|
get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
|
||||||
{
|
{
|
||||||
@ -485,6 +512,7 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
KBNODE
|
KBNODE
|
||||||
get_pubkeyblock (u32 * keyid)
|
get_pubkeyblock (u32 * keyid)
|
||||||
{
|
{
|
||||||
@ -507,13 +535,7 @@ get_pubkeyblock (u32 * keyid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a public key and store it into PK. This functions check that a
|
|
||||||
* corresponding secret key is available. With no secret key it does
|
|
||||||
* not succeeed.
|
|
||||||
*/
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
get_seckey (PKT_public_key *pk, u32 *keyid)
|
get_seckey (PKT_public_key *pk, u32 *keyid)
|
||||||
{
|
{
|
||||||
@ -546,6 +568,8 @@ get_seckey (PKT_public_key *pk, u32 *keyid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Skip unusable keys. A key is unusable if it is revoked, expired or
|
||||||
|
disabled or if the selected user id is revoked or expired. */
|
||||||
static int
|
static int
|
||||||
skip_unusable (void *dummy, u32 * keyid, int uid_no)
|
skip_unusable (void *dummy, u32 * keyid, int uid_no)
|
||||||
{
|
{
|
||||||
@ -601,13 +625,48 @@ leave:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Try to get the pubkey by the userid. This function looks for the
|
/* Search for keys matching some criteria.
|
||||||
* 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
|
If RETCTX is not NULL, then the constructed context is returned in
|
||||||
* with that algo. If NAMELIST is NULL, the first key is returned.
|
*RETCTX so that getpubkey_next can be used to get subsequent
|
||||||
* The caller should provide storage for the PK or pass NULL if it is
|
results. In this case, getkey_end() must be used to free the
|
||||||
* not needed. If RET_KB is not NULL the function stores the entire
|
search context. If RETCTX is not NULL, then RET_KDBHD must be
|
||||||
* keyblock at that address. */
|
NULL.
|
||||||
|
|
||||||
|
If NAMELIST is not NULL, then a search query is constructed using
|
||||||
|
classify_user_id on each of the strings in the list. (Recall: the
|
||||||
|
database does an OR of the terms, not an AND.) If NAMELIST is
|
||||||
|
NULL, then all results are returned.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the first result is returned
|
||||||
|
in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is
|
||||||
|
set, it is used to filter the search results. See the
|
||||||
|
documentation for finish_lookup to understand exactly how this is
|
||||||
|
used. Note: The self-signed data has already been merged into the
|
||||||
|
public key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
If WANT_SECRET is set, then only keys with an available secret key
|
||||||
|
(either locally or via key registered on a smartcard) are returned.
|
||||||
|
|
||||||
|
If INCLUDE_UNUSABLE is set, then unusable keys (see the
|
||||||
|
documentation for skip_unusable for an exact definition) are
|
||||||
|
skipped unless they are looked up by key id or by fingerprint.
|
||||||
|
|
||||||
|
If RET_KB is not NULL, the keyblock is returned in *RET_KB. This
|
||||||
|
should be freed using release_kbnode().
|
||||||
|
|
||||||
|
If RET_KDBHD is not NULL, then the new database handle used to
|
||||||
|
conduct the search is returned in *RET_KDBHD. This can be used to
|
||||||
|
get subsequent results using keydb_search_next. Note: in this
|
||||||
|
case, no advanced filtering is done for subsequent results (e.g.,
|
||||||
|
WANT_SECRET and PK->REQ_USAGE are not respected).
|
||||||
|
|
||||||
|
This function returns 0 on success. Otherwise, an error code is
|
||||||
|
returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY
|
||||||
|
(if want_secret is set) is returned if the key is not found. */
|
||||||
static int
|
static int
|
||||||
key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
||||||
PKT_public_key *pk,
|
PKT_public_key *pk,
|
||||||
@ -632,6 +691,7 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
|||||||
*ret_kdbhd = NULL;
|
*ret_kdbhd = NULL;
|
||||||
|
|
||||||
if (!namelist)
|
if (!namelist)
|
||||||
|
/* No search terms: iterate over the whole DB. */
|
||||||
{
|
{
|
||||||
ctx = xmalloc_clear (sizeof *ctx);
|
ctx = xmalloc_clear (sizeof *ctx);
|
||||||
ctx->nitems = 1;
|
ctx->nitems = 1;
|
||||||
@ -645,6 +705,9 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
|||||||
for (n = 0, r = namelist; r; r = r->next)
|
for (n = 0, r = namelist; r; r = r->next)
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
|
/* CTX has space for a single search term at the end. Thus, we
|
||||||
|
need to allocate sizeof *CTX plus (n - 1) sizeof
|
||||||
|
CTX->ITEMS. */
|
||||||
ctx = xmalloc_clear (sizeof *ctx + (n - 1) * sizeof ctx->items);
|
ctx = xmalloc_clear (sizeof *ctx + (n - 1) * sizeof ctx->items);
|
||||||
ctx->nitems = n;
|
ctx->nitems = n;
|
||||||
|
|
||||||
@ -705,14 +768,7 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
/* Find a public key from NAME and return the keyblock or the key. If
|
|
||||||
ret_kdb is not NULL, the KEYDB handle used to locate this keyblock
|
|
||||||
is returned and the caller is responsible for closing it. If a key
|
|
||||||
was not found (or if local search has been disabled) and NAME is a
|
|
||||||
valid RFC822 mailbox and --auto-key-locate has been enabled, we try
|
|
||||||
to import the key via the online mechanisms defined by
|
|
||||||
--auto-key-locate. */
|
|
||||||
int
|
int
|
||||||
get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||||
const char *name, KBNODE * ret_keyblock,
|
const char *name, KBNODE * ret_keyblock,
|
||||||
@ -728,25 +784,38 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
if (retctx)
|
if (retctx)
|
||||||
*retctx = NULL;
|
*retctx = NULL;
|
||||||
|
|
||||||
|
/* Does NAME appear to be a mailbox (mail address)? */
|
||||||
is_mbox = is_valid_mailbox (name);
|
is_mbox = is_valid_mailbox (name);
|
||||||
|
|
||||||
/* Check whether the default local search has been disabled.
|
/* The auto-key-locate feature works as follows: there are a number
|
||||||
This is the case if either the "nodefault" or the "local" keyword
|
of methods to look up keys. By default, the local keyring is
|
||||||
are in the list of auto key locate mechanisms.
|
tried first. Then, each method listed in the --auto-key-locate is
|
||||||
|
tried in the order it appears.
|
||||||
|
|
||||||
ANYLOCALFIRST is set if the search order has the local method
|
This can be changed as follows:
|
||||||
before any other or if "local" is used first by default. This
|
|
||||||
makes sure that if a RETCTX is used it is only set if a local
|
- if nodefault appears anywhere in the list of options, then
|
||||||
search has precedence over the other search methods and only then
|
the local keyring is not tried first, or,
|
||||||
a followup call to get_pubkey_next shall succeed. */
|
|
||||||
|
- if local appears anywhere in the list of options, then the
|
||||||
|
local keyring is not tried first, but in the order in which
|
||||||
|
it was listed in the --auto-key-locate option.
|
||||||
|
|
||||||
|
Note: we only save the search context in RETCTX if the local
|
||||||
|
method is the first method tried (either explicitly or
|
||||||
|
implicitly). */
|
||||||
if (!no_akl)
|
if (!no_akl)
|
||||||
|
/* auto-key-locate is enabled. */
|
||||||
{
|
{
|
||||||
|
/* nodefault is true if "nodefault" or "local" appear. */
|
||||||
for (akl = opt.auto_key_locate; akl; akl = akl->next)
|
for (akl = opt.auto_key_locate; akl; akl = akl->next)
|
||||||
if (akl->type == AKL_NODEFAULT || akl->type == AKL_LOCAL)
|
if (akl->type == AKL_NODEFAULT || akl->type == AKL_LOCAL)
|
||||||
{
|
{
|
||||||
nodefault = 1;
|
nodefault = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* anylocalfirst is true if "local" appears before any other
|
||||||
|
search methods (except "nodefault"). */
|
||||||
for (akl = opt.auto_key_locate; akl; akl = akl->next)
|
for (akl = opt.auto_key_locate; akl; akl = akl->next)
|
||||||
if (akl->type != AKL_NODEFAULT)
|
if (akl->type != AKL_NODEFAULT)
|
||||||
{
|
{
|
||||||
@ -757,14 +826,23 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!nodefault)
|
if (!nodefault)
|
||||||
|
/* "nodefault" didn't occur. Thus, "local" is implicitly the
|
||||||
|
first method to try. */
|
||||||
anylocalfirst = 1;
|
anylocalfirst = 1;
|
||||||
|
|
||||||
if (nodefault && is_mbox)
|
if (nodefault && is_mbox)
|
||||||
|
/* Either "nodefault" or "local" (explicitly) appeared in the auto
|
||||||
|
key locate list and NAME appears to be an email address. Don't
|
||||||
|
try the local keyring. */
|
||||||
{
|
{
|
||||||
/* Nodefault but a mailbox - let the AKL locate the key. */
|
|
||||||
rc = GPG_ERR_NO_PUBKEY;
|
rc = GPG_ERR_NO_PUBKEY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
/* Either "nodefault" and "local" don't appear in the auto key
|
||||||
|
locate list (in which case we try the local keyring first) or
|
||||||
|
NAME does not appear to be an email address (in which case we
|
||||||
|
only try the local keyring). In this case, lookup NAME in the
|
||||||
|
local keyring. */
|
||||||
{
|
{
|
||||||
add_to_strlist (&namelist, name);
|
add_to_strlist (&namelist, name);
|
||||||
rc = key_byname (retctx, namelist, pk, 0,
|
rc = key_byname (retctx, namelist, pk, 0,
|
||||||
@ -774,6 +852,10 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
/* If the requested name resembles a valid mailbox and automatic
|
/* If the requested name resembles a valid mailbox and automatic
|
||||||
retrieval has been enabled, we try to import the key. */
|
retrieval has been enabled, we try to import the key. */
|
||||||
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && !no_akl && is_mbox)
|
if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY && !no_akl && is_mbox)
|
||||||
|
/* NAME wasn't present in the local keyring (or we didn't try the
|
||||||
|
local keyring). Since the auto key locate feature is enabled
|
||||||
|
and NAME appears to be an email address, try the auto locate
|
||||||
|
feature. */
|
||||||
{
|
{
|
||||||
for (akl = opt.auto_key_locate; akl; akl = akl->next)
|
for (akl = opt.auto_key_locate; akl; akl = akl->next)
|
||||||
{
|
{
|
||||||
@ -885,6 +967,8 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
add_to_strlist (&namelist, fpr_string);
|
add_to_strlist (&namelist, fpr_string);
|
||||||
}
|
}
|
||||||
else if (!rc && !fpr && !did_key_byname)
|
else if (!rc && !fpr && !did_key_byname)
|
||||||
|
/* The acquisition method said no failure occured, but it
|
||||||
|
didn't return a fingerprint. That's a failure. */
|
||||||
{
|
{
|
||||||
no_fingerprint = 1;
|
no_fingerprint = 1;
|
||||||
rc = GPG_ERR_NO_PUBKEY;
|
rc = GPG_ERR_NO_PUBKEY;
|
||||||
@ -893,6 +977,10 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
fpr = NULL;
|
fpr = NULL;
|
||||||
|
|
||||||
if (!rc && !did_key_byname)
|
if (!rc && !did_key_byname)
|
||||||
|
/* There was no error and we didn't do a local lookup.
|
||||||
|
This means that we imported a key into the local
|
||||||
|
keyring. Try to read the imported key from the
|
||||||
|
keyring. */
|
||||||
{
|
{
|
||||||
if (retctx)
|
if (retctx)
|
||||||
{
|
{
|
||||||
@ -930,17 +1018,11 @@ get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Search for a key with the given fingerprint. The caller need to
|
/* For documentation see keydb.h.
|
||||||
* prove an allocated public key object at PK. If R_KEYBLOCK is not
|
|
||||||
* NULL the entire keyblock is stored there and the caller needs to
|
FIXME: We should replace this with the _byname function. This can
|
||||||
* call release_kbnode() on it. Note that this function does an exact
|
be done by creating a userID conforming to the unified fingerprint
|
||||||
* search and thus the public key stored at PK may be a copy of a
|
style. */
|
||||||
* subkey.
|
|
||||||
*
|
|
||||||
* FIXME:
|
|
||||||
* We should replace this with the _byname function. This can be done
|
|
||||||
* by creating a userID conforming to the unified fingerprint style.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
|
get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
|
||||||
const byte * fprint, size_t fprint_len)
|
const byte * fprint, size_t fprint_len)
|
||||||
@ -981,11 +1063,7 @@ get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get a public key and store it into the allocated pk. This function
|
/* For documentation see keydb.h. */
|
||||||
differs from get_pubkey_byfprint() in that it does not do a check
|
|
||||||
of the key to avoid recursion. It should be used only in very
|
|
||||||
certain cases. PK may be NULL to check just for the existance of
|
|
||||||
the key. */
|
|
||||||
int
|
int
|
||||||
get_pubkey_byfprint_fast (PKT_public_key * pk,
|
get_pubkey_byfprint_fast (PKT_public_key * pk,
|
||||||
const byte * fprint, size_t fprint_len)
|
const byte * fprint, size_t fprint_len)
|
||||||
@ -1029,9 +1107,7 @@ get_pubkey_byfprint_fast (PKT_public_key * pk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get a secret key by NAME and store it into PK. If NAME is NULL use
|
/* For documentation see keydb.h. */
|
||||||
* the default key. This functions checks that a corresponding secret
|
|
||||||
* key is available. With no secret key it does not succeeed. */
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
get_seckey_default (PKT_public_key *pk)
|
get_seckey_default (PKT_public_key *pk)
|
||||||
{
|
{
|
||||||
@ -1051,8 +1127,7 @@ get_seckey_default (PKT_public_key *pk)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The new function to return a key.
|
/* For documentation see keydb.h. */
|
||||||
FIXME: Document it. */
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||||
strlist_t names, int want_secret, kbnode_t *ret_keyblock)
|
strlist_t names, int want_secret, kbnode_t *ret_keyblock)
|
||||||
@ -1062,23 +1137,7 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get a key by name and store it into PK if that is not NULL. If
|
/* For documentation see keydb.h. */
|
||||||
* 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
|
|
||||||
* available key is used.
|
|
||||||
*
|
|
||||||
* FIXME: Explain what is up with unusable keys.
|
|
||||||
*
|
|
||||||
* FIXME: We also have the get_pubkey_byname function which has a
|
|
||||||
* different semantic. Should be merged with this one.
|
|
||||||
*/
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||||
const char *name, int want_secret, kbnode_t *ret_keyblock)
|
const char *name, int want_secret, kbnode_t *ret_keyblock)
|
||||||
@ -1106,7 +1165,7 @@ getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The new function to return the next key. */
|
/* For documentation see keydb.h. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock)
|
getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock)
|
||||||
{
|
{
|
||||||
@ -1115,8 +1174,8 @@ getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock)
|
|||||||
|
|
||||||
/* We need to disable the caching so that for an exact key search we
|
/* We need to disable the caching so that for an exact key search we
|
||||||
won't get the result back from the cache and thus end up in an
|
won't get the result back from the cache and thus end up in an
|
||||||
endless loop. Disabling this here is sufficient because although
|
endless loop. The endless loop can occur, because the cache is
|
||||||
the result has been cached, if won't be used then. */
|
used without respecting the current file pointer! */
|
||||||
keydb_disable_caching (ctx->kr_handle);
|
keydb_disable_caching (ctx->kr_handle);
|
||||||
|
|
||||||
rc = lookup (ctx, ret_keyblock, &found_key, ctx->want_secret);
|
rc = lookup (ctx, ret_keyblock, &found_key, ctx->want_secret);
|
||||||
@ -1127,7 +1186,7 @@ getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The new function to finish a key listing. */
|
/* For documentation see keydb.h. */
|
||||||
void
|
void
|
||||||
getkey_end (getkey_ctx_t ctx)
|
getkey_end (getkey_ctx_t ctx)
|
||||||
{
|
{
|
||||||
@ -1145,10 +1204,7 @@ getkey_end (getkey_ctx_t ctx)
|
|||||||
************* Merging stuff ********************
|
************* Merging stuff ********************
|
||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
/* Set the mainkey_id fields for all keys in KEYBLOCK. This is
|
/* For documentation see keydb.h. */
|
||||||
usually done by merge_selfsigs but at some places we only need the
|
|
||||||
main_kid but the the full merging. The function also guarantees
|
|
||||||
that all pk->keyids are computed. */
|
|
||||||
void
|
void
|
||||||
setup_main_keyids (kbnode_t keyblock)
|
setup_main_keyids (kbnode_t keyblock)
|
||||||
{
|
{
|
||||||
@ -1177,7 +1233,7 @@ setup_main_keyids (kbnode_t keyblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Merge all self-signatures with the keys. */
|
/* For documentation see keydb.h. */
|
||||||
void
|
void
|
||||||
merge_keys_and_selfsig (KBNODE keyblock)
|
merge_keys_and_selfsig (KBNODE keyblock)
|
||||||
{
|
{
|
||||||
@ -1252,7 +1308,7 @@ parse_key_usage (PKT_signature * sig)
|
|||||||
|
|
||||||
/* Apply information from SIGNODE (which is the valid self-signature
|
/* Apply information from SIGNODE (which is the valid self-signature
|
||||||
* associated with that UID) to the UIDNODE:
|
* associated with that UID) to the UIDNODE:
|
||||||
* - wether the UID has been revoked
|
* - weather the UID has been revoked
|
||||||
* - assumed creation date of the UID
|
* - assumed creation date of the UID
|
||||||
* - temporary store the keyflags here
|
* - temporary store the keyflags here
|
||||||
* - temporary store the key expiration time here
|
* - temporary store the key expiration time here
|
||||||
@ -1377,7 +1433,33 @@ sig_to_revoke_info (PKT_signature * sig, struct revoke_info *rinfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Note that R_REVOKED may be set to 0, 1 or 2. */
|
/* Given a keyblock, parse the key block and extract various pieces of
|
||||||
|
information and save them with the primary key packet and the user
|
||||||
|
id packets. For instance, some information is stored in signature
|
||||||
|
packets. We find the latest such valid packet (since the user can
|
||||||
|
change that information) and copy its contents into the
|
||||||
|
PKT_public_key.
|
||||||
|
|
||||||
|
Note that R_REVOKED may be set to 0, 1 or 2.
|
||||||
|
|
||||||
|
This function fills in the following fields in the primary key's
|
||||||
|
keyblock:
|
||||||
|
|
||||||
|
main_keyid (computed)
|
||||||
|
revkey / numrevkeys (derived from self signed key data)
|
||||||
|
flags.valid (whether we have at least 1 self-sig)
|
||||||
|
flags.maybe_revoked (whether a designed revoked the key, but
|
||||||
|
we are missing the key to check the sig)
|
||||||
|
selfsigversion (highest version of any valid self-sig)
|
||||||
|
pubkey_usage (derived from most recent self-sig or most
|
||||||
|
recent user id)
|
||||||
|
has_expired (various sources)
|
||||||
|
expiredate (various sources)
|
||||||
|
|
||||||
|
See the documentation for fixup_uidnode for how the user id packets
|
||||||
|
are modified. In addition to that the primary user id's is_primary
|
||||||
|
field is set to 1 and the other user id's is_primary are set to
|
||||||
|
0. */
|
||||||
static void
|
static void
|
||||||
merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
||||||
struct revoke_info *rinfo)
|
struct revoke_info *rinfo)
|
||||||
@ -1397,7 +1479,18 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
*r_revoked = 0;
|
*r_revoked = 0;
|
||||||
memset (rinfo, 0, sizeof (*rinfo));
|
memset (rinfo, 0, sizeof (*rinfo));
|
||||||
|
|
||||||
|
/* Section 11.1 of RFC 4880 determines the order of packets within a
|
||||||
|
message. There are three sections, which must occur in the
|
||||||
|
following order: the public key, the user ids and user attributes
|
||||||
|
and the subkeys. Within each section, each primary packet (e.g.,
|
||||||
|
a user id packet) is followed by one or more signature packets,
|
||||||
|
which modify that packet. */
|
||||||
|
|
||||||
|
/* According to Section 11.1 of RFC 4880, the public key must be the
|
||||||
|
first packet. */
|
||||||
if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
|
if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
|
||||||
|
/* parse_keyblock_image ensures that the first packet is the
|
||||||
|
public key. */
|
||||||
BUG ();
|
BUG ();
|
||||||
pk = keyblock->pkt->pkt.public_key;
|
pk = keyblock->pkt->pkt.public_key;
|
||||||
keytimestamp = pk->timestamp;
|
keytimestamp = pk->timestamp;
|
||||||
@ -1415,10 +1508,20 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
key_expire_seen = 1;
|
key_expire_seen = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First pass: Find the latest direct key self-signature. We assume
|
/* First pass:
|
||||||
* that the newest one overrides all others. */
|
|
||||||
|
|
||||||
/* In case this key was already merged. */
|
- Find the latest direct key self-signature. We assume that the
|
||||||
|
newest one overrides all others.
|
||||||
|
|
||||||
|
- Determine whether the key has been revoked.
|
||||||
|
|
||||||
|
- Gather all revocation keys (unlike other data, we don't just
|
||||||
|
take them from the latest self-signed packet).
|
||||||
|
|
||||||
|
- Determine max (sig[...]->version).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Reset this in case this key was already merged. */
|
||||||
xfree (pk->revkey);
|
xfree (pk->revkey);
|
||||||
pk->revkey = NULL;
|
pk->revkey = NULL;
|
||||||
pk->numrevkeys = 0;
|
pk->numrevkeys = 0;
|
||||||
@ -1431,6 +1534,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
{
|
{
|
||||||
PKT_signature *sig = k->pkt->pkt.signature;
|
PKT_signature *sig = k->pkt->pkt.signature;
|
||||||
if (sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1])
|
if (sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1])
|
||||||
|
/* Self sig. */
|
||||||
{
|
{
|
||||||
if (check_key_signature (keyblock, k, NULL))
|
if (check_key_signature (keyblock, k, NULL))
|
||||||
; /* Signature did not verify. */
|
; /* Signature did not verify. */
|
||||||
@ -1450,13 +1554,12 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
}
|
}
|
||||||
else if (IS_KEY_SIG (sig))
|
else if (IS_KEY_SIG (sig))
|
||||||
{
|
{
|
||||||
/* Add any revocation keys onto the pk. This is
|
/* Add the indicated revocations keys from all
|
||||||
particularly interesting since we normally only
|
signatures not just the latest. We do this
|
||||||
get data from the most recent 1F signature, but
|
because you need multiple 1F sigs to properly
|
||||||
you need multiple 1F sigs to properly handle
|
handle revocation keys (PGP does it this way, and
|
||||||
revocation keys (PGP does it this way, and a
|
a revocation key could be sensitive and hence in
|
||||||
revocation key could be sensitive and hence in a
|
a different signature). */
|
||||||
different signature). */
|
|
||||||
if (sig->revkey)
|
if (sig->revkey)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -1472,6 +1575,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sig->timestamp >= sigdate)
|
if (sig->timestamp >= sigdate)
|
||||||
|
/* This is the latest signature so far. */
|
||||||
{
|
{
|
||||||
if (sig->flags.expired)
|
if (sig->flags.expired)
|
||||||
; /* Signature has expired - ignore it. */
|
; /* Signature has expired - ignore it. */
|
||||||
@ -1490,7 +1594,6 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove dupes from the revocation keys. */
|
/* Remove dupes from the revocation keys. */
|
||||||
|
|
||||||
if (pk->revkey)
|
if (pk->revkey)
|
||||||
{
|
{
|
||||||
int i, j, x, changed = 0;
|
int i, j, x, changed = 0;
|
||||||
@ -1521,6 +1624,8 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (signode)
|
if (signode)
|
||||||
|
/* SIGNODE is the 1F signature packet with the latest creation
|
||||||
|
time. Extract some information from it. */
|
||||||
{
|
{
|
||||||
/* Some information from a direct key signature take precedence
|
/* Some information from a direct key signature take precedence
|
||||||
* over the same information given in UID sigs. */
|
* over the same information given in UID sigs. */
|
||||||
@ -1588,6 +1693,8 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
if (k->pkt->pkttype == PKT_USER_ID)
|
if (k->pkt->pkttype == PKT_USER_ID)
|
||||||
{
|
{
|
||||||
if (uidnode && signode)
|
if (uidnode && signode)
|
||||||
|
/* Apply the data from the most recent self-signed packet
|
||||||
|
to the preceding user id packet. */
|
||||||
{
|
{
|
||||||
fixup_uidnode (uidnode, signode, keytimestamp);
|
fixup_uidnode (uidnode, signode, keytimestamp);
|
||||||
pk->flags.valid = 1;
|
pk->flags.valid = 1;
|
||||||
@ -1608,7 +1715,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
{
|
{
|
||||||
/* Note: we allow to invalidate cert revocations
|
/* Note: we allow to invalidate cert revocations
|
||||||
* by a newer signature. An attacker can't use this
|
* by a newer signature. An attacker can't use this
|
||||||
* because a key should be revoced with a key revocation.
|
* because a key should be revoked with a key revocation.
|
||||||
* The reason why we have to allow for that is that at
|
* The reason why we have to allow for that is that at
|
||||||
* one time an email address may become invalid but later
|
* one time an email address may become invalid but later
|
||||||
* the same email address may become valid again (hired,
|
* the same email address may become valid again (hired,
|
||||||
@ -1664,7 +1771,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
|
|||||||
avoid infinite recursion in certain cases.
|
avoid infinite recursion in certain cases.
|
||||||
There is no reason to check that an ultimately
|
There is no reason to check that an ultimately
|
||||||
trusted key is still valid - if it has been
|
trusted key is still valid - if it has been
|
||||||
revoked or the user should also renmove the
|
revoked the user should also remove the
|
||||||
ultimate trust flag. */
|
ultimate trust flag. */
|
||||||
if (get_pubkey_fast (ultimate_pk, sig->keyid) == 0
|
if (get_pubkey_fast (ultimate_pk, sig->keyid) == 0
|
||||||
&& check_key_signature2 (keyblock, k, ultimate_pk,
|
&& check_key_signature2 (keyblock, k, ultimate_pk,
|
||||||
@ -1885,6 +1992,25 @@ buf_to_sig (const byte * buf, size_t len)
|
|||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use the self-signed data to fill in various fields in subkeys.
|
||||||
|
|
||||||
|
KEYBLOCK is the whole keyblock. SUBNODE is the subkey to fill in.
|
||||||
|
|
||||||
|
Sets the following fields on the subkey:
|
||||||
|
|
||||||
|
main_keyid
|
||||||
|
flags.valid if the subkey has a valid self-sig binding
|
||||||
|
flags.revoked
|
||||||
|
flags.backsig
|
||||||
|
pubkey_usage
|
||||||
|
has_expired
|
||||||
|
expired_date
|
||||||
|
|
||||||
|
On this subkey's most revent valid self-signed packet, the
|
||||||
|
following field is set:
|
||||||
|
|
||||||
|
flags.chosen_selfsig
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
|
merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
|
||||||
{
|
{
|
||||||
@ -2070,18 +2196,11 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Merge information from the self-signatures with the public key,
|
||||||
* Merge information from the self-signatures with the key, so that
|
subkeys and user ids to make using them more easy.
|
||||||
* we can later use them more easy.
|
|
||||||
* The function works by first applying the self signatures to the
|
See documentation for merge_selfsigs_main, merge_selfsigs_subkey
|
||||||
* primary key and the to each subkey.
|
and fixup_uidnode for exactly which fields are updated. */
|
||||||
* Here are the rules we use to decide which inormation from which
|
|
||||||
* self-signature is used:
|
|
||||||
* We check all self signatures or validity and ignore all invalid signatures.
|
|
||||||
* All signatures are then ordered by their creation date ....
|
|
||||||
* For the primary key:
|
|
||||||
* FIXME the docs
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
merge_selfsigs (KBNODE keyblock)
|
merge_selfsigs (KBNODE keyblock)
|
||||||
{
|
{
|
||||||
@ -2180,50 +2299,75 @@ merge_selfsigs (KBNODE keyblock)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* See whether the key fits our requirements and in case we do not
|
/* See whether the key satisfies any additional requirements specified
|
||||||
* request the primary key, select a suitable subkey.
|
in CTX. If so, return 1 and set CTX->FOUND_KEY to an appropriate
|
||||||
*
|
key or subkey. Otherwise, return 0 if there was no appropriate
|
||||||
* Returns: True when a suitable key has been found.
|
key.
|
||||||
*
|
|
||||||
* We have to distinguish four cases: FIXME!
|
In case the primary key is not required, select a suitable subkey.
|
||||||
* 1. No usage and no primary key requested
|
We need the primary key if PUBKEY_USAGE_CERT is set in
|
||||||
* Examples for this case are that we have a keyID to be used
|
CTX->REQ_USAGE or we are in PGP6 or PGP7 mode and PUBKEY_USAGE_SIG
|
||||||
* for decrytion or verification.
|
is set in CTX->REQ_USAGE.
|
||||||
* 2. No usage but primary key requested
|
|
||||||
* This is the case for all functions which work on an
|
If any of PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT
|
||||||
* entire keyblock, e.g. for editing or listing
|
are set in CTX->REQ_USAGE, we filter by the key's function.
|
||||||
* 3. Usage and primary key requested
|
Concretely, if PUBKEY_USAGE_SIG and PUBKEY_USAGE_CERT are set, then
|
||||||
* FXME
|
we only return a key if it is (at least) either a signing or a
|
||||||
* 4. Usage but no primary key requested
|
certification key.
|
||||||
* FIXME
|
|
||||||
* FIXME: Tell what is going to happen here and something about the rationale
|
If CTX->REQ_USAGE is set, then we reject any keys that are not good
|
||||||
* Note: We don't use this function if no specific usage is requested;
|
(i.e., valid, not revoked, not expired, etc.). This allows the
|
||||||
* This way the getkey functions can be used for plain key listings.
|
getkey functions to be used for plain key listings.
|
||||||
*
|
|
||||||
* CTX ist the keyblock we are investigating, if FOUNDK is not NULL this
|
Sets the matched key's user id field (pk->user_id) to the user id
|
||||||
* is the key we actually found by looking at the keyid or a fingerprint and
|
that matched the low-level search criteria or NULL.
|
||||||
* may either point to the primary or one of the subkeys. */
|
|
||||||
|
|
||||||
|
This function needs to handle several different cases:
|
||||||
|
|
||||||
|
1. No requested usage and no primary key requested
|
||||||
|
Examples for this case are that we have a keyID to be used
|
||||||
|
for decrytion or verification.
|
||||||
|
2. No usage but primary key requested
|
||||||
|
This is the case for all functions which work on an
|
||||||
|
entire keyblock, e.g. for editing or listing
|
||||||
|
3. Usage and primary key requested
|
||||||
|
FXME
|
||||||
|
4. Usage but no primary key requested
|
||||||
|
FIXME
|
||||||
|
|
||||||
|
*/
|
||||||
static KBNODE
|
static KBNODE
|
||||||
finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
|
finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
|
||||||
{
|
{
|
||||||
KBNODE k;
|
KBNODE k;
|
||||||
|
|
||||||
|
/* If CTX->EXACT is set, the key or subkey that actually matched the
|
||||||
|
low-level search criteria. */
|
||||||
KBNODE foundk = NULL;
|
KBNODE foundk = NULL;
|
||||||
|
/* The user id (if any) that matched the low-level search criteria. */
|
||||||
PKT_user_id *foundu = NULL;
|
PKT_user_id *foundu = NULL;
|
||||||
|
|
||||||
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
|
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
|
||||||
unsigned int req_usage = (ctx->req_usage & USAGE_MASK);
|
unsigned int req_usage = (ctx->req_usage & USAGE_MASK);
|
||||||
|
|
||||||
/* Request the primary if we're certifying another key, and also
|
/* Request the primary if we're certifying another key, and also
|
||||||
if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7
|
if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7
|
||||||
do not understand signatures made by a signing subkey. PGP 8
|
do not understand signatures made by a signing subkey. PGP 8
|
||||||
does. */
|
does. */
|
||||||
int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) ||
|
int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) ||
|
||||||
((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG));
|
((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG));
|
||||||
|
|
||||||
|
u32 curtime = make_timestamp ();
|
||||||
|
|
||||||
u32 latest_date;
|
u32 latest_date;
|
||||||
KBNODE latest_key;
|
KBNODE latest_key;
|
||||||
u32 curtime = make_timestamp ();
|
|
||||||
|
|
||||||
assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
|
||||||
|
|
||||||
if (ctx->exact)
|
if (ctx->exact)
|
||||||
|
/* Get the key or subkey that matched the low-level search
|
||||||
|
criteria. */
|
||||||
{
|
{
|
||||||
for (k = keyblock; k; k = k->next)
|
for (k = keyblock; k; k = k->next)
|
||||||
{
|
{
|
||||||
@ -2237,6 +2381,7 @@ finish_lookup (GETKEY_CTX ctx, KBNODE keyblock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the user id that matched that low-level search criteria. */
|
||||||
for (k = keyblock; k; k = k->next)
|
for (k = keyblock; k; k = k->next)
|
||||||
{
|
{
|
||||||
if ((k->flag & 2))
|
if ((k->flag & 2))
|
||||||
@ -2420,9 +2565,22 @@ search_modes_are_fingerprint (getkey_ctx_t ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The main function to lookup a key. On success the found keyblock
|
/* A high-level function to lookup keys.
|
||||||
is stored at RET_KEYBLOCK and also in CTX. If WANT_SECRET is true
|
|
||||||
a corresponding secret key is required. */
|
This function builds on top of the low-level keydb API. It first
|
||||||
|
searches the database using the description stored in CTX->ITEMS,
|
||||||
|
then it filters the results using CTX and, finally, if WANT_SECRET
|
||||||
|
is set, it ignores any keys for which no secret key is available.
|
||||||
|
|
||||||
|
Note: this function skips any legacy keys unless the search mode is
|
||||||
|
KEYDB_SEARCH_MODE_FIRST or KEYDB_SEARCH_MODE_NEXT or we are
|
||||||
|
searching by fingerprint.
|
||||||
|
|
||||||
|
Unlike the low-level search functions, this function also merges
|
||||||
|
all of the self-signed data into the keys, subkeys and user id
|
||||||
|
packets (see the merge_selfsigs for details).
|
||||||
|
|
||||||
|
On success the key's keyblock is stored at *RET_KEYBLOCK. */
|
||||||
static int
|
static int
|
||||||
lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
||||||
int want_secret)
|
int want_secret)
|
||||||
@ -2435,8 +2593,10 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems, NULL);
|
rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems, NULL);
|
||||||
/* Skip over all legacy keys but only if they are not requested
|
|
||||||
by fingerprints.
|
/* Skip over all legacy keys unless we are iterating over all
|
||||||
|
keys in the DB or the key was requested by its fingerprint.
|
||||||
|
|
||||||
Fixme: The lower level keydb code should actually do that but
|
Fixme: The lower level keydb code should actually do that but
|
||||||
then it would be harder to report the number of skipped
|
then it would be harder to report the number of skipped
|
||||||
legacy keys during import. */
|
legacy keys during import. */
|
||||||
@ -2448,9 +2608,10 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
|||||||
if (rc)
|
if (rc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If we are searching for the first key we have to make sure
|
/* If we are iterating over the entire database, then we need to
|
||||||
that the next iteration does not do an implicit reset.
|
change from KEYDB_SEARCH_MODE_FIRST, which does an implicit
|
||||||
This can be triggered by an empty key ring. */
|
reset, to KEYDB_SEARCH_MODE_NEXT, which gets the next
|
||||||
|
record. */
|
||||||
if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
|
if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
|
||||||
ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
|
ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
|
||||||
|
|
||||||
@ -2482,11 +2643,11 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, kbnode_t *ret_found_key,
|
|||||||
/* Release resources and continue search. */
|
/* Release resources and continue search. */
|
||||||
release_kbnode (keyblock);
|
release_kbnode (keyblock);
|
||||||
keyblock = NULL;
|
keyblock = NULL;
|
||||||
/* We need to disable the caching so that for an exact key
|
/* The keyblock cache ignores the current "file position".
|
||||||
search we won't get the result back from the cache and thus
|
Thus, if we request the next result and the cache matches
|
||||||
end up in an endless loop. Disabling the cache here at this
|
(and it will since it is what we just looked for), we'll get
|
||||||
point is sufficient because even a cached result won't be
|
the same entry back! We can avoid this infinite loop by
|
||||||
used after a call to keydb_disable_caching. */
|
disabling the cache. */
|
||||||
keydb_disable_caching (ctx->kr_handle);
|
keydb_disable_caching (ctx->kr_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2520,18 +2681,7 @@ found:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 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.
|
|
||||||
*/
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
enum_secret_keys (void **context, PKT_public_key *sk)
|
enum_secret_keys (void **context, PKT_public_key *sk)
|
||||||
{
|
{
|
||||||
@ -2652,7 +2802,7 @@ get_user_id_string (u32 * keyid, int mode, size_t *r_len)
|
|||||||
int pass = 0;
|
int pass = 0;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
/* Try it two times; second pass reads from key resources. */
|
/* Try it two times; second pass reads from the database. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
for (r = user_id_db; r; r = r->next)
|
for (r = user_id_db; r; r = r->next)
|
||||||
@ -2741,8 +2891,11 @@ get_user_id_native (u32 * keyid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return a user id from the caching by looking it up using the FPR
|
/* Return the user id for a key designated by its fingerprint, FPR,
|
||||||
which must be of size MAX_FINGERPRINT_LEN. */
|
which must be MAX_FINGERPRINT_LEN bytes in size. Note: the
|
||||||
|
returned string, which must be freed using xfree, may not be NUL
|
||||||
|
terminated. To determine the length of the string, you must use
|
||||||
|
*RN. */
|
||||||
char *
|
char *
|
||||||
get_user_id_byfpr (const byte *fpr, size_t *rn)
|
get_user_id_byfpr (const byte *fpr, size_t *rn)
|
||||||
{
|
{
|
||||||
@ -2750,7 +2903,7 @@ get_user_id_byfpr (const byte *fpr, size_t *rn)
|
|||||||
char *p;
|
char *p;
|
||||||
int pass = 0;
|
int pass = 0;
|
||||||
|
|
||||||
/* Try it two times; second pass reads from key resources. */
|
/* Try it two times; second pass reads from the database. */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
for (r = user_id_db; r; r = r->next)
|
for (r = user_id_db; r; r = r->next)
|
||||||
@ -2778,6 +2931,9 @@ get_user_id_byfpr (const byte *fpr, size_t *rn)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Like get_user_id_byfpr, but convert the string to the native
|
||||||
|
encoding. The returned string needs to be freed. Unlike
|
||||||
|
get_user_id_byfpr, the returned string is NUL terminated. */
|
||||||
char *
|
char *
|
||||||
get_user_id_byfpr_native (const byte *fpr)
|
get_user_id_byfpr_native (const byte *fpr)
|
||||||
{
|
{
|
||||||
@ -2790,6 +2946,7 @@ get_user_id_byfpr_native (const byte *fpr)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
KEYDB_HANDLE
|
KEYDB_HANDLE
|
||||||
get_ctx_handle (GETKEY_CTX ctx)
|
get_ctx_handle (GETKEY_CTX ctx)
|
||||||
{
|
{
|
||||||
@ -2893,12 +3050,7 @@ parse_auto_key_locate (char *options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For documentation see keydb.h. */
|
||||||
|
|
||||||
/* Return true if a secret key is available for the public key with
|
|
||||||
* the given KEYID. This is just a fast check and does not tell us
|
|
||||||
* whether the secret key is valid. It merely tells os whether there
|
|
||||||
* is some secret key. */
|
|
||||||
int
|
int
|
||||||
have_secret_key_with_kid (u32 *keyid)
|
have_secret_key_with_kid (u32 *keyid)
|
||||||
{
|
{
|
||||||
|
342
g10/keydb.h
342
g10/keydb.h
@ -70,7 +70,7 @@ enum resource_type {
|
|||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* A data structre to hold information about the external position
|
* A data structure to hold information about the external position
|
||||||
* of a keyblock.
|
* of a keyblock.
|
||||||
*/
|
*/
|
||||||
struct keyblock_pos_struct {
|
struct keyblock_pos_struct {
|
||||||
@ -398,50 +398,380 @@ char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped);
|
|||||||
|
|
||||||
|
|
||||||
/*-- getkey.c --*/
|
/*-- getkey.c --*/
|
||||||
|
|
||||||
|
/* Cache a copy of a public key in the public key cache. PK is not
|
||||||
|
cached if caching is disabled (via getkey_disable_caches), if
|
||||||
|
PK->FLAGS.DONT_CACHE is set, we don't know how to derive a key id
|
||||||
|
from the public key (e.g., unsupported algorithm), or a key with
|
||||||
|
the key id is already in the cache.
|
||||||
|
|
||||||
|
The public key packet is copied into the cache using
|
||||||
|
copy_public_key. Thus, any secret parts are not copied, for
|
||||||
|
instance.
|
||||||
|
|
||||||
|
This cache is filled by get_pubkey and is read by get_pubkey and
|
||||||
|
get_pubkey_fast. */
|
||||||
void cache_public_key( PKT_public_key *pk );
|
void cache_public_key( PKT_public_key *pk );
|
||||||
|
|
||||||
|
/* Disable and drop the public key cache (which is filled by
|
||||||
|
cache_public_key and get_pubkey). Note: there is currently no way
|
||||||
|
to reenable this cache. */
|
||||||
void getkey_disable_caches(void);
|
void getkey_disable_caches(void);
|
||||||
|
|
||||||
|
/* Return the public key with the key id KEYID and store it in *PK.
|
||||||
|
The resources in *PK should be released using
|
||||||
|
release_public_key_parts(). This function also stores a copy of
|
||||||
|
the public key in the user id cache (see cache_public_key).
|
||||||
|
|
||||||
|
If PK is NULL, this function just stores the public key in the
|
||||||
|
cache and returns the usual return code.
|
||||||
|
|
||||||
|
PK->REQ_USAGE (which is a mask of PUBKEY_USAGE_SIG,
|
||||||
|
PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT) is passed through to the
|
||||||
|
lookup function. If this is non-zero, only keys with the specified
|
||||||
|
usage will be returned. As such, it is essential that
|
||||||
|
PK->REQ_USAGE be correctly initialized!
|
||||||
|
|
||||||
|
Returns 0 on success, GPG_ERR_NO_PUBKEY if there is no public key
|
||||||
|
with the specified key id, or another error code if an error
|
||||||
|
occurs.
|
||||||
|
|
||||||
|
If the data was not read from the cache, then the self-signed data
|
||||||
|
has definately been merged into the public key using
|
||||||
|
merge_selfsigs. */
|
||||||
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
||||||
|
|
||||||
|
/* Similar to get_pubkey, but it does not take PK->REQ_USAGE into
|
||||||
|
account nor does it merge in the self-signed data. This function
|
||||||
|
also only considers primary keys. It is intended to be used as a
|
||||||
|
quick check of the key to avoid recursion. It should only be used
|
||||||
|
in very certain cases. Like get_pubkey and unlike any of the other
|
||||||
|
lookup functions, this function also consults the user id cache
|
||||||
|
(see cache_public_key).
|
||||||
|
|
||||||
|
Return the public key in *PK. The resources in *PK should be
|
||||||
|
released using release_public_key_parts(). */
|
||||||
int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
|
int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
|
||||||
|
|
||||||
|
/* Return the key block for the key with key id KEYID or NULL, if an
|
||||||
|
error occurs. Use release_kbnode() to release the key block.
|
||||||
|
|
||||||
|
The self-signed data has already been merged into the public key
|
||||||
|
using merge_selfsigs. */
|
||||||
KBNODE get_pubkeyblock( u32 *keyid );
|
KBNODE get_pubkeyblock( u32 *keyid );
|
||||||
|
|
||||||
|
/* Find a public key identified by the name NAME.
|
||||||
|
|
||||||
|
If name appears to be a valid valid RFC822 mailbox (i.e., email
|
||||||
|
address) and auto key lookup is enabled (no_akl == 0), then the
|
||||||
|
specified auto key lookup methods (--auto-key-lookup) are used to
|
||||||
|
import the key into the local keyring. Otherwise, just the local
|
||||||
|
keyring is consulted.
|
||||||
|
|
||||||
|
|
||||||
|
If RETCTX is not NULL, then the constructed context is returned in
|
||||||
|
*RETCTX so that getpubkey_next can be used to get subsequent
|
||||||
|
results. In this case, getkey_end() must be used to free the
|
||||||
|
search context. If RETCTX is not NULL, then RET_KDBHD must be
|
||||||
|
NULL.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the first result is returned
|
||||||
|
in *PK. Note: PK->REQ_USAGE must be valid!!! PK->REQ_USAGE is
|
||||||
|
passed through to the lookup function and is a mask of
|
||||||
|
PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. If this
|
||||||
|
is non-zero, only keys with the specified usage will be returned.
|
||||||
|
Note: The self-signed data has already been merged into the public
|
||||||
|
key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
NAME is a string, which is turned into a search query using
|
||||||
|
classify_user_id.
|
||||||
|
|
||||||
|
If RET_KEYBLOCK is not NULL, the keyblock is returned in
|
||||||
|
*RET_KEYBLOCK. This should be freed using release_kbnode().
|
||||||
|
|
||||||
|
If RET_KDBHD is not NULL, then the new database handle used to
|
||||||
|
conduct the search is returned in *RET_KDBHD. This can be used to
|
||||||
|
get subsequent results using keydb_search_next or to modify the
|
||||||
|
returned record. Note: in this case, no advanced filtering is done
|
||||||
|
for subsequent results (e.g., PK->REQ_USAGE is not respected).
|
||||||
|
Unlike RETCTX, this is always returned.
|
||||||
|
|
||||||
|
If INCLUDE_UNUSABLE is set, then unusable keys (see the
|
||||||
|
documentation for skip_unusable for an exact definition) are
|
||||||
|
skipped unless they are looked up by key id or by fingerprint.
|
||||||
|
|
||||||
|
If NO_AKL is set, then the auto key locate functionality is
|
||||||
|
disabled and only the local key ring is considered. Note: the
|
||||||
|
local key ring is consulted even if local is not in the
|
||||||
|
--auto-key-locate option list!
|
||||||
|
|
||||||
|
This function returns 0 on success. Otherwise, an error code is
|
||||||
|
returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY
|
||||||
|
(if want_secret is set) is returned if the key is not found. */
|
||||||
int get_pubkey_byname (ctrl_t ctrl,
|
int get_pubkey_byname (ctrl_t ctrl,
|
||||||
GETKEY_CTX *rx, PKT_public_key *pk, const char *name,
|
GETKEY_CTX *retctx, PKT_public_key *pk,
|
||||||
|
const char *name,
|
||||||
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
|
||||||
int include_unusable, int no_akl );
|
int include_unusable, int no_akl );
|
||||||
|
|
||||||
|
/* Return the public key with the key id KEYID and store it in *PK.
|
||||||
|
The resources should be released using release_public_key_parts().
|
||||||
|
|
||||||
|
Unlike other lookup functions, PK may not be NULL. PK->REQ_USAGE
|
||||||
|
is passed through to the lookup function and is a mask of
|
||||||
|
PUBKEY_USAGE_SIG, PUBKEY_USAGE_ENC and PUBKEY_USAGE_CERT. Thus, it
|
||||||
|
must be valid! If this is non-zero, only keys with the specified
|
||||||
|
usage will be returned.
|
||||||
|
|
||||||
|
Returns 0 on success. If a public key with the specified key id is
|
||||||
|
not found or a secret key is not available for that public key, an
|
||||||
|
error code is returned. Note: this function ignores legacy keys.
|
||||||
|
An error code is also return if an error occurs.
|
||||||
|
|
||||||
|
The self-signed data has already been merged into the public key
|
||||||
|
using merge_selfsigs. */
|
||||||
gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid);
|
gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid);
|
||||||
|
|
||||||
|
/* Lookup a key with the specified fingerprint.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the first result is returned
|
||||||
|
in *PK. Note: this function does an exact search and thus the
|
||||||
|
returned public key may be a subkey rather than the primary key.
|
||||||
|
Note: The self-signed data has already been merged into the public
|
||||||
|
key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
If PK->REQ_USAGE is set, it is used to filter the search results.
|
||||||
|
(Thus, if PK is not NULL, PK->REQ_USAGE must be valid!!!) See the
|
||||||
|
documentation for finish_lookup to understand exactly how this is
|
||||||
|
used.
|
||||||
|
|
||||||
|
If R_KEYBLOCK is not NULL, then the first result's keyblock is
|
||||||
|
returned in *R_KEYBLOCK. This should be freed using
|
||||||
|
release_kbnode().
|
||||||
|
|
||||||
|
FPRINT is a byte array whose contents is the fingerprint to use as
|
||||||
|
the search term. FPRINT_LEN specifies the length of the
|
||||||
|
fingerprint (in bytes). Currently, only 16 and 20-byte
|
||||||
|
fingerprints are supported. */
|
||||||
int get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
|
int get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
|
||||||
const byte *fprint, size_t fprint_len);
|
const byte *fprint, size_t fprint_len);
|
||||||
|
|
||||||
|
/* This function is similar to get_pubkey_byfprint, but it doesn't
|
||||||
|
merge the self-signed data into the public key and subkeys or into
|
||||||
|
the user ids. It also doesn't add the key to the user id cache.
|
||||||
|
Further, this function ignores PK->REQ_USAGE.
|
||||||
|
|
||||||
|
This function is intended to avoid recursion and, as such, should
|
||||||
|
only be used in very specific situations.
|
||||||
|
|
||||||
|
Like get_pubkey_byfprint, PK may be NULL. In that case, this
|
||||||
|
function effectively just checks for the existence of the key. */
|
||||||
int get_pubkey_byfprint_fast (PKT_public_key *pk,
|
int get_pubkey_byfprint_fast (PKT_public_key *pk,
|
||||||
const byte *fprint, size_t fprint_len);
|
const byte *fprint, size_t fprint_len);
|
||||||
|
|
||||||
/* Return whether a secret key is available for the public key with
|
/* Return whether a secret key is available for the public key with
|
||||||
key id KEYID. Note: this is just a fast check and does not tell us
|
key id KEYID. This function ignores legacy keys. Note: this is
|
||||||
whether the secret key is valid; this check merely indicates
|
just a fast check and does not tell us whether the secret key is
|
||||||
whether there is some secret key with the specified key id. */
|
valid; this check merely indicates whether there is some secret key
|
||||||
|
with the specified key id. */
|
||||||
int have_secret_key_with_kid (u32 *keyid);
|
int have_secret_key_with_kid (u32 *keyid);
|
||||||
|
|
||||||
|
/* Look up a secret key.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the first result is returned
|
||||||
|
in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is
|
||||||
|
set, it is used to filter the search results. See the
|
||||||
|
documentation for finish_lookup to understand exactly how this is
|
||||||
|
used. Note: The self-signed data has already been merged into the
|
||||||
|
public key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
If --default-key was set, then the specified key is looked up. (In
|
||||||
|
this case, the default key is returned even if it is considered
|
||||||
|
unusable. See the documentation for skip_unusable for exactly what
|
||||||
|
this means.)
|
||||||
|
|
||||||
|
Otherwise, this initiates a DB scan that returns all keys that are
|
||||||
|
usable (see previous paragraph for exactly what usable means) and
|
||||||
|
for which a secret key is available.
|
||||||
|
|
||||||
|
This function returns the first match. Additional results can be
|
||||||
|
returned using getkey_next. */
|
||||||
gpg_error_t get_seckey_default (PKT_public_key *pk);
|
gpg_error_t get_seckey_default (PKT_public_key *pk);
|
||||||
|
|
||||||
|
/* Search for keys matching some criteria.
|
||||||
|
|
||||||
|
If RETCTX is not NULL, then the constructed context is returned in
|
||||||
|
*RETCTX so that getpubkey_next can be used to get subsequent
|
||||||
|
results. In this case, getkey_end() must be used to free the
|
||||||
|
search context. If RETCTX is not NULL, then RET_KDBHD must be
|
||||||
|
NULL.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the first result is returned
|
||||||
|
in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is
|
||||||
|
set, it is used to filter the search results. See the
|
||||||
|
documentation for finish_lookup to understand exactly how this is
|
||||||
|
used. Note: The self-signed data has already been merged into the
|
||||||
|
public key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
If NAMES is not NULL, then a search query is constructed using
|
||||||
|
classify_user_id on each of the strings in the list. (Recall: the
|
||||||
|
database does an OR of the terms, not an AND.) If NAMES is
|
||||||
|
NULL, then all results are returned.
|
||||||
|
|
||||||
|
If WANT_SECRET is set, then only keys with an available secret key
|
||||||
|
(either locally or via key registered on a smartcard) are returned.
|
||||||
|
|
||||||
|
This function does not skip unusable keys (see the documentation
|
||||||
|
for skip_unusable for an exact definition).
|
||||||
|
|
||||||
|
If RET_KEYBLOCK is not NULL, the keyblock is returned in
|
||||||
|
*RET_KEYBLOCK. This should be freed using release_kbnode().
|
||||||
|
|
||||||
|
This function returns 0 on success. Otherwise, an error code is
|
||||||
|
returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY
|
||||||
|
(if want_secret is set) is returned if the key is not found. */
|
||||||
gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||||
strlist_t names, int want_secret,
|
strlist_t names, int want_secret,
|
||||||
kbnode_t *ret_keyblock);
|
kbnode_t *ret_keyblock);
|
||||||
|
|
||||||
|
/* Search for keys matching some criteria.
|
||||||
|
|
||||||
|
If RETCTX is not NULL, then the constructed context is returned in
|
||||||
|
*RETCTX so that getpubkey_next can be used to get subsequent
|
||||||
|
results. In this case, getkey_end() must be used to free the
|
||||||
|
search context. If RETCTX is not NULL, then RET_KDBHD must be
|
||||||
|
NULL.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the first result is returned
|
||||||
|
in *PK. Note: PK->REQ_USAGE must be valid!!! If PK->REQ_USAGE is
|
||||||
|
set, it is used to filter the search results. See the
|
||||||
|
documentation for finish_lookup to understand exactly how this is
|
||||||
|
used. Note: The self-signed data has already been merged into the
|
||||||
|
public key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
If NAME is not NULL, then a search query is constructed using
|
||||||
|
classify_user_id on the string. In this case, even unusable keys
|
||||||
|
(see the documentation for skip_unusable for an exact definition of
|
||||||
|
unusable) are returned. Otherwise, if --default-key was set, then
|
||||||
|
that key is returned (even if it is unusable). If neither of these
|
||||||
|
conditions holds, then the first usable key is returned.
|
||||||
|
|
||||||
|
If WANT_SECRET is set, then only keys with an available secret key
|
||||||
|
(either locally or via key registered on a smartcard) are returned.
|
||||||
|
|
||||||
|
This function does not skip unusable keys (see the documentation
|
||||||
|
for skip_unusable for an exact definition).
|
||||||
|
|
||||||
|
If RET_KEYBLOCK is not NULL, the keyblock is returned in
|
||||||
|
*RET_KEYBLOCK. This should be freed using release_kbnode().
|
||||||
|
|
||||||
|
This function returns 0 on success. Otherwise, an error code is
|
||||||
|
returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY
|
||||||
|
(if want_secret is set) is returned if the key is not found.
|
||||||
|
|
||||||
|
FIXME: We also have the get_pubkey_byname function which has a
|
||||||
|
different semantic. Should be merged with this one. */
|
||||||
gpg_error_t getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
gpg_error_t getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||||
const char *name, int want_secret,
|
const char *name, int want_secret,
|
||||||
kbnode_t *ret_keyblock);
|
kbnode_t *ret_keyblock);
|
||||||
|
|
||||||
|
/* Return the next search result.
|
||||||
|
|
||||||
|
If PK is not NULL, the public key of the next result is returned in
|
||||||
|
*PK. Note: The self-signed data has already been merged into the
|
||||||
|
public key using merge_selfsigs. Free *PK by calling
|
||||||
|
release_public_key_parts (or, if PK was allocated using xfree, you
|
||||||
|
can use free_public_key, which calls release_public_key_parts(PK)
|
||||||
|
and then xfree(PK)).
|
||||||
|
|
||||||
|
The self-signed data has already been merged into the public key
|
||||||
|
using merge_selfsigs. */
|
||||||
gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk,
|
gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk,
|
||||||
kbnode_t *ret_keyblock);
|
kbnode_t *ret_keyblock);
|
||||||
|
|
||||||
|
/* Release any resources used by a key listing content. This must be
|
||||||
|
called on the context returned by, e.g., getkey_byname. */
|
||||||
void getkey_end (getkey_ctx_t ctx);
|
void getkey_end (getkey_ctx_t ctx);
|
||||||
|
|
||||||
|
/* Return the database handle used by this context. The context still
|
||||||
|
owns the handle. */
|
||||||
|
KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
while ((err = enum_secret_keys (&ctx, sk)))
|
||||||
|
{
|
||||||
|
// Process SK.
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
|
||||||
|
free_public_key (sk);
|
||||||
|
sk = xmalloc_clear (sizeof (*sk));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release any resources used by CTX.
|
||||||
|
enum_secret_keys (&ctx, NULL);
|
||||||
|
free_public_key (sk);
|
||||||
|
|
||||||
|
if (gpg_err_code (err) != GPG_ERR_EOF)
|
||||||
|
; // An error occured.
|
||||||
|
*/
|
||||||
gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk);
|
gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk);
|
||||||
|
|
||||||
|
/* Set the mainkey_id fields for all keys in KEYBLOCK. This is
|
||||||
|
usually done by merge_selfsigs but at some places we only need the
|
||||||
|
main_kid not a full merge. The function also guarantees that all
|
||||||
|
pk->keyids are computed. */
|
||||||
void setup_main_keyids (kbnode_t keyblock);
|
void setup_main_keyids (kbnode_t keyblock);
|
||||||
|
|
||||||
|
/* KEYBLOCK corresponds to a public key block. This function merges
|
||||||
|
much of the information from the self-signed data into the public
|
||||||
|
key, public subkey and user id data structures. If you use the
|
||||||
|
high-level search API (e.g., get_pubkey) for looking up key blocks,
|
||||||
|
then you don't need to call this function. This function is
|
||||||
|
useful, however, if you change the keyblock, e.g., by adding or
|
||||||
|
removing a self-signed data packet. */
|
||||||
void merge_keys_and_selfsig( KBNODE keyblock );
|
void merge_keys_and_selfsig( KBNODE keyblock );
|
||||||
|
|
||||||
char*get_user_id_string_native( u32 *keyid );
|
char*get_user_id_string_native( u32 *keyid );
|
||||||
char*get_long_user_id_string( u32 *keyid );
|
char*get_long_user_id_string( u32 *keyid );
|
||||||
char*get_user_id( u32 *keyid, size_t *rn );
|
char*get_user_id( u32 *keyid, size_t *rn );
|
||||||
char*get_user_id_native( u32 *keyid );
|
char*get_user_id_native( u32 *keyid );
|
||||||
char *get_user_id_byfpr (const byte *fpr, size_t *rn);
|
char *get_user_id_byfpr (const byte *fpr, size_t *rn);
|
||||||
char *get_user_id_byfpr_native (const byte *fpr);
|
char *get_user_id_byfpr_native (const byte *fpr);
|
||||||
KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
|
|
||||||
void release_akl(void);
|
void release_akl(void);
|
||||||
int parse_auto_key_locate(char *options);
|
int parse_auto_key_locate(char *options);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user