* minip12.c (parse_bag_encrypted_data): Print error if a bad
authorWerner Koch <wk@gnupg.org>
Wed, 29 Sep 2004 13:50:31 +0000 (13:50 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 29 Sep 2004 13:50:31 +0000 (13:50 +0000)
passphrase has been given.

* gpg-agent.texi (Invoking GPG-AGENT): Add a few words about the
expected pinentry filename.

* import.c (parse_p12): Write an error status line for bad
passphrases. Add new arg CTRL and changed caller.
* export.c (export_p12): Likewise.

TODO
agent/ChangeLog
agent/minip12.c
agent/protect-tool.c
doc/ChangeLog
doc/gpg-agent.texi
sm/ChangeLog
sm/export.c
sm/import.c

diff --git a/TODO b/TODO
index dd69544..89db14a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -86,7 +86,8 @@ might want to have an agent context for each service request
 * doc/
 ** Explain how to setup a root CA key as trusted
 ** Explain how trustlist.txt might be managed.
-
+** Document watchgnupg
+** Write a script to generate man pages from texi.
 
 * Requirements by the BSI
 ** Support authorityKeyIdentifier.keyIdentifier
index 22846f3..f72bd50 100644 (file)
@@ -1,3 +1,8 @@
+2004-09-29  Werner Koch  <wk@g10code.com>
+
+       * minip12.c (parse_bag_encrypted_data): Print error if a bad
+       passphrase has been given.
+
 2004-09-28  Werner Koch  <wk@g10code.com>
 
        * protect.c (agent_unprotect): Fixed wiping of CLEARTEXT.  Thanks
index e32a40d..fc9b26d 100644 (file)
@@ -379,7 +379,6 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
   
 
 
-
 static int
 parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
                           int startoffset, const char *pw,
@@ -393,8 +392,8 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
   char salt[8];
   unsigned int iter;
   unsigned char *plain = NULL;
-
-
+  int bad_pass = 0;
+  
   where = "start";
   if (parse_tag (&p, &n, &ti))
     goto bailout;
@@ -495,12 +494,21 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
 
   where = "outer.outer.seq";
   if (parse_tag (&p, &n, &ti))
-    goto bailout;
+    {
+      bad_pass = 1;
+      goto bailout;
+    }
   if (ti.class || ti.tag != TAG_SEQUENCE)
-    goto bailout;
+    {
+      bad_pass = 1;
+      goto bailout;
+    }
 
   if (parse_tag (&p, &n, &ti))
-    goto bailout;
+    {
+      bad_pass = 1;
+      goto bailout;
+    }
 
   /* Loop over all certificates inside the bab. */
   while (n)
@@ -611,6 +619,13 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
   gcry_free (plain);
   log_error ("encryptedData error at \"%s\", offset %u\n",
              where, (p - buffer)+startoffset);
+  if (bad_pass)
+    {
+      /* Note, that the following string might be used by other programs
+         to check for a bad passphrase; it should therefore not be
+         translated or changed. */
+      log_error ("possibly bad passphrase given\n");
+    }
   return -1;
 }
 
