Changed to GPLv3.
[gnupg.git] / agent / findkey.c
1 /* findkey.c - locate the secret key
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005 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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <fcntl.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <assert.h>
31 #include <pth.h> /* (we use pth_sleep) */
32
33 #include "agent.h"
34
35 /* Helper to pass data to the check callback of the unprotect function. */
36 struct try_unprotect_arg_s {
37   const unsigned char *protected_key;
38   unsigned char *unprotected_key;
39 };
40
41
42 /* Write an S-expression formatted key to our key storage.  With FORCE
43    pased as true an existing key with the given GRIP will get
44    overwritten.  */
45 int
46 agent_write_private_key (const unsigned char *grip,
47                          const void *buffer, size_t length, int force)
48 {
49   int i;
50   char *fname;
51   FILE *fp;
52   char hexgrip[40+4+1];
53   int fd;
54   
55   for (i=0; i < 20; i++)
56     sprintf (hexgrip+2*i, "%02X", grip[i]);
57   strcpy (hexgrip+40, ".key");
58
59   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
60
61   if (!force && !access (fname, F_OK))
62     {
63       log_error ("secret key file `%s' already exists\n", fname);
64       xfree (fname);
65       return gpg_error (GPG_ERR_GENERAL);
66     }
67
68   /* In FORCE mode we would like to create FNAME but only if it does
69      not already exist.  We cannot make this guarantee just using
70      POSIX (GNU provides the "x" opentype for fopen, however, this is
71      not portable).  Thus, we use the more flexible open function and
72      then use fdopen to obtain a stream. */
73   fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY)
74                          : (O_CREAT | O_EXCL | O_WRONLY),
75              S_IRUSR | S_IWUSR 
76 #ifndef HAVE_W32_SYSTEM
77                  | S_IRGRP 
78 #endif
79                  );
80   if (fd < 0)
81     fp = NULL;
82   else
83     {
84       fp = fdopen (fd, "wb");
85       if (!fp)
86         { 
87           int save_e = errno;
88           close (fd);
89           errno = save_e;
90         }
91     }
92
93   if (!fp) 
94     { 
95       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
96       log_error ("can't create `%s': %s\n", fname, strerror (errno));
97       xfree (fname);
98       return tmperr;
99     }
100
101   if (fwrite (buffer, length, 1, fp) != 1)
102     {
103       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
104       log_error ("error writing `%s': %s\n", fname, strerror (errno));
105       fclose (fp);
106       remove (fname);
107       xfree (fname);
108       return tmperr;
109     }
110   if ( fclose (fp) )
111     {
112       gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
113       log_error ("error closing `%s': %s\n", fname, strerror (errno));
114       remove (fname);
115       xfree (fname);
116       return tmperr;
117     }
118   bump_key_eventcounter ();
119   xfree (fname);
120   return 0;
121 }
122
123
124 /* Callback function to try the unprotection from the passpharse query
125    code. */
126 static int
127 try_unprotect_cb (struct pin_entry_info_s *pi)
128 {
129   struct try_unprotect_arg_s *arg = pi->check_cb_arg;
130   size_t dummy;
131
132   assert (!arg->unprotected_key);
133   return agent_unprotect (arg->protected_key, pi->pin,
134                           &arg->unprotected_key, &dummy);
135 }
136
137
138 /* Modify a Key description, replacing certain special format
139    characters.  List of currently supported replacements:
140
141    %% - Replaced by a single %
142    %c - Replaced by the content of COMMENT.
143
144    The functions returns 0 on success or an error code.  On success a
145    newly allocated string is stored at the address of RESULT.
146  */
147 static gpg_error_t
148 modify_description (const char *in, const char *comment, char **result)
149 {
150   size_t comment_length;
151   size_t in_len;
152   size_t out_len;
153   char *out;
154   size_t i;
155   int special, pass;
156
157   comment_length = strlen (comment);
158   in_len  = strlen (in);
159
160   /* First pass calculates the length, second pass does the actual
161      copying.  */
162   out = NULL;
163   out_len = 0;
164   for (pass=0; pass < 2; pass++)
165     {
166       special = 0;
167       for (i = 0; i < in_len; i++)
168         {
169           if (special)
170             {
171               special = 0;
172               switch (in[i])
173                 {
174                 case '%':
175                   if (out)
176                     *out++ = '%';
177                   else
178                     out_len++;
179                   break;
180
181                 case 'c': /* Comment.  */
182                   if (out)
183                     {
184                       memcpy (out, comment, comment_length);
185                       out += comment_length;
186                     }
187                   else
188                     out_len += comment_length;
189                   break;
190
191                 default: /* Invalid special sequences are kept as they are. */
192                   if (out)
193                     {
194                       *out++ = '%';
195                       *out++ = in[i];
196                     }
197                   else
198                     out_len+=2;
199                   break;
200                 }
201             }
202           else if (in[i] == '%')
203             special = 1;
204           else
205             {
206               if (out)
207                 *out++ = in[i];
208               else
209                 out_len++;
210             }
211         }
212       
213       if (!pass)
214         {
215           *result = out = xtrymalloc (out_len + 1);
216           if (!out)
217             return gpg_error_from_syserror ();
218         }
219     }
220
221   *out = 0;
222   assert (*result + out_len == out);
223   return 0;
224 }
225
226   
227
228 /* Unprotect the canconical encoded S-expression key in KEYBUF.  GRIP
229    should be the hex encoded keygrip of that key to be used with the
230    caching mechanism. DESC_TEXT may be set to override the default
231    description used for the pinentry. */
232 static int
233 unprotect (ctrl_t ctrl, const char *desc_text,
234            unsigned char **keybuf, const unsigned char *grip, 
235            cache_mode_t cache_mode)
236 {
237   struct pin_entry_info_s *pi;
238   struct try_unprotect_arg_s arg;
239   int rc, i;
240   unsigned char *result;
241   size_t resultlen;
242   char hexgrip[40+1];
243   
244   for (i=0; i < 20; i++)
245     sprintf (hexgrip+2*i, "%02X", grip[i]);
246   hexgrip[40] = 0;
247
248   /* First try to get it from the cache - if there is none or we can't
249      unprotect it, we fall back to ask the user */
250   if (cache_mode != CACHE_MODE_IGNORE)
251     {
252       void *cache_marker;
253       const char *pw;
254       
255     retry:
256       pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
257       if (pw)
258         {
259           rc = agent_unprotect (*keybuf, pw, &result, &resultlen);
260           agent_unlock_cache_entry (&cache_marker);
261           if (!rc)
262             {
263               xfree (*keybuf);
264               *keybuf = result;
265               return 0;
266             }
267           rc  = 0;
268         }
269
270       /* If the pinentry is currently in use, we wait up to 60 seconds
271          for it close and check the cache again.  This solves a common
272          situation where several requests for unprotecting a key have
273          been made but the user is still entering the passphrase for
274          the first request.  Because all requests to agent_askpin are
275          serialized they would then pop up one after the other to
276          request the passphrase - despite that the user has already
277          entered it and is then available in the cache.  This
278          implementation is not race free but in the worst case the
279          user has to enter the passphrase only once more. */
280       if (pinentry_active_p (ctrl, 0))
281         {
282           /* Active - wait */
283           if (!pinentry_active_p (ctrl, 60))
284             {
285               /* We need to give the other thread a chance to actually put
286                  it into the cache. */
287               pth_sleep (1); 
288               goto retry;
289             }
290           /* Timeout - better call pinentry now the plain way. */
291         }
292     }
293   
294   pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
295   if (!pi)
296     return gpg_error_from_syserror ();
297   pi->max_length = 100;
298   pi->min_digits = 0;  /* we want a real passphrase */
299   pi->max_digits = 8;
300   pi->max_tries = 3;
301   pi->check_cb = try_unprotect_cb;
302   arg.protected_key = *keybuf;
303   arg.unprotected_key = NULL;
304   pi->check_cb_arg = &arg;
305
306   rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
307   if (!rc)
308     {
309       assert (arg.unprotected_key);
310       agent_put_cache (hexgrip, cache_mode, pi->pin, 0);
311       xfree (*keybuf);
312       *keybuf = arg.unprotected_key;
313     }
314   xfree (pi);
315   return rc;
316 }
317
318
319 /* Read the key identified by GRIP from the private key directory and
320    return it as an gcrypt S-expression object in RESULT.  On failure
321    returns an error code and stores NULL at RESULT. */
322 static gpg_error_t
323 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
324 {
325   int i, rc;
326   char *fname;
327   FILE *fp;
328   struct stat st;
329   unsigned char *buf;
330   size_t buflen, erroff;
331   gcry_sexp_t s_skey;
332   char hexgrip[40+4+1];
333   
334   *result = NULL;
335
336   for (i=0; i < 20; i++)
337     sprintf (hexgrip+2*i, "%02X", grip[i]);
338   strcpy (hexgrip+40, ".key");
339
340   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
341   fp = fopen (fname, "rb");
342   if (!fp)
343     {
344       rc = gpg_error_from_syserror ();
345       log_error ("can't open `%s': %s\n", fname, strerror (errno));
346       xfree (fname);
347       return rc;
348     }
349   
350   if (fstat (fileno(fp), &st))
351     {
352       rc = gpg_error_from_syserror ();
353       log_error ("can't stat `%s': %s\n", fname, strerror (errno));
354       xfree (fname);
355       fclose (fp);
356       return rc;
357     }
358
359   buflen = st.st_size;
360   buf = xtrymalloc (buflen+1);
361   if (!buf || fread (buf, buflen, 1, fp) != 1)
362     {
363       rc = gpg_error_from_syserror ();
364       log_error ("error reading `%s': %s\n", fname, strerror (errno));
365       xfree (fname);
366       fclose (fp);
367       xfree (buf);
368       return rc;
369     }
370
371   /* Convert the file into a gcrypt S-expression object.  */
372   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
373   xfree (fname);
374   fclose (fp);
375   xfree (buf);
376   if (rc)
377     {
378       log_error ("failed to build S-Exp (off=%u): %s\n",
379                  (unsigned int)erroff, gpg_strerror (rc));
380       return rc;
381     }
382   *result = s_skey;
383   return 0;
384 }
385
386
387 /* Return the secret key as an S-Exp in RESULT after locating it using
388    the grip.  Returns NULL in RESULT if the operation should be
389    diverted to a token; SHADOW_INFO will point then to an allocated
390    S-Expression with the shadow_info part from the file.  CACHE_MODE
391    defines now the cache shall be used.  DESC_TEXT may be set to
392    present a custom description for the pinentry. */
393 gpg_error_t
394 agent_key_from_file (ctrl_t ctrl, const char *desc_text,
395                      const unsigned char *grip, unsigned char **shadow_info,
396                      cache_mode_t cache_mode, gcry_sexp_t *result)
397 {
398   int rc;
399   unsigned char *buf;
400   size_t len, buflen, erroff;
401   gcry_sexp_t s_skey;
402   int got_shadow_info = 0;
403   
404   *result = NULL;
405   if (shadow_info)
406       *shadow_info = NULL;
407
408   rc = read_key_file (grip, &s_skey);
409   if (rc)
410     return rc;
411
412   /* For use with the protection functions we also need the key as an
413      canonical encoded S-expression in abuffer.  Create this buffer
414      now.  */
415   len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
416   assert (len);
417   buf = xtrymalloc (len);
418   if (!buf)
419     {
420       rc = gpg_error_from_syserror ();
421       gcry_sexp_release (s_skey);
422       return rc;
423     }
424   len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len);
425   assert (len);
426
427
428   switch (agent_private_key_type (buf))
429     {
430     case PRIVATE_KEY_CLEAR:
431       break; /* no unprotection needed */
432     case PRIVATE_KEY_PROTECTED:
433       {
434         gcry_sexp_t comment_sexp;
435         size_t comment_length;
436         char *desc_text_final;
437         const char *comment = NULL;
438
439         /* Note, that we will take the comment as a C string for
440            display purposes; i.e. all stuff beyond a Nul character is
441            ignored.  */
442         comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
443         if (comment_sexp)
444           comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
445         if (!comment)
446           {
447             comment = "";
448             comment_length = 0;
449           }
450
451         desc_text_final = NULL;
452         if (desc_text)
453           {
454             if (comment[comment_length])
455               {
456                 /* Not a C-string; create one.  We might here allocate
457                    more than actually displayed but well, that
458                    shouldn't be a problem.  */
459                 char *tmp = xtrymalloc (comment_length+1);
460                 if (!tmp)
461                   rc = gpg_error_from_syserror ();
462                 else
463                   {
464                     memcpy (tmp, comment, comment_length);
465                     tmp[comment_length] = 0;
466                     rc = modify_description (desc_text, tmp, &desc_text_final);
467                     xfree (tmp);
468                   }
469               }
470             else
471               rc = modify_description (desc_text, comment, &desc_text_final);
472           }
473
474         if (!rc)
475           {
476             rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode);
477             if (rc)
478               log_error ("failed to unprotect the secret key: %s\n",
479                          gpg_strerror (rc));
480           }
481         
482         gcry_sexp_release (comment_sexp);
483         xfree (desc_text_final);
484       }
485       break;
486     case PRIVATE_KEY_SHADOWED:
487       if (shadow_info)
488         {
489           const unsigned char *s;
490           size_t n;
491
492           rc = agent_get_shadow_info (buf, &s);
493           if (!rc)
494             {
495               n = gcry_sexp_canon_len (s, 0, NULL,NULL);
496               assert (n);
497               *shadow_info = xtrymalloc (n);
498               if (!*shadow_info)
499                 rc = out_of_core ();
500               else
501                 {
502                   memcpy (*shadow_info, s, n);
503                   rc = 0;
504                   got_shadow_info = 1;
505                 }
506             }
507           if (rc)
508             log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
509         }
510       else
511         rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
512       break;
513     default:
514       log_error ("invalid private key format\n");
515       rc = gpg_error (GPG_ERR_BAD_SECKEY);
516       break;
517     }
518   gcry_sexp_release (s_skey);
519   s_skey = NULL;
520   if (rc || got_shadow_info)
521     {
522       xfree (buf);
523       return rc;
524     }
525
526   buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
527   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
528   wipememory (buf, buflen);
529   xfree (buf);
530   if (rc)
531     {
532       log_error ("failed to build S-Exp (off=%u): %s\n",
533                  (unsigned int)erroff, gpg_strerror (rc));
534       return rc;
535     }
536
537   *result = s_skey;
538   return 0;
539 }
540
541
542
543 /* Return the public key for the keygrip GRIP.  The result is stored
544    at RESULT.  This function extracts the public key from the private
545    key database.  On failure an error code is returned and NULL stored
546    at RESULT. */
547 gpg_error_t
548 agent_public_key_from_file (ctrl_t ctrl, 
549                             const unsigned char *grip,
550                             gcry_sexp_t *result)
551 {
552   int i, idx, rc;
553   gcry_sexp_t s_skey;
554   const char *algoname;
555   gcry_sexp_t uri_sexp, comment_sexp;
556   const char *uri, *comment;
557   size_t uri_length, comment_length;
558   char *format, *p;
559   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
560                            for comment + end-of-list.  */
561   int argidx;
562   gcry_sexp_t list, l2;
563   const char *name;
564   const char *s;
565   size_t n;
566   const char *elems;
567   gcry_mpi_t *array;
568
569   *result = NULL;
570
571   rc = read_key_file (grip, &s_skey);
572   if (rc)
573     return rc;
574
575   list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
576   if (!list)
577     list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
578   if (!list)
579     list = gcry_sexp_find_token (s_skey, "private-key", 0 );
580   if (!list)
581     {
582       log_error ("invalid private key format\n");
583       gcry_sexp_release (s_skey);
584       return gpg_error (GPG_ERR_BAD_SECKEY);
585     }
586
587   l2 = gcry_sexp_cadr (list);
588   gcry_sexp_release (list);
589   list = l2;
590   name = gcry_sexp_nth_data (list, 0, &n);
591   if (n==3 && !memcmp (name, "rsa", 3))
592     {
593       algoname = "rsa";
594       elems = "ne";
595     }
596   else if (n==3 && !memcmp (name, "dsa", 3))
597     {
598       algoname = "dsa";
599       elems = "pqgy";
600     }
601   else if (n==3 && !memcmp (name, "elg", 3))
602     {
603       algoname = "elg";
604       elems = "pgy";
605     }
606   else
607     {
608       log_error ("unknown private key algorithm\n");
609       gcry_sexp_release (list);
610       gcry_sexp_release (s_skey);
611       return gpg_error (GPG_ERR_BAD_SECKEY);
612     }
613
614   /* Allocate an array for the parameters and copy them out of the
615      secret key.   FIXME: We should have a generic copy function. */
616   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
617   if (!array)
618     {
619       rc = gpg_error_from_syserror ();
620       gcry_sexp_release (list);
621       gcry_sexp_release (s_skey);
622       return rc;
623     }
624
625   for (idx=0, s=elems; *s; s++, idx++ ) 
626     {
627       l2 = gcry_sexp_find_token (list, s, 1);
628       if (!l2)
629         {
630           /* Required parameter not found.  */
631           for (i=0; i<idx; i++)
632             gcry_mpi_release (array[i]);
633           xfree (array);
634           gcry_sexp_release (list);
635           gcry_sexp_release (s_skey);
636           return gpg_error (GPG_ERR_BAD_SECKEY);
637         }
638       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
639       gcry_sexp_release (l2);
640       if (!array[idx])
641         {
642           /* Required parameter is invalid. */
643           for (i=0; i<idx; i++)
644             gcry_mpi_release (array[i]);
645           xfree (array);
646           gcry_sexp_release (list);
647           gcry_sexp_release (s_skey);
648           return gpg_error (GPG_ERR_BAD_SECKEY);
649         }
650     }
651   gcry_sexp_release (list);
652   list = NULL;
653
654   uri = NULL;
655   uri_length = 0;
656   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
657   if (uri_sexp)
658     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
659
660   comment = NULL;
661   comment_length = 0;
662   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
663   if (comment_sexp)
664     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
665
666   gcry_sexp_release (s_skey);
667   s_skey = NULL;
668
669
670   /* FIXME: The following thing is pretty ugly code; we should
671      investigate how to make it cleaner. Probably code to handle
672      canonical S-expressions in a memory buffer is better suioted for
673      such a task.  After all that is what we do in protect.c.  Neeed
674      to find common patterns and write a straightformward API to use
675      them.  */
676   assert (sizeof (size_t) <= sizeof (void*));
677
678   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
679   if (!format)
680     {
681       rc = gpg_error_from_syserror ();
682       for (i=0; array[i]; i++)
683         gcry_mpi_release (array[i]);
684       xfree (array);
685       gcry_sexp_release (uri_sexp);
686       gcry_sexp_release (comment_sexp);
687       return rc;
688     }
689
690   argidx = 0;
691   p = stpcpy (stpcpy (format, "(public-key("), algoname);
692   for (idx=0, s=elems; *s; s++, idx++ ) 
693     {
694       *p++ = '(';
695       *p++ = *s;
696       p = stpcpy (p, " %m)");
697       assert (argidx < DIM (args));
698       args[argidx++] = &array[idx];
699     }
700   *p++ = ')';
701   if (uri)
702     {
703       p = stpcpy (p, "(uri %b)");
704       assert (argidx+1 < DIM (args));
705       args[argidx++] = (void *)uri_length;
706       args[argidx++] = (void *)uri;
707     }
708   if (comment)
709     {
710       p = stpcpy (p, "(comment %b)");
711       assert (argidx+1 < DIM (args));
712       args[argidx++] = (void *)comment_length;
713       args[argidx++] = (void*)comment;
714     }
715   *p++ = ')';
716   *p = 0;
717   assert (argidx < DIM (args));
718   args[argidx] = NULL;
719     
720   rc = gcry_sexp_build_array (&list, NULL, format, args);
721   xfree (format);
722   for (i=0; array[i]; i++)
723     gcry_mpi_release (array[i]);
724   xfree (array);
725   gcry_sexp_release (uri_sexp);
726   gcry_sexp_release (comment_sexp);
727
728   if (!rc)
729     *result = list;
730   return rc;
731 }
732
733
734
735 /* Return the secret key as an S-Exp after locating it using the grip.
736    Returns NULL if key is not available. 0 = key is available */
737 int
738 agent_key_available (const unsigned char *grip)
739 {
740   int i;
741   char *fname;
742   char hexgrip[40+4+1];
743   
744   for (i=0; i < 20; i++)
745     sprintf (hexgrip+2*i, "%02X", grip[i]);
746   strcpy (hexgrip+40, ".key");
747
748   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
749   i = !access (fname, R_OK)? 0 : -1;
750   xfree (fname);
751   return i;
752 }
753
754
755