chiark / gitweb /
build: Enable gcc warnings to detect non-portable code.
[gnupg2.git] / sm / keylist.c
1 /* keylist.c - Print certificates in various formats.
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2008, 2009,
3  *               2010, 2011 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
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.
11  *
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.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
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>
29
30 #include "gpgsm.h"
31
32 #include <gcrypt.h>
33 #include <ksba.h>
34
35 #include "keydb.h"
36 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
37 #include "i18n.h"
38 #include "tlv.h"
39
40 struct list_external_parm_s
41 {
42   ctrl_t ctrl;
43   estream_t fp;
44   int print_header;
45   int with_colons;
46   int with_chain;
47   int raw_mode;
48 };
49
50
51 /* This table is to map Extended Key Usage OIDs to human readable
52    names.  */
53 struct
54 {
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" },
71
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. */
74
75   { "1.3.6.1.5.5.7.48.1.5", "ocspNoCheck" },
76
77   { NULL, NULL }
78 };
79
80
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
86
87 /* A table mapping OIDs to a descriptive string. */
88 static struct
89 {
90   char *oid;
91   char *name;
92   unsigned int flag; /* A flag as described above.  */
93 } oidtranstbl[] = {
94
95   /* Algorithms. */
96   { "1.2.840.10040.4.1", "dsa" },
97   { "1.2.840.10040.4.3", "dsaWithSha1" },
98
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" },
111
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" },
115
116
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 },
128
129
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" },
142
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" },
147
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" },
173
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" },
186
187   /* GnuPG extensions */
188   { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
189   { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" },
190   { "1.3.6.1.4.1.11591.2.2.2", "wellKnownPrivateKey" },
191
192   /* Extensions used by the Bundesnetzagentur.  */
193   { "1.3.6.1.4.1.8301.3.5", "validityModel" },
194
195   { NULL }
196 };
197
198
199 /* Return the description for OID; if no description is available
200    NULL is returned. */
201 static const char *
202 get_oid_desc (const char *oid, unsigned int *flag)
203 {
204   int i;
205
206   if (oid)
207     for (i=0; oidtranstbl[i].oid; i++)
208       if (!strcmp (oidtranstbl[i].oid, oid))
209         {
210           if (flag)
211             *flag = oidtranstbl[i].flag;
212           return oidtranstbl[i].name;
213         }
214   if (flag)
215     *flag = 0;
216   return NULL;
217 }
218
219
220 static void
221 print_key_data (ksba_cert_t cert, estream_t fp)
222 {
223 #if 0
224   int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
225   int i;
226
227   for(i=0; i < n; i++ )
228     {
229       es_fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
230       mpi_print(stdout, pk->pkey[i], 1 );
231       putchar(':');
232       putchar('\n');
233     }
234 #else
235   (void)cert;
236   (void)fp;
237 #endif
238 }
239
240 static void
241 print_capabilities (ksba_cert_t cert, estream_t fp)
242 {
243   gpg_error_t err;
244   unsigned int use;
245   size_t buflen;
246   char buffer[1];
247
248   err = ksba_cert_get_user_data (cert, "is_qualified",
249                                  &buffer, sizeof (buffer), &buflen);
250   if (!err && buflen)
251     {
252       if (*buffer)
253         es_putc ('q', fp);
254     }
255   else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
256     ; /* Don't know - will not get marked as 'q' */
257   else
258     log_debug ("get_user_data(is_qualified) failed: %s\n",
259                gpg_strerror (err));
260
261   err = ksba_cert_get_key_usage (cert, &use);
262   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
263     {
264       es_putc ('e', fp);
265       es_putc ('s', fp);
266       es_putc ('c', fp);
267       es_putc ('E', fp);
268       es_putc ('S', fp);
269       es_putc ('C', fp);
270       return;
271     }
272   if (err)
273     {
274       log_error (_("error getting key usage information: %s\n"),
275                  gpg_strerror (err));
276       return;
277     }
278
279   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
280     es_putc ('e', fp);
281   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
282     es_putc ('s', fp);
283   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
284     es_putc ('c', fp);
285   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
286     es_putc ('E', fp);
287   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
288     es_putc ('S', fp);
289   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
290     es_putc ('C', fp);
291
292   es_putc (':', fp);
293 }
294
295
296 static void
297 print_time (gnupg_isotime_t t, estream_t fp)
298 {
299   if (!t || !*t)
300     ;
301   else
302     es_fputs (t, fp);
303 }
304
305
306 /* Return an allocated string with the email address extracted from a
307    DN.  Note hat we use this code also in ../kbx/keybox-blob.c.  */
308 static char *
309 email_kludge (const char *name)
310 {
311   const char *p, *string;
312   unsigned char *buf;
313   int n;
314
315   string = name;
316   for (;;)
317     {
318       p = strstr (string, "1.2.840.113549.1.9.1=#");
319       if (!p)
320         return NULL;
321       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
322         {
323           name = p + 22;
324           break;
325         }
326       string = p + 22;
327     }
328
329
330   /* This looks pretty much like an email address in the subject's DN
331      we use this to add an additional user ID entry.  This way,
332      OpenSSL generated keys get a nicer and usable listing.  */
333   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
334     ;
335   if (!n)
336     return NULL;
337   buf = xtrymalloc (n+3);
338   if (!buf)
339     return NULL; /* oops, out of core */
340   *buf = '<';
341   for (n=1, p=name; hexdigitp (p); p +=2, n++)
342     buf[n] = xtoi_2 (p);
343   buf[n++] = '>';
344   buf[n] = 0;
345   return (char*)buf;
346 }
347
348
349
350
351 /* List one certificate in colon mode */
352 static void
353 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
354                  estream_t fp, int have_secret)
355 {
356   int rc;
357   int idx;
358   char truststring[2];
359   char *p;
360   ksba_sexp_t sexp;
361   char *fpr;
362   ksba_isotime_t t;
363   gpg_error_t valerr;
364   int algo;
365   unsigned int nbits;
366   const char *chain_id;
367   char *chain_id_buffer = NULL;
368   int is_root = 0;
369   char *kludge_uid;
370
371   if (ctrl->with_validation)
372     valerr = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, NULL, 0, NULL);
373   else
374     valerr = 0;
375
376
377   /* We need to get the fingerprint and the chaining ID in advance. */
378   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
379   {
380     ksba_cert_t next;
381
382     rc = gpgsm_walk_cert_chain (ctrl, cert, &next);
383     if (!rc) /* We known the issuer's certificate. */
384       {
385         p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
386         chain_id_buffer = p;
387         chain_id = chain_id_buffer;
388         ksba_cert_release (next);
389       }
390     else if (rc == -1)  /* We have reached the root certificate. */
391       {
392         chain_id = fpr;
393         is_root = 1;
394       }
395     else
396       chain_id = NULL;
397   }
398
399
400   es_fputs (have_secret? "crs:":"crt:", fp);
401
402   /* Note: We can't use multiple flags, like "ei", because the
403      validation check does only return one error.  */
404   truststring[0] = 0;
405   truststring[1] = 0;
406   if ((validity & VALIDITY_REVOKED)
407       || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
408     *truststring = 'r';
409   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
410     *truststring = 'e';
411   else
412     {
413       /* Lets also check whether the certificate under question
414          expired.  This is merely a hack until we found a proper way
415          to store the expiration flag in the keybox. */
416       ksba_isotime_t current_time, not_after;
417
418       gnupg_get_isotime (current_time);
419       if (!opt.ignore_expiration
420           && !ksba_cert_get_validity (cert, 1, not_after)
421           && *not_after && strcmp (current_time, not_after) > 0 )
422         *truststring = 'e';
423       else if (valerr)
424         {
425           if (gpgsm_cert_has_well_known_private_key (cert))
426             *truststring = 'w';  /* Well, this is dummy CA.  */
427           else
428             *truststring = 'i';
429         }
430       else if (ctrl->with_validation && !is_root)
431         *truststring = 'f';
432     }
433
434   /* If we have no truststring yet (i.e. the certificate might be
435      good) and this is a root certificate, we ask the agent whether
436      this is a trusted root certificate. */
437   if (!*truststring && is_root)
438     {
439       struct rootca_flags_s dummy_flags;
440
441       if (gpgsm_cert_has_well_known_private_key (cert))
442         *truststring = 'w';  /* Well, this is dummy CA.  */
443       else
444         {
445           rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
446           if (!rc)
447             *truststring = 'u';  /* Yes, we trust this one (ultimately). */
448           else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
449             *truststring = 'n';  /* No, we do not trust this one. */
450           /* (in case of an error we can't tell anything.) */
451         }
452     }
453
454   if (*truststring)
455     es_fputs (truststring, fp);
456
457   algo = gpgsm_get_key_algo_info (cert, &nbits);
458   es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
459
460   ksba_cert_get_validity (cert, 0, t);
461   print_time (t, fp);
462   es_putc (':', fp);
463   ksba_cert_get_validity (cert, 1, t);
464   print_time ( t, fp);
465   es_putc (':', fp);
466   /* Field 8, serial number: */
467   if ((sexp = ksba_cert_get_serial (cert)))
468     {
469       int len;
470       const unsigned char *s = sexp;
471
472       if (*s == '(')
473         {
474           s++;
475           for (len=0; *s && *s != ':' && digitp (s); s++)
476             len = len*10 + atoi_1 (s);
477           if (*s == ':')
478             for (s++; len; len--, s++)
479               es_fprintf (fp,"%02X", *s);
480         }
481       xfree (sexp);
482     }
483   es_putc (':', fp);
484   /* Field 9, ownertrust - not used here */
485   es_putc (':', fp);
486   /* field 10, old user ID - we use it here for the issuer DN */
487   if ((p = ksba_cert_get_issuer (cert,0)))
488     {
489       es_write_sanitized (fp, p, strlen (p), ":", NULL);
490       xfree (p);
491     }
492   es_putc (':', fp);
493   /* Field 11, signature class - not used */
494   es_putc (':', fp);
495   /* Field 12, capabilities: */
496   print_capabilities (cert, fp);
497   /* Field 13, not used: */
498   es_putc (':', fp);
499   if (have_secret || ctrl->with_secret)
500     {
501       char *cardsn;
502
503       p = gpgsm_get_keygrip_hexstring (cert);
504       if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn)
505           && (cardsn || ctrl->with_secret))
506         {
507           /* Field 14, not used: */
508           es_putc (':', fp);
509           /* Field 15:  Token serial number or secret key indicator.  */
510           if (cardsn)
511             es_fputs (cardsn, fp);
512           else if (ctrl->with_secret)
513             es_putc ('+', fp);
514           es_putc (':', fp);
515         }
516       xfree (cardsn);
517       xfree (p);
518     }
519   es_putc ('\n', fp);
520
521   /* FPR record */
522   es_fprintf (fp, "fpr:::::::::%s:::", fpr);
523   /* Print chaining ID (field 13)*/
524   if (chain_id)
525     es_fputs (chain_id, fp);
526   es_putc (':', fp);
527   es_putc ('\n', fp);
528   xfree (fpr); fpr = NULL; chain_id = NULL;
529   xfree (chain_id_buffer); chain_id_buffer = NULL;
530
531   if (opt.with_key_data)
532     {
533       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
534         {
535           es_fprintf (fp, "grp:::::::::%s:\n", p);
536           xfree (p);
537         }
538       print_key_data (cert, fp);
539     }
540
541   kludge_uid = NULL;
542   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
543     {
544       /* In the case that the same email address is in the subject DN
545          as well as in an alternate subject name we avoid printing it
546          a second time. */
547       if (kludge_uid && !strcmp (kludge_uid, p))
548         continue;
549
550       es_fprintf (fp, "uid:%s::::::::", truststring);
551       es_write_sanitized (fp, p, strlen (p), ":", NULL);
552       es_putc (':', fp);
553       es_putc (':', fp);
554       es_putc ('\n', fp);
555       if (!idx)
556         {
557           /* It would be better to get the faked email address from
558              the keydb.  But as long as we don't have a way to pass
559              the meta data back, we just check it the same way as the
560              code used to create the keybox meta data does */
561           kludge_uid = email_kludge (p);
562           if (kludge_uid)
563             {
564               es_fprintf (fp, "uid:%s::::::::", truststring);
565               es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
566                                   ":", NULL);
567               es_putc (':', fp);
568               es_putc (':', fp);
569               es_putc ('\n', fp);
570             }
571         }
572       xfree (p);
573     }
574   xfree (kludge_uid);
575 }
576
577
578 static void
579 print_name_raw (estream_t fp, const char *string)
580 {
581   if (!string)
582     es_fputs ("[error]", fp);
583   else
584     es_write_sanitized (fp, string, strlen (string), NULL, NULL);
585 }
586
587 static void
588 print_names_raw (estream_t fp, int indent, ksba_name_t name)
589 {
590   int idx;
591   const char *s;
592   int indent_all;
593
594   if ((indent_all = (indent < 0)))
595     indent = - indent;
596
597   if (!name)
598     {
599       es_fputs ("none\n", fp);
600       return;
601     }
602
603   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
604     {
605       char *p = ksba_name_get_uri (name, idx);
606       es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
607       es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
608       es_putc ('\n', fp);
609       xfree (p);
610     }
611 }
612
613
614 static void
615 print_utf8_extn_raw (estream_t fp, int indent,
616                      const unsigned char *der, size_t derlen)
617 {
618   gpg_error_t err;
619   int class, tag, constructed, ndef;
620   size_t objlen, hdrlen;
621
622   if (indent < 0)
623     indent = - indent;
624
625   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
626                           &ndef, &objlen, &hdrlen);
627   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
628     err = gpg_error (GPG_ERR_INV_OBJ);
629   if (err)
630     {
631       es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
632       return;
633     }
634   es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
635 }
636
637
638 static void
639 print_utf8_extn (estream_t fp, int indent,
640                  const unsigned char *der, size_t derlen)
641 {
642   gpg_error_t err;
643   int class, tag, constructed, ndef;
644   size_t objlen, hdrlen;
645   int indent_all;
646
647   if ((indent_all = (indent < 0)))
648     indent = - indent;
649
650   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
651                           &ndef, &objlen, &hdrlen);
652   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
653     err = gpg_error (GPG_ERR_INV_OBJ);
654   if (err)
655     {
656       es_fprintf (fp, "%*s[%s%s]\n",
657                   indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
658       return;
659     }
660   es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
661   /* Fixme: we should implement word wrapping */
662   es_write_sanitized (fp, der, objlen, "\"", NULL);
663   es_fputs ("\"\n", fp);
664 }
665
666
667 /* List one certificate in raw mode useful to have a closer look at
668    the certificate.  This one does no beautification and only minimal
669    output sanitation.  It is mainly useful for debugging. */
670 static void
671 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
672                ksba_cert_t cert, estream_t fp, int have_secret,
673                int with_validation)
674 {
675   gpg_error_t err;
676   size_t off, len;
677   ksba_sexp_t sexp, keyid;
678   char *dn;
679   ksba_isotime_t t;
680   int idx, i;
681   int is_ca, chainlen;
682   unsigned int kusage;
683   char *string, *p, *pend;
684   const char *oid, *s;
685   ksba_name_t name, name2;
686   unsigned int reason;
687   const unsigned char *cert_der = NULL;
688
689   (void)have_secret;
690
691   es_fprintf (fp, "           ID: 0x%08lX\n",
692               gpgsm_get_short_fingerprint (cert, NULL));
693
694   sexp = ksba_cert_get_serial (cert);
695   es_fputs ("          S/N: ", fp);
696   gpgsm_print_serial (fp, sexp);
697   ksba_free (sexp);
698   es_putc ('\n', fp);
699
700   dn = ksba_cert_get_issuer (cert, 0);
701   es_fputs ("       Issuer: ", fp);
702   print_name_raw (fp, dn);
703   ksba_free (dn);
704   es_putc ('\n', fp);
705   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
706     {
707       es_fputs ("          aka: ", fp);
708       print_name_raw (fp, dn);
709       ksba_free (dn);
710       es_putc ('\n', fp);
711     }
712
713   dn = ksba_cert_get_subject (cert, 0);
714   es_fputs ("      Subject: ", fp);
715   print_name_raw (fp, dn);
716   ksba_free (dn);
717   es_putc ('\n', fp);
718   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
719     {
720       es_fputs ("          aka: ", fp);
721       print_name_raw (fp, dn);
722       ksba_free (dn);
723       es_putc ('\n', fp);
724     }
725
726   dn = gpgsm_get_fingerprint_string (cert, 0);
727   es_fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
728   xfree (dn);
729
730   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
731   es_fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
732   xfree (dn);
733
734   dn = gpgsm_get_certid (cert);
735   es_fprintf (fp, "       certid: %s\n", dn?dn:"error");
736   xfree (dn);
737
738   dn = gpgsm_get_keygrip_hexstring (cert);
739   es_fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
740   xfree (dn);
741
742   ksba_cert_get_validity (cert, 0, t);
743   es_fputs ("    notBefore: ", fp);
744   gpgsm_print_time (fp, t);
745   es_putc ('\n', fp);
746   es_fputs ("     notAfter: ", fp);
747   ksba_cert_get_validity (cert, 1, t);
748   gpgsm_print_time (fp, t);
749   es_putc ('\n', fp);
750
751   oid = ksba_cert_get_digest_algo (cert);
752   s = get_oid_desc (oid, NULL);
753   es_fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
754
755   {
756     const char *algoname;
757     unsigned int nbits;
758
759     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
760     es_fprintf (fp, "      keyType: %u bit %s\n",
761                 nbits, algoname? algoname:"?");
762   }
763
764   /* subjectKeyIdentifier */
765   es_fputs ("    subjKeyId: ", fp);
766   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
767   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
768     {
769       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
770         es_fputs ("[none]\n", fp);
771       else
772         {
773           gpgsm_print_serial (fp, keyid);
774           ksba_free (keyid);
775           es_putc ('\n', fp);
776         }
777     }
778   else
779     es_fputs ("[?]\n", fp);
780
781
782   /* authorityKeyIdentifier */
783   es_fputs ("    authKeyId: ", fp);
784   err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
785   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
786     {
787       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
788         es_fputs ("[none]\n", fp);
789       else
790         {
791           gpgsm_print_serial (fp, sexp);
792           ksba_free (sexp);
793           es_putc ('\n', fp);
794           print_names_raw (fp, -15, name);
795           ksba_name_release (name);
796         }
797       if (keyid)
798         {
799           es_fputs (" authKeyId.ki: ", fp);
800           gpgsm_print_serial (fp, keyid);
801           ksba_free (keyid);
802           es_putc ('\n', fp);
803         }
804     }
805   else
806     es_fputs ("[?]\n", fp);
807
808   es_fputs ("     keyUsage:", fp);
809   err = ksba_cert_get_key_usage (cert, &kusage);
810   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
811     {
812       if (err)
813         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
814       else
815         {
816           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
817             es_fputs (" digitalSignature", fp);
818           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
819             es_fputs (" nonRepudiation", fp);
820           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
821             es_fputs (" keyEncipherment", fp);
822           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
823             es_fputs (" dataEncipherment", fp);
824           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
825             es_fputs (" keyAgreement", fp);
826           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
827             es_fputs (" certSign", fp);
828           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
829             es_fputs (" crlSign", fp);
830           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
831             es_fputs (" encipherOnly", fp);
832           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
833             es_fputs (" decipherOnly", fp);
834         }
835       es_putc ('\n', fp);
836     }
837   else
838     es_fputs (" [none]\n", fp);
839
840   es_fputs ("  extKeyUsage: ", fp);
841   err = ksba_cert_get_ext_key_usages (cert, &string);
842   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
843     {
844       if (err)
845         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
846       else
847         {
848           p = string;
849           while (p && (pend=strchr (p, ':')))
850             {
851               *pend++ = 0;
852               for (i=0; key_purpose_map[i].oid; i++)
853                 if ( !strcmp (key_purpose_map[i].oid, p) )
854                   break;
855               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
856               p = pend;
857               if (*p != 'C')
858                 es_fputs (" (suggested)", fp);
859               if ((p = strchr (p, '\n')))
860                 {
861                   p++;
862                   es_fputs ("\n               ", fp);
863                 }
864             }
865           xfree (string);
866         }
867       es_putc ('\n', fp);
868     }
869   else
870     es_fputs ("[none]\n", fp);
871
872
873   es_fputs ("     policies: ", fp);
874   err = ksba_cert_get_cert_policies (cert, &string);
875   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
876     {
877       if (err)
878         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
879       else
880         {
881           p = string;
882           while (p && (pend=strchr (p, ':')))
883             {
884               *pend++ = 0;
885               for (i=0; key_purpose_map[i].oid; i++)
886                 if ( !strcmp (key_purpose_map[i].oid, p) )
887                   break;
888               es_fputs (p, fp);
889               p = pend;
890               if (*p == 'C')
891                 es_fputs (" (critical)", fp);
892               if ((p = strchr (p, '\n')))
893                 {
894                   p++;
895                   es_fputs ("\n               ", fp);
896                 }
897             }
898           xfree (string);
899         }
900       es_putc ('\n', fp);
901     }
902   else
903     es_fputs ("[none]\n", fp);
904
905   es_fputs ("  chainLength: ", fp);
906   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
907   if (err || is_ca)
908     {
909       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
910         es_fprintf (fp, "[none]");
911       else if (err)
912         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
913       else if (chainlen == -1)
914         es_fputs ("unlimited", fp);
915       else
916         es_fprintf (fp, "%d", chainlen);
917       es_putc ('\n', fp);
918     }
919   else
920     es_fputs ("not a CA\n", fp);
921
922
923   /* CRL distribution point */
924   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
925                                                   &reason)) ;idx++)
926     {
927       es_fputs ("        crlDP: ", fp);
928       print_names_raw (fp, 15, name);
929       if (reason)
930         {
931           es_fputs ("               reason: ", fp);
932           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
933             es_fputs (" unused", fp);
934           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
935             es_fputs (" keyCompromise", fp);
936           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
937             es_fputs (" caCompromise", fp);
938           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
939             es_fputs (" affiliationChanged", fp);
940           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
941             es_fputs (" superseded", fp);
942           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
943             es_fputs (" cessationOfOperation", fp);
944           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
945             es_fputs (" certificateHold", fp);
946           es_putc ('\n', fp);
947         }
948       es_fputs ("               issuer: ", fp);
949       print_names_raw (fp, 23, name2);
950       ksba_name_release (name);
951       ksba_name_release (name2);
952     }
953   if (err && gpg_err_code (err) != GPG_ERR_EOF
954       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
955     es_fputs ("        crlDP: [error]\n", fp);
956   else if (!idx)
957     es_fputs ("        crlDP: [none]\n", fp);
958
959
960   /* authorityInfoAccess. */
961   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
962                                                          &name)); idx++)
963     {
964       es_fputs ("     authInfo: ", 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);
970     }
971   if (err && gpg_err_code (err) != GPG_ERR_EOF
972       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
973     es_fputs ("     authInfo: [error]\n", fp);
974   else if (!idx)
975     es_fputs ("     authInfo: [none]\n", fp);
976
977   /* subjectInfoAccess. */
978   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
979                                                          &name)); idx++)
980     {
981       es_fputs ("  subjectInfo: ", fp);
982       s = get_oid_desc (string, NULL);
983       es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
984       print_names_raw (fp, -15, name);
985       ksba_name_release (name);
986       ksba_free (string);
987     }
988   if (err && gpg_err_code (err) != GPG_ERR_EOF
989       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
990     es_fputs ("     subjInfo: [error]\n", fp);
991   else if (!idx)
992     es_fputs ("     subjInfo: [none]\n", fp);
993
994
995   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
996                                              &oid, &i, &off, &len));idx++)
997     {
998       unsigned int flag;
999
1000       s = get_oid_desc (oid, &flag);
1001       if ((flag & OID_FLAG_SKIP))
1002         continue;
1003
1004       es_fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
1005                   i? "critExtn":"    extn",
1006                   oid, s?" (":"", s?s:"", s?")":"", (int)len);
1007       if ((flag & OID_FLAG_UTF8))
1008         {
1009           if (!cert_der)
1010             cert_der = ksba_cert_get_image (cert, NULL);
1011           assert (cert_der);
1012           print_utf8_extn_raw (fp, -15, cert_der+off, len);
1013         }
1014     }
1015
1016
1017   if (with_validation)
1018     {
1019       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1020       if (!err)
1021         es_fprintf (fp, "  [certificate is good]\n");
1022       else
1023         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1024     }
1025
1026   if (hd)
1027     {
1028       unsigned int blobflags;
1029
1030       err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
1031       if (err)
1032         es_fprintf (fp, "  [error getting keyflags: %s]\n",gpg_strerror (err));
1033       else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1034         es_fprintf (fp, "  [stored as ephemeral]\n");
1035     }
1036
1037 }
1038
1039
1040
1041
1042 /* List one certificate in standard mode */
1043 static void
1044 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1045                int with_validation)
1046 {
1047   gpg_error_t err;
1048   ksba_sexp_t sexp;
1049   char *dn;
1050   ksba_isotime_t t;
1051   int idx, i;
1052   int is_ca, chainlen;
1053   unsigned int kusage;
1054   char *string, *p, *pend;
1055   size_t off, len;
1056   const char *oid;
1057   const unsigned char *cert_der = NULL;
1058
1059
1060   es_fprintf (fp, "           ID: 0x%08lX\n",
1061               gpgsm_get_short_fingerprint (cert, NULL));
1062
1063   sexp = ksba_cert_get_serial (cert);
1064   es_fputs ("          S/N: ", fp);
1065   gpgsm_print_serial (fp, sexp);
1066   ksba_free (sexp);
1067   es_putc ('\n', fp);
1068
1069   dn = ksba_cert_get_issuer (cert, 0);
1070   es_fputs ("       Issuer: ", fp);
1071   gpgsm_es_print_name (fp, dn);
1072   ksba_free (dn);
1073   es_putc ('\n', fp);
1074   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1075     {
1076       es_fputs ("          aka: ", fp);
1077       gpgsm_es_print_name (fp, dn);
1078       ksba_free (dn);
1079       es_putc ('\n', fp);
1080     }
1081
1082   dn = ksba_cert_get_subject (cert, 0);
1083   es_fputs ("      Subject: ", fp);
1084   gpgsm_es_print_name (fp, dn);
1085   ksba_free (dn);
1086   es_putc ('\n', fp);
1087   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1088     {
1089       es_fputs ("          aka: ", fp);
1090       gpgsm_es_print_name (fp, dn);
1091       ksba_free (dn);
1092       es_putc ('\n', fp);
1093     }
1094
1095   ksba_cert_get_validity (cert, 0, t);
1096   es_fputs ("     validity: ", fp);
1097   gpgsm_print_time (fp, t);
1098   es_fputs (" through ", fp);
1099   ksba_cert_get_validity (cert, 1, t);
1100   gpgsm_print_time (fp, t);
1101   es_putc ('\n', fp);
1102
1103
1104   {
1105     const char *algoname;
1106     unsigned int nbits;
1107
1108     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1109     es_fprintf (fp, "     key type: %u bit %s\n",
1110                 nbits, algoname? algoname:"?");
1111   }
1112
1113
1114   err = ksba_cert_get_key_usage (cert, &kusage);
1115   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1116     {
1117       es_fputs ("    key usage:", fp);
1118       if (err)
1119         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1120       else
1121         {
1122           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1123             es_fputs (" digitalSignature", fp);
1124           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
1125             es_fputs (" nonRepudiation", fp);
1126           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
1127             es_fputs (" keyEncipherment", fp);
1128           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1129             es_fputs (" dataEncipherment", fp);
1130           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
1131             es_fputs (" keyAgreement", fp);
1132           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1133             es_fputs (" certSign", fp);
1134           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
1135             es_fputs (" crlSign", fp);
1136           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1137             es_fputs (" encipherOnly", fp);
1138           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
1139             es_fputs (" decipherOnly", fp);
1140         }
1141       es_putc ('\n', fp);
1142     }
1143
1144   err = ksba_cert_get_ext_key_usages (cert, &string);
1145   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1146     {
1147       es_fputs ("ext key usage: ", fp);
1148       if (err)
1149         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1150       else
1151         {
1152           p = string;
1153           while (p && (pend=strchr (p, ':')))
1154             {
1155               *pend++ = 0;
1156               for (i=0; key_purpose_map[i].oid; i++)
1157                 if ( !strcmp (key_purpose_map[i].oid, p) )
1158                   break;
1159               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1160               p = pend;
1161               if (*p != 'C')
1162                 es_fputs (" (suggested)", fp);
1163               if ((p = strchr (p, '\n')))
1164                 {
1165                   p++;
1166                   es_fputs (", ", fp);
1167                 }
1168             }
1169           xfree (string);
1170         }
1171       es_putc ('\n', fp);
1172     }
1173
1174   /* Print restrictions.  */
1175   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1176                                              &oid, NULL, &off, &len));idx++)
1177     {
1178       if (!strcmp (oid, OIDSTR_restriction) )
1179         {
1180           if (!cert_der)
1181             cert_der = ksba_cert_get_image (cert, NULL);
1182           assert (cert_der);
1183           es_fputs ("  restriction: ", fp);
1184           print_utf8_extn (fp, 15, cert_der+off, len);
1185         }
1186     }
1187
1188   /* Print policies.  */
1189   err = ksba_cert_get_cert_policies (cert, &string);
1190   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1191     {
1192       es_fputs ("     policies: ", fp);
1193       if (err)
1194         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1195       else
1196         {
1197           for (p=string; *p; p++)
1198             {
1199               if (*p == '\n')
1200                 *p = ',';
1201             }
1202           es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1203           xfree (string);
1204         }
1205       es_putc ('\n', fp);
1206     }
1207
1208   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1209   if (err || is_ca)
1210     {
1211       es_fputs (" chain length: ", fp);
1212       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1213         es_fprintf (fp, "none");
1214       else if (err)
1215         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1216       else if (chainlen == -1)
1217         es_fputs ("unlimited", fp);
1218       else
1219         es_fprintf (fp, "%d", chainlen);
1220       es_putc ('\n', fp);
1221     }
1222
1223   if (opt.with_md5_fingerprint)
1224     {
1225       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1226       es_fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
1227       xfree (dn);
1228     }
1229
1230   dn = gpgsm_get_fingerprint_string (cert, 0);
1231   es_fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
1232   xfree (dn);
1233
1234   if (opt.with_keygrip)
1235     {
1236       dn = gpgsm_get_keygrip_hexstring (cert);
1237       if (dn)
1238         {
1239           es_fprintf (fp, "      keygrip: %s\n", dn);
1240           xfree (dn);
1241         }
1242     }
1243
1244   if (have_secret)
1245     {
1246       char *cardsn;
1247
1248       p = gpgsm_get_keygrip_hexstring (cert);
1249       if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
1250         es_fprintf (fp, "     card s/n: %s\n", cardsn);
1251       xfree (cardsn);
1252       xfree (p);
1253     }
1254
1255   if (with_validation)
1256     {
1257       gpg_error_t tmperr;
1258       size_t buflen;
1259       char buffer[1];
1260
1261       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1262       tmperr = ksba_cert_get_user_data (cert, "is_qualified",
1263                                         &buffer, sizeof (buffer), &buflen);
1264       if (!tmperr && buflen)
1265         {
1266           if (*buffer)
1267             es_fputs ("  [qualified]\n", fp);
1268         }
1269       else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1270         ; /* Don't know - will not get marked as 'q' */
1271       else
1272         log_debug ("get_user_data(is_qualified) failed: %s\n",
1273                    gpg_strerror (tmperr));
1274
1275       if (!err)
1276         es_fprintf (fp, "  [certificate is good]\n");
1277       else
1278         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1279     }
1280 }
1281
1282
1283 /* Same as standard mode mode list all certifying certs too. */
1284 static void
1285 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1286                  ksba_cert_t cert, int raw_mode,
1287                  estream_t fp, int with_validation)
1288 {
1289   ksba_cert_t next = NULL;
1290
1291   if (raw_mode)
1292     list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1293   else
1294     list_cert_std (ctrl, cert, fp, 0, with_validation);
1295   ksba_cert_ref (cert);
1296   while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1297     {
1298       ksba_cert_release (cert);
1299       es_fputs ("Certified by\n", fp);
1300       if (raw_mode)
1301         list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1302       else
1303         list_cert_std (ctrl, next, fp, 0, with_validation);
1304       cert = next;
1305     }
1306   ksba_cert_release (cert);
1307   es_putc ('\n', fp);
1308 }
1309
1310
1311 \f
1312 /* List all internal keys or just the keys given as NAMES.  MODE is a
1313    bit vector to specify what keys are to be included; see
1314    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
1315    output mode will be used instead of the standard beautified one.
1316  */
1317 static gpg_error_t
1318 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1319                     unsigned int mode, int raw_mode)
1320 {
1321   KEYDB_HANDLE hd;
1322   KEYDB_SEARCH_DESC *desc = NULL;
1323   strlist_t sl;
1324   int ndesc;
1325   ksba_cert_t cert = NULL;
1326   ksba_cert_t lastcert = NULL;
1327   gpg_error_t rc = 0;
1328   const char *lastresname, *resname;
1329   int have_secret;
1330   int want_ephemeral = ctrl->with_ephemeral_keys;
1331
1332   hd = keydb_new ();
1333   if (!hd)
1334     {
1335       log_error ("keydb_new failed\n");
1336       rc = gpg_error (GPG_ERR_GENERAL);
1337       goto leave;
1338     }
1339
1340   if (!names)
1341     ndesc = 1;
1342   else
1343     {
1344       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1345         ;
1346     }
1347
1348   desc = xtrycalloc (ndesc, sizeof *desc);
1349   if (!ndesc)
1350     {
1351       rc = gpg_error_from_syserror ();
1352       log_error ("out of core\n");
1353       goto leave;
1354     }
1355
1356   if (!names)
1357     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1358   else
1359     {
1360       for (ndesc=0, sl=names; sl; sl = sl->next)
1361         {
1362           rc = classify_user_id (sl->d, desc+ndesc, 0);
1363           if (rc)
1364             {
1365               log_error ("key '%s' not found: %s\n",
1366                          sl->d, gpg_strerror (rc));
1367               rc = 0;
1368             }
1369           else
1370             ndesc++;
1371         }
1372
1373     }
1374
1375   /* If all specifications are done by fingerprint or keygrip, we
1376      switch to ephemeral mode so that _all_ currently available and
1377      matching certificates are listed.  */
1378   if (!want_ephemeral && names && ndesc)
1379     {
1380       int i;
1381
1382       for (i=0; (i < ndesc
1383                  && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
1384                      || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
1385                      || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
1386                      || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
1387         ;
1388       if (i == ndesc)
1389         want_ephemeral = 1;
1390     }
1391
1392   if (want_ephemeral)
1393     keydb_set_ephemeral (hd, 1);
1394
1395   /* It would be nice to see which of the given users did actually
1396      match one in the keyring.  To implement this we need to have a
1397      found flag for each entry in desc and to set this we must check
1398      all those entries after a match to mark all matched one -
1399      currently we stop at the first match.  To do this we need an
1400      extra flag to enable this feature so */
1401
1402   /* Suppress duplicates at least when they follow each other.  */
1403   lastresname = NULL;
1404   while (!(rc = keydb_search (ctrl, hd, desc, ndesc)))
1405     {
1406       unsigned int validity;
1407
1408       if (!names)
1409         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1410
1411       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1412       if (rc)
1413         {
1414           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1415           goto leave;
1416         }
1417       rc = keydb_get_cert (hd, &cert);
1418       if (rc)
1419         {
1420           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1421           goto leave;
1422         }
1423       /* Skip duplicated certificates, at least if they follow each
1424          others.  This works best if a single key is searched for and
1425          expected.  FIXME: Non-sequential duplicates remain.  */
1426       if (gpgsm_certs_identical_p (cert, lastcert))
1427         {
1428           ksba_cert_release (cert);
1429           cert = NULL;
1430           continue;
1431         }
1432
1433       resname = keydb_get_resource_name (hd);
1434
1435       if (lastresname != resname )
1436         {
1437           int i;
1438
1439           if (ctrl->no_server)
1440             {
1441               es_fprintf (fp, "%s\n", resname );
1442               for (i=strlen(resname); i; i-- )
1443                 es_putc ('-', fp);
1444               es_putc ('\n', fp);
1445               lastresname = resname;
1446             }
1447         }
1448
1449       have_secret = 0;
1450       if (mode)
1451         {
1452           char *p = gpgsm_get_keygrip_hexstring (cert);
1453           if (p)
1454             {
1455               rc = gpgsm_agent_havekey (ctrl, p);
1456               if (!rc)
1457                 have_secret = 1;
1458               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1459                 goto leave;
1460               rc = 0;
1461               xfree (p);
1462             }
1463         }
1464
1465       if (!mode          || ((mode & 1) && !have_secret)
1466           || ((mode & 2) && have_secret)  )
1467         {
1468           if (ctrl->with_colons)
1469             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1470           else if (ctrl->with_chain)
1471             list_cert_chain (ctrl, hd, cert,
1472                              raw_mode, fp, ctrl->with_validation);
1473           else
1474             {
1475               if (raw_mode)
1476                 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1477                                ctrl->with_validation);
1478               else
1479                 list_cert_std (ctrl, cert, fp, have_secret,
1480                                ctrl->with_validation);
1481               es_putc ('\n', fp);
1482             }
1483         }
1484
1485       ksba_cert_release (lastcert);
1486       lastcert = cert;
1487       cert = NULL;
1488     }
1489   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1490     rc = 0;
1491   if (rc)
1492     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1493
1494  leave:
1495   ksba_cert_release (cert);
1496   ksba_cert_release (lastcert);
1497   xfree (desc);
1498   keydb_release (hd);
1499   return rc;
1500 }
1501
1502
1503
1504 static void
1505 list_external_cb (void *cb_value, ksba_cert_t cert)
1506 {
1507   struct list_external_parm_s *parm = cb_value;
1508
1509   if (keydb_store_cert (parm->ctrl, cert, 1, NULL))
1510     log_error ("error storing certificate as ephemeral\n");
1511
1512   if (parm->print_header)
1513     {
1514       const char *resname = "[external keys]";
1515       int i;
1516
1517       es_fprintf (parm->fp, "%s\n", resname );
1518       for (i=strlen(resname); i; i-- )
1519         es_putc('-', parm->fp);
1520       es_putc ('\n', parm->fp);
1521       parm->print_header = 0;
1522     }
1523
1524   if (parm->with_colons)
1525     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1526   else if (parm->with_chain)
1527     list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1528   else
1529     {
1530       if (parm->raw_mode)
1531         list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1532       else
1533         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1534       es_putc ('\n', parm->fp);
1535     }
1536 }
1537
1538
1539 /* List external keys similar to internal one.  Note: mode does not
1540    make sense here because it would be unwise to list external secret
1541    keys */
1542 static gpg_error_t
1543 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1544 {
1545   int rc;
1546   struct list_external_parm_s parm;
1547
1548   parm.fp = fp;
1549   parm.ctrl = ctrl,
1550   parm.print_header = ctrl->no_server;
1551   parm.with_colons = ctrl->with_colons;
1552   parm.with_chain = ctrl->with_chain;
1553   parm.raw_mode  = raw_mode;
1554
1555   rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
1556   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
1557       || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1558     rc = 0; /* "Not found" is not an error here. */
1559   if (rc)
1560     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1561   return rc;
1562 }
1563
1564 /* List all keys or just the key given as NAMES.
1565    MODE controls the operation mode:
1566     Bit 0-2:
1567       0 = list all public keys but don't flag secret ones
1568       1 = list only public keys
1569       2 = list only secret keys
1570       3 = list secret and public keys
1571     Bit 6: list internal keys
1572     Bit 7: list external keys
1573     Bit 8: Do a raw format dump.
1574  */
1575 gpg_error_t
1576 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1577                  unsigned int mode)
1578 {
1579   gpg_error_t err = 0;
1580
1581   if ((mode & (1<<6)))
1582     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1583   if (!err && (mode & (1<<7)))
1584     err = list_external_keys (ctrl, names, fp, (mode&256));
1585   return err;
1586 }