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