g10: Improve interface documentation of the keydb API.
authorNeal H. Walfield <neal@g10code.com>
Mon, 31 Aug 2015 09:14:21 +0000 (11:14 +0200)
committerNeal H. Walfield <neal@g10code.com>
Mon, 31 Aug 2015 09:30:56 +0000 (11:30 +0200)
* g10/keydb.c: Improve code comments and documentation of internal
interfaces.  Improve documentation of public APIs and move that to...
* g10/keydb.h: ... this file.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>.
g10/keydb.c
g10/keydb.h

index eeefd2a..423205d 100644 (file)
@@ -64,18 +64,37 @@ static void *primary_keyring=NULL;
 
 struct keydb_handle
 {
+  /* When we locked all of the resources in ACTIVE (using keyring_lock
+     / keybox_lock, as appropriate).  */
   int locked;
+
+  /* The index into ACTIVE of the resources in which the last search
+     result was found.  Initially -1.  */
   int found;
+
+  /* Initially -1 (invalid).  This is used to save a search result and
+     later restore it as the selected result.  */
   int saved_found;
+
+  /* The number of skipped long blobs since the last search
+     (keydb_search_reset).  */
   unsigned long skipped_long_blobs;
+
+  /* If set, this disables the use of the keyblock cache.  */
   int no_caching;
 
   /* Whether the next search will be from the beginning of the
      database (and thus consider all records).  */
   int is_reset;
 
+  /* The "file position."  In our case, this is index of the current
+     resource in ACTIVE.  */
   int current;
-  int used;   /* Number of items in ACTIVE. */
+
+  /* The number of resources in ACTIVE.  */
+  int used;
+
+  /* Copy of ALL_RESOURCES when keydb_new is called.  */
   struct resource_item active[MAX_KEYDB_RESOURCES];
 };
 
@@ -187,7 +206,7 @@ kid_not_found_insert (u32 *kid)
 }
 
 
-/* Flush kid found cache.  */
+/* Flush the kid not found cache.  */
 static void
 kid_not_found_flush (void)
 {
@@ -229,7 +248,9 @@ keyblock_cache_clear (void)
    keyring/keybox already locked.  This lock check does not work if
    the directory itself is not yet available.  If IS_BOX is true the
    filename is expected to refer to a keybox.  If FORCE_CREATE is true
-   the keyring or keybox will be created.  */
+   the keyring or keybox will be created.
+
+   Return 0 if it is okay to access the specified file.  */
 static int
 maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
 {
@@ -392,10 +413,15 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create)
 }
 
 
-/* Helper for keydb_add_resource.  Opens FILENAME to figures out the
-   resource type.  Returns the resource type and a flag at R_NOTFOUND
-   indicating whether FILENAME could be opened at all.  If the openpgp
-   flag is set in a keybox header, R_OPENPGP will be set to true.  */
+/* Helper for keydb_add_resource.  Opens FILENAME to figure out the
+   resource type.
+
+   Returns the specified file's likely type.  If the file does not
+   exist, returns KEYDB_RESOURCE_TYPE_NONE and sets *R_FOUND to 0.
+   Otherwise, tries to figure out the file's type.  This is either
+   KEYDB_RESOURCE_TYPE_KEYBOX, KEYDB_RESOURCE_TYPE_KEYRING or
+   KEYDB_RESOURCE_TYPE_KEYNONE.  If the file is a keybox and it has
+   the OpenPGP flag set, then R_OPENPGP is also set.  */
 static KeydbResourceType
 rt_from_file (const char *filename, int *r_found, int *r_openpgp)
 {
@@ -436,17 +462,14 @@ rt_from_file (const char *filename, int *r_found, int *r_openpgp)
 }
 
 
-/*
- * Register a resource (keyring or aeybox).  The first keyring or
- * keybox which is added by this function is created if it does not
- * exist.  FLAGS are a combination of the KEYDB_RESOURCE_FLAG_
- * constants as defined in keydb.h.
- */
 gpg_error_t
 keydb_add_resource (const char *url, unsigned int flags)
 {
+  /* Whether we have successfully registered a resource.  */
   static int any_registered;
+  /* The file named by the URL (i.e., without the prototype).  */
   const char *resname = url;
+
   char *filename = NULL;
   int create;
   int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY);
@@ -459,11 +482,6 @@ keydb_add_resource (const char *url, unsigned int flags)
   /* Create the resource if it is the first registered one.  */
   create = (!read_only && !any_registered);
 
