[svn] GnuPG - r4650 - in trunk: . common doc g10 include scd sm

svn author wk cvs at cvs.gnupg.org
Wed Dec 12 11:28:36 CET 2007


Author: wk
Date: 2007-12-12 11:28:30 +0100 (Wed, 12 Dec 2007)
New Revision: 4650

Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/TODO
   trunk/common/ChangeLog
   trunk/common/asshelp.c
   trunk/common/audit.c
   trunk/common/audit.h
   trunk/configure.ac
   trunk/doc/help.de.txt
   trunk/doc/help.txt
   trunk/g10/ChangeLog
   trunk/g10/encode.c
   trunk/g10/encr-data.c
   trunk/g10/gpg.c
   trunk/g10/import.c
   trunk/g10/keyedit.c
   trunk/g10/main.h
   trunk/g10/mainproc.c
   trunk/g10/misc.c
   trunk/g10/parse-packet.c
   trunk/g10/pubkey-enc.c
   trunk/g10/sign.c
   trunk/include/ChangeLog
   trunk/include/cipher.h
   trunk/scd/ChangeLog
   trunk/scd/app-openpgp.c
   trunk/sm/ChangeLog
   trunk/sm/call-agent.c
   trunk/sm/call-dirmngr.c
   trunk/sm/certchain.c
   trunk/sm/encrypt.c
   trunk/sm/gpgsm.c
   trunk/sm/gpgsm.h
   trunk/sm/server.c
Log:
Support DSA2.
Support Camellia for testing.
More audit stuff.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/ChangeLog	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,3 +1,7 @@
+2007-12-12  Werner Koch  <wk at g10code.com>
+
+	* configure.ac (USE_CAMELLIA): Define by new option --enable-camellia.
+
 2007-12-03  Werner Koch  <wk at g10code.com>
 
 	* configure.ac: Add test gt_LC_MESSAGES..

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/NEWS	2007-12-12 10:28:30 UTC (rev 4650)
@@ -14,7 +14,15 @@
  * The envvars XAUTHORITY and PINENTRY_USER_DATA are now passed to the
    pinentry.
 
+ * Allow encryption using Elgamal keys with the algorithm id 20.
 
+ * Fixed the auto creation of the key stub for smartcards.  
+
+ * Fixed a rare bug in decryption using the OpenPGP card.
+
+ * Creating DSA2 keys is now possible.
+
+
 Noteworthy changes in version 2.0.7 (2007-09-10)
 ------------------------------------------------
 

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/TODO	2007-12-12 10:28:30 UTC (rev 4650)
@@ -91,7 +91,7 @@
 ** issue a NO_SECKEY xxxx if a -u key was not found.
 
 
-* When switching to libgcrypt 1.3
+* When switching to libgcrypt 1.4
 ** scd#encode_md_for_card, g10#encode_md_value, sm at do_encode_md
    Remove the extra test for a valid algorithm as libgcrypt will do it
    then in gcry_md_algo_info.

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/common/ChangeLog	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,3 +1,9 @@
+2007-12-11  Werner Koch  <wk at g10code.com>
+
+	* asshelp.c (send_pinentry_environment): Allow using of old
+	gpg-agents not capabale of the xauthority and pinentry_user_data
+	options.
+
 2007-12-04  Werner Koch  <wk at g10code.com>
 
 	* Makefile.am (t_helpfile_LDADD, module_maint_tests): New.

Modified: trunk/common/asshelp.c
===================================================================
--- trunk/common/asshelp.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/common/asshelp.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -172,6 +172,8 @@
     {
       err = send_one_option (ctx, errsource, "xauthority", 
                              opt_xauthority ? opt_xauthority : dft_xauthority);
+      if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
+        err = 0;
       if (err)
         return err;
     }
@@ -183,6 +185,8 @@
       err = send_one_option (ctx, errsource, "pinentry-user-data", 
                              opt_pinentry_user_data ?
                              opt_pinentry_user_data : dft_pinentry_user_data);
+      if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
+        err = 0;
       if (err)
         return err;
     }

Modified: trunk/common/audit.c
===================================================================
--- trunk/common/audit.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/common/audit.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -449,9 +449,9 @@
 
   if (ctx->use_html && format && oktext)
     {
-      if (!strcmp (oktext, "OK") || !strcmp (oktext, "Yes"))
+      if (!strcmp (oktext, "Yes"))
         color = "green";
-      else if (!strcmp (oktext, "FAIL") || !strcmp (oktext, "No"))
+      else if (!strcmp (oktext, "No"))
         color = "red";
     }
 
@@ -648,68 +648,179 @@
 }
 
 
+/* List the given certificiate.  If CERT is NULL, this is a NOP.  */
+static void
+list_cert (audit_ctx_t ctx, ksba_cert_t cert, int with_subj)
+{
+  char *name;
+  int idx;
+
+  name = get_cert_name (cert);
+  writeout_rem (ctx, "%s", name);
+  xfree (name);
+  if (with_subj)
+    {
+      enter_li (ctx);
+      for (idx=0; (name = get_cert_subject (cert, idx)); idx++)
+        {
+          writeout_rem (ctx, "%s", name);
+          xfree (name);
+        }
+      leave_li (ctx);
+    }
+}
+
+
 /* List the chain of certificates from STARTITEM up to STOPEVENT.  The
    certifcates are written out as comments.  */
 static void
 list_certchain (audit_ctx_t ctx, log_item_t startitem, audit_event_t stopevent)
 {
   log_item_t item;
-  char *name;
-  int idx;
 
   startitem = find_next_log_item (ctx, startitem, AUDIT_CHAIN_BEGIN,stopevent);
+  writeout_li (ctx, startitem? "Yes":"No", _("Certificate chain available"));
   if (!startitem)
-    {
-      writeout_li (ctx, gpg_strerror (GPG_ERR_MISSING_CERT)
-                   , _("Certificate chain"));
-      return; 
-    }
-  writeout_li (ctx, "OK", _("Certificate chain"));
+    return; 
+
   item = find_next_log_item (ctx, startitem, 
                              AUDIT_CHAIN_ROOTCERT, AUDIT_CHAIN_END);
   if (!item)
     writeout_rem (ctx, "%s", _("root certificate missing"));
   else
     {
-      name = get_cert_name (item->cert);
-      writeout_rem (ctx, "%s", name);
-      xfree (name);
+      list_cert (ctx, item->cert, 0);
     }
   item = startitem;
   while ( ((item = find_next_log_item (ctx, item, 
                                        AUDIT_CHAIN_CERT, AUDIT_CHAIN_END))))
     {
-      name = get_cert_name (item->cert);
-      writeout_rem (ctx, "%s", name);
-      xfree (name);
-      enter_li (ctx);
-      for (idx=0; (name = get_cert_subject (item->cert, idx)); idx++)
+      list_cert (ctx, item->cert, 1);
+    }
+}
+
+
+
+/* Process an encrypt operation's log.  */
+static void
+proc_type_encrypt (audit_ctx_t ctx)
+{
+  log_item_t loopitem, item;
+  int recp_no, idx;
+  char numbuf[35];
+  int algo;
+  char *name;
+
+  item = find_log_item (ctx, AUDIT_ENCRYPTION_DONE, 0);
+  writeout_li (ctx, item?"Yes":"No", "%s", _("Data encryption succeeded"));
+
+  enter_li (ctx);
+
+  item = find_log_item (ctx, AUDIT_GOT_DATA, 0);
+  writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
+
+  item = find_log_item (ctx, AUDIT_SESSION_KEY, 0);
+  writeout_li (ctx, item? "Yes":"No", "%s", _("Session key created"));
+  if (item)
+    {
+      algo = gcry_cipher_map_name (item->string);
+      if (algo)
+        writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo));
+      else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2"))
+        writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2");
+      else if (item->string)
+        writeout_rem (ctx, _("unsupported algorithm: %s"), item->string);
+      else
+        writeout_rem (ctx, _("seems to be not encrypted"));
+    }
+
+  item = find_log_item (ctx, AUDIT_GOT_RECIPIENTS, 0);
+  snprintf (numbuf, sizeof numbuf, "%d", 
+            item && item->have_intvalue? item->intvalue : 0);
+  writeout_li (ctx, numbuf, "%s", _("Number of recipients"));
+
+  /* Loop over all recipients.  */
+  loopitem = NULL;
+  recp_no = 0;
+  while ((loopitem=find_next_log_item (ctx, loopitem, AUDIT_ENCRYPTED_TO, 0)))
+    {
+      recp_no++;
+      writeout_li (ctx, NULL, _("Recipient %d"), recp_no);
+      if (loopitem->cert)
         {
+          name = get_cert_name (loopitem->cert);
           writeout_rem (ctx, "%s", name);
           xfree (name);
+          enter_li (ctx);
+          for (idx=0; (name = get_cert_subject (loopitem->cert, idx)); idx++)
+            {
+              writeout_rem (ctx, "%s", name);
+              xfree (name);
+            }
+          leave_li (ctx);
         }
-      leave_li (ctx);
     }