index 7cfb760..286adde 100644 (file)
@@ -882,6 +882,8 @@ export_p12_file (const char *fname)
       release_passphrase (pw);
       if (rc)
         {
+          if (opt_status_msg && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE )
+            log_info ("[PROTECT-TOOL:] bad-passphrase\n");
           log_error ("unprotecting key `%s' failed: %s\n",
                      fname, gpg_strerror (rc));
           xfree (key);
index d7015bd..6373b03 100644 (file)
@@ -1,5 +1,8 @@
 2004-09-29  Werner Koch  <wk@g10code.com>
 
+       * gpg-agent.texi (Invoking GPG-AGENT): Add a few words about the
+       expected pinentry filename.
+
         Changed license of the manual stuff to GPL.
        
        * gnupg.texi (Top): New menu item Helper Tools.
index ab28eeb..2b45a41 100644 (file)
@@ -52,9 +52,17 @@ GPG_TTY=`tty`
 export GPG_TTY
 @end smallexample
 
+@noindent
 It is important that this environment variable always reflects the
 output of the @code{tty} command.
 
+Please make sure that a proper pinentry program has been installed
+under the default filename (which is system dependant) or use the
+option @code{pinentry-pgm} to specify the full name of that program.
+It is often useful to install a symbolic link from the actual used
+pinentry (e.g. @file{/usr/bin/pinentry-gtk}) to the expected
+one (e.g. @file{/usr/bin/pinentry}).
+
 @c man end
 
 @noindent
index d687591..2391deb 100644 (file)
@@ -1,3 +1,9 @@
+2004-09-29  Werner Koch  <wk@g10code.com>
+
+       * import.c (parse_p12): Write an error status line for bad
+       passphrases. Add new arg CTRL and changed caller.
+       * export.c (export_p12): Likewise.
+
 2004-09-14  Werner Koch  <wk@g10code.com>
 
        * certchain.c (gpgsm_validate_chain): Give expired certificates a
index 3f74575..15ad87b 100644 (file)
@@ -65,7 +65,8 @@ typedef struct duptable_s *duptable_t;
 
 
 static void print_short_info (ksba_cert_t cert, FILE *fp);
-static gpg_error_t export_p12 (const unsigned char *certimg, size_t certimglen,
+static gpg_error_t export_p12 (ctrl_t ctrl,
+                               const unsigned char *certimg, size_t certimglen,
                                const char *prompt, const char *keygrip,
                                FILE **retfp);
 
@@ -423,7 +424,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
 
 
   prompt = gpgsm_format_keydesc (cert);
-  rc = export_p12 (image, imagelen, prompt, keygrip, &datafp);
+  rc = export_p12 (ctrl, image, imagelen, prompt, keygrip, &datafp);
   xfree (prompt);
   if (rc)
     goto leave;
@@ -587,6 +588,7 @@ popen_protect_tool (const char *pgmname,
               "--homedir", opt.homedir,
               "--p12-export",
               "--prompt", prompt?prompt:"", 
+              "--enable-status-msg",
               "--",
               keygrip,
               NULL);
@@ -610,7 +612,7 @@ popen_protect_tool (const char *pgmname,
 
 
 static gpg_error_t
-export_p12 (const unsigned char *certimg, size_t certimglen,
+export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
             const char *prompt, const char *keygrip,
             FILE **retfp)
 {
@@ -621,6 +623,7 @@ export_p12 (const unsigned char *certimg, size_t certimglen,
   FILE *infp = NULL, *outfp = NULL, *fp = NULL;
   char buffer[1024];
   pid_t pid = -1;
+  int bad_pass = 0;
 
   if (!opt.protect_tool_program || !*opt.protect_tool_program)
     pgmname = GNUPG_DEFAULT_PROTECT_TOOL;
@@ -675,7 +678,21 @@ export_p12 (const unsigned char *certimg, size_t certimglen,
           if (cont_line)
             log_printf ("%s", buffer);
           else
-            log_info ("%s", buffer);
+            {
+              if (!strncmp (buffer, "gpg-protect-tool: [PROTECT-TOOL:] ",34))
+                {
+                  char *p, *pend;
+
+                  p = buffer + 34;
+                  pend = strchr (p, ' ');
+                  if (pend)
+                    *pend = 0;
+                  if ( !strcmp (p, "bad-passphrase"))
+                    bad_pass++;
+                }
+              else 
+                log_info ("%s", buffer);
+            }
           pos = 0;
           cont_line = (c != '\n');
         }
@@ -731,6 +748,14 @@ export_p12 (const unsigned char *certimg, size_t certimglen,
     }
   else
     *retfp = outfp;
+  if (bad_pass)
+    {
+      /* During export this is the passphrase used to unprotect the
+         key and not the pkcs#12 thing as in export.  Therefore we can
+         issue the regular passphrase status.  FIXME: replace the all
+         zero keyid by a regular one. */
+      gpgsm_status (ctrl, STATUS_BAD_PASSPHRASE, "0000000000000000");
+    }
   return err;
 }
 
index 836ac08..938bc17 100644 (file)
@@ -55,7 +55,7 @@ struct stats_s {
  };
 
 
-static gpg_error_t parse_p12 (ksba_reader_t reader, FILE **retfp,
+static gpg_error_t parse_p12 (ctrl_t ctrl, ksba_reader_t reader, FILE **retfp,
                               struct stats_s *stats);
 
 
@@ -341,7 +341,7 @@ import_one (CTRL ctrl, struct stats_s *stats, int in_fd)
           Base64Context b64p12rdr;
           ksba_reader_t p12rdr;
           
-          rc = parse_p12 (reader, &certfp, stats);
+          rc = parse_p12 (ctrl, reader, &certfp, stats);
           if (!rc)
             {
               any = 1;
@@ -572,13 +572,14 @@ popen_protect_tool (const char *pgmname,
 
 
 /* Assume that the reader is at a pkcs#12 message and try to import
-   certificates from that stupid format. We will alos store secret
+   certificates from that stupid format.  We will also store secret
    keys.  All of the pkcs#12 parsing and key storing is handled by the
    gpg-protect-tool, we merely have to take care of receiving the
    certificates. On success RETFP returns a temporary file with
    certificates. */
 static gpg_error_t
-parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
+parse_p12 (ctrl_t ctrl, ksba_reader_t reader,
+           FILE **retfp, struct stats_s *stats)
 {
   const char *pgmname;
   gpg_error_t err = 0, child_err = 0;
@@ -588,6 +589,7 @@ parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
   char buffer[1024];
   size_t nread;
   pid_t pid = -1;
+  int bad_pass = 0;
 
   if (!opt.protect_tool_program || !*opt.protect_tool_program)
     pgmname = GNUPG_DEFAULT_PROTECT_TOOL;
@@ -681,8 +683,13 @@ parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
                   else if ( !strcmp (p, "bad-passphrase"))
                     ;
                 }
-              else
-                log_info ("%s", buffer);
+              else 
+                {
+                  log_info ("%s", buffer);
+                  if (!strncmp (buffer, "gpg-protect-tool: "
+                                "possibly bad passphrase given",46))
+                    bad_pass++;
+                }
             }
           pos = 0;
           cont_line = (c != '\n');
@@ -698,6 +705,7 @@ parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
         log_info ("%s\n", buffer);
     }
 
+
   /* If we found no error in the output of the cild, setup a suitable
      error code, which will later be reset if the exit status of the
      child is 0. */
@@ -738,5 +746,17 @@ parse_p12 (ksba_reader_t reader, FILE **retfp, struct stats_s *stats)
     }
   else
     *retfp = certfp;
+
+  if (bad_pass)
+    {
+      /* We only write a plain error code and not direct
+         BAD_PASSPHRASE because the pkcs12 parser might issue this
+         message multiple times, BAd_PASSPHRASE in general requires a
+         keyID and parts of the import might actually succeed so that
+         IMPORT_PROBLEM is also not appropriate. */
+      gpgsm_status_with_err_code (ctrl, STATUS_ERROR,
+                                  "import.parsep12", GPG_ERR_BAD_PASSPHRASE);
+    }
+  
   return err;
 }