sm: Avoid warnings about useless assignments.
[gnupg.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 <http://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   es_putc (':', fp);
498   /* Field 13, not used: */
499   es_putc (':', fp);
500   if (have_secret || ctrl->with_secret)
501     {
502       char *cardsn;
503
504       p = gpgsm_get_keygrip_hexstring (cert);
505       if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn)
506           && (cardsn || ctrl->with_secret))
507         {
508           /* Field 14, not used: */
509           es_putc (':', fp);
510           /* Field 15:  Token serial number or secret key indicator.  */
511           if (cardsn)
512             es_fputs (cardsn, fp);
513           else if (ctrl->with_secret)
514             es_putc ('+', fp);
515           es_putc (':', fp);
516         }
517       xfree (cardsn);
518       xfree (p);
519     }
520   es_putc ('\n', fp);
521
522   /* FPR record */
523   es_fprintf (fp, "fpr:::::::::%s:::", fpr);
524   /* Print chaining ID (field 13)*/
525   if (chain_id)
526     es_fputs (chain_id, fp);
527   es_putc (':', fp);
528   es_putc ('\n', fp);
529   xfree (fpr); fpr = NULL; chain_id = NULL;
530   xfree (chain_id_buffer); chain_id_buffer = NULL;
531
532   if (opt.with_key_data)
533     {
534       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
535         {
536           es_fprintf (fp, "grp:::::::::%s:\n", p);
537           xfree (p);
538         }
539       print_key_data (cert, fp);
540     }
541
542   kludge_uid = NULL;
543   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
544     {
545       /* In the case that the same email address is in the subject DN
546          as well as in an alternate subject name we avoid printing it
547          a second time. */
548       if (kludge_uid && !strcmp (kludge_uid, p))
549         continue;
550
551       es_fprintf (fp, "uid:%s::::::::", truststring);
552       es_write_sanitized (fp, p, strlen (p), ":", NULL);
553       es_putc (':', fp);
554       es_putc (':', fp);
555       es_putc ('\n', fp);
556       if (!idx)
557         {
558           /* It would be better to get the faked email address from
559              the keydb.  But as long as we don't have a way to pass
560              the meta data back, we just check it the same way as the
561              code used to create the keybox meta data does */
562           kludge_uid = email_kludge (p);
563           if (kludge_uid)
564             {
565               es_fprintf (fp, "uid:%s::::::::", truststring);
566               es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
567                                   ":", NULL);
568               es_putc (':', fp);
569               es_putc (':', fp);
570               es_putc ('\n', fp);
571             }
572         }
573       xfree (p);
574     }
575   xfree (kludge_uid);
576 }
577
578
579 static void
580 print_name_raw (estream_t fp, const char *string)
581 {
582   if (!string)
583     es_fputs ("[error]", fp);
584   else
585     es_write_sanitized (fp, string, strlen (string), NULL, NULL);
586 }
587
588 static void
589 print_names_raw (estream_t fp, int indent, ksba_name_t name)
590 {
591   int idx;
592   const char *s;
593   int indent_all;
594
595   if ((indent_all = (indent < 0)))
596     indent = - indent;
597
598   if (!name)
599     {
600       es_fputs ("none\n", fp);
601       return;
602     }
603
604   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
605     {
606       char *p = ksba_name_get_uri (name, idx);
607       es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
608       es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
609       es_putc ('\n', fp);
610       xfree (p);
611     }
612 }
613
614
615 static void
616 print_utf8_extn_raw (estream_t fp, int indent,
617                      const unsigned char *der, size_t derlen)
618 {
619   gpg_error_t err;
620   int class, tag, constructed, ndef;
621   size_t objlen, hdrlen;
622
623   if (indent < 0)
624     indent = - indent;
625
626   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
627                           &ndef, &objlen, &hdrlen);
628   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
629     err = gpg_error (GPG_ERR_INV_OBJ);
630   if (err)
631     {
632       es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
633       return;
634     }
635   es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
636 }
637
638
639 static void
640 print_utf8_extn (estream_t fp, int indent,
641                  const unsigned char *der, size_t derlen)
642 {
643   gpg_error_t err;
644   int class, tag, constructed, ndef;
645   size_t objlen, hdrlen;
646   int indent_all;
647
648   if ((indent_all = (indent < 0)))
649     indent = - indent;
650
651   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
652                           &ndef, &objlen, &hdrlen);
653   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
654     err = gpg_error (GPG_ERR_INV_OBJ);
655   if (err)
656     {
657       es_fprintf (fp, "%*s[%s%s]\n",
658                   indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
659       return;
660     }
661   es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
662   /* Fixme: we should implement word wrapping */
663   es_write_sanitized (fp, der, objlen, "\"", NULL);
664   es_fputs ("\"\n", fp);
665 }
666
667
668 /* List one certificate in raw mode useful to have a closer look at
669    the certificate.  This one does no beautification and only minimal
670    output sanitation.  It is mainly useful for debugging. */
671 static void
672 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
673                ksba_cert_t cert, estream_t fp, int have_secret,
674                int with_validation)
675 {
676   gpg_error_t err;
677   size_t off, len;
678   ksba_sexp_t sexp, keyid;
679   char *dn;
680   ksba_isotime_t t;
681   int idx, i;
682   int is_ca, chainlen;
683   unsigned int kusage;
684   char *string, *p, *pend;
685   const char *oid, *s;
686   ksba_name_t name, name2;
687   unsigned int reason;
688   const unsigned char *cert_der = NULL;
689
690   (void)have_secret;
691
692   es_fprintf (fp, "           ID: 0x%08lX\n",
693               gpgsm_get_short_fingerprint (cert, NULL));
694
695   sexp = ksba_cert_get_serial (cert);
696   es_fputs ("          S/N: ", fp);
697   gpgsm_print_serial (fp, sexp);
698   ksba_free (sexp);
699   es_putc ('\n', fp);
700
701   dn = ksba_cert_get_issuer (cert, 0);
702   es_fputs ("       Issuer: ", fp);
703   print_name_raw (fp, dn);
704   ksba_free (dn);
705   es_putc ('\n', fp);
706   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
707     {
708       es_fputs ("          aka: ", fp);
709       print_name_raw (fp, dn);
710       ksba_free (dn);
711       es_putc ('\n', fp);
712     }
713
714   dn = ksba_cert_get_subject (cert, 0);
715   es_fputs ("      Subject: ", fp);
716   print_name_raw (fp, dn);
717   ksba_free (dn);
718   es_putc ('\n', fp);
719   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
720     {
721       es_fputs ("          aka: ", fp);
722       print_name_raw (fp, dn);
723       ksba_free (dn);
724       es_putc ('\n', fp);
725     }
726
727   dn = gpgsm_get_fingerprint_string (cert, 0);
728   es_fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
729   xfree (dn);
730
731   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
732   es_fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
733   xfree (dn);
734
735   dn = gpgsm_get_certid (cert);
736   es_fprintf (fp, "       certid: %s\n", dn?dn:"error");
737   xfree (dn);
738
739   dn = gpgsm_get_keygrip_hexstring (cert);
740   es_fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
741   xfree (dn);
742
743   ksba_cert_get_validity (cert, 0, t);
744   es_fputs ("    notBefore: ", fp);
745   gpgsm_print_time (fp, t);
746   es_putc ('\n', fp);
747   es_fputs ("     notAfter: ", fp);
748   ksba_cert_get_validity (cert, 1, t);
749   gpgsm_print_time (fp, t);
750   es_putc ('\n', fp);
751
752   oid = ksba_cert_get_digest_algo (cert);
753   s = get_oid_desc (oid, NULL);
754   es_fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
755
756   {
757     const char *algoname;
758     unsigned int nbits;
759
760     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
761     es_fprintf (fp, "      keyType: %u bit %s\n",
762                 nbits, algoname? algoname:"?");
763   }
764
765   /* subjectKeyIdentifier */
766   es_fputs ("    subjKeyId: ", fp);
767   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
768   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
769     {
770       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
771         es_fputs ("[none]\n", fp);
772       else
773         {
774           gpgsm_print_serial (fp, keyid);
775           ksba_free (keyid);
776           es_putc ('\n', fp);
777         }
778     }
779   else
780     es_fputs ("[?]\n", fp);
781
782
783   /* authorityKeyIdentifier */
784   es_fputs ("    authKeyId: ", fp);
785   err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
786   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
787     {
788       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
789         es_fputs ("[none]\n", fp);
790       else
791         {
792           gpgsm_print_serial (fp, sexp);
793           ksba_free (sexp);
794           es_putc ('\n', fp);
795           print_names_raw (fp, -15, name);
796           ksba_name_release (name);
797         }
798       if (keyid)
799         {
800           es_fputs (" authKeyId.ki: ", fp);
801           gpgsm_print_serial (fp, keyid);
802           ksba_free (keyid);
803           es_putc ('\n', fp);
804         }
805     }
806   else
807     es_fputs ("[?]\n", fp);
808
809   es_fputs ("     keyUsage:", fp);
810   err = ksba_cert_get_key_usage (cert, &kusage);
811   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
812     {
813       if (err)
814         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
815       else
816         {
817           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
818             es_fputs (" digitalSignature", fp);
819           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
820             es_fputs (" nonRepudiation", fp);
821           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
822             es_fputs (" keyEncipherment", fp);
823           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
824             es_fputs (" dataEncipherment", fp);
825           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
826             es_fputs (" keyAgreement", fp);
827           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
828             es_fputs (" certSign", fp);
829           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
830             es_fputs (" crlSign", fp);
831           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
832             es_fputs (" encipherOnly", fp);
833           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
834             es_fputs (" decipherOnly", fp);
835         }
836       es_putc ('\n', fp);
837     }
838   else
839     es_fputs (" [none]\n", fp);
840
841   es_fputs ("  extKeyUsage: ", fp);
842   err = ksba_cert_get_ext_key_usages (cert, &string);
843   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
844     {
845       if (err)
846         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
847       else
848         {
849           p = string;
850           while (p && (pend=strchr (p, ':')))
851             {
852               *pend++ = 0;
853               for (i=0; key_purpose_map[i].oid; i++)
854                 if ( !strcmp (key_purpose_map[i].oid, p) )
855                   break;
856               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
857               p = pend;
858               if (*p != 'C')
859                 es_fputs (" (suggested)", fp);
860               if ((p = strchr (p, '\n')))
861                 {
862                   p++;
863                   es_fputs ("\n               ", fp);
864                 }
865             }
866           xfree (string);
867         }
868       es_putc ('\n', fp);
869     }
870   else
871     es_fputs ("[none]\n", fp);
872
873
874   es_fputs ("     policies: ", fp);
875   err = ksba_cert_get_cert_policies (cert, &string);
876   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
877     {
878       if (err)
879         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
880       else
881         {
882           p = string;
883           while (p && (pend=strchr (p, ':')))
884             {
885               *pend++ = 0;
886               for (i=0; key_purpose_map[i].oid; i++)
887                 if ( !strcmp (key_purpose_map[i].oid, p) )
888                   break;
889               es_fputs (p, fp);
890               p = pend;
891               if (*p == 'C')
892                 es_fputs (" (critical)", fp);
893               if ((p = strchr (p, '\n')))
894                 {
895                   p++;
896                   es_fputs ("\n               ", fp);
897                 }
898             }
899           xfree (string);
900         }
901       es_putc ('\n', fp);
902     }
903   else
904     es_fputs ("[none]\n", fp);
905
906   es_fputs ("  chainLength: ", fp);
907   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
908   if (err || is_ca)
909     {
910       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
911         es_fprintf (fp, "[none]");
912       else if (err)
913         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
914       else if (chainlen == -1)
915         es_fputs ("unlimited", fp);
916       else
917         es_fprintf (fp, "%d", chainlen);
918       es_putc ('\n', fp);
919     }
920   else
921     es_fputs ("not a CA\n", fp);
922
923
924   /* CRL distribution point */
925   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
926                                                   &reason)) ;idx++)
927     {
928       es_fputs ("        crlDP: ", fp);
929       print_names_raw (fp, 15, name);
930       if (reason)
931         {
932           es_fputs ("               reason: ", fp);
933           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
934             es_fputs (" unused", fp);
935           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
936             es_fputs (" keyCompromise", fp);
937           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
938             es_fputs (" caCompromise", fp);
939           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
940             es_fputs (" affiliationChanged", fp);
941           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
942             es_fputs (" superseded", fp);
943           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
944             es_fputs (" cessationOfOperation", fp);
945           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
946             es_fputs (" certificateHold", fp);
947           es_putc ('\n', fp);
948         }
949       es_fputs ("               issuer: ", fp);
950       print_names_raw (fp, 23, name2);
951       ksba_name_release (name);
952       ksba_name_release (name2);
953     }
954   if (err && gpg_err_code (err) != GPG_ERR_EOF
955       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
956     es_fputs ("        crlDP: [error]\n", fp);
957   else if (!idx)
958     es_fputs ("        crlDP: [none]\n", fp);
959
960
961   /* authorityInfoAccess. */
962   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
963                                                          &name)); idx++)
964     {
965       es_fputs ("     authInfo: ", fp);
966       s = get_oid_desc (string, NULL);
967       es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
968       print_names_raw (fp, -15, name);
969       ksba_name_release (name);
970       ksba_free (string);
971     }
972   if (err && gpg_err_code (err) != GPG_ERR_EOF
973       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
974     es_fputs ("     authInfo: [error]\n", fp);
975   else if (!idx)
976     es_fputs ("     authInfo: [none]\n", fp);
977
978   /* subjectInfoAccess. */
979   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
980                                                          &name)); idx++)
981     {
982       es_fputs ("  subjectInfo: ", fp);
983       s = get_oid_desc (string, NULL);
984       es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
985       print_names_raw (fp, -15, name);
986       ksba_name_release (name);
987       ksba_free (string);
988     }
989   if (err && gpg_err_code (err) != GPG_ERR_EOF
990       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
991     es_fputs ("     subjInfo: [error]\n", fp);
992   else if (!idx)
993     es_fputs ("     subjInfo: [none]\n", fp);
994
995
996   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
997                                              &oid, &i, &off, &len));idx++)
998     {
999       unsigned int flag;
1000
1001       s = get_oid_desc (oid, &flag);
1002       if ((flag & OID_FLAG_SKIP))
1003         continue;
1004
1005       es_fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
1006                   i? "critExtn":"    extn",
1007                   oid, s?" (":"", s?s:"", s?")":"", (int)len);
1008       if ((flag & OID_FLAG_UTF8))
1009         {
1010           if (!cert_der)
1011             cert_der = ksba_cert_get_image (cert, NULL);
1012           assert (cert_der);
1013           print_utf8_extn_raw (fp, -15, cert_der+off, len);
1014         }
1015     }
1016
1017
1018   if (with_validation)
1019     {
1020       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1021       if (!err)
1022         es_fprintf (fp, "  [certificate is good]\n");
1023       else
1024         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1025     }
1026
1027   if (hd)
1028     {
1029       unsigned int blobflags;
1030
1031       err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
1032       if (err)
1033         es_fprintf (fp, "  [error getting keyflags: %s]\n",gpg_strerror (err));
1034       else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1035         es_fprintf (fp, "  [stored as ephemeral]\n");
1036     }
1037
1038 }
1039
1040
1041
1042
1043 /* List one certificate in standard mode */
1044 static void
1045 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1046                int with_validation)
1047 {
1048   gpg_error_t err;
1049   ksba_sexp_t sexp;
1050   char *dn;
1051   ksba_isotime_t t;
1052   int idx, i;
1053   int is_ca, chainlen;
1054   unsigned int kusage;
1055   char *string, *p, *pend;
1056   size_t off, len;
1057   const char *oid;
1058   const unsigned char *cert_der = NULL;
1059
1060
1061   es_fprintf (fp, "           ID: 0x%08lX\n",
1062               gpgsm_get_short_fingerprint (cert, NULL));
1063
1064   sexp = ksba_cert_get_serial (cert);
1065   es_fputs ("          S/N: ", fp);
1066   gpgsm_print_serial (fp, sexp);
1067   ksba_free (sexp);
1068   es_putc ('\n', fp);
1069
1070   dn = ksba_cert_get_issuer (cert, 0);
1071   es_fputs ("       Issuer: ", fp);
1072   gpgsm_es_print_name (fp, dn);
1073   ksba_free (dn);
1074   es_putc ('\n', fp);
1075   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1076     {
1077       es_fputs ("          aka: ", fp);
1078       gpgsm_es_print_name (fp, dn);
1079       ksba_free (dn);
1080       es_putc ('\n', fp);
1081     }
1082
1083   dn = ksba_cert_get_subject (cert, 0);
1084   es_fputs ("      Subject: ", fp);
1085   gpgsm_es_print_name (fp, dn);
1086   ksba_free (dn);
1087   es_putc ('\n', fp);
1088   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1089     {
1090       es_fputs ("          aka: ", fp);
1091       gpgsm_es_print_name (fp, dn);
1092       ksba_free (dn);
1093       es_putc ('\n', fp);
1094     }
1095
1096   ksba_cert_get_validity (cert, 0, t);
1097   es_fputs ("     validity: ", fp);
1098   gpgsm_print_time (fp, t);
1099   es_fputs (" through ", fp);
1100   ksba_cert_get_validity (cert, 1, t);
1101   gpgsm_print_time (fp, t);
1102   es_putc ('\n', fp);
1103
1104
1105   {
1106     const char *algoname;
1107     unsigned int nbits;
1108
1109     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1110     es_fprintf (fp, "     key type: %u bit %s\n",
1111                 nbits, algoname? algoname:"?");
1112   }
1113
1114
1115   err = ksba_cert_get_key_usage (cert, &kusage);
1116   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1117     {
1118       es_fputs ("    key usage:", fp);
1119       if (err)
1120         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1121       else
1122         {
1123           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1124             es_fputs (" digitalSignature", fp);
1125           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
1126             es_fputs (" nonRepudiation", fp);
1127           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
1128             es_fputs (" keyEncipherment", fp);
1129           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1130             es_fputs (" dataEncipherment", fp);
1131           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
1132             es_fputs (" keyAgreement", fp);
1133           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1134             es_fputs (" certSign", fp);
1135           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
1136             es_fputs (" crlSign", fp);
1137           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1138             es_fputs (" encipherOnly", fp);
1139           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
1140             es_fputs (" decipherOnly", fp);
1141         }
1142       es_putc ('\n', fp);
1143     }
1144
1145   err = ksba_cert_get_ext_key_usages (cert, &string);
1146   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1147     {
1148       es_fputs ("ext key usage: ", fp);
1149       if (err)
1150         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1151       else
1152         {
1153           p = string;
1154           while (p && (pend=strchr (p, ':')))
1155             {
1156               *pend++ = 0;
1157               for (i=0; key_purpose_map[i].oid; i++)
1158                 if ( !strcmp (key_purpose_map[i].oid, p) )
1159                   break;
1160               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1161               p = pend;
1162               if (*p != 'C')
1163                 es_fputs (" (suggested)", fp);
1164               if ((p = strchr (p, '\n')))
1165                 {
1166                   p++;
1167                   es_fputs (", ", fp);
1168                 }
1169             }
1170           xfree (string);
1171         }
1172       es_putc ('\n', fp);
1173     }
1174
1175   /* Print restrictions.  */
1176   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1177                                              &oid, NULL, &off, &len));idx++)
1178     {
1179       if (!strcmp (oid, OIDSTR_restriction) )
1180         {
1181           if (!cert_der)
1182             cert_der = ksba_cert_get_image (cert, NULL);
1183           assert (cert_der);
1184           es_fputs ("  restriction: ", fp);
1185           print_utf8_extn (fp, 15, cert_der+off, len);
1186         }
1187     }
1188
1189   /* Print policies.  */
1190   err = ksba_cert_get_cert_policies (cert, &string);
1191   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1192     {
1193       es_fputs ("     policies: ", fp);
1194       if (err)
1195         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1196       else
1197         {
1198           for (p=string; *p; p++)
1199             {
1200               if (*p == '\n')
1201                 *p = ',';
1202             }
1203           es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1204           xfree (string);
1205         }
1206       es_putc ('\n', fp);
1207     }
1208
1209   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1210   if (err || is_ca)
1211     {
1212       es_fputs (" chain length: ", fp);
1213       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1214         es_fprintf (fp, "none");
1215       else if (err)
1216         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1217       else if (chainlen == -1)
1218         es_fputs ("unlimited", fp);
1219       else
1220         es_fprintf (fp, "%d", chainlen);
1221       es_putc ('\n', fp);
1222     }
1223
1224   if (opt.with_md5_fingerprint)
1225     {
1226       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1227       es_fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
1228       xfree (dn);
1229     }
1230
1231   dn = gpgsm_get_fingerprint_string (cert, 0);
1232   es_fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
1233   xfree (dn);
1234
1235   if (opt.with_keygrip)
1236     {
1237       dn = gpgsm_get_keygrip_hexstring (cert);
1238       if (dn)
1239         {
1240           es_fprintf (fp, "      keygrip: %s\n", dn);
1241           xfree (dn);
1242         }
1243     }
1244
1245   if (have_secret)
1246     {
1247       char *cardsn;
1248
1249       p = gpgsm_get_keygrip_hexstring (cert);
1250       if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
1251         es_fprintf (fp, "     card s/n: %s\n", cardsn);
1252       xfree (cardsn);
1253       xfree (p);
1254     }
1255
1256   if (with_validation)
1257     {
1258       gpg_error_t tmperr;
1259       size_t buflen;
1260       char buffer[1];
1261
1262       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1263       tmperr = ksba_cert_get_user_data (cert, "is_qualified",
1264                                         &buffer, sizeof (buffer), &buflen);
1265       if (!tmperr && buflen)
1266         {
1267           if (*buffer)
1268             es_fputs ("  [qualified]\n", fp);
1269         }
1270       else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1271         ; /* Don't know - will not get marked as 'q' */
1272       else
1273         log_debug ("get_user_data(is_qualified) failed: %s\n",
1274                    gpg_strerror (tmperr));
1275
1276       if (!err)
1277         es_fprintf (fp, "  [certificate is good]\n");
1278       else
1279         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1280     }
1281 }
1282
1283
1284 /* Same as standard mode mode list all certifying certs too. */
1285 static void
1286 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1287                  ksba_cert_t cert, int raw_mode,
1288                  estream_t fp, int with_validation)
1289 {
1290   ksba_cert_t next = NULL;
1291
1292   if (raw_mode)
1293     list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1294   else
1295     list_cert_std (ctrl, cert, fp, 0, with_validation);
1296   ksba_cert_ref (cert);
1297   while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1298     {
1299       ksba_cert_release (cert);
1300       es_fputs ("Certified by\n", fp);
1301       if (raw_mode)
1302         list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1303       else
1304         list_cert_std (ctrl, next, fp, 0, with_validation);
1305       cert = next;
1306     }
1307   ksba_cert_release (cert);
1308   es_putc ('\n', fp);
1309 }
1310
1311
1312 \f
1313 /* List all internal keys or just the keys given as NAMES.  MODE is a
1314    bit vector to specify what keys are to be included; see
1315    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
1316    output mode will be used instead of the standard beautified one.
1317  */
1318 static gpg_error_t
1319 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1320                     unsigned int mode, int raw_mode)
1321 {
1322   KEYDB_HANDLE hd;
1323   KEYDB_SEARCH_DESC *desc = NULL;
1324   strlist_t sl;
1325   int ndesc;
1326   ksba_cert_t cert = NULL;
1327   ksba_cert_t lastcert = NULL;
1328   gpg_error_t rc = 0;
1329   const char *lastresname, *resname;
1330   int have_secret;
1331   int want_ephemeral = ctrl->with_ephemeral_keys;
1332
1333   hd = keydb_new (0);
1334   if (!hd)
1335     {
1336       log_error ("keydb_new failed\n");
1337       rc = gpg_error (GPG_ERR_GENERAL);
1338       goto leave;
1339     }
1340
1341   if (!names)
1342     ndesc = 1;
1343   else
1344     {
1345       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1346         ;
1347     }
1348
1349   desc = xtrycalloc (ndesc, sizeof *desc);
1350   if (!ndesc)
1351     {
1352       rc = gpg_error_from_syserror ();
1353       log_error ("out of core\n");
1354       goto leave;
1355     }
1356
1357   if (!names)
1358     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1359   else
1360     {
1361       for (ndesc=0, sl=names; sl; sl = sl->next)
1362         {
1363           rc = classify_user_id (sl->d, desc+ndesc, 0);
1364           if (rc)
1365             {
1366               log_error ("key '%s' not found: %s\n",
1367                          sl->d, gpg_strerror (rc));
1368               rc = 0;
1369             }
1370           else
1371             ndesc++;
1372         }
1373
1374     }
1375
1376   /* If all specifications are done by fingerprint or keygrip, we
1377      switch to ephemeral mode so that _all_ currently available and
1378      matching certificates are listed.  */
1379   if (!want_ephemeral && names && ndesc)
1380     {
1381       int i;
1382
1383       for (i=0; (i < ndesc
1384                  && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
1385                      || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
1386                      || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
1387                      || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
1388         ;
1389       if (i == ndesc)
1390         want_ephemeral = 1;
1391     }
1392
1393   if (want_ephemeral)
1394     keydb_set_ephemeral (hd, 1);
1395
1396   /* It would be nice to see which of the given users did actually
1397      match one in the keyring.  To implement this we need to have a
1398      found flag for each entry in desc and to set this we must check
1399      all those entries after a match to mark all matched one -
1400      currently we stop at the first match.  To do this we need an
1401      extra flag to enable this feature so */
1402
1403   /* Suppress duplicates at least when they follow each other.  */
1404   lastresname = NULL;
1405   while (!(rc = keydb_search (hd, desc, ndesc)))
1406     {
1407       unsigned int validity;
1408
1409       if (!names)
1410         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1411
1412       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1413       if (rc)
1414         {
1415           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1416           goto leave;
1417         }
1418       rc = keydb_get_cert (hd, &cert);
1419       if (rc)
1420         {
1421           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1422           goto leave;
1423         }
1424       /* Skip duplicated certificates, at least if they follow each
1425          others.  This works best if a single key is searched for and
1426          expected.  FIXME: Non-sequential duplicates remain.  */
1427       if (gpgsm_certs_identical_p (cert, lastcert))
1428         {
1429           ksba_cert_release (cert);
1430           cert = NULL;
1431           continue;
1432         }
1433
1434       resname = keydb_get_resource_name (hd);
1435
1436       if (lastresname != resname )
1437         {
1438           int i;
1439
1440           if (ctrl->no_server)
1441             {
1442               es_fprintf (fp, "%s\n", resname );
1443               for (i=strlen(resname); i; i-- )
1444                 es_putc ('-', fp);
1445               es_putc ('\n', fp);
1446               lastresname = resname;
1447             }
1448         }
1449
1450       have_secret = 0;
1451       if (mode)
1452         {
1453           char *p = gpgsm_get_keygrip_hexstring (cert);
1454           if (p)
1455             {
1456               rc = gpgsm_agent_havekey (ctrl, p);
1457               if (!rc)
1458                 have_secret = 1;
1459               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1460                 goto leave;
1461               rc = 0;
1462               xfree (p);
1463             }
1464         }
1465
1466       if (!mode
1467           || ((mode & 1) && !have_secret)
1468           || ((mode & 2) && have_secret)  )
1469         {
1470           if (ctrl->with_colons)
1471             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1472           else if (ctrl->with_chain)
1473             list_cert_chain (ctrl, hd, cert,
1474                              raw_mode, fp, ctrl->with_validation);
1475           else
1476             {
1477               if (raw_mode)
1478                 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1479                                ctrl->with_validation);
1480               else
1481                 list_cert_std (ctrl, cert, fp, have_secret,
1482                                ctrl->with_validation);
1483               es_putc ('\n', fp);
1484             }
1485         }
1486
1487       ksba_cert_release (lastcert);
1488       lastcert = cert;
1489       cert = NULL;
1490     }
1491   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1492     rc = 0;
1493   if (rc)
1494     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1495
1496  leave:
1497   ksba_cert_release (cert);
1498   ksba_cert_release (lastcert);
1499   xfree (desc);
1500   keydb_release (hd);
1501   return rc;
1502 }
1503
1504
1505
1506 static void
1507 list_external_cb (void *cb_value, ksba_cert_t cert)
1508 {
1509   struct list_external_parm_s *parm = cb_value;
1510
1511   if (keydb_store_cert (cert, 1, NULL))
1512     log_error ("error storing certificate as ephemeral\n");
1513
1514   if (parm->print_header)
1515     {
1516       const char *resname = "[external keys]";
1517       int i;
1518
1519       es_fprintf (parm->fp, "%s\n", resname );
1520       for (i=strlen(resname); i; i-- )
1521         es_putc('-', parm->fp);
1522       es_putc ('\n', parm->fp);
1523       parm->print_header = 0;
1524     }
1525
1526   if (parm->with_colons)
1527     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1528   else if (parm->with_chain)
1529     list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1530   else
1531     {
1532       if (parm->raw_mode)
1533         list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1534       else
1535         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1536       es_putc ('\n', parm->fp);
1537     }
1538 }
1539
1540
1541 /* List external keys similar to internal one.  Note: mode does not
1542    make sense here because it would be unwise to list external secret
1543    keys */
1544 static gpg_error_t
1545 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1546 {
1547   int rc;
1548   struct list_external_parm_s parm;
1549
1550   parm.fp = fp;
1551   parm.ctrl = ctrl,
1552   parm.print_header = ctrl->no_server;
1553   parm.with_colons = ctrl->with_colons;
1554   parm.with_chain = ctrl->with_chain;
1555   parm.raw_mode  = raw_mode;
1556
1557   rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
1558   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
1559       || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1560     rc = 0; /* "Not found" is not an error here. */
1561   if (rc)
1562     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1563   return rc;
1564 }
1565
1566 /* List all keys or just the key given as NAMES.
1567    MODE controls the operation mode:
1568     Bit 0-2:
1569       0 = list all public keys but don't flag secret ones
1570       1 = list only public keys
1571       2 = list only secret keys
1572       3 = list secret and public keys
1573     Bit 6: list internal keys
1574     Bit 7: list external keys
1575     Bit 8: Do a raw format dump.
1576  */
1577 gpg_error_t
1578 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1579                  unsigned int mode)
1580 {
1581   gpg_error_t err = 0;
1582
1583   if ((mode & (1<<6)))
1584     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1585   if (!err && (mode & (1<<7)))
1586     err = list_external_keys (ctrl, names, fp, (mode&256));
1587   return err;
1588 }