* command-ssh.c (get_passphrase): Removed.
[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 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 <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <fcntl.h>
28 #include <assert.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <assert.h>
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 existsing 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
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 (in[i] == '%')
170             special = 1;
171           else if (special)
172             {
173               special = 0;
174               switch (in[i])
175                 {
176                 case '%':
177                   if (out)
178                     *out++ = '%';
179                   else
180                     out_len++;
181                   break;
182
183                 case 'c': /* Comment.  */
184                   if (out)
185                     {
186                       memcpy (out, comment, comment_length);
187                       out += comment_length;
188                     }
189                   else
190                     out_len += comment_length;
191                   break;
192
193                 default: /* Invalid special sequences are ignored.  */
194                   break;
195                 }
196             }
197           else
198             {
199               if (out)
200                 *out++ = in[i];
201               else
202                 out_len++;
203             }
204         }
205       
206       if (!pass)
207         {
208           *result = out = xtrymalloc (out_len + 1);
209           if (!out)
210             return gpg_error_from_errno (errno);
211         }
212     }
213
214   *out = 0;
215   assert (*result + out_len == out);
216   return 0;
217 }
218
219   
220
221 /* Unprotect the canconical encoded S-expression key in KEYBUF.  GRIP
222    should be the hex encoded keygrip of that key to be used with the
223    caching mechanism. DESC_TEXT may be set to override the default
224    description used for the pinentry. */
225 static int
226 unprotect (CTRL ctrl, const char *desc_text,
227            unsigned char **keybuf, const unsigned char *grip, int ignore_cache)
228 {
229   struct pin_entry_info_s *pi;
230   struct try_unprotect_arg_s arg;
231   int rc, i;
232   unsigned char *result;
233   size_t resultlen;
234   char hexgrip[40+1];
235   
236   for (i=0; i < 20; i++)
237     sprintf (hexgrip+2*i, "%02X", grip[i]);
238   hexgrip[40] = 0;
239
240   /* First try to get it from the cache - if there is none or we can't
241      unprotect it, we fall back to ask the user */
242   if (!ignore_cache)
243     {
244       void *cache_marker;
245       const char *pw = agent_get_cache (hexgrip, &cache_marker);
246       if (pw)
247         {
248           rc = agent_unprotect (*keybuf, pw, &result, &resultlen);
249           agent_unlock_cache_entry (&cache_marker);
250           if (!rc)
251             {
252               xfree (*keybuf);
253               *keybuf = result;
254               return 0;
255             }
256           rc  = 0;
257         }
258     }
259   
260   pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
261   if (!pi)
262     return gpg_error_from_errno (errno);
263   pi->max_length = 100;
264   pi->min_digits = 0;  /* we want a real passphrase */
265   pi->max_digits = 8;
266   pi->max_tries = 3;
267   pi->check_cb = try_unprotect_cb;
268   arg.protected_key = *keybuf;
269   arg.unprotected_key = NULL;
270   pi->check_cb_arg = &arg;
271
272   rc = agent_askpin (ctrl, desc_text, NULL, pi);
273   if (!rc)
274     {
275       assert (arg.unprotected_key);
276       agent_put_cache (hexgrip, pi->pin, 0);
277       xfree (*keybuf);
278       *keybuf = arg.unprotected_key;
279     }
280   xfree (pi);
281   return rc;
282 }
283
284
285 /* Read the key identified by GRIP from the private key directory and
286    return it as an gcrypt S-expression object in RESULT.  On failure
287    returns an error code and stores NULL at RESULT. */
288 static gpg_error_t
289 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
290 {
291   int i, rc;
292   char *fname;
293   FILE *fp;
294   struct stat st;
295   unsigned char *buf;
296   size_t buflen, erroff;
297   gcry_sexp_t s_skey;
298   char hexgrip[40+4+1];
299   
300   *result = NULL;
301
302   for (i=0; i < 20; i++)
303     sprintf (hexgrip+2*i, "%02X", grip[i]);
304   strcpy (hexgrip+40, ".key");
305
306   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
307   fp = fopen (fname, "rb");
308   if (!fp)
309     {
310       rc = gpg_error_from_errno (errno);
311       log_error ("can't open `%s': %s\n", fname, strerror (errno));
312       xfree (fname);
313       return rc;
314     }
315   
316   if (fstat (fileno(fp), &st))
317     {
318       rc = gpg_error_from_errno (errno);
319       log_error ("can't stat `%s': %s\n", fname, strerror (errno));
320       xfree (fname);
321       fclose (fp);
322       return rc;
323     }
324
325   buflen = st.st_size;
326   buf = xtrymalloc (buflen+1);
327   if (!buf || fread (buf, buflen, 1, fp) != 1)
328     {
329       rc = gpg_error_from_errno (errno);
330       log_error ("error reading `%s': %s\n", fname, strerror (errno));
331       xfree (fname);
332       fclose (fp);
333       xfree (buf);
334       return rc;
335     }
336
337   /* Convert the file into a gcrypt S-expression object.  */
338   rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen);
339   xfree (fname);
340   fclose (fp);
341   xfree (buf);
342   if (rc)
343     {
344       log_error ("failed to build S-Exp (off=%u): %s\n",
345                  (unsigned int)erroff, gpg_strerror (rc));
346       return rc;
347     }
348   *result = s_skey;
349   return 0;
350 }
351
352
353 /* Return the secret key as an S-Exp in RESULT after locating it using
354    the grip.  Returns NULL in RESULT if the operation should be
355    diverted to a token; SHADOW_INFO will point then to an allocated
356    S-Expression with the shadow_info part from the file.  With
357    IGNORE_CACHE passed as true the passphrase is not taken from the
358    cache.  DESC_TEXT may be set to present a custom description for the
359    pinentry. */
360 gpg_error_t
361 agent_key_from_file (ctrl_t ctrl, const char *desc_text,
362                      const unsigned char *grip, unsigned char **shadow_info,
363                      int ignore_cache, gcry_sexp_t *result)
364 {
365   int rc;
366   unsigned char *buf;
367   size_t len, buflen, erroff;
368   gcry_sexp_t s_skey;
369   int got_shadow_info = 0;
370   
371   *result = NULL;
372   if (shadow_info)
373       *shadow_info = NULL;
374
375   rc = read_key_file (grip, &s_skey);
376   if (rc)
377     return rc;
378
379   /* For use with the protection functions we also need the key as an
380      canonical encoded S-expression in abuffer.  Create this buffer
381      now.  */
382   len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
383   assert (len);
384   buf = xtrymalloc (len);
385   if (!buf)
386     {
387       rc = gpg_error_from_errno (errno);
388       gcry_sexp_release (s_skey);
389       return rc;
390     }
391   len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len);
392   assert (len);
393
394
395   switch (agent_private_key_type (buf))
396     {
397     case PRIVATE_KEY_CLEAR:
398       break; /* no unprotection needed */
399     case PRIVATE_KEY_PROTECTED:
400       {
401         gcry_sexp_t comment_sexp;
402         size_t comment_length;
403         char *desc_text_final;
404         const char *comment = NULL;
405
406         /* Note, that we will take the comment as a C string for
407            display purposes; i.e. all stuff beyond a Nul character is
408            ignored.  */
409         comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
410         if (comment_sexp)
411           comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
412         if (!comment)
413           {
414             comment = "";
415             comment_length = 0;
416           }
417
418         desc_text_final = NULL;
419         if (desc_text)
420           {
421             if (comment[comment_length])
422               {
423                 /* Not a C-string; create one.  We might here allocate
424                    more than actually displayed but well, that
425                    shouldn't be a problem.  */
426                 char *tmp = xtrymalloc (comment_length+1);
427                 if (!tmp)
428                   rc = gpg_error_from_errno (errno);
429                 else
430                   {
431                     memcpy (tmp, comment, comment_length);
432                     tmp[comment_length] = 0;
433                     rc = modify_description (desc_text, tmp, &desc_text_final);
434                     xfree (tmp);
435                   }
436               }
437             else
438               rc = modify_description (desc_text, comment, &desc_text_final);
439           }
440
441         if (!rc)
442           {
443             rc = unprotect (ctrl, desc_text_final, &buf, grip, ignore_cache);
444             if (rc)
445               log_error ("failed to unprotect the secret key: %s\n",
446                          gpg_strerror (rc));
447           }
448         
449         gcry_sexp_release (comment_sexp);
450         xfree (desc_text_final);
451       }
452       break;
453     case PRIVATE_KEY_SHADOWED:
454       if (shadow_info)
455         {
456           const unsigned char *s;
457           size_t n;
458
459           rc = agent_get_shadow_info (buf, &s);
460           if (!rc)
461             {
462               n = gcry_sexp_canon_len (s, 0, NULL,NULL);
463               assert (n);
464               *shadow_info = xtrymalloc (n);
465               if (!*shadow_info)
466                 rc = out_of_core ();
467               else
468                 {
469                   memcpy (*shadow_info, s, n);
470                   rc = 0;
471                   got_shadow_info = 1;
472                 }
473             }
474           if (rc)
475             log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
476         }
477       else
478         rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
479       break;
480     default:
481       log_error ("invalid private key format\n");
482       rc = gpg_error (GPG_ERR_BAD_SECKEY);
483       break;
484     }
485   gcry_sexp_release (s_skey);
486   s_skey = NULL;
487   if (rc || got_shadow_info)
488     {
489       xfree (buf);
490       return rc;
491     }
492
493   buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
494   rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen);
495   wipememory (buf, buflen);
496   xfree (buf);
497   if (rc)
498     {
499       log_error ("failed to build S-Exp (off=%u): %s\n",
500                  (unsigned int)erroff, gpg_strerror (rc));
501       return rc;
502     }
503
504   *result = s_skey;
505   return 0;
506 }
507
508
509
510 /* Return the public key for the keygrip GRIP.  The result is stored
511    at RESULT.  This function extracts the public key from the private
512    key database.  On failure an error code is returned and NULL stored
513    at RESULT. */
514 gpg_error_t
515 agent_public_key_from_file (ctrl_t ctrl, 
516                             const unsigned char *grip,
517                             gcry_sexp_t *result)
518 {
519   int i, idx, rc;
520   gcry_sexp_t s_skey;
521   const char *algoname;
522   gcry_sexp_t uri_sexp, comment_sexp;
523   const char *uri, *comment;
524   size_t uri_length, comment_length;
525   char *format, *p;
526   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
527                            for comment + end-of-list.  */
528   int argidx;
529   gcry_sexp_t list, l2;
530   const char *name;
531   const char *s;
532   size_t n;
533   const char *elems;
534   gcry_mpi_t *array;
535
536   *result = NULL;
537
538   rc = read_key_file (grip, &s_skey);
539   if (rc)
540     return rc;
541
542   list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
543   if (!list)
544     list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
545   if (!list)
546     list = gcry_sexp_find_token (s_skey, "private-key", 0 );
547   if (!list)
548     {
549       log_error ("invalid private key format\n");
550       gcry_sexp_release (s_skey);
551       return gpg_error (GPG_ERR_BAD_SECKEY);
552     }
553
554   l2 = gcry_sexp_cadr (list);
555   gcry_sexp_release (list);
556   list = l2;
557   name = gcry_sexp_nth_data (list, 0, &n);
558   if (n==3 && !memcmp (name, "rsa", 3))
559     {
560       algoname = "rsa";
561       elems = "ne";
562     }
563   else if (n==3 && !memcmp (name, "dsa", 3))
564     {
565       algoname = "dsa";
566       elems = "pqgy";
567     }
568   else if (n==3 && !memcmp (name, "elg", 3))
569     {
570       algoname = "elg";
571       elems = "pgy";
572     }
573   else
574     {
575       log_error ("unknown private key algorithm\n");
576       gcry_sexp_release (list);
577       gcry_sexp_release (s_skey);
578       return gpg_error (GPG_ERR_BAD_SECKEY);
579     }
580
581   /* Allocate an array for the parameters and copy them out of the
582      secret key.   FIXME: We should have a generic copy function. */
583   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
584   if (!array)
585     {
586       rc = gpg_error_from_errno (errno);
587       gcry_sexp_release (list);
588       gcry_sexp_release (s_skey);
589       return rc;
590     }
591
592   for (idx=0, s=elems; *s; s++, idx++ ) 
593     {
594       l2 = gcry_sexp_find_token (list, s, 1);
595       if (!l2)
596         {
597           /* Required parameter not found.  */
598           for (i=0; i<idx; i++)
599             gcry_mpi_release (array[i]);
600           xfree (array);
601           gcry_sexp_release (list);
602           gcry_sexp_release (s_skey);
603           return gpg_error (GPG_ERR_BAD_SECKEY);
604         }
605       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
606       gcry_sexp_release (l2);
607       if (!array[idx])
608         {
609           /* Required parameter is invalid. */
610           for (i=0; i<idx; i++)
611             gcry_mpi_release (array[i]);
612           xfree (array);
613           gcry_sexp_release (list);
614           gcry_sexp_release (s_skey);
615           return gpg_error (GPG_ERR_BAD_SECKEY);
616         }
617     }
618   gcry_sexp_release (list);
619   list = NULL;
620
621   uri = NULL;
622   uri_length = 0;
623   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
624   if (uri_sexp)
625     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
626
627   comment = NULL;
628   comment_length = 0;
629   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
630   if (comment_sexp)
631     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
632
633   gcry_sexp_release (s_skey);
634   s_skey = NULL;
635
636
637   /* FIXME: The following thing is pretty ugly code; we should
638      investigate how to make it cleaner. Probably code to handle
639      canonical S-expressions in a memory buffer is better suioted for
640      such a task.  After all that is what we do in protect.c.  Neeed
641      to find common patterns and write a straightformward API to use
642      them.  */
643   assert (sizeof (size_t) <= sizeof (void*));
644
645   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
646   if (!format)
647     {
648       rc = gpg_error_from_errno (errno);
649       for (i=0; array[i]; i++)
650         gcry_mpi_release (array[i]);
651       xfree (array);
652       gcry_sexp_release (uri_sexp);
653       gcry_sexp_release (comment_sexp);
654       return rc;
655     }
656
657   argidx = 0;
658   p = stpcpy (stpcpy (format, "(public-key("), algoname);
659   for (idx=0, s=elems; *s; s++, idx++ ) 
660     {
661       *p++ = '(';
662       *p++ = *s;
663       p = stpcpy (p, " %m)");
664       assert (argidx < DIM (args));
665       args[argidx++] = array[idx];
666     }
667   *p++ = ')';
668   if (uri)
669     {
670       p = stpcpy (p, "(uri %b)");
671       assert (argidx+1 < DIM (args));
672       args[argidx++] = (void *)uri_length;
673       args[argidx++] = (void *)uri;
674     }
675   if (comment)
676     {
677       p = stpcpy (p, "(comment %b)");
678       assert (argidx+1 < DIM (args));
679       args[argidx++] = (void *)comment_length;
680       args[argidx++] = (void*)comment;
681     }
682   *p++ = ')';
683   *p = 0;
684   assert (argidx < DIM (args));
685   args[argidx] = NULL;
686     
687   rc = gcry_sexp_build_array (&list, NULL, format, args);
688   xfree (format);
689   for (i=0; array[i]; i++)
690     gcry_mpi_release (array[i]);
691   xfree (array);
692   gcry_sexp_release (uri_sexp);
693   gcry_sexp_release (comment_sexp);
694
695   if (!rc)
696     *result = list;
697   return rc;
698 }
699
700
701
702 /* Return the secret key as an S-Exp after locating it using the grip.
703    Returns NULL if key is not available. 0 = key is available */
704 int
705 agent_key_available (const unsigned char *grip)
706 {
707   int i;
708   char *fname;
709   char hexgrip[40+4+1];
710   
711   for (i=0; i < 20; i++)
712     sprintf (hexgrip+2*i, "%02X", grip[i]);
713   strcpy (hexgrip+40, ".key");
714
715   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
716   i = !access (fname, R_OK)? 0 : -1;
717   xfree (fname);
718   return i;
719 }
720
721
722