Rename encode.c to encrypt.c.
[gnupg.git] / sm / keylist.c
blob9b8538c84fad0c7a2589203f935bc79f030d7b0d
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);
290 es_putc (':', fp);
294 static void
295 print_time (gnupg_isotime_t t, estream_t fp)
297 if (!t || !*t)
299 else
300 es_fputs (t, fp);
304 /* Return an allocated string with the email address extracted from a
305 DN. Note hat we use this code also in ../kbx/keybox-blob.c. */
306 static char *
307 email_kludge (const char *name)
309 const char *p, *string;
310 unsigned char *buf;
311 int n;
313 string = name;
314 for (;;)
316 p = strstr (string, "1.2.840.113549.1.9.1=#");
317 if (!p)
318 return NULL;
319 if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
321 name = p + 22;
322 break;
324 string = p + 22;
328 /* This looks pretty much like an email address in the subject's DN
329 we use this to add an additional user ID entry. This way,
330 OpenSSL generated keys get a nicer and usable listing. */
331 for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
333 if (!n)
334 return NULL;
335 buf = xtrymalloc (n+3);
336 if (!buf)
337 return NULL; /* oops, out of core */
338 *buf = '<';
339 for (n=1, p=name; hexdigitp (p); p +=2, n++)
340 buf[n] = xtoi_2 (p);
341 buf[n++] = '>';
342 buf[n] = 0;
343 return (char*)buf;
349 /* List one certificate in colon mode */
350 static void
351 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
352 estream_t fp, int have_secret)
354 int rc;
355 int idx;
356 char truststring[2];
357 char *p;
358 ksba_sexp_t sexp;
359 char *fpr;
360 ksba_isotime_t t;
361 gpg_error_t valerr;
362 int algo;
363 unsigned int nbits;
364 const char *chain_id;
365 char *chain_id_buffer = NULL;
366 int is_root = 0;
367 char *kludge_uid;
369 if (ctrl->with_validation)
370 valerr = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, NULL, 0, NULL);
371 else
372 valerr = 0;
375 /* We need to get the fingerprint and the chaining ID in advance. */
376 fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
378 ksba_cert_t next;
380 rc = gpgsm_walk_cert_chain (ctrl, cert, &next);
381 if (!rc) /* We known the issuer's certificate. */
383 p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
384 chain_id_buffer = p;
385 chain_id = chain_id_buffer;
386 ksba_cert_release (next);
388 else if (rc == -1) /* We have reached the root certificate. */
390 chain_id = fpr;
391 is_root = 1;
393 else
394 chain_id = NULL;
398 es_fputs (have_secret? "crs:":"crt:", fp);
400 /* Note: We can't use multiple flags, like "ei", because the
401 validation check does only return one error. */
402 truststring[0] = 0;
403 truststring[1] = 0;
404 if ((validity & VALIDITY_REVOKED)
405 || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
406 *truststring = 'r';
407 else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
408 *truststring = 'e';
409 else
411 /* Lets also check whether the certificate under question
412 expired. This is merely a hack until we found a proper way
413 to store the expiration flag in the keybox. */
414 ksba_isotime_t current_time, not_after;
416 gnupg_get_isotime (current_time);
417 if (!opt.ignore_expiration
418 && !ksba_cert_get_validity (cert, 1, not_after)
419 && *not_after && strcmp (current_time, not_after) > 0 )
420 *truststring = 'e';
421 else if (valerr)
422 *truststring = 'i';
423 else if (ctrl->with_validation && !is_root)
424 *truststring = 'f';
427 /* If we have no truststring yet (i.e. the certificate might be
428 good) and this is a root certificate, we ask the agent whether
429 this is a trusted root certificate. */
430 if (!*truststring && is_root)
432 struct rootca_flags_s dummy_flags;
434 rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
435 if (!rc)
436 *truststring = 'u'; /* Yes, we trust this one (ultimately). */
437 else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
438 *truststring = 'n'; /* No, we do not trust this one. */
439 /* (in case of an error we can't tell anything.) */
442 if (*truststring)
443 es_fputs (truststring, fp);
445 algo = gpgsm_get_key_algo_info (cert, &nbits);
446 es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
448 /* We assume --fixed-list-mode for gpgsm */
449 ksba_cert_get_validity (cert, 0, t);
450 print_time (t, fp);
451 es_putc (':', fp);
452 ksba_cert_get_validity (cert, 1, t);
453 print_time ( t, fp);
454 es_putc (':', fp);
455 /* Field 8, serial number: */
456 if ((sexp = ksba_cert_get_serial (cert)))
458 int len;
459 const unsigned char *s = sexp;
461 if (*s == '(')
463 s++;
464 for (len=0; *s && *s != ':' && digitp (s); s++)
465 len = len*10 + atoi_1 (s);
466 if (*s == ':')
467 for (s++; len; len--, s++)
468 es_fprintf (fp,"%02X", *s);
470 xfree (sexp);
472 es_putc (':', fp);
473 /* Field 9, ownertrust - not used here */
474 es_putc (':', fp);
475 /* field 10, old user ID - we use it here for the issuer DN */
476 if ((p = ksba_cert_get_issuer (cert,0)))
478 es_write_sanitized (fp, p, strlen (p), ":", NULL);
479 xfree (p);
481 es_putc (':', fp);
482 /* Field 11, signature class - not used */
483 es_putc (':', fp);
484 /* Field 12, capabilities: */
485 print_capabilities (cert, fp);
486 /* Field 13, not used: */
487 es_putc (':', fp);
488 if (have_secret)
490 char *cardsn;
492 p = gpgsm_get_keygrip_hexstring (cert);
493 if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
495 /* Field 14, not used: */
496 es_putc (':', fp);
497 /* Field 15: Token serial number. */
498 es_fputs (cardsn, fp);
499 es_putc (':', fp);
501 xfree (cardsn);
502 xfree (p);
504 es_putc ('\n', fp);
506 /* FPR record */
507 es_fprintf (fp, "fpr:::::::::%s:::", fpr);
508 /* Print chaining ID (field 13)*/
509 if (chain_id)
510 es_fputs (chain_id, fp);
511 es_putc (':', fp);
512 es_putc ('\n', fp);
513 xfree (fpr); fpr = NULL; chain_id = NULL;
514 xfree (chain_id_buffer); chain_id_buffer = NULL;
516 if (opt.with_key_data)
518 if ( (p = gpgsm_get_keygrip_hexstring (cert)))
520 es_fprintf (fp, "grp:::::::::%s:\n", p);
521 xfree (p);
523 print_key_data (cert, fp);
526 kludge_uid = NULL;
527 for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
529 /* In the case that the same email address is in the subject DN
530 as well as in an alternate subject name we avoid printing it
531 a second time. */
532 if (kludge_uid && !strcmp (kludge_uid, p))
533 continue;
535 es_fprintf (fp, "uid:%s::::::::", truststring);
536 es_write_sanitized (fp, p, strlen (p), ":", NULL);
537 es_putc (':', fp);
538 es_putc (':', fp);
539 es_putc ('\n', fp);
540 if (!idx)
542 /* It would be better to get the faked email address from
543 the keydb. But as long as we don't have a way to pass
544 the meta data back, we just check it the same way as the
545 code used to create the keybox meta data does */
546 kludge_uid = email_kludge (p);
547 if (kludge_uid)
549 es_fprintf (fp, "uid:%s::::::::", truststring);
550 es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
551 ":", NULL);
552 es_putc (':', fp);
553 es_putc (':', fp);
554 es_putc ('\n', fp);
557 xfree (p);
559 xfree (kludge_uid);
563 static void
564 print_name_raw (estream_t fp, const char *string)
566 if (!string)
567 es_fputs ("[error]", fp);
568 else
569 es_write_sanitized (fp, string, strlen (string), NULL, NULL);
572 static void
573 print_names_raw (estream_t fp, int indent, ksba_name_t name)
575 int idx;
576 const char *s;
577 int indent_all;
579 if ((indent_all = (indent < 0)))
580 indent = - indent;
582 if (!name)
584 es_fputs ("none\n", fp);
585 return;
588 for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
590 char *p = ksba_name_get_uri (name, idx);
591 es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
592 es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
593 es_putc ('\n', fp);
594 xfree (p);
599 static void
600 print_utf8_extn_raw (estream_t fp, int indent,
601 const unsigned char *der, size_t derlen)
603 gpg_error_t err;
604 int class, tag, constructed, ndef;
605 size_t objlen, hdrlen;
607 if (indent < 0)
608 indent = - indent;
610 err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
611 &ndef, &objlen, &hdrlen);
612 if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
613 err = gpg_error (GPG_ERR_INV_OBJ);
614 if (err)
616 es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
617 return;
619 es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
623 static void
624 print_utf8_extn (estream_t fp, int indent,
625 const unsigned char *der, size_t derlen)
627 gpg_error_t err;
628 int class, tag, constructed, ndef;
629 size_t objlen, hdrlen;
630 int indent_all;
632 if ((indent_all = (indent < 0)))
633 indent = - indent;
635 err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
636 &ndef, &objlen, &hdrlen);
637 if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
638 err = gpg_error (GPG_ERR_INV_OBJ);
639 if (err)
641 es_fprintf (fp, "%*s[%s%s]\n",
642 indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
643 return;
645 es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
646 /* Fixme: we should implement word wrapping */
647 es_write_sanitized (fp, der, objlen, "\"", NULL);
648 es_fputs ("\"\n", fp);
652 /* List one certificate in raw mode useful to have a closer look at
653 the certificate. This one does no beautification and only minimal
654 output sanitation. It is mainly useful for debugging. */
655 static void
656 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
657 ksba_cert_t cert, estream_t fp, int have_secret,
658 int with_validation)
660 gpg_error_t err;
661 size_t off, len;
662 ksba_sexp_t sexp, keyid;
663 char *dn;
664 ksba_isotime_t t;
665 int idx, i;
666 int is_ca, chainlen;
667 unsigned int kusage;
668 char *string, *p, *pend;
669 const char *oid, *s;
670 ksba_name_t name, name2;
671 unsigned int reason;
672 const unsigned char *cert_der = NULL;
674 (void)have_secret;
676 es_fprintf (fp, " ID: 0x%08lX\n",
677 gpgsm_get_short_fingerprint (cert, NULL));
679 sexp = ksba_cert_get_serial (cert);
680 es_fputs (" S/N: ", fp);
681 gpgsm_print_serial (fp, sexp);
682 ksba_free (sexp);
683 es_putc ('\n', fp);
685 dn = ksba_cert_get_issuer (cert, 0);
686 es_fputs (" Issuer: ", fp);
687 print_name_raw (fp, dn);
688 ksba_free (dn);
689 es_putc ('\n', fp);
690 for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
692 es_fputs (" aka: ", fp);
693 print_name_raw (fp, dn);
694 ksba_free (dn);
695 es_putc ('\n', fp);
698 dn = ksba_cert_get_subject (cert, 0);
699 es_fputs (" Subject: ", fp);
700 print_name_raw (fp, dn);
701 ksba_free (dn);
702 es_putc ('\n', fp);
703 for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
705 es_fputs (" aka: ", fp);
706 print_name_raw (fp, dn);
707 ksba_free (dn);
708 es_putc ('\n', fp);
711 dn = gpgsm_get_fingerprint_string (cert, 0);
712 es_fprintf (fp, " sha1_fpr: %s\n", dn?dn:"error");
713 xfree (dn);
715 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
716 es_fprintf (fp, " md5_fpr: %s\n", dn?dn:"error");
717 xfree (dn);
719 dn = gpgsm_get_certid (cert);
720 es_fprintf (fp, " certid: %s\n", dn?dn:"error");
721 xfree (dn);
723 dn = gpgsm_get_keygrip_hexstring (cert);
724 es_fprintf (fp, " keygrip: %s\n", dn?dn:"error");
725 xfree (dn);
727 ksba_cert_get_validity (cert, 0, t);
728 es_fputs (" notBefore: ", fp);
729 gpgsm_print_time (fp, t);
730 es_putc ('\n', fp);
731 es_fputs (" notAfter: ", fp);
732 ksba_cert_get_validity (cert, 1, t);
733 gpgsm_print_time (fp, t);
734 es_putc ('\n', fp);
736 oid = ksba_cert_get_digest_algo (cert);
737 s = get_oid_desc (oid, NULL);
738 es_fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
741 const char *algoname;
742 unsigned int nbits;
744 algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
745 es_fprintf (fp, " keyType: %u bit %s\n",
746 nbits, algoname? algoname:"?");
749 /* subjectKeyIdentifier */
750 es_fputs (" subjKeyId: ", fp);
751 err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
752 if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
754 if (gpg_err_code (err) == GPG_ERR_NO_DATA)
755 es_fputs ("[none]\n", fp);
756 else
758 gpgsm_print_serial (fp, keyid);
759 ksba_free (keyid);
760 es_putc ('\n', fp);
763 else
764 es_fputs ("[?]\n", fp);
767 /* authorityKeyIdentifier */
768 es_fputs (" authKeyId: ", fp);
769 err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
770 if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
772 if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
773 es_fputs ("[none]\n", fp);
774 else
776 gpgsm_print_serial (fp, sexp);
777 ksba_free (sexp);
778 es_putc ('\n', fp);
779 print_names_raw (fp, -15, name);
780 ksba_name_release (name);
782 if (keyid)
784 es_fputs (" authKeyId.ki: ", fp);
785 gpgsm_print_serial (fp, keyid);
786 ksba_free (keyid);
787 es_putc ('\n', fp);
790 else
791 es_fputs ("[?]\n", fp);
793 es_fputs (" keyUsage:", fp);
794 err = ksba_cert_get_key_usage (cert, &kusage);
795 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
797 if (err)
798 es_fprintf (fp, " [error: %s]", gpg_strerror (err));
799 else
801 if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
802 es_fputs (" digitalSignature", fp);
803 if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
804 es_fputs (" nonRepudiation", fp);
805 if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
806 es_fputs (" keyEncipherment", fp);
807 if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
808 es_fputs (" dataEncipherment", fp);
809 if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
810 es_fputs (" keyAgreement", fp);
811 if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
812 es_fputs (" certSign", fp);
813 if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
814 es_fputs (" crlSign", fp);
815 if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
816 es_fputs (" encipherOnly", fp);
817 if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
818 es_fputs (" decipherOnly", fp);
820 es_putc ('\n', fp);
822 else
823 es_fputs (" [none]\n", fp);
825 es_fputs (" extKeyUsage: ", fp);
826 err = ksba_cert_get_ext_key_usages (cert, &string);
827 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
829 if (err)
830 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
831 else
833 p = string;
834 while (p && (pend=strchr (p, ':')))
836 *pend++ = 0;
837 for (i=0; key_purpose_map[i].oid; i++)
838 if ( !strcmp (key_purpose_map[i].oid, p) )
839 break;
840 es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
841 p = pend;
842 if (*p != 'C')
843 es_fputs (" (suggested)", fp);
844 if ((p = strchr (p, '\n')))
846 p++;
847 es_fputs ("\n ", fp);
850 xfree (string);
852 es_putc ('\n', fp);
854 else
855 es_fputs ("[none]\n", fp);
858 es_fputs (" policies: ", fp);
859 err = ksba_cert_get_cert_policies (cert, &string);
860 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
862 if (err)
863 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
864 else
866 p = string;
867 while (p && (pend=strchr (p, ':')))
869 *pend++ = 0;
870 for (i=0; key_purpose_map[i].oid; i++)
871 if ( !strcmp (key_purpose_map[i].oid, p) )
872 break;
873 es_fputs (p, fp);
874 p = pend;
875 if (*p == 'C')
876 es_fputs (" (critical)", fp);
877 if ((p = strchr (p, '\n')))
879 p++;
880 es_fputs ("\n ", fp);
883 xfree (string);
885 es_putc ('\n', fp);
887 else
888 es_fputs ("[none]\n", fp);
890 es_fputs (" chainLength: ", fp);
891 err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
892 if (err || is_ca)
894 if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
895 es_fprintf (fp, "[none]");
896 else if (err)
897 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
898 else if (chainlen == -1)
899 es_fputs ("unlimited", fp);
900 else
901 es_fprintf (fp, "%d", chainlen);
902 es_putc ('\n', fp);
904 else
905 es_fputs ("not a CA\n", fp);
908 /* CRL distribution point */
909 for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
910 &reason)) ;idx++)
912 es_fputs (" crlDP: ", fp);
913 print_names_raw (fp, 15, name);
914 if (reason)
916 es_fputs (" reason: ", fp);
917 if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
918 es_fputs (" unused", fp);
919 if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
920 es_fputs (" keyCompromise", fp);
921 if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
922 es_fputs (" caCompromise", fp);
923 if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
924 es_fputs (" affiliationChanged", fp);
925 if ( (reason & KSBA_CRLREASON_SUPERSEDED))
926 es_fputs (" superseded", fp);
927 if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
928 es_fputs (" cessationOfOperation", fp);
929 if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
930 es_fputs (" certificateHold", fp);
931 es_putc ('\n', fp);
933 es_fputs (" issuer: ", fp);
934 print_names_raw (fp, 23, name2);
935 ksba_name_release (name);
936 ksba_name_release (name2);
938 if (err && gpg_err_code (err) != GPG_ERR_EOF
939 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
940 es_fputs (" crlDP: [error]\n", fp);
941 else if (!idx)
942 es_fputs (" crlDP: [none]\n", fp);
945 /* authorityInfoAccess. */
946 for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
947 &name)); idx++)
949 es_fputs (" authInfo: ", fp);
950 s = get_oid_desc (string, NULL);
951 es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
952 print_names_raw (fp, -15, name);
953 ksba_name_release (name);
954 ksba_free (string);
956 if (err && gpg_err_code (err) != GPG_ERR_EOF
957 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
958 es_fputs (" authInfo: [error]\n", fp);
959 else if (!idx)
960 es_fputs (" authInfo: [none]\n", fp);
962 /* subjectInfoAccess. */
963 for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
964 &name)); idx++)
966 es_fputs (" subjectInfo: ", fp);
967 s = get_oid_desc (string, NULL);
968 es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
969 print_names_raw (fp, -15, name);
970 ksba_name_release (name);
971 ksba_free (string);
973 if (err && gpg_err_code (err) != GPG_ERR_EOF
974 && gpg_err_code (err) != GPG_ERR_NO_VALUE)
975 es_fputs (" subjInfo: [error]\n", fp);
976 else if (!idx)
977 es_fputs (" subjInfo: [none]\n", fp);
980 for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
981 &oid, &i, &off, &len));idx++)
983 unsigned int flag;
985 s = get_oid_desc (oid, &flag);
986 if ((flag & OID_FLAG_SKIP))
987 continue;
989 es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n",
990 i? "critExtn":" extn",
991 oid, s?" (":"", s?s:"", s?")":"", (int)len);
992 if ((flag & OID_FLAG_UTF8))
994 if (!cert_der)
995 cert_der = ksba_cert_get_image (cert, NULL);
996 assert (cert_der);
997 print_utf8_extn_raw (fp, -15, cert_der+off, len);
1002 if (with_validation)
1004 err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1005 if (!err)
1006 es_fprintf (fp, " [certificate is good]\n");
1007 else
1008 es_fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
1011 if (hd)
1013 unsigned int blobflags;
1015 err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
1016 if (err)
1017 es_fprintf (fp, " [error getting keyflags: %s]\n",gpg_strerror (err));
1018 else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1019 es_fprintf (fp, " [stored as ephemeral]\n");
1027 /* List one certificate in standard mode */
1028 static void
1029 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1030 int with_validation)
1032 gpg_error_t err;
1033 ksba_sexp_t sexp;
1034 char *dn;
1035 ksba_isotime_t t;
1036 int idx, i;
1037 int is_ca, chainlen;
1038 unsigned int kusage;
1039 char *string, *p, *pend;
1040 size_t off, len;
1041 const char *oid;
1042 const unsigned char *cert_der = NULL;
1045 es_fprintf (fp, " ID: 0x%08lX\n",
1046 gpgsm_get_short_fingerprint (cert, NULL));
1048 sexp = ksba_cert_get_serial (cert);
1049 es_fputs (" S/N: ", fp);
1050 gpgsm_print_serial (fp, sexp);
1051 ksba_free (sexp);
1052 es_putc ('\n', fp);
1054 dn = ksba_cert_get_issuer (cert, 0);
1055 es_fputs (" Issuer: ", fp);
1056 gpgsm_es_print_name (fp, dn);
1057 ksba_free (dn);
1058 es_putc ('\n', fp);
1059 for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1061 es_fputs (" aka: ", fp);
1062 gpgsm_es_print_name (fp, dn);
1063 ksba_free (dn);
1064 es_putc ('\n', fp);
1067 dn = ksba_cert_get_subject (cert, 0);
1068 es_fputs (" Subject: ", fp);
1069 gpgsm_es_print_name (fp, dn);
1070 ksba_free (dn);
1071 es_putc ('\n', fp);
1072 for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1074 es_fputs (" aka: ", fp);
1075 gpgsm_es_print_name (fp, dn);
1076 ksba_free (dn);
1077 es_putc ('\n', fp);
1080 ksba_cert_get_validity (cert, 0, t);
1081 es_fputs (" validity: ", fp);
1082 gpgsm_print_time (fp, t);
1083 es_fputs (" through ", fp);
1084 ksba_cert_get_validity (cert, 1, t);
1085 gpgsm_print_time (fp, t);
1086 es_putc ('\n', fp);
1090 const char *algoname;
1091 unsigned int nbits;
1093 algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1094 es_fprintf (fp, " key type: %u bit %s\n",
1095 nbits, algoname? algoname:"?");
1099 err = ksba_cert_get_key_usage (cert, &kusage);
1100 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1102 es_fputs (" key usage:", fp);
1103 if (err)
1104 es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1105 else
1107 if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1108 es_fputs (" digitalSignature", fp);
1109 if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
1110 es_fputs (" nonRepudiation", fp);
1111 if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
1112 es_fputs (" keyEncipherment", fp);
1113 if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1114 es_fputs (" dataEncipherment", fp);
1115 if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
1116 es_fputs (" keyAgreement", fp);
1117 if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1118 es_fputs (" certSign", fp);
1119 if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
1120 es_fputs (" crlSign", fp);
1121 if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1122 es_fputs (" encipherOnly", fp);
1123 if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
1124 es_fputs (" decipherOnly", fp);
1126 es_putc ('\n', fp);
1129 err = ksba_cert_get_ext_key_usages (cert, &string);
1130 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1132 es_fputs ("ext key usage: ", fp);
1133 if (err)
1134 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1135 else
1137 p = string;
1138 while (p && (pend=strchr (p, ':')))
1140 *pend++ = 0;
1141 for (i=0; key_purpose_map[i].oid; i++)
1142 if ( !strcmp (key_purpose_map[i].oid, p) )
1143 break;
1144 es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1145 p = pend;
1146 if (*p != 'C')
1147 es_fputs (" (suggested)", fp);
1148 if ((p = strchr (p, '\n')))
1150 p++;
1151 es_fputs (", ", fp);
1154 xfree (string);
1156 es_putc ('\n', fp);
1159 /* Print restrictions. */
1160 for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1161 &oid, NULL, &off, &len));idx++)
1163 if (!strcmp (oid, OIDSTR_restriction) )
1165 if (!cert_der)
1166 cert_der = ksba_cert_get_image (cert, NULL);
1167 assert (cert_der);
1168 es_fputs (" restriction: ", fp);
1169 print_utf8_extn (fp, 15, cert_der+off, len);
1173 /* Print policies. */
1174 err = ksba_cert_get_cert_policies (cert, &string);
1175 if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1177 es_fputs (" policies: ", fp);
1178 if (err)
1179 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1180 else
1182 for (p=string; *p; p++)
1184 if (*p == '\n')
1185 *p = ',';
1187 es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1188 xfree (string);
1190 es_putc ('\n', fp);
1193 err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1194 if (err || is_ca)
1196 es_fputs (" chain length: ", fp);
1197 if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1198 es_fprintf (fp, "none");
1199 else if (err)
1200 es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1201 else if (chainlen == -1)
1202 es_fputs ("unlimited", fp);
1203 else
1204 es_fprintf (fp, "%d", chainlen);
1205 es_putc ('\n', fp);
1208 if (opt.with_md5_fingerprint)
1210 dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1211 es_fprintf (fp, " md5 fpr: %s\n", dn?dn:"error");
1212 xfree (dn);
1215 dn = gpgsm_get_fingerprint_string (cert, 0);
1216 es_fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
1217 xfree (dn);
1219 if (have_secret)
1221 char *cardsn;
1223 p = gpgsm_get_keygrip_hexstring (cert);
1224 if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
1225 es_fprintf (fp, " card s/n: %s\n", cardsn);
1226 xfree (cardsn);
1227 xfree (p);
1230 if (with_validation)
1232 gpg_error_t tmperr;
1233 size_t buflen;
1234 char buffer[1];
1236 err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1237 tmperr = ksba_cert_get_user_data (cert, "is_qualified",
1238 &buffer, sizeof (buffer), &buflen);
1239 if (!tmperr && buflen)
1241 if (*buffer)
1242 es_fputs (" [qualified]\n", fp);
1244 else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1245 ; /* Don't know - will not get marked as 'q' */
1246 else
1247 log_debug ("get_user_data(is_qualified) failed: %s\n",
1248 gpg_strerror (tmperr));
1250 if (!err)
1251 es_fprintf (fp, " [certificate is good]\n");
1252 else
1253 es_fprintf (fp, " [certificate is bad: %s]\n", gpg_strerror (err));
1258 /* Same as standard mode mode list all certifying certs too. */
1259 static void
1260 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1261 ksba_cert_t cert, int raw_mode,
1262 estream_t fp, int with_validation)
1264 ksba_cert_t next = NULL;
1266 if (raw_mode)
1267 list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1268 else
1269 list_cert_std (ctrl, cert, fp, 0, with_validation);
1270 ksba_cert_ref (cert);
1271 while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1273 ksba_cert_release (cert);
1274 es_fputs ("Certified by\n", fp);
1275 if (raw_mode)
1276 list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1277 else
1278 list_cert_std (ctrl, next, fp, 0, with_validation);
1279 cert = next;
1281 ksba_cert_release (cert);
1282 es_putc ('\n', fp);
1287 /* List all internal keys or just the keys given as NAMES. MODE is a
1288 bit vector to specify what keys are to be included; see
1289 gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
1290 output mode will be used instead of the standard beautified one.
1292 static gpg_error_t
1293 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1294 unsigned int mode, int raw_mode)
1296 KEYDB_HANDLE hd;
1297 KEYDB_SEARCH_DESC *desc = NULL;
1298 strlist_t sl;
1299 int ndesc;
1300 ksba_cert_t cert = NULL;
1301 ksba_cert_t lastcert = NULL;
1302 gpg_error_t rc = 0;
1303 const char *lastresname, *resname;
1304 int have_secret;
1305 int want_ephemeral = ctrl->with_ephemeral_keys;
1307 hd = keydb_new (0);
1308 if (!hd)
1310 log_error ("keydb_new failed\n");
1311 rc = gpg_error (GPG_ERR_GENERAL);
1312 goto leave;
1315 if (!names)
1316 ndesc = 1;
1317 else
1319 for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1323 desc = xtrycalloc (ndesc, sizeof *desc);
1324 if (!ndesc)
1326 rc = gpg_error_from_syserror ();
1327 log_error ("out of core\n");
1328 goto leave;
1331 if (!names)
1332 desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1333 else
1335 for (ndesc=0, sl=names; sl; sl = sl->next)
1337 rc = keydb_classify_name (sl->d, desc+ndesc);
1338 if (rc)
1340 log_error ("key `%s' not found: %s\n",
1341 sl->d, gpg_strerror (rc));
1342 rc = 0;
1344 else
1345 ndesc++;
1350 /* If all specifications are done by fingerprint or keygrip, we
1351 switch to ephemeral mode so that _all_ currently available and
1352 matching certificates are listed. */
1353 if (!want_ephemeral && names && ndesc)
1355 int i;
1357 for (i=0; (i < ndesc
1358 && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
1359 || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
1360 || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
1361 || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
1363 if (i == ndesc)
1364 want_ephemeral = 1;
1367 if (want_ephemeral)
1368 keydb_set_ephemeral (hd, 1);
1370 /* It would be nice to see which of the given users did actually
1371 match one in the keyring. To implement this we need to have a
1372 found flag for each entry in desc and to set this we must check
1373 all those entries after a match to mark all matched one -
1374 currently we stop at the first match. To do this we need an
1375 extra flag to enable this feature so */
1377 /* Suppress duplicates at least when they follow each other. */
1378 lastresname = NULL;
1379 while (!(rc = keydb_search (hd, desc, ndesc)))
1381 unsigned int validity;
1383 if (!names)
1384 desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1386 rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1387 if (rc)
1389 log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1390 goto leave;
1392 rc = keydb_get_cert (hd, &cert);
1393 if (rc)
1395 log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1396 goto leave;
1398 /* Skip duplicated certificates, at least if they follow each
1399 others. This works best if a single key is searched for and
1400 expected. FIXME: Non-sequential duplicates remain. */
1401 if (gpgsm_certs_identical_p (cert, lastcert))
1403 ksba_cert_release (cert);
1404 cert = NULL;
1405 continue;
1408 resname = keydb_get_resource_name (hd);
1410 if (lastresname != resname )
1412 int i;
1414 if (ctrl->no_server)
1416 es_fprintf (fp, "%s\n", resname );
1417 for (i=strlen(resname); i; i-- )
1418 es_putc ('-', fp);
1419 es_putc ('\n', fp);
1420 lastresname = resname;
1424 have_secret = 0;
1425 if (mode)
1427 char *p = gpgsm_get_keygrip_hexstring (cert);
1428 if (p)
1430 rc = gpgsm_agent_havekey (ctrl, p);
1431 if (!rc)
1432 have_secret = 1;
1433 else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1434 goto leave;
1435 rc = 0;
1436 xfree (p);
1440 if (!mode
1441 || ((mode & 1) && !have_secret)
1442 || ((mode & 2) && have_secret) )
1444 if (ctrl->with_colons)
1445 list_cert_colon (ctrl, cert, validity, fp, have_secret);
1446 else if (ctrl->with_chain)
1447 list_cert_chain (ctrl, hd, cert,
1448 raw_mode, fp, ctrl->with_validation);
1449 else
1451 if (raw_mode)
1452 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1453 ctrl->with_validation);
1454 else
1455 list_cert_std (ctrl, cert, fp, have_secret,
1456 ctrl->with_validation);
1457 es_putc ('\n', fp);
1461 ksba_cert_release (lastcert);
1462 lastcert = cert;
1463 cert = NULL;
1465 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1466 rc = 0;
1467 if (rc)
1468 log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1470 leave:
1471 ksba_cert_release (cert);
1472 ksba_cert_release (lastcert);
1473 xfree (desc);
1474 keydb_release (hd);
1475 return rc;
1480 static void
1481 list_external_cb (void *cb_value, ksba_cert_t cert)
1483 struct list_external_parm_s *parm = cb_value;
1485 if (keydb_store_cert (cert, 1, NULL))
1486 log_error ("error storing certificate as ephemeral\n");
1488 if (parm->print_header)
1490 const char *resname = "[external keys]";
1491 int i;
1493 es_fprintf (parm->fp, "%s\n", resname );
1494 for (i=strlen(resname); i; i-- )
1495 es_putc('-', parm->fp);
1496 es_putc ('\n', parm->fp);
1497 parm->print_header = 0;
1500 if (parm->with_colons)
1501 list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1502 else if (parm->with_chain)
1503 list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1504 else
1506 if (parm->raw_mode)
1507 list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1508 else
1509 list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1510 es_putc ('\n', parm->fp);
1515 /* List external keys similar to internal one. Note: mode does not
1516 make sense here because it would be unwise to list external secret
1517 keys */
1518 static gpg_error_t
1519 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1521 int rc;
1522 struct list_external_parm_s parm;
1524 parm.fp = fp;
1525 parm.ctrl = ctrl,
1526 parm.print_header = ctrl->no_server;
1527 parm.with_colons = ctrl->with_colons;
1528 parm.with_chain = ctrl->with_chain;
1529 parm.raw_mode = raw_mode;
1531 rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
1532 if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
1533 || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1534 rc = 0; /* "Not found" is not an error here. */
1535 if (rc)
1536 log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1537 return rc;
1540 /* List all keys or just the key given as NAMES.
1541 MODE controls the operation mode:
1542 Bit 0-2:
1543 0 = list all public keys but don't flag secret ones
1544 1 = list only public keys
1545 2 = list only secret keys
1546 3 = list secret and public keys
1547 Bit 6: list internal keys
1548 Bit 7: list external keys
1549 Bit 8: Do a raw format dump.
1551 gpg_error_t
1552 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1553 unsigned int mode)
1555 gpg_error_t err = 0;
1557 if ((mode & (1<<6)))
1558 err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1559 if (!err && (mode & (1<<7)))
1560 err = list_external_keys (ctrl, names, fp, (mode&256));
1561 return err;