+
+  leave_li (ctx);
 }
 
 
 
-/* Process a verification operation.  */
+/* Process a sign operation's log.  */
 static void
+proc_type_sign (audit_ctx_t ctx)
+{
+  log_item_t item;
+
+  item = NULL;
+  writeout_li (ctx, item?"Yes":"No", "%s", _("Data signing succeeded"));
+
+  enter_li (ctx);
+
+  item = find_log_item (ctx, AUDIT_GOT_DATA, 0);
+  writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
+
+
+  leave_li (ctx);
+}
+
+
+
+/* Process a decrypt operation's log.  */
+static void
+proc_type_decrypt (audit_ctx_t ctx)
+{
+  log_item_t item;
+
+  item = NULL;
+  writeout_li (ctx, item?"Yes":"No", "%s", _("Data decryption succeeded"));
+
+  enter_li (ctx);
+
+  item = find_log_item (ctx, AUDIT_GOT_DATA, 0);
+  writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
+
+
+  leave_li (ctx);
+}
+
+
+
+/* Process a verification operation's log.  */
+static void
 proc_type_verify (audit_ctx_t ctx)
 {
   log_item_t loopitem, item;
   int signo, count, idx;
   char numbuf[35];
 
+  /* If there is at least one signature status we claim that the
+     verifciation succeeded.  This does not mean that the data has
+     verified okay.  */
+  item = find_log_item (ctx, AUDIT_SIG_STATUS, 0);
+  writeout_li (ctx, item?"Yes":"No", "%s", _("Data verification succeeded"));
   enter_li (ctx);
-  
-  writeout_li (ctx, "fixme", "%s", _("Signature verification"));
-  enter_li (ctx);
 
-  writeout_li (ctx, "fixme", "%s", _("Gpg-Agent ready"));
-  writeout_li (ctx, "fixme", "%s", _("Dirmngr ready"));
-
   item = find_log_item (ctx, AUDIT_GOT_DATA, AUDIT_NEW_SIG);
   writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
   if (!item)
@@ -721,19 +832,14 @@
     goto leave;
 
   item = find_log_item (ctx, AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG);
-  if (item)
-    writeout_li (ctx, "OK", "%s", _("Parsing signature"));
-  else 
+  writeout_li (ctx, item?"Yes":"No", "%s", _("Parsing signature succeeded"));
+  if (!item)
     {
       item = find_log_item (ctx, AUDIT_BAD_DATA_HASH_ALGO, AUDIT_NEW_SIG);
       if (item)
-        {
-          writeout_li (ctx,"FAIL", "%s",  _("Parsing signature"));
-          writeout_rem (ctx, _("Bad hash algorithm: %s"), 
-                        item->string? item->string:"?");
-        }
-      else
-        writeout_li (ctx, "FAIL", "%s", _("Parsing signature") );
+        writeout_rem (ctx, _("Bad hash algorithm: %s"), 
+                      item->string? item->string:"?");
+
       goto leave;
     }
 
@@ -761,19 +867,30 @@
                                  AUDIT_CHAIN_STATUS, AUDIT_NEW_SIG);
       if (item && item->have_err)
         {
-          writeout_li (ctx, item->err? "FAIL":"OK", 
-                       _("Validation of certificate chain"));
+          writeout_li (ctx, item->err? "No":"Yes", 
+                       _("Certificate chain valid"));
           if (item->err)
             writeout_rem (ctx, "%s", gpg_strerror (item->err));
         }
       
       /* Show whether the root certificate is fine.  */
-      writeout_li (ctx, "No", "%s", _("Root certificate trustworthy"));
-      add_helptag (ctx, "gpgsm.root-cert-not-trusted");
+      item = find_next_log_item (ctx, loopitem,
+                                 AUDIT_ROOT_TRUSTED, AUDIT_CHAIN_STATUS);
+      if (item)
+        {
+          writeout_li (ctx, item->err?"No":"Yes", "%s",
+                       _("Root certificate trustworthy"));
+          if (item->err)
+            {
+              add_helptag (ctx, "gpgsm.root-cert-not-trusted");
+              writeout_rem (ctx, "%s", gpg_strerror (item->err));
+              list_cert (ctx, item->cert, 0);
+            }
+        }
 
       /* Show result of the CRL/OCSP check.  */
       writeout_li (ctx, "-", "%s", _("CRL/OCSP check of certificates"));
-      add_helptag (ctx, "gpgsm.ocsp-problem");
+ /*      add_helptag (ctx, "gpgsm.ocsp-problem"); */
 
 
       leave_li (ctx);
@@ -805,9 +922,7 @@
         }
       leave_li (ctx);
     }
-
   leave_li (ctx);
-  leave_li (ctx);
 }
 
 
@@ -818,16 +933,24 @@
 audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
 {
   int idx;
-  int maxlen;
   size_t n;
+  log_item_t item;
   helptag_t helptag;
-
-  if (getenv ("use_html"))
-    use_html = 1;
-
+  const char *s;
+  int show_raw = 0;
+  
   if (!ctx)
     return;
 
+  /* We use an environment variable to include some debug info in the
+     log.  */
+  if ((s = getenv ("gnupg_debug_audit")))
+    {
+      show_raw = 1;
+      if (!strcmp (s, "html"))
+        use_html = 1;
+    }
+
   assert (!ctx->outstream);
   ctx->outstream = out;
   ctx->use_html = use_html;
@@ -843,51 +966,87 @@
       goto leave;
     }
 
