[git] GnuPG - branch, master, updated. gnupg-2.1.0beta3-428-g715285b

by Werner Koch cvs at cvs.gnupg.org
Mon Jun 2 16:22:26 CEST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  715285bcbc12c024dbd9b633805189c09173e317 (commit)
       via  42c043a8ad542c131917879c9b458f234b4bb645 (commit)
      from  99972bd6e9abea71f270284f49997de5f00208af (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 715285bcbc12c024dbd9b633805189c09173e317
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jun 2 16:02:30 2014 +0200

    gpgsm: Handle re-issued CA certificates in a better way.
    
    * sm/certchain.c (find_up_search_by_keyid): Consider all matching
    certificates.
    (find_up): Add some debug messages.
    --
    
    The DFN-Verein recently re-issued its CA certificates without
    generating new keys.  Thus looking up the chain using the authority
    keyids works but may use still existing old certificates.  This may
    break the CRL lookup in the Dirmngr.  The hack to fix this is by using
    the latest issued certificate with the same subject key identifier.
    
    As usual Peter Gutman's X.509 style guide has some comments on that
    re-issuing.
    
    GnuPG-bug-id: 1644

diff --git a/sm/certchain.c b/sm/certchain.c
index b51291d..5f5fd80 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -444,6 +444,8 @@ find_up_search_by_keyid (KEYDB_HANDLE kh,
   int rc;
   ksba_cert_t cert = NULL;
   ksba_sexp_t subj = NULL;
+  int anyfound = 0;
+  ksba_isotime_t not_before, last_not_before;
 
   keydb_search_reset (kh);
   while (!(rc = keydb_search_subject (kh, issuer)))
@@ -460,10 +462,37 @@ find_up_search_by_keyid (KEYDB_HANDLE kh,
       if (!ksba_cert_get_subj_key_id (cert, NULL, &subj))
         {
           if (!cmp_simple_canon_sexp (keyid, subj))
-            break; /* Found matching cert. */
+            {
+              /* Found matching cert. */
+              rc = ksba_cert_get_validity (cert, 0, not_before);
+              if (rc)
+                {
+                  log_error ("keydb_get_validity() failed: rc=%d\n", rc);
+                  rc = -1;
+                  break;
+                }
+
+              if (!anyfound || strcmp (last_not_before, not_before) < 0)
+                {
+                  /* This certificate is the first one found or newer
+                     than the previous one.  This copes with
+                     re-issuing CA certificates while keeping the same
+                     key information.  */
+                  anyfound = 1;
+                  gnupg_copy_time (last_not_before, not_before);
+                  keydb_push_found_state (kh);
+                }
+            }
         }
     }
 
+  if (anyfound)
+    {
+      /* Take the last saved one.  */
+      keydb_pop_found_state (kh);
+      rc = 0;  /* Ignore EOF or other error after the first cert.  */
+    }
+
   ksba_cert_release (cert);
   xfree (subj);
   return rc? -1:0;
@@ -606,6 +635,8 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
   ksba_sexp_t keyid;
   int rc = -1;
 
+  if (DBG_X509)
+    log_debug ("looking for parent certificate\n");
   if (!ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno))
     {
       const char *s = ksba_name_enum (authid, 0);
@@ -615,6 +646,9 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
           if (rc)
             keydb_search_reset (kh);
 
+          if (!rc && DBG_X509)
+            log_debug ("  found via authid and sn+issuer\n");
+
           /* In case of an error, try to get the certificate from the
              dirmngr.  That is done by trying to put that certifcate
              into the ephemeral DB and let the code below do the
@@ -634,6 +668,9 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
                   rc = keydb_search_issuer_sn (kh, s, authidno);
                   if (rc)
                     keydb_search_reset (kh);
+
+                  if (!rc && DBG_X509)
+                    log_debug ("  found via authid and sn+issuer (ephem)\n");
                 }
               keydb_set_ephemeral (kh, old);
             }
@@ -649,11 +686,15 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
              subjectKeyIdentifier. */
           /* Fixme: Should we also search in the dirmngr?  */
           rc = find_up_search_by_keyid (kh, issuer, keyid);
+          if (!rc && DBG_X509)
+            log_debug ("  found via authid and keyid\n");
           if (rc)
             {
               int old = keydb_set_ephemeral (kh, 1);
               if (!old)
                 rc = find_up_search_by_keyid (kh, issuer, keyid);
+              if (!rc && DBG_X509)
+                log_debug ("  found via authid and keyid (ephem)\n");
               keydb_set_ephemeral (kh, old);
             }
           if (rc)
@@ -678,11 +719,19 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
             }
           if (rc)
             rc = -1; /* Need to make sure to have this error code. */
+
+          if (!rc && DBG_X509)
+            log_debug ("  found via authid and issuer from dirmngr cache\n");
         }
 
       /* If we still didn't found it, try an external lookup.  */
       if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
