Add a custom prompt for the CSR generation.
authorWerner Koch <wk@gnupg.org>
Fri, 5 Dec 2008 16:31:39 +0000 (16:31 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 5 Dec 2008 16:31:39 +0000 (16:31 +0000)
Add a new percent escape fucntion.

common/ChangeLog
common/Makefile.am
common/percent.c [new file with mode: 0644]
common/t-percent.c [new file with mode: 0644]
common/util.h
g10/ChangeLog
g10/call-agent.c
sm/ChangeLog
sm/certdump.c
sm/certreqgen.c

index b1390d5..4dd772d 100644 (file)
@@ -1,5 +1,7 @@
 2008-12-05  Werner Koch  <wk@g10code.com>
 
+       * percent.c, t-percent.c: New.
+
        * exechelp.c (gnupg_spawn_process, gnupg_spawn_process_fd) 
        (gnupg_spawn_process_detached) [W32]: Remove debug output.
 
index 5a5d6ba..d1a2d48 100644 (file)
@@ -52,6 +52,7 @@ common_sources = \
        yesno.c \
        b64enc.c b64dec.c \
        convert.c \
+       percent.c \
        miscellaneous.c \
        xasprintf.c \
        xreadline.c \
@@ -107,13 +108,14 @@ status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h
 #
 # Module tests
 #
-module_tests = t-convert t-gettime t-sysutils t-sexputil
+module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil
 module_maint_tests = t-helpfile t-b64
 
 t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \
                  $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
 
 t_convert_LDADD = $(t_common_ldadd)
+t_percent_LDADD = $(t_common_ldadd)
 t_gettime_LDADD = $(t_common_ldadd)
 t_sysutils_LDADD = $(t_common_ldadd)
 t_helpfile_LDADD = $(t_common_ldadd)
diff --git a/common/percent.c b/common/percent.c
new file mode 100644 (file)
index 0000000..a0c78ec
--- /dev/null
@@ -0,0 +1,76 @@
+/* percent.c - Percent escaping
+ *     Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "util.h"
+
+
+/* Create a newly alloced string from STRING with all spaces and
+   control characters converted to plus signs or %xx sequences.  The
+   function returns the new string or NULL in case of a malloc
+   failure.
+
+   Note that we also escape the quote character to work around a bug
+   in the mingw32 runtime which does not correcty handle command line
+   quoting.  We correctly double the quote mark when calling a program
+   (i.e. gpg-protect-tool), but the pre-main code does not notice the
+   double quote as an escaped quote.  We do this also on POSIX systems
+   for consistency.  */
+char *
+percent_plus_escape (const char *string)
+{
+  char *buffer, *p;
+  const char *s;
+  size_t length;
+
+  for (length=1, s=string; *s; s++)
+    {
+      if (*s == '+' || *s == '\"' || *s == '%' 
+          || *(const unsigned char *)s < 0x20)
+        length += 3;
+      else
+        length++;
+    }
+  
+  buffer = p = xtrymalloc (length);
+  if (!buffer)
+    return NULL;
+
+  for (s=string; *s; s++)
+    {
+      if (*s == '+' || *s == '\"' || *s == '%'
+          || *(const unsigned char *)s < 0x20)
+        {
+          snprintf (p, 4, "%%%02X", *(unsigned char *)s);
+          p += 3;
+        }
+      else if (*s == ' ')
+        *p++ = '+';
+      else
+        *p++ = *s;
+    }
+  *p = 0;
+
+  return buffer;
+
+}
diff --git a/common/t-percent.c b/common/t-percent.c
new file mode 100644 (file)
index 0000000..93d95f7
--- /dev/null
@@ -0,0 +1,97 @@
+/* t-percent.c - Module test for percent.c
+ *     Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "util.h"
+
+#define pass()  do { ; } while(0)
+#define fail(a)  do { fprintf (stderr, "%s:%d: test %d failed\n",\
+                               __FILE__,__LINE__, (a));          \
+                     exit (1);                                   \
+                   } while(0)
+
+static void
+test_percent_plus_escape (void)
+{
+  static struct {
+    const char *string;
+    const char *expect;
+  } tbl[] = {
+    { 
+      "",
+      "" 
+    }, { 
+      "a",
+      "a",
+    }, { 
+      " ",
+      "+",
+    }, { 
+      "  ",
+      "++"
+    }, { 
+      "+ +",
+      "%2B+%2B"
+    }, { 
+      "\" \"",
+      "%22+%22"
+    }, { 
+      "%22",
+      "%2522"
+    }, { 
+      "%% ",
+      "%25%25+"
+    }, { 
+      "\n ABC\t",
+      "%0A+ABC%09"
+    }, { NULL, NULL }
+  };
+  char *buf;
+  int i;
+  
+  for (i=0; tbl[i].string; i++)
+    {
+      buf = percent_plus_escape (tbl[i].string);
+      if (!buf)
+        {
+          fprintf (stderr, "out of core: %s\n", strerror (errno));
+          exit (2);
+        }
+      if (strcmp (buf, tbl[i].expect))
+        fail (i);
+      xfree (buf);
+    }
+}
+
+
+int
+main (int argc, char **argv)
+{
+  (void)argc;
+  (void)argv;
+  
+  test_percent_plus_escape ();
+
+  return 0;
+}
+
index 29955a4..66569e2 100644 (file)
@@ -199,6 +199,9 @@ const char *hex2str (const char *hexstring,
                      char *buffer, size_t bufsize, size_t *buflen);
 char *hex2str_alloc (const char *hexstring, size_t *r_count);
 
+/*-- percent.c --*/
+char *percent_plus_escape (const char *string);
+
 
 /*-- homedir.c --*/
 const char *standard_homedir (void);
index eec3d6f..0ad19ab 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-05  Werner Koch  <wk@g10code.com>
+
+       * call-agent.c (percent_plus_escape): Rename to
+       my_percent_plus_escape and also escape the percent character.
+       Change all callers.
+
 2008-11-18  Werner Koch  <wk@g10code.com>
 
        * gpg.c (build_lib_list): Remove.
index 15c17b0..33025ef 100644 (file)
@@ -148,15 +148,15 @@ unescape_status_string (const unsigned char *s)
    escaping.  Note that the provided buffer needs to be 3 times the
    size of ATEXT plus 1.  Returns a pointer to the leading Nul in P. */
 static char *
-percent_plus_escape (char *p, const char *atext)
+my_percent_plus_escape (char *p, const char *atext)
 {
   const unsigned char *s;
 
   for (s=atext; *s; s++)
     {
-      if (*s < ' ' || *s == '+')
+      if (*s < ' ' || *s == '+' || *s == '%')
         {
-          sprintf (p, "%%%02X", *s);
+          snprintf (p, 4, "%%%02X", *s);
           p += 3;
         }
       else if (*s == ' ')
@@ -865,25 +865,25 @@ agent_get_passphrase (const char *cache_id,
 
   p = stpcpy (line, cmd);
   if (cache_id && *cache_id)
-    p = percent_plus_escape (p, cache_id);
+    p = my_percent_plus_escape (p, cache_id);
   else
     *p++ = 'X';
   *p++ = ' ';
 
   if (err_msg && *err_msg)
-    p = percent_plus_escape (p, err_msg);
+    p = my_percent_plus_escape (p, err_msg);
   else
     *p++ = 'X';
   *p++ = ' ';
 
   if (prompt && *prompt)
-    p = percent_plus_escape (p, prompt);
+    p = my_percent_plus_escape (p, prompt);
   else
     *p++ = 'X'; 
   *p++ = ' ';
 
   if (desc_msg && *desc_msg)
-    p = percent_plus_escape (p, desc_msg);
+    p = my_percent_plus_escape (p, desc_msg);
   else
     *p++ = 'X';
   *p = 0;
index 37ef9e8..67e35f0 100644 (file)
@@ -1,3 +1,14 @@
+2008-12-05  Werner Koch  <wk@g10code.com>
+
+       * certreqgen.c (create_request): Provide a custom prompt for the
+       signing.
+
+       * certdump.c (gpgsm_format_keydesc): Remove debug output.
+       (gpgsm_format_keydesc): Remove saving of errno as xfree is
+       supposed not to change it.  Use the new percent_plus_escape
+       function which also fixes the issue that we did not escaped a
+       percent in the past.
+
 2008-11-18  Werner Koch  <wk@g10code.com>
 
        * gpgsm.c (make_libversion): New.
index ddfc1d1..71907d1 100644 (file)
@@ -924,13 +924,12 @@ gpgsm_fpr_and_name_for_status (ksba_cert_t cert)
 
 
 /* Create a key description for the CERT, this may be passed to the
-   pinentry.  The caller must free the returned string. NULL may be
+   pinentry.  The caller must free the returned string.  NULL may be
    returned on error. */
 char *
 gpgsm_format_keydesc (ksba_cert_t cert)
 {
-  char *name, *subject, *buffer, *p;
-  const char *s;
+  char *name, *subject, *buffer;
   ksba_isotime_t t;
   char created[20];
   char expires[20];
@@ -939,10 +938,8 @@ gpgsm_format_keydesc (ksba_cert_t cert)
   char *orig_codeset;
 
   name = ksba_cert_get_subject (cert, 0);
-  log_printhex ("XXXX NAME: ", name, strlen (name));
   subject = name? gpgsm_format_name2 (name, 0) : NULL;
   ksba_free (name); name = NULL;
-  log_printhex ("YYYY NAME: ", subject, strlen (subject));
 
   sexp = ksba_cert_get_serial (cert);
   sn = sexp? gpgsm_format_serial (sexp) : NULL;
@@ -975,38 +972,16 @@ gpgsm_format_keydesc (ksba_cert_t cert)
   
   if (!name)
     {
-      int save_errno = errno;
       xfree (subject);
       xfree (sn);
-      errno = save_errno;
       return NULL;
     }
   
   xfree (subject);
   xfree (sn);
 
-  buffer = p = xtrymalloc (strlen (name) * 3 + 1);
-  for (s=name; *s; s++)
-    {
-      /* We also escape the quote character to work around a bug in
-         the mingw32 runtime which does not correcty handle command
-         line quoting.  We correctly double the quote mark when
-         calling a program (i.e. gpg-protect-tool), but the pre-main
-         code does not notice the double quote as an escaped
-         quote.  */
-      if (*s < ' ' || *s == '+' || *s == '\"')
-        {
-          sprintf (p, "%%%02X", *(unsigned char *)s);
-          p += 3;
-        }
-      else if (*s == ' ')
-        *p++ = '+';
-      else
-        *p++ = *s;
-    }
-  *p = 0;
+  buffer = percent_plus_escape (name);
   xfree (name); 
-
   return buffer;
 }
 
index 30b8179..ca791aa 100644 (file)
@@ -788,6 +788,8 @@ create_request (ctrl_t ctrl,
           gcry_sexp_release (s_pkey);
           bin2hex (grip, 20, hexgrip);
 
+          log_info ("about to sign CSR for key: &%s\n", hexgrip); 
+
           if (carddirect)
             rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
                                      gcry_md_read(md, GCRY_MD_SHA1), 
@@ -795,11 +797,23 @@ create_request (ctrl_t ctrl,
                                      GCRY_MD_SHA1,
                                      &sigval, &siglen);
           else
-            rc = gpgsm_agent_pksign (ctrl, hexgrip, NULL,
-                                     gcry_md_read(md, GCRY_MD_SHA1), 
-                                     gcry_md_get_algo_dlen (GCRY_MD_SHA1),
-                                     GCRY_MD_SHA1,
-                                     &sigval, &siglen);
+            {
+              char *orig_codeset;
+              char *desc;
+
+              orig_codeset = i18n_switchto_utf8 ();
+              desc = percent_plus_escape 
+                (_("To complete this certificate request please enter"
+                   " the passphrase for the key you just created once"
+                   " more.\n"));
+              i18n_switchback (orig_codeset);
+              rc = gpgsm_agent_pksign (ctrl, hexgrip, desc,
+                                       gcry_md_read(md, GCRY_MD_SHA1), 
+                                       gcry_md_get_algo_dlen (GCRY_MD_SHA1),
+                                       GCRY_MD_SHA1,
+                                       &sigval, &siglen);
+              xfree (desc);
+            }
           if (rc)
             {
               log_error ("signing failed: %s\n", gpg_strerror (rc));
@@ -818,7 +832,7 @@ create_request (ctrl_t ctrl,
         }
     }
   while (stopreason != KSBA_SR_READY);   
-  
+
 
  leave:
   gcry_md_close (md);