-  for (idx=0,maxlen=0; idx < DIM (eventstr_msgidx); idx++)
+  if (show_raw)
     {
-      n = strlen (eventstr_msgstr + eventstr_msgidx[idx]);    
-      if (n > maxlen)
-        maxlen = n;
-    }
+      int maxlen;
 
-  if (use_html)
-    es_fputs ("<pre>\n", out);
-  for (idx=0; idx < ctx->logused; idx++)
-    {
-      es_fprintf (out, "log: %-*s", 
-                  maxlen, event2str (ctx->log[idx].event));
-      if (ctx->log[idx].have_intvalue)
-        es_fprintf (out, " i=%d", ctx->log[idx].intvalue); 
-      if (ctx->log[idx].string)
+      for (idx=0,maxlen=0; idx < DIM (eventstr_msgidx); idx++)
         {
-          es_fputs (" s=`", out); 
-          writeout (ctx, ctx->log[idx].string); 
-          es_fputs ("'", out); 
+          n = strlen (eventstr_msgstr + eventstr_msgidx[idx]);    
+          if (n > maxlen)
+            maxlen = n;
         }
-      if (ctx->log[idx].cert)
-        es_fprintf (out, " has_cert"); 
-      if (ctx->log[idx].have_err)
+      
+      if (use_html)
+        es_fputs ("<pre>\n", out);
+      for (idx=0; idx < ctx->logused; idx++)
         {
-          es_fputs (" err=`", out);
-          writeout (ctx, gpg_strerror (ctx->log[idx].err)); 
-          es_fputs ("'", out);
+          es_fprintf (out, "log: %-*s", 
+                      maxlen, event2str (ctx->log[idx].event));
+          if (ctx->log[idx].have_intvalue)
+            es_fprintf (out, " i=%d", ctx->log[idx].intvalue); 
+          if (ctx->log[idx].string)
+            {
+              es_fputs (" s=`", out); 
+              writeout (ctx, ctx->log[idx].string); 
+              es_fputs ("'", out); 
+            }
+          if (ctx->log[idx].cert)
+            es_fprintf (out, " has_cert"); 
+          if (ctx->log[idx].have_err)
+            {
+              es_fputs (" err=`", out);
+              writeout (ctx, gpg_strerror (ctx->log[idx].err)); 
+              es_fputs ("'", out);
+            }
+          es_fputs ("\n", out);
         }
-      es_fputs ("\n", out);
+      if (use_html)
+        es_fputs ("</pre>\n", out);
+      else
+        es_fputs ("\n", out);
     }
-  if (use_html)
-    es_fputs ("</pre>\n", out);
-  else
-    es_fputs ("\n", out);
 
+  enter_li (ctx);
   switch (ctx->type)
     {
     case AUDIT_TYPE_NONE:
-      writeout_para (ctx, _("Audit of this operation is not supported."));
+      writeout_li (ctx, NULL, _("Unknown operation"));
       break;
+    case AUDIT_TYPE_ENCRYPT:
+      proc_type_encrypt (ctx);
+      break;
+    case AUDIT_TYPE_SIGN:
+      proc_type_sign (ctx);
+      break;
+    case AUDIT_TYPE_DECRYPT:
+      proc_type_decrypt (ctx);
+      break;
     case AUDIT_TYPE_VERIFY:
       proc_type_verify (ctx);
       break;
     }
+  item = find_log_item (ctx, AUDIT_AGENT_READY, 0);
+  if (item && item->have_err)
+    {
+      writeout_li (ctx, item->err? "No":"Yes", "%s", _("Gpg-Agent usable"));
+      if (item->err)
+        {
+          writeout_rem (ctx, "%s", gpg_strerror (item->err));
+          add_helptag (ctx, "gnupg.agent-problem");
+        }
+    }
+  item = find_log_item (ctx, AUDIT_DIRMNGR_READY, 0);
+  if (item && item->have_err)
+    {
+      writeout_li (ctx, item->err? "No":"Yes", "%s", _("Dirmngr usable"));
+      if (item->err)
+        {
+          writeout_rem (ctx, "%s", gpg_strerror (item->err));
+          add_helptag (ctx, "gnupg.dirmngr-problem");
+        }
+    }
+  leave_li (ctx);
 
 
   /* Show the help from the collected help tags.  */

Modified: trunk/common/audit.h
===================================================================
--- trunk/common/audit.h	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/common/audit.h	2007-12-12 10:28:30 UTC (rev 4650)
@@ -31,6 +31,9 @@
 typedef enum
   {
     AUDIT_TYPE_NONE  = 0,  /* No type set.  */
+    AUDIT_TYPE_ENCRYPT,    /* Data encryption.  */
+    AUDIT_TYPE_SIGN,       /* Signature creation.  */
+    AUDIT_TYPE_DECRYPT,    /* Data decryption.  */
     AUDIT_TYPE_VERIFY      /* Signature verification.  */
   }
 audit_type_t;
@@ -49,6 +52,16 @@
        now.  This indicates that all parameters are okay and we can
        start to process the actual data.  */
 
+    AUDIT_AGENT_READY,   /* err */
+    /* Indicates whether the gpg-agent is available.  For some
+       operations the agent is not required and thus no such event
+       will be logged.  */
+    
+    AUDIT_DIRMNGR_READY,   /* err */
+    /* Indicates whether the Dirmngr is available.  For some
+       operations the Dirmngr is not required and thus no such event
+       will be logged.  */
+
     AUDIT_GOT_DATA,
     /* Data to be processed has been seen.  */
 
@@ -122,7 +135,29 @@
     AUDIT_CHAIN_STATUS,  /* err */
     /* Tells the final status of the chain validation.  */
 
+    AUDIT_ROOT_TRUSTED,  /* cert, err */
+    /* Tells whether the root certificate is trusted.  This event is
+       emmited durcing chain validation.  */
 
+    AUDIT_GOT_RECIPIENTS,  /* int */
+    /* Records the number of recipients to be used for encryption.
+       This includes the recipients set by --encrypt-to but records 0
+       if no real recipient has been given.  */
+
+    AUDIT_SESSION_KEY,     /* string */
+    /* Mark the creation or availibility of the session key.  The
+       parameter is the algorithm ID.  */
+
+    AUDIT_ENCRYPTED_TO,   /* cert, err */
+    /* Records the certificate used for encryption and whether the
+       session key could be encrypted to it (err==0).  */
+
+    AUDIT_ENCRYPTION_DONE,
+    /* Encryption succeeded.  */
+
+    
+
+
     AUDIT_LAST_EVENT  /* Marker for parsing this list.  */
   }
 audit_event_t;

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/configure.ac	2007-12-12 10:28:30 UTC (rev 4650)
@@ -73,6 +73,7 @@
 use_bzip2=yes
 use_exec=yes
 disable_keyserver_path=no
+use_camellia=no
 
 
 GNUPG_BUILD_PROGRAM(gpg, yes)
@@ -172,7 +173,22 @@
    use_bzip2=$enableval)
 AC_MSG_RESULT($use_bzip2)
 
