(oidtranstbl): New. OIDs collected from several sources.
[gnupg.git] / sm / keylist.c
1 /* keylist.c
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3  *               2004 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"},
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 unsigned char *p;
260   unsigned char *buf;
261   int n;
262
263   if (strncmp (name, "1.2.840.113549.1.9.1=#", 22))
264     return NULL;
265   /* This looks pretty much like an email address in the subject's DN
266      we use this to add an additional user ID entry.  This way,
267      openSSL generated keys get a nicer and usable listing */
268   name += 22;    
269   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
270     ;
271   if (*p != '#' || !n)
272     return NULL;
273   buf = xtrymalloc (n+3);
274   if (!buf)
275     return NULL; /* oops, out of core */
276   *buf = '<';
277   for (n=1, p=name; *p != '#'; p +=2, n++)
278     buf[n] = xtoi_2 (p);
279   buf[n++] = '>';
280   buf[n] = 0;
281   return buf;
282 }
283
284
285
286
287 /* List one certificate in colon mode */
288 static void
289 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
290                  FILE *fp, int have_secret)
291 {
292   int idx;
293   char truststring[2];
294   char *p;
295   ksba_sexp_t sexp;
296   char *fpr;
297   ksba_isotime_t t;
298   gpg_error_t valerr;
299
300   if (ctrl->with_validation)
301     valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
302   else
303     valerr = 0;
304
305   fputs (have_secret? "crs:":"crt:", fp);
306   truststring[0] = 0;
307   truststring[1] = 0;
308   if ((validity & VALIDITY_REVOKED)
309       || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
310     *truststring = 'r';
311   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
312     *truststring = 'e';
313   else if (valerr)
314     *truststring = 'i';
315   else 
316     {
317       /* Lets also check whether the certificate under question
318          expired.  This is merely a hack until we found a proper way
319          to store the expiration flag in the keybox. */
320       ksba_isotime_t current_time, not_after;
321   
322       gnupg_get_isotime (current_time);
323       if (!opt.ignore_expiration
324           && !ksba_cert_get_validity (cert, 1, not_after)
325           && *not_after && strcmp (current_time, not_after) > 0 )
326         *truststring = 'e';
327     }
328   
329   if (*truststring)
330     fputs (truststring, fp);
331
332   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
333   fprintf (fp, ":%u:%d:%s:",
334            /*keylen_of_cert (cert)*/1024,
335            /* pubkey_algo_of_cert (cert)*/1,
336            fpr+24);
337
338   /* We assume --fixed-list-mode for gpgsm */
339   ksba_cert_get_validity (cert, 0, t);
340   print_time (t, fp);
341   putc (':', fp);
342   ksba_cert_get_validity (cert, 1, t);
343   print_time ( t, fp);
344   putc (':', fp);
345   /* Field 8, serial number: */
346   if ((sexp = ksba_cert_get_serial (cert)))
347     {
348       int len;
349       const unsigned char *s = sexp;
350       
351       if (*s == '(')
352         {
353           s++;
354           for (len=0; *s && *s != ':' && digitp (s); s++)
355             len = len*10 + atoi_1 (s);
356           if (*s == ':')
357             for (s++; len; len--, s++)
358               fprintf (fp,"%02X", *s);
359         }
360       xfree (sexp);
361     }
362   putc (':', fp);
363   /* Field 9, ownertrust - not used here */
364   putc (':', fp);
365   /* field 10, old user ID - we use it here for the issuer DN */
366   if ((p = ksba_cert_get_issuer (cert,0)))
367     {
368       print_sanitized_string (fp, p, ':');
369       xfree (p);
370     }
371   putc (':', fp);
372   /* Field 11, signature class - not used */ 
373   putc (':', fp);
374   /* Field 12, capabilities: */ 
375   print_capabilities (cert, fp);
376   putc (':', fp);
377   putc ('\n', fp);
378
379   /* FPR record */
380   fprintf (fp, "fpr:::::::::%s:::", fpr);
381   /* Print chaining ID (field 13)*/
382   {
383     ksba_cert_t next;
384     int rc;
385     
386     rc = gpgsm_walk_cert_chain (cert, &next);
387     if (!rc) /* We known the issuer's certificate. */
388       {
389         p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
390         fputs (p, fp);
391         xfree (p);
392         ksba_cert_release (next);
393       }
394     else if (rc == -1)  /* We reached the root certificate. */
395       {
396         fputs (fpr, fp);
397       }
398   }
399   putc (':', fp);
400   putc ('\n', fp);
401   xfree (fpr); fpr = NULL;
402
403
404   if (opt.with_key_data)
405     {
406       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
407         {
408           fprintf (fp, "grp:::::::::%s:\n", p);
409           xfree (p);
410         }
411       print_key_data (cert, fp);
412     }
413
414   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
415     {
416       fprintf (fp, "uid:%s::::::::", truststring);
417       print_sanitized_string (fp, p, ':');
418       putc (':', fp);
419       putc (':', fp);
420       putc ('\n', fp);
421       if (!idx)
422         {
423           /* It would be better to get the faked email address from
424              the keydb.  But as long as we don't have a way to pass
425              the meta data back, we just check it the same way as the
426              code used to create the keybox meta data does */
427           char *pp = email_kludge (p);
428           if (pp)
429             {
430               fprintf (fp, "uid:%s::::::::", truststring);
431               print_sanitized_string (fp, pp, ':');
432               putc (':', fp);
433               putc (':', fp);
434               putc ('\n', fp);
435               xfree (pp);
436             }
437         }
438       xfree (p);
439     }
440 }
441
442
443 static void
444 print_name_raw (FILE *fp, const char *string)
445 {
446   if (!string)
447     fputs ("[error]", fp);
448   else
449     print_sanitized_string (fp, string, 0);
450 }
451
452 static void
453 print_names_raw (FILE *fp, int indent, ksba_name_t name)
454 {
455   int idx;
456   const char *s;
457   int indent_all;
458
459   if ((indent_all = (indent < 0)))
460     indent = - indent;
461
462   if (!name)
463     {
464       fputs ("none\n", fp);
465       return;
466     }
467   
468   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
469     {
470       char *p = ksba_name_get_uri (name, idx);
471       printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s);
472       xfree (p);
473     }
474 }
475
476
477 /* List one certificate in raw mode useful to have a closer look at
478    the certificate.  This one does not beautification and only minimal
479    output sanitation.  It is mainly useful for debugging. */
480 static void
481 list_cert_raw (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
482                int with_validation)
483 {
484   gpg_error_t err;
485   size_t off, len;
486   ksba_sexp_t sexp;
487   char *dn;
488   ksba_isotime_t t;
489   int idx, i;
490   int is_ca, chainlen;
491   unsigned int kusage;
492   char *string, *p, *pend;
493   const char *oid, *s;
494   ksba_name_t name, name2;
495   unsigned int reason;
496
497   sexp = ksba_cert_get_serial (cert);
498   fputs ("Serial number: ", fp);
499   gpgsm_print_serial (fp, sexp);
500   ksba_free (sexp);
501   putc ('\n', fp);
502
503   dn = ksba_cert_get_issuer (cert, 0);
504   fputs ("       Issuer: ", fp);
505   print_name_raw (fp, dn);
506   ksba_free (dn);
507   putc ('\n', fp);
508   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
509     {
510       fputs ("          aka: ", fp);
511       print_name_raw (fp, dn);
512       ksba_free (dn);
513       putc ('\n', fp);
514     }
515
516   dn = ksba_cert_get_subject (cert, 0);
517   fputs ("      Subject: ", fp);
518   print_name_raw (fp, dn);
519   ksba_free (dn);
520   putc ('\n', fp);
521   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
522     {
523       fputs ("          aka: ", fp);
524       print_name_raw (fp, dn);
525       ksba_free (dn);
526       putc ('\n', fp);
527     }
528
529   dn = gpgsm_get_fingerprint_string (cert, 0);
530   fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
531   xfree (dn);
532
533   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
534   fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
535   xfree (dn);
536
537   ksba_cert_get_validity (cert, 0, t);
538   fputs ("    notBefore: ", fp);
539   gpgsm_print_time (fp, t);
540   putc ('\n', fp);
541   fputs ("     notAfter: ", fp);
542   ksba_cert_get_validity (cert, 1, t);
543   gpgsm_print_time (fp, t);
544   putc ('\n', fp);
545
546   oid = ksba_cert_get_digest_algo (cert);
547   s = get_oid_desc (oid, NULL);
548   fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
549
550   /* authorityKeyIdentifier */
551   fputs ("    authKeyId: ", fp);
552   err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp);
553   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
554     {
555       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
556         fputs ("[none]\n", fp);
557       else
558         {
559           gpgsm_print_serial (fp, sexp);
560           ksba_free (sexp);
561           putc ('\n', fp);
562           print_names_raw (fp, -15, name);
563           ksba_name_release (name);
564         }
565     }
566   else
567     fputs ("[?]\n", fp);
568
569   fputs ("     keyUsage:", fp);
570   err = ksba_cert_get_key_usage (cert, &kusage);
571   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
572     {
573       if (err)
574         fprintf (fp, " [error: %s]", gpg_strerror (err));
575       else
576         {
577           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
578             fputs (" digitalSignature", fp);
579           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
580             fputs (" nonRepudiation", fp);
581           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
582             fputs (" keyEncipherment", fp);
583           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
584             fputs (" dataEncipherment", fp);
585           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
586             fputs (" keyAgreement", fp);
587           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
588             fputs (" certSign", fp);
589           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
590             fputs (" crlSign", fp);
591           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
592             fputs (" encipherOnly", fp);
593           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
594             fputs (" decipherOnly", fp);
595         }
596       putc ('\n', fp);
597     }
598   else
599     fputs ("[none]\n", fp);
600
601   fputs ("  extKeyUsage: ", fp);
602   err = ksba_cert_get_ext_key_usages (cert, &string);
603   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
604     { 
605       if (err)
606         fprintf (fp, "[error: %s]", gpg_strerror (err));
607       else
608         {
609           p = string;
610           while (p && (pend=strchr (p, ':')))
611             {
612               *pend++ = 0;
613               for (i=0; key_purpose_map[i].oid; i++)
614                 if ( !strcmp (key_purpose_map[i].oid, p) )
615                   break;
616               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
617               p = pend;
618               if (*p != 'C')
619                 fputs (" (suggested)", fp);
620               if ((p = strchr (p, '\n')))
621                 {
622                   p++;
623                   fputs ("\n               ", fp);
624                 }
625             }
626           xfree (string);
627         }
628       putc ('\n', fp);
629     }
630   else
631     fputs ("[none]\n", fp);
632
633
634   fputs ("     policies: ", fp);
635   err = ksba_cert_get_cert_policies (cert, &string);
636   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
637     {
638       if (err)
639         fprintf (fp, "[error: %s]", gpg_strerror (err));
640       else
641         {
642           p = string;
643           while (p && (pend=strchr (p, ':')))
644             {
645               *pend++ = 0;
646               for (i=0; key_purpose_map[i].oid; i++)
647                 if ( !strcmp (key_purpose_map[i].oid, p) )
648                   break;
649               fputs (p, fp);
650               p = pend;
651               if (*p == 'C')
652                 fputs (" (critical)", fp);
653               if ((p = strchr (p, '\n')))
654                 {
655                   p++;
656                   fputs ("\n               ", fp);
657                 }
658             }
659           xfree (string);
660         }
661       putc ('\n', fp);
662     }
663   else
664     fputs ("[none]\n", fp);
665
666   fputs ("  chainLength: ", fp);
667   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
668   if (err || is_ca)
669     {
670       if (err)
671         fprintf (fp, "[error: %s]", gpg_strerror (err));
672       else if (chainlen == -1)
673         fputs ("unlimited", fp);
674       else
675         fprintf (fp, "%d", chainlen);
676       putc ('\n', fp);
677     }
678   else
679     fputs ("not a CA\n", fp);
680
681
682   /* CRL distribution point */
683   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
684                                                   &reason)) ;idx++)
685     {
686       fputs ("        crlDP: ", fp);
687       print_names_raw (fp, 15, name);
688       if (reason)
689         {
690           fputs ("               reason: ", fp);
691           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
692             fputs (" unused", stdout);
693           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
694             fputs (" keyCompromise", stdout);
695           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
696             fputs (" caCompromise", stdout);
697           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
698             fputs (" affiliationChanged", stdout);
699           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
700             fputs (" superseded", stdout);
701           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
702             fputs (" cessationOfOperation", stdout);
703           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
704             fputs (" certificateHold", stdout);
705           putchar ('\n');
706         }
707       fputs ("               issuer: ", fp);
708       print_names_raw (fp, 23, name2);
709       ksba_name_release (name);
710       ksba_name_release (name2);
711     }
712   if (err && gpg_err_code (err) != GPG_ERR_EOF)
713     fputs ("        crlDP: [error]\n", fp);
714   else if (!idx)
715     fputs ("        crlDP: [none]\n", fp);
716
717
718   /* authorityInfoAccess. */
719   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
720                                                          &name)); idx++)
721     {
722       fputs ("     authInfo: ", fp);
723       s = get_oid_desc (string, NULL);
724       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
725       print_names_raw (fp, -15, name);
726       ksba_name_release (name);
727       ksba_free (string);
728     }
729   if (err && gpg_err_code (err) != GPG_ERR_EOF)
730     fputs ("     authInfo: [error]\n", fp);
731   else if (!idx)
732     fputs ("     authInfo: [none]\n", fp);
733
734   /* subjectInfoAccess. */
735   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
736                                                          &name)); idx++)
737     {
738       fputs ("  subjectInfo: ", fp);
739       s = get_oid_desc (string, NULL);
740       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
741       print_names_raw (fp, -15, name);
742       ksba_name_release (name);
743       ksba_free (string);
744     }
745   if (err && gpg_err_code (err) != GPG_ERR_EOF)
746     fputs ("     subjInfo: [error]\n", fp);
747   else if (!idx)
748     fputs ("     subjInfo: [none]\n", fp);
749
750
751   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
752                                              &oid, &i, &off, &len));idx++)
753     {
754       unsigned int flag;
755
756       s = get_oid_desc (oid, &flag);
757
758       if (!(flag & 1))
759         fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
760                  i? "critExtn":"    extn",
761                  oid, s?" (":"", s?s:"", s?")":"", (int)len);
762     }
763
764
765   if (with_validation)
766     {
767       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
768       if (!err)
769         fprintf (fp, "  [certificate is good]\n");
770       else
771         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
772     }
773 }
774
775
776
777
778 /* List one certificate in standard mode */
779 static void
780 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
781                int with_validation)
782 {
783   gpg_error_t err;
784   ksba_sexp_t sexp;
785   char *dn;
786   ksba_isotime_t t;
787   int idx, i;
788   int is_ca, chainlen;
789   unsigned int kusage;
790   char *string, *p, *pend;
791
792   sexp = ksba_cert_get_serial (cert);
793   fputs ("Serial number: ", fp);
794   gpgsm_print_serial (fp, sexp);
795   ksba_free (sexp);
796   putc ('\n', fp);
797
798   dn = ksba_cert_get_issuer (cert, 0);
799   fputs ("       Issuer: ", fp);
800   gpgsm_print_name (fp, dn);
801   ksba_free (dn);
802   putc ('\n', fp);
803   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
804     {
805       fputs ("          aka: ", fp);
806       gpgsm_print_name (fp, dn);
807       ksba_free (dn);
808       putc ('\n', fp);
809     }
810
811   dn = ksba_cert_get_subject (cert, 0);
812   fputs ("      Subject: ", fp);
813   gpgsm_print_name (fp, dn);
814   ksba_free (dn);
815   putc ('\n', fp);
816   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
817     {
818       fputs ("          aka: ", fp);
819       gpgsm_print_name (fp, dn);
820       ksba_free (dn);
821       putc ('\n', fp);
822     }
823
824   ksba_cert_get_validity (cert, 0, t);
825   fputs ("     validity: ", fp);
826   gpgsm_print_time (fp, t);
827   fputs (" through ", fp);
828   ksba_cert_get_validity (cert, 1, t);
829   gpgsm_print_time (fp, t);
830   putc ('\n', fp);
831
832   err = ksba_cert_get_key_usage (cert, &kusage);
833   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
834     {
835       fputs ("    key usage:", fp);
836       if (err)
837         fprintf (fp, " [error: %s]", gpg_strerror (err));
838       else
839         {
840           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
841             fputs (" digitalSignature", fp);
842           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
843             fputs (" nonRepudiation", fp);
844           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
845             fputs (" keyEncipherment", fp);
846           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
847             fputs (" dataEncipherment", fp);
848           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
849             fputs (" keyAgreement", fp);
850           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
851             fputs (" certSign", fp);
852           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
853             fputs (" crlSign", fp);
854           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
855             fputs (" encipherOnly", fp);
856           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
857             fputs (" decipherOnly", fp);
858         }
859       putc ('\n', fp);
860     }
861
862   err = ksba_cert_get_ext_key_usages (cert, &string);
863   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
864     { 
865       fputs ("ext key usage: ", fp);
866       if (err)
867         fprintf (fp, "[error: %s]", gpg_strerror (err));
868       else
869         {
870           p = string;
871           while (p && (pend=strchr (p, ':')))
872             {
873               *pend++ = 0;
874               for (i=0; key_purpose_map[i].oid; i++)
875                 if ( !strcmp (key_purpose_map[i].oid, p) )
876                   break;
877               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
878               p = pend;
879               if (*p != 'C')
880                 fputs (" (suggested)", fp);
881               if ((p = strchr (p, '\n')))
882                 {
883                   p++;
884                   fputs (", ", fp);
885                 }
886             }
887           xfree (string);
888         }
889       putc ('\n', fp);
890     }
891
892   err = ksba_cert_get_cert_policies (cert, &string);
893   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
894     {
895       fputs ("     policies: ", fp);
896       if (err)
897         fprintf (fp, "[error: %s]", gpg_strerror (err));
898       else
899         {
900           for (p=string; *p; p++)
901             {
902               if (*p == '\n')
903                 *p = ',';
904             }
905           print_sanitized_string (fp, string, 0);
906           xfree (string);
907         }
908       putc ('\n', fp);
909     }
910
911   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
912   if (err || is_ca)
913     {
914       fputs (" chain length: ", fp);
915       if (err)
916         fprintf (fp, "[error: %s]", gpg_strerror (err));
917       else if (chainlen == -1)
918         fputs ("unlimited", fp);
919       else
920         fprintf (fp, "%d", chainlen);
921       putc ('\n', fp);
922     }
923
924   if (opt.with_md5_fingerprint)
925     {
926       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
927       fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
928       xfree (dn);
929     }
930
931   dn = gpgsm_get_fingerprint_string (cert, 0);
932   fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
933   xfree (dn);
934
935   if (with_validation)
936     {
937       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
938       if (!err)
939         fprintf (fp, "  [certificate is good]\n");
940       else
941         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
942     }
943 }
944
945
946 /* Same as standard mode mode list all certifying certs too. */
947 static void
948 list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, int raw_mode,
949                  FILE *fp, int with_validation)
950 {
951   ksba_cert_t next = NULL;
952
953   if (raw_mode)
954     list_cert_raw (ctrl, cert, fp, 0, with_validation);
955   else
956     list_cert_std (ctrl, cert, fp, 0, with_validation);
957   ksba_cert_ref (cert);
958   while (!gpgsm_walk_cert_chain (cert, &next))
959     {
960       ksba_cert_release (cert);
961       fputs ("Certified by\n", fp);
962       if (raw_mode)
963         list_cert_raw (ctrl, next, fp, 0, with_validation);
964       else
965         list_cert_std (ctrl, next, fp, 0, with_validation);
966       cert = next;
967     }
968   ksba_cert_release (cert);
969   putc ('\n', fp);
970 }
971
972
973 \f
974 /* List all internal keys or just the keys given as NAMES.  MODE is a
975    bit vector to specify what keys are to be included; see
976    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
977    output mode will be used intead of the standard beautified one.
978  */
979 static gpg_error_t
980 list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp,
981                     unsigned int mode, int raw_mode)
982 {
983   KEYDB_HANDLE hd;
984   KEYDB_SEARCH_DESC *desc = NULL;
985   STRLIST sl;
986   int ndesc;
987   ksba_cert_t cert = NULL;
988   gpg_error_t rc = 0;
989   const char *lastresname, *resname;
990   int have_secret;
991
992   hd = keydb_new (0);
993   if (!hd)
994     {
995       log_error ("keydb_new failed\n");
996       rc = gpg_error (GPG_ERR_GENERAL);
997       goto leave;
998     }
999
1000   if (!names)
1001     ndesc = 1;
1002   else
1003     {
1004       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1005         ;
1006     }
1007
1008   desc = xtrycalloc (ndesc, sizeof *desc);
1009   if (!ndesc)
1010     {
1011       rc = gpg_error_from_errno (errno);
1012       log_error ("out of core\n");
1013       goto leave;
1014     }
1015
1016   if (!names)
1017     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1018   else 
1019     {
1020       for (ndesc=0, sl=names; sl; sl = sl->next) 
1021         {
1022           rc = keydb_classify_name (sl->d, desc+ndesc);
1023           if (rc)
1024             {
1025               log_error ("key `%s' not found: %s\n",
1026                          sl->d, gpg_strerror (rc));
1027               rc = 0;
1028             }
1029           else
1030             ndesc++;
1031         }
1032       
1033     }
1034
1035   /* It would be nice to see which of the given users did actually
1036      match one in the keyring.  To implement this we need to have a
1037      found flag for each entry in desc and to set this we must check
1038      all those entries after a match to mark all matched one -
1039      currently we stop at the first match.  To do this we need an
1040      extra flag to enable this feature so */
1041
1042   lastresname = NULL;
1043   while (!(rc = keydb_search (hd, desc, ndesc)))
1044     {
1045       unsigned int validity;
1046
1047       if (!names) 
1048         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1049
1050       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1051       if (rc)
1052         {
1053           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1054           goto leave;
1055         }
1056       rc = keydb_get_cert (hd, &cert);
1057       if (rc) 
1058         {
1059           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1060           goto leave;
1061         }
1062       
1063       resname = keydb_get_resource_name (hd);
1064       
1065       if (lastresname != resname ) 
1066         {
1067           int i;
1068           
1069           if (ctrl->no_server)
1070             {
1071               fprintf (fp, "%s\n", resname );
1072               for (i=strlen(resname); i; i-- )
1073                 putchar('-');
1074               putc ('\n', fp);
1075               lastresname = resname;
1076             }
1077         }
1078
1079       have_secret = 0;
1080       if (mode)
1081         {
1082           char *p = gpgsm_get_keygrip_hexstring (cert);
1083           if (p)
1084             {
1085               rc = gpgsm_agent_havekey (p);
1086               if (!rc)
1087                 have_secret = 1;
1088               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1089                 goto leave;
1090               rc = 0;
1091               xfree (p);
1092             }
1093         }
1094
1095       if (!mode
1096           || ((mode & 1) && !have_secret)
1097           || ((mode & 2) && have_secret)  )
1098         {
1099           if (ctrl->with_colons)
1100             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1101           else if (ctrl->with_chain)
1102             list_cert_chain (ctrl, cert, raw_mode, fp, ctrl->with_validation);
1103           else
1104             {
1105               if (raw_mode)
1106                 list_cert_raw (ctrl, cert, fp, have_secret,
1107                                ctrl->with_validation);
1108               else
1109                 list_cert_std (ctrl, cert, fp, have_secret,
1110                                ctrl->with_validation);
1111               putc ('\n', fp);
1112             }
1113         }
1114       ksba_cert_release (cert); 
1115       cert = NULL;
1116     }
1117   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1118     rc = 0;
1119   if (rc)
1120     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1121   
1122  leave:
1123   ksba_cert_release (cert);
1124   xfree (desc);
1125   keydb_release (hd);
1126   return rc;
1127 }
1128
1129
1130
1131 static void
1132 list_external_cb (void *cb_value, ksba_cert_t cert)
1133 {
1134   struct list_external_parm_s *parm = cb_value;
1135
1136   if (keydb_store_cert (cert, 1, NULL))
1137     log_error ("error storing certificate as ephemeral\n");
1138
1139   if (parm->print_header)
1140     {
1141       const char *resname = "[external keys]";
1142       int i;
1143
1144       fprintf (parm->fp, "%s\n", resname );
1145       for (i=strlen(resname); i; i-- )
1146         putchar('-');
1147       putc ('\n', parm->fp);
1148       parm->print_header = 0;
1149     }
1150
1151   if (parm->with_colons)
1152     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1153   else if (parm->with_chain)
1154     list_cert_chain (parm->ctrl, cert, parm->raw_mode, parm->fp, 0);
1155   else
1156     {
1157       if (parm->raw_mode)
1158         list_cert_raw (parm->ctrl, cert, parm->fp, 0, 0);
1159       else
1160         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1161       putc ('\n', parm->fp);
1162     }
1163 }
1164
1165
1166 /* List external keys similar to internal one.  Note: mode does not
1167    make sense here because it would be unwise to list external secret
1168    keys */
1169 static gpg_error_t
1170 list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode)
1171 {
1172   int rc;
1173   struct list_external_parm_s parm;
1174
1175   parm.fp = fp;
1176   parm.ctrl = ctrl,
1177   parm.print_header = ctrl->no_server;
1178   parm.with_colons = ctrl->with_colons;
1179   parm.with_chain = ctrl->with_chain;
1180   parm.raw_mode  = raw_mode;
1181
1182   rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
1183   if (rc)
1184     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1185   return rc;
1186 }
1187
1188 /* List all keys or just the key given as NAMES.
1189    MODE controls the operation mode: 
1190     Bit 0-2:
1191       0 = list all public keys but don't flag secret ones
1192       1 = list only public keys
1193       2 = list only secret keys
1194       3 = list secret and public keys
1195     Bit 6: list internal keys
1196     Bit 7: list external keys
1197     Bit 8: Do a raw format dump.
1198  */
1199 gpg_error_t
1200 gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
1201 {
1202   gpg_error_t err = 0;
1203
1204   if ((mode & (1<<6)))
1205     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1206   if (!err && (mode & (1<<7)))
1207     err = list_external_keys (ctrl, names, fp, (mode&256)); 
1208   return err;
1209 }