From eff62d82bfcb9df1b85ce596f0f5b6ef00d3a0ca Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Apr 2005 10:44:46 +0000 Subject: [PATCH] * configure.ac: Require libksba 0.9.11. sm/ * call-dirmngr.c (inq_certificate): Add new inquire SENDCERT_SKI. * certlist.c (gpgsm_find_cert): Add new arg KEYID and implement this filter. Changed all callers. * certchain.c (find_up_search_by_keyid): New helper. (find_up): Also try using the AKI.keyIdentifier. (find_up_external): Ditto. --- ChangeLog | 4 ++ NEWS | 9 +++- README | 8 ++-- TODO | 4 ++ agent/command-ssh.c | 1 + common/ChangeLog | 5 ++ common/sexputil.c | 78 ++++++++++++++++++++++++++++++ common/util.h | 3 ++ configure.ac | 2 +- sm/ChangeLog | 15 ++++++ sm/call-dirmngr.c | 21 ++++++-- sm/certchain.c | 113 ++++++++++++++++++++++++++++++++++++-------- sm/certdump.c | 1 + sm/certlist.c | 40 ++++++++++++++-- sm/gpgsm.c | 2 +- sm/gpgsm.h | 2 +- sm/keylist.c | 35 ++++++++++++-- 17 files changed, 302 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c3c700c5..013241648 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-04-15 Werner Koch + + * configure.ac: Require libksba 0.9.11. + 2005-04-15 Marcus Brinkmann * configure.ac: Check for /usr/bin/shred and define SHRED. diff --git a/NEWS b/NEWS index 101e04b98..d2334d9cd 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,13 @@ Noteworthy changes in version 1.9.16 ------------------------------------------------- + * gpg-agent does now support the ssh-agent protocol and thus allows + to use the pinentry as well as the OpenPGP smartcard with ssh. + + * New tool gpg-connect-agent as a genereal client for the gpg-agent. + + * New tool symcryptrun as a wrapper for certain encryption tools. + Noteworthy changes in version 1.9.15 (2005-01-13) ------------------------------------------------- @@ -226,7 +233,7 @@ Noteworthy changes in version 1.9.0 (2003-08-05) development branch. - Copyright 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without diff --git a/README b/README index c14534e93..7e44765a6 100644 --- a/README +++ b/README @@ -399,7 +399,7 @@ modes for gpgsm, here is the entire list of ways to specify a key: +Heinrich Heine duesseldorf - * [NEW] Exact match by subject's DN + * Exact match by subject's DN This is indicated by a leading slash, directly followed by the rfc2253 encoded DN of the subject. Note that you can't use the @@ -411,7 +411,7 @@ modes for gpgsm, here is the entire list of ways to specify a key: /CN=Heinrich Heine,O=Poets,L=Paris,C=FR - * [NEW] Excact match by issuer's DN + * Excact match by issuer's DN This is indicated by a leading hash mark, directly followed by a slash and then directly followed by the rfc2253 encoded DN of the @@ -422,10 +422,10 @@ modes for gpgsm, here is the entire list of ways to specify a key: #/CN=Root Cert,O=Poets,L=Paris,C=FR - * [NEW] Exact match by serial number and subject's DN + * Exact match by serial number and issuer's DN This is indicated by a hash mark, followed by the hexadecmal - representation of the serial number, the followed by a slahs and + representation of the serial number, the followed by a slash and the RFC2253 encoded DN of the issuer. See note above. Example: diff --git a/TODO b/TODO index 9efbe6a1c..26b2cee60 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,9 @@ -*- outline -*- +* IMPORTANT +Check that openpty and pty.h are available and build symcryptrun only +then. Run shred on the temporary files. + * src/base64 ** Make parsing more robust diff --git a/agent/command-ssh.c b/agent/command-ssh.c index f9ad2a80e..00c202078 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -1741,6 +1741,7 @@ ssh_handler_request_identities (ctrl_t ctrl, /* Prepare buffer stream. */ +#warning Huh, sleep? why that? Anyway, this should be pth_sleep sleep (5); key_directory = NULL; diff --git a/common/ChangeLog b/common/ChangeLog index a42b07b4d..4688d2765 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2005-04-17 Werner Koch + + * sexputil.c (cmp_simple_canon_sexp): New. + (make_simple_sexp_from_hexstr): New. + 2005-04-07 Werner Koch * sexputil.c: New. diff --git a/common/sexputil.c b/common/sexputil.c index 853d7e58a..802916b44 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -61,3 +61,81 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, return err; } + +/* Compare two simple S-expressions like "(3:foo)". Returns 0 if they + are identical or !0 if they are not. Not that this function can't + be used for sorting. */ +int +cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b) +{ + unsigned long n1, n2; + char *endp; + + if (!a && !b) + return 0; /* Both are NULL, they are identical. */ + if (!a || !b) + return 1; /* One is NULL, they are not identical. */ + if (*a != '(' || *b != '(') + log_bug ("invalid S-exp in cmp_simple_canon_sexp\n"); + + a++; + n1 = strtoul (a, &endp, 10); + a = endp; + b++; + n2 = strtoul (b, &endp, 10); + b = endp; + + if (*a != ':' || *b != ':' ) + log_bug ("invalid S-exp in cmp_simple_canon_sexp\n"); + if (n1 != n2) + return 1; /* Not the same. */ + + for (a++, b++; n1; n1--, a++, b++) + if (*a != *b) + return 1; /* Not the same. */ + return 0; +} + + +/* Create a simple S-expression from the hex string at LIBNE. Returns + a newly allocated buffer with that canonical encoded S-expression + or NULL in case of an error. On return the number of characters + scanned in LINE will be stored at NSCANNED. This fucntions stops + converting at the first character not representing a hexdigit. Odd + numbers of hex digits are allowed; a leading zero is then + assumed. If no characters have been found, NULL is returned.*/ +unsigned char * +make_simple_sexp_from_hexstr (const char *line, size_t *nscanned) +{ + size_t n, len; + const char *s; + unsigned char *buf; + unsigned char *p; + char numbuf[50]; + + for (n=0, s=line; hexdigitp (s); s++, n++) + ; + if (nscanned) + *nscanned = n; + if (!n) + return NULL; + len = ((n+1) & ~0x01)/2; + sprintf (numbuf, "(%u:", (unsigned int)len); + buf = xtrymalloc (strlen (numbuf) + len + 1 + 1); + if (!buf) + return NULL; + p = stpcpy (buf, numbuf); + s = line; + if ((n&1)) + { + *p++ = xtoi_1 (s); + s++; + n--; + } + for (; n > 1; n -=2, s += 2) + *p++ = xtoi_2 (s); + *p++ = ')'; + *p = 0; /* (Not really neaded.) */ + + return buf; +} diff --git a/common/util.h b/common/util.h index 14180bec4..6a9b54ef5 100644 --- a/common/util.h +++ b/common/util.h @@ -123,6 +123,9 @@ gpg_error_t b64enc_finish (struct b64state *state); /*-- sexputil.c */ gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, unsigned char *grip); +int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b); +unsigned char *make_simple_sexp_from_hexstr (const char *line, + size_t *nscanned); /*-- homedir. c --*/ const char *default_homedir (void); diff --git a/configure.ac b/configure.ac index d331566be..d0ffa8ca4 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ NEED_LIBGCRYPT_VERSION=1.1.94 NEED_LIBASSUAN_VERSION=0.6.9 -NEED_KSBA_VERSION=0.9.7 +NEED_KSBA_VERSION=0.9.11 NEED_OPENSC_VERSION=0.8.0 diff --git a/sm/ChangeLog b/sm/ChangeLog index e74381bd5..7b67407ad 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,18 @@ +2005-04-17 Werner Koch + + * call-dirmngr.c (inq_certificate): Add new inquire SENDCERT_SKI. + * certlist.c (gpgsm_find_cert): Add new arg KEYID and implement + this filter. Changed all callers. + + * certchain.c (find_up_search_by_keyid): New helper. + (find_up): Also try using the AKI.keyIdentifier. + (find_up_external): Ditto. + +2005-04-15 Werner Koch + + * keylist.c (list_cert_raw): Print the subjectKeyIdentifier as + well as the keyIdentifier part of the authorityKeyIdentifier. + 2005-03-31 Werner Koch * call-dirmngr.c (start_dirmngr): Use PATHSEP_C instead of ':'. diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 5988ea952..847e78490 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -1,5 +1,5 @@ /* call-dirmngr.c - communication with the dromngr - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -266,11 +266,25 @@ inq_certificate (void *opaque, const char *line) const unsigned char *der; size_t derlen; int issuer_mode = 0; + ksba_sexp_t ski = NULL; if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8])) { line += 8; } + else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12])) + { + size_t n; + + /* Send a certificate where a sourceKeyidentifier is included. */ + line += 12; + while (*line == ' ') + line++; + ski = make_simple_sexp_from_hexstr (line, &n); + line += n; + while (*line == ' ') + line++; + } else if (!strncmp (line, "SENDISSUERCERT", 14) && (line[14] == ' ' || !line[14])) { @@ -304,7 +318,7 @@ inq_certificate (void *opaque, const char *line) ksba_cert_t cert; - err = gpgsm_find_cert (line, &cert); + err = gpgsm_find_cert (line, ski, &cert); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); @@ -321,6 +335,7 @@ inq_certificate (void *opaque, const char *line) } } + xfree (ski); return rc; } @@ -717,7 +732,7 @@ run_command_inq_cb (void *opaque, const char *line) if (!*line) return ASSUAN_Inquire_Error; - err = gpgsm_find_cert (line, &cert); + err = gpgsm_find_cert (line, NULL, &cert); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); diff --git a/sm/certchain.c b/sm/certchain.c index 514ee23a5..a5fdbc622 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -266,6 +266,42 @@ check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist) } +/* Helper fucntion for find_up. This resets the key handle and search + for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns + 0 obn success or -1 when not found. */ +static int +find_up_search_by_keyid (KEYDB_HANDLE kh, + const char *issuer, ksba_sexp_t keyid) +{ + int rc; + ksba_cert_t cert = NULL; + ksba_sexp_t subj = NULL; + + keydb_search_reset (kh); + while (!(rc = keydb_search_subject (kh, issuer))) + { + ksba_cert_release (cert); cert = NULL; + rc = keydb_get_cert (kh, &cert); + if (rc) + { + log_error ("keydb_get_cert() failed: rc=%d\n", rc); + rc = -1; + break; + } + xfree (subj); + if (!ksba_cert_get_subj_key_id (cert, NULL, &subj)) + { + if (!cmp_simple_canon_sexp (keyid, subj)) + break; /* Found matching cert. */ + } + } + + ksba_cert_release (cert); + xfree (subj); + return rc? -1:0; +} + + static void find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) { @@ -275,13 +311,13 @@ find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) } - /* Helper for find_up(). Locate the certificate for ISSUER using an external lookup. KH is the keydb context we are currently using. On success 0 is returned and the certificate may be retrieved from - the keydb using keydb_get_cert().*/ + the keydb using keydb_get_cert(). KEYID is the keyIdentifier from + the AKI or NULL. */ static int -find_up_external (KEYDB_HANDLE kh, const char *issuer) +find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) { int rc; strlist_t names = NULL; @@ -324,8 +360,13 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer) /* The issuers are currently stored in the ephemeral key DB, so we temporary switch to ephemeral mode. */ old = keydb_set_ephemeral (kh, 1); - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); + if (keyid) + rc = find_up_search_by_keyid (kh, issuer, keyid); + else + { + keydb_search_reset (kh); + rc = keydb_search_subject (kh, issuer); + } keydb_set_ephemeral (kh, old); } return rc; @@ -343,9 +384,10 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) { ksba_name_t authid; ksba_sexp_t authidno; + ksba_sexp_t keyid; int rc = -1; - if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno)) + if (!ksba_cert_get_auth_key_id (cert, &keyid, &authid, &authidno)) { const char *s = ksba_name_enum (authid, 0); if (s && *authidno) @@ -369,28 +411,57 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) keydb_set_ephemeral (kh, old); } - /* If we didn't found it, try an external lookup. */ - if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - rc = find_up_external (kh, issuer); } + if (rc == -1 && keyid && !find_next) + { + /* Not found by AIK.issuer_sn. Lets try the AIY.ki + instead. Loop over all certificates with that issuer as + subject and stop for the one with a matching + subjectKeyIdentifier. */ + rc = find_up_search_by_keyid (kh, issuer, keyid); + if (rc) + { + int old = keydb_set_ephemeral (kh, 1); + if (!old) + rc = find_up_search_by_keyid (kh, issuer, keyid); + keydb_set_ephemeral (kh, old); + } + if (rc) + rc = -1; /* Need to make sure to have this error code. */ + } + + /* 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 (kh, issuer, keyid); + /* Print a note so that the user does not feel too helpless when an issuer certificate was found and gpgsm prints BAD signature because it is not the correct one. */ if (rc == -1) { - log_info ("%sissuer certificate (#", find_next?"next ":""); - gpgsm_dump_serial (authidno); - log_printf ("/"); - gpgsm_dump_string (s); - log_printf (") not found using authorityKeyIdentifier\n"); + log_info ("%sissuer certificate ", find_next?"next ":""); + if (keyid) + { + log_printf ("{"); + gpgsm_dump_serial (keyid); + log_printf ("} "); + } + if (authidno) + { + log_printf ("(#"); + gpgsm_dump_serial (authidno); + log_printf ("/"); + gpgsm_dump_string (s); + log_printf (") "); + } + log_printf ("not found using authorityKeyIdentifier\n"); } else if (rc) log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc); + xfree (keyid); ksba_name_release (authid); xfree (authidno); - /* Fixme: There is no way to do an external lookup with - serial+issuer. */ } if (rc) /* Not found via authorithyKeyIdentifier, try regular issuer name. */ @@ -409,7 +480,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) /* Still not found. If enabled, try an external lookup. */ if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - rc = find_up_external (kh, issuer); + rc = find_up_external (kh, issuer, NULL); return rc; } @@ -468,7 +539,7 @@ gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next) rc = keydb_get_cert (kh, r_next); if (rc) { - log_error ("failed to get cert: rc=%d\n", rc); + log_error ("keydb_get_cert() failed: rc=%d\n", rc); rc = gpg_error (GPG_ERR_GENERAL); } @@ -791,7 +862,7 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, rc = keydb_get_cert (kh, &issuer_cert); if (rc) { - log_error ("failed to get cert: rc=%d\n", rc); + log_error ("keydb_get_cert() failed: rc=%d\n", rc); rc = gpg_error (GPG_ERR_GENERAL); goto leave; } @@ -818,6 +889,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, might have been used. This is required because some CAs are reusing the issuer and subject DN for new root certificates. */ + /* FIXME: Do this only if we don't have an + AKI.keyIdentifier */ rc = find_up (kh, subject_cert, issuer, 1); if (!rc) { @@ -1008,7 +1081,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert) rc = keydb_get_cert (kh, &issuer_cert); if (rc) { - log_error ("failed to get cert: rc=%d\n", rc); + log_error ("keydb_get_cert() failed: rc=%d\n", rc); rc = gpg_error (GPG_ERR_GENERAL); goto leave; } diff --git a/sm/certdump.c b/sm/certdump.c index cdf4edcc1..26510c70d 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -75,6 +75,7 @@ gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) } +/* Dump the serial number or any other simple S-expression. */ void gpgsm_dump_serial (ksba_const_sexp_t p) { diff --git a/sm/certlist.c b/sm/certlist.c index 018ad47ff..b036a85d7 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -1,5 +1,5 @@ /* certlist.c - build list of certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -412,9 +412,11 @@ gpgsm_release_certlist (CERTLIST list) /* Like gpgsm_add_to_certlist, but look only for one certificate. No - chain validation is done */ + chain validation is done. If KEYID is not NULL it is take as an + additional filter value which must match the + subjectKeyIdentifier. */ int -gpgsm_find_cert (const char *name, ksba_cert_t *r_cert) +gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) { int rc; KEYDB_SEARCH_DESC desc; @@ -429,10 +431,38 @@ gpgsm_find_cert (const char *name, ksba_cert_t *r_cert) rc = gpg_error (GPG_ERR_ENOMEM); else { + nextone: rc = keydb_search (kh, &desc, 1); if (!rc) - rc = keydb_get_cert (kh, r_cert); - if (!rc) + { + rc = keydb_get_cert (kh, r_cert); + if (!rc && keyid) + { + ksba_sexp_t subj; + + rc = ksba_cert_get_subj_key_id (*r_cert, NULL, &subj); + if (!rc) + { + if (cmp_simple_canon_sexp (keyid, subj)) + { + xfree (subj); + goto nextone; + } + xfree (subj); + /* Okay: Here we know that the certificate's + subjectKeyIdentifier matches the requested + one. */ + } + else if (gpg_err_code (rc) == GPG_ERR_NO_DATA) + goto nextone; + } + } + + /* If we don't have the KEYID filter we need to check for + ambigious search results. Note, that it is somehwat + reasonable to assume that a specification of a KEYID + won't lead to ambiguous names. */ + if (!rc && !keyid) { rc = keydb_search (kh, &desc, 1); if (rc == -1) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ff404dc69..dae547702 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1566,7 +1566,7 @@ main ( int argc, char **argv) ksba_cert_t cert = NULL; char *grip = NULL; - rc = gpgsm_find_cert (*argv, &cert); + rc = gpgsm_find_cert (*argv, NULL, &cert); if (rc) ; else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 17ad21ed6..aafc4815d 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -252,7 +252,7 @@ int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, 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_cert_t *r_cert); +int gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert); /*-- keylist.c --*/ gpg_error_t gpgsm_list_keys (ctrl_t ctrl, STRLIST names, diff --git a/sm/keylist.c b/sm/keylist.c index aa6db46c3..8e1233341 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -1,6 +1,6 @@ -/* keylist.c +/* keylist.c - Print certificates in various formats. * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. + * 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -122,7 +122,7 @@ static struct { { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" }, /* X.509 id-ce */ - { "2.5.29.14", "subjectKeyIdentifier"}, + { "2.5.29.14", "subjectKeyIdentifier", 1}, { "2.5.29.15", "keyUsage", 1 }, { "2.5.29.16", "privateKeyUsagePeriod" }, { "2.5.29.17", "subjectAltName", 1 }, @@ -512,7 +512,7 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, { gpg_error_t err; size_t off, len; - ksba_sexp_t sexp; + ksba_sexp_t sexp, keyid; char *dn; ksba_isotime_t t; int idx, i; @@ -588,9 +588,27 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?"); } + /* subjectKeyIdentifier */ + fputs (" subjKeyId: ", fp); + err = ksba_cert_get_subj_key_id (cert, NULL, &keyid); + if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) + { + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + fputs ("[none]\n", fp); + else + { + gpgsm_print_serial (fp, keyid); + ksba_free (keyid); + putc ('\n', fp); + } + } + else + fputs ("[?]\n", fp); + + /* authorityKeyIdentifier */ fputs (" authKeyId: ", fp); - err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp); + err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp); if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) { if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name) @@ -603,6 +621,13 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, print_names_raw (fp, -15, name); ksba_name_release (name); } + if (keyid) + { + fputs (" authKeyId.ki: ", fp); + gpgsm_print_serial (fp, keyid); + ksba_free (keyid); + putc ('\n', fp); + } } else fputs ("[?]\n", fp);