-        rc = find_up_external (ctrl, kh, issuer, keyid);
+        {
+          rc = find_up_external (ctrl, kh, issuer, keyid);
+          if (!rc && DBG_X509)
+            log_debug ("  found via authid and external lookup\n");
+        }
+
 
       /* Print a note so that the user does not feel too helpless when
          an issuer certificate was found and gpgsm prints BAD
@@ -733,11 +782,18 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
           rc = keydb_search_subject (kh, issuer);
         }
       keydb_set_ephemeral (kh, old);
+
+      if (!rc && DBG_X509)
+        log_debug ("  found via issuer\n");
     }
 
   /* Still not found.  If enabled, try an external lookup.  */
   if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
-    rc = find_up_external (ctrl, kh, issuer, NULL);
+    {
+      rc = find_up_external (ctrl, kh, issuer, NULL);
+      if (!rc && DBG_X509)
+        log_debug ("  found via issuer and external lookup\n");
+    }
 
   return rc;
 }

commit 42c043a8ad542c131917879c9b458f234b4bb645
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jun 2 15:55:00 2014 +0200

    gpgsm: Add a way to save a found state.
    
    * kbx/keybox-defs.h (keybox_found_s): New.
    (keybox_handle): Factor FOUND out to above.  Add saved_found.
    * kbx/keybox-init.c (keybox_release): Release saved_found.
    (keybox_push_found_state, keybox_pop_found_state): New.
    
    * sm/keydb.c (keydb_handle): Add field saved_found.
    (keydb_new): Init it.
    (keydb_push_found_state, keydb_pop_found_state): New.

diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h
index f79c093..7bbcf83 100644
--- a/kbx/keybox-defs.h
+++ b/kbx/keybox-defs.h
@@ -85,6 +85,14 @@ struct keybox_name
 };
 
 
+struct keybox_found_s
+{
+  KEYBOXBLOB blob;
+  off_t offset;
+  size_t pk_no;
+  size_t uid_no;
+  unsigned int n_packets; /*used for delete and update*/
+};
 
 struct keybox_handle {
   CONST_KB_NAME kb;
@@ -93,13 +101,8 @@ struct keybox_handle {
   int eof;
   int error;
   int ephemeral;
-  struct {
-    KEYBOXBLOB blob;
-    off_t offset;
-    size_t pk_no;
-    size_t uid_no;
-    unsigned int n_packets; /*used for delete and update*/
-  } found;
+  struct keybox_found_s found;
+  struct keybox_found_s saved_found;
   struct {
     char *name;
     char *pattern;
diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c
index d329941..8ae3ec3 100644
--- a/kbx/keybox-init.c
+++ b/kbx/keybox-init.c
@@ -148,6 +148,7 @@ keybox_release (KEYBOX_HANDLE hd)
           hd->kb->handle_table[idx] = NULL;
     }
   _keybox_release_blob (hd->found.blob);
+  _keybox_release_blob (hd->saved_found.blob);
   if (hd->fp)
     {
       fclose (hd->fp);
@@ -159,6 +160,35 @@ keybox_release (KEYBOX_HANDLE hd)
 }
 
 
+/* Save the current found state in HD for later retrieval by
+   keybox_restore_found_state.  Only one state may be saved.  */
+void
+keybox_push_found_state (KEYBOX_HANDLE hd)
+{
+  if (hd->saved_found.blob)
+    {
+      _keybox_release_blob (hd->saved_found.blob);
+      hd->saved_found.blob = NULL;
+    }
+  hd->saved_found = hd->found;
+  hd->found.blob = NULL;
+}
+
+
+/* Restore the saved found state in HD.  */
+void
+keybox_pop_found_state (KEYBOX_HANDLE hd)
+{
+  if (hd->found.blob)
+    {
+      _keybox_release_blob (hd->found.blob);
+      hd->found.blob = NULL;
+    }
+  hd->found = hd->saved_found;
+  hd->saved_found.blob = NULL;
+}
+
+
 const char *
 keybox_get_resource_name (KEYBOX_HANDLE hd)
 {
diff --git a/kbx/keybox.h b/kbx/keybox.h
index 4c447a5..96c6db5 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -64,6 +64,8 @@ int keybox_is_writable (void *token);
 
 KEYBOX_HANDLE keybox_new (void *token, int secret);
 void keybox_release (KEYBOX_HANDLE hd);
+void keybox_push_found_state (KEYBOX_HANDLE hd);
+void keybox_pop_found_state (KEYBOX_HANDLE hd);
 const char *keybox_get_resource_name (KEYBOX_HANDLE hd);
 int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes);
 
diff --git a/sm/keydb.c b/sm/keydb.c
index 845ebba..d9eb2e0 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -56,6 +56,7 @@ static int used_resources;
 struct keydb_handle {
   int locked;
   int found;
+  int saved_found;
   int current;
   int is_ephemeral;
   int used; /* items in active */
@@ -265,6 +266,7 @@ keydb_new (int secret)
 
   hd = xcalloc (1, sizeof *hd);
   hd->found = -1;
+  hd->saved_found = -1;
 
   assert (used_resources <= MAX_KEYDB_RESOURCES);
   for (i=j=0; i < used_resources; i++)
@@ -476,6 +478,58 @@ unlock_all (KEYDB_HANDLE hd)
   hd->locked = 0;
 }
 
+
+

+/* Push the last found state if any.  */
+void
+keydb_push_found_state (KEYDB_HANDLE hd)
+{
+  if (!hd)
+    return;
+
+  if (hd->found < 0 || hd->found >= hd->used)
+    {
+      hd->saved_found = -1;
+      return;
+    }
+
+  switch (hd->active[hd->found].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      keybox_push_found_state (hd->active[hd->found].u.kr);
+      break;
+    }
+
+  hd->saved_found = hd->found;
+  hd->found = -1;
+}
+
+
+/* Pop the last found state.  */
+void
+keydb_pop_found_state (KEYDB_HANDLE hd)
+{
+  if (!hd)
+    return;
+
+  hd->found = hd->saved_found;
+  hd->saved_found = -1;
+  if (hd->found < 0 || hd->found >= hd->used)
+    return;
+
+  switch (hd->active[hd->found].type)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      break;
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      keybox_pop_found_state (hd->active[hd->found].u.kr);
+      break;
+    }
+}
+
+
 

 /*
   Return the last found object.  Caller must free it.  The returned
diff --git a/sm/keydb.h b/sm/keydb.h
index 6e432f8..aec31c3 100644
--- a/sm/keydb.h
+++ b/sm/keydb.h
@@ -43,6 +43,8 @@ gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx,
                              unsigned int *value);
 gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx,
                              unsigned int value);
+void keydb_push_found_state (KEYDB_HANDLE hd);
+void keydb_pop_found_state (KEYDB_HANDLE hd);
 int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert);
 int keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert);
 int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert);

-----------------------------------------------------------------------

Summary of changes:
 kbx/keybox-defs.h |   17 +++++++++------
 kbx/keybox-init.c |   30 ++++++++++++++++++++++++++
 kbx/keybox.h      |    2 ++
 sm/certchain.c    |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 sm/keydb.c        |   54 ++++++++++++++++++++++++++++++++++++++++++++++
 sm/keydb.h        |    2 ++
 6 files changed, 157 insertions(+), 10 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list