[svn] GnuPG - r5315 - in trunk: agent common doc g10 kbx po tools

svn author wk cvs at cvs.gnupg.org
Wed Apr 21 18:26:19 CEST 2010


Author: wk
Date: 2010-04-21 18:26:17 +0200 (Wed, 21 Apr 2010)
New Revision: 5315

Modified:
   trunk/agent/ChangeLog
   trunk/agent/agent.h
   trunk/agent/command.c
   trunk/agent/findkey.c
   trunk/agent/pksign.c
   trunk/common/ChangeLog
   trunk/common/estream.c
   trunk/doc/DETAILS
   trunk/g10/ChangeLog
   trunk/g10/call-agent.c
   trunk/g10/call-agent.h
   trunk/g10/delkey.c
   trunk/g10/export.c
   trunk/g10/getkey.c
   trunk/g10/gpgv.c
   trunk/g10/import.c
   trunk/g10/keydb.c
   trunk/g10/keydb.h
   trunk/g10/keyedit.c
   trunk/g10/keygen.c
   trunk/g10/keylist.c
   trunk/g10/keyserver.c
   trunk/g10/mainproc.c
   trunk/g10/pkclist.c
   trunk/g10/revoke.c
   trunk/g10/sign.c
   trunk/g10/trustdb.c
   trunk/kbx/ChangeLog
   trunk/kbx/keybox-blob.c
   trunk/po/POTFILES.in
   trunk/tools/Makefile.am
Log:
More changes on the way to remove secring.gpg.


[The diff below has been truncated]

Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/agent/ChangeLog	2010-04-21 16:26:17 UTC (rev 5315)
@@ -1,3 +1,13 @@
+2010-04-19  Werner Koch  <wk at 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 at g10code.com>
 
 	* Makefile.am (libexec_PROGRAMS) [W32CE]: Do not build

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/common/ChangeLog	2010-04-21 16:26:17 UTC (rev 5315)
@@ -1,5 +1,8 @@
 2010-04-20  Werner Koch  <wk at 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 at g10code.de>
@@ -16,7 +19,7 @@
 
 2010-04-15  Werner Koch  <wk at 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.

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/ChangeLog	2010-04-21 16:26:17 UTC (rev 5315)
@@ -1,3 +1,37 @@
+2010-04-21  Werner Koch  <wk at 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 at 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.

Modified: trunk/kbx/ChangeLog
===================================================================
--- trunk/kbx/ChangeLog	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/kbx/ChangeLog	2010-04-21 16:26:17 UTC (rev 5315)
@@ -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 at g10code.com>
+
+	* keybox-blob.c: Include gettime.h
+	(make_timestamp): Remove.
+
 2010-03-23  Werner Koch  <wk at g10code.com>
 
 	* Makefile.am (extra_libs): New.

Modified: trunk/agent/agent.h
===================================================================
--- trunk/agent/agent.h	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/agent/agent.h	2010-04-21 16:26:17 UTC (rev 5315)
@@ -232,6 +232,7 @@
 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,

Modified: trunk/agent/command.c
===================================================================
--- trunk/agent/command.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/agent/command.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -589,7 +589,7 @@
 
 
 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 @@
         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 @@
   "\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"

Modified: trunk/agent/findkey.c
===================================================================
--- trunk/agent/findkey.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/agent/findkey.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -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 @@
 }
 
 
-
-/* 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 @@
     {
       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 @@
 
 
   /* 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 @@
   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 @@
   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 @@
   gcry_sexp_release (uri_sexp);
   gcry_sexp_release (comment_sexp);
 
-  if (!rc)
+  if (!err)
     *result = list;
-  return rc;
+  return err;
 }
 
 

Modified: trunk/agent/pksign.c
===================================================================
--- trunk/agent/pksign.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/agent/pksign.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -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 @@
 }
 
 
+/* 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 @@
   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 @@
                                   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,

Modified: trunk/common/estream.c
===================================================================
--- trunk/common/estream.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/common/estream.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -423,6 +423,14 @@
 
 
 
+static void
+es_deinit (void)
+{
+  /* Flush all streams. */
+  es_fflush (NULL);
+}
+
+
 /*
  * Initialization.
  */
@@ -430,17 +438,20 @@
 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);  
     }
-#endif
   return 0;
 }
 

Modified: trunk/doc/DETAILS
===================================================================
--- trunk/doc/DETAILS	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/doc/DETAILS	2010-04-21 16:26:17 UTC (rev 5315)
@@ -34,7 +34,7 @@
             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

Modified: trunk/g10/call-agent.c
===================================================================
--- trunk/g10/call-agent.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/call-agent.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -1294,23 +1294,25 @@
 
 
 
