Index: gnupg-2.1.3.zzz/sm/call-dirmngr.c =================================================================== --- gnupg-2.1.3.zzz/sm/call-dirmngr.c +++ gnupg-2.1.3.zzz/sm/call-dirmngr.c @@ -368,7 +368,7 @@ ksba_cert_t cert; - err = gpgsm_find_cert (line, ski, &cert); + err = gpgsm_find_cert (line, ski, &cert, 1); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); @@ -893,7 +893,7 @@ if (!*line) return gpg_error (GPG_ERR_ASS_PARAMETER); - err = gpgsm_find_cert (line, NULL, &cert); + err = gpgsm_find_cert (line, NULL, &cert, 1); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); Index: gnupg-2.1.3.zzz/sm/certlist.c =================================================================== --- gnupg-2.1.3.zzz/sm/certlist.c +++ gnupg-2.1.3.zzz/sm/certlist.c @@ -488,7 +488,8 @@ additional filter value which must match the subjectKeyIdentifier. */ int -gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) +gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert, + int allow_ambiguous) { int rc; KEYDB_SEARCH_DESC desc; @@ -536,6 +537,16 @@ 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 (kh, &desc, 1); if (rc == -1) @@ -545,6 +556,10 @@ 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)) { @@ -553,6 +568,29 @@ 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); Index: gnupg-2.1.3.zzz/sm/gpgsm.h =================================================================== --- gnupg-2.1.3.zzz/sm/gpgsm.h +++ gnupg-2.1.3.zzz/sm/gpgsm.h @@ -338,7 +338,8 @@ 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 (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert); +int gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert, + int allow_ambiguous); /*-- keylist.c --*/ gpg_error_t gpgsm_list_keys (ctrl_t ctrl, strlist_t names, Index: gnupg-2.1.3.zzz/sm/gpgsm.c =================================================================== --- gnupg-2.1.3.zzz/sm/gpgsm.c +++ gnupg-2.1.3.zzz/sm/gpgsm.c @@ -1970,7 +1970,7 @@ ksba_cert_t cert = NULL; char *grip = NULL; - rc = gpgsm_find_cert (*argv, NULL, &cert); + rc = gpgsm_find_cert (*argv, NULL, &cert, 0); if (rc) ; else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) Index: gnupg-2.1.3.zzz/sm/server.c =================================================================== --- gnupg-2.1.3.zzz/sm/server.c +++ gnupg-2.1.3.zzz/sm/server.c @@ -1169,7 +1169,7 @@ line = skip_options (line); - err = gpgsm_find_cert (line, NULL, &cert); + err = gpgsm_find_cert (line, NULL, &cert, 0); if (err) ; else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))