Page MenuHome GnuPG

No OneTemporary

diff --git a/g10/keydb.h b/g10/keydb.h
index 882af35cf..b1dfa08c7 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -1,836 +1,837 @@
/* 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.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef G10_KEYDB_H
#define G10_KEYDB_H
#include <assuan.h>
#include "types.h"
#include "util.h"
#include "packet.h"
/* What qualifies as a certification (rather than a signature?) */
#define IS_CERT(s) (IS_KEY_SIG(s) || IS_UID_SIG(s) || IS_SUBKEY_SIG(s) \
|| IS_KEY_REV(s) || IS_UID_REV(s) || IS_SUBKEY_REV(s))
#define IS_SIG(s) (!IS_CERT(s))
#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18)
#define IS_KEY_REV(s) ((s)->sig_class == 0x20)
#define IS_UID_REV(s) ((s)->sig_class == 0x30)
#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28)
struct getkey_ctx_s;
typedef struct getkey_ctx_s *GETKEY_CTX;
typedef struct getkey_ctx_s *getkey_ctx_t;
/****************
* A Keyblock is all packets which form an entire certificate;
* i.e. the public key, certificate, trust packets, user ids,
* signatures, and subkey.
*
* This structure is also used to bind arbitrary packets together.
*/
struct kbnode_struct {
KBNODE next;
PACKET *pkt;
int flag;
int private_flag;
ulong recno; /* used while updating the trustdb */
};
#define is_deleted_kbnode(a) ((a)->private_flag & 1)
#define is_cloned_kbnode(a) ((a)->private_flag & 2)
enum resource_type {
rt_UNKNOWN = 0,
rt_RING = 1
};
/****************
* A data structure to hold information about the external position
* of a keyblock.
*/
struct keyblock_pos_struct {
int resno; /* resource number */
enum resource_type rt;
off_t offset; /* position information */
unsigned count; /* length of the keyblock in packets */
iobuf_t fp; /* Used by enum_keyblocks. */
int secret; /* working on a secret keyring */
PACKET *pkt; /* ditto */
int valid;
};
typedef struct keyblock_pos_struct KBPOS;
/* Structure to hold a couple of public key certificates. */
typedef struct pk_list *PK_LIST; /* Deprecated. */
typedef struct pk_list *pk_list_t;
struct pk_list
{
PK_LIST next;
PKT_public_key *pk;
int flags; /* flag bit 1==throw_keyid */
};
/* Structure to hold a list of secret key certificates. */
typedef struct sk_list *SK_LIST;
struct sk_list
{
SK_LIST next;
PKT_public_key *pk;
int mark; /* not used */
};
/* structure to collect all information which can be used to
* identify a public key */
typedef struct pubkey_find_info *PUBKEY_FIND_INFO;
struct pubkey_find_info {
u32 keyid[2];
unsigned nbits;
byte pubkey_algo;
byte fingerprint[MAX_FINGERPRINT_LEN];
char userid[1];
};
typedef struct keydb_handle *KEYDB_HANDLE;
/* Helper type for preference fucntions. */
union pref_hint
{
int digest_length;
};
/*-- keydb.c --*/
#define KEYDB_RESOURCE_FLAG_PRIMARY 2 /* The primary resource. */
#define KEYDB_RESOURCE_FLAG_DEFAULT 4 /* The default one. */
#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);
/* 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 occurred.
(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
occurred, 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);
/*-- pkclist.c --*/
void show_revocation_reason( PKT_public_key *pk, int mode );
int check_signatures_trust( PKT_signature *sig );
void release_pk_list (PK_LIST pk_list);
int build_pk_list (ctrl_t ctrl,
strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use);
gpg_error_t find_and_check_key (ctrl_t ctrl,
const char *name, unsigned int use,
int mark_hidden, pk_list_t *pk_list_addr);
int algo_available( preftype_t preftype, int algo,
const union pref_hint *hint );
int select_algo_from_prefs( PK_LIST pk_list, int preftype,
int request, const union pref_hint *hint);
int select_mdc_from_pklist (PK_LIST pk_list);
void warn_missing_mdc_from_pklist (PK_LIST pk_list);
void warn_missing_aes_from_pklist (PK_LIST pk_list);
/*-- skclist.c --*/
int random_is_faked (void);
void release_sk_list( SK_LIST sk_list );
gpg_error_t build_sk_list (ctrl_t ctrl, strlist_t locusr,
SK_LIST *ret_sk_list, unsigned use);
/*-- passphrase.h --*/
unsigned char encode_s2k_iterations (int iterations);
assuan_context_t agent_open (int try, const char *orig_codeset);
void agent_close (assuan_context_t ctx);
int have_static_passphrase(void);
const char *get_static_passphrase (void);
void set_passphrase_from_string(const char *pass);
void read_passphrase_from_fd( int fd );
void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo );
DEK *passphrase_to_dek_ext(u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode,
const char *tryagain_text,
const char *custdesc, const char *custprompt,
int *canceled);
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode,
const char *tryagain_text, int *canceled);
void set_next_passphrase( const char *s );
char *get_last_passphrase(void);
void next_to_last_passphrase(void);
void emit_status_need_passphrase (u32 *keyid, u32 *mainkeyid, int pubkey_algo);
#define FORMAT_KEYDESC_NORMAL 0
#define FORMAT_KEYDESC_IMPORT 1
#define FORMAT_KEYDESC_EXPORT 2
#define FORMAT_KEYDESC_DELKEY 3
char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped);
/*-- 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 );
/* 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);
/* 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 definitely been merged into the public key using
merge_selfsigs. */
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 );
/* 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 );
/* 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,
GETKEY_CTX *retctx, PKT_public_key *pk,
const char *name,
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
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);
/* 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,
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,
const byte *fprint, size_t fprint_len);
/* Return whether a secret key is available for the public key with
key id KEYID. This function ignores legacy keys. Note: this is
just a fast check and does not tell us whether the secret key is
valid; this check merely indicates whether there is some secret key
with the specified key id. */
int have_secret_key_with_kid (u32 *keyid);
/* Parse the --default-key parameter. Returns the last key (in terms
of when the option is given) that is available. */
const char *parse_def_secret_key (ctrl_t ctrl);
/* 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 (ctrl_t ctrl, 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,
strlist_t names, int want_secret,
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 (ctrl_t ctrl,
getkey_ctx_t *retctx, PKT_public_key *pk,
const char *name, int want_secret,
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,
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);
/* 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 occurred.
*/
gpg_error_t enum_secret_keys (ctrl_t ctrl, 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);
/* 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 );
char*get_user_id_string_native( u32 *keyid );
char*get_long_user_id_string( u32 *keyid );
char*get_user_id( u32 *keyid, size_t *rn );
char*get_user_id_native( u32 *keyid );
char *get_user_id_byfpr (const byte *fpr, size_t *rn);
char *get_user_id_byfpr_native (const byte *fpr);
void release_akl(void);
int parse_auto_key_locate(char *options);
/*-- keyid.c --*/
int pubkey_letter( int algo );
char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize);
#define PUBKEY_STRING_SIZE 32
u32 v3_keyid (gcry_mpi_t a, u32 *ki);
void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk );
+const char *format_keyid (u32 *keyid, int format, char *buffer, int len);
size_t keystrlen(void);
const char *keystr(u32 *keyid);
const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid);
const char *keystr_from_pk(PKT_public_key *pk);
const char *keystr_from_pk_with_sub (PKT_public_key *main_pk,
PKT_public_key *sub_pk);
const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
u32 keyid_from_fingerprint(const byte *fprint, size_t fprint_len, u32 *keyid);
byte *namehash_from_uid(PKT_user_id *uid);
unsigned nbits_from_pk( PKT_public_key *pk );
const char *datestr_from_pk( PKT_public_key *pk );
const char *datestr_from_sig( PKT_signature *sig );
const char *expirestr_from_pk( PKT_public_key *pk );
const char *expirestr_from_sig( PKT_signature *sig );
const char *revokestr_from_pk( PKT_public_key *pk );
const char *usagestr_from_pk (PKT_public_key *pk, int fill);
const char *colon_strtime (u32 t);
const char *colon_datestr_from_pk (PKT_public_key *pk);
const char *colon_datestr_from_sig (PKT_signature *sig);
const char *colon_expirestr_from_sig (PKT_signature *sig);
byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen);
char *format_hexfingerprint (const char *fingerprint,
char *buffer, size_t buflen);
gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array);
gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip);
/*-- kbnode.c --*/
KBNODE new_kbnode( PACKET *pkt );
KBNODE clone_kbnode( KBNODE node );
void release_kbnode( KBNODE n );
void delete_kbnode( KBNODE node );
void add_kbnode( KBNODE root, KBNODE node );
void insert_kbnode( KBNODE root, KBNODE node, int pkttype );
void move_kbnode( KBNODE *root, KBNODE node, KBNODE where );
void remove_kbnode( KBNODE *root, KBNODE node );
KBNODE find_prev_kbnode( KBNODE root, KBNODE node, int pkttype );
KBNODE find_next_kbnode( KBNODE node, int pkttype );
KBNODE find_kbnode( KBNODE node, int pkttype );
KBNODE walk_kbnode( KBNODE root, KBNODE *context, int all );
void clear_kbnode_flags( KBNODE n );
int commit_kbnode( KBNODE *root );
void dump_kbnode( KBNODE node );
#endif /*G10_KEYDB_H*/
diff --git a/g10/keyid.c b/g10/keyid.c
index d71698594..cb237ef54 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -1,892 +1,908 @@
/* keyid.c - key ID and fingerprint handling
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
* 2004, 2006, 2010 Free Software Foundation, Inc.
* Copyright (C) 2014 Werner Koch
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <assert.h>
#include "gpg.h"
#include "util.h"
#include "main.h"
#include "packet.h"
#include "options.h"
#include "keydb.h"
#include "i18n.h"
#include "rmd160.h"
#include "host2net.h"
#define KEYID_STR_SIZE 19
#ifdef HAVE_UNSIGNED_TIME_T
# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
#else
/* Error or 32 bit time_t and value after 2038-01-19. */
# define IS_INVALID_TIME_T(a) ((a) < 0)
#endif
/* Return a letter describing the public key algorithms. */
int
pubkey_letter( int algo )
{
switch (algo)
{
case PUBKEY_ALGO_RSA: return 'R' ;
case PUBKEY_ALGO_RSA_E: return 'r' ;
case PUBKEY_ALGO_RSA_S: return 's' ;
case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
case PUBKEY_ALGO_ELGAMAL: return 'G' ;
case PUBKEY_ALGO_DSA: return 'D' ;
case PUBKEY_ALGO_ECDH: return 'e' ; /* ECC DH (encrypt only) */
case PUBKEY_ALGO_ECDSA: return 'E' ; /* ECC DSA (sign only) */
case PUBKEY_ALGO_EDDSA: return 'E' ; /* ECC EdDSA (sign only) */
default: return '?';
}
}
/* Return a string describing the public key algorithm and the
keysize. For elliptic curves the functions prints the name of the
curve because the keysize is a property of the curve. The string
is copied to the supplied buffer up a length of BUFSIZE-1.
Examples for the output are:
"rsa2048" - RSA with 2048 bit
"elg1024" - Elgamal with 1024 bit
"ed25519" - ECC using the curve Ed25519.
"E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4".
"E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
"unknown_N" - Unknown OpenPGP algorithm N.
If the option --legacy-list-mode is active, the output use the
legacy format:
"2048R" - RSA with 2048 bit
"1024g" - Elgamal with 1024 bit
"256E" - ECDSA using a curve with 256 bit
The macro PUBKEY_STRING_SIZE may be used to allocate a buffer with
a suitable size.*/
char *
pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
{
const char *prefix = NULL;
if (opt.legacy_list_mode)
{
snprintf (buffer, bufsize, "%4u%c",
nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo));
return buffer;
}
switch (pk->pubkey_algo)
{
case PUBKEY_ALGO_RSA:
case PUBKEY_ALGO_RSA_E:
case PUBKEY_ALGO_RSA_S: prefix = "rsa"; break;
case PUBKEY_ALGO_ELGAMAL_E: prefix = "elg"; break;
case PUBKEY_ALGO_DSA: prefix = "dsa"; break;
case PUBKEY_ALGO_ELGAMAL: prefix = "xxx"; break;
case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA: prefix = ""; break;
}
if (prefix && *prefix)
snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
else if (prefix)
{
char *curve = openpgp_oid_to_str (pk->pkey[0]);
const char *name = openpgp_oid_to_curve (curve, 0);
if (name)
snprintf (buffer, bufsize, "%s", name);
else if (curve)
snprintf (buffer, bufsize, "E_%s", curve);
else
snprintf (buffer, bufsize, "E_error");
xfree (curve);
}
else
snprintf (buffer, bufsize, "unknown_%u", (unsigned int)pk->pubkey_algo);
return buffer;
}
/* Hash a public key. This function is useful for v4 fingerprints and
for v3 or v4 key signing. */
void
hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
{
unsigned int n = 6;
unsigned int nn[PUBKEY_MAX_NPKEY];
byte *pp[PUBKEY_MAX_NPKEY];
int i;
unsigned int nbits;
size_t nbytes;
int npkey = pubkey_get_npkey (pk->pubkey_algo);
/* FIXME: We can avoid the extra malloc by calling only the first
mpi_print here which computes the required length and calling the
real mpi_print only at the end. The speed advantage would only be
for ECC (opaque MPIs) or if we could implement an mpi_print
variant with a callback handler to do the hashing. */
if (npkey==0 && pk->pkey[0]
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
{
pp[0] = gcry_mpi_get_opaque (pk->pkey[0], &nbits);
nn[0] = (nbits+7)/8;
n+=nn[0];
}
else
{
for (i=0; i < npkey; i++ )
{
if (!pk->pkey[i])
{
/* This case may only happen if the parsing of the MPI
failed but the key was anyway created. May happen
during "gpg KEYFILE". */
pp[i] = NULL;
nn[i] = 0;
}
else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
{
const void *p;
p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
pp[i] = xmalloc ((nbits+7)/8);
if (p)
memcpy (pp[i], p, (nbits+7)/8);
else
pp[i] = NULL;
nn[i] = (nbits+7)/8;
n += nn[i];
}
else
{
if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
&nbytes, pk->pkey[i]))
BUG ();
pp[i] = xmalloc (nbytes);
if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
&nbytes, pk->pkey[i]))
BUG ();
nn[i] = nbytes;
n += nn[i];
}
}
}
gcry_md_putc ( md, 0x99 ); /* ctb */
/* What does it mean if n is greater than than 0xFFFF ? */
gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
gcry_md_putc ( md, n );
gcry_md_putc ( md, pk->version );
gcry_md_putc ( md, pk->timestamp >> 24 );
gcry_md_putc ( md, pk->timestamp >> 16 );
gcry_md_putc ( md, pk->timestamp >> 8 );
gcry_md_putc ( md, pk->timestamp );
gcry_md_putc ( md, pk->pubkey_algo );
if(npkey==0 && pk->pkey[0]
&& gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
{
if (pp[0])
gcry_md_write (md, pp[0], nn[0]);
}
else
{
for(i=0; i < npkey; i++ )
{
if (pp[i])
gcry_md_write ( md, pp[i], nn[i] );
xfree(pp[i]);
}
}
}
static gcry_md_hd_t
do_fingerprint_md( PKT_public_key *pk )
{
gcry_md_hd_t md;
if (gcry_md_open (&md, DIGEST_ALGO_SHA1, 0))
BUG ();
hash_public_key(md,pk);
gcry_md_final( md );
return md;
}
/* fixme: Check whether we can replace this function or if not
describe why we need it. */
u32
v3_keyid (gcry_mpi_t a, u32 *ki)
{
byte *buffer, *p;
size_t nbytes;
if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a ))
BUG ();
/* fixme: allocate it on the stack */
buffer = xmalloc (nbytes);
if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a ))
BUG ();
if (nbytes < 8) /* oops */
ki[0] = ki[1] = 0;
else
{
p = buffer + nbytes - 8;
ki[0] = buf32_to_u32 (p);
p += 4;
ki[1] = buf32_to_u32 (p);
}
xfree (buffer);
return ki[1];
}
-size_t
-keystrlen(void)
+const char *
+format_keyid (u32 *keyid, int format, char *buffer, int len)
{
- switch(opt.keyid_format)
+ char tmp[KEYID_STR_SIZE];
+ if (! buffer)
+ buffer = tmp;
+
+ if (format == KF_DEFAULT)
+ format = opt.keyid_format;
+ if (format == KF_DEFAULT)
+ format = KF_0xLONG;
+
+ switch (format)
{
case KF_SHORT:
- return 8;
+ snprintf (buffer, len, "%08lX", (ulong)keyid[1]);
+ break;
case KF_LONG:
- return 16;
+ if (keyid[0])
+ snprintf (buffer, len, "%08lX%08lX",
+ (ulong)keyid[0], (ulong)keyid[1]);
+ else
+ snprintf (buffer, len, "%08lX", (ulong)keyid[1]);
+ break;
case KF_0xSHORT:
- return 10;
+ snprintf (buffer, len, "0x%08lX", (ulong)keyid[1]);
+ break;
case KF_0xLONG:
- return 18;
+ if(keyid[0])
+ snprintf (buffer, len, "0x%08lX%08lX",
+ (ulong)keyid[0],(ulong)keyid[1]);
+ else
+ snprintf (buffer, len, "0x%08lX", (ulong)keyid[1]);
+ break;
default:
BUG();
}
-}
+ if (buffer == tmp)
+ return xstrdup (buffer);
+ return buffer;
+}
-const char *
-keystr (u32 *keyid)
+size_t
+keystrlen(void)
{
- static char keyid_str[KEYID_STR_SIZE];
-
- switch (opt.keyid_format)
+ switch(opt.keyid_format)
{
case KF_SHORT:
- snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
- break;
+ return 8;
case KF_LONG:
- if (keyid[0])
- snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
- (ulong)keyid[0], (ulong)keyid[1]);
- else
- snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
- break;
+ return 16;
case KF_0xSHORT:
- snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
- break;
+ return 10;
case KF_0xLONG:
- if(keyid[0])
- snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
- (ulong)keyid[0],(ulong)keyid[1]);
- else
- snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
- break;
+ return 18;
default:
BUG();
}
+}
+
- return keyid_str;
+const char *
+keystr (u32 *keyid)
+{
+ static char keyid_str[KEYID_STR_SIZE];
+ return format_keyid (keyid, opt.keyid_format, keyid_str, sizeof (keyid_str));
}
const char *
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
{
static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
char *p;
mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
if (sub_kid)
{
p = buffer + strlen (buffer);
*p++ = '/';
mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
}
return buffer;
}
const char *
keystr_from_pk(PKT_public_key *pk)
{
keyid_from_pk(pk,NULL);
return keystr(pk->keyid);
}
const char *
keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
{
keyid_from_pk (main_pk, NULL);
if (sub_pk)
keyid_from_pk (sub_pk, NULL);
return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
}
const char *
keystr_from_desc(KEYDB_SEARCH_DESC *desc)
{
switch(desc->mode)
{
case KEYDB_SEARCH_MODE_LONG_KID:
case KEYDB_SEARCH_MODE_SHORT_KID:
return keystr(desc->u.kid);
case KEYDB_SEARCH_MODE_FPR20:
{
u32 keyid[2];
keyid[0] = buf32_to_u32 (desc->u.fpr+12);
keyid[1] = buf32_to_u32 (desc->u.fpr+16);
return keystr(keyid);
}
case KEYDB_SEARCH_MODE_FPR16:
return "?v3 fpr?";
default:
BUG();
}
}
/*
* Get the keyid from the public key and put it into keyid
* if this is not NULL. Return the 32 low bits of the keyid.
*/
u32
keyid_from_pk (PKT_public_key *pk, u32 *keyid)
{
u32 lowbits;
u32 dummy_keyid[2];
if (!keyid)
keyid = dummy_keyid;
if( pk->keyid[0] || pk->keyid[1] )
{
keyid[0] = pk->keyid[0];
keyid[1] = pk->keyid[1];
lowbits = keyid[1];
}
else
{
const byte *dp;
gcry_md_hd_t md;
md = do_fingerprint_md(pk);
if(md)
{
dp = gcry_md_read ( md, 0 );
keyid[0] = buf32_to_u32 (dp+12);
keyid[1] = buf32_to_u32 (dp+16);
lowbits = keyid[1];
gcry_md_close (md);
pk->keyid[0] = keyid[0];
pk->keyid[1] = keyid[1];
}
else
pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
}
return lowbits;
}
/*
* Get the keyid from the fingerprint. This function is simple for most
* keys, but has to do a keylookup for old stayle keys.
*/
u32
keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
{
u32 dummy_keyid[2];
if( !keyid )
keyid = dummy_keyid;
if (fprint_len != 20)
{
/* This is special as we have to lookup the key first. */
PKT_public_key pk;
int rc;
memset (&pk, 0, sizeof pk);
rc = get_pubkey_byfprint (&pk, NULL, fprint, fprint_len);
if( rc )
{
log_error("Oops: keyid_from_fingerprint: no pubkey\n");
keyid[0] = 0;
keyid[1] = 0;
}
else
keyid_from_pk (&pk, keyid);
}
else
{
const byte *dp = fprint;
keyid[0] = buf32_to_u32 (dp+12);
keyid[1] = buf32_to_u32 (dp+16);
}
return keyid[1];
}
u32
keyid_from_sig (PKT_signature *sig, u32 *keyid)
{
if( keyid )
{
keyid[0] = sig->keyid[0];
keyid[1] = sig->keyid[1];
}
return sig->keyid[1];
}
byte *
namehash_from_uid (PKT_user_id *uid)
{
if (!uid->namehash)
{
uid->namehash = xmalloc (20);
if (uid->attrib_data)
rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
else
rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
}
return uid->namehash;
}
/*
* Return the number of bits used in PK.
*/
unsigned int
nbits_from_pk (PKT_public_key *pk)
{
return pubkey_nbits (pk->pubkey_algo, pk->pkey);
}
static const char *
mk_datestr (char *buffer, time_t atime)
{
struct tm *tp;
if (IS_INVALID_TIME_T (atime))
strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
else
{
tp = gmtime (&atime);
sprintf (buffer,"%04d-%02d-%02d",
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
}
return buffer;
}
/*
* return a string with the creation date of the pk
* Note: this is alloced in a static buffer.
* Format is: yyyy-mm-dd
*/
const char *
datestr_from_pk (PKT_public_key *pk)
{
static char buffer[11+5];
time_t atime = pk->timestamp;
return mk_datestr (buffer, atime);
}
const char *
datestr_from_sig (PKT_signature *sig )
{
static char buffer[11+5];
time_t atime = sig->timestamp;
return mk_datestr (buffer, atime);
}
const char *
expirestr_from_pk (PKT_public_key *pk)
{
static char buffer[11+5];
time_t atime;
if (!pk->expiredate)
return _("never ");
atime = pk->expiredate;
return mk_datestr (buffer, atime);
}
const char *
expirestr_from_sig (PKT_signature *sig)
{
static char buffer[11+5];
time_t atime;
if (!sig->expiredate)
return _("never ");
atime=sig->expiredate;
return mk_datestr (buffer, atime);
}
const char *
revokestr_from_pk( PKT_public_key *pk )
{
static char buffer[11+5];
time_t atime;
if(!pk->revoked.date)
return _("never ");
atime=pk->revoked.date;
return mk_datestr (buffer, atime);
}
const char *
usagestr_from_pk (PKT_public_key *pk, int fill)
{
static char buffer[10];
int i = 0;
unsigned int use = pk->pubkey_usage;
if ( use & PUBKEY_USAGE_SIG )
buffer[i++] = 'S';
if ( use & PUBKEY_USAGE_CERT )
buffer[i++] = 'C';
if ( use & PUBKEY_USAGE_ENC )
buffer[i++] = 'E';
if ( (use & PUBKEY_USAGE_AUTH) )
buffer[i++] = 'A';
while (fill && i < 4)
buffer[i++] = ' ';
buffer[i] = 0;
return buffer;
}
const char *
colon_strtime (u32 t)
{
static char buf[20];
if (!t)
return "";
snprintf (buf, sizeof buf, "%lu", (ulong)t);
return buf;
}
const char *
colon_datestr_from_pk (PKT_public_key *pk)
{
static char buf[20];
snprintf (buf, sizeof buf, "%lu", (ulong)pk->timestamp);
return buf;
}
const char *
colon_datestr_from_sig (PKT_signature *sig)
{
static char buf[20];
snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
return buf;
}
const char *
colon_expirestr_from_sig (PKT_signature *sig)
{
static char buf[20];
if (!sig->expiredate)
return "";
snprintf (buf, sizeof buf,"%lu", (ulong)sig->expiredate);
return buf;
}
/*
* Return a byte array with the fingerprint for the given PK/SK
* The length of the array is returned in ret_len. Caller must free
* the array or provide an array of length MAX_FINGERPRINT_LEN.
*/
byte *
fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
{
const byte *dp;
size_t len;
gcry_md_hd_t md;
md = do_fingerprint_md(pk);
dp = gcry_md_read( md, 0 );
len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
assert( len <= MAX_FINGERPRINT_LEN );
if (!array)
array = xmalloc ( len );
memcpy (array, dp, len );
pk->keyid[0] = buf32_to_u32 (dp+12);
pk->keyid[1] = buf32_to_u32 (dp+16);
gcry_md_close( md);
if (ret_len)
*ret_len = len;
return array;
}
/* Return an allocated buffer with the fingerprint of PK formatted as
a plain hexstring. If BUFFER is NULL the result is a malloc'd
string. If BUFFER is not NULL the result will be copied into this
buffer. In the latter case BUFLEN describes the length of the
buffer; if this is too short the function terminates the process.
Returns a malloc'ed string or BUFFER. A suitable length for BUFFER
is (2*MAX_FINGERPRINT_LEN + 1). */
char *
hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
{
unsigned char fpr[MAX_FINGERPRINT_LEN];
size_t len;
fingerprint_from_pk (pk, fpr, &len);
if (!buffer)
buffer = xmalloc (2 * len + 1);
else if (buflen < 2*len+1)
log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
bin2hex (fpr, len, buffer);
return buffer;
}
/* Pretty print a hex fingerprint. If BUFFER is NULL the result is a
malloc'd string. If BUFFER is not NULL the result will be copied
into this buffer. In the latter case BUFLEN describes the length
of the buffer; if this is too short the function terminates the
process. Returns a malloc'ed string or BUFFER. A suitable length
for BUFFER is (MAX_FORMATTED_FINGERPRINT_LEN + 1). */
char *
format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
{
int hexlen = strlen (fingerprint);
int space;
int i, j;
if (hexlen == 40) /* v4 fingerprint */
{
space = (/* The characters and the NUL. */
40 + 1
/* After every fourth character, we add a space (except
the last). */
+ 40 / 4 - 1
/* Half way through we add a second space. */
+ 1);
}
else /* Other fingerprint versions - print as is. */
{
space = hexlen + 1;
}
if (!buffer)
buffer = xmalloc (space);
else if (buflen < space)
log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
if (hexlen == 40) /* v4 fingerprint */
{
for (i = 0, j = 0; i < 40; i ++)
{
if (i && i % 4 == 0)
buffer[j ++] = ' ';
if (i == 40 / 2)
buffer[j ++] = ' ';
buffer[j ++] = fingerprint[i];
}
buffer[j ++] = 0;
assert (j == space);
}
else
{
strcpy (buffer, fingerprint);
}
return buffer;
}
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
key parameters expressed as an canoncial encoded S-Exp. ARRAY must
be 20 bytes long. Returns 0 on success or an error code. */
gpg_error_t
keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
{
gpg_error_t err;
gcry_sexp_t s_pkey;
if (DBG_PACKET)
log_debug ("get_keygrip for public key\n");
switch (pk->pubkey_algo)
{
case GCRY_PK_DSA:
err = gcry_sexp_build (&s_pkey, NULL,
"(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
pk->pkey[0], pk->pkey[1],
pk->pkey[2], pk->pkey[3]);
break;
case GCRY_PK_ELG:
case GCRY_PK_ELG_E:
err = gcry_sexp_build (&s_pkey, NULL,
"(public-key(elg(p%m)(g%m)(y%m)))",
pk->pkey[0], pk->pkey[1], pk->pkey[2]);
break;
case GCRY_PK_RSA:
case GCRY_PK_RSA_S:
case GCRY_PK_RSA_E:
err = gcry_sexp_build (&s_pkey, NULL,
"(public-key(rsa(n%m)(e%m)))",
pk->pkey[0], pk->pkey[1]);
break;
case PUBKEY_ALGO_EDDSA:
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_ECDH:
{
char *curve = openpgp_oid_to_str (pk->pkey[0]);
if (!curve)
err = gpg_error_from_syserror ();
else
{
err = gcry_sexp_build (&s_pkey, NULL,
pk->pubkey_algo == PUBKEY_ALGO_EDDSA?
"(public-key(ecc(curve%s)(flags eddsa)(q%m)))":
(pk->pubkey_algo == PUBKEY_ALGO_ECDH
&& openpgp_oid_is_crv25519 (pk->pkey[0]))?
"(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))":
"(public-key(ecc(curve%s)(q%m)))",
curve, pk->pkey[1]);
xfree (curve);
}
}
break;
default:
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
break;
}
if (err)
return err;
if (!gcry_pk_get_keygrip (s_pkey, array))
{
log_info ("error computing keygrip\n");
memset (array, 0, 20);
err = gpg_error (GPG_ERR_GENERAL);
}
else
{
if (DBG_PACKET)
log_printhex ("keygrip=", array, 20);
/* FIXME: Save the keygrip in PK. */
}
gcry_sexp_release (s_pkey);
return 0;
}
/* Store an allocated buffer with the keygrip of PK encoded as a
hexstring at r_GRIP. Returns 0 on success. */
gpg_error_t
hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
{
gpg_error_t err;
unsigned char grip[20];
*r_grip = NULL;
err = keygrip_from_pk (pk, grip);
if (!err)
{
char * buf = xtrymalloc (20*2+1);
if (!buf)
err = gpg_error_from_syserror ();
else
{
bin2hex (grip, 20, buf);
*r_grip = buf;
}
}
return err;
}
diff --git a/g10/options.h b/g10/options.h
index 6fca714dd..0bb2aaee6 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -1,387 +1,387 @@
/* options.h
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
* 2007, 2010, 2011 Free Software Foundation, Inc.
* Copyright (C) 2015 g10 Code GmbH
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef G10_OPTIONS_H
#define G10_OPTIONS_H
#include <sys/types.h>
#include <types.h>
#include "main.h"
#include "packet.h"
#include "tofu.h"
#include "../common/session-env.h"
#ifndef EXTERN_UNLESS_MAIN_MODULE
/* Norcraft can't cope with common symbols */
#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
#define EXTERN_UNLESS_MAIN_MODULE extern
#else
#define EXTERN_UNLESS_MAIN_MODULE
#endif
#endif
/* Declaration of a keyserver spec type. The definition is found in
../common/keyserver.h. */
struct keyserver_spec;
typedef struct keyserver_spec *keyserver_spec_t;
/* Global options for GPG. */
EXTERN_UNLESS_MAIN_MODULE
struct
{
int verbose;
int quiet;
unsigned debug;
int armor;
char *outfile;
estream_t outfp; /* Hack, sometimes used in place of outfile. */
off_t max_output;
int dry_run;
int autostart;
int list_only;
int textmode;
int expert;
const char *def_sig_expire;
int ask_sig_expire;
const char *def_cert_expire;
int ask_cert_expire;
int batch; /* run in batch mode */
int answer_yes; /* answer yes on most questions */
int answer_no; /* answer no on most questions */
int check_sigs; /* check key signatures */
int with_colons;
int with_key_data;
int with_icao_spelling; /* Print ICAO spelling with fingerprints. */
int with_fingerprint; /* Option --with-fingerprint active. */
int with_keygrip; /* Option --with-keygrip active. */
int with_secret; /* Option --with-secret active. */
int fingerprint; /* list fingerprints */
int list_sigs; /* list signatures */
int print_pka_records;
int print_dane_records;
int no_armor;
int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
int def_cipher_algo;
int force_mdc;
int disable_mdc;
int def_digest_algo;
int cert_digest_algo;
int compress_algo;
int compress_level;
int bz2_compress_level;
int bz2_decompress_lowmem;
strlist_t def_secret_key;
char *def_recipient;
int def_recipient_self;
strlist_t secret_keys_to_try;
int def_cert_level;
int min_cert_level;
int ask_cert_level;
int emit_version; /* 0 = none,
1 = major only,
2 = major and minor,
3 = full version,
4 = full version plus OS string. */
int marginals_needed;
int completes_needed;
int max_cert_depth;
const char *homedir;
const char *agent_program;
const char *dirmngr_program;
/* Options to be passed to the gpg-agent */
session_env_t session_env;
char *lc_ctype;
char *lc_messages;
int skip_verify;
int skip_hidden_recipients;
/* TM_CLASSIC must be zero to accommodate trustdbs generated before
we started storing the trust model inside the trustdb. */
enum
{
TM_CLASSIC=0, TM_PGP=1, TM_EXTERNAL=2,
TM_ALWAYS, TM_DIRECT, TM_AUTO, TM_TOFU, TM_TOFU_PGP
} trust_model;
enum
{
TOFU_DB_AUTO=0, TOFU_DB_SPLIT, TOFU_DB_FLAT
} tofu_db_format;
enum tofu_policy tofu_default_policy;
int force_ownertrust;
enum
{
CO_GNUPG, CO_RFC4880, CO_RFC2440,
CO_PGP6, CO_PGP7, CO_PGP8
} compliance;
enum
{
- KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
+ KF_DEFAULT, KF_SHORT, KF_LONG, KF_0xSHORT, KF_0xLONG
} keyid_format;
int shm_coprocess;
const char *set_filename;
strlist_t comments;
int throw_keyids;
const char *photo_viewer;
int s2k_mode;
int s2k_digest_algo;
int s2k_cipher_algo;
unsigned char s2k_count; /* This is the encoded form, not the raw
count */
int not_dash_escaped;
int escape_from;
int lock_once;
keyserver_spec_t keyserver; /* The list of configured keyservers. */
struct
{
unsigned int options;
unsigned int import_options;
unsigned int export_options;
char *http_proxy;
} keyserver_options;
int exec_disable;
int exec_path_set;
unsigned int import_options;
unsigned int export_options;
unsigned int list_options;
unsigned int verify_options;
const char *def_preference_list;
const char *def_keyserver_url;
prefitem_t *personal_cipher_prefs;
prefitem_t *personal_digest_prefs;
prefitem_t *personal_compress_prefs;
struct weakhash *weak_digests;
int no_perm_warn;
int no_mdc_warn;
char *temp_dir;
int no_encrypt_to;
int encrypt_to_default_key;
int interactive;
struct notation *sig_notations;
struct notation *cert_notations;
strlist_t sig_policy_url;
strlist_t cert_policy_url;
strlist_t sig_keyserver_url;
strlist_t cert_subpackets;
strlist_t sig_subpackets;
int allow_non_selfsigned_uid;
int allow_freeform_uid;
int no_literal;
ulong set_filesize;
int fast_list_mode;
int legacy_list_mode;
int ignore_time_conflict;
int ignore_valid_from;
int ignore_crc_error;
int ignore_mdc_error;
int command_fd;
const char *override_session_key;
int show_session_key;
const char *gpg_agent_info;
int try_all_secrets;
int no_expensive_trust_checks;
int no_sig_cache;
int no_auto_check_trustdb;
int preserve_permissions;
int no_homedir_creation;
struct groupitem *grouplist;
int mangle_dos_filenames;
int enable_progress_filter;
unsigned int screen_columns;
unsigned int screen_lines;
byte *show_subpackets;
int rfc2440_text;
/* If true, let write failures on the status-fd exit the process. */
int exit_on_status_write_error;
/* If > 0, limit the number of card insertion prompts to this
value. */
int limit_card_insert_tries;
#ifdef ENABLE_CARD_SUPPORT
/* FIXME: We don't needs this here as it is done in scdaemon. */
const char *ctapi_driver; /* Library to access the ctAPI. */
const char *pcsc_driver; /* Library to access the PC/SC system. */
int disable_ccid; /* Disable the use of the internal CCID driver. */
#endif /*ENABLE_CARD_SUPPORT*/
struct
{
/* If set, require an 0x19 backsig to be present on signatures
made by signing subkeys. If not set, a missing backsig is not
an error (but an invalid backsig still is). */
unsigned int require_cross_cert:1;
unsigned int use_embedded_filename:1;
unsigned int utf8_filename:1;
unsigned int dsa2:1;
unsigned int allow_multiple_messages:1;
unsigned int allow_weak_digest_algos:1;
unsigned int large_rsa:1;
} flags;
/* Linked list of ways to find a key if the key isn't on the local
keyring. */
struct akl
{
enum {
AKL_NODEFAULT,
AKL_LOCAL,
AKL_CERT,
AKL_PKA,
AKL_DANE,
AKL_LDAP,
AKL_KEYSERVER,
AKL_SPEC
} type;
keyserver_spec_t spec;
struct akl *next;
} *auto_key_locate;
int passphrase_repeat;
int pinentry_mode;
int unwrap_encryption;
int only_sign_text_ids;
} opt;
/* CTRL is used to keep some global variables we currently can't
avoid. Future concurrent versions of gpg will put it into a per
request structure CTRL. */
EXTERN_UNLESS_MAIN_MODULE
struct {
int in_auto_key_retrieve; /* True if we are doing an
auto_key_retrieve. */
/* Hack to store the last error. We currently need it because the
proc_packet machinery is not able to reliabale return error
codes. Thus for the --server purposes we store some of the error
codes here. FIXME! */
gpg_error_t lasterr;
} glo_ctrl;
#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */
#define DBG_MPI_VALUE 2 /* debug mpi details */
#define DBG_CRYPTO_VALUE 4 /* debug crypto handling */
/* (may reveal sensitive data) */
#define DBG_FILTER_VALUE 8 /* debug internal filter handling */
#define DBG_IOBUF_VALUE 16 /* debug iobuf stuff */
#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */
#define DBG_CACHE_VALUE 64 /* debug the caching */
#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
#define DBG_TRUST_VALUE 256 /* debug the trustdb */
#define DBG_HASHING_VALUE 512 /* debug hashing operations */
#define DBG_IPC_VALUE 1024 /* debug assuan communication */
#define DBG_CARD_IO_VALUE 2048 /* debug smart card I/O. */
#define DBG_CLOCK_VALUE 4096
#define DBG_LOOKUP_VALUE 8192 /* debug the kety lookup */
#define DBG_EXTPROG_VALUE 16384 /* debug external program calls */
/* Tests for the debugging flags. */
#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE)
#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE)
#define DBG_FILTER (opt.debug & DBG_FILTER_VALUE)
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
#define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE)
#define DBG_IPC (opt.debug & DBG_IPC_VALUE)
#define DBG_CLOCK (opt.debug & DBG_CLOCK_VALUE)
#define DBG_LOOKUP (opt.debug & DBG_LOOKUP_VALUE)
#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE)
/* FIXME: We need to check whey we did not put this into opt. */
#define DBG_MEMORY memory_debug_mode
#define DBG_MEMSTAT memory_stat_debug_mode
EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode;
EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
/* Compatibility flags. */
#define GNUPG (opt.compliance==CO_GNUPG)
#define RFC2440 (opt.compliance==CO_RFC2440)
#define RFC4880 (opt.compliance==CO_RFC4880)
#define PGP6 (opt.compliance==CO_PGP6)
#define PGP7 (opt.compliance==CO_PGP7)
#define PGP8 (opt.compliance==CO_PGP8)
#define PGPX (PGP6 || PGP7 || PGP8)
/* Various option flags. Note that there should be no common string
names between the IMPORT_ and EXPORT_ flags as they can be mixed in
the keyserver-options option. */
#define IMPORT_LOCAL_SIGS (1<<0)
#define IMPORT_REPAIR_PKS_SUBKEY_BUG (1<<1)
#define IMPORT_FAST (1<<2)
#define IMPORT_MERGE_ONLY (1<<4)
#define IMPORT_MINIMAL (1<<5)
#define IMPORT_CLEAN (1<<6)
#define IMPORT_NO_SECKEY (1<<7)
#define IMPORT_KEEP_OWNERTTRUST (1<<8)
#define EXPORT_LOCAL_SIGS (1<<0)
#define EXPORT_ATTRIBUTES (1<<1)
#define EXPORT_SENSITIVE_REVKEYS (1<<2)
#define EXPORT_RESET_SUBKEY_PASSWD (1<<3)
#define EXPORT_MINIMAL (1<<4)
#define EXPORT_CLEAN (1<<5)
#define EXPORT_DANE_FORMAT (1<<6)
#define LIST_SHOW_PHOTOS (1<<0)
#define LIST_SHOW_POLICY_URLS (1<<1)
#define LIST_SHOW_STD_NOTATIONS (1<<2)
#define LIST_SHOW_USER_NOTATIONS (1<<3)
#define LIST_SHOW_NOTATIONS (LIST_SHOW_STD_NOTATIONS|LIST_SHOW_USER_NOTATIONS)
#define LIST_SHOW_KEYSERVER_URLS (1<<4)
#define LIST_SHOW_UID_VALIDITY (1<<5)
#define LIST_SHOW_UNUSABLE_UIDS (1<<6)
#define LIST_SHOW_UNUSABLE_SUBKEYS (1<<7)
#define LIST_SHOW_KEYRING (1<<8)
#define LIST_SHOW_SIG_EXPIRE (1<<9)
#define LIST_SHOW_SIG_SUBPACKETS (1<<10)
#define LIST_SHOW_USAGE (1<<11)
#define VERIFY_SHOW_PHOTOS (1<<0)
#define VERIFY_SHOW_POLICY_URLS (1<<1)
#define VERIFY_SHOW_STD_NOTATIONS (1<<2)
#define VERIFY_SHOW_USER_NOTATIONS (1<<3)
#define VERIFY_SHOW_NOTATIONS (VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_USER_NOTATIONS)
#define VERIFY_SHOW_KEYSERVER_URLS (1<<4)
#define VERIFY_SHOW_UID_VALIDITY (1<<5)
#define VERIFY_SHOW_UNUSABLE_UIDS (1<<6)
#define VERIFY_PKA_LOOKUPS (1<<7)
#define VERIFY_PKA_TRUST_INCREASE (1<<8)
#define VERIFY_SHOW_PRIMARY_UID_ONLY (1<<9)
#define KEYSERVER_HTTP_PROXY (1<<0)
#define KEYSERVER_TIMEOUT (1<<1)
#define KEYSERVER_ADD_FAKE_V3 (1<<2)
#define KEYSERVER_AUTO_KEY_RETRIEVE (1<<3)
#define KEYSERVER_HONOR_KEYSERVER_URL (1<<4)
#define KEYSERVER_HONOR_PKA_RECORD (1<<5)
#endif /*G10_OPTIONS_H*/

File Metadata

Mime Type
text/x-diff
Expires
Mon, Dec 8, 6:21 AM (1 d, 6 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
94/55/d63c2643d5bab9ce2335ce5c23d2

Event Timeline