-/* 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;

Modified: trunk/g10/call-agent.h
===================================================================
--- trunk/g10/call-agent.h	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/call-agent.h	2010-04-21 16:26:17 UTC (rev 5315)
@@ -140,8 +140,9 @@
 /* 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_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);

Modified: trunk/g10/delkey.c
===================================================================
--- trunk/g10/delkey.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/delkey.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -52,7 +52,7 @@
     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 @@
 
 	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;
 	  }

Modified: trunk/g10/export.c
===================================================================
--- trunk/g10/export.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/export.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -306,7 +306,7 @@
 
     *any = 0;
     init_packet( &pkt );
-    kdbhd = keydb_new (secret);
+    kdbhd = keydb_new ();
 
     if (!users) {
         ndesc = 1;

Modified: trunk/g10/getkey.c
===================================================================
--- trunk/g10/getkey.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/getkey.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -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 @@
   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 @@
     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 @@
   }
 #endif
 
-  hd = keydb_new (0);
+  hd = keydb_new ();
   rc = keydb_search_kid (hd, keyid);
   if (rc == -1)
     {
@@ -480,7 +469,7 @@
   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 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 @@
 }
 
 
-/* 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 @@
   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 @@
     }
 
   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 @@
       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 @@
   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 @@
 		}
 	      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 @@
 		  *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 @@
 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 @@
       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 @@
   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 @@
 
       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 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 @@
   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 @@
 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 @@
  * 
  * 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 @@
   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 @@
 	  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 @@
 /****************
  * 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 @@
 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 @@
       /* 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 @@
   while (!rc);
 
   return rc; /* Error.  */
+#endif
 }
 
 
@@ -2893,37 +2817,71 @@
 }
 
 
-/* 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)
 {
-  gpg_error_t err;
-  unsigned char fpr[MAX_FINGERPRINT_LEN];
-  size_t fprlen;
-  KEYDB_HANDLE kdh;
+  kbnode_t node;
 
-  if (!keyblock || keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
-    return gpg_error (GPG_ERR_NO_PUBKEY);  /* Should not happen.  */
+  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;
+}
 
-  fingerprint_from_pk (keyblock->pkt->pkt.public_key, fpr, &fprlen);
-  while (fprlen < MAX_FINGERPRINT_LEN) 
-    fpr[fprlen++] = 0;
 
-  /* 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);
+/* 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;
+  KEYDB_HANDLE kdbhd;
+  KEYDB_SEARCH_DESC desc;
+  kbnode_t keyblock;
+  kbnode_t node;
+  int result = 0;
 
-  err = keydb_search_fpr (kdh, fpr);
-  if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
-    err = gpg_error (GPG_ERR_NO_SECKEY);
+  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;
+        }
 
-  keydb_release (kdh);
+      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);
 
-  return err;
+              if (!agent_probe_secret_key (NULL, node->pkt->pkt.public_key))
+                {
+                  result = 1;
+                  break;
+                }
+	    }
+	}
+      release_kbnode (keyblock);
+    }
+  keydb_release (kdbhd);
+  return result;
 }
 
 

Modified: trunk/g10/gpgv.c
===================================================================
--- trunk/g10/gpgv.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/gpgv.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -533,3 +533,10 @@
 {
 }
 
+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);
+}

Modified: trunk/g10/import.c
===================================================================
--- trunk/g10/import.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/import.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -800,7 +800,7 @@
 	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 @@
 	  }
 
 	/* now read the original keyblock */
-        hd = keydb_new (0);
+        hd = keydb_new ();
         {
             byte afp[MAX_FINGERPRINT_LEN];
             size_t an;
@@ -1012,17 +1012,17 @@
        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 @@
     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 @@
       }
 
     /* read the original keyblock */
-    hd = keydb_new (0);
+    hd = keydb_new ();
     {
         byte afp[MAX_FINGERPRINT_LEN];
         size_t an;
@@ -1594,7 +1599,7 @@
 	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,9 +2400,10 @@
     ;
   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.  */
   {
     PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;

Modified: trunk/g10/keydb.c
===================================================================
--- trunk/g10/keydb.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/keydb.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -348,10 +348,11 @@
 
 
 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;

Modified: trunk/g10/keydb.h
===================================================================
--- trunk/g10/keydb.h	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/keydb.h	2010-04-21 16:26:17 UTC (rev 5315)
@@ -24,6 +24,7 @@
 #include <assuan.h>
 
 #include "types.h"
+#include "util.h"
 #include "packet.h"
 #include "cipher.h"
 
@@ -132,7 +133,7 @@
   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,27 +208,23 @@
 			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,
                             kbnode_t *ret_keyblock);
@@ -238,7 +235,7 @@
                          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,

Modified: trunk/g10/keyedit.c
===================================================================
--- trunk/g10/keyedit.c	2010-04-21 09:56:43 UTC (rev 5314)
+++ trunk/g10/keyedit.c	2010-04-21 16:26:17 UTC (rev 5315)
@@ -45,6 +45,7 @@
 #include "status.h"
 #include "i18n.h"
 #include "keyserver-internal.h"
+#include "call-agent.h"
 
 static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
 			int verbose);