+# Check whether testing support for Camellia has been requested
+AC_MSG_CHECKING([whether to enable the CAMELLIA cipher for gpg])
+AC_ARG_ENABLE(camellia,
+   AC_HELP_STRING([--enable-camellia],[enable the CAMELLIA cipher for gpg]),
+   use_camellia=$enableval)
+AC_MSG_RESULT($use_camellia)
+if test x"$use_camellia" = xyes ; then
+   AC_DEFINE(USE_CAMELLIA,1,[Define to include the CAMELLIA cipher into gpg])
+   AC_MSG_WARN([[
+***
+*** The Camellia cipher for gpg is for testing only and 
+*** is NOT for production use!
+***]])
+fi
 
+
 # Configure option to allow or disallow execution of external
 # programs, like a photo viewer.
 AC_MSG_CHECKING([whether to enable external program execution])
@@ -1417,4 +1433,10 @@
                  gpg-check-pattern will not be build.
 "
 fi
+if test  x"$use_camellia" = xyes ; then
+  echo
+  echo "WARNING: The Camellia cipher for gpg is for testing only"
+  echo "         and is NOT for production use!"
+  echo
+fi
 

Modified: trunk/doc/help.de.txt
===================================================================
--- trunk/doc/help.de.txt	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/doc/help.de.txt	2007-12-12 10:28:30 UTC (rev 4650)
@@ -272,6 +272,6 @@
 
 
 # Local variables:
-# mode: fundamental
+# mode: default-generic
 # coding: utf-8
 # End:

Modified: trunk/doc/help.txt
===================================================================
--- trunk/doc/help.txt	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/doc/help.txt	2007-12-12 10:28:30 UTC (rev 4650)
@@ -52,6 +52,44 @@
 .
 
 
+.gnupg.agent-problem
+# There was a problem accessing or starting the agent.
+It was either not possible to connect to a running Gpg-Agent or a
+communication problem with a running agent occurred.  
+
+The system uses a background process, called Gpg-Agent, for processing
+private keys and to ask for passphrases.  The agent is usually started
+when the user logs in and runs as long the user is logged in. In case
+that no agent is available, the system tries to start one on the fly
+but that version of the agent is somewhat limited in functionality and
+thus may lead to little problems.
+
+You probably need to ask your administrator on how to solve the
+problem.  As a workaround you might try to log out and in to your
+session and see whether this helps.  If this helps please tell the
+administrator anyway because this indicates a bug in the software.
+.
+
+
+.gnupg.dirmngr-problem
+# There was a problen accessing the dirmngr.
+It was either not possible to connect to a running Dirmngr or a
+communication problem with a running Dirmngr occurred.  
+
+To lookup certificate revocation lists (CRLs), performing OCSP
+validation and to lookup keys through LDAP servers, the system uses an
+external service program named Dirmngr.  The Dirmngr is usually running
+as a system service (daemon) and does not need any attention by the
+user.  In case of problems the system might start its own copy of the
+Dirmngr on a per request base; this is a workaround and yields limited
+performance.
+
+If you encounter this problem, you should ask your system
+administrator how to proceed.  As an interim solution you may try to
+disable CRL checking in gpgsm's configuration.
+.
+
+
 .gpg.edit_ownertrust.value
 # The help identies prefixed with "gpg." used to be hard coded in gpg
 # but may now be overridden by help texts from this file.
@@ -312,6 +350,6 @@
 
 
 # Local variables:
-# mode: fundamental
+# mode: default-generic
 # coding: utf-8
 # End:

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/ChangeLog	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,6 +1,30 @@
+2007-12-12  Werner Koch  <wk at g10code.com>
+
+	* misc.c (map_cipher_openpgp_to_gcry): New.  Used to map Camellia
+	algorithms to Gcrypt.
+	(openpgp_cipher_test_algo): Call new map function.  Replace
+	all remaining calls to gcry_cipher_test_algo by a call to this.
+	(openpgp_cipher_algo_name): New.  Replace all remaining calls to
+	gcry_cipher_algo_name by a call to this.
+	(map_cipher_gcry_to_openpgp): New.
+	(string_to_cipher_algo): Use it.
+	* gpg.c	(main): Print a warning if Camellia support is build in.
+	
+	* gpg.c (print_algo_names): New.  From the 1.4 branch by David.
+	(list_config): Use it here for the "ciphername" and "digestname"
+	config items so we can get a script-parseable list of the names.
+
+	* parse-packet.c (parse_onepass_sig): Sigclass is hex, so include
+	the 0x.
+
+	* sign.c (match_dsa_hash): Remove conditional builds dending on
+	USE_SHAxxx.  We don't need this becuase it can be expected that
+	libgcrypt provides it.  However we need to runtime test for SHA244
+	becuase that is only available with libgcrypt 2.4.
+
 2007-12-11  Werner Koch  <wk at g10code.com>
 
-	* mainproc.c (proc_pubkey_enc): Allo type 20 Elgamal key for
+	* mainproc.c (proc_pubkey_enc): Allow type 20 Elgamal key for
 	decryption.
 
 2007-12-10  Werner Koch  <wk at g10code.com>

Modified: trunk/g10/encode.c
===================================================================
--- trunk/g10/encode.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/encode.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -244,7 +244,7 @@
 
 	if(opt.verbose)
 	  log_info(_("using cipher %s\n"),
-		   gcry_cipher_algo_name (cfx.dek->algo));
+		   openpgp_cipher_algo_name (cfx.dek->algo));
 
 	cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
     }
@@ -558,7 +558,7 @@
 				opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
 	log_info(_("WARNING: forcing symmetric cipher %s (%d)"
 		   " violates recipient preferences\n"),
-		 gcry_cipher_algo_name (opt.def_cipher_algo),
+		 openpgp_cipher_algo_name (opt.def_cipher_algo),
 		 opt.def_cipher_algo);
 
       cfx.dek->algo = opt.def_cipher_algo;
@@ -750,7 +750,7 @@
 					NULL)!=opt.def_cipher_algo)
 		log_info(_("forcing symmetric cipher %s (%d) "
 			   "violates recipient preferences\n"),
-			 gcry_cipher_algo_name (opt.def_cipher_algo),
+			 openpgp_cipher_algo_name (opt.def_cipher_algo),
 			 opt.def_cipher_algo);
 
 	      efx->cfx.dek->algo = opt.def_cipher_algo;
@@ -847,7 +847,7 @@
 		char *ustr = get_user_id_string_native (enc->keyid);
 		log_info(_("%s/%s encrypted for: \"%s\"\n"),
                          gcry_pk_algo_name (enc->pubkey_algo),
-                         gcry_cipher_algo_name (dek->algo),
+                         openpgp_cipher_algo_name (dek->algo),
                          ustr );
 		xfree(ustr);
 	    }

Modified: trunk/g10/encr-data.c
===================================================================
--- trunk/g10/encr-data.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/encr-data.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -88,8 +88,9 @@
 
   if ( opt.verbose && !dek->algo_info_printed )
     {
-      if (!gcry_cipher_test_algo (dek->algo))
-        log_info (_("%s encrypted data\n"), gcry_cipher_algo_name (dek->algo));
+      if (!openpgp_cipher_test_algo (dek->algo))
+        log_info (_("%s encrypted data\n"), 
+                  openpgp_cipher_algo_name (dek->algo));
       else
         log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
       dek->algo_info_printed = 1;

Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/gpg.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -791,7 +791,7 @@
       case 35:
 	if( !ciphers )
 	    ciphers = build_list(_("Cipher: "), 'S', 
-                                 gcry_cipher_algo_name,
+                                 openpgp_cipher_algo_name,
                                  openpgp_cipher_test_algo );
 	p = ciphers;
 	break;
@@ -1384,6 +1384,24 @@
 }
 
 