-  /* Do we have an URL?
-   *   gnupg-ring:filename  := this is a plain keyring.
-   *   gnupg-kbx:filename   := this is a keybox file.
-   *   filename := See what is is, but create as plain keyring.
-   */
   if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) )
     {
       rt = KEYDB_RESOURCE_TYPE_KEYRING;
@@ -750,9 +768,6 @@ keydb_release (KEYDB_HANDLE hd)
 }
 
 
-/* Set a flag on handle to not use cached results.  This is required
-   for updating a keyring and for key listins.  Fixme: Using a new
-   parameter for keydb_new might be a better solution.  */
 void
 keydb_disable_caching (KEYDB_HANDLE hd)
 {
@@ -761,14 +776,6 @@ keydb_disable_caching (KEYDB_HANDLE hd)
 }
 
 
-/*
- * Return the name of the current resource.  This is function first
- * looks for the last found found, then for the current search
- * position, and last returns the first available resource.  The
- * returned string is only valid as long as the handle exists.  This
- * function does only return NULL if no handle is specified, in all
- * other error cases an empty string is returned.
- */
 const char *
 keydb_get_resource_name (KEYDB_HANDLE hd)
 {
@@ -882,7 +889,6 @@ unlock_all (KEYDB_HANDLE hd)
 
 
 \f
-/* Push the last found state if any.  */
 void
 keydb_push_found_state (KEYDB_HANDLE hd)
 {
@@ -912,7 +918,6 @@ keydb_push_found_state (KEYDB_HANDLE hd)
 }
 
 
-/* Pop the last found state.  */
 void
 keydb_pop_found_state (KEYDB_HANDLE hd)
 {
@@ -1103,12 +1108,6 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
 }
 
 
-/*
- * Return the last found keyring.  Caller must free it.
- * The returned keyblock has the kbode flag bit 0 set for the node with
- * the public key used to locate the keyblock or flag bit 1 set for
- * the user ID node.
- */
 gpg_error_t
 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
 {
@@ -1279,9 +1278,6 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf, u32 **r_sigstatus)
 }
 
 
-/*
- * Update the current keyblock with the keyblock KB
- */
 gpg_error_t
 keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
 {
@@ -1332,9 +1328,6 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
 }
 
 
-/*
- * Insert a new KB into one of the resources.
- */
 gpg_error_t
 keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
 {
@@ -1396,9 +1389,6 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
 }
 
 
