Make use of the card's extended capabilities.
[gnupg.git] / sm / keylist.c
blob2ea722370a5af723bd471f7898f91c5bc50e0d0f
1 /* keylist.c - Print certificates in various formats.
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3 * 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <assert.h>
30 #include "gpgsm.h"
32 #include <gcrypt.h>
33 #include <ksba.h>
35 #include "keydb.h"
36 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
37 #include "i18n.h"
38 #include "tlv.h"
40 struct list_external_parm_s
42 ctrl_t ctrl;
43 estream_t fp;
44 int print_header;
45 int with_colons;
46 int with_chain;
47 int raw_mode;
51 /* This table is to map Extended Key Usage OIDs to human readable
52 names. */
53 struct
55 const char *oid;
56 const char *name;
57 } key_purpose_map[] = {
58 { "1.3.6.1.5.5.7.3.1", "serverAuth" },
59 { "1.3.6.1.5.5.7.3.2", "clientAuth" },
60 { "1.3.6.1.5.5.7.3.3", "codeSigning" },
61 { "1.3.6.1.5.5.7.3.4", "emailProtection" },
62 { "1.3.6.1.5.5.7.3.5", "ipsecEndSystem" },
63 { "1.3.6.1.5.5.7.3.6", "ipsecTunnel" },
64 { "1.3.6.1.5.5.7.3.7", "ipsecUser" },
65 { "1.3.6.1.5.5.7.3.8", "timeStamping" },
66 { "1.3.6.1.5.5.7.3.9", "ocspSigning" },
67 { "1.3.6.1.5.5.7.3.10", "dvcs" },
68 { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
69 { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
70 { "1.3.6.1.5.5.7.3.14", "wlanSSID" },
72 { "2.16.840.1.113730.4.1", "serverGatedCrypto.ns" }, /* Netscape. */
73 { "1.3.6.1.4.1.311.10.3.3", "serverGatedCrypto.ms"}, /* Microsoft. */
75 { "1.3.6.1.5.5.7.48.1.5", "ocspNoCheck" },
77 { NULL, NULL }
81 /* Do not print this extension in the list of extensions. This is set
82 for oids which are already available via ksba fucntions. */
83 #define OID_FLAG_SKIP 1
84 /* The extension is a simple UTF8String and should be printed. */
85 #define OID_FLAG_UTF8 2
87 /* A table mapping OIDs to a descriptive string. */
88 static struct
90 char *oid;
91 char *name;
92 unsigned int flag; /* A flag as described above. */
93 } oidtranstbl[] = {
95 /* Algorithms. */
96 { "1.2.840.10040.4.1", "dsa" },
97 { "1.2.840.10040.4.3", "dsaWithSha1" },
99 { "1.2.840.113549.1.1.1", "rsaEncryption" },
100 { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
101 { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
102 { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
103 { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
104 { "1.2.840.113549.1.1.7", "rsaOAEP" },
105 { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
106 { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
107 { "1.2.840.113549.1.1.10", "rsaPSS" },
108 { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
109 { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
110 { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
112 { "1.3.14.3.2.26", "sha1" },
113 { "1.3.14.3.2.29", "sha-1WithRSAEncryption" },
114 { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
117 /* Telesec extensions. */
118 { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
119 { "0.2.262.1.10.12.1", "telesecCertIdExt" },
120 { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
121 { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
122 { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
123 { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
124 { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
125 #define OIDSTR_restriction \
126 "1.3.36.8.3.8"
127 { OIDSTR_restriction, "restriction", OID_FLAG_UTF8 },
130 /* PKIX private extensions. */
131 { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
132 { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
133 { "1.3.6.1.5.5.7.1.3", "qcStatements" },
134 { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
135 { "1.3.6.1.5.5.7.1.5", "acTargeting" },
136 { "1.3.6.1.5.5.7.1.6", "acAaControls" },
137 { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
138 { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
139 { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
140 { "1.3.6.1.5.5.7.1.10", "acProxying" },
141 { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
143 { "1.3.6.1.5.5.7.48.1", "ocsp" },
144 { "1.3.6.1.5.5.7.48.2", "caIssuers" },
145 { "1.3.6.1.5.5.7.48.3", "timeStamping" },
146 { "1.3.6.1.5.5.7.48.5", "caRepository" },
148 /* X.509 id-ce */
149 { "2.5.29.14", "subjectKeyIdentifier", OID_FLAG_SKIP},
150 { "2.5.29.15", "keyUsage", OID_FLAG_SKIP},
151 { "2.5.29.16", "privateKeyUsagePeriod" },
152 { "2.5.29.17", "subjectAltName", OID_FLAG_SKIP},
153 { "2.5.29.18", "issuerAltName", OID_FLAG_SKIP},
154 { "2.5.29.19", "basicConstraints", OID_FLAG_SKIP},
155 { "2.5.29.20", "cRLNumber" },
156 { "2.5.29.21", "cRLReason" },
157 { "2.5.29.22", "expirationDate" },
158 { "2.5.29.23", "instructionCode" },
159 { "2.5.29.24", "invalidityDate" },
160 { "2.5.29.27", "deltaCRLIndicator" },
161 { "2.5.29.28", "issuingDistributionPoint" },
162 { "2.5.29.29", "certificateIssuer" },
163 { "2.5.29.30", "nameConstraints" },
164 { "2.5.29.31", "cRLDistributionPoints", OID_FLAG_SKIP},
165 { "2.5.29.32", "certificatePolicies", OID_FLAG_SKIP},
166 { "2.5.29.32.0", "anyPolicy" },
167 { "2.5.29.33", "policyMappings" },
168 { "2.5.29.35", "authorityKeyIdentifier", OID_FLAG_SKIP},
169 { "2.5.29.36", "policyConstraints" },
170 { "2.5.29.37", "extKeyUsage", OID_FLAG_SKIP},
171 { "2.5.29.46", "freshestCRL" },
172 { "2.5.29.54", "inhibitAnyPolicy" },
174 /* Netscape certificate extensions. */
175 { "2.16.840.1.113730.1.1", "netscape-cert-type" },
176 { "2.16.840.1.113730.1.2", "netscape-base-url" },
177 { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
178 { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
179 { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
180 { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
181 { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
182 { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
183 { "2.16.840.1.113730.1.11", "netscape-userPicture" },
184 { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
185 { "2.16.840.1.113730.1.13", "netscape-comment" },
187 /* GnuPG extensions */
188 { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
190 /* Extensions used by the Bundesnetzagentur. */
191 { "1.3.6.1.4.1.8301.3.5", "validityModel" },
193 { NULL }
197 /* Return the description for OID; if no description is available
198 NULL is returned. */
199 static const char *
200 get_oid_desc (const char *oid, unsigned int *flag)
202 int i;
204 if (oid)
205 for (i=0; oidtranstbl[i].oid; i++)
206 if (!strcmp (oidtranstbl[i].oid, oid))
208 if (flag)
209 *flag = oidtranstbl[i].flag;
210 return oidtranstbl[i].name;
212 if (flag)
213 *flag = 0;
214 return NULL;
218 static void
219 print_key_data (ksba_cert_t cert, estream_t fp)
221 #if 0
222 int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
223 int i;
225 for(i=0; i < n; i++ )
227 es_fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
228 mpi_print(stdout, pk->pkey[i], 1 );
229 putchar(':');
230 putchar('\n');
232 #else
233 (void)cert;
234 (void)fp;
235 #endif
238 static void
239 print_capabilities (ksba_cert_t cert, estream_t fp)
241 gpg_error_t err;
242 unsigned int use;
243 size_t buflen;
244 char buffer[1];
246 err = ksba_cert_get_user_data (cert, "is_qualified",
247 &buffer, sizeof (buffer), &buflen);
248 if (!err && buflen)
250 if (*buffer)
251 es_putc ('q', fp);
253 else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
254 ; /* Don't know - will not get marked as 'q' */
255 else
256 log_debug ("get_user_data(is_qualified) failed: %s\n",
257 gpg_strerror (err));
259 err = ksba_cert_get_key_usage (cert, &use);
260 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
262 es_putc ('e', fp);
263 es_putc ('s', fp);
264 es_putc ('c', fp);
265 es_putc ('E', fp);
266 es_putc ('S', fp);
267 es_putc ('C', fp);
268 return;
270 if (err)
272 log_error (_("error getting key usage information: %s\n"),
273 gpg_strerror (err));
274 return;
277 if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
278 es_putc ('e', fp);
279 if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
280 es_putc ('s', fp);
281 if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
282 es_putc ('c', fp);
283 if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
284 es_putc ('E', fp);
285 if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
286 es_putc ('S', fp);
287 if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
288 es_putc ('C', fp);
292 static void
293 print_time (gnupg_isotime_t t, estream_t fp)
295 if (!t || !*t)
297 else
298 es_fputs (t, fp);
302 /* Return an allocated string with the email address extracted from a
303 DN. Note hat we use this code also in ../kbx/keybox-blob.c. */
304 static char *
305 email_kludge (const char *name)
307 const char *p, *string;
308 unsigned char *buf;
309 int n;
311 string = name;
312 for (;;)
314 p = strstr (string, "1.2.840.113549.1.9.1=#");
315 if (!p)
316 return NULL;
317 if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
319 name = p + 22;
320 break;
322 string = p + 22;
326 /* This looks pretty much like an email address in the subject's DN
327 we use this to add an additional user ID entry. This way,
328 OpenSSL generated keys get a nicer and usable listing. */
329 for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
331 if (!n)
332 return NULL;
333 buf = xtrymalloc (n+3);
334 if (!buf)
335 return NULL; /* oops, out of core */
336 *buf = '<';
337 for (n=1, p=name; hexdigitp (p); p +=2, n++)
338 buf[n] = xtoi_2 (p);
339 buf[n++] = '>';
340 buf[n] = 0;
341 return (char*)buf;
347 /* List one certificate in colon mode */
348 static void
349 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
350 estream_t fp, int have_secret)
352 int rc;
353 int idx;
354 char truststring[2];
355 char *p;
356 ksba_sexp_t sexp;
357 char *fpr;
358 ksba_isotime_t t;
359 gpg_error_t valerr;
360 int algo;
361 unsigned int nbits;
362 const char *chain_id;
363 char *chain_id_buffer = NULL;
364 int is_root = 0;
365 char *kludge_uid;
367 if (ctrl->with_validation)
368 valerr = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, NULL, 0, NULL);
369 else
370 valerr = 0;
373 /* We need to get the fingerprint and the chaining ID in advance. */
374 fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
376 ksba_cert_t next;
378 rc = gpgsm_walk_cert_chain (ctrl, cert, &next);
379 if (!rc) /* We known the issuer's certificate. */
381 p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
382 chain_id_buffer = p;
383 chain_id = chain_id_buffer;
384 ksba_cert_release (next);
386 else if (rc == -1) /* We have reached the root certificate. */
388 chain_id = fpr;
389 is_root = 1;
391 else
392 chain_id = NULL;
396 es_fputs (have_secret? "crs:":"crt:", fp);
398 /* Note: We can't use multiple flags, like "ei", because the
399 validation check does only return one error. */
400 truststring[0] = 0;
401 truststring[1] = 0;
402 if ((validity & VALIDITY_REVOKED)
403 || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
404 *truststring = 'r';
405 else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
406 *truststring = 'e';
407 else
409 /* Lets also check whether the certificate under question
410 expired. This is merely a hack until we found a proper way
411 to store the expiration flag in the keybox. */
412 ksba_isotime_t current_time, not_after;
414 gnupg_get_isotime (current_time);
415 if (!opt.ignore_expiration
416 && !ksba_cert_get_validity (cert, 1, not_after)
417 && *not_after && strcmp (current_time, not_after) > 0 )
418 *truststring = 'e';
419 else if (valerr)
420 *truststring = 'i';
421 else if (ctrl->with_validation && !is_root)
422 *truststring = 'f';
425 /* If we have no truststring yet (i.e. the certificate might be
426 good) and this is a root certificate, we ask the agent whether
427 this is a trusted root certificate. */
428 if (!*truststring && is_root)
430 struct rootca_flags_s dummy_flags;
432 rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
433 if (!rc)
434 *truststring = 'u'; /* Yes, we trust this one (ultimately). */
435 else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
436 *truststring = 'n'; /* No, we do not trust this one. */
437 /* (in case of an error we can't tell anything.) */
440 if (*truststring)
441 es_fputs (truststring, fp);
443 algo = gpgsm_get_key_algo_info (cert, &nbits);
444 es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
446 /* We assume --fixed-list-mode for gpgsm */
447 ksba_cert_get_validity (cert, 0, t);
448 print_time (t, fp);
449 es_putc (':', fp);
450 ksba_cert_get_validity (cert, 1, t);
451 print_time ( t, fp);
452 es_putc (':', fp);
453 /* Field 8, serial number: */
454 if ((sexp = ksba_cert_get_serial (cert)))
456 int len;
457 const unsigned char *s = sexp;
459 if (*s == '(')
461 s++;
462 for (len=0; *s && *s != ':' && digitp (s); s++)
463 len = len*10 + atoi_1 (s);
464 if (*s == ':')
465 for (s++; len; len--, s++)
466 es_fprintf (fp,"%02X", *s);
468 xfree (sexp);
470 es_putc (':', fp);
471 /* Field 9, ownertrust - not used here */
472 es_putc (':', fp);
473 /* field 10, old user ID - we use it here for the issuer DN */
474 if ((p = ksba_cert_get_issuer (cert,0)))
476 es_write_sanitized (fp, p, strlen (p), ":", NULL);
477 xfree (p);
479 es_putc (':', fp);
480 /* Field 11, signature class - not used */
481 es_putc (':', fp);
482 /* Field 12, capabilities: */
483 print_capabilities (cert, fp);
484 /* Field 13, not used: */
485 es_putc (':', fp);
486 if (have_secret)
488 char *cardsn;
490 p = gpgsm_get_keygrip_hexstring (cert);
491 if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
493 /* Field 14, not used: */
494 es_putc (':', fp);
495 /* Field 15: Token serial number. */
496 es_fputs (cardsn, fp);
497 es_putc (':', fp);
499 xfree (cardsn);
500 xfree (p);
502 es_putc ('\n', fp);
504 /* FPR record */
505 es_fprintf (fp, "fpr:::::::::%s:::", fpr);
506 /* Print chaining ID (field 13)*/
507 if (chain_id)
508 es_fputs (chain_id, fp);
509 es_putc (':', fp);
510 es_putc ('\n', fp);
511 xfree (fpr); fpr = NULL; chain_id = NULL;
512 xfree (chain_id_buffer); chain_id_buffer = NULL;
514 if (opt.with_key_data)
516 if ( (p = gpgsm_get_keygrip_hexstring (cert)))
518 es_fprintf (fp, "grp:::::::::%s:\n", p);
519 xfree (p);
521 print_key_data (cert, fp);
524 kludge_uid = NULL;
525 for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
527 /* In the case that the same email address is in the subject DN
528 as well as in an alternate subject name we avoid printing it
529 a second time. */
530 if (kludge_uid && !strcmp (kludge_uid, p))
531 continue;
533 es_fprintf (fp, "uid:%s::::::::", truststring);
534 es_write_sanitized (fp, p, strlen (p), ":", NULL);
535 es_putc (':', fp);
536 es_putc (':', fp);
537 es_putc ('\n', fp);
538 if (!idx)
540 /* It would be better to get the faked email address from
541 the keydb. But as long as we don't have a way to pass
542 the meta data back, we just check it the same way as the
543 code used to create the keybox meta data does */
544 kludge_uid = email_kludge (p);
545 if (kludge_uid)
547 es_fprintf (fp, "uid:%s::::::::", truststring);
548 es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
549 ":", NULL);
550 es_putc (':', fp);
551 es_putc (':', fp);
552 es_putc ('\n', fp);
555 xfree (p);
557 xfree (kludge_uid);
561 static void
562 print_name_raw (estream_t fp, const char *string)
564 if (!string)
565 es_fputs ("[error]", fp);
566 else
567 es_write_sanitized (fp, string, strlen (string), NULL, NULL);
570 static void
571 print_names_raw (estream_t fp, int indent, ksba_name_t name)
573 int idx;
574 const char *s;
575 int indent_all;
577 if ((indent_all = (indent < 0)))
578 indent = - indent;
580 if (!name)
582 es_fputs ("none\n", fp);
583 return;
586 for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
588 char *p = ksba_name_get_uri (name, idx);
589 es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
590 es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
591 es_putc ('\n', fp);
592 xfree (p);
597 static void
598 print_utf8_extn_raw (estream_t fp, int indent,
599 const unsigned char *der, size_t derlen)
601 gpg_error_t err;
602 int class, tag, constructed, ndef;
603 size_t objlen, hdrlen;
605 if (indent < 0)
606 indent = - indent;
608 err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
609 &ndef, &objlen, &hdrlen);
610 if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
611 err = gpg_error (GPG_ERR_INV_OBJ);
612 if (err)
614 es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
615 return;
617 es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
621 static void
622 print_utf8_extn (estream_t fp, int indent,
623 const unsigned char *der, size_t derlen)
625 gpg_error_t err;
626 int class, tag, constructed, ndef;
627 size_t objlen, hdrlen;
628 int indent_all;
630 if ((indent_all = (indent < 0)))
631 indent = - indent;
633 err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
634 &ndef, &objlen, &hdrlen);
635 if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
636 err = gpg_error (GPG_ERR_INV_OBJ);
637 if (err)
639 es_fprintf (fp, "%*s[%s%s]\n",
640 indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
641 return;
643 es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
644 /* Fixme: we should implement word wrapping */
645 es_write_sanitized (fp, der, objlen, "\"", NULL);
646 es_fputs ("\"\n", fp);
650 /* List one certificate in raw mode useful to have a closer look at
651 the certificate. This one does no beautification and only minimal
652 output sanitation. It is mainly useful for debugging. */
653 static void
654 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
655 ksba_cert_t cert, estream_t fp, int have_secret,
656 int with_validation)
658 gpg_error_t err;
659 size_t off, len;
660 ksba_sexp_t sexp, keyid;
661 char *dn;
662 ksba_isotime_t t;
663 int idx, i;
664 int is_ca, chainlen;
665 unsigned int kusage;
666 char *string, *p, *pend;
667 const char *oid, *s;
668 ksba_name_t name, name2;
669 unsigned int reason;
670 const unsigned char *cert_der = NULL;
672 (void)have_secret;
674 es_fprintf (fp, " ID: 0x%08lX\n",
675 gpgsm_get_short_fingerprint (cert, NULL));
677 sexp = ksba_cert_get_serial (cert);
678 es_fputs (" S/N: ", fp);
679 gpgsm_print_serial (fp, sexp);
680 ksba_free (sexp);
681 es_putc ('\n', fp);
683 dn = ksba_cert_get_issuer (cert, 0);
684 es_fputs (" Issuer: ", fp);
685 print_name_raw (fp, dn);
686 ksba_free (dn);
687 es_putc ('\n', fp);
688 for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
690 es_fputs (" aka: ", fp);
691 print_name_raw (fp, dn);
692 ksba_free (dn);
693 es_putc ('\n', fp);
696 dn = ksba_cert_get_subject (cert, 0);
697 es_fputs (" Subject: ", fp);
698 print_name_raw (fp, dn);
699 ksba_free (dn);
700 es_putc ('\n', fp);
701 for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
703 es_fputs (" aka: ", fp);
704 print_name_raw (fp, dn);
705 ksba_free (dn);
706 es_putc ('\n', fp);
709 dn = gpgsm_get_fingerprint_string (cert, 0);
710 es_fprintf (fp, " sha1_fpr: %s\n", dn?dn:"error");
711 xfree (dn);
713 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
714 es_fprintf (fp, " md5_fpr: %s\n", dn?dn:"error");
715 xfree (dn);
717 dn = gpgsm_get_certid (cert);
718 es_fprintf (fp, " certid: %s\n", dn?dn:"error");
719 xfree (dn);
721 dn = gpgsm_get_keygrip_hexstring (cert);
722 es_fprintf (fp, " keygrip: %s\n", dn?dn:"error");
723 xfree (dn);
725 ksba_cert_get_validity (cert, 0, t);
726 es_fputs (" notBefore: ", fp);
727 gpgsm_print_time (fp, t);
728 es_putc ('\n', fp);
729 es_fputs (" notAfter: ", fp);
730 ksba_cert_get_validity (cert, 1, t);
731 gpgsm_print_time (fp, t);
732 es_putc ('\n', fp);
734 oid = ksba_cert_get_digest_algo (cert);
735 s = get_oid_desc (oid, NULL);
736 es_fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
739 const char *algoname;
740 unsigned int nbits;
742 algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
743 es_fprintf (fp, " keyType: %u bit %s\n",
744 nbits, algoname? algoname:"?");
747 /* subjectKeyIdentifier */
748 es_fputs (" subjKeyId: ", fp);
749 err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
750 if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
752 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
753 es_fputs ("[none]\n", fp);
754 else
756 gpgsm_print_serial (fp, keyid);
757 ksba_free (keyid);
758 es_putc ('\n', fp);
761 else
762 es_fputs ("[?]\n", fp);
765 /* authorityKeyIdentifier */
766 es_fputs (" authKeyId: ", fp);
767 err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
768 if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
770 if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
771 es_fputs ("[none]\n", fp);
772 else
774 gpgsm_print_serial (fp, sexp);
775 ksba_free (sexp);
776 es_putc ('\n', fp);
777 print_names_raw (fp, -15, name);
778 ksba_name_release (name);
780 if (keyid)
782 es_fputs (" authKeyId.ki: ", fp);
783 gpgsm_print_serial (fp, keyid);
784 ksba_free (keyid);
785 es_putc ('\n', fp);
788 else
789 es_fputs ("[?]\n", fp);
791 es_fputs (" keyUsage:", fp);
792 err = ksba_cert_get_key_usage (cert, &kusage);
793 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
795 if (err)
796 es_fprintf (fp, " [error: %s]", gpg_strerror (err));
797 else
799 if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
800 es_fputs (" digitalSignature", fp);
801 if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
802 es_fputs (" nonRepudiation", fp);
803 if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
804 es_fputs (" keyEncipherment", fp);
805 if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
806 es_fputs (" dataEncipherment", fp);
807 if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
808 es_fputs (" keyAgreement", fp);
809 if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
810 es_fputs (" certSign", fp);
811 if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
812 es_fputs (" crlSign", fp);
813 if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
814 es_fputs (" encipherOnly", fp);
815 if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
816 es_fputs (" decipherOnly", fp);
818 es_putc ('\n', fp);
820 else
821 es_fputs (" [none]\n", fp);
823 es_fputs (" extKeyUsage: ", fp);
824 err = ksba_cert_get_ext_key_usages (cert, &string);
825 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
827 if (err)
828 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
829 else
831 p = string;
832 while (p && (pend=strchr (p, ':')))
834 *pend++ = 0;
835 for (i=0; key_purpose_map[i].oid; i++)
836 if ( !strcmp (key_purpose_map[i].oid, p) )
837 break;
838 es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
839 p = pend;
840 if (*p != 'C')
841 es_fputs (" (suggested)", fp);
842 if ((p = strchr (p, '\n')))
844 p++;
845 es_fputs ("\n ", fp);
848 xfree (string);
850 es_putc ('\n', fp);
852 else
853 es_fputs ("[none]\n", fp);
856 es_fputs (" policies: ", fp);
857 err = ksba_cert_get_cert_policies (cert, &string);
858 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
860 if (err)
861 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
862 else
864 p = string;
865 while (p && (pend=strchr (p, ':')))
867 *pend++ = 0;
868 for (i=0; key_purpose_map[i].oid; i++)
869 if ( !strcmp (key_purpose_map[i].oid, p) )
870 break;
871 es_fputs (p, fp);
872 p = pend;
873 if (*p == 'C')
874 es_fputs (" (critical)", fp);
875 if ((p = strchr (p, '\n')))
877 p++;
878 es_fputs ("\n ", fp);
881 xfree (string);
883 es_putc ('\n', fp);
885 else
886 es_fputs ("[none]\n", fp);
888 es_fputs (" chainLength: ", fp);
889 err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
890 if (err || is_ca)
892 if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
893 es_fprintf (fp, "[none]");
894 else if (err)
895 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
896 else if (chainlen == -1)
897 es_fputs ("unlimited", fp);
898 else
899 es_fprintf (fp, "%d", chainlen);
900 es_putc ('\n', fp);
902 else
903 es_fputs ("not a CA\n", fp);
906 /* CRL distribution point */
907 for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
908 &reason)) ;idx++)
910 es_fputs (" crlDP: ", fp);
911 print_names_raw (fp, 15, name);
912 if (reason)
914 es_fputs (" reason: ", fp);
915 if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
916 es_fputs (" unused", fp);
917 if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
918 es_fputs (" keyCompromise", fp);
919 if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
920 es_fputs (" caCompromise", fp);
921 if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
922 es_fputs (" affiliationChanged", fp);
923 if ( (reason & KSBA_CRLREASON_SUPERSEDED))
924 es_fputs (" superseded", fp);
925 if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
926 es_fputs (" cessationOfOperation", fp);
927 if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
928 es_fputs (" certificateHold", fp);
929 es_putc ('\n', fp);
931 es_fputs (" issuer: ", fp);
932 print_names_raw (fp, 23, name2);
933 ksba_name_release (name);
934 ksba_name_release (name2);
936 if (err && gpg_err_code (err) != GPG_ERR_EOF
937 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
938 es_fputs (" crlDP: [error]\n", fp);
939 else if (!idx)
940 es_fputs (" crlDP: [none]\n", fp);
943 /* authorityInfoAccess. */
944 for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
945 &name)); idx++)
947 es_fputs (" authInfo: ", fp);
948 s = get_oid_desc (string, NULL);
949 es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
950 print_names_raw (fp, -15, name);
951 ksba_name_release (name);
952 ksba_free (string);
954 if (err && gpg_err_code (err) != GPG_ERR_EOF
955 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
956 es_fputs (" authInfo: [error]\n", fp);
957 else if (!idx)
958 es_fputs (" authInfo: [none]\n", fp);
960 /* subjectInfoAccess. */
961 for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
962 &name)); idx++)
964 es_fputs (" subjectInfo: ", fp);
965 s = get_oid_desc (string, NULL);
966 es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
967 print_names_raw (fp, -15, name);
968 ksba_name_release (name);
969 ksba_free (string);
971 if (err && gpg_err_code (err) != GPG_ERR_EOF
972 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
973 es_fputs (" subjInfo: [error]\n", fp);
974 else if (!idx)
975 es_fputs (" subjInfo: [none]\n", fp);
978 for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
979 &oid, &i, &off, &len));idx++)
981 unsigned int flag;
983 s = get_oid_desc (oid, &flag);
984 if ((flag & OID_FLAG_SKIP))
985 continue;
987 es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n",
988 i? "critExtn":" extn",
989 oid, s?" (":"", s?s:"", s?")":"", (int)len);
990 if ((flag & OID_FLAG_UTF8))
992 if (!cert_der)
993 cert_der = ksba_cert_get_image (cert, NULL);
994 assert (cert_der);
995 print_utf8_extn_raw (fp, -15, cert_der+off, len);
1000 if (with_validation)
1002 err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1003 if (!err)
1004 es_fprintf (fp, " [certificate is good]\n");
1005 else
1006 es_fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
1009 if (hd)
1011 unsigned int blobflags;
1013 err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
1014 if (err)
1015 es_fprintf (fp, " [error getting keyflags: %s]\n",gpg_strerror (err));
1016 else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1017 es_fprintf (fp, " [stored as ephemeral]\n");
1025 /* List one certificate in standard mode */
1026 static void
1027 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1028 int with_validation)
1030 gpg_error_t err;
1031 ksba_sexp_t sexp;
1032 char *dn;
1033 ksba_isotime_t t;
1034 int idx, i;
1035 int is_ca, chainlen;
1036 unsigned int kusage;
1037 char *string, *p, *pend;
1038 size_t off, len;
1039 const char *oid;
1040 const unsigned char *cert_der = NULL;
1043 es_fprintf (fp, " ID: 0x%08lX\n",
1044 gpgsm_get_short_fingerprint (cert, NULL));
1046 sexp = ksba_cert_get_serial (cert);
1047 es_fputs (" S/N: ", fp);
1048 gpgsm_print_serial (fp, sexp);
1049 ksba_free (sexp);
1050 es_putc ('\n', fp);
1052 dn = ksba_cert_get_issuer (cert, 0);
1053 es_fputs (" Issuer: ", fp);
1054 gpgsm_es_print_name (fp, dn);
1055 ksba_free (dn);
1056 es_putc ('\n', fp);
1057 for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1059 es_fputs (" aka: ", fp);
1060 gpgsm_es_print_name (fp, dn);
1061 ksba_free (dn);
1062 es_putc ('\n', fp);
1065 dn = ksba_cert_get_subject (cert, 0);
1066 es_fputs (" Subject: ", fp);
1067 gpgsm_es_print_name (fp, dn);
1068 ksba_free (dn);
1069 es_putc ('\n', fp);
1070 for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1072 es_fputs (" aka: ", fp);
1073 gpgsm_es_print_name (fp, dn);
1074 ksba_free (dn);
1075 es_putc ('\n', fp);
1078 ksba_cert_get_validity (cert, 0, t);
1079 es_fputs (" validity: ", fp);
1080 gpgsm_print_time (fp, t);
1081 es_fputs (" through ", fp);
1082 ksba_cert_get_validity (cert, 1, t);
1083 gpgsm_print_time (fp, t);
1084 es_putc ('\n', fp);
1088 const char *algoname;
1089 unsigned int nbits;
1091 algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1092 es_fprintf (fp, " key type: %u bit %s\n",
1093 nbits, algoname? algoname:"?");
1097 err = ksba_cert_get_key_usage (cert, &kusage);
1098 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1100 es_fputs (" key usage:", fp);
1101 if (err)
1102 es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1103 else
1105 if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1106 es_fputs (" digitalSignature", fp);
1107 if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
1108 es_fputs (" nonRepudiation", fp);
1109 if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
1110 es_fputs (" keyEncipherment", fp);
1111 if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1112 es_fputs (" dataEncipherment", fp);
1113 if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
1114 es_fputs (" keyAgreement", fp);
1115 if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1116 es_fputs (" certSign", fp);
1117 if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
1118 es_fputs (" crlSign", fp);
1119 if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1120 es_fputs (" encipherOnly", fp);
1121 if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
1122 es_fputs (" decipherOnly", fp);
1124 es_putc ('\n', fp);
1127 err = ksba_cert_get_ext_key_usages (cert, &string);
1128 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1130 es_fputs ("ext key usage: ", fp);
1131 if (err)
1132 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1133 else
1135 p = string;
1136 while (p && (pend=strchr (p, ':')))
1138 *pend++ = 0;
1139 for (i=0; key_purpose_map[i].oid; i++)
1140 if ( !strcmp (key_purpose_map[i].oid, p) )
1141 break;
1142 es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1143 p = pend;
1144 if (*p != 'C')
1145 es_fputs (" (suggested)", fp);
1146 if ((p = strchr (p, '\n')))
1148 p++;
1149 es_fputs (", ", fp);
1152 xfree (string);
1154 es_putc ('\n', fp);
1157 /* Print restrictions. */
1158 for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1159 &oid, NULL, &off, &len));idx++)
1161 if (!strcmp (oid, OIDSTR_restriction) )
1163 if (!cert_der)
1164 cert_der = ksba_cert_get_image (cert, NULL);
1165 assert (cert_der);
1166 es_fputs (" restriction: ", fp);
1167 print_utf8_extn (fp, 15, cert_der+off, len);
1171 /* Print policies. */
1172 err = ksba_cert_get_cert_policies (cert, &string);
1173 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1175 es_fputs (" policies: ", fp);
1176 if (err)
1177 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1178 else
1180 for (p=string; *p; p++)
1182 if (*p == '\n')
1183 *p = ',';
1185 es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1186 xfree (string);
1188 es_putc ('\n', fp);
1191 err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1192 if (err || is_ca)
1194 es_fputs (" chain length: ", fp);
1195 if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1196 es_fprintf (fp, "none");
1197 else if (err)
1198 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1199 else if (chainlen == -1)
1200 es_fputs ("unlimited", fp);
1201 else
1202 es_fprintf (fp, "%d", chainlen);
1203 es_putc ('\n', fp);
1206 if (opt.with_md5_fingerprint)
1208 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1209 es_fprintf (fp, " md5 fpr: %s\n", dn?dn:"error");
1210 xfree (dn);
1213 dn = gpgsm_get_fingerprint_string (cert, 0);
1214 es_fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
1215 xfree (dn);
1217 if (have_secret)
1219 char *cardsn;
1221 p = gpgsm_get_keygrip_hexstring (cert);
1222 if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
1223 es_fprintf (fp, " card s/n: %s\n", cardsn);
1224 xfree (cardsn);
1225 xfree (p);
1228 if (with_validation)
1230 gpg_error_t tmperr;
1231 size_t buflen;
1232 char buffer[1];
1234 err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1235 tmperr = ksba_cert_get_user_data (cert, "is_qualified",
1236 &buffer, sizeof (buffer), &buflen);
1237 if (!tmperr && buflen)
1239 if (*buffer)
1240 es_fputs (" [qualified]\n", fp);
1242 else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1243 ; /* Don't know - will not get marked as 'q' */
1244 else
1245 log_debug ("get_user_data(is_qualified) failed: %s\n",
1246 gpg_strerror (tmperr));
1248 if (!err)
1249 es_fprintf (fp, " [certificate is good]\n");
1250 else
1251 es_fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
1256 /* Same as standard mode mode list all certifying certs too. */
1257 static void
1258 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1259 ksba_cert_t cert, int raw_mode,
1260 estream_t fp, int with_validation)
1262 ksba_cert_t next = NULL;
1264 if (raw_mode)
1265 list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1266 else
1267 list_cert_std (ctrl, cert, fp, 0, with_validation);
1268 ksba_cert_ref (cert);
1269 while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1271 ksba_cert_release (cert);
1272 es_fputs ("Certified by\n", fp);
1273 if (raw_mode)
1274 list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1275 else
1276 list_cert_std (ctrl, next, fp, 0, with_validation);
1277 cert = next;
1279 ksba_cert_release (cert);
1280 es_putc ('\n', fp);
1285 /* List all internal keys or just the keys given as NAMES. MODE is a
1286 bit vector to specify what keys are to be included; see
1287 gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
1288 output mode will be used instead of the standard beautified one.
1290 static gpg_error_t
1291 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1292 unsigned int mode, int raw_mode)
1294 KEYDB_HANDLE hd;
1295 KEYDB_SEARCH_DESC *desc = NULL;
1296 strlist_t sl;
1297 int ndesc;
1298 ksba_cert_t cert = NULL;
1299 ksba_cert_t lastcert = NULL;
1300 gpg_error_t rc = 0;
1301 const char *lastresname, *resname;
1302 int have_secret;
1303 int want_ephemeral = ctrl->with_ephemeral_keys;
1305 hd = keydb_new (0);
1306 if (!hd)
1308 log_error ("keydb_new failed\n");
1309 rc = gpg_error (GPG_ERR_GENERAL);
1310 goto leave;
1313 if (!names)
1314 ndesc = 1;
1315 else
1317 for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1321 desc = xtrycalloc (ndesc, sizeof *desc);
1322 if (!ndesc)
1324 rc = gpg_error_from_syserror ();
1325 log_error ("out of core\n");
1326 goto leave;
1329 if (!names)
1330 desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1331 else
1333 for (ndesc=0, sl=names; sl; sl = sl->next)
1335 rc = keydb_classify_name (sl->d, desc+ndesc);
1336 if (rc)
1338 log_error ("key `%s' not found: %s\n",
1339 sl->d, gpg_strerror (rc));
1340 rc = 0;
1342 else
1343 ndesc++;
1348 /* If all specifications are done by fingerprint or keygrip, we
1349 switch to ephemeral mode so that _all_ currently available and
1350 matching certificates are listed. */
1351 if (!want_ephemeral && names && ndesc)
1353 int i;
1355 for (i=0; (i < ndesc
1356 && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
1357 || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
1358 || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
1359 || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
1361 if (i == ndesc)
1362 want_ephemeral = 1;
1365 if (want_ephemeral)
1366 keydb_set_ephemeral (hd, 1);
1368 /* It would be nice to see which of the given users did actually
1369 match one in the keyring. To implement this we need to have a
1370 found flag for each entry in desc and to set this we must check
1371 all those entries after a match to mark all matched one -
1372 currently we stop at the first match. To do this we need an
1373 extra flag to enable this feature so */
1375 /* Suppress duplicates at least when they follow each other. */
1376 lastresname = NULL;
1377 while (!(rc = keydb_search (hd, desc, ndesc)))
1379 unsigned int validity;
1381 if (!names)
1382 desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1384 rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1385 if (rc)
1387 log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1388 goto leave;
1390 rc = keydb_get_cert (hd, &cert);
1391 if (rc)
1393 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1394 goto leave;
1396 /* Skip duplicated certificates, at least if they follow each
1397 others. This works best if a single key is searched for and
1398 expected. FIXME: Non-sequential duplicates remain. */
1399 if (gpgsm_certs_identical_p (cert, lastcert))
1401 ksba_cert_release (cert);
1402 cert = NULL;
1403 continue;
1406 resname = keydb_get_resource_name (hd);
1408 if (lastresname != resname )
1410 int i;
1412 if (ctrl->no_server)
1414 es_fprintf (fp, "%s\n", resname );
1415 for (i=strlen(resname); i; i-- )
1416 es_putc ('-', fp);
1417 es_putc ('\n', fp);
1418 lastresname = resname;
1422 have_secret = 0;
1423 if (mode)
1425 char *p = gpgsm_get_keygrip_hexstring (cert);
1426 if (p)
1428 rc = gpgsm_agent_havekey (ctrl, p);
1429 if (!rc)
1430 have_secret = 1;
1431 else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1432 goto leave;
1433 rc = 0;
1434 xfree (p);
1438 if (!mode
1439 || ((mode & 1) && !have_secret)
1440 || ((mode & 2) && have_secret) )
1442 if (ctrl->with_colons)
1443 list_cert_colon (ctrl, cert, validity, fp, have_secret);
1444 else if (ctrl->with_chain)
1445 list_cert_chain (ctrl, hd, cert,
1446 raw_mode, fp, ctrl->with_validation);
1447 else
1449 if (raw_mode)
1450 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1451 ctrl->with_validation);
1452 else
1453 list_cert_std (ctrl, cert, fp, have_secret,
1454 ctrl->with_validation);
1455 es_putc ('\n', fp);
1459 ksba_cert_release (lastcert);
1460 lastcert = cert;
1461 cert = NULL;
1463 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1464 rc = 0;
1465 if (rc)
1466 log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1468 leave:
1469 ksba_cert_release (cert);
1470 ksba_cert_release (lastcert);
1471 xfree (desc);
1472 keydb_release (hd);
1473 return rc;
1478 static void
1479 list_external_cb (void *cb_value, ksba_cert_t cert)
1481 struct list_external_parm_s *parm = cb_value;
1483 if (keydb_store_cert (cert, 1, NULL))
1484 log_error ("error storing certificate as ephemeral\n");
1486 if (parm->print_header)
1488 const char *resname = "[external keys]";
1489 int i;
1491 es_fprintf (parm->fp, "%s\n", resname );
1492 for (i=strlen(resname); i; i-- )
1493 es_putc('-', parm->fp);
1494 es_putc ('\n', parm->fp);
1495 parm->print_header = 0;
1498 if (parm->with_colons)
1499 list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1500 else if (parm->with_chain)
1501 list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1502 else
1504 if (parm->raw_mode)
1505 list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1506 else
1507 list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1508 es_putc ('\n', parm->fp);
1513 /* List external keys similar to internal one. Note: mode does not
1514 make sense here because it would be unwise to list external secret
1515 keys */
1516 static gpg_error_t
1517 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1519 int rc;
1520 struct list_external_parm_s parm;
1522 parm.fp = fp;
1523 parm.ctrl = ctrl,
1524 parm.print_header = ctrl->no_server;
1525 parm.with_colons = ctrl->with_colons;
1526 parm.with_chain = ctrl->with_chain;
1527 parm.raw_mode = raw_mode;
1529 rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
1530 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
1531 || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1532 rc = 0; /* "Not found" is not an error here. */
1533 if (rc)
1534 log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1535 return rc;
1538 /* List all keys or just the key given as NAMES.
1539 MODE controls the operation mode:
1540 Bit 0-2:
1541 0 = list all public keys but don't flag secret ones
1542 1 = list only public keys
1543 2 = list only secret keys
1544 3 = list secret and public keys
1545 Bit 6: list internal keys
1546 Bit 7: list external keys
1547 Bit 8: Do a raw format dump.
1549 gpg_error_t
1550 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1551 unsigned int mode)
1553 gpg_error_t err = 0;
1555 if ((mode & (1<<6)))
1556 err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1557 if (!err && (mode & (1<<7)))
1558 err = list_external_keys (ctrl, names, fp, (mode&256));
1559 return err;