@@ -54,22 +55,18 @@
 				     int with_revoker, int with_fpr,
 				     int with_subkeys, int with_prefs);
 static void show_key_and_fingerprint (KBNODE keyblock);
-static int menu_adduid (KBNODE keyblock, KBNODE sec_keyblock,
-			int photo, const char *photo_name);
-static void menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock);
+static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name);
+static void menu_deluid (KBNODE pub_keyblock);
 static int menu_delsig (KBNODE pub_keyblock);
 static int menu_clean (KBNODE keyblock, int self_only);
-static void menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_addrevoker (KBNODE pub_keyblock,
-			    KBNODE sec_keyblock, int sensitive);
-static int menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_keyserver_url (const char *url,
-				   KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_notation (const char *string,
-			      KBNODE pub_keyblock, KBNODE sec_keyblock);
+static void menu_delkey (KBNODE pub_keyblock);
+static int menu_addrevoker (KBNODE pub_keyblock, int sensitive);
+static int menu_expire (KBNODE pub_keyblock);
+static int menu_backsign (KBNODE pub_keyblock);
+static int menu_set_primary_uid (KBNODE pub_keyblock);
+static int menu_set_preferences (KBNODE pub_keyblock);
+static int menu_set_keyserver_url (const char *url, KBNODE pub_keyblock);
+static int menu_set_notation (const char *string, KBNODE pub_keyblock);
 static int menu_select_uid (KBNODE keyblock, int idx);
 static int menu_select_uid_namehash (KBNODE keyblock, const char *namehash);
 static int menu_select_key (KBNODE keyblock, int idx);
@@ -80,9 +77,9 @@
 static int real_uids_left (KBNODE keyblock);
 static int count_selected_keys (KBNODE keyblock);
 static int menu_revsig (KBNODE keyblock);
-static int menu_revuid (KBNODE keyblock, KBNODE sec_keyblock);
-static int menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
+static int menu_revuid (KBNODE keyblock);
+static int menu_revkey (KBNODE pub_keyblock);
+static int menu_revsubkey (KBNODE pub_keyblock);
 static int enable_disable_key (KBNODE keyblock, int disable);
 static void menu_showphoto (KBNODE keyblock);
 
@@ -120,6 +117,7 @@
   PKT_secret_key *sk;
   PKT_public_key *pk;
 
+#warning:  This is not anymore needed.
   if (sec_node->pkt->pkttype == PKT_SECRET_KEY
       && node->pkt->pkttype == PKT_PUBLIC_KEY)
     return node->pkt->pkt.public_key;
@@ -525,7 +523,7 @@
 
 
 /*
- * Loop over all locusr and and sign the uids after asking.
+ * Loop over all LOCUSR and and sign the uids after asking.
  * If no user id is marked, all user ids will be signed;
  * if some user_ids are marked those will be signed.
  */
@@ -572,18 +570,11 @@
       u32 duration = 0, timestamp = 0;
       byte trust_depth = 0, trust_value = 0;
 
-      if (local || nonrevocable || trust ||
-	  opt.cert_policy_url || opt.cert_notations)
+      if (local || nonrevocable || trust 
+          || opt.cert_policy_url || opt.cert_notations)
 	force_v4 = 1;
 
-      /* We have to use a copy of the pk, because make_keysig_packet
-       * may remove the protection from sk and if we did other
-       * changes to the secret key, we would save the unprotected
-       * version.  FIXME: This can be removed because all protection
-       * is now done by gpg-agent.  */
-      if (pk)
-	free_public_key (pk);
-      pk = copy_public_key (NULL, sk_rover->pk);
+      pk = sk_rover->pk;
       keyid_from_pk (pk, sk_keyid);
 
       /* Set mark A for all selected user ids.  */
@@ -594,6 +585,7 @@
 	  else
 	    node->flag &= ~NODFLG_MARK_A;
 	}
+
       /* Reset mark for uids which are already signed.  */
       uidnode = NULL;
       for (node = keyblock; node; node = node->next)
@@ -620,11 +612,11 @@
 	      if (uidnode)
 		{
 		  int yesreally = 0;
-		  char *user =
-		    utf8_to_native (uidnode->pkt->pkt.user_id->name,
-				    uidnode->pkt->pkt.user_id->len,
-				    0);
+		  char *user;




More information about the Gnupg-commits mailing list