-/*
- * Delete the current keyblock.
- */
 gpg_error_t
 keydb_delete_keyblock (KEYDB_HANDLE hd)
 {
@@ -1439,11 +1429,6 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
 
 
 \f
-/*
- * Locate the default writable key resource, so that the next
- * operation (which is only relevant for inserts) will be done on this
- * resource.
- */
 gpg_error_t
 keydb_locate_writable (KEYDB_HANDLE hd)
 {
@@ -1496,9 +1481,6 @@ keydb_locate_writable (KEYDB_HANDLE hd)
   return gpg_error (GPG_ERR_NOT_FOUND);
 }
 
-/*
- * Rebuild the caches of all key resources.
- */
 void
 keydb_rebuild_caches (int noisy)
 {
@@ -1528,7 +1510,6 @@ keydb_rebuild_caches (int noisy)
 }
 
 
-/* Return the number of skipped blocks since the last search reset.  */
 unsigned long
 keydb_get_skipped_counter (KEYDB_HANDLE hd)
 {
@@ -1536,9 +1517,6 @@ keydb_get_skipped_counter (KEYDB_HANDLE hd)
 }
 
 
-/*
- * Start the next search on this handle right at the beginning
- */
 gpg_error_t
 keydb_search_reset (KEYDB_HANDLE hd)
 {
@@ -1626,18 +1604,13 @@ dump_search_desc (KEYDB_HANDLE hd, const char *text,
 }
 
 
-/*
- * Search through all keydb resources, starting at the current
- * position, for a keyblock which contains one of the keys described
- * in the DESC array.  Returns GPG_ERR_NOT_FOUND if no matching
- * keyring was found.
- */
 gpg_error_t
 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
               size_t ndesc, size_t *descindex)
 {
   gpg_error_t rc;
   int was_reset = hd->is_reset;
+  /* If an entry is already in the cache, then don't add it again.  */
   int already_in_cache = 0;
 
   if (descindex)
@@ -1732,8 +1705,6 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
 }
 
 
-/* Note that in contrast to using keydb_search in search first mode,
-   this function skips legacy keys.  */
 gpg_error_t
 keydb_search_first (KEYDB_HANDLE hd)
 {
@@ -1753,8 +1724,6 @@ keydb_search_first (KEYDB_HANDLE hd)
 }
 
 
-/* Note that in contrast to using keydb_search in search next mode,
-   this fucntion skips legacy keys.  */
 gpg_error_t
 keydb_search_next (KEYDB_HANDLE hd)
 {
index 1086450..a943ded 100644 (file)
@@ -1,6 +1,7 @@
 /* keydb.h - Key database
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  *               2006, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2015 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -132,28 +133,212 @@ union pref_hint
 #define KEYDB_RESOURCE_FLAG_READONLY 8  /* Open in read only mode.  */
 #define KEYDB_RESOURCE_FLAG_GPGVDEF 16  /* Default file for gpgv.  */
 
+/* Register a resource (keyring or keybox).  The first keyring or
+   keybox that is added using this function is created if it does not
+   already exist and the KEYDB_RESOURCE_FLAG_READONLY is not set.
+
+   FLAGS are a combination of the KEYDB_RESOURCE_FLAG_* constants.
+
+   URL must have the following form:
+
+     gnupg-ring:filename  = plain keyring
+     gnupg-kbx:filename   = keybox file
+     filename             = check file's type (create as a plain keyring)
+
+   Note: on systems with drive letters (Windows) invalid URLs (i.e.,
+   those with an unrecognized part before the ':' such as "c:\...")
+   will silently be treated as bare filenames.  On other systems, such
+   URLs will cause this function to return GPG_ERR_GENERAL.
+
+   If KEYDB_RESOURCE_FLAG_DEFAULT is set, the resource is a keyring
+   and the file ends in ".gpg", then this function also checks if a
+   file with the same name, but the extension ".kbx" exists, is a
+   keybox and the OpenPGP flag is set.  If so, this function opens
+   that resource instead.
+
+   If the file is not found, KEYDB_RESOURCE_FLAG_GPGVDEF is set and
+   the URL ends in ".kbx", then this function will try opening the
+   same URL, but with the extension ".gpg".  If that file is a keybox
+   with the OpenPGP flag set or it is a keyring, then we use that
+   instead.
+
+   If the file is not found, KEYDB_RESOURCE_FLAG_DEFAULT is set, the
+   file should be created and the file's extension is ".gpg" then we
+   replace the extension with ".kbx".
+
+
+   If the KEYDB_RESOURCE_FLAG_PRIMARY is set and the resource is a
+   keyring (not a keybox), then this resource is considered the
+   primary resource.  This is used by keydb_locate_writable().  If
+   another primary keyring is set, then that keyring is considered the
+   primary.
+
+   If KEYDB_RESOURCE_FLAG_READONLY is set and the resource is a
+   keyring (not a keybox), then the keyring is marked as read only and
+   operations just as keyring_insert_keyblock will return
+   GPG_ERR_ACCESS.  */
 gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
-void        keydb_dump_stats (void);
 
+/* Dump some statistics to the log.  */
+void keydb_dump_stats (void);
+
+/* Create a new database handle.  A database handle is similar to a
+   file handle: it contains a local file position.  This is used when
+   searching: subsequent searches resume where the previous search
+   left off.  To rewind the position, use keydb_search_reset().  */
 KEYDB_HANDLE keydb_new (void);
+
+/* Free all resources owned by the database handle.  */
 void keydb_release (KEYDB_HANDLE hd);
+
+/* Set a flag on the handle to suppress use of cached results.  This
+   is required for updating a keyring and for key listings.  Fixme:
+   Using a new parameter for keydb_new might be a better solution.  */
 void keydb_disable_caching (KEYDB_HANDLE hd);
+
+/* Save the last found state and invalidate the current selection
+   (i.e., the entry selected by keydb_search() is invalidated and
+   something like keydb_get_keyblock() will return an error).  This
+   does not change the file position.  This makes it possible to do
+   something like:
+
+     keydb_search (hd, ...);  // Result 1.
+     keydb_push_found_state (hd);
+       keydb_search_reset (hd);
+       keydb_search (hd, ...);  // Result 2.
+     keydb_pop_found_state (hd);
+     keydb_get_keyblock (hd, ...);  // -> Result 1.
+
+   Note: it is only possible to save a single save state at a time.
+   In other words, the the save stack only has room for a single
+   instance of the state.  */
 void keydb_push_found_state (KEYDB_HANDLE hd);
+
+/* Restore the previous save state.  If the saved state is invalid,
+   this is equivalent to */
 void keydb_pop_found_state (KEYDB_HANDLE hd);
+
+/* Return the file name of the resource in which the current search
+   result was found or, if there is no search result, the filename of
+   the current resource (i.e., the resource that the file position
+   points to).  Note: the filename is not necessarily the URL used to
+   open it!
+
+   This function only returns NULL if no handle is specified, in all
+   other error cases an empty string is returned.  */
 const char *keydb_get_resource_name (KEYDB_HANDLE hd);
+
+/* Return the keyblock last found by keydb_search() in *RET_KB.
+
+   On success, the function returns 0 and the caller must free *RET_KB
+   using release_kbnode().  Otherwise, the function returns an error
+   code.
+
+   The returned keyblock has the kbnode flag bit 0 set for the node
+   with the public key used to locate the keyblock or flag bit 1 set
+   for the user ID node.  */
 gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
+
+/* Replace the currently selected keyblock (i.e., the last result
+   returned by keydb_search) with the key block in KB.
+
+   This doesn't do anything if --dry-run was specified.
+
+   Returns 0 on success.  Otherwise, it returns an error code.  */
 gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
+
+/* Insert a keyblock into one of the underlying keyrings or keyboxes.
+
+   Be default, the keyring / keybox from which the last search result
+   came is used.  If there was no previous search result (or
+   keydb_search_reset was called), then the keyring / keybox where the
+   next search would start is used (i.e., the current file position).
+
+   Note: this doesn't do anything if --dry-run was specified.
+
+   Returns 0 on success.  Otherwise, it returns an error code.  */
 gpg_error_t keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb);
+
+/* Delete the currently selected keyblock.  If you haven't done a
+   search yet on this database handle (or called keydb_search_reset),
+   then this will return an error.
+
+   Returns 0 on success or an error code, if an error occurs.  */
 gpg_error_t keydb_delete_keyblock (KEYDB_HANDLE hd);
+
+/* A database may consists of multiple keyrings / key boxes.  This
+   sets the "file position" to the start of the first keyring / key
+   box that is writable (i.e., doesn't have the read-only flag set).
+
+   This first tries the primary keyring (the last keyring (not
+   keybox!) added using keydb_add_resource() and with
+   KEYDB_RESOURCE_FLAG_PRIMARY set).  If that is not writable, then it
+   tries the keyrings / keyboxes in the order in which they were
+   added.  */
 gpg_error_t keydb_locate_writable (KEYDB_HANDLE hd);
+
+/* Rebuild the on-disk caches of all key resources.  */
 void keydb_rebuild_caches (int noisy);
+
+/* Return the number of skipped blocks (because they were to large to
+   read from a keybox) since the last search reset.  */
 unsigned long keydb_get_skipped_counter (KEYDB_HANDLE hd);
+
+/* Clears the current search result and resets the handle's position
+   so that the next search starts at the beginning of the database
+   (the start of the first resource).
+
+   Returns 0 on success and an error code if an error occured.
+   (Currently, this function always returns 0 if HD is valid.)  */
 gpg_error_t keydb_search_reset (KEYDB_HANDLE hd);
+
+/* Search the database for keys matching the search description.
+
+   DESC is an array of search terms with NDESC entries.  The search
+   terms are or'd together.  That is, the next entry in the DB that
+   matches any of the descriptions will be returned.
+
+   Note: this function resumes searching where the last search left
+   off (i.e., at the current file position).  If you want to search
+   from the start of the database, then you need to first call
+   keydb_search_reset().
+
+   If no key matches the search description, returns
+   GPG_ERR_NOT_FOUND.  If there was a match, returns 0.  If an error
+   occured, returns an error code.
+
+   The returned key is considered to be selected and the raw data can,
+   for instance, be returned by calling keydb_get_keyblock().  */
 gpg_error_t keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
                           size_t ndesc, size_t *descindex);
+
+/* Return the first non-legacy key in the database.
+
+   If you want the very first key in the database, you can directly
+   call keydb_search with the search description
+   KEYDB_SEARCH_MODE_FIRST.  */
 gpg_error_t keydb_search_first (KEYDB_HANDLE hd);
+
+/* Return the next key (not the next matching key!).
+
+   Unlike calling keydb_search with KEYDB_SEARCH_MODE_NEXT, this
+   function silently skips legacy keys.  */
 gpg_error_t keydb_search_next (KEYDB_HANDLE hd);
+
+/* This is a convenience function for searching for keys with a long
+   key id.
+
+   Note: this function resumes searching where the last search left
+   off.  If you want to search the whole database, then you need to
+   first call keydb_search_reset().  */
 gpg_error_t keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
+
+/* This is a convenience function for searching for keys with a long
+   (20 byte) fingerprint.  This function ignores legacy keys.
+
+   Note: this function resumes searching where the last search left
+   off.  If you want to search the whole database, then you need to
+   first call keydb_search_reset().  */
 gpg_error_t keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);