+static void
+print_algo_names(int (*checker)(int),const char *(*mapper)(int))
+{
+  int i,first=1;
+
+  for(i=0;i<=110;i++)
+    {
+      if(!checker(i))
+	{
+	  if(first)
+	    first=0;
+	  else
+	    printf(";");
+	  printf("%s",mapper(i));
+	}
+    }
+}
+
 /* In the future, we can do all sorts of interesting configuration
    output here.  For now, just give "group" as the Enigmail folks need
    it, and pubkey, cipher, hash, and compress as they may be useful
@@ -1450,6 +1468,14 @@
 	  any=1;
 	}
 
+      if (show_all || !ascii_strcasecmp (name,"ciphername"))
+	{
+	  printf ("cfg:ciphername:");
+	  print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name);
+	  printf ("\n");
+	  any = 1;
+	}
+
       if(show_all
 	 || ascii_strcasecmp(name,"digest")==0
 	 || ascii_strcasecmp(name,"hash")==0)
@@ -1460,6 +1486,16 @@
 	  any=1;
 	}
 
+      if (show_all
+          || !ascii_strcasecmp(name,"digestname")
+          || !ascii_strcasecmp(name,"hashname"))
+	{
+	  printf ("cfg:digestname:");
+	  print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
+	  printf("\n");
+	  any=1;
+	}
+      
       if(show_all || ascii_strcasecmp(name,"compress")==0)
 	{
 	  printf("cfg:compress:");
@@ -2864,6 +2900,15 @@
         log_set_prefix (NULL, 1|2|4);
       }
 
+#ifdef USE_CAMELLIA    
+    /* We better also print a runtime warning if people build it with
+       support for Camellia (which is not yet defined by OpenPGP). */
+    log_info ("WARNING: This version has been built with support for the "
+              "Camellia cipher.\n");
+    log_info ("         It is for testing only and is NOT for production "
+              "use!\n");
+#endif
+
     if (opt.verbose > 2)
         log_info ("using character set `%s'\n", get_native_charset ());
 
@@ -3129,7 +3174,7 @@
 	if(opt.def_cipher_algo
 	   && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
 	  {
-	    badalg = gcry_cipher_algo_name (opt.def_cipher_algo);
+	    badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
 	    badtype = PREFTYPE_SYM;
 	  }
 	else if(opt.def_digest_algo

Modified: trunk/g10/import.c
===================================================================
--- trunk/g10/import.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/import.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -602,9 +602,9 @@
 		  if (openpgp_cipher_test_algo (prefs->value))
 		    {
 		      const char *algo = 
-                        (gcry_cipher_test_algo (prefs->value)
+                        (openpgp_cipher_test_algo (prefs->value)
                          ? num 
-                         : gcry_cipher_algo_name (prefs->value));
+                         : openpgp_cipher_algo_name (prefs->value));
 		      if(!problem)
 			check_prefs_warning(pk);
 		      log_info(_("         \"%s\": preference for cipher"

Modified: trunk/g10/keyedit.c
===================================================================
--- trunk/g10/keyedit.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/keyedit.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -2325,9 +2325,10 @@
                     tty_printf (", ");
                 any = 1;
                 /* We don't want to display strings for experimental algos */
-                if (!gcry_cipher_test_algo (prefs[i].value)
+                if (!openpgp_cipher_test_algo (prefs[i].value)
                     && prefs[i].value < 100 )
-                    tty_printf ("%s", gcry_cipher_algo_name (prefs[i].value));
+                    tty_printf ("%s",
+                                openpgp_cipher_algo_name (prefs[i].value));
                 else
                     tty_printf ("[%d]", prefs[i].value);
                 if (prefs[i].value == CIPHER_ALGO_3DES )
@@ -2337,7 +2338,7 @@
         if (!des_seen) {
             if (any)
                 tty_printf (", ");
-            tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES));
+            tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
         }
         tty_printf ("\n     ");
 	tty_printf (_("Digest: "));

Modified: trunk/g10/main.h
===================================================================
--- trunk/g10/main.h	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/main.h	2007-12-12 10:28:30 UTC (rev 4650)
@@ -83,6 +83,7 @@
 u32 buffer_to_u32( const byte *buffer );
 const byte *get_session_marker( size_t *rlen );
 int openpgp_cipher_test_algo( int algo );
+const char *openpgp_cipher_algo_name (int algo);
 int openpgp_pk_test_algo( int algo );
 int openpgp_pk_test_algo2 ( int algo, unsigned int use );
 int openpgp_pk_algo_usage ( int algo );

Modified: trunk/g10/mainproc.c
===================================================================
--- trunk/g10/mainproc.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/mainproc.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -274,9 +274,9 @@
     else if(!c->dek)
       {
         int algo = enc->cipher_algo;
-	const char *s = gcry_cipher_algo_name (algo);
+	const char *s = openpgp_cipher_algo_name (algo);
 
-	if (!gcry_cipher_test_algo (algo))
+	if (!openpgp_cipher_test_algo (algo))
 	  {
 	    if(!opt.quiet)
 	      {
@@ -524,8 +524,8 @@
 	    algo = opt.def_cipher_algo;
 	    if ( algo )
 	      log_info (_("assuming %s encrypted data\n"),
-                        gcry_cipher_algo_name (algo));
-	    else if ( gcry_cipher_test_algo (CIPHER_ALGO_IDEA) )
+                        openpgp_cipher_algo_name (algo));
+	    else if ( openpgp_cipher_test_algo (CIPHER_ALGO_IDEA) )
 	      {
 		algo = opt.def_cipher_algo;
 		if (!algo)
@@ -533,7 +533,7 @@
 		idea_cipher_warn(1);
 		log_info (_("IDEA cipher unavailable, "
 			    "optimistically attempting to use %s instead\n"),
-			  gcry_cipher_algo_name (algo));
+			  openpgp_cipher_algo_name (algo));
 	      }
 	    else
 	      {

Modified: trunk/g10/misc.c
===================================================================
--- trunk/g10/misc.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/misc.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -301,7 +301,7 @@
 	{
 	  warn=1;
 	  log_info (_("WARNING: using experimental cipher algorithm %s\n"),
-                    gcry_cipher_algo_name (algo));
+                    openpgp_cipher_algo_name (algo));
 	}
     }
 }
@@ -324,6 +324,33 @@
               gcry_md_algo_name (algo));
 }
 
+
+/* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
+   this for algorithms we implemented in Libgcrypt after they become
+   part of OpenPGP.  */
+static int
+map_cipher_openpgp_to_gcry (int algo)
+{
+  switch (algo)
+    {
+    case CIPHER_ALGO_CAMELLIA128: return 310; 
+    case CIPHER_ALGO_CAMELLIA256: return 312; 
+    default: return algo;
+    }
+}
+
+/* The inverse fucntion of above.  */
+static int
+map_cipher_gcry_to_openpgp (int algo)
+{
+  switch (algo)
+    {
+    case 310: return CIPHER_ALGO_CAMELLIA128;
+    case 312: return CIPHER_ALGO_CAMELLIA256;
+    default: return algo;
+    }
+}
+
 /****************
  * Wrapper around the libgcrypt function with additonal checks on
  * the OpenPGP contraints for the algo ID.
@@ -331,12 +358,32 @@
 int
 openpgp_cipher_test_algo( int algo )
 {
-  /* 5 and 6 are marked reserved by rfc2440bis.  */
+  /* (5 and 6 are marked reserved by rfc4880.)  */
   if ( algo < 0 || algo > 110 || algo == 5 || algo == 6 )
     return gpg_error (GPG_ERR_CIPHER_ALGO);
-  return gcry_cipher_test_algo (algo);
+
+  /* Camellia is not yet defined for OpenPGP thus only allow it if
+     requested.  */
+#ifndef USE_CAMELLIA
+  if (algo == CIPHER_ALGO_CAMELLIA128 
+       || algo == CIPHER_ALGO_CAMELLIA256)
+    return gpg_error (GPG_ERR_CIPHER_ALGO);
+#endif
+
+  return gcry_cipher_test_algo (map_cipher_openpgp_to_gcry (algo));
 }
 
