mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
More changes on the way to remove secring.gpg.
This commit is contained in:
parent
00f8eafbef
commit
a1412b05de
@ -1,3 +1,13 @@
|
||||
2010-04-19 Werner Koch <wk@g10code.com>
|
||||
|
||||
* pksign.c (get_dsa_qbits, do_encode_dsa): New.
|
||||
(agent_pksign_do): Detect DSA keys and use do_encode_dsa.
|
||||
* findkey.c (agent_public_key_from_file): Factor some code out to ..
|
||||
(key_parms_from_sexp): New.
|
||||
(agent_is_dsa_key): New.
|
||||
|
||||
* command.c (cmd_sethash): Clear digeest.RAW_VALUE.
|
||||
|
||||
2010-04-14 Werner Koch <wk@g10code.com>
|
||||
|
||||
* Makefile.am (libexec_PROGRAMS) [W32CE]: Do not build
|
||||
|
@ -232,6 +232,7 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl,
|
||||
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result);
|
||||
int agent_is_dsa_key (gcry_sexp_t s_key);
|
||||
int agent_key_available (const unsigned char *grip);
|
||||
gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
|
||||
int *r_keytype,
|
||||
|
@ -589,7 +589,7 @@ cmd_setkeydesc (assuan_context_t ctx, char *line)
|
||||
|
||||
|
||||
static const char hlp_sethash[] =
|
||||
"SETHASH --hash=<name>|<algonumber> <hexstring>\n"
|
||||
"SETHASH (--hash=<name>)|(<algonumber>) <hexstring>\n"
|
||||
"\n"
|
||||
"The client can use this command to tell the server about the data\n"
|
||||
"(which usually is a hash) to be signed.";
|
||||
@ -642,6 +642,7 @@ cmd_sethash (assuan_context_t ctx, char *line)
|
||||
return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL);
|
||||
}
|
||||
ctrl->digest.algo = algo;
|
||||
ctrl->digest.raw_value = 0;
|
||||
|
||||
/* Parse the hash value. */
|
||||
n = 0;
|
||||
@ -848,7 +849,7 @@ static const char hlp_keyinfo[] =
|
||||
"\n"
|
||||
"TYPE is describes the type of the key:\n"
|
||||
" 'D' - Regular key stored on disk,\n"
|
||||
" 'T' - Key is stored on a smartcard (token).\n"
|
||||
" 'T' - Key is stored on a smartcard (token),\n"
|
||||
" '-' - Unknown type.\n"
|
||||
"\n"
|
||||
"SERIALNO is an ASCII string with the serial number of the\n"
|
||||
|
154
agent/findkey.c
154
agent/findkey.c
@ -1,6 +1,6 @@
|
||||
/* findkey.c - Locate the secret key
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
|
||||
* 2007 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
|
||||
* 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -626,50 +626,32 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return the public key for the keygrip GRIP. The result is stored
|
||||
at RESULT. This function extracts the public key from the private
|
||||
key database. On failure an error code is returned and NULL stored
|
||||
at RESULT. */
|
||||
gpg_error_t
|
||||
agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result)
|
||||
/* Return the string name from the S-expression S_KEY as well as a
|
||||
string describing the names of the parameters. ALGONAMESIZE and
|
||||
ELEMSSIZE give the allocated size of the provided buffers. The
|
||||
buffers may be NULL if not required. If R_LIST is not NULL the top
|
||||
level list will be stored tehre; the caller needs to release it in
|
||||
this case. */
|
||||
static gpg_error_t
|
||||
key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
|
||||
char *r_algoname, size_t algonamesize,
|
||||
char *r_elems, size_t elemssize)
|
||||
{
|
||||
int i, idx, rc;
|
||||
gcry_sexp_t s_skey;
|
||||
const char *algoname;
|
||||
gcry_sexp_t uri_sexp, comment_sexp;
|
||||
const char *uri, *comment;
|
||||
size_t uri_length, comment_length;
|
||||
char *format, *p;
|
||||
void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
|
||||
for comment + end-of-list. */
|
||||
int argidx;
|
||||
gcry_sexp_t list, l2;
|
||||
const char *name;
|
||||
const char *s;
|
||||
const char *name, *algoname, *elems;
|
||||
size_t n;
|
||||
const char *elems;
|
||||
gcry_mpi_t *array;
|
||||
|
||||
(void)ctrl;
|
||||
if (r_list)
|
||||
*r_list = NULL;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
rc = read_key_file (grip, &s_skey);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
|
||||
list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
|
||||
if (!list)
|
||||
list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
|
||||
list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
|
||||
if (!list)
|
||||
list = gcry_sexp_find_token (s_skey, "private-key", 0 );
|
||||
list = gcry_sexp_find_token (s_key, "private-key", 0 );
|
||||
if (!list)
|
||||
{
|
||||
log_error ("invalid private key format\n");
|
||||
gcry_sexp_release (s_skey);
|
||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
}
|
||||
|
||||
@ -696,19 +678,99 @@ agent_public_key_from_file (ctrl_t ctrl,
|
||||
{
|
||||
log_error ("unknown private key algorithm\n");
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (s_skey);
|
||||
return gpg_error (GPG_ERR_BAD_SECKEY);
|
||||
}
|
||||
|
||||
if (r_algoname)
|
||||
{
|
||||
if (strlen (algoname) >= algonamesize)
|
||||
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
|
||||
strcpy (r_algoname, algoname);
|
||||
}
|
||||
if (r_elems)
|
||||
{
|
||||
if (strlen (elems) >= elemssize)
|
||||
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
|
||||
strcpy (r_elems, elems);
|
||||
}
|
||||
|
||||
if (r_list)
|
||||
*r_list = list;
|
||||
else
|
||||
gcry_sexp_release (list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if S_KEY is a DSA style key. */
|
||||
int
|
||||
agent_is_dsa_key (gcry_sexp_t s_key)
|
||||
{
|
||||
char algoname[6];
|
||||
|
||||
if (!s_key)
|
||||
return 0;
|
||||
|
||||
if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
|
||||
return 0; /* Error - assume it is not an DSA key. */
|
||||
|
||||
return (!strcmp (algoname, "dsa") || !strcmp (algoname, "ecdsa"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return the public key for the keygrip GRIP. The result is stored
|
||||
at RESULT. This function extracts the public key from the private
|
||||
key database. On failure an error code is returned and NULL stored
|
||||
at RESULT. */
|
||||
gpg_error_t
|
||||
agent_public_key_from_file (ctrl_t ctrl,
|
||||
const unsigned char *grip,
|
||||
gcry_sexp_t *result)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int i, idx;
|
||||
gcry_sexp_t s_skey;
|
||||
char algoname[6];
|
||||
char elems[6];
|
||||
gcry_sexp_t uri_sexp, comment_sexp;
|
||||
const char *uri, *comment;
|
||||
size_t uri_length, comment_length;
|
||||
char *format, *p;
|
||||
void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
|
||||
for comment + end-of-list. */
|
||||
int argidx;
|
||||
gcry_sexp_t list, l2;
|
||||
const char *s;
|
||||
gcry_mpi_t *array;
|
||||
|
||||
(void)ctrl;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
err = read_key_file (grip, &s_skey);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = key_parms_from_sexp (s_skey, &list,
|
||||
algoname, sizeof algoname,
|
||||
elems, sizeof elems);
|
||||
if (err)
|
||||
{
|
||||
gcry_sexp_release (s_skey);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Allocate an array for the parameters and copy them out of the
|
||||
secret key. FIXME: We should have a generic copy function. */
|
||||
array = xtrycalloc (strlen(elems) + 1, sizeof *array);
|
||||
if (!array)
|
||||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
err = gpg_error_from_syserror ();
|
||||
gcry_sexp_release (list);
|
||||
gcry_sexp_release (s_skey);
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
for (idx=0, s=elems; *s; s++, idx++ )
|
||||
@ -757,8 +819,8 @@ agent_public_key_from_file (ctrl_t ctrl,
|
||||
|
||||
|
||||
/* FIXME: The following thing is pretty ugly code; we should
|
||||
investigate how to make it cleaner. Probably code to handle
|
||||
canonical S-expressions in a memory buffer is better suioted for
|
||||
investigate how to make it cleaner. Probably code to handle
|
||||
canonical S-expressions in a memory buffer is better suited for
|
||||
such a task. After all that is what we do in protect.c. Neeed
|
||||
to find common patterns and write a straightformward API to use
|
||||
them. */
|
||||
@ -767,13 +829,13 @@ agent_public_key_from_file (ctrl_t ctrl,
|
||||
format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
|
||||
if (!format)
|
||||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
err = gpg_error_from_syserror ();
|
||||
for (i=0; array[i]; i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
xfree (array);
|
||||
gcry_sexp_release (uri_sexp);
|
||||
gcry_sexp_release (comment_sexp);
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
argidx = 0;
|
||||
@ -806,7 +868,7 @@ agent_public_key_from_file (ctrl_t ctrl,
|
||||
assert (argidx < DIM (args));
|
||||
args[argidx] = NULL;
|
||||
|
||||
rc = gcry_sexp_build_array (&list, NULL, format, args);
|
||||
err = gcry_sexp_build_array (&list, NULL, format, args);
|
||||
xfree (format);
|
||||
for (i=0; array[i]; i++)
|
||||
gcry_mpi_release (array[i]);
|
||||
@ -814,9 +876,9 @@ agent_public_key_from_file (ctrl_t ctrl,
|
||||
gcry_sexp_release (uri_sexp);
|
||||
gcry_sexp_release (comment_sexp);
|
||||
|
||||
if (!rc)
|
||||
if (!err)
|
||||
*result = list;
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
108
agent/pksign.c
108
agent/pksign.c
@ -1,5 +1,5 @@
|
||||
/* pksign.c - public key signing (well, actually using a secret key)
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -28,6 +28,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "agent.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
static int
|
||||
@ -75,6 +76,104 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
|
||||
}
|
||||
|
||||
|
||||
/* Return the number of bits of the Q parameter from the DSA key
|
||||
KEY. */
|
||||
static unsigned int
|
||||
get_dsa_qbits (gcry_sexp_t key)
|
||||
{
|
||||
gcry_sexp_t l1, l2;
|
||||
gcry_mpi_t q;
|
||||
unsigned int nbits;
|
||||
|
||||
l1 = gcry_sexp_find_token (key, "private-key", 0);
|
||||
if (!l1)
|
||||
l1 = gcry_sexp_find_token (key, "protected-private-key", 0);
|
||||
if (!l1)
|
||||
l1 = gcry_sexp_find_token (key, "shadowed-private-key", 0);
|
||||
if (!l1)
|
||||
l1 = gcry_sexp_find_token (key, "public-key", 0);
|
||||
if (!l1)
|
||||
return 0; /* Does not contain a key object. */
|
||||
l2 = gcry_sexp_cadr (l1);
|
||||
gcry_sexp_release (l1);
|
||||
l1 = gcry_sexp_find_token (l2, "q", 1);
|
||||
gcry_sexp_release (l2);
|
||||
if (!l1)
|
||||
return 0; /* Invalid object. */
|
||||
q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
|
||||
gcry_sexp_release (l1);
|
||||
if (!q)
|
||||
return 0; /* Missing value. */
|
||||
nbits = gcry_mpi_get_nbits (q);
|
||||
gcry_mpi_release (q);
|
||||
|
||||
return nbits;
|
||||
}
|
||||
|
||||
|
||||
/* Encode a message digest for use with an DSA algorithm. */
|
||||
static gpg_error_t
|
||||
do_encode_dsa (const byte * md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey,
|
||||
gcry_sexp_t *r_hash)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gcry_sexp_t hash;
|
||||
unsigned int qbits;
|
||||
|
||||
*r_hash = NULL;
|
||||
|
||||
if (dsaalgo == GCRY_PK_ECDSA)
|
||||
qbits = gcry_pk_get_nbits (pkey);
|
||||
else if (dsaalgo == GCRY_PK_DSA)
|
||||
qbits = get_dsa_qbits (pkey);
|
||||
else
|
||||
return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
|
||||
|
||||
if ((qbits%8))
|
||||
{
|
||||
log_error (_("DSA requires the hash length to be a"
|
||||
" multiple of 8 bits\n"));
|
||||
return gpg_error (GPG_ERR_INV_LENGTH);
|
||||
}
|
||||
|
||||
/* Don't allow any Q smaller than 160 bits. We don't want someone
|
||||
to issue signatures from a key with a 16-bit Q or something like
|
||||
that, which would look correct but allow trivial forgeries. Yes,
|
||||
I know this rules out using MD5 with DSA. ;) */
|
||||
if (qbits < 160)
|
||||
{
|
||||
log_error (_("%s key uses an unsafe (%u bit) hash\n"),
|
||||
gcry_pk_algo_name (dsaalgo), qbits);
|
||||
return gpg_error (GPG_ERR_INV_LENGTH);
|
||||
}
|
||||
|
||||
/* Check if we're too short. Too long is safe as we'll
|
||||
automatically left-truncate. */
|
||||
if (mdlen < qbits/8)
|
||||
{
|
||||
log_error (_("a %zu bit hash is not valid for a %u bit %s key\n"),
|
||||
mdlen*8,
|
||||
gcry_pk_get_nbits (pkey),
|
||||
gcry_pk_algo_name (dsaalgo));
|
||||
/* FIXME: we need to check the requirements for ECDSA. */
|
||||
if (mdlen < 20 || dsaalgo == GCRY_PK_DSA)
|
||||
return gpg_error (GPG_ERR_INV_LENGTH);
|
||||
}
|
||||
|
||||
/* Truncate. */
|
||||
if (mdlen > qbits/8)
|
||||
mdlen = qbits/8;
|
||||
|
||||
/* Create the S-expression. */
|
||||
err = gcry_sexp_build (&hash, NULL,
|
||||
"(data (flags raw) (value %b))",
|
||||
(int)mdlen, md);
|
||||
if (!err)
|
||||
*r_hash = hash;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Special version of do_encode_md to take care of pkcs#1 padding.
|
||||
For TLS-MD5SHA1 we need to do the padding ourself as Libgrypt does
|
||||
not know about this special scheme. Fixme: We should have a
|
||||
@ -180,8 +279,8 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text,
|
||||
else
|
||||
{
|
||||
/* No smartcard, but a private key */
|
||||
|
||||
gcry_sexp_t s_hash = NULL;
|
||||
int dsaalgo;
|
||||
|
||||
/* Put the hash into a sexp */
|
||||
if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1)
|
||||
@ -189,6 +288,11 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text,
|
||||
ctrl->digest.valuelen,
|
||||
gcry_pk_get_nbits (s_skey),
|
||||
&s_hash);
|
||||
else if ( (dsaalgo = agent_is_dsa_key (s_skey)) )
|
||||
rc = do_encode_dsa (ctrl->digest.value,
|
||||
ctrl->digest.valuelen,
|
||||
dsaalgo, s_skey,
|
||||
&s_hash);
|
||||
else
|
||||
rc = do_encode_md (ctrl->digest.value,
|
||||
ctrl->digest.valuelen,
|
||||
|
@ -1,5 +1,8 @@
|
||||
2010-04-20 Werner Koch <wk@g10code.com>
|
||||
|
||||
* estream.c (es_deinit): New.
|
||||
(es_init_do): Intll atexit handler to flush all streams.
|
||||
|
||||
* Makefile.am (common_sources): Add gettime.h.
|
||||
|
||||
2010-04-20 Marcus Brinkmann <marcus@g10code.de>
|
||||
@ -16,7 +19,7 @@
|
||||
|
||||
2010-04-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* util.h: Factor time related fucntions out to ...
|
||||
* util.h: Factor time related functions out to ...
|
||||
* gettime.h: New.
|
||||
(gnupg_copy_time): Move to ...
|
||||
* gettime.c (gnupg_copy_time): New.
|
||||
|
@ -423,6 +423,14 @@ es_pth_write (int fd, const void *buffer, size_t size)
|
||||
|
||||
|
||||
|
||||
static void
|
||||
es_deinit (void)
|
||||
{
|
||||
/* Flush all streams. */
|
||||
es_fflush (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialization.
|
||||
*/
|
||||
@ -430,17 +438,20 @@ es_pth_write (int fd, const void *buffer, size_t size)
|
||||
static int
|
||||
es_init_do (void)
|
||||
{
|
||||
#ifdef HAVE_PTH
|
||||
static int initialized;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
#ifdef HAVE_PTH
|
||||
if (!pth_init () && errno != EPERM )
|
||||
return -1;
|
||||
if (pth_mutex_init (&estream_list_lock))
|
||||
initialized = 1;
|
||||
}
|
||||
#else
|
||||
initialized = 1;
|
||||
#endif
|
||||
atexit (es_deinit);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ record; gpg2 does this by default and the option is a dummy.
|
||||
rev = revocation signature
|
||||
fpr = fingerprint: (fingerprint is in field 10)
|
||||
pkd = public key data (special field format, see below)
|
||||
grp = reserved for gpgsm
|
||||
grp = keygrip
|
||||
rvk = revocation key
|
||||
tru = trust database information
|
||||
spk = signature subpacket
|
||||
|
@ -1,3 +1,37 @@
|
||||
2010-04-21 Werner Koch <wk@g10code.com>
|
||||
|
||||
* pkclist.c (default_recipient): Change to use public keys.
|
||||
|
||||
* keydb.c (keydb_new): Remove arg SECRET. Change all callers.
|
||||
|
||||
* getkey.c (get_seckey): Change to take a public key.
|
||||
(have_secret_key): Rename to have_any_secret_key and make use of
|
||||
the agent.
|
||||
(key_byname): Rmemove unused arg SK.
|
||||
(get_seckey_byname2): Remove and move code to
|
||||
(get_seckey_byname): .. here. Remove INLOCK arg.
|
||||
(get_seckey_bynames): Remove.
|
||||
(get_seckey_next): Remove.
|
||||
(get_seckey_end): Remove. Use get_pubkey_end instead.
|
||||
(get_seckey_byfprint, get_seckeyblock_byfprint): Change to use
|
||||
public keys.
|
||||
(seckey_available): Rename to ..
|
||||
(have_secret_key_with_kid): .. this and change to employ the
|
||||
agent. Change all callers.
|
||||
(sk_from_block): Remove.
|
||||
|
||||
* call-agent.c (agent_probe_secret_key): New.
|
||||
(agent_havekey): Remove.
|
||||
* gpgv.c (agent_probe_secret_key): New.
|
||||
|
||||
* keyedit.c (keyedit_menu)
|
||||
(sign_uids, menu_adduid, menu_deluid, menu_delkey)
|
||||
(menu_addrevoker, menu_expire, menu_backsign)
|
||||
(menu_set_primary_uid, menu_set_preferences)
|
||||
(menu_set_keyserver_url, menu_set_notation, menu_revsig)
|
||||
(menu_revuid, menu_revkey, menu_revsubkey): Remove all code to
|
||||
manage the secret keyring.
|
||||
|
||||
2010-04-20 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keylist.c (list_keyblock_colon): Print the keygrip.
|
||||
@ -6,6 +40,7 @@
|
||||
(mpi_from_sexp): New.
|
||||
* keyid.c (keygrip_from_pk, hexkeygrip_from_pk): New.
|
||||
* call-agent.c (agent_pksign): New.
|
||||
|
||||
* pkglue.c (pk_sign): Remove.
|
||||
|
||||
* keygen.c (generate_keypair): Do not ask for a passphrase.
|
||||
|
@ -1294,23 +1294,25 @@ agent_get_s2k_count (unsigned long *r_count)
|
||||
|
||||
|
||||
|
||||
/* Ask the agent whether a secret key with the given keygrip is
|
||||
known. */
|
||||
/* Ask the agent whether a secret key for the given public key is
|
||||
available. Returns 0 if available. */
|
||||
gpg_error_t
|
||||
agent_havekey (ctrl_t ctrl, const char *hexkeygrip)
|
||||
agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
|
||||
{
|
||||
gpg_error_t err;
|
||||
char line[ASSUAN_LINELENGTH];
|
||||
char *hexgrip;
|
||||
|
||||
err = start_agent (ctrl, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!hexkeygrip || strlen (hexkeygrip) != 40)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
err = hexkeygrip_from_pk (pk, &hexgrip);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip);
|
||||
line[DIM(line)-1] = 0;
|
||||
snprintf (line, sizeof line, "HAVEKEY %s", hexgrip);
|
||||
xfree (hexgrip);
|
||||
|
||||
err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
return err;
|
||||
|
@ -140,8 +140,9 @@ gpg_error_t gpg_agent_get_confirmation (const char *desc);
|
||||
/* Return the S2K iteration count as computed by gpg-agent. */
|
||||
gpg_error_t agent_get_s2k_count (unsigned long *r_count);
|
||||
|
||||
/* Check whether a secret key with HEXKEYGRIP is available. */
|
||||
gpg_error_t agent_havekey (ctrl_t ctrl, const char *hexkeygrip);
|
||||
/* Check whether a secret key for public key PK is available. Returns
|
||||
0 if the secret key is available. */
|
||||
gpg_error_t agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk);
|
||||
|
||||
/* Return infos about the secret key with HEXKEYGRIP. */
|
||||
gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
|
||||
@ -151,8 +152,8 @@ gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
|
||||
gpg_error_t agent_genkey (ctrl_t ctrl, const char *keyparms,
|
||||
gcry_sexp_t *r_pubkey);
|
||||
|
||||
/* Create a sigtnature. */
|
||||
gpg_error_t agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
|
||||
/* Create a signature. */
|
||||
gpg_error_t agent_pksign (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
|
||||
unsigned char *digest, size_t digestlen,
|
||||
int digestalgo,
|
||||
gcry_sexp_t *r_sigval);
|
||||
|
@ -52,7 +52,7 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
|
||||
int rc = 0;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE node;
|
||||
KEYDB_HANDLE hd = keydb_new (secret);
|
||||
KEYDB_HANDLE hd = keydb_new ();
|
||||
PKT_public_key *pk = NULL;
|
||||
PKT_secret_key *sk = NULL;
|
||||
u32 keyid[2];
|
||||
@ -104,15 +104,12 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
|
||||
|
||||
if(!force)
|
||||
{
|
||||
rc = seckey_available( keyid );
|
||||
if( !rc )
|
||||
if (have_secret_key_with_kid (keyid))
|
||||
{
|
||||
*r_sec_avail = 1;
|
||||
rc = -1;
|
||||
goto leave;
|
||||
}
|
||||
else if( rc != G10ERR_NO_SECKEY )
|
||||
log_error("%s: get secret key: %s\n", username, g10_errstr(rc) );
|
||||
else
|
||||
rc = 0;
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ do_export_stream( IOBUF out, strlist_t users, int secret,
|
||||
|
||||
*any = 0;
|
||||
init_packet( &pkt );
|
||||
kdbhd = keydb_new (secret);
|
||||
kdbhd = keydb_new ();
|
||||
|
||||
if (!users) {
|
||||
ndesc = 1;
|
||||
|
326
g10/getkey.c
326
g10/getkey.c
@ -35,6 +35,7 @@
|
||||
#include "trustdb.h"
|
||||
#include "i18n.h"
|
||||
#include "keyserver-internal.h"
|
||||
#include "call-agent.h"
|
||||
|
||||
#define MAX_PK_CACHE_ENTRIES PK_UID_CACHE_SIZE
|
||||
#define MAX_UID_CACHE_ENTRIES PK_UID_CACHE_SIZE
|
||||
@ -325,18 +326,6 @@ pk_from_block (GETKEY_CTX ctx, PKT_public_key * pk, KBNODE keyblock)
|
||||
copy_public_key (pk, a->pkt->pkt.public_key);
|
||||
}
|
||||
|
||||
static void
|
||||
sk_from_block (GETKEY_CTX ctx, PKT_secret_key * sk, KBNODE keyblock)
|
||||
{
|
||||
KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
|
||||
|
||||
assert (a->pkt->pkttype == PKT_SECRET_KEY
|
||||
|| a->pkt->pkttype == PKT_SECRET_SUBKEY);
|
||||
|
||||
copy_secret_key (sk, a->pkt->pkt.secret_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
|
||||
* structures. */
|
||||
@ -378,7 +367,7 @@ get_pubkey (PKT_public_key * pk, u32 * keyid)
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
ctx.exact = 1; /* Use the key ID exactly as given. */
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (0);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||
ctx.items[0].u.kid[0] = keyid[0];
|
||||
@ -437,7 +426,7 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
|
||||
}
|
||||
#endif
|
||||
|
||||
hd = keydb_new (0);
|
||||
hd = keydb_new ();
|
||||
rc = keydb_search_kid (hd, keyid);
|
||||
if (rc == -1)
|
||||
{
|
||||
@ -480,7 +469,7 @@ get_pubkeyblock (u32 * keyid)
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
/* No need to set exact here because we want the entire block. */
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (0);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||
ctx.items[0].u.kid[0] = keyid[0];
|
||||
@ -494,67 +483,43 @@ get_pubkeyblock (u32 * keyid)
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Get a secret key and store it into sk
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
int
|
||||
get_seckey (PKT_secret_key * sk, u32 * keyid)
|
||||
gpg_error_t
|
||||
get_seckey (PKT_public_key *pk, u32 *keyid)
|
||||
{
|
||||
int rc;
|
||||
gpg_error_t err;
|
||||
struct getkey_ctx_s ctx;
|
||||
KBNODE kb = NULL;
|
||||
kbnode_t keyblock = NULL;
|
||||
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
ctx.exact = 1; /* Use the key ID exactly as given. */
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (1);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||
ctx.items[0].u.kid[0] = keyid[0];
|
||||
ctx.items[0].u.kid[1] = keyid[1];
|
||||
ctx.req_algo = sk->req_algo;
|
||||
ctx.req_usage = sk->req_usage;
|
||||
rc = lookup (&ctx, &kb, 1);
|
||||
if (!rc)
|
||||
ctx.req_algo = pk->req_algo;
|
||||
ctx.req_usage = pk->req_usage;
|
||||
err = lookup (&ctx, &keyblock, 1);
|
||||
if (!err)
|
||||
{
|
||||
sk_from_block (&ctx, sk, kb);
|
||||
pk_from_block (&ctx, pk, keyblock);
|
||||
}
|
||||
get_seckey_end (&ctx);
|
||||
release_kbnode (kb);
|
||||
get_pubkey_end (&ctx);
|
||||
release_kbnode (keyblock);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
/* Check the secret key (this may prompt for a passprase to
|
||||
* unlock the secret key. */
|
||||
/* rc = check_secret_key (sk, 0); */
|
||||
}
|
||||
if (!err)
|
||||
err = agent_probe_secret_key (/*ctrl*/NULL, pk);
|
||||
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Check whether the secret key is available. This is just a fast
|
||||
* check and does not tell us whether the secret key is valid. It
|
||||
* merely tells other whether there is some secret key.
|
||||
* Returns:
|
||||
* 0 := key is available
|
||||
* G10ERR_NO_SECKEY := key not availabe
|
||||
*/
|
||||
int
|
||||
seckey_available (u32 * keyid)
|
||||
{
|
||||
int rc;
|
||||
KEYDB_HANDLE hd = keydb_new (1);
|
||||
|
||||
rc = keydb_search_kid (hd, keyid);
|
||||
if (rc == -1)
|
||||
rc = G10ERR_NO_SECKEY;
|
||||
keydb_release (hd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
skip_unusable (void *dummy, u32 * keyid, PKT_user_id * uid)
|
||||
{
|
||||
@ -599,16 +564,15 @@ leave:
|
||||
}
|
||||
|
||||
|
||||
/* Try to get the pubkey by the userid. This function looks for the
|
||||
/* Try to get the pubkey by the userid. This function looks for the
|
||||
* first pubkey certificate which has the given name in a user_id. If
|
||||
* pk/sk has the pubkey algo set, the function will only return a
|
||||
* pubkey with that algo. If namelist is NULL, the first key is
|
||||
* returned. The caller should provide storage for either the pk or
|
||||
* the sk. If ret_kb is not NULL the function will return the
|
||||
* keyblock there. */
|
||||
* PK has the pubkey algo set, the function will only return a pubkey
|
||||
* with that algo. If NAMELIST is NULL, the first key is returned.
|
||||
* The caller should provide storage for the PK. If RET_KB is not
|
||||
* NULL the function will return the keyblock there. */
|
||||
static int
|
||||
key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
PKT_public_key * pk, PKT_secret_key * sk,
|
||||
key_byname (GETKEY_CTX *retctx, strlist_t namelist,
|
||||
PKT_public_key *pk,
|
||||
int want_secret, int include_unusable,
|
||||
KBNODE * ret_kb, KEYDB_HANDLE * ret_kdbhd)
|
||||
{
|
||||
@ -618,8 +582,6 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
GETKEY_CTX ctx;
|
||||
KBNODE help_kb = NULL;
|
||||
|
||||
/* FIXME: Eventually remove the SK argument. */
|
||||
|
||||
if (retctx)
|
||||
{
|
||||
/* Reset the returned context in case of error. */
|
||||
@ -671,7 +633,7 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
}
|
||||
|
||||
ctx->want_secret = want_secret;
|
||||
ctx->kr_handle = keydb_new (0);
|
||||
ctx->kr_handle = keydb_new ();
|
||||
if (!ret_kb)
|
||||
ret_kb = &help_kb;
|
||||
|
||||
@ -680,11 +642,7 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist,
|
||||
ctx->req_algo = pk->req_algo;
|
||||
ctx->req_usage = pk->req_usage;
|
||||
}
|
||||
else if (sk) /* FIXME: We should remove this. */
|
||||
{
|
||||
ctx->req_algo = sk->req_algo;
|
||||
ctx->req_usage = sk->req_usage;
|
||||
}
|
||||
|
||||
rc = lookup (ctx, ret_kb, want_secret);
|
||||
if (!rc && pk)
|
||||
{
|
||||
@ -771,7 +729,7 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
else
|
||||
{
|
||||
add_to_strlist (&namelist, name);
|
||||
rc = key_byname (retctx, namelist, pk, NULL, 0,
|
||||
rc = key_byname (retctx, namelist, pk, 0,
|
||||
include_unusable, ret_keyblock, ret_kdbhd);
|
||||
}
|
||||
|
||||
@ -805,7 +763,7 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
}
|
||||
add_to_strlist (&namelist, name);
|
||||
rc = key_byname (anylocalfirst ? retctx : NULL,
|
||||
namelist, pk, NULL, 0,
|
||||
namelist, pk, 0,
|
||||
include_unusable, ret_keyblock, ret_kdbhd);
|
||||
break;
|
||||
|
||||
@ -904,7 +862,7 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
*retctx = NULL;
|
||||
}
|
||||
rc = key_byname (anylocalfirst ? retctx : NULL,
|
||||
namelist, pk, NULL, 0,
|
||||
namelist, pk, 0,
|
||||
include_unusable, ret_keyblock, ret_kdbhd);
|
||||
}
|
||||
if (!rc)
|
||||
@ -943,7 +901,7 @@ int
|
||||
get_pubkey_bynames (GETKEY_CTX * retctx, PKT_public_key * pk,
|
||||
strlist_t names, KBNODE * ret_keyblock)
|
||||
{
|
||||
return key_byname (retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL);
|
||||
return key_byname (retctx, names, pk, 0, 1, ret_keyblock, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
@ -991,7 +949,7 @@ get_pubkey_byfprint (PKT_public_key * pk,
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
ctx.exact = 1;
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (0);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16
|
||||
: KEYDB_SEARCH_MODE_FPR20;
|
||||
@ -1028,7 +986,7 @@ get_pubkey_byfprint_fast (PKT_public_key * pk,
|
||||
while (i < MAX_FINGERPRINT_LEN)
|
||||
fprbuf[i++] = 0;
|
||||
|
||||
hd = keydb_new (0);
|
||||
hd = keydb_new ();
|
||||
rc = keydb_search_fpr (hd, fprbuf);
|
||||
if (rc == -1)
|
||||
{
|
||||
@ -1070,7 +1028,7 @@ get_keyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint,
|
||||
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (0);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = (fprint_len == 16
|
||||
? KEYDB_SEARCH_MODE_FPR16
|
||||
@ -1086,15 +1044,15 @@ get_keyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint,
|
||||
}
|
||||
|
||||
|
||||
/* Get a secret key by name and store it into sk.
|
||||
* If NAME is NULL use the default key. */
|
||||
static int
|
||||
get_seckey_byname2 (GETKEY_CTX * retctx,
|
||||
PKT_secret_key * sk, const char *name, int unprotect,
|
||||
KBNODE * retblock)
|
||||
/* Get a secret key by NAME and store it into PK. If NAME is NULL use
|
||||
* the default key. This functions checks that a corresponding secret
|
||||
* key is available. With no secret key it does not succeeed. */
|
||||
gpg_error_t
|
||||
get_seckey_byname (PKT_public_key *pk, const char *name)
|
||||
{
|
||||
gpg_error_t err;
|
||||
strlist_t namelist = NULL;
|
||||
int rc, include_unusable = 1;
|
||||
int include_unusable = 1;
|
||||
|
||||
/* If we have no name, try to use the default secret key. If we
|
||||
have no default, we'll use the first usable one. */
|
||||
@ -1106,110 +1064,73 @@ get_seckey_byname2 (GETKEY_CTX * retctx,
|
||||
else
|
||||
include_unusable = 0;
|
||||
|
||||
rc = key_byname (retctx, namelist, NULL, sk, 1, include_unusable,
|
||||
retblock, NULL);
|
||||
err = key_byname (NULL, namelist, pk, 1, include_unusable, NULL, NULL);
|
||||
|
||||
free_strlist (namelist);
|
||||
|
||||
/* if (!rc && unprotect) */
|
||||
/* rc = check_secret_key (sk, 0); */
|
||||
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
get_seckey_byname (PKT_secret_key * sk, const char *name, int unlock)
|
||||
{
|
||||
return get_seckey_byname2 (NULL, sk, name, unlock, NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_seckey_bynames (GETKEY_CTX * retctx, PKT_secret_key * sk,
|
||||
strlist_t names, KBNODE * ret_keyblock)
|
||||
{
|
||||
return key_byname (retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_seckey_next (GETKEY_CTX ctx, PKT_secret_key * sk, KBNODE * ret_keyblock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = lookup (ctx, ret_keyblock, 1);
|
||||
if (!rc && sk && ret_keyblock)
|
||||
sk_from_block (ctx, sk, *ret_keyblock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
get_seckey_end (GETKEY_CTX ctx)
|
||||
{
|
||||
get_pubkey_end (ctx);
|
||||
}
|
||||
|
||||
|
||||
/* Search for a key with the given fingerprint.
|
||||
* FIXME:
|
||||
* We should replace this with the _byname function. Thiscsan be done
|
||||
* We should replace this with the _byname function. This can be done
|
||||
* by creating a userID conforming to the unified fingerprint style. */
|
||||
int
|
||||
get_seckey_byfprint (PKT_secret_key * sk,
|
||||
const byte * fprint, size_t fprint_len)
|
||||
gpg_error_t
|
||||
get_seckey_byfprint (PKT_public_key *pk, const byte * fprint, size_t fprint_len)
|
||||
{
|
||||
int rc;
|
||||
gpg_error_t err;
|
||||
|
||||
if (fprint_len == 20 || fprint_len == 16)
|
||||
{
|
||||
struct getkey_ctx_s ctx;
|
||||
KBNODE kb = NULL;
|
||||
kbnode_t kb = NULL;
|
||||
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
ctx.exact = 1;
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (1);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16
|
||||
: KEYDB_SEARCH_MODE_FPR20;
|
||||
memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
|
||||
rc = lookup (&ctx, &kb, 1);
|
||||
if (!rc && sk)
|
||||
sk_from_block (&ctx, sk, kb);
|
||||
err = lookup (&ctx, &kb, 1);
|
||||
if (!err && pk)
|
||||
pk_from_block (&ctx, pk, kb);
|
||||
release_kbnode (kb);
|
||||
get_seckey_end (&ctx);
|
||||
get_pubkey_end (&ctx);
|
||||
}
|
||||
else
|
||||
rc = G10ERR_GENERAL; /* Oops */
|
||||
return rc;
|
||||
err = gpg_error (GPG_ERR_BUG);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Search for a secret key with the given fingerprint and return the
|
||||
complete keyblock which may have more than only this key. */
|
||||
int
|
||||
get_seckeyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint,
|
||||
size_t fprint_len)
|
||||
complete keyblock which may have more than only this key. Return
|
||||
an error if no corresponding secret key is available. */
|
||||
gpg_error_t
|
||||
get_seckeyblock_byfprint (kbnode_t *ret_keyblock,
|
||||
const byte *fprint, size_t fprint_len)
|
||||
{
|
||||
int rc;
|
||||
gpg_error_t err;
|
||||
struct getkey_ctx_s ctx;
|
||||
|
||||
if (fprint_len != 20 && fprint_len == 16)
|
||||
return G10ERR_GENERAL; /* Oops */
|
||||
return gpg_error (GPG_ERR_BUG);
|
||||
|
||||
memset (&ctx, 0, sizeof ctx);
|
||||
ctx.not_allocated = 1;
|
||||
ctx.kr_handle = keydb_new (1);
|
||||
ctx.kr_handle = keydb_new ();
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = (fprint_len == 16
|
||||
? KEYDB_SEARCH_MODE_FPR16 : KEYDB_SEARCH_MODE_FPR20);
|
||||
memcpy (ctx.items[0].u.fpr, fprint, fprint_len);
|
||||
rc = lookup (&ctx, ret_keyblock, 1);
|
||||
get_seckey_end (&ctx);
|
||||
err = lookup (&ctx, ret_keyblock, 1);
|
||||
get_pubkey_end (&ctx);
|
||||
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -1220,7 +1141,7 @@ gpg_error_t
|
||||
getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
strlist_t names, int want_secret, kbnode_t *ret_keyblock)
|
||||
{
|
||||
return key_byname (retctx, names, pk, NULL, want_secret, 1,
|
||||
return key_byname (retctx, names, pk, want_secret, 1,
|
||||
ret_keyblock, NULL);
|
||||
}
|
||||
|
||||
@ -1238,7 +1159,7 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
*
|
||||
* FIXME: Explain what is up with unusable keys.
|
||||
*
|
||||
* FIXME: We also have the get_pubkey_byname fucntion which has a
|
||||
* FIXME: We also have the get_pubkey_byname function which has a
|
||||
* different semantic. Should be merged with this one.
|
||||
*/
|
||||
gpg_error_t
|
||||
@ -1256,7 +1177,7 @@ getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
else
|
||||
with_unusable = 0;
|
||||
|
||||
err = key_byname (retctx, namelist, pk, NULL, want_secret, with_unusable,
|
||||
err = key_byname (retctx, namelist, pk, want_secret, with_unusable,
|
||||
ret_keyblock, NULL);
|
||||
|
||||
/* FIXME: Check that we really return GPG_ERR_NO_SECKEY if
|
||||
@ -2538,7 +2459,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret)
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (want_secret && have_secret_key (ctx->keyblock))
|
||||
if (want_secret && !have_any_secret_key (NULL, ctx->keyblock))
|
||||
goto skip; /* No secret key available. */
|
||||
|
||||
/* Warning: node flag bits 0 and 1 should be preserved by
|
||||
@ -2586,9 +2507,7 @@ found:
|
||||
/****************
|
||||
* FIXME: Replace by the generic function
|
||||
* It does not work as it is right now - it is used at
|
||||
* 2 places: a) to get the key for an anonyous recipient
|
||||
* b) to get the ultimately trusted keys.
|
||||
* The a) usage might have some problems.
|
||||
* one place: to get the key for an anonymous recipient.
|
||||
*
|
||||
* set with_subkeys true to include subkeys
|
||||
* set with_spm true to include secret-parts-missing keys
|
||||
@ -2606,6 +2525,10 @@ int
|
||||
enum_secret_keys (void **context, PKT_secret_key * sk,
|
||||
int with_subkeys, int with_spm)
|
||||
{
|
||||
log_debug ("FIXME: Anonymous recipient does not yet work\n");
|
||||
return -1;
|
||||
#if 0
|
||||
|
||||
int rc = 0;
|
||||
struct
|
||||
{
|
||||
@ -2622,7 +2545,7 @@ enum_secret_keys (void **context, PKT_secret_key * sk,
|
||||
/* Make a new context. */
|
||||
c = xmalloc_clear (sizeof *c);
|
||||
*context = c;
|
||||
c->hd = keydb_new (1);
|
||||
c->hd = keydb_new (1); /*FIXME*/
|
||||
c->first = 1;
|
||||
c->keyblock = NULL;
|
||||
c->node = NULL;
|
||||
@ -2676,6 +2599,7 @@ enum_secret_keys (void **context, PKT_secret_key * sk,
|
||||
while (!rc);
|
||||
|
||||
return rc; /* Error. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2893,37 +2817,71 @@ parse_auto_key_locate (char *options)
|
||||
}
|
||||
|
||||
|
||||
/* Return 0 if a secret key is available for the key described by
|
||||
KEYBLOCK. FIXME: How do we handel subkeys? */
|
||||
gpg_error_t
|
||||
have_secret_key (kbnode_t keyblock)
|
||||
/* Return true if a secret key or secret subkey is available for one
|
||||
of the public keys in KEYBLOCK. */
|
||||
int
|
||||
have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock)
|
||||
{
|
||||
kbnode_t node;
|
||||
|
||||
for (node = keyblock; node; node = node->next)
|
||||
if ((node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||
&& !agent_probe_secret_key (ctrl, node->pkt->pkt.public_key))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
have_secret_key_with_kid (u32 *keyid)
|
||||
{
|
||||
gpg_error_t err;
|
||||
unsigned char fpr[MAX_FINGERPRINT_LEN];
|
||||
size_t fprlen;
|
||||
KEYDB_HANDLE kdh;
|
||||
KEYDB_HANDLE kdbhd;
|
||||
KEYDB_SEARCH_DESC desc;
|
||||
kbnode_t keyblock;
|
||||
kbnode_t node;
|
||||
int result = 0;
|
||||
|
||||
if (!keyblock || keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
|
||||
return gpg_error (GPG_ERR_NO_PUBKEY); /* Should not happen. */
|
||||
kdbhd = keydb_new ();
|
||||
memset (&desc, 0, sizeof desc);
|
||||
desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||
desc.u.kid[0] = keyid[0];
|
||||
desc.u.kid[1] = keyid[1];
|
||||
while (!result && !(err = keydb_search (kdbhd, &desc, 1)))
|
||||
{
|
||||
desc.mode = KEYDB_SEARCH_MODE_NEXT;
|
||||
err = keydb_get_keyblock (kdbhd, &keyblock);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error reading keyblock: %s\n"), g10_errstr (err));
|
||||
break;
|
||||
}
|
||||
|
||||
fingerprint_from_pk (keyblock->pkt->pkt.public_key, fpr, &fprlen);
|
||||
while (fprlen < MAX_FINGERPRINT_LEN)
|
||||
fpr[fprlen++] = 0;
|
||||
for (node = keyblock; node; node = node->next)
|
||||
{
|
||||
/* Bit 0 of the flags is set if the search found the key
|
||||
using that key or subkey. */
|
||||
if ((node->flag & 1))
|
||||
{
|
||||
assert (node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
|
||||
|
||||
/* FIXME: Always allocating a new handle is too slow. However this
|
||||
entire implementation is anyway a temporary solution until we can
|
||||
ask gpg-agent for the secret key. */
|
||||
kdh = keydb_new (1);
|
||||
if (!kdh)
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
|
||||
err = keydb_search_fpr (kdh, fpr);
|
||||
if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
|
||||
err = gpg_error (GPG_ERR_NO_SECKEY);
|
||||
|
||||
keydb_release (kdh);
|
||||
|
||||
return err;
|
||||
if (!agent_probe_secret_key (NULL, node->pkt->pkt.public_key))
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
release_kbnode (keyblock);
|
||||
}
|
||||
keydb_release (kdbhd);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -533,3 +533,10 @@ remove_lockfiles (void)
|
||||
{
|
||||
}
|
||||
|
||||
gpg_error_t
|
||||
agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
|
||||
{
|
||||
(void)ctrl;
|
||||
(void)pk;
|
||||
return gpg_error (GPG_ERR_NO_SECKEY);
|
||||
}
|
||||
|
38
g10/import.c
38
g10/import.c
@ -800,7 +800,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
||||
stats->skipped_new_keys++;
|
||||
}
|
||||
else if( rc ) { /* insert this key */
|
||||
KEYDB_HANDLE hd = keydb_new (0);
|
||||
KEYDB_HANDLE hd = keydb_new ();
|
||||
|
||||
rc = keydb_locate_writable (hd, NULL);
|
||||
if (rc) {
|
||||
@ -861,7 +861,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
||||
}
|
||||
|
||||
/* now read the original keyblock */
|
||||
hd = keydb_new (0);
|
||||
hd = keydb_new ();
|
||||
{
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
size_t an;
|
||||
@ -1012,17 +1012,17 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
|
||||
need to check if a designated revocation is present or if the
|
||||
prefs are not rational so we can warn the user. */
|
||||
|
||||
if(mod_key)
|
||||
if (mod_key)
|
||||
{
|
||||
revocation_present(keyblock_orig);
|
||||
if(!from_sk && seckey_available(keyid)==0)
|
||||
check_prefs(keyblock_orig);
|
||||
revocation_present (keyblock_orig);
|
||||
if (!from_sk && have_secret_key_with_kid (keyid))
|
||||
check_prefs (keyblock_orig);
|
||||
}
|
||||
else if(new_key)
|
||||
else if (new_key)
|
||||
{
|
||||
revocation_present(keyblock);
|
||||
if(!from_sk && seckey_available(keyid)==0)
|
||||
check_prefs(keyblock);
|
||||
revocation_present (keyblock);
|
||||
if (!from_sk && have_secret_key_with_kid (keyid))
|
||||
check_prefs (keyblock);
|
||||
}
|
||||
|
||||
release_kbnode( keyblock_orig );
|
||||
@ -1160,11 +1160,16 @@ import_secret_one( const char *fname, KBNODE keyblock,
|
||||
clear_kbnode_flags( keyblock );
|
||||
|
||||
/* do we have this key already in one of our secrings ? */
|
||||
rc = seckey_available( keyid );
|
||||
rc = -1 /* fixme seckey_available( keyid ) is not anymore
|
||||
available and has been replaced by
|
||||
have_secret_key_with_kid. We need to rework the entire
|
||||
secret key import code. The solution I am currently
|
||||
thinking about is to move that code into a helper
|
||||
program. */;
|
||||
if( rc == G10ERR_NO_SECKEY && !(opt.import_options&IMPORT_MERGE_ONLY) )
|
||||
{
|
||||
/* simply insert this key */
|
||||
KEYDB_HANDLE hd = keydb_new (1);
|
||||
KEYDB_HANDLE hd = keydb_new (); /* FIXME*/
|
||||
|
||||
/* get default resource */
|
||||
rc = keydb_locate_writable (hd, NULL);
|
||||
@ -1265,7 +1270,7 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
|
||||
}
|
||||
|
||||
/* read the original keyblock */
|
||||
hd = keydb_new (0);
|
||||
hd = keydb_new ();
|
||||
{
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
size_t an;
|
||||
@ -1594,7 +1599,7 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
|
||||
else if( node->pkt->pkttype == PKT_SIGNATURE &&
|
||||
!node->pkt->pkt.signature->flags.exportable &&
|
||||
!(options&IMPORT_LOCAL_SIGS) &&
|
||||
seckey_available( node->pkt->pkt.signature->keyid ) )
|
||||
!have_secret_key_with_kid (node->pkt->pkt.signature->keyid))
|
||||
{
|
||||
/* here we violate the rfc a bit by still allowing
|
||||
* to import non-exportable signature when we have the
|
||||
@ -2395,8 +2400,9 @@ auto_create_card_key_stub ( const char *serialnostr,
|
||||
;
|
||||
else
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
hd = keydb_new (1);
|
||||
|
||||
log_debug ("FIXME: Do we need the stub at all?\n");
|
||||
hd = keydb_new (); /* FIXME. */
|
||||
|
||||
/* Now check whether there is a secret keyring. */
|
||||
{
|
||||
|
@ -348,10 +348,11 @@ keydb_add_resource (const char *url, int flags, int secret)
|
||||
|
||||
|
||||
KEYDB_HANDLE
|
||||
keydb_new (int secret)
|
||||
keydb_new (void)
|
||||
{
|
||||
KEYDB_HANDLE hd;
|
||||
int i, j;
|
||||
int secret = 0; /* FIXME: Remove the secret stuff all together. */
|
||||
|
||||
hd = xmalloc_clear (sizeof *hd);
|
||||
hd->found = -1;
|
||||
|
27
g10/keydb.h
27
g10/keydb.h
@ -24,6 +24,7 @@
|
||||
#include <assuan.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
#include "cipher.h"
|
||||
|
||||
@ -132,7 +133,7 @@ union pref_hint
|
||||
Flag 2 == default
|
||||
*/
|
||||
int keydb_add_resource (const char *url, int flags, int secret);
|
||||
KEYDB_HANDLE keydb_new (int secret);
|
||||
KEYDB_HANDLE keydb_new (void);
|
||||
void keydb_release (KEYDB_HANDLE hd);
|
||||
const char *keydb_get_resource_name (KEYDB_HANDLE hd);
|
||||
int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
|
||||
@ -207,26 +208,22 @@ int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
|
||||
strlist_t names, KBNODE *ret_keyblock );
|
||||
int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
|
||||
void get_pubkey_end( GETKEY_CTX ctx );
|
||||
int get_seckey( PKT_secret_key *sk, u32 *keyid );
|
||||
int get_primary_seckey( PKT_secret_key *sk, u32 *keyid );
|
||||
gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid);
|
||||
int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint,
|
||||
size_t fprint_len );
|
||||
int get_pubkey_byfprint_fast (PKT_public_key *pk,
|
||||
const byte *fprint, size_t fprint_len);
|
||||
int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
|
||||
size_t fprint_len );
|
||||
int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid );
|
||||
int seckey_available( u32 *keyid );
|
||||
int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
|
||||
int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
|
||||
strlist_t names, KBNODE *ret_keyblock );
|
||||
int get_seckey_next (GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock);
|
||||
void get_seckey_end( GETKEY_CTX ctx );
|
||||
|
||||
int get_seckey_byfprint( PKT_secret_key *sk,
|
||||
const byte *fprint, size_t fprint_len);
|
||||
int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint,
|
||||
size_t fprint_len );
|
||||
int have_secret_key_with_kid (u32 *keyid);
|
||||
|
||||
gpg_error_t get_seckey_byname (PKT_public_key *pk, const char *name);
|
||||
|
||||
gpg_error_t get_seckey_byfprint (PKT_public_key *pk,
|
||||
const byte *fprint, size_t fprint_len);
|
||||
gpg_error_t get_seckeyblock_byfprint (kbnode_t *ret_keyblock,
|
||||
const byte *fprint, size_t fprint_len);
|
||||
|
||||
gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
|
||||
strlist_t names, int want_secret,
|
||||
@ -238,7 +235,7 @@ gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk,
|
||||
kbnode_t *ret_keyblock);
|
||||
void getkey_end (getkey_ctx_t ctx);
|
||||
|
||||
gpg_error_t have_secret_key (kbnode_t keyblock);
|
||||
int have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
|
||||
|
||||
|
||||
int enum_secret_keys( void **context, PKT_secret_key *sk,
|
||||
|
944
g10/keyedit.c
944
g10/keyedit.c
File diff suppressed because it is too large
Load Diff
@ -3310,7 +3310,7 @@ do_generate_keypair (struct para_data_s *para,
|
||||
}
|
||||
else if (!err) /* Write to the standard keyrings. */
|
||||
{
|
||||
KEYDB_HANDLE pub_hd = keydb_new (0);
|
||||
KEYDB_HANDLE pub_hd = keydb_new ();
|
||||
|
||||
err = keydb_locate_writable (pub_hd, NULL);
|
||||
if (err)
|
||||
|
@ -420,7 +420,7 @@ list_all (int secret)
|
||||
|
||||
memset (&stats, 0, sizeof (stats));
|
||||
|
||||
hd = keydb_new (0);
|
||||
hd = keydb_new ();
|
||||
if (!hd)
|
||||
rc = G10ERR_GENERAL;
|
||||
else
|
||||
@ -441,7 +441,7 @@ list_all (int secret)
|
||||
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
|
||||
goto leave;
|
||||
}
|
||||
if (secret && have_secret_key (keyblock))
|
||||
if (secret && !have_any_secret_key (NULL, keyblock))
|
||||
; /* Secret key listing requested but this isn't one. */
|
||||
else
|
||||
{
|
||||
|
@ -1719,7 +1719,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
|
||||
|
||||
*klist=xmalloc(sizeof(KEYDB_SEARCH_DESC)*num);
|
||||
|
||||
kdbhd=keydb_new(0);
|
||||
kdbhd=keydb_new ();
|
||||
|
||||
if(!users)
|
||||
{
|
||||
|
@ -395,7 +395,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
||||
experience if wildcard keyids are used. */
|
||||
if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
|
||||
|| opt.try_all_secrets
|
||||
|| !seckey_available( enc->keyid )) ) {
|
||||
|| have_secret_key_with_kid (enc->keyid)) ) {
|
||||
if( opt.list_only )
|
||||
result = -1;
|
||||
else {
|
||||
|
@ -697,7 +697,7 @@ key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
|
||||
static char *
|
||||
default_recipient(void)
|
||||
{
|
||||
PKT_secret_key *sk;
|
||||
PKT_public_key *pk;
|
||||
byte fpr[MAX_FINGERPRINT_LEN+1];
|
||||
size_t n;
|
||||
char *p;
|
||||
@ -707,15 +707,15 @@ default_recipient(void)
|
||||
return xstrdup( opt.def_recipient );
|
||||
if( !opt.def_recipient_self )
|
||||
return NULL;
|
||||
sk = xmalloc_clear( sizeof *sk );
|
||||
i = get_seckey_byname( sk, NULL, 0 );
|
||||
pk = xmalloc_clear( sizeof *pk );
|
||||
i = get_seckey_byname (pk, NULL);
|
||||
if( i ) {
|
||||
free_secret_key( sk );
|
||||
free_public_key( pk );
|
||||
return NULL;
|
||||
}
|
||||
n = MAX_FINGERPRINT_LEN;
|
||||
fingerprint_from_sk( sk, fpr, &n );
|
||||
free_secret_key( sk );
|
||||
fingerprint_from_pk( pk, fpr, &n );
|
||||
free_public_key( pk );
|
||||
p = xmalloc( 2*n+3 );
|
||||
*p++ = '0';
|
||||
*p++ = 'x';
|
||||
|
@ -219,7 +219,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
|
||||
|
||||
afx = new_armor_context ();
|
||||
|
||||
kdbhd = keydb_new (0);
|
||||
kdbhd = keydb_new ();
|
||||
rc = classify_user_id (uname, &desc);
|
||||
if (!rc)
|
||||
rc = keydb_search (kdbhd, &desc, 1);
|
||||
@ -461,7 +461,8 @@ gen_revoke (const char *uname)
|
||||
init_packet( &pkt );
|
||||
|
||||
/* Search the userid; we don't want the whole getkey stuff here. */
|
||||
kdbhd = keydb_new (1);
|
||||
log_debug ("FIXME: This needs to be adjusted for public key based lookups\n");
|
||||
kdbhd = keydb_new ();
|
||||
rc = classify_user_id (uname, &desc);
|
||||
if (!rc)
|
||||
rc = keydb_search (kdbhd, &desc, 1);
|
||||
|
@ -1546,6 +1546,9 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
||||
/****************
|
||||
* Create a new signature packet based on an existing one.
|
||||
* Only user ID signatures are supported for now.
|
||||
* PK is the public key to work on.
|
||||
* PKSK is the key used to make the signature.
|
||||
*
|
||||
* TODO: Merge this with make_keysig_packet.
|
||||
*/
|
||||
int
|
||||
|
@ -2283,7 +2283,7 @@ validate_keys (int interactive)
|
||||
used = new_key_hash_table ();
|
||||
full_trust = new_key_hash_table ();
|
||||
|
||||
kdb = keydb_new (0);
|
||||
kdb = keydb_new ();
|
||||
reset_trust_records();
|
||||
|
||||
/* Fixme: Instead of always building a UTK list, we could just build it
|
||||
|
@ -4,6 +4,11 @@
|
||||
../common/sysutils.h even then to silence gcc warning about
|
||||
missing declaration of gnupg_remove.
|
||||
|
||||
2010-04-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* keybox-blob.c: Include gettime.h
|
||||
(make_timestamp): Remove.
|
||||
|
||||
2010-03-23 Werner Koch <wk@g10code.com>
|
||||
|
||||
* Makefile.am (extra_libs): New.
|
||||
|
@ -127,6 +127,8 @@ X.509 specific are noted like [X.509: xxx]
|
||||
#endif
|
||||
|
||||
|
||||
#include "../common/gettime.h"
|
||||
|
||||
|
||||
/* special values of the signature status */
|
||||
#define SF_NONE(a) ( !(a) )
|
||||
@ -307,20 +309,6 @@ add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Some wrappers
|
||||
*/
|
||||
|
||||
static u32
|
||||
make_timestamp (void)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
#warning using time and not gnupg_get_time
|
||||
#endif
|
||||
return time(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef KEYBOX_WITH_OPENPGP
|
||||
|
@ -9,6 +9,7 @@ agent/preset-passphrase.c
|
||||
agent/protect-tool.c
|
||||
agent/trustlist.c
|
||||
agent/findkey.c
|
||||
agent/pksign.c
|
||||
|
||||
common/exechelp-posix.c
|
||||
common/exechelp-w32.c
|
||||
|
@ -48,7 +48,7 @@ if !HAVE_W32_SYSTEM
|
||||
bin_PROGRAMS += watchgnupg gpgparsemail
|
||||
endif
|
||||
if !HAVE_W32CE_SYSTEM
|
||||
bin_PROGRAMS += gpgkey2ssh
|
||||
bin_PROGRAMS += gpgkey2ssh gpgtar
|
||||
endif
|
||||
|
||||
if !DISABLE_REGEX
|
||||
@ -114,6 +114,15 @@ gpg_check_pattern_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \
|
||||
$(LIBINTL) $(LIBICONV) $(W32SOCKLIBS)
|
||||
endif
|
||||
|
||||
gpgtar_SOURCES = \
|
||||
gpgtar.c gpgtar.h \
|
||||
gpgtar-create.c \
|
||||
gpgtar-extract.c \
|
||||
gpgtar-list.c \
|
||||
no-libgcrypt.c
|
||||
gpgtar_LDADD = $(common_libs)
|
||||
|
||||
|
||||
# Make sure that all libs are build before we use them. This is
|
||||
# important for things like make -j2.
|
||||
$(PROGRAMS): $(common_libs) $(pwquery_libs) ../common/libgpgrl.a
|
||||
|
Loading…
x
Reference in New Issue
Block a user