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