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