+/* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
+   string representation of the algorithm name.  For unknown algorithm
+   IDs this function returns "?".  */
+const char *
+openpgp_cipher_algo_name (int algo) 
+{
+  return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
+}
+
+
+
 int
 openpgp_pk_test_algo( int algo )
 {
@@ -690,7 +737,7 @@
 { 
   int val;
 
-  val = gcry_cipher_map_name (string);
+  val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
   if (!val && string && (string[0]=='S' || string[0]=='s'))
     {
       char *endptr;

Modified: trunk/g10/parse-packet.c
===================================================================
--- trunk/g10/parse-packet.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/parse-packet.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1588,8 +1588,10 @@
     ops->keyid[1] = read_32(inp); pktlen -= 4;
     ops->last = iobuf_get_noeof(inp); pktlen--;
     if( list_mode )
-	fprintf (listfp, ":onepass_sig packet: keyid %08lX%08lX\n"
-	       "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
+	fprintf (listfp,
+                 ":onepass_sig packet: keyid %08lX%08lX\n"
+                 "\tversion %d, sigclass 0x%02x, digest %d, pubkey %d, "
+                 "last=%d\n",
 		(ulong)ops->keyid[0], (ulong)ops->keyid[1],
 		version, ops->sig_class,
 		ops->digest_algo, ops->pubkey_algo, ops->last );

Modified: trunk/g10/pubkey-enc.c
===================================================================
--- trunk/g10/pubkey-enc.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/pubkey-enc.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -282,7 +282,7 @@
 		&& !opt.quiet
 		&& !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ))
 	  log_info (_("WARNING: cipher algorithm %s not found in recipient"
-                      " preferences\n"), gcry_cipher_algo_name (dek->algo));
+                      " preferences\n"), openpgp_cipher_algo_name (dek->algo));
         if (!rc) {
             KBNODE k;
             

Modified: trunk/g10/sign.c
===================================================================
--- trunk/g10/sign.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/g10/sign.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -345,22 +345,24 @@
 {
   if (qbytes <= 20)
     return DIGEST_ALGO_SHA1;
-#ifdef USE_SHA256
-  if (qbytes <= 28)
+
+  /* SHA244 is only available with libgcrypt 1.4 - thus do a runtime
+     test.  */
+  if (qbytes <= 28 && !gcry_md_test_algo (DIGEST_ALGO_SHA224))
     return DIGEST_ALGO_SHA224;
+
   if (qbytes <= 32)
     return DIGEST_ALGO_SHA256;
-#endif
 
-#ifdef USE_SHA512
   if (qbytes <= 48)
     return DIGEST_ALGO_SHA384;
+
   if (qbytes <= 64)
     return DIGEST_ALGO_SHA512;
-#endif
+
   return DEFAULT_DIGEST_ALGO;
   /* DEFAULT_DIGEST_ALGO will certainly fail, but it's the best wrong
-     answer we have if the larger SHAs aren't there. */
+     answer we have if a digest larger than 512 bits is requested.  */
 }
 
 
@@ -1258,7 +1260,7 @@
     algo = default_cipher_algo();
     if (!opt.quiet || !opt.batch)
         log_info (_("%s encryption will be used\n"),
-                  gcry_cipher_algo_name (algo) );
+                  openpgp_cipher_algo_name (algo) );
     cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, &canceled);
 
     if (!cfx.dek || !cfx.dek->keylen) {

Modified: trunk/include/ChangeLog
===================================================================
--- trunk/include/ChangeLog	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/include/ChangeLog	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,3 +1,7 @@
+2007-12-12  Werner Koch  <wk at g10code.com>
+
+	* cipher.h (CIPHER_ALGO_CAMELLIA128, CIPHER_ALGO_CAMELLIA256): New.
+
 2006-09-20  Werner Koch  <wk at g10code.com>
 
 	* errors.h, http.h, memory.h, mpi.h, util.h, i18n.h: Removed.

Modified: trunk/include/cipher.h
===================================================================
--- trunk/include/cipher.h	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/include/cipher.h	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,5 +1,6 @@
 /* cipher.h - Definitions for OpenPGP 
- * Copyright (C) 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2006,
+ *               2007  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -44,6 +45,9 @@
 #define CIPHER_ALGO_RIJNDAEL192  CIPHER_ALGO_AES192
 #define CIPHER_ALGO_RIJNDAEL256  CIPHER_ALGO_AES256
 #define CIPHER_ALGO_TWOFISH	 /* 10 */  GCRY_CIPHER_TWOFISH  /* 256 bit */
+/* Note: Camellia ids don't match those used by libgcrypt. */
+#define CIPHER_ALGO_CAMELLIA128     11
+#define CIPHER_ALGO_CAMELLIA256     12
 #define CIPHER_ALGO_DUMMY          110    /* No encryption at all. */
 
 #define PUBKEY_ALGO_RSA          /*  1 */ GCRY_PK_RSA  
@@ -66,8 +70,8 @@
 #define DIGEST_ALGO_SHA256    /*  8 */ GCRY_MD_SHA256
 #define DIGEST_ALGO_SHA384    /*  9 */ GCRY_MD_SHA384
 #define DIGEST_ALGO_SHA512    /* 10 */ GCRY_MD_SHA512
-/* SHA224 is as of now only defined in the libgcrypt SVN; thus we
-   can't use that macro.  */
+/* SHA224 is only available in libgcrypt 1.4.0; thus we
+   can't use the GCRY macro here.  */
 #define DIGEST_ALGO_SHA224    /* 11 */ 11 /* GCRY_MD_SHA224 */
 
 #define COMPRESS_ALGO_NONE 0

Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/scd/ChangeLog	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,6 +1,6 @@
 2007-12-10  Werner Koch  <wk at g10code.com>
 
-	* app-openpgp.c (do_decipher): Take care of cryptograms shiorther
+	* app-openpgp.c (do_decipher): Take care of cryptograms shorter
 	that 128 bytes.  Fixes bug#851.
 
 2007-11-14  Werner Koch  <wk at g10code.com>

Modified: trunk/scd/app-openpgp.c
===================================================================
--- trunk/scd/app-openpgp.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/scd/app-openpgp.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -2461,7 +2461,7 @@
 
       /* We might encounter a couple of leading zeroes in the
          cryptogram.  Due to internal use of MPIs thease leading
-         zeroes are stripped.  However the OpenPGp card expects
+         zeroes are stripped.  However the OpenPGP card expects
          exactly 128 bytes for the cryptogram (for a 1k key).  Thus we
          need to fix it up.  We do this for up to 16 leading zero
          bytes; a cryptogram with more than this is with a very high

Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/ChangeLog	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,3 +1,20 @@
+2007-12-11  Werner Koch  <wk at g10code.com>
+
+	* certchain.c (do_validate_chain): Log AUDIT_ROOT_TRUSTED.
+
+	* server.c (cmd_sign, cmd_decrypt, cmd_encrypt): Start audit log.
+	(cmd_recipient): Start audit session.
+
+	* gpgsm.c (main): Revamp creation of the audit log.
+
+	* gpgsm.h (struct server_control_s): Add AGENT_SEEN and DIRMNGR_SEEN.
+	* call-agent.c (start_agent): Record an audit event.
+	* call-dirmngr.c (start_dirmngr): Ditto. Add new arg CTRL and pass
+	it from all callers.
+	(prepare_dirmngr): New helper for start_dirmngr.
+
+	* encrypt.c (gpgsm_encrypt): Add calls to audit_log.
+
 2007-12-03  Werner Koch  <wk at g10code.com>
 
 	* gpgsm.c (main): All gnupg_reopen_std.

Modified: trunk/sm/call-agent.c
===================================================================
--- trunk/sm/call-agent.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/call-agent.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,5 +1,6 @@
 /* call-agent.c - divert operations to the agent
- *	Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2005,
+ *               2007 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -69,13 +70,14 @@
 static int
 start_agent (ctrl_t ctrl)
 {
+  int rc;
+
   if (agent_ctx)
-    return 0; /* fixme: We need a context for each thread or serialize
-                 the access to the agent (which is suitable given that
-                 the agent is not MT. */
-
-
-  return start_new_gpg_agent (&agent_ctx,
+    rc = 0;      /* fixme: We need a context for each thread or
+                    serialize the access to the agent (which is
+                    suitable given that the agent is not MT. */
+  else
+    rc = start_new_gpg_agent (&agent_ctx,
                               GPG_ERR_SOURCE_DEFAULT,
                               opt.homedir,
                               opt.agent_program,
@@ -84,7 +86,13 @@
                               opt.xauthority, opt.pinentry_user_data,
                               opt.verbose, DBG_ASSUAN,
                               gpgsm_status2, ctrl);
+  if (!ctrl->agent_seen)
+    {
+      ctrl->agent_seen = 1;
+      audit_log_ok (ctrl->audit, AUDIT_AGENT_READY, rc);
+    }
 
+  return rc;
 }
 
 

Modified: trunk/sm/call-dirmngr.c
===================================================================
--- trunk/sm/call-dirmngr.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/call-dirmngr.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,5 +1,5 @@
 /* call-dirmngr.c - communication with the dromngr 
- *	Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+ *	Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -134,13 +134,32 @@
 }
 
 
+/* This fucntion prepares the dirmngr for a new session.  The
+   audit-events option is used so that other dirmngr clients won't get
+   disturbed by such events.  */
+static void
+prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err)
+{
+  if (!ctrl->dirmngr_seen)
+    {
+      ctrl->dirmngr_seen = 1;
+      if (!err)
+        {
+          err = assuan_transact (ctx, "OPTION audit-events=1",
+                                 NULL, NULL, NULL, NULL, NULL, NULL);
+          if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
+            err = 0;  /* Allow the use of old dirmngr versions.  */
+        }
+      audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err);
+    }
+}
 
 
 
 /* Try to connect to the agent via socket or fork it off and work by
    pipes.  Handle the server's initial greeting */
 static int
