* gpgsm.c: New option --with-md5-fingerprint.
[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 };
47
48
49
50 static void
51 print_key_data (ksba_cert_t cert, FILE *fp)
52 {
53 #if 0  
54   int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
55   int i;
56
57   for(i=0; i < n; i++ ) 
58     {
59       fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
60       mpi_print(stdout, pk->pkey[i], 1 );
61       putchar(':');
62       putchar('\n');
63     }
64 #endif
65 }
66
67 static void
68 print_capabilities (ksba_cert_t cert, FILE *fp)
69 {
70   gpg_error_t err;
71   unsigned int use;
72
73   err = ksba_cert_get_key_usage (cert, &use);
74   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
75     {
76       putc ('e', fp);
77       putc ('s', fp);
78       putc ('c', fp);
79       putc ('E', fp);
80       putc ('S', fp);
81       putc ('C', fp);
82       return;
83     }
84   if (err)
85     { 
86       log_error (_("error getting key usage information: %s\n"),
87                  gpg_strerror (err));
88       return;
89     } 
90
91   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
92     putc ('e', fp);
93   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
94     putc ('s', fp);
95   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
96     putc ('c', fp);
97   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
98     putc ('E', fp);
99   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
100     putc ('S', fp);
101   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
102     putc ('C', fp);
103 }
104
105
106 static void
107 print_time (gnupg_isotime_t t, FILE *fp)
108 {
109   if (!t || !*t)
110     ;
111   else 
112     fputs (t, fp);
113 }
114
115
116 /* return an allocated string with the email address extracted from a
117    DN */
118 static char *
119 email_kludge (const char *name)
120 {
121   const unsigned char *p;
122   unsigned char *buf;
123   int n;
124
125   if (strncmp (name, "1.2.840.113549.1.9.1=#", 22))
126     return NULL;
127   /* This looks pretty much like an email address in the subject's DN
128      we use this to add an additional user ID entry.  This way,
129      openSSL generated keys get a nicer and usable listing */
130   name += 22;    
131   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
132     ;
133   if (*p != '#' || !n)
134     return NULL;
135   buf = xtrymalloc (n+3);
136   if (!buf)
137     return NULL; /* oops, out of core */
138   *buf = '<';
139   for (n=1, p=name; *p != '#'; p +=2, n++)
140     buf[n] = xtoi_2 (p);
141   buf[n++] = '>';
142   buf[n] = 0;
143   return buf;
144 }
145
146
147
148
149 /* List one certificate in colon mode */
150 static void
151 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
152                  FILE *fp, int have_secret)
153 {
154   int idx;
155   char truststring[2];
156   char *p;
157   ksba_sexp_t sexp;
158   char *fpr;
159   ksba_isotime_t t;
160   gpg_error_t valerr;
161
162   if (ctrl->with_validation)
163     valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL);
164   else
165     valerr = 0;
166
167   fputs (have_secret? "crs:":"crt:", fp);
168   truststring[0] = 0;
169   truststring[1] = 0;
170   if ((validity & VALIDITY_REVOKED)
171       || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
172     *truststring = 'r';
173   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
174     *truststring = 'e';
175   else if (valerr)
176     *truststring = 'i';
177   
178   if (*truststring)
179     fputs (truststring, fp);
180
181   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
182   fprintf (fp, ":%u:%d:%s:",
183            /*keylen_of_cert (cert)*/1024,
184            /* pubkey_algo_of_cert (cert)*/1,
185            fpr+24);
186
187   /* we assume --fixed-list-mode for gpgsm */
188   ksba_cert_get_validity (cert, 0, t);
189   print_time (t, fp);
190   putc (':', fp);
191   ksba_cert_get_validity (cert, 1, t);
192   print_time ( t, fp);
193   putc (':', fp);
194   /* field 8, serial number: */
195   if ((sexp = ksba_cert_get_serial (cert)))
196     {
197       int len;
198       const unsigned char *s = sexp;
199       
200       if (*s == '(')
201         {
202           s++;
203           for (len=0; *s && *s != ':' && digitp (s); s++)
204             len = len*10 + atoi_1 (s);
205           if (*s == ':')
206             for (s++; len; len--, s++)
207               fprintf (fp,"%02X", *s);
208         }
209       xfree (sexp);
210     }
211   putc (':', fp);
212   /* field 9, ownertrust - not used here */
213   putc (':', fp);
214   /* field 10, old user ID - we use it here for the issuer DN */
215   if ((p = ksba_cert_get_issuer (cert,0)))
216     {
217       print_sanitized_string (fp, p, ':');
218       xfree (p);
219     }
220   putc (':', fp);
221   /* field 11, signature class - not used */ 
222   putc (':', fp);
223   /* field 12, capabilities: */ 
224   print_capabilities (cert, fp);
225   putc (':', fp);
226   putc ('\n', fp);
227
228   /* FPR record */
229   fprintf (fp, "fpr:::::::::%s:::", fpr);
230   xfree (fpr); fpr = NULL;
231   /* print chaining ID (field 13)*/
232   {
233     ksba_cert_t next;
234     
235     if (!gpgsm_walk_cert_chain (cert, &next))
236       {
237         p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
238         fputs (p, fp);
239         xfree (p);
240         ksba_cert_release (next);
241       }
242   }
243   putc (':', fp);
244   putc ('\n', fp);
245
246
247   if (opt.with_key_data)
248     {
249       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
250         {
251           fprintf (fp, "grp:::::::::%s:\n", p);
252           xfree (p);
253         }
254       print_key_data (cert, fp);
255     }
256
257   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
258     {
259       fprintf (fp, "uid:%s::::::::", truststring);
260       print_sanitized_string (fp, p, ':');
261       putc (':', fp);
262       putc (':', fp);
263       putc ('\n', fp);
264       if (!idx)
265         {
266           /* It would be better to get the faked email address from
267              the keydb.  But as long as we don't have a way to pass
268              the meta data back, we just check it the same way as the
269              code used to create the keybox meta data does */
270           char *pp = email_kludge (p);
271           if (pp)
272             {
273               fprintf (fp, "uid:%s::::::::", truststring);
274               print_sanitized_string (fp, pp, ':');
275               putc (':', fp);
276               putc (':', fp);
277               putc ('\n', fp);
278               xfree (pp);
279             }
280         }
281       xfree (p);
282     }
283 }
284
285
286 /* List one certificate in standard mode */
287 static void
288 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
289                int with_validation)
290 {
291   gpg_error_t err;
292   ksba_sexp_t sexp;
293   char *dn;
294   ksba_isotime_t t;
295   int idx;
296   int is_ca, chainlen;
297   unsigned int kusage;
298   char *string, *p;
299
300   sexp = ksba_cert_get_serial (cert);
301   fputs ("Serial number: ", fp);
302   gpgsm_print_serial (fp, sexp);
303   ksba_free (sexp);
304   putc ('\n', fp);
305
306   dn = ksba_cert_get_issuer (cert, 0);
307   fputs ("       Issuer: ", fp);
308   gpgsm_print_name (fp, dn);
309   ksba_free (dn);
310   putc ('\n', fp);
311   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
312     {
313       fputs ("          aka: ", fp);
314       gpgsm_print_name (fp, dn);
315       ksba_free (dn);
316       putc ('\n', fp);
317     }
318
319   dn = ksba_cert_get_subject (cert, 0);
320   fputs ("      Subject: ", fp);
321   gpgsm_print_name (fp, dn);
322   ksba_free (dn);
323   putc ('\n', fp);
324   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
325     {
326       fputs ("          aka: ", fp);
327       gpgsm_print_name (fp, dn);
328       ksba_free (dn);
329       putc ('\n', fp);
330     }
331
332   ksba_cert_get_validity (cert, 0, t);
333   fputs ("     validity: ", fp);
334   gpgsm_print_time (fp, t);
335   fputs (" through ", fp);
336   ksba_cert_get_validity (cert, 1, t);
337   gpgsm_print_time (fp, t);
338   putc ('\n', fp);
339
340   err = ksba_cert_get_key_usage (cert, &kusage);
341   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
342     {
343       fputs ("    key usage:", fp);
344       if (err)
345         fprintf (fp, " [error: %s]", gpg_strerror (err));
346       else
347         {
348           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
349             fputs (" digitalSignature", fp);
350           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
351             fputs (" nonRepudiation", fp);
352           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
353             fputs (" keyEncipherment", fp);
354           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
355             fputs (" dataEncipherment", fp);
356           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
357             fputs (" keyAgreement", fp);
358           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
359             fputs (" certSign", fp);
360           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
361             fputs (" crlSign", fp);
362           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
363             fputs (" encipherOnly", fp);
364           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
365             fputs (" decipherOnly", fp);
366         }
367       putc ('\n', fp);
368     }
369
370   err = ksba_cert_get_cert_policies (cert, &string);
371   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
372     {
373       fputs ("     policies: ", fp);
374       if (err)
375         fprintf (fp, "[error: %s]", gpg_strerror (err));
376       else
377         {
378           for (p=string; *p; p++)
379             {
380               if (*p == '\n')
381                 *p = ',';
382             }
383           print_sanitized_string (fp, string, 0);
384           xfree (string);
385         }
386       putc ('\n', fp);
387     }
388
389   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
390   if (err || is_ca)
391     {
392       fputs (" chain length: ", fp);
393       if (err)
394         fprintf (fp, "[error: %s]", gpg_strerror (err));
395       else if (chainlen == -1)
396         fputs ("unlimited", fp);
397       else
398         fprintf (fp, "%d", chainlen);
399       putc ('\n', fp);
400     }
401
402   if (opt.with_md5_fingerprint)
403     {
404       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
405       fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
406       xfree (dn);
407     }
408
409   dn = gpgsm_get_fingerprint_string (cert, 0);
410   fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
411   xfree (dn);
412
413   if (with_validation)
414     {
415       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp);
416       if (!err)
417         fprintf (fp, "  [certificate is good]\n");
418       else
419         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
420     }
421 }
422
423
424 /* Same as standard mode mode list all certifying certs too. */
425 static void
426 list_cert_chain (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int with_validation)
427 {
428   ksba_cert_t next = NULL;
429
430   list_cert_std (ctrl, cert, fp, 0, with_validation);
431   ksba_cert_ref (cert);
432   while (!gpgsm_walk_cert_chain (cert, &next))
433     {
434       ksba_cert_release (cert);
435       fputs ("Certified by\n", fp);
436       list_cert_std (ctrl, next, fp, 0, with_validation);
437       cert = next;
438     }
439   ksba_cert_release (cert);
440   putc ('\n', fp);
441 }
442
443
444 \f
445 /* List all internal keys or just the key given as NAMES.
446  */
447 static void
448 list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
449 {
450   KEYDB_HANDLE hd;
451   KEYDB_SEARCH_DESC *desc = NULL;
452   STRLIST sl;
453   int ndesc;
454   ksba_cert_t cert = NULL;
455   int rc=0;
456   const char *lastresname, *resname;
457   int have_secret;
458
459   hd = keydb_new (0);
460   if (!hd)
461     {
462       log_error ("keydb_new failed\n");
463       goto leave;
464     }
465
466   if (!names)
467     ndesc = 1;
468   else
469     {
470       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
471         ;
472     }
473
474   desc = xtrycalloc (ndesc, sizeof *desc);
475   if (!ndesc)
476     {
477       log_error ("out of core\n");
478       goto leave;
479     }
480
481   if (!names)
482     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
483   else 
484     {
485       for (ndesc=0, sl=names; sl; sl = sl->next) 
486         {
487           rc = keydb_classify_name (sl->d, desc+ndesc);
488           if (rc)
489             {
490               log_error ("key `%s' not found: %s\n",
491                          sl->d, gpg_strerror (rc));
492               rc = 0;
493             }
494           else
495             ndesc++;
496         }
497       
498     }
499
500   /* It would be nice to see which of the given users did actually
501      match one in the keyring.  To implement this we need to have a
502      found flag for each entry in desc and to set this we must check
503      all those entries after a match to mark all matched one -
504      currently we stop at the first match.  To do this we need an
505      extra flag to enable this feature so */
506
507   lastresname = NULL;
508   while (!(rc = keydb_search (hd, desc, ndesc)))
509     {
510       unsigned int validity;
511
512       if (!names) 
513         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
514
515       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
516       if (rc)
517         {
518           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
519           goto leave;
520         }
521       rc = keydb_get_cert (hd, &cert);
522       if (rc) 
523         {
524           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
525           goto leave;
526         }
527       
528       resname = keydb_get_resource_name (hd);
529       
530       if (lastresname != resname ) 
531         {
532           int i;
533           
534           if (ctrl->no_server)
535             {
536               fprintf (fp, "%s\n", resname );
537               for (i=strlen(resname); i; i-- )
538                 putchar('-');
539               putc ('\n', fp);
540               lastresname = resname;
541             }
542         }
543
544       have_secret = 0;
545       if (mode)
546         {
547           char *p = gpgsm_get_keygrip_hexstring (cert);
548           if (p)
549             {
550               if (!gpgsm_agent_havekey (p))
551                 have_secret = 1;
552               xfree (p);
553             }
554         }
555
556       if (!mode
557           || ((mode & 1) && !have_secret)
558           || ((mode & 2) && have_secret)  )
559         {
560           if (ctrl->with_colons)
561             list_cert_colon (ctrl, cert, validity, fp, have_secret);
562           else if (ctrl->with_chain)
563             list_cert_chain (ctrl, cert, fp, ctrl->with_validation);
564           else
565             {
566               list_cert_std (ctrl, cert, fp, have_secret,
567                              ctrl->with_validation);
568               putc ('\n', fp);
569             }
570         }
571       ksba_cert_release (cert); 
572       cert = NULL;
573     }
574   if (rc && rc != -1)
575     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
576   
577  leave:
578   ksba_cert_release (cert);
579   xfree (desc);
580   keydb_release (hd);
581 }
582
583
584
585 static void
586 list_external_cb (void *cb_value, ksba_cert_t cert)
587 {
588   struct list_external_parm_s *parm = cb_value;
589
590   if (keydb_store_cert (cert, 1, NULL))
591     log_error ("error storing certificate as ephemeral\n");
592
593   if (parm->print_header)
594     {
595       const char *resname = "[external keys]";
596       int i;
597
598       fprintf (parm->fp, "%s\n", resname );
599       for (i=strlen(resname); i; i-- )
600         putchar('-');
601       putc ('\n', parm->fp);
602       parm->print_header = 0;
603     }
604
605   if (parm->with_colons)
606     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
607   else if (parm->with_chain)
608     list_cert_chain (parm->ctrl, cert, parm->fp, 0);
609   else
610     {
611       list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
612       putc ('\n', parm->fp);
613     }
614 }
615
616
617 /* List external keys similar to internal one.  Note: mode does not
618    make sense here because it would be unwise to list external secret
619    keys */
620 static void
621 list_external_keys (CTRL ctrl, STRLIST names, FILE *fp)
622 {
623   int rc;
624   struct list_external_parm_s parm;
625
626   parm.fp = fp;
627   parm.ctrl = ctrl,
628   parm.print_header = ctrl->no_server;
629   parm.with_colons = ctrl->with_colons;
630   parm.with_chain = ctrl->with_chain;
631
632   rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
633   if (rc)
634     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
635 }
636
637 /* List all keys or just the key given as NAMES.
638    MODE controls the operation mode: 
639     Bit 0-2:
640       0 = list all public keys but don't flag secret ones
641       1 = list only public keys
642       2 = list only secret keys
643       3 = list secret and public keys
644     Bit 6: list internal keys
645     Bit 7: list external keys
646  */
647 void
648 gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
649 {
650   if ((mode & (1<<6)))
651       list_internal_keys (ctrl, names, fp, (mode & 3));
652   if ((mode & (1<<7)))
653       list_external_keys (ctrl, names, fp); 
654 }