* command.c (cmd_setkeydesc): New.
authorWerner Koch <wk@gnupg.org>
Fri, 13 Feb 2004 17:06:34 +0000 (17:06 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 13 Feb 2004 17:06:34 +0000 (17:06 +0000)
(register_commands): Add command SETKEYDESC.
(cmd_pksign, cmd_pkdecrypt): Use the key description.
(reset_notify): Reset the description.
* findkey.c (unprotect): Add arg DESC_TEXT.
(agent_key_from_file): Ditto.
* pksign.c (agent_pksign): Ditto.
* pkdecrypt.c (agent_pkdecrypt): Ditto. Made CIPHERTEXT an
unsigned char*.

NEWS
agent/ChangeLog
agent/agent.h
agent/command.c
agent/findkey.c
agent/pkdecrypt.c
agent/pksign.c

diff --git a/NEWS b/NEWS
index 41edd66..07216f5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,11 @@ Noteworthy changes in version 1.9.5
    Cleaned up the build system to better comply with the coding
    standards.
 
- * The --import command is now able to autodetect pkcs#12 files and
-   import secret and private keys from this file format.
+ * [gpgsm] The --import command is now able to autodetect pkcs#12
+   files and import secret and private keys from this file format.
+
+ * [gpgsm] The pinentry will no present a description of the key for
+   whom the passphrase is requests.
 
 
 Noteworthy changes in version 1.9.4 (2004-01-30)
index b3c5d73..f064bc1 100644 (file)
@@ -1,5 +1,15 @@
 2004-02-13  Werner Koch  <wk@gnupg.org>
 
+       * command.c (cmd_setkeydesc): New.
+       (register_commands): Add command SETKEYDESC.
+       (cmd_pksign, cmd_pkdecrypt): Use the key description.
+       (reset_notify): Reset the description.
+       * findkey.c (unprotect): Add arg DESC_TEXT.
+       (agent_key_from_file): Ditto.
+       * pksign.c (agent_pksign): Ditto.
+       * pkdecrypt.c (agent_pkdecrypt): Ditto. Made CIPHERTEXT an
+       unsigned char*.
+
        * protect-tool.c (main): New options --no-fail-on-exist, --homedir.
        (store_private_key): Use them here.
 
index b70a4ae..a849e87 100644 (file)
@@ -132,18 +132,20 @@ void start_command_handler (int, int);
 /*-- findkey.c --*/
 int agent_write_private_key (const unsigned char *grip,
                              const void *buffer, size_t length, int force);
-gpg_error_t agent_key_from_file (CTRL ctrl, const unsigned char *grip,
+gpg_error_t agent_key_from_file (ctrl_t ctrl, 
+                                 const char *desc_text,
+                                 const unsigned char *grip,
                                  unsigned char **shadow_info,
                                  int ignore_cache, gcry_sexp_t *result);
 int agent_key_available (const unsigned char *grip);
 
 /*-- query.c --*/
-int agent_askpin (CTRL ctrl,
+int agent_askpin (ctrl_t ctrl,
                   const char *desc_text, struct pin_entry_info_s *pininfo);
-int agent_get_passphrase (CTRL ctrl, char **retpass,
+int agent_get_passphrase (ctrl_t ctrl, char **retpass,
                           const char *desc, const char *prompt,
                           const char *errtext);
-int agent_get_confirmation (CTRL ctrl, const char *desc, const char *ok,
+int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
                            const char *cancel);
 
 /*-- cache.c --*/
@@ -154,16 +156,18 @@ void agent_unlock_cache_entry (void **cache_id);
 
 
 /*-- pksign.c --*/
-int agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache);
+int agent_pksign (ctrl_t ctrl, const char *desc_text,
+                  FILE *outfp, int ignore_cache);
 
 /*-- pkdecrypt.c --*/
-int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
+int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
+                     const unsigned char *ciphertext, size_t ciphertextlen,
                      FILE *outfp);
 
 /*-- genkey.c --*/
-int agent_genkey (CTRL ctrl,
+int agent_genkey (ctrl_t ctrl, 
                   const char *keyparam, size_t keyparmlen, FILE *outfp);
-int agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey);
+int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey);
 
 /*-- protect.c --*/
 int agent_protect (const unsigned char *plainkey, const char *passphrase,
@@ -181,18 +185,20 @@ int agent_get_shadow_info (const unsigned char *shadowkey,
 /*-- trustlist.c --*/
 int agent_istrusted (const char *fpr);
 int agent_listtrusted (void *assuan_context);
-int agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag);
+int agent_marktrusted (ctrl_t ctrl, const char *name,
+                       const char *fpr, int flag);
 
 
 /*-- divert-scd.c --*/
-int divert_pksign (CTRL ctrl, 
+int divert_pksign (ctrl_t ctrl, 
                    const unsigned char *digest, size_t digestlen, int algo,
                    const unsigned char *shadow_info, unsigned char **r_sig);
-int divert_pkdecrypt (CTRL ctrl,
+int divert_pkdecrypt (ctrl_t ctrl,
                       const unsigned char *cipher,
                       const unsigned char *shadow_info,
                       char **r_buf, size_t *r_len);
-int divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context);
+int divert_generic_cmd (ctrl_t ctrl,
+                        const char *cmdline, void *assuan_context);
 
 
 /*-- call-scd.c --*/
index aec48e1..2fa182f 100644 (file)
@@ -1,5 +1,5 @@
 /* command.c - gpg-agent command handler
- *     Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -50,6 +50,8 @@ struct server_local_s {
   ASSUAN_CONTEXT assuan_ctx;
   int message_fd;
   int use_cache_for_signing;
+  char *keydesc;  /* Allocated description fro the next key
+                     operation. */
 };
 
 
@@ -59,11 +61,14 @@ struct server_local_s {
 static void
 reset_notify (ASSUAN_CONTEXT ctx)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
 
   memset (ctrl->keygrip, 0, 20);
   ctrl->have_keygrip = 0;
   ctrl->digest.valuelen = 0;
+
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = NULL;
 }
 
 
@@ -78,6 +83,18 @@ has_option (const char *line, const char *name)
   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
 }
 
+/* Replace all '+' by a blank. */
+static void
+plus_to_blank (char *s)
+{
+  for (; *s; s++)
+    {
+      if (*s == '+')
+        *s = ' ';
+    }
+}
+
+
 /* Parse a hex string.  Return an Assuan error code or 0 on success and the
    length of the parsed string in LEN. */
 static int
@@ -179,7 +196,7 @@ cmd_listtrusted (ASSUAN_CONTEXT ctx, char *line)
 static int
 cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc, n, i;
   char *p;
   char fpr[41];
@@ -245,7 +262,7 @@ static int
 cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
 {
   int rc;
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
 
   rc = parse_keygrip (ctx, line, ctrl->keygrip);
   if (rc)
@@ -255,6 +272,50 @@ cmd_sigkey (ASSUAN_CONTEXT ctx, char *line)
 }
 
 
+/* SETKEYDESC plus_percent_escaped_string:
+
+   Set a description to be used for the next PKSIGN or PKDECRYPT
+   operation if this operation requires the entry of a passphrase.  If
+   this command is not used a default text will be used.  Note, that
+   this description implictly selects the label used for the entry
+   box; if the string contains the string PIN (which in general will
+   not be translated), "PIN" is used, other wiese the translation of
+   'passphrase" is used.  The description string should not contain
+   blanks unless they are percent or '+' escaped.
+
+   The descrition is only valid for the next PKSIGN or PKDECRYPT
+   operation.
+*/
+static int
+cmd_setkeydesc (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  char *desc, *p;
+
+  for (p=line; *p == ' '; p++)
+    ;
+  desc = p;
+  p = strchr (desc, ' ');
+  if (p)
+    *p = 0; /* We ignore any garbage; we might late use it for other args. */
+
+  if (!desc || !*desc)
+    return set_error (Parameter_Error, "no description given");
+
+  /* Note, that we only need to replace the + characters and should
+     leave the other escaping in place because the escaped string is
+     send verbatim to the pinentry which does the unescaping (but not
+     the + replacing) */
+  plus_to_blank (desc);
+
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = xtrystrdup (desc);
+  if (!ctrl->server_local->keydesc)
+    return map_to_assuan_status (gpg_error_from_errno (errno));
+  return 0;
+}
+
+
 /* SETHASH <algonumber> <hexstring> 
 
   The client can use this command to tell the server about the data
@@ -265,7 +326,7 @@ cmd_sethash (ASSUAN_CONTEXT ctx, char *line)
   int rc;
   size_t n;
   char *p;
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   unsigned char *buf;
   char *endp;
   int algo;
@@ -307,16 +368,19 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
 {
   int rc;
   int ignore_cache = 0;
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
 
   if (opt.ignore_cache_for_signing)
     ignore_cache = 1;
   else if (!ctrl->server_local->use_cache_for_signing)
     ignore_cache = 1;
 
-  rc = agent_pksign (ctrl, assuan_get_data_fp (ctx), ignore_cache);
+  rc = agent_pksign (ctrl, ctrl->server_local->keydesc,
+                     assuan_get_data_fp (ctx), ignore_cache);
   if (rc)
     log_error ("command pksign failed: %s\n", gpg_strerror (rc));
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = NULL;
   return map_to_assuan_status (rc);
 }
 
@@ -328,7 +392,7 @@ static int
 cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
 {
   int rc;
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   unsigned char *value;
   size_t valuelen;
 
@@ -338,10 +402,13 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
   if (rc)
     return rc;
 
-  rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx));
+  rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
+                        value, valuelen, assuan_get_data_fp (ctx));
   xfree (value);
   if (rc)
     log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc));
+  xfree (ctrl->server_local->keydesc);
+  ctrl->server_local->keydesc = NULL;
   return map_to_assuan_status (rc);
 }
 
@@ -363,7 +430,7 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
 static int
 cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
   unsigned char *value;
   size_t valuelen;
@@ -381,16 +448,6 @@ cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
 }
 
 
-static void
-plus_to_blank (char *s)
-{
-  for (; *s; s++)
-    {
-      if (*s == '+')
-        *s = ' ';
-    }
-}
-
 /* GET_PASSPHRASE <cache_id> [<error_message> <prompt> <description>]
 
    This function is usually used to ask for a passphrase to be used
@@ -405,7 +462,7 @@ plus_to_blank (char *s)
 static int
 cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
   const char *pw;
   char *response;
@@ -530,15 +587,15 @@ cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line)
    command uses a syntax which helps clients to use the agent with
    minimum effort.  The agent either returns with an error or with a
    OK.  Note, that the length of DESCRIPTION is implicitly limited by
-   the maximum length of a command. DESCRIPTION should not conmtain
-   ant spaces, those must be encoded either percent escaped or simply
+   the maximum length of a command. DESCRIPTION should not contain
+   any spaces, those must be encoded either percent escaped or simply
    as '+'.
 */
 
 static int
 cmd_get_confirmation (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
   char *desc = NULL;
   char *p;
@@ -596,7 +653,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
 static int
 cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
   unsigned char grip[20];
   gcry_sexp_t s_skey = NULL;
@@ -607,7 +664,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
     return rc; /* we can't jump to leave because this is already an
                   Assuan error code. */
 
-  rc = agent_key_from_file (ctrl, grip, &shadow_info, 1, &s_skey);
+  rc = agent_key_from_file (ctrl, NULL, grip, &shadow_info, 1, &s_skey);
   if (rc)
     ;
   else if (!s_skey)
@@ -633,7 +690,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
 static int
 cmd_scd (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
 
   rc = divert_generic_cmd (ctrl, line, ctx);
@@ -646,7 +703,7 @@ cmd_scd (ASSUAN_CONTEXT ctx, char *line)
 static int
 option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
 {
-   CTRL ctrl = assuan_get_pointer (ctx);
+  ctrl_t ctrl = assuan_get_pointer (ctx);
 
   if (!strcmp (key, "display"))
     {
@@ -715,6 +772,7 @@ register_commands (ASSUAN_CONTEXT ctx)
     { "HAVEKEY",        cmd_havekey },
     { "SIGKEY",         cmd_sigkey },
     { "SETKEY",         cmd_sigkey },
+    { "SETKEYDESC",     cmd_setkeydesc },
     { "SETHASH",        cmd_sethash },
     { "PKSIGN",         cmd_pksign },
     { "PKDECRYPT",      cmd_pkdecrypt },
index f145dae..14ca384 100644 (file)
@@ -1,5 +1,5 @@
 /* findkey.c - locate the secret key
- *     Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -138,9 +138,10 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
 
 /* Unprotect the canconical encoded S-expression key in KEYBUF.  GRIP
    should be the hex encoded keygrip of that key to be used with the
-   caching mechanism. */
+   caching mechanism. DESC_TEXT may be set to override the default
+   description used for the pinentry. */
 static int
-unprotect (CTRL ctrl,
+unprotect (CTRL ctrl, const char *desc_text,
            unsigned char **keybuf, const unsigned char *grip, int ignore_cache)
 {
   struct pin_entry_info_s *pi;
@@ -184,7 +185,7 @@ unprotect (CTRL ctrl,
   arg.unprotected_key = NULL;
   pi->check_cb_arg = &arg;
 
-  rc = agent_askpin (ctrl, NULL, pi);
+  rc = agent_askpin (ctrl, desc_text, pi);
   if (!rc)
     {
       assert (arg.unprotected_key);
@@ -203,9 +204,10 @@ unprotect (CTRL ctrl,
    diverted to a token; SHADOW_INFO will point then to an allocated
    S-Expression with the shadow_info part from the file.  With
    IGNORE_CACHE passed as true the passphrase is not taken from the
-   cache.*/
+   cache.  DESC_TEXT may be set to present a custom description for the
+   pinentry. */
 gpg_error_t
-agent_key_from_file (CTRL ctrl,
+agent_key_from_file (CTRL ctrl, const char *desc_text,
                      const unsigned char *grip, unsigned char **shadow_info,
                      int ignore_cache, gcry_sexp_t *result)
 {
@@ -286,7 +288,7 @@ agent_key_from_file (CTRL ctrl,
     case PRIVATE_KEY_CLEAR:
       break; /* no unprotection needed */
     case PRIVATE_KEY_PROTECTED:
-      rc = unprotect (ctrl, &buf, grip, ignore_cache);
+      rc = unprotect (ctrl, desc_text, &buf, grip, ignore_cache);
       if (rc)
         log_error ("failed to unprotect the secret key: %s\n",
                    gpg_strerror (rc));
index 72f8177..eaa2b22 100644 (file)
@@ -35,7 +35,8 @@
    Try to get the key from CTRL and write the decoded stuff back to
    OUTFP. */
 int
-agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
+agent_pkdecrypt (CTRL ctrl, const char *desc_text,
+                 const unsigned char *ciphertext, size_t ciphertextlen,
                  FILE *outfp) 
 {
   gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
@@ -64,7 +65,8 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen,
       log_printhex ("keygrip:", ctrl->keygrip, 20);
       log_printhex ("cipher: ", ciphertext, ciphertextlen);
     }
-  rc = agent_key_from_file (ctrl, ctrl->keygrip, &shadow_info, 0, &s_skey);
+  rc = agent_key_from_file (ctrl, desc_text,
+                            ctrl->keygrip, &shadow_info, 0, &s_skey);
   if (rc)
     {
       log_error ("failed to read the secret key\n");
index 3438136..8bec33c 100644 (file)
@@ -70,7 +70,7 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash)
 /* SIGN whatever information we have accumulated in CTRL and write it
    back to OUTFP. */
 int
-agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) 
+agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache) 
 {
   gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL;
   unsigned char *shadow_info = NULL;
@@ -81,7 +81,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache)
   if (!ctrl->have_keygrip)
     return gpg_error (GPG_ERR_NO_SECKEY);
 
-  rc = agent_key_from_file (ctrl, ctrl->keygrip,
+  rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
                             &shadow_info, ignore_cache, &s_skey);
   if (rc)
     {