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