-start_dirmngr (void)
+start_dirmngr (ctrl_t ctrl)
 {
   int rc;
   char *infostr, *p;
@@ -148,8 +167,11 @@
   int try_default = 0;
 
   if (dirmngr_ctx)
-    return 0; /* fixme: We need a context for each thread or serialize
-                 the access to the dirmngr */
+    {
+      prepare_dirmngr (ctrl, dirmngr_ctx, 0);
+      return 0; /* fixme: We need a context for each thread or serialize
+                   the access to the dirmngr */
+    }
   /* Note: if you change this to multiple connections, you also need
      to take care of the implicit option sending caching. */
 
@@ -220,7 +242,7 @@
               log_error (_("malformed DIRMNGR_INFO environment variable\n"));
               xfree (infostr);
               force_pipe_server = 1;
-              return start_dirmngr ();
+              return start_dirmngr (ctrl);
             }
           *p++ = 0;
           pid = atoi (p);
@@ -233,7 +255,7 @@
                          prot);
               xfree (infostr);
               force_pipe_server = 1;
-              return start_dirmngr ();
+              return start_dirmngr (ctrl);
             }
         }
       else
@@ -251,11 +273,13 @@
         {
           log_error (_("can't connect to the dirmngr - trying fall back\n"));
           force_pipe_server = 1;
-          return start_dirmngr ();
+          return start_dirmngr (ctrl);
         }
 #endif /*!HAVE_W32_SYSTEM*/
     }
 
+  prepare_dirmngr (ctrl, ctx, rc);
+
   if (rc)
     {
       log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc));
@@ -424,7 +448,7 @@
   struct isvalid_status_parm_s stparm;
 
 
-  rc = start_dirmngr ();
+  rc = start_dirmngr (ctrl);
   if (rc)
     return rc;
 
@@ -691,7 +715,7 @@
   struct lookup_parm_s parm;
   size_t len;
 
-  rc = start_dirmngr ();
+  rc = start_dirmngr (ctrl);
   if (rc)
     return rc;
 
@@ -821,7 +845,7 @@
   size_t len;
   struct run_command_parm_s parm;
 
-  rc = start_dirmngr ();
+  rc = start_dirmngr (ctrl);
   if (rc)
     return rc;
 

Modified: trunk/sm/certchain.c
===================================================================
--- trunk/sm/certchain.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/certchain.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1127,6 +1127,8 @@
              associated with that specific root certificate.  */
           istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert,
                                                 rootca_flags);
+          audit_log_cert (ctrl->audit, AUDIT_ROOT_TRUSTED,
+                          subject_cert, istrusted_rc);
           /* If the chain model extended attribute is used, make sure
              that our chain model flag is set. */
           if (has_validation_model_chain (subject_cert, listmode, listfp))

Modified: trunk/sm/encrypt.c
===================================================================
--- trunk/sm/encrypt.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/encrypt.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -1,5 +1,5 @@
 /* encrypt.c - Encrypt a message
- *	Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ *	Copyright (C) 2001, 2003, 2004, 2007 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -318,9 +318,12 @@
   int recpno;
   FILE *data_fp = NULL;
   certlist_t cl;
+  int count;
 
   memset (&encparm, 0, sizeof encparm);
 
+  audit_set_type (ctrl->audit, AUDIT_TYPE_ENCRYPT);
+
   /* Check that the certificate list is not empty and that at least
      one certificate is not flagged as encrypt_to; i.e. is a real
      recipient. */
