* keylist.c (email_kludge): Reworked.
[gnupg.git] / sm / keylist.c
1 /* keylist.c - Print certificates in various formats.
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3  *               2004, 2005 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 2 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, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <unistd.h> 
28 #include <time.h>
29 #include <assert.h>
30
31 #include "gpgsm.h"
32
33 #include <gcrypt.h>
34 #include <ksba.h>
35
36 #include "keydb.h"
37 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
38 #include "i18n.h"
39
40 struct list_external_parm_s {
41   ctrl_t ctrl;
42   FILE *fp;
43   int print_header;
44   int with_colons;
45   int with_chain;
46   int raw_mode;
47 };
48
49
50 /* This table is to map Extended Key Usage OIDs to human readable
51    names.  */
52 struct {
53   const char *oid;
54   const char *name;
55 } key_purpose_map[] = {
56   { "1.3.6.1.5.5.7.3.1",  "serverAuth" },
57   { "1.3.6.1.5.5.7.3.2",  "clientAuth" },          
58   { "1.3.6.1.5.5.7.3.3",  "codeSigning" },      
59   { "1.3.6.1.5.5.7.3.4",  "emailProtection" },     
60   { "1.3.6.1.5.5.7.3.5",  "ipsecEndSystem" }, 
61   { "1.3.6.1.5.5.7.3.6",  "ipsecTunnel" },  
62   { "1.3.6.1.5.5.7.3.7",  "ipsecUser" },     
63   { "1.3.6.1.5.5.7.3.8",  "timeStamping" },       
64   { "1.3.6.1.5.5.7.3.9",  "ocspSigning" },    
65   { "1.3.6.1.5.5.7.3.10", "dvcs" },      
66   { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
67   { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
68   { "1.3.6.1.5.5.7.3.14", "wlanSSID" },       
69   { NULL, NULL }
70 };
71
72
73 /* A table mapping OIDs to a descriptive string. */
74 static struct {
75   char *oid;
76   char *name;
77   unsigned int flag;
78 } oidtranstbl[] = {
79
80   /* Algorithms. */
81   { "1.2.840.10040.4.1", "dsa" },
82   { "1.2.840.10040.4.3", "dsaWithSha1" },
83
84   { "1.2.840.113549.1.1.1", "rsaEncryption" },
85   { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
86   { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
87   { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
88   { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
89   { "1.2.840.113549.1.1.7", "rsaOAEP" },
90   { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
91   { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
92   { "1.2.840.113549.1.1.10", "rsaPSS" },
93   { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
94   { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
95   { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
96
97   { "1.3.14.3.2.26", "sha1" },
98   { "1.3.14.3.2.29",  "sha-1WithRSAEncryption" },
99   { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
100
101
102   /* Telesec extensions. */
103   { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
104   { "0.2.262.1.10.12.1", "telesecCertIdExt" },
105   { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
106   { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
107   { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
108   { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
109   { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
110
111   /* PKIX private extensions. */
112   { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
113   { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
114   { "1.3.6.1.5.5.7.1.3", "qcStatements" },
115   { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
116   { "1.3.6.1.5.5.7.1.5", "acTargeting" },
117   { "1.3.6.1.5.5.7.1.6", "acAaControls" },
118   { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
119   { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
120   { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
121   { "1.3.6.1.5.5.7.1.10", "acProxying" },
122   { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
123
124   /* X.509 id-ce */
125   { "2.5.29.14", "subjectKeyIdentifier", 1},
126   { "2.5.29.15", "keyUsage", 1 },
127   { "2.5.29.16", "privateKeyUsagePeriod" },
128   { "2.5.29.17", "subjectAltName", 1 },
129   { "2.5.29.18", "issuerAltName", 1 },
130   { "2.5.29.19", "basicConstraints", 1},
131   { "2.5.29.20", "cRLNumber" },
132   { "2.5.29.21", "cRLReason" },
133   { "2.5.29.22", "expirationDate" },
134   { "2.5.29.23", "instructionCode" }, 
135   { "2.5.29.24", "invalidityDate" },
136   { "2.5.29.27", "deltaCRLIndicator" },
137   { "2.5.29.28", "issuingDistributionPoint" },
138   { "2.5.29.29", "certificateIssuer" },
139   { "2.5.29.30", "nameConstraints" },
140   { "2.5.29.31", "cRLDistributionPoints", 1 },
141   { "2.5.29.32", "certificatePolicies", 1 },
142   { "2.5.29.32.0", "anyPolicy" },
143   { "2.5.29.33", "policyMappings" },
144   { "2.5.29.35", "authorityKeyIdentifier", 1 },
145   { "2.5.29.36", "policyConstraints" },
146   { "2.5.29.37", "extKeyUsage", 1 },
147   { "2.5.29.46", "freshestCRL" },
148   { "2.5.29.54", "inhibitAnyPolicy" },
149
150   /* Netscape certificate extensions. */
151   { "2.16.840.1.113730.1.1", "netscape-cert-type" },
152   { "2.16.840.1.113730.1.2", "netscape-base-url" },
153   { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
154   { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
155   { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
156   { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
157   { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
158   { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
159   { "2.16.840.1.113730.1.11", "netscape-userPicture" },
160   { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
161   { "2.16.840.1.113730.1.13", "netscape-comment" },
162
163   { NULL }
164 };
165
166
167 /* Return the description for OID; if no description is available 
168    NULL is returned. */
169 static const char *
170 get_oid_desc (const char *oid, unsigned int *flag)
171 {
172   int i;
173
174   if (oid)
175     for (i=0; oidtranstbl[i].oid; i++)
176       if (!strcmp (oidtranstbl[i].oid, oid))
177         {
178           if (flag)
179             *flag = oidtranstbl[i].flag;
180           return oidtranstbl[i].name;
181         }
182   if (flag)
183     *flag = 0;
184   return NULL;
185 }
186
187
188 static void
189 print_key_data (ksba_cert_t cert, FILE *fp)
190 {
191 #if 0  
192   int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
193   int i;
194
195   for(i=0; i < n; i++ ) 
196     {
197       fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
198       mpi_print(stdout, pk->pkey[i], 1 );
199       putchar(':');
200       putchar('\n');
201     }
202 #endif
203 }
204
205 static void
206 print_capabilities (ksba_cert_t cert, FILE *fp)
207 {
208   gpg_error_t err;
209   unsigned int use;
210
211   err = ksba_cert_get_key_usage (cert, &use);
212   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
213     {
214       putc ('e', fp);
215       putc ('s', fp);
216       putc ('c', fp);
217       putc ('E', fp);
218       putc ('S', fp);
219       putc ('C', fp);
220       return;
221     }
222   if (err)
223     { 
224       log_error (_("error getting key usage information: %s\n"),
225                  gpg_strerror (err));
226       return;
227     } 
228
229   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
230     putc ('e', fp);
231   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
232     putc ('s', fp);
233   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
234     putc ('c', fp);
235   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
236     putc ('E', fp);
237   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
238     putc ('S', fp);
239   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
240     putc ('C', fp);
241 }
242
243
244 static void
245 print_time (gnupg_isotime_t t, FILE *fp)
246 {
247   if (!t || !*t)
248     ;
249   else 
250     fputs (t, fp);
251 }
252
253
254 /* Return an allocated string with the email address extracted from a
255    DN */
256 static char *
257 email_kludge (const char *name)
258 {
259   const char *p, *string;
260   unsigned char *buf;
261   int n;
262
263   string = name;
264   for (;;)
265     {
266       p = strstr (string, "1.2.840.113549.1.9.1=#");
267       if (!p)
268         return NULL;
269       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
270         {
271           name = p + 22;
272           break;
273         }
274       string = p + 22;
275     }
276
277
278   /* This looks pretty much like an email address in the subject's DN
279      we use this to add an additional user ID entry.  This way,
280      openSSL generated keys get a nicer and usable listing */
281   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
282     ;
283   if (!n)
284     return NULL;
285   buf = xtrymalloc (n+3);
286   if (!buf)
287     return NULL; /* oops, out of core */
288   *buf = '<';
289   for (n=1, p=name; hexdigitp (p); p +=2, n++)
290     buf[n] = xtoi_2 (p);
291   buf[n++] = '>';
292   buf[n] = 0;
293   return (char*)buf;
294 }
295
296
297
298
299 /* List one certificate in colon mode */
300 static void
301 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
302                  FILE *fp, int have_secret)
303 {
304   int rc;
305   int idx;
306   char truststring[2];
307   char *p;
308   ksba_sexp_t sexp;
309   char *fpr;
310   ksba_isotime_t t;
311   gpg_error_t valerr;
312   int algo;
313   unsigned int nbits;
314   const char *chain_id;
315   char *chain_id_buffer = NULL;
316   int is_root = 0;
317
318   if (ctrl->with_validation)
319     valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
320   else
321     valerr = 0;
322
323
324   /* We need to get the fingerprint and the chaining ID in advance. */
325   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
326   {
327     ksba_cert_t next;
328
329     rc = gpgsm_walk_cert_chain (cert, &next);
330     if (!rc) /* We known the issuer's certificate. */
331       {
332         p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
333         chain_id_buffer = p;
334         chain_id = chain_id_buffer;
335         ksba_cert_release (next);
336       }
337     else if (rc == -1)  /* We have reached the root certificate. */
338       {
339         chain_id = fpr;
340         is_root = 1;
341       }
342     else
343       chain_id = NULL;
344   }
345
346
347   fputs (have_secret? "crs:":"crt:", fp);
348
349   /* Note: We can't use multiple flags, like "ei", because the
350      validation check does only return one error.  */
351   truststring[0] = 0;
352   truststring[1] = 0;
353   if ((validity & VALIDITY_REVOKED)
354       || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
355     *truststring = 'r';
356   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
357     *truststring = 'e';
358   else 
359     {
360       /* Lets also check whether the certificate under question
361          expired.  This is merely a hack until we found a proper way
362          to store the expiration flag in the keybox. */
363       ksba_isotime_t current_time, not_after;
364   
365       gnupg_get_isotime (current_time);
366       if (!opt.ignore_expiration
367           && !ksba_cert_get_validity (cert, 1, not_after)
368           && *not_after && strcmp (current_time, not_after) > 0 )
369         *truststring = 'e';
370       else if (valerr)
371         *truststring = 'i';
372     }
373
374   /* Is we have no truststring yet (i.e. the certificate might be
375      good) and this is a root certificate, we ask the agent whether
376      this is a trusted root certificate. */
377   if (!*truststring && is_root)
378     {
379       rc = gpgsm_agent_istrusted (ctrl, cert);
380       if (!rc)
381         *truststring = 'u';  /* Yes, we trust this one (ultimately). */
382       else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
383         *truststring = 'n';  /* No, we do not trust this one. */
384       /* (in case of an error we can't tell anything.) */
385     }
386   
387   if (*truststring)
388     fputs (truststring, fp);
389
390   algo = gpgsm_get_key_algo_info (cert, &nbits);
391   fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
392
393   /* We assume --fixed-list-mode for gpgsm */
394   ksba_cert_get_validity (cert, 0, t);
395   print_time (t, fp);
396   putc (':', fp);
397   ksba_cert_get_validity (cert, 1, t);
398   print_time ( t, fp);
399   putc (':', fp);
400   /* Field 8, serial number: */
401   if ((sexp = ksba_cert_get_serial (cert)))
402     {
403       int len;
404       const unsigned char *s = sexp;
405       
406       if (*s == '(')
407         {
408           s++;
409           for (len=0; *s && *s != ':' && digitp (s); s++)
410             len = len*10 + atoi_1 (s);
411           if (*s == ':')
412             for (s++; len; len--, s++)
413               fprintf (fp,"%02X", *s);
414         }
415       xfree (sexp);
416     }
417   putc (':', fp);
418   /* Field 9, ownertrust - not used here */
419   putc (':', fp);
420   /* field 10, old user ID - we use it here for the issuer DN */
421   if ((p = ksba_cert_get_issuer (cert,0)))
422     {
423       print_sanitized_string (fp, p, ':');
424       xfree (p);
425     }
426   putc (':', fp);
427   /* Field 11, signature class - not used */ 
428   putc (':', fp);
429   /* Field 12, capabilities: */ 
430   print_capabilities (cert, fp);
431   putc (':', fp);
432   putc ('\n', fp);
433
434   /* FPR record */
435   fprintf (fp, "fpr:::::::::%s:::", fpr);
436   /* Print chaining ID (field 13)*/
437   if (chain_id)
438     fputs (chain_id, fp);
439   putc (':', fp);
440   putc ('\n', fp);
441   xfree (fpr); fpr = NULL; chain_id = NULL;
442   xfree (chain_id_buffer); chain_id_buffer = NULL;
443
444   if (opt.with_key_data)
445     {
446       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
447         {
448           fprintf (fp, "grp:::::::::%s:\n", p);
449           xfree (p);
450         }
451       print_key_data (cert, fp);
452     }
453
454   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
455     {
456       fprintf (fp, "uid:%s::::::::", truststring);
457       print_sanitized_string (fp, p, ':');
458       putc (':', fp);
459       putc (':', fp);
460       putc ('\n', fp);
461       if (!idx)
462         {
463           /* It would be better to get the faked email address from
464              the keydb.  But as long as we don't have a way to pass
465              the meta data back, we just check it the same way as the
466              code used to create the keybox meta data does */
467           char *pp = email_kludge (p);
468           if (pp)
469             {
470               fprintf (fp, "uid:%s::::::::", truststring);
471               print_sanitized_string (fp, pp, ':');
472               putc (':', fp);
473               putc (':', fp);
474               putc ('\n', fp);
475               xfree (pp);
476             }
477         }
478       xfree (p);
479     }
480 }
481
482
483 static void
484 print_name_raw (FILE *fp, const char *string)
485 {
486   if (!string)
487     fputs ("[error]", fp);
488   else
489     print_sanitized_string (fp, string, 0);
490 }
491
492 static void
493 print_names_raw (FILE *fp, int indent, ksba_name_t name)
494 {
495   int idx;
496   const char *s;
497   int indent_all;
498
499   if ((indent_all = (indent < 0)))
500     indent = - indent;
501
502   if (!name)
503     {
504       fputs ("none\n", fp);
505       return;
506     }
507   
508   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
509     {
510       char *p = ksba_name_get_uri (name, idx);
511       printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s);
512       xfree (p);
513     }
514 }
515
516
517 /* List one certificate in raw mode useful to have a closer look at
518    the certificate.  This one does no beautification and only minimal
519    output sanitation.  It is mainly useful for debugging. */
520 static void
521 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
522                ksba_cert_t cert, FILE *fp, int have_secret,
523                int with_validation)
524 {
525   gpg_error_t err;
526   size_t off, len;
527   ksba_sexp_t sexp, keyid;
528   char *dn;
529   ksba_isotime_t t;
530   int idx, i;
531   int is_ca, chainlen;
532   unsigned int kusage;
533   char *string, *p, *pend;
534   const char *oid, *s;
535   ksba_name_t name, name2;
536   unsigned int reason;
537
538   sexp = ksba_cert_get_serial (cert);
539   fputs ("Serial number: ", fp);
540   gpgsm_print_serial (fp, sexp);
541   ksba_free (sexp);
542   putc ('\n', fp);
543
544   dn = ksba_cert_get_issuer (cert, 0);
545   fputs ("       Issuer: ", fp);
546   print_name_raw (fp, dn);
547   ksba_free (dn);
548   putc ('\n', fp);
549   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
550     {
551       fputs ("          aka: ", fp);
552       print_name_raw (fp, dn);
553       ksba_free (dn);
554       putc ('\n', fp);
555     }
556
557   dn = ksba_cert_get_subject (cert, 0);
558   fputs ("      Subject: ", fp);
559   print_name_raw (fp, dn);
560   ksba_free (dn);
561   putc ('\n', fp);
562   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
563     {
564       fputs ("          aka: ", fp);
565       print_name_raw (fp, dn);
566       ksba_free (dn);
567       putc ('\n', fp);
568     }
569
570   dn = gpgsm_get_fingerprint_string (cert, 0);
571   fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
572   xfree (dn);
573
574   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
575   fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
576   xfree (dn);
577
578   dn = gpgsm_get_keygrip_hexstring (cert);
579   fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
580   xfree (dn);
581
582   ksba_cert_get_validity (cert, 0, t);
583   fputs ("    notBefore: ", fp);
584   gpgsm_print_time (fp, t);
585   putc ('\n', fp);
586   fputs ("     notAfter: ", fp);
587   ksba_cert_get_validity (cert, 1, t);
588   gpgsm_print_time (fp, t);
589   putc ('\n', fp);
590
591   oid = ksba_cert_get_digest_algo (cert);
592   s = get_oid_desc (oid, NULL);
593   fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
594
595   {
596     const char *algoname;
597     unsigned int nbits;
598
599     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
600     fprintf (fp, "      keyType: %u bit %s\n",  nbits, algoname? algoname:"?");
601   }
602
603   /* subjectKeyIdentifier */
604   fputs ("    subjKeyId: ", fp);
605   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
606   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
607     {
608       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
609         fputs ("[none]\n", fp);
610       else
611         {
612           gpgsm_print_serial (fp, keyid);
613           ksba_free (keyid);
614           putc ('\n', fp);
615         }
616     }
617   else
618     fputs ("[?]\n", fp);
619
620
621   /* authorityKeyIdentifier */
622   fputs ("    authKeyId: ", fp);
623   err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
624   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
625     {
626       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
627         fputs ("[none]\n", fp);
628       else
629         {
630           gpgsm_print_serial (fp, sexp);
631           ksba_free (sexp);
632           putc ('\n', fp);
633           print_names_raw (fp, -15, name);
634           ksba_name_release (name);
635         }
636       if (keyid)
637         {
638           fputs (" authKeyId.ki: ", fp);
639           gpgsm_print_serial (fp, keyid);
640           ksba_free (keyid);
641           putc ('\n', fp);
642         }
643     }
644   else
645     fputs ("[?]\n", fp);
646
647   fputs ("     keyUsage:", fp);
648   err = ksba_cert_get_key_usage (cert, &kusage);
649   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
650     {
651       if (err)
652         fprintf (fp, " [error: %s]", gpg_strerror (err));
653       else
654         {
655           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
656             fputs (" digitalSignature", fp);
657           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
658             fputs (" nonRepudiation", fp);
659           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
660             fputs (" keyEncipherment", fp);
661           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
662             fputs (" dataEncipherment", fp);
663           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
664             fputs (" keyAgreement", fp);
665           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
666             fputs (" certSign", fp);
667           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
668             fputs (" crlSign", fp);
669           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
670             fputs (" encipherOnly", fp);
671           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
672             fputs (" decipherOnly", fp);
673         }
674       putc ('\n', fp);
675     }
676   else
677     fputs ("[none]\n", fp);
678
679   fputs ("  extKeyUsage: ", fp);
680   err = ksba_cert_get_ext_key_usages (cert, &string);
681   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
682     { 
683       if (err)
684         fprintf (fp, "[error: %s]", gpg_strerror (err));
685       else
686         {
687           p = string;
688           while (p && (pend=strchr (p, ':')))
689             {
690               *pend++ = 0;
691               for (i=0; key_purpose_map[i].oid; i++)
692                 if ( !strcmp (key_purpose_map[i].oid, p) )
693                   break;
694               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
695               p = pend;
696               if (*p != 'C')
697                 fputs (" (suggested)", fp);
698               if ((p = strchr (p, '\n')))
699                 {
700                   p++;
701                   fputs ("\n               ", fp);
702                 }
703             }
704           xfree (string);
705         }
706       putc ('\n', fp);
707     }
708   else
709     fputs ("[none]\n", fp);
710
711
712   fputs ("     policies: ", fp);
713   err = ksba_cert_get_cert_policies (cert, &string);
714   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
715     {
716       if (err)
717         fprintf (fp, "[error: %s]", gpg_strerror (err));
718       else
719         {
720           p = string;
721           while (p && (pend=strchr (p, ':')))
722             {
723               *pend++ = 0;
724               for (i=0; key_purpose_map[i].oid; i++)
725                 if ( !strcmp (key_purpose_map[i].oid, p) )
726                   break;
727               fputs (p, fp);
728               p = pend;
729               if (*p == 'C')
730                 fputs (" (critical)", fp);
731               if ((p = strchr (p, '\n')))
732                 {
733                   p++;
734                   fputs ("\n               ", fp);
735                 }
736             }
737           xfree (string);
738         }
739       putc ('\n', fp);
740     }
741   else
742     fputs ("[none]\n", fp);
743
744   fputs ("  chainLength: ", fp);
745   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
746   if (err || is_ca)
747     {
748       if (err)
749         fprintf (fp, "[error: %s]", gpg_strerror (err));
750       else if (chainlen == -1)
751         fputs ("unlimited", fp);
752       else
753         fprintf (fp, "%d", chainlen);
754       putc ('\n', fp);
755     }
756   else
757     fputs ("not a CA\n", fp);
758
759
760   /* CRL distribution point */
761   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
762                                                   &reason)) ;idx++)
763     {
764       fputs ("        crlDP: ", fp);
765       print_names_raw (fp, 15, name);
766       if (reason)
767         {
768           fputs ("               reason: ", fp);
769           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
770             fputs (" unused", stdout);
771           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
772             fputs (" keyCompromise", stdout);
773           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
774             fputs (" caCompromise", stdout);
775           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
776             fputs (" affiliationChanged", stdout);
777           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
778             fputs (" superseded", stdout);
779           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
780             fputs (" cessationOfOperation", stdout);
781           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
782             fputs (" certificateHold", stdout);
783           putchar ('\n');
784         }
785       fputs ("               issuer: ", fp);
786       print_names_raw (fp, 23, name2);
787       ksba_name_release (name);
788       ksba_name_release (name2);
789     }
790   if (err && gpg_err_code (err) != GPG_ERR_EOF)
791     fputs ("        crlDP: [error]\n", fp);
792   else if (!idx)
793     fputs ("        crlDP: [none]\n", fp);
794
795
796   /* authorityInfoAccess. */
797   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
798                                                          &name)); idx++)
799     {
800       fputs ("     authInfo: ", fp);
801       s = get_oid_desc (string, NULL);
802       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
803       print_names_raw (fp, -15, name);
804       ksba_name_release (name);
805       ksba_free (string);
806     }
807   if (err && gpg_err_code (err) != GPG_ERR_EOF)
808     fputs ("     authInfo: [error]\n", fp);
809   else if (!idx)
810     fputs ("     authInfo: [none]\n", fp);
811
812   /* subjectInfoAccess. */
813   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
814                                                          &name)); idx++)
815     {
816       fputs ("  subjectInfo: ", fp);
817       s = get_oid_desc (string, NULL);
818       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
819       print_names_raw (fp, -15, name);
820       ksba_name_release (name);
821       ksba_free (string);
822     }
823   if (err && gpg_err_code (err) != GPG_ERR_EOF)
824     fputs ("     subjInfo: [error]\n", fp);
825   else if (!idx)
826     fputs ("     subjInfo: [none]\n", fp);
827
828
829   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
830                                              &oid, &i, &off, &len));idx++)
831     {
832       unsigned int flag;
833
834       s = get_oid_desc (oid, &flag);
835
836       if (!(flag & 1))
837         fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
838                  i? "critExtn":"    extn",
839                  oid, s?" (":"", s?s:"", s?")":"", (int)len);
840     }
841
842
843   if (with_validation)
844     {
845       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
846       if (!err)
847         fprintf (fp, "  [certificate is good]\n");
848       else
849         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
850     }
851
852   if (opt.with_ephemeral_keys && hd)
853     {
854       unsigned int blobflags;
855
856       err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
857       if (err)
858         fprintf (fp, "  [error getting keyflags: %s]\n", gpg_strerror (err));
859       else if ((blobflags & 2))
860         fprintf (fp, "  [stored as ephemeral]\n");
861     }
862
863 }
864
865
866
867
868 /* List one certificate in standard mode */
869 static void
870 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
871                int with_validation)
872 {
873   gpg_error_t err;
874   ksba_sexp_t sexp;
875   char *dn;
876   ksba_isotime_t t;
877   int idx, i;
878   int is_ca, chainlen;
879   unsigned int kusage;
880   char *string, *p, *pend;
881
882   sexp = ksba_cert_get_serial (cert);
883   fputs ("Serial number: ", fp);
884   gpgsm_print_serial (fp, sexp);
885   ksba_free (sexp);
886   putc ('\n', fp);
887
888   dn = ksba_cert_get_issuer (cert, 0);
889   fputs ("       Issuer: ", fp);
890   gpgsm_print_name (fp, dn);
891   ksba_free (dn);
892   putc ('\n', fp);
893   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
894     {
895       fputs ("          aka: ", fp);
896       gpgsm_print_name (fp, dn);
897       ksba_free (dn);
898       putc ('\n', fp);
899     }
900
901   dn = ksba_cert_get_subject (cert, 0);
902   fputs ("      Subject: ", fp);
903   gpgsm_print_name (fp, dn);
904   ksba_free (dn);
905   putc ('\n', fp);
906   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
907     {
908       fputs ("          aka: ", fp);
909       gpgsm_print_name (fp, dn);
910       ksba_free (dn);
911       putc ('\n', fp);
912     }
913
914   ksba_cert_get_validity (cert, 0, t);
915   fputs ("     validity: ", fp);
916   gpgsm_print_time (fp, t);
917   fputs (" through ", fp);
918   ksba_cert_get_validity (cert, 1, t);
919   gpgsm_print_time (fp, t);
920   putc ('\n', fp);
921
922
923   {
924     const char *algoname;
925     unsigned int nbits;
926
927     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
928     fprintf (fp, "     key type: %u bit %s\n", nbits, algoname? algoname:"?");
929   }
930
931
932   err = ksba_cert_get_key_usage (cert, &kusage);
933   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
934     {
935       fputs ("    key usage:", fp);
936       if (err)
937         fprintf (fp, " [error: %s]", gpg_strerror (err));
938       else
939         {
940           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
941             fputs (" digitalSignature", fp);
942           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
943             fputs (" nonRepudiation", fp);
944           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
945             fputs (" keyEncipherment", fp);
946           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
947             fputs (" dataEncipherment", fp);
948           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
949             fputs (" keyAgreement", fp);
950           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
951             fputs (" certSign", fp);
952           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
953             fputs (" crlSign", fp);
954           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
955             fputs (" encipherOnly", fp);
956           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
957             fputs (" decipherOnly", fp);
958         }
959       putc ('\n', fp);
960     }
961
962   err = ksba_cert_get_ext_key_usages (cert, &string);
963   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
964     { 
965       fputs ("ext key usage: ", fp);
966       if (err)
967         fprintf (fp, "[error: %s]", gpg_strerror (err));
968       else
969         {
970           p = string;
971           while (p && (pend=strchr (p, ':')))
972             {
973               *pend++ = 0;
974               for (i=0; key_purpose_map[i].oid; i++)
975                 if ( !strcmp (key_purpose_map[i].oid, p) )
976                   break;
977               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
978               p = pend;
979               if (*p != 'C')
980                 fputs (" (suggested)", fp);
981               if ((p = strchr (p, '\n')))
982                 {
983                   p++;
984                   fputs (", ", fp);
985                 }
986             }
987           xfree (string);
988         }
989       putc ('\n', fp);
990     }
991
992   err = ksba_cert_get_cert_policies (cert, &string);
993   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
994     {
995       fputs ("     policies: ", fp);
996       if (err)
997         fprintf (fp, "[error: %s]", gpg_strerror (err));
998       else
999         {
1000           for (p=string; *p; p++)
1001             {
1002               if (*p == '\n')
1003                 *p = ',';
1004             }
1005           print_sanitized_string (fp, string, 0);
1006           xfree (string);
1007         }
1008       putc ('\n', fp);
1009     }
1010
1011   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1012   if (err || is_ca)
1013     {
1014       fputs (" chain length: ", fp);
1015       if (err)
1016         fprintf (fp, "[error: %s]", gpg_strerror (err));
1017       else if (chainlen == -1)
1018         fputs ("unlimited", fp);
1019       else
1020         fprintf (fp, "%d", chainlen);
1021       putc ('\n', fp);
1022     }
1023
1024   if (opt.with_md5_fingerprint)
1025     {
1026       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1027       fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
1028       xfree (dn);
1029     }
1030
1031   dn = gpgsm_get_fingerprint_string (cert, 0);
1032   fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
1033   xfree (dn);
1034
1035   if (with_validation)
1036     {
1037       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
1038       if (!err)
1039         fprintf (fp, "  [certificate is good]\n");
1040       else
1041         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1042     }
1043 }
1044
1045
1046 /* Same as standard mode mode list all certifying certs too. */
1047 static void
1048 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1049                  ksba_cert_t cert, int raw_mode,
1050                  FILE *fp, int with_validation)
1051 {
1052   ksba_cert_t next = NULL;
1053
1054   if (raw_mode)
1055     list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1056   else
1057     list_cert_std (ctrl, cert, fp, 0, with_validation);
1058   ksba_cert_ref (cert);
1059   while (!gpgsm_walk_cert_chain (cert, &next))
1060     {
1061       ksba_cert_release (cert);
1062       fputs ("Certified by\n", fp);
1063       if (raw_mode)
1064         list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1065       else
1066         list_cert_std (ctrl, next, fp, 0, with_validation);
1067       cert = next;
1068     }
1069   ksba_cert_release (cert);
1070   putc ('\n', fp);
1071 }
1072
1073
1074 \f
1075 /* List all internal keys or just the keys given as NAMES.  MODE is a
1076    bit vector to specify what keys are to be included; see
1077    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
1078    output mode will be used intead of the standard beautified one.
1079  */
1080 static gpg_error_t
1081 list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp,
1082                     unsigned int mode, int raw_mode)
1083 {
1084   KEYDB_HANDLE hd;
1085   KEYDB_SEARCH_DESC *desc = NULL;
1086   STRLIST sl;
1087   int ndesc;
1088   ksba_cert_t cert = NULL;
1089   gpg_error_t rc = 0;
1090   const char *lastresname, *resname;
1091   int have_secret;
1092
1093   hd = keydb_new (0);
1094   if (!hd)
1095     {
1096       log_error ("keydb_new failed\n");
1097       rc = gpg_error (GPG_ERR_GENERAL);
1098       goto leave;
1099     }
1100
1101   if (!names)
1102     ndesc = 1;
1103   else
1104     {
1105       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1106         ;
1107     }
1108
1109   desc = xtrycalloc (ndesc, sizeof *desc);
1110   if (!ndesc)
1111     {
1112       rc = gpg_error_from_errno (errno);
1113       log_error ("out of core\n");
1114       goto leave;
1115     }
1116
1117   if (!names)
1118     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1119   else 
1120     {
1121       for (ndesc=0, sl=names; sl; sl = sl->next) 
1122         {
1123           rc = keydb_classify_name (sl->d, desc+ndesc);
1124           if (rc)
1125             {
1126               log_error ("key `%s' not found: %s\n",
1127                          sl->d, gpg_strerror (rc));
1128               rc = 0;
1129             }
1130           else
1131             ndesc++;
1132         }
1133       
1134     }
1135
1136   if (opt.with_ephemeral_keys)
1137     keydb_set_ephemeral (hd, 1);
1138
1139   /* It would be nice to see which of the given users did actually
1140      match one in the keyring.  To implement this we need to have a
1141      found flag for each entry in desc and to set this we must check
1142      all those entries after a match to mark all matched one -
1143      currently we stop at the first match.  To do this we need an
1144      extra flag to enable this feature so */
1145
1146   lastresname = NULL;
1147   while (!(rc = keydb_search (hd, desc, ndesc)))
1148     {
1149       unsigned int validity;
1150
1151       if (!names) 
1152         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1153
1154       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1155       if (rc)
1156         {
1157           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1158           goto leave;
1159         }
1160       rc = keydb_get_cert (hd, &cert);
1161       if (rc) 
1162         {
1163           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1164           goto leave;
1165         }
1166       
1167       resname = keydb_get_resource_name (hd);
1168       
1169       if (lastresname != resname ) 
1170         {
1171           int i;
1172           
1173           if (ctrl->no_server)
1174             {
1175               fprintf (fp, "%s\n", resname );
1176               for (i=strlen(resname); i; i-- )
1177                 putchar('-');
1178               putc ('\n', fp);
1179               lastresname = resname;
1180             }
1181         }
1182
1183       have_secret = 0;
1184       if (mode)
1185         {
1186           char *p = gpgsm_get_keygrip_hexstring (cert);
1187           if (p)
1188             {
1189               rc = gpgsm_agent_havekey (ctrl, p); 
1190              if (!rc)
1191                 have_secret = 1;
1192               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1193                 goto leave;
1194               rc = 0;
1195               xfree (p);
1196             }
1197         }
1198
1199       if (!mode
1200           || ((mode & 1) && !have_secret)
1201           || ((mode & 2) && have_secret)  )
1202         {
1203           if (ctrl->with_colons)
1204             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1205           else if (ctrl->with_chain)
1206             list_cert_chain (ctrl, hd, cert,
1207                              raw_mode, fp, ctrl->with_validation);
1208           else
1209             {
1210               if (raw_mode)
1211                 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1212                                ctrl->with_validation);
1213               else
1214                 list_cert_std (ctrl, cert, fp, have_secret,
1215                                ctrl->with_validation);
1216               putc ('\n', fp);
1217             }
1218         }
1219       ksba_cert_release (cert); 
1220       cert = NULL;
1221     }
1222   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1223     rc = 0;
1224   if (rc)
1225     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1226   
1227  leave:
1228   ksba_cert_release (cert);
1229   xfree (desc);
1230   keydb_release (hd);
1231   return rc;
1232 }
1233
1234
1235
1236 static void
1237 list_external_cb (void *cb_value, ksba_cert_t cert)
1238 {
1239   struct list_external_parm_s *parm = cb_value;
1240
1241   if (keydb_store_cert (cert, 1, NULL))
1242     log_error ("error storing certificate as ephemeral\n");
1243
1244   if (parm->print_header)
1245     {
1246       const char *resname = "[external keys]";
1247       int i;
1248
1249       fprintf (parm->fp, "%s\n", resname );
1250       for (i=strlen(resname); i; i-- )
1251         putchar('-');
1252       putc ('\n', parm->fp);
1253       parm->print_header = 0;
1254     }
1255
1256   if (parm->with_colons)
1257     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1258   else if (parm->with_chain)
1259     list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1260   else
1261     {
1262       if (parm->raw_mode)
1263         list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1264       else
1265         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1266       putc ('\n', parm->fp);
1267     }
1268 }
1269
1270
1271 /* List external keys similar to internal one.  Note: mode does not
1272    make sense here because it would be unwise to list external secret
1273    keys */
1274 static gpg_error_t
1275 list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode)
1276 {
1277   int rc;
1278   struct list_external_parm_s parm;
1279
1280   parm.fp = fp;
1281   parm.ctrl = ctrl,
1282   parm.print_header = ctrl->no_server;
1283   parm.with_colons = ctrl->with_colons;
1284   parm.with_chain = ctrl->with_chain;
1285   parm.raw_mode  = raw_mode;
1286
1287   rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
1288   if (rc)
1289     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1290   return rc;
1291 }
1292
1293 /* List all keys or just the key given as NAMES.
1294    MODE controls the operation mode: 
1295     Bit 0-2:
1296       0 = list all public keys but don't flag secret ones
1297       1 = list only public keys
1298       2 = list only secret keys
1299       3 = list secret and public keys
1300     Bit 6: list internal keys
1301     Bit 7: list external keys
1302     Bit 8: Do a raw format dump.
1303  */
1304 gpg_error_t
1305 gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
1306 {
1307   gpg_error_t err = 0;
1308
1309   if ((mode & (1<<6)))
1310     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1311   if (!err && (mode & (1<<7)))
1312     err = list_external_keys (ctrl, names, fp, (mode&256)); 
1313   return err;
1314 }