e9056b6dad8d193872e21c9feabf77e3e06bcff9
[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   int algo;
300   unsigned int nbits;
301
302   if (ctrl->with_validation)
303     valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
304   else
305     valerr = 0;
306
307   fputs (have_secret? "crs:":"crt:", fp);
308   truststring[0] = 0;
309   truststring[1] = 0;
310   if ((validity & VALIDITY_REVOKED)
311       || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
312     *truststring = 'r';
313   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
314     *truststring = 'e';
315   else if (valerr)
316     *truststring = 'i';
317   else 
318     {
319       /* Lets also check whether the certificate under question
320          expired.  This is merely a hack until we found a proper way
321          to store the expiration flag in the keybox. */
322       ksba_isotime_t current_time, not_after;
323   
324       gnupg_get_isotime (current_time);
325       if (!opt.ignore_expiration
326           && !ksba_cert_get_validity (cert, 1, not_after)
327           && *not_after && strcmp (current_time, not_after) > 0 )
328         *truststring = 'e';
329     }
330   
331   if (*truststring)
332     fputs (truststring, fp);
333
334   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
335   algo = gpgsm_get_key_algo_info (cert, &nbits);
336   fprintf (fp, ":%u:%d:%s:", nbits, algo, 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   {
551     const char *algoname;
552     unsigned int nbits;
553
554     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
555     fprintf (fp, "      keyType: %u bit %s\n",  nbits, algoname? algoname:"?");
556   }
557
558   /* authorityKeyIdentifier */
559   fputs ("    authKeyId: ", fp);
560   err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp);
561   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
562     {
563       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
564         fputs ("[none]\n", fp);
565       else
566         {
567           gpgsm_print_serial (fp, sexp);
568           ksba_free (sexp);
569           putc ('\n', fp);
570           print_names_raw (fp, -15, name);
571           ksba_name_release (name);
572         }
573     }
574   else
575     fputs ("[?]\n", fp);
576
577   fputs ("     keyUsage:", fp);
578   err = ksba_cert_get_key_usage (cert, &kusage);
579   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
580     {
581       if (err)
582         fprintf (fp, " [error: %s]", gpg_strerror (err));
583       else
584         {
585           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
586             fputs (" digitalSignature", fp);
587           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
588             fputs (" nonRepudiation", fp);
589           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
590             fputs (" keyEncipherment", fp);
591           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
592             fputs (" dataEncipherment", fp);
593           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
594             fputs (" keyAgreement", fp);
595           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
596             fputs (" certSign", fp);
597           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
598             fputs (" crlSign", fp);
599           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
600             fputs (" encipherOnly", fp);
601           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
602             fputs (" decipherOnly", fp);
603         }
604       putc ('\n', fp);
605     }
606   else
607     fputs ("[none]\n", fp);
608
609   fputs ("  extKeyUsage: ", fp);
610   err = ksba_cert_get_ext_key_usages (cert, &string);
611   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
612     { 
613       if (err)
614         fprintf (fp, "[error: %s]", gpg_strerror (err));
615       else
616         {
617           p = string;
618           while (p && (pend=strchr (p, ':')))
619             {
620               *pend++ = 0;
621               for (i=0; key_purpose_map[i].oid; i++)
622                 if ( !strcmp (key_purpose_map[i].oid, p) )
623                   break;
624               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
625               p = pend;
626               if (*p != 'C')
627                 fputs (" (suggested)", fp);
628               if ((p = strchr (p, '\n')))
629                 {
630                   p++;
631                   fputs ("\n               ", fp);
632                 }
633             }
634           xfree (string);
635         }
636       putc ('\n', fp);
637     }
638   else
639     fputs ("[none]\n", fp);
640
641
642   fputs ("     policies: ", fp);
643   err = ksba_cert_get_cert_policies (cert, &string);
644   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
645     {
646       if (err)
647         fprintf (fp, "[error: %s]", gpg_strerror (err));
648       else
649         {
650           p = string;
651           while (p && (pend=strchr (p, ':')))
652             {
653               *pend++ = 0;
654               for (i=0; key_purpose_map[i].oid; i++)
655                 if ( !strcmp (key_purpose_map[i].oid, p) )
656                   break;
657               fputs (p, fp);
658               p = pend;
659               if (*p == 'C')
660                 fputs (" (critical)", fp);
661               if ((p = strchr (p, '\n')))
662                 {
663                   p++;
664                   fputs ("\n               ", fp);
665                 }
666             }
667           xfree (string);
668         }
669       putc ('\n', fp);
670     }
671   else
672     fputs ("[none]\n", fp);
673
674   fputs ("  chainLength: ", fp);
675   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
676   if (err || is_ca)
677     {
678       if (err)
679         fprintf (fp, "[error: %s]", gpg_strerror (err));
680       else if (chainlen == -1)
681         fputs ("unlimited", fp);
682       else
683         fprintf (fp, "%d", chainlen);
684       putc ('\n', fp);
685     }
686   else
687     fputs ("not a CA\n", fp);
688
689
690   /* CRL distribution point */
691   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
692                                                   &reason)) ;idx++)
693     {
694       fputs ("        crlDP: ", fp);
695       print_names_raw (fp, 15, name);
696       if (reason)
697         {
698           fputs ("               reason: ", fp);
699           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
700             fputs (" unused", stdout);
701           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
702             fputs (" keyCompromise", stdout);
703           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
704             fputs (" caCompromise", stdout);
705           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
706             fputs (" affiliationChanged", stdout);
707           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
708             fputs (" superseded", stdout);
709           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
710             fputs (" cessationOfOperation", stdout);
711           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
712             fputs (" certificateHold", stdout);
713           putchar ('\n');
714         }
715       fputs ("               issuer: ", fp);
716       print_names_raw (fp, 23, name2);
717       ksba_name_release (name);
718       ksba_name_release (name2);
719     }
720   if (err && gpg_err_code (err) != GPG_ERR_EOF)
721     fputs ("        crlDP: [error]\n", fp);
722   else if (!idx)
723     fputs ("        crlDP: [none]\n", fp);
724
725
726   /* authorityInfoAccess. */
727   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
728                                                          &name)); idx++)
729     {
730       fputs ("     authInfo: ", fp);
731       s = get_oid_desc (string, NULL);
732       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
733       print_names_raw (fp, -15, name);
734       ksba_name_release (name);
735       ksba_free (string);
736     }
737   if (err && gpg_err_code (err) != GPG_ERR_EOF)
738     fputs ("     authInfo: [error]\n", fp);
739   else if (!idx)
740     fputs ("     authInfo: [none]\n", fp);
741
742   /* subjectInfoAccess. */
743   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
744                                                          &name)); idx++)
745     {
746       fputs ("  subjectInfo: ", fp);
747       s = get_oid_desc (string, NULL);
748       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
749       print_names_raw (fp, -15, name);
750       ksba_name_release (name);
751       ksba_free (string);
752     }
753   if (err && gpg_err_code (err) != GPG_ERR_EOF)
754     fputs ("     subjInfo: [error]\n", fp);
755   else if (!idx)
756     fputs ("     subjInfo: [none]\n", fp);
757
758
759   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
760                                              &oid, &i, &off, &len));idx++)
761     {
762       unsigned int flag;
763
764       s = get_oid_desc (oid, &flag);
765
766       if (!(flag & 1))
767         fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
768                  i? "critExtn":"    extn",
769                  oid, s?" (":"", s?s:"", s?")":"", (int)len);
770     }
771
772
773   if (with_validation)
774     {
775       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
776       if (!err)
777         fprintf (fp, "  [certificate is good]\n");
778       else
779         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
780     }
781 }
782
783
784
785
786 /* List one certificate in standard mode */
787 static void
788 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
789                int with_validation)
790 {
791   gpg_error_t err;
792   ksba_sexp_t sexp;
793   char *dn;
794   ksba_isotime_t t;
795   int idx, i;
796   int is_ca, chainlen;
797   unsigned int kusage;
798   char *string, *p, *pend;
799
800   sexp = ksba_cert_get_serial (cert);
801   fputs ("Serial number: ", fp);
802   gpgsm_print_serial (fp, sexp);
803   ksba_free (sexp);
804   putc ('\n', fp);
805
806   dn = ksba_cert_get_issuer (cert, 0);
807   fputs ("       Issuer: ", fp);
808   gpgsm_print_name (fp, dn);
809   ksba_free (dn);
810   putc ('\n', fp);
811   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
812     {
813       fputs ("          aka: ", fp);
814       gpgsm_print_name (fp, dn);
815       ksba_free (dn);
816       putc ('\n', fp);
817     }
818
819   dn = ksba_cert_get_subject (cert, 0);
820   fputs ("      Subject: ", fp);
821   gpgsm_print_name (fp, dn);
822   ksba_free (dn);
823   putc ('\n', fp);
824   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
825     {
826       fputs ("          aka: ", fp);
827       gpgsm_print_name (fp, dn);
828       ksba_free (dn);
829       putc ('\n', fp);
830     }
831
832   ksba_cert_get_validity (cert, 0, t);
833   fputs ("     validity: ", fp);
834   gpgsm_print_time (fp, t);
835   fputs (" through ", fp);
836   ksba_cert_get_validity (cert, 1, t);
837   gpgsm_print_time (fp, t);
838   putc ('\n', fp);
839
840
841   {
842     const char *algoname;
843     unsigned int nbits;
844
845     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
846     fprintf (fp, "     key type: %u bit %s\n", nbits, algoname? algoname:"?");
847   }
848
849
850   err = ksba_cert_get_key_usage (cert, &kusage);
851   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
852     {
853       fputs ("    key usage:", fp);
854       if (err)
855         fprintf (fp, " [error: %s]", gpg_strerror (err));
856       else
857         {
858           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
859             fputs (" digitalSignature", fp);
860           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
861             fputs (" nonRepudiation", fp);
862           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
863             fputs (" keyEncipherment", fp);
864           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
865             fputs (" dataEncipherment", fp);
866           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
867             fputs (" keyAgreement", fp);
868           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
869             fputs (" certSign", fp);
870           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
871             fputs (" crlSign", fp);
872           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
873             fputs (" encipherOnly", fp);
874           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
875             fputs (" decipherOnly", fp);
876         }
877       putc ('\n', fp);
878     }
879
880   err = ksba_cert_get_ext_key_usages (cert, &string);
881   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
882     { 
883       fputs ("ext key usage: ", fp);
884       if (err)
885         fprintf (fp, "[error: %s]", gpg_strerror (err));
886       else
887         {
888           p = string;
889           while (p && (pend=strchr (p, ':')))
890             {
891               *pend++ = 0;
892               for (i=0; key_purpose_map[i].oid; i++)
893                 if ( !strcmp (key_purpose_map[i].oid, p) )
894                   break;
895               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
896               p = pend;
897               if (*p != 'C')
898                 fputs (" (suggested)", fp);
899               if ((p = strchr (p, '\n')))
900                 {
901                   p++;
902                   fputs (", ", fp);
903                 }
904             }
905           xfree (string);
906         }
907       putc ('\n', fp);
908     }
909
910   err = ksba_cert_get_cert_policies (cert, &string);
911   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
912     {
913       fputs ("     policies: ", fp);
914       if (err)
915         fprintf (fp, "[error: %s]", gpg_strerror (err));
916       else
917         {
918           for (p=string; *p; p++)
919             {
920               if (*p == '\n')
921                 *p = ',';
922             }
923           print_sanitized_string (fp, string, 0);
924           xfree (string);
925         }
926       putc ('\n', fp);
927     }
928
929   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
930   if (err || is_ca)
931     {
932       fputs (" chain length: ", fp);
933       if (err)
934         fprintf (fp, "[error: %s]", gpg_strerror (err));
935       else if (chainlen == -1)
936         fputs ("unlimited", fp);
937       else
938         fprintf (fp, "%d", chainlen);
939       putc ('\n', fp);
940     }
941
942   if (opt.with_md5_fingerprint)
943     {
944       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
945       fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
946       xfree (dn);
947     }
948
949   dn = gpgsm_get_fingerprint_string (cert, 0);
950   fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
951   xfree (dn);
952
953   if (with_validation)
954     {
955       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
956       if (!err)
957         fprintf (fp, "  [certificate is good]\n");
958       else
959         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
960     }
961 }
962
963
964 /* Same as standard mode mode list all certifying certs too. */
965 static void
966 list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, int raw_mode,
967                  FILE *fp, int with_validation)
968 {
969   ksba_cert_t next = NULL;
970
971   if (raw_mode)
972     list_cert_raw (ctrl, cert, fp, 0, with_validation);
973   else
974     list_cert_std (ctrl, cert, fp, 0, with_validation);
975   ksba_cert_ref (cert);
976   while (!gpgsm_walk_cert_chain (cert, &next))
977     {
978       ksba_cert_release (cert);
979       fputs ("Certified by\n", fp);
980       if (raw_mode)
981         list_cert_raw (ctrl, next, fp, 0, with_validation);
982       else
983         list_cert_std (ctrl, next, fp, 0, with_validation);
984       cert = next;
985     }
986   ksba_cert_release (cert);
987   putc ('\n', fp);
988 }
989
990
991 \f
992 /* List all internal keys or just the keys given as NAMES.  MODE is a
993    bit vector to specify what keys are to be included; see
994    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
995    output mode will be used intead of the standard beautified one.
996  */
997 static gpg_error_t
998 list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp,
999                     unsigned int mode, int raw_mode)
1000 {
1001   KEYDB_HANDLE hd;
1002   KEYDB_SEARCH_DESC *desc = NULL;
1003   STRLIST sl;
1004   int ndesc;
1005   ksba_cert_t cert = NULL;
1006   gpg_error_t rc = 0;
1007   const char *lastresname, *resname;
1008   int have_secret;
1009
1010   hd = keydb_new (0);
1011   if (!hd)
1012     {
1013       log_error ("keydb_new failed\n");
1014       rc = gpg_error (GPG_ERR_GENERAL);
1015       goto leave;
1016     }
1017
1018   if (!names)
1019     ndesc = 1;
1020   else
1021     {
1022       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1023         ;
1024     }
1025
1026   desc = xtrycalloc (ndesc, sizeof *desc);
1027   if (!ndesc)
1028     {
1029       rc = gpg_error_from_errno (errno);
1030       log_error ("out of core\n");
1031       goto leave;
1032     }
1033
1034   if (!names)
1035     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1036   else 
1037     {
1038       for (ndesc=0, sl=names; sl; sl = sl->next) 
1039         {
1040           rc = keydb_classify_name (sl->d, desc+ndesc);
1041           if (rc)
1042             {
1043               log_error ("key `%s' not found: %s\n",
1044                          sl->d, gpg_strerror (rc));
1045               rc = 0;
1046             }
1047           else
1048             ndesc++;
1049         }
1050       
1051     }
1052
1053   /* It would be nice to see which of the given users did actually
1054      match one in the keyring.  To implement this we need to have a
1055      found flag for each entry in desc and to set this we must check
1056      all those entries after a match to mark all matched one -
1057      currently we stop at the first match.  To do this we need an
1058      extra flag to enable this feature so */
1059
1060   lastresname = NULL;
1061   while (!(rc = keydb_search (hd, desc, ndesc)))
1062     {
1063       unsigned int validity;
1064
1065       if (!names) 
1066         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1067
1068       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1069       if (rc)
1070         {
1071           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1072           goto leave;
1073         }
1074       rc = keydb_get_cert (hd, &cert);
1075       if (rc) 
1076         {
1077           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1078           goto leave;
1079         }
1080       
1081       resname = keydb_get_resource_name (hd);
1082       
1083       if (lastresname != resname ) 
1084         {
1085           int i;
1086           
1087           if (ctrl->no_server)
1088             {
1089               fprintf (fp, "%s\n", resname );
1090               for (i=strlen(resname); i; i-- )
1091                 putchar('-');
1092               putc ('\n', fp);
1093               lastresname = resname;
1094             }
1095         }
1096
1097       have_secret = 0;
1098       if (mode)
1099         {
1100           char *p = gpgsm_get_keygrip_hexstring (cert);
1101           if (p)
1102             {
1103               rc = gpgsm_agent_havekey (ctrl, p);
1104               if (!rc)
1105                 have_secret = 1;
1106               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1107                 goto leave;
1108               rc = 0;
1109               xfree (p);
1110             }
1111         }
1112
1113       if (!mode
1114           || ((mode & 1) && !have_secret)
1115           || ((mode & 2) && have_secret)  )
1116         {
1117           if (ctrl->with_colons)
1118             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1119           else if (ctrl->with_chain)
1120             list_cert_chain (ctrl, cert, raw_mode, fp, ctrl->with_validation);
1121           else
1122             {
1123               if (raw_mode)
1124                 list_cert_raw (ctrl, cert, fp, have_secret,
1125                                ctrl->with_validation);
1126               else
1127                 list_cert_std (ctrl, cert, fp, have_secret,
1128                                ctrl->with_validation);
1129               putc ('\n', fp);
1130             }
1131         }
1132       ksba_cert_release (cert); 
1133       cert = NULL;
1134     }
1135   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1136     rc = 0;
1137   if (rc)
1138     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1139   
1140  leave:
1141   ksba_cert_release (cert);
1142   xfree (desc);
1143   keydb_release (hd);
1144   return rc;
1145 }
1146
1147
1148
1149 static void
1150 list_external_cb (void *cb_value, ksba_cert_t cert)
1151 {
1152   struct list_external_parm_s *parm = cb_value;
1153
1154   if (keydb_store_cert (cert, 1, NULL))
1155     log_error ("error storing certificate as ephemeral\n");
1156
1157   if (parm->print_header)
1158     {
1159       const char *resname = "[external keys]";
1160       int i;
1161
1162       fprintf (parm->fp, "%s\n", resname );
1163       for (i=strlen(resname); i; i-- )
1164         putchar('-');
1165       putc ('\n', parm->fp);
1166       parm->print_header = 0;
1167     }
1168
1169   if (parm->with_colons)
1170     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1171   else if (parm->with_chain)
1172     list_cert_chain (parm->ctrl, cert, parm->raw_mode, parm->fp, 0);
1173   else
1174     {
1175       if (parm->raw_mode)
1176         list_cert_raw (parm->ctrl, cert, parm->fp, 0, 0);
1177       else
1178         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1179       putc ('\n', parm->fp);
1180     }
1181 }
1182
1183
1184 /* List external keys similar to internal one.  Note: mode does not
1185    make sense here because it would be unwise to list external secret
1186    keys */
1187 static gpg_error_t
1188 list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode)
1189 {
1190   int rc;
1191   struct list_external_parm_s parm;
1192
1193   parm.fp = fp;
1194   parm.ctrl = ctrl,
1195   parm.print_header = ctrl->no_server;
1196   parm.with_colons = ctrl->with_colons;
1197   parm.with_chain = ctrl->with_chain;
1198   parm.raw_mode  = raw_mode;
1199
1200   rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
1201   if (rc)
1202     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1203   return rc;
1204 }
1205
1206 /* List all keys or just the key given as NAMES.
1207    MODE controls the operation mode: 
1208     Bit 0-2:
1209       0 = list all public keys but don't flag secret ones
1210       1 = list only public keys
1211       2 = list only secret keys
1212       3 = list secret and public keys
1213     Bit 6: list internal keys
1214     Bit 7: list external keys
1215     Bit 8: Do a raw format dump.
1216  */
1217 gpg_error_t
1218 gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
1219 {
1220   gpg_error_t err = 0;
1221
1222   if ((mode & (1<<6)))
1223     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1224   if (!err && (mode & (1<<7)))
1225     err = list_external_keys (ctrl, names, fp, (mode&256)); 
1226   return err;
1227 }