@@ -331,10 +334,15 @@
     {
       log_error(_("no valid recipients given\n"));
       gpgsm_status (ctrl, STATUS_NO_RECP, "0");
+      audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0);
       rc = gpg_error (GPG_ERR_NO_PUBKEY);
       goto leave;
     }
 
+  for (count = 0, cl = recplist; cl; cl = cl->next)
+    count++;
+  audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, count);
+
   kh = keydb_new (0);
   if (!kh)
     {
@@ -385,6 +393,8 @@
       goto leave;
     }
 
+  audit_log (ctrl->audit, AUDIT_GOT_DATA);
+
   /* We are going to create enveloped data with uninterpreted data as
      inner content */
   err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
@@ -432,6 +442,8 @@
       rc = out_of_core ();
       goto leave;
     }
+  
+  audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
 
   /* Gather certificates of recipients, encrypt the session key for
      each and store them in the CMS object */
@@ -442,6 +454,7 @@
       rc = encrypt_dek (dek, cl->cert, &encval);
       if (rc)
         {
+          audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc);
           log_error ("encryption failed for recipient no. %d: %s\n",
                      recpno, gpg_strerror (rc));
           goto leave;
@@ -450,6 +463,7 @@
       err = ksba_cms_add_recipient (cms, cl->cert);
       if (err)
         {
+          audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
           log_error ("ksba_cms_add_recipient failed: %s\n",
                      gpg_strerror (err));
           rc = err;
@@ -459,6 +473,7 @@
       
       err = ksba_cms_set_enc_val (cms, recpno, encval);
       xfree (encval);
+      audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
       if (err)
         {
           log_error ("ksba_cms_set_enc_val failed: %s\n",
@@ -466,7 +481,7 @@
           rc = err;
           goto leave;
         }
-  }
+    }
 
   /* Main control loop for encryption. */
   recpno = 0;
@@ -496,6 +511,7 @@
       log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
     }
+  audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE);
   log_info ("encrypted data created\n");
 
  leave:

Modified: trunk/sm/gpgsm.c
===================================================================
--- trunk/sm/gpgsm.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/gpgsm.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -848,6 +848,7 @@
   certlist_t signerlist = NULL;
   int do_not_setup_keys = 0;
   int recp_required = 0;
+  estream_t auditfp = NULL;
 
   /*mtrace();*/
 
@@ -1482,6 +1483,26 @@
     keydb_add_resource (sl->d, 0, 0, NULL);
   FREE_STRLIST(nrings);
 
+
+  /* Prepare the audit log feature for certain commands.  */
+  if (auditlog)
+    {
+      switch (cmd)
+        {
+        case aEncr: 
+        case aSign:
+        case aDecrypt:
+        case aVerify:
+          audit_release (ctrl.audit);
+          ctrl.audit = audit_new ();
+          auditfp = open_es_fwrite (auditlog);
+          break;
+        default:
+          break;
+        }
+    }
+
+
   if (!do_not_setup_keys)
     {
       for (sl = locusr; sl ; sl = sl->next)
@@ -1528,6 +1549,7 @@
   
   fname = argc? *argv : NULL;
   
+  /* Dispatch command.  */
   switch (cmd)
     {
     case aGPGConfList: 
@@ -1650,7 +1672,6 @@
     case aVerify:
       {
         FILE *fp = NULL;
-        estream_t auditfp = NULL;
 
         set_binary (stdin);
         if (argc == 2 && opt.outfile)
@@ -1658,13 +1679,6 @@
         else if (opt.outfile)
           fp = open_fwrite (opt.outfile);
 
-        if (auditlog)
-          {
-            audit_release (ctrl.audit);
-            ctrl.audit = audit_new ();
-            auditfp = open_es_fwrite (auditlog);
-          }
-
         if (!argc)
           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
         else if (argc == 1)
@@ -1674,16 +1688,8 @@
         else
           wrong_args ("--verify [signature [detached_data]]");
 
-        if (auditlog)
-          {
-            audit_print_result (ctrl.audit, auditfp, 0);
-            audit_release (ctrl.audit);
-            ctrl.audit = NULL;
-          }
-
         if (fp && fp != stdout)
           fclose (fp);
-        es_fclose (auditfp);
       }
       break;
 
@@ -1846,6 +1852,15 @@
         log_error ("invalid command (there is no implicit command)\n");
 	break;
     }
+
+  /* Print the audit result if needed.  */
+  if (auditlog && auditfp)
+    {
+      audit_print_result (ctrl.audit, auditfp, 0);
+      audit_release (ctrl.audit);
+      ctrl.audit = NULL;
+      es_fclose (auditfp);
+    }
   
   /* cleanup */
   gpgsm_release_certlist (recplist);

Modified: trunk/sm/gpgsm.h
===================================================================
--- trunk/sm/gpgsm.h	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/gpgsm.h	2007-12-12 10:28:30 UTC (rev 4650)
@@ -152,6 +152,10 @@
   struct server_local_s *server_local;
   
   audit_ctx_t audit;  /* NULL or a context for the audit subsystem.  */
+  int agent_seen;     /* Flag indicating that the gpg-agent has been
+                         accessed.  */
+  int dirmngr_seen;   /* Flag indicating that the dirmngr has been
+                         accessed.  */
   
   int with_colons;    /* Use column delimited output format */
   int with_chain;     /* Include the certifying certs in a listing */

Modified: trunk/sm/server.c
===================================================================
--- trunk/sm/server.c	2007-12-11 17:14:05 UTC (rev 4649)
+++ trunk/sm/server.c	2007-12-12 10:28:30 UTC (rev 4650)
@@ -366,7 +366,14 @@
   ctrl_t ctrl = assuan_get_pointer (ctx);
   int rc;
 
-  rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist, 0);
+  if (!ctrl->audit)
+    rc = start_audit_session (ctrl);
+  else
+    rc = 0;
+
+  if (!rc)
+    rc = gpgsm_add_to_certlist (ctrl, line, 0,
+                                &ctrl->server_local->recplist, 0);
   if (rc)
     {
       gpg_err_code_t r = gpg_err_code (rc);
@@ -478,6 +485,8 @@
                                            &ctrl->server_local->recplist, 1);
     }
   if (!rc)
+    rc = ctrl->audit? 0 : start_audit_session (ctrl);
+  if (!rc)
     rc = gpgsm_encrypt (assuan_get_pointer (ctx),
                         ctrl->server_local->recplist,
                         inp_fd, out_fp);
@@ -492,6 +501,7 @@
   return rc;
 }
 
+
 /* DECRYPT
 
   This performs the decrypt operation after doing some check on the
@@ -517,7 +527,10 @@
   out_fp = fdopen (dup(out_fd), "w");
   if (!out_fp)
     return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
-  rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); 
+
+  rc = start_audit_session (ctrl);
+  if (!rc)
+    rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); 
   fclose (out_fp);
 
   /* close and reset the fd */
@@ -600,8 +613,10 @@
   if (!out_fp)
     return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
 
-  rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist,
-                   inp_fd, detached, out_fp);
+  rc = start_audit_session (ctrl);
+  if (!rc)
+    rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist,
+                     inp_fd, detached, out_fp);
   fclose (out_fp);
 
   /* close and reset the fd */




More information about the Gnupg-commits mailing list