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