[git] GnuPG - branch, STABLE-BRANCH-2-2, updated. gnupg-2.2.1-19-g1067403

by Rainer Perske cvs at cvs.gnupg.org
Tue Oct 24 17:49:56 CEST 2017


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, STABLE-BRANCH-2-2 has been updated
       via  1067403c8a7fb51decf30059e46901b5ee9f5b37 (commit)
      from  6e808ae4700dc5e95bf4cc2d5c063df582c234d0 (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 1067403c8a7fb51decf30059e46901b5ee9f5b37
Author: Rainer Perske <rainer.perske at uni-muenster.de>
Date:   Tue Oct 24 17:29:04 2017 +0200

    sm: Do not expect X.509 keyids to be unique
    
    * sm/certlist.c (gpgsm_find_cert): Add arg allow_ambiguous and use it.
    * sm/call-dirmngr.c (inq_certificate): Pass true to ALLOW_AMBIGUOUS
    (run_command_inq_cb): Ditto.
    * sm/gpgsm.c (main): Pass false.
    * sm/server.c (cmd_passwd): Pass false.
    
    --
    
    As described in my report T1644, it is possible that multiple
    certificates exist with the same Distinguished Name and the same key.
    In this case, verifying S/MIME signatures and other actions fail with
    "certificate not found: Ambiguous name". For details see the bug
    report.
    
    To circumvent the problem, I am patching GnuPG since 2014 so that in
    this case the newest of the ambiguous certificates is used.
    
    This is not an ultimate solution of the problem: You should try every
    certificate with the same DN until verification succeeds or until all
    certificates fail, and if multiple certificates of a chain are
    ambiguous you even have to check every combination. You may even
    consider checking the keyUsage attributes of the ambiguous certificates
    to reduce the number of combinations.
    
    But in the existing case of the certificates in the German Research
    Network (DFN) PKI where the newest one is the valid one and all
    ambiguous certificates have the same keyUsage attributes, this patch
    has proven to be sufficient over the last three years.
    
    With every GnuPG update, I have adapted the patch, luckily I never
    needed to change anything except line numbers.
    
    GnuPG-bug-id: 1644
    
    ChangeLog log written by wk, comment taken from mail.  Signed-off line
    was missing in the plain diff.  However the mail with the patch and
    the DCO posted as reply to that mail were both signed.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index 9301940..e943118 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -415,7 +415,7 @@ inq_certificate (void *opaque, const char *line)
       ksba_cert_t cert;
 
 
-      err = gpgsm_find_cert (parm->ctrl, line, ski, &cert);
+      err = gpgsm_find_cert (parm->ctrl, line, ski, &cert, 1);
       if (err)
         {
           log_error ("certificate not found: %s\n", gpg_strerror (err));
@@ -936,7 +936,7 @@ run_command_inq_cb (void *opaque, const char *line)
       if (!*line)
         return gpg_error (GPG_ERR_ASS_PARAMETER);
 
-      err = gpgsm_find_cert (parm->ctrl, line, NULL, &cert);
+      err = gpgsm_find_cert (parm->ctrl, line, NULL, &cert, 1);
       if (err)
         {
           log_error ("certificate not found: %s\n", gpg_strerror (err));
diff --git a/sm/certlist.c b/sm/certlist.c
index 39ab03c..c9e275e 100644
--- a/sm/certlist.c
+++ b/sm/certlist.c
@@ -489,7 +489,8 @@ gpgsm_release_certlist (certlist_t list)
    subjectKeyIdentifier. */
 int
 gpgsm_find_cert (ctrl_t ctrl,
-                 const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert)
+                 const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert,
+                 int allow_ambiguous)
 {
   int rc;
   KEYDB_SEARCH_DESC desc;
@@ -537,6 +538,16 @@ gpgsm_find_cert (ctrl_t ctrl,
              won't lead to ambiguous names. */
           if (!rc && !keyid)
             {
+              ksba_isotime_t notbefore = "";
+              const unsigned char *image = NULL;
+              size_t length = 0;
+              if (allow_ambiguous)
+                {
+                  /* We want to return the newest certificate */
+                  if (ksba_cert_get_validity (*r_cert, 0, notbefore))
+                    *notbefore = '\0';
+                  image = ksba_cert_get_image (*r_cert, &length);
+                }
             next_ambiguous:
               rc = keydb_search (ctrl, kh, &desc, 1);
               if (rc == -1)
@@ -546,6 +557,10 @@ gpgsm_find_cert (ctrl_t ctrl,
                   if (!rc)
                     {
                       ksba_cert_t cert2 = NULL;
+                      ksba_isotime_t notbefore2 = "";
+                      const unsigned char *image2 = NULL;
+                      size_t length2 = 0;
+                      int cmp = 0;
 
                       if (!keydb_get_cert (kh, &cert2))
                         {
@@ -554,6 +569,29 @@ gpgsm_find_cert (ctrl_t ctrl,
                               ksba_cert_release (cert2);
                               goto next_ambiguous;
                             }
+                          if (allow_ambiguous)
+                            {
+                              if (ksba_cert_get_validity (cert2, 0, notbefore2))
+                                *notbefore2 = '\0';
+                              image2 = ksba_cert_get_image (cert2, &length2);
+                              cmp = strcmp (notbefore, notbefore2);
+                              /* use certificate image bits as last resort for stable ordering */
+                              if (!cmp)
+                                cmp = memcmp (image, image2, length < length2 ? length : length2);
+                              if (!cmp)
+                                cmp = length < length2 ? -1 : length > length2 ? 1 : 0;
+                              if (cmp < 0)
+                                {
+                                  ksba_cert_release (*r_cert);
+                                  *r_cert = cert2;
+                                  strcpy (notbefore, notbefore2);
+                                  image = image2;
+                                  length = length2;
+                                }
+                              else
+                                ksba_cert_release (cert2);
+                              goto next_ambiguous;
+                            }
                           ksba_cert_release (cert2);
                         }
                       rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 10eff0a..0feda90 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -2052,7 +2052,7 @@ main ( int argc, char **argv)
           ksba_cert_t cert = NULL;
           char *grip = NULL;
 
-          rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert);
+          rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert, 0);
           if (rc)
             ;
           else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 8c1f520..cd4fc99 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -328,7 +328,7 @@ int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
                            certlist_t *listaddr, int is_encrypt_to);
 void gpgsm_release_certlist (certlist_t list);
 int gpgsm_find_cert (ctrl_t ctrl, const char *name, ksba_sexp_t keyid,
-                     ksba_cert_t *r_cert);
+                     ksba_cert_t *r_cert, int allow_ambiguous);
 
 /*-- keylist.c --*/
 gpg_error_t gpgsm_list_keys (ctrl_t ctrl, strlist_t names,
diff --git a/sm/server.c b/sm/server.c
index 64a3add..568e51b 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -1179,7 +1179,7 @@ cmd_passwd (assuan_context_t ctx, char *line)
 
   line = skip_options (line);
 
-  err = gpgsm_find_cert (ctrl, line, NULL, &cert);
+  err = gpgsm_find_cert (ctrl, line, NULL, &cert, 0);
   if (err)
     ;
   else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))

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

Summary of changes:
 sm/call-dirmngr.c |  4 ++--
 sm/certlist.c     | 40 +++++++++++++++++++++++++++++++++++++++-
 sm/gpgsm.c        |  2 +-
 sm/gpgsm.h        |  2 +-
 sm/server.c       |  2 +-
 5 files changed, 44 insertions(+), 6 deletions(-)


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




More information about the Gnupg-commits mailing list