Change stack size for Wince.
[gnupg.git] / agent / findkey.c
1 /* findkey.c - Locate the secret key
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
3  *               2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
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 #include <pth.h> /* (we use pth_sleep) */
33
34 #include "agent.h"
35 #include "i18n.h"
36
37 #ifndef O_BINARY
38 #define O_BINARY 0
39 #endif
40
41 /* Helper to pass data to the check callback of the unprotect function. */
42 struct try_unprotect_arg_s 
43 {
44   ctrl_t ctrl;
45   const unsigned char *protected_key;
46   unsigned char *unprotected_key;
47   int change_required; /* Set by the callback to indicate that the
48                           user should chnage the passphrase.  */
49 };
50
51
52 /* Write an S-expression formatted key to our key storage.  With FORCE
53    passed as true an existing key with the given GRIP will get
54    overwritten.  */
55 int
56 agent_write_private_key (const unsigned char *grip,
57                          const void *buffer, size_t length, int force)
58 {
59   char *fname;
60   estream_t fp;
61   char hexgrip[40+4+1];
62   
63   bin2hex (grip, 20, hexgrip);
64   strcpy (hexgrip+40, ".key");
65
66   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
67
68   if (!force && !access (fname, F_OK))
69     {
70       log_error ("secret key file `%s' already exists\n", fname);
71       xfree (fname);
72       return gpg_error (GPG_ERR_EEXIST);
73     }
74
75   fp = es_fopen (fname, force? "wb,mode=-rw" : "wbx,mode=-rw");
76   if (!fp) 
77     { 
78       gpg_error_t tmperr = gpg_error_from_syserror ();
79       log_error ("can't create `%s': %s\n", fname, gpg_strerror (tmperr));
80       xfree (fname);
81       return tmperr;
82     }
83
84   if (es_fwrite (buffer, length, 1, fp) != 1)
85     {
86       gpg_error_t tmperr = gpg_error_from_syserror ();
87       log_error ("error writing `%s': %s\n", fname, gpg_strerror (tmperr));
88       es_fclose (fp);
89       gnupg_remove (fname);
90       xfree (fname);
91       return tmperr;
92     }
93   if (es_fclose (fp))
94     {
95       gpg_error_t tmperr = gpg_error_from_syserror ();
96       log_error ("error closing `%s': %s\n", fname, gpg_strerror (tmperr));
97       gnupg_remove (fname);
98       xfree (fname);
99       return tmperr;
100     }
101   bump_key_eventcounter ();
102   xfree (fname);
103   return 0;
104 }
105
106
107 /* Callback function to try the unprotection from the passphrase query
108    code. */
109 static int
110 try_unprotect_cb (struct pin_entry_info_s *pi)
111 {
112   struct try_unprotect_arg_s *arg = pi->check_cb_arg;
113   size_t dummy;
114   gpg_error_t err;
115   gnupg_isotime_t now, protected_at, tmptime;
116   char *desc = NULL;
117
118   assert (!arg->unprotected_key);
119
120   arg->change_required = 0;
121   err = agent_unprotect (arg->protected_key, pi->pin, protected_at,
122                          &arg->unprotected_key, &dummy);
123   if (err)
124     return err;
125   if (!opt.max_passphrase_days || arg->ctrl->in_passwd)
126     return 0;  /* No regular passphrase change required.  */
127
128   if (!*protected_at)
129     {
130       /* No protection date known - must force passphrase change.  */
131       desc = xtrystrdup (_("Note: This passphrase has never been changed.%0A"
132                            "Please change it now."));
133       if (!desc)
134         return gpg_error_from_syserror ();
135     }
136   else
137     {
138       gnupg_get_isotime (now);
139       gnupg_copy_time (tmptime, protected_at);
140       err = add_days_to_isotime (tmptime, opt.max_passphrase_days);
141       if (err)
142         return err;
143       if (strcmp (now, tmptime) > 0 )
144         {
145           /* Passphrase "expired".  */
146           desc = xtryasprintf 
147             (_("This passphrase has not been changed%%0A"
148                "since %.4s-%.2s-%.2s.  Please change it now."),
149              protected_at, protected_at+4, protected_at+6);
150           if (!desc)
151             return gpg_error_from_syserror ();
152         }
153     }
154
155   if (desc)
156     {
157       /* Change required.  */
158       if (opt.enforce_passphrase_constraints)
159         {
160           err = agent_get_confirmation (arg->ctrl, desc,
161                                         _("Change passphrase"), NULL, 0);
162           if (!err)
163             arg->change_required = 1;
164         }
165       else
166         {
167           err = agent_get_confirmation (arg->ctrl, desc,
168                                         _("Change passphrase"),
169                                         _("I'll change it later"), 0);
170           if (!err)
171             arg->change_required = 1;
172           else if (gpg_err_code (err) == GPG_ERR_CANCELED
173                    || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
174             err = 0;
175         }
176       xfree (desc);
177     }
178
179   return 0;
180 }
181
182
183 /* Modify a Key description, replacing certain special format
184    characters.  List of currently supported replacements:
185
186    %% - Replaced by a single %
187    %c - Replaced by the content of COMMENT.
188
189    The functions returns 0 on success or an error code.  On success a
190    newly allocated string is stored at the address of RESULT.
191  */
192 static gpg_error_t
193 modify_description (const char *in, const char *comment, char **result)
194 {
195   size_t comment_length;
196   size_t in_len;
197   size_t out_len;
198   char *out;
199   size_t i;
200   int special, pass;
201
202   comment_length = strlen (comment);
203   in_len  = strlen (in);
204
205   /* First pass calculates the length, second pass does the actual
206      copying.  */
207   out = NULL;
208   out_len = 0;
209   for (pass=0; pass < 2; pass++)
210     {
211       special = 0;
212       for (i = 0; i < in_len; i++)
213         {
214           if (special)
215             {
216               special = 0;
217               switch (in[i])
218                 {
219                 case '%':
220                   if (out)
221                     *out++ = '%';
222                   else
223                     out_len++;
224                   break;
225
226                 case 'c': /* Comment.  */
227                   if (out)
228                     {
229                       memcpy (out, comment, comment_length);
230                       out += comment_length;
231                     }
232                   else
233                     out_len += comment_length;
234                   break;
235
236                 default: /* Invalid special sequences are kept as they are. */
237                   if (out)
238                     {
239                       *out++ = '%';
240                       *out++ = in[i];
241                     }
242                   else
243                     out_len+=2;
244                   break;
245                 }
246             }
247           else if (in[i] == '%')
248             special = 1;
249           else
250             {
251               if (out)
252                 *out++ = in[i];
253               else
254                 out_len++;
255             }
256         }
257       
258       if (!pass)
259         {
260           *result = out = xtrymalloc (out_len + 1);
261           if (!out)
262             return gpg_error_from_syserror ();
263         }
264     }
265
266   *out = 0;
267   assert (*result + out_len == out);
268   return 0;
269 }
270
271   
272
273 /* Unprotect the canconical encoded S-expression key in KEYBUF.  GRIP
274    should be the hex encoded keygrip of that key to be used with the
275    caching mechanism. DESC_TEXT may be set to override the default
276    description used for the pinentry.  If LOOKUP_TTL is given this
277    function is used to lookup the default ttl.  If R_PASSPHRASE is not
278    NULL, the function succeeded and the key was protected the used
279    passphrase (entered or from the cache) is stored there; if not NULL
280    will be stored.  The caller needs to free the returned
281    passphrase. */
282 static int
283 unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
284            unsigned char **keybuf, const unsigned char *grip, 
285            cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
286            char **r_passphrase)
287 {
288   struct pin_entry_info_s *pi;
289   struct try_unprotect_arg_s arg;
290   int rc;
291   unsigned char *result;
292   size_t resultlen;
293   char hexgrip[40+1];
294
295   if (r_passphrase)
296     *r_passphrase = NULL;
297   
298   bin2hex (grip, 20, hexgrip);
299
300   /* Initially try to get it using a cache nonce.  */
301   if (cache_nonce)
302     {
303       char *pw;
304       
305       pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
306       if (pw)
307         {
308           rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
309           if (!rc)
310             {
311               if (r_passphrase)
312                 *r_passphrase = pw;
313               else
314                 xfree (pw);
315               xfree (*keybuf);
316               *keybuf = result;
317               return 0;
318             }
319           xfree (pw);
320         }
321     }
322
323   /* First try to get it from the cache - if there is none or we can't
324      unprotect it, we fall back to ask the user */
325   if (cache_mode != CACHE_MODE_IGNORE)
326     {
327       char *pw;
328       
329     retry:
330       pw = agent_get_cache (hexgrip, cache_mode);
331       if (pw)
332         {
333           rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
334           if (!rc)
335             {
336               if (r_passphrase)
337                 *r_passphrase = pw;
338               else
339                 xfree (pw);
340               xfree (*keybuf);
341               *keybuf = result;
342               return 0;
343             }
344           xfree (pw);
345           rc  = 0;
346         }
347
348       /* If the pinentry is currently in use, we wait up to 60 seconds
349          for it to close and check the cache again.  This solves a common
350          situation where several requests for unprotecting a key have
351          been made but the user is still entering the passphrase for
352          the first request.  Because all requests to agent_askpin are
353          serialized they would then pop up one after the other to
354          request the passphrase - despite that the user has already
355          entered it and is then available in the cache.  This
356          implementation is not race free but in the worst case the
357          user has to enter the passphrase only once more. */
358       if (pinentry_active_p (ctrl, 0))
359         {
360           /* Active - wait */
361           if (!pinentry_active_p (ctrl, 60))
362             {
363               /* We need to give the other thread a chance to actually put
364                  it into the cache. */
365               pth_sleep (1); 
366               goto retry;
367             }
368           /* Timeout - better call pinentry now the plain way. */
369         }
370     }
371
372   pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
373   if (!pi)
374     return gpg_error_from_syserror ();
375   pi->max_length = 100;
376   pi->min_digits = 0;  /* we want a real passphrase */
377   pi->max_digits = 16;
378   pi->max_tries = 3;
379   pi->check_cb = try_unprotect_cb;
380   arg.ctrl = ctrl;
381   arg.protected_key = *keybuf;
382   arg.unprotected_key = NULL;
383   arg.change_required = 0;
384   pi->check_cb_arg = &arg;
385
386   rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
387   if (!rc)
388     {
389       assert (arg.unprotected_key);
390       if (arg.change_required)
391         {
392           size_t canlen, erroff;
393           gcry_sexp_t s_skey;
394           
395           assert (arg.unprotected_key);
396           canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
397           rc = gcry_sexp_sscan (&s_skey, &erroff,
398                                 (char*)arg.unprotected_key, canlen);
399           if (rc)
400             {
401               log_error ("failed to build S-Exp (off=%u): %s\n",
402                          (unsigned int)erroff, gpg_strerror (rc));
403               wipememory (arg.unprotected_key, canlen);
404               xfree (arg.unprotected_key);
405               xfree (pi);
406               return rc;
407             }
408           rc = agent_protect_and_store (ctrl, s_skey, NULL);
409           gcry_sexp_release (s_skey);
410           if (rc)
411             {
412               log_error ("changing the passphrase failed: %s\n", 
413                          gpg_strerror (rc));
414               wipememory (arg.unprotected_key, canlen);
415               xfree (arg.unprotected_key);
416               xfree (pi);
417               return rc;
418             }
419         }
420       else
421         {
422           agent_put_cache (hexgrip, cache_mode, pi->pin, 
423                            lookup_ttl? lookup_ttl (hexgrip) : 0);
424           if (r_passphrase && *pi->pin)
425             *r_passphrase = xtrystrdup (pi->pin);
426         }
427       xfree (*keybuf);
428       *keybuf = arg.unprotected_key;
429     }
430   xfree (pi);
431   return rc;
432 }
433
434
435 /* Read the key identified by GRIP from the private key directory and
436    return it as an gcrypt S-expression object in RESULT.  On failure
437    returns an error code and stores NULL at RESULT. */
438 static gpg_error_t
439 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
440 {
441   int rc;
442   char *fname;
443   estream_t fp;
444   struct stat st;
445   unsigned char *buf;
446   size_t buflen, erroff;
447   gcry_sexp_t s_skey;
448   char hexgrip[40+4+1];
449   
450   *result = NULL;
451
452   bin2hex (grip, 20, hexgrip);
453   strcpy (hexgrip+40, ".key");
454
455   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
456   fp = es_fopen (fname, "rb");
457   if (!fp)
458     {
459       rc = gpg_error_from_syserror ();
460       if (gpg_err_code (rc) != GPG_ERR_ENOENT)
461         log_error ("can't open `%s': %s\n", fname, strerror (errno));
462       xfree (fname);
463       return rc;
464     }
465   
466   if (fstat (es_fileno (fp), &st))
467     {
468       rc = gpg_error_from_syserror ();
469       log_error ("can't stat `%s': %s\n", fname, strerror (errno));
470       xfree (fname);
471       es_fclose (fp);
472       return rc;
473     }
474
475   buflen = st.st_size;
476   buf = xtrymalloc (buflen+1);
477   if (!buf)
478     {
479       rc = gpg_error_from_syserror ();
480       log_error ("error allocating %zu bytes for `%s': %s\n",
481                  buflen, fname, strerror (errno));
482       xfree (fname);
483       es_fclose (fp);
484       xfree (buf);
485       return rc;
486
487     }
488
489   if (es_fread (buf, buflen, 1, fp) != 1)
490     {
491       rc = gpg_error_from_syserror ();
492       log_error ("error reading %zu bytes from `%s': %s\n", 
493                  buflen, fname, strerror (errno));
494       xfree (fname);
495       es_fclose (fp);
496       xfree (buf);
497       return rc;
498     }
499
500   /* Convert the file into a gcrypt S-expression object.  */
501   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
502   xfree (fname);
503   es_fclose (fp);
504   xfree (buf);
505   if (rc)
506     {
507       log_error ("failed to build S-Exp (off=%u): %s\n",
508                  (unsigned int)erroff, gpg_strerror (rc));
509       return rc;
510     }
511   *result = s_skey;
512   return 0;
513 }
514
515
516 /* Return the secret key as an S-Exp in RESULT after locating it using
517    the GRIP.  Stores NULL at RESULT if the operation shall be diverted
518    to a token; in this case an allocated S-expression with the
519    shadow_info part from the file is stored at SHADOW_INFO.
520    CACHE_MODE defines now the cache shall be used.  DESC_TEXT may be
521    set to present a custom description for the pinentry.  LOOKUP_TTL
522    is an optional function to convey a TTL to the cache manager; we do
523    not simply pass the TTL value because the value is only needed if
524    an unprotect action was needed and looking up the TTL may have some
525    overhead (e.g. scanning the sshcontrol file).  If a CACHE_NONCE is
526    given that cache item is first tried to get a passphrase.  If
527    R_PASSPHRASE is not NULL, the function succeeded and the key was
528    protected the used passphrase (entered or from the cache) is stored
529    there; if not NULL will be stored.  The caller needs to free the
530    returned passphrase.   */
531 gpg_error_t
532 agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
533                      const char *desc_text,
534                      const unsigned char *grip, unsigned char **shadow_info,
535                      cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
536                      gcry_sexp_t *result, char **r_passphrase)
537 {
538   int rc;
539   unsigned char *buf;
540   size_t len, buflen, erroff;
541   gcry_sexp_t s_skey;
542   int got_shadow_info = 0;
543   
544   *result = NULL;
545   if (shadow_info)
546     *shadow_info = NULL;
547   if (r_passphrase)
548     *r_passphrase = NULL;
549
550   rc = read_key_file (grip, &s_skey);
551   if (rc)
552     return rc;
553
554   /* For use with the protection functions we also need the key as an
555      canonical encoded S-expression in a buffer.  Create this buffer
556      now.  */
557   rc = make_canon_sexp (s_skey, &buf, &len);
558   if (rc)
559     return rc;
560
561   switch (agent_private_key_type (buf))
562     {
563     case PRIVATE_KEY_CLEAR:
564       break; /* no unprotection needed */
565     case PRIVATE_KEY_PROTECTED:
566       {
567         gcry_sexp_t comment_sexp;
568         size_t comment_length;
569         char *desc_text_final;
570         const char *comment = NULL;
571
572         /* Note, that we will take the comment as a C string for
573            display purposes; i.e. all stuff beyond a Nul character is
574            ignored.  */
575         comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
576         if (comment_sexp)
577           comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
578         if (!comment)
579           {
580             comment = "";
581             comment_length = 0;
582           }
583
584         desc_text_final = NULL;
585         if (desc_text)
586           {
587             if (comment[comment_length])
588               {
589                 /* Not a C-string; create one.  We might here allocate
590                    more than actually displayed but well, that
591                    shouldn't be a problem.  */
592                 char *tmp = xtrymalloc (comment_length+1);
593                 if (!tmp)
594                   rc = gpg_error_from_syserror ();
595                 else
596                   {
597                     memcpy (tmp, comment, comment_length);
598                     tmp[comment_length] = 0;
599                     rc = modify_description (desc_text, tmp, &desc_text_final);
600                     xfree (tmp);
601                   }
602               }
603             else
604               rc = modify_description (desc_text, comment, &desc_text_final);
605           }
606
607         if (!rc)
608           {
609             rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
610                             cache_mode, lookup_ttl, r_passphrase);
611             if (rc)
612               log_error ("failed to unprotect the secret key: %s\n",
613                          gpg_strerror (rc));
614           }
615         
616         gcry_sexp_release (comment_sexp);
617         xfree (desc_text_final);
618       }
619       break;
620     case PRIVATE_KEY_SHADOWED:
621       if (shadow_info)
622         {
623           const unsigned char *s;
624           size_t n;
625
626           rc = agent_get_shadow_info (buf, &s);
627           if (!rc)
628             {
629               n = gcry_sexp_canon_len (s, 0, NULL,NULL);
630               assert (n);
631               *shadow_info = xtrymalloc (n);
632               if (!*shadow_info)
633                 rc = out_of_core ();
634               else
635                 {
636                   memcpy (*shadow_info, s, n);
637                   rc = 0;
638                   got_shadow_info = 1;
639                 }
640             }
641           if (rc)
642             log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
643         }
644       else
645         rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
646       break;
647     default:
648       log_error ("invalid private key format\n");
649       rc = gpg_error (GPG_ERR_BAD_SECKEY);
650       break;
651     }
652   gcry_sexp_release (s_skey);
653   s_skey = NULL;
654   if (rc || got_shadow_info)
655     {
656       xfree (buf);
657       if (r_passphrase)
658         {
659           xfree (*r_passphrase);
660           *r_passphrase = NULL;
661         }
662       return rc;
663     }
664
665   buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
666   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
667   wipememory (buf, buflen);
668   xfree (buf);
669   if (rc)
670     {
671       log_error ("failed to build S-Exp (off=%u): %s\n",
672                  (unsigned int)erroff, gpg_strerror (rc));
673       if (r_passphrase)
674         {
675           xfree (*r_passphrase);
676           *r_passphrase = NULL;
677         }
678       return rc;
679     }
680
681   *result = s_skey;
682   return 0;
683 }
684
685
686 /* Return the string name from the S-expression S_KEY as well as a
687    string describing the names of the parameters.  ALGONAMESIZE and
688    ELEMSSIZE give the allocated size of the provided buffers.  The
689    buffers may be NULL if not required.  If R_LIST is not NULL the top
690    level list will be stored tehre; the caller needs to release it in
691    this case.  */
692 static gpg_error_t
693 key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
694                      char *r_algoname, size_t algonamesize,
695                      char *r_elems, size_t elemssize)
696 {
697   gcry_sexp_t list, l2;
698   const char *name, *algoname, *elems;
699   size_t n;
700
701   if (r_list)
702     *r_list = NULL;
703
704   list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
705   if (!list)
706     list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
707   if (!list)
708     list = gcry_sexp_find_token (s_key, "private-key", 0 );
709   if (!list)
710     {
711       log_error ("invalid private key format\n");
712       return gpg_error (GPG_ERR_BAD_SECKEY);
713     }
714
715   l2 = gcry_sexp_cadr (list);
716   gcry_sexp_release (list);
717   list = l2;
718   name = gcry_sexp_nth_data (list, 0, &n);
719   if (n==3 && !memcmp (name, "rsa", 3))
720     {
721       algoname = "rsa";
722       elems = "ne";
723     }
724   else if (n==3 && !memcmp (name, "dsa", 3))
725     {
726       algoname = "dsa";
727       elems = "pqgy";
728     }
729   else if (n==3 && !memcmp (name, "elg", 3))
730     {
731       algoname = "elg";
732       elems = "pgy";
733     }
734   else
735     {
736       log_error ("unknown private key algorithm\n");
737       gcry_sexp_release (list);
738       return gpg_error (GPG_ERR_BAD_SECKEY);
739     }
740
741   if (r_algoname)
742     {
743       if (strlen (algoname) >= algonamesize)
744         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
745       strcpy (r_algoname, algoname);
746     } 
747   if (r_elems)
748     {
749       if (strlen (elems) >= elemssize)
750         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
751       strcpy (r_elems, elems);
752     }
753
754   if (r_list)
755     *r_list = list;
756   else
757     gcry_sexp_release (list);
758       
759   return 0;
760 }
761
762
763 /* Return the public key algorithm number if S_KEY is a DSA style key.
764    If it is not a DSA style key, return 0.  */
765 int 
766 agent_is_dsa_key (gcry_sexp_t s_key)
767 {
768   char algoname[6];
769
770   if (!s_key)
771     return 0;
772
773   if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
774     return 0; /* Error - assume it is not an DSA key.  */
775
776   if (!strcmp (algoname, "dsa"))
777     return GCRY_PK_DSA;
778   else if (!strcmp (algoname, "ecdsa"))
779     return GCRY_PK_ECDSA;
780   else
781     return 0;
782 }
783
784
785
786 /* Return the public key for the keygrip GRIP.  The result is stored
787    at RESULT.  This function extracts the public key from the private
788    key database.  On failure an error code is returned and NULL stored
789    at RESULT. */
790 gpg_error_t
791 agent_public_key_from_file (ctrl_t ctrl, 
792                             const unsigned char *grip,
793                             gcry_sexp_t *result)
794 {
795   gpg_error_t err;
796   int i, idx;
797   gcry_sexp_t s_skey;
798   char algoname[6];
799   char elems[6];
800   gcry_sexp_t uri_sexp, comment_sexp;
801   const char *uri, *comment;
802   size_t uri_length, comment_length;
803   char *format, *p;
804   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
805                            for comment + end-of-list.  */
806   int argidx;
807   gcry_sexp_t list, l2;
808   const char *s;
809   gcry_mpi_t *array;
810
811   (void)ctrl;
812
813   *result = NULL;
814
815   err = read_key_file (grip, &s_skey);
816   if (err)
817     return err;
818
819   err = key_parms_from_sexp (s_skey, &list, 
820                             algoname, sizeof algoname,
821                             elems, sizeof elems);
822   if (err)
823     {
824       gcry_sexp_release (s_skey);
825       return err;
826     }
827
828   /* Allocate an array for the parameters and copy them out of the
829      secret key.   FIXME: We should have a generic copy function. */
830   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
831   if (!array)
832     {
833       err = gpg_error_from_syserror ();
834       gcry_sexp_release (list);
835       gcry_sexp_release (s_skey);
836       return err;
837     }
838
839   for (idx=0, s=elems; *s; s++, idx++ ) 
840     {
841       l2 = gcry_sexp_find_token (list, s, 1);
842       if (!l2)
843         {
844           /* Required parameter not found.  */
845           for (i=0; i<idx; i++)
846             gcry_mpi_release (array[i]);
847           xfree (array);
848           gcry_sexp_release (list);
849           gcry_sexp_release (s_skey);
850           return gpg_error (GPG_ERR_BAD_SECKEY);
851         }
852       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
853       gcry_sexp_release (l2);
854       if (!array[idx])
855         {
856           /* Required parameter is invalid. */
857           for (i=0; i<idx; i++)
858             gcry_mpi_release (array[i]);
859           xfree (array);
860           gcry_sexp_release (list);
861           gcry_sexp_release (s_skey);
862           return gpg_error (GPG_ERR_BAD_SECKEY);
863         }
864     }
865   gcry_sexp_release (list);
866   list = NULL;
867
868   uri = NULL;
869   uri_length = 0;
870   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
871   if (uri_sexp)
872     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
873
874   comment = NULL;
875   comment_length = 0;
876   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
877   if (comment_sexp)
878     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
879
880   gcry_sexp_release (s_skey);
881   s_skey = NULL;
882
883
884   /* FIXME: The following thing is pretty ugly code; we should
885      investigate how to make it cleaner.  Probably code to handle
886      canonical S-expressions in a memory buffer is better suited for
887      such a task.  After all that is what we do in protect.c.  Neeed
888      to find common patterns and write a straightformward API to use
889      them.  */
890   assert (sizeof (size_t) <= sizeof (void*));
891
892   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
893   if (!format)
894     {
895       err = gpg_error_from_syserror ();
896       for (i=0; array[i]; i++)
897         gcry_mpi_release (array[i]);
898       xfree (array);
899       gcry_sexp_release (uri_sexp);
900       gcry_sexp_release (comment_sexp);
901       return err;
902     }
903
904   argidx = 0;
905   p = stpcpy (stpcpy (format, "(public-key("), algoname);
906   for (idx=0, s=elems; *s; s++, idx++ ) 
907     {
908       *p++ = '(';
909       *p++ = *s;
910       p = stpcpy (p, " %m)");
911       assert (argidx < DIM (args));
912       args[argidx++] = &array[idx];
913     }
914   *p++ = ')';
915   if (uri)
916     {
917       p = stpcpy (p, "(uri %b)");
918       assert (argidx+1 < DIM (args));
919       args[argidx++] = (void *)uri_length;
920       args[argidx++] = (void *)uri;
921     }
922   if (comment)
923     {
924       p = stpcpy (p, "(comment %b)");
925       assert (argidx+1 < DIM (args));
926       args[argidx++] = (void *)comment_length;
927       args[argidx++] = (void*)comment;
928     }
929   *p++ = ')';
930   *p = 0;
931   assert (argidx < DIM (args));
932   args[argidx] = NULL;
933     
934   err = gcry_sexp_build_array (&list, NULL, format, args);
935   xfree (format);
936   for (i=0; array[i]; i++)
937     gcry_mpi_release (array[i]);
938   xfree (array);
939   gcry_sexp_release (uri_sexp);
940   gcry_sexp_release (comment_sexp);
941
942   if (!err)
943     *result = list;
944   return err;
945 }
946
947
948
949 /* Check whether the the secret key identified by GRIP is available.
950    Returns 0 is the key is available.  */
951 int
952 agent_key_available (const unsigned char *grip)
953 {
954   int result;
955   char *fname;
956   char hexgrip[40+4+1];
957   
958   bin2hex (grip, 20, hexgrip);
959   strcpy (hexgrip+40, ".key");
960
961   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
962   result = !access (fname, R_OK)? 0 : -1;
963   xfree (fname);
964   return result;
965 }
966
967
968
969 /* Return the information about the secret key specified by the binary
970    keygrip GRIP.  If the key is a shadowed one the shadow information
971    will be stored at the address R_SHADOW_INFO as an allocated
972    S-expression.  */
973 gpg_error_t
974 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
975                           int *r_keytype, unsigned char **r_shadow_info)
976 {
977   gpg_error_t err;
978   unsigned char *buf;
979   size_t len;
980   int keytype;
981
982   (void)ctrl;
983   
984   if (r_keytype)
985     *r_keytype = PRIVATE_KEY_UNKNOWN;
986   if (r_shadow_info)
987     *r_shadow_info = NULL;
988
989   {
990     gcry_sexp_t sexp;
991     
992     err = read_key_file (grip, &sexp);
993     if (err)
994       {
995         if (gpg_err_code (err) == GPG_ERR_ENOENT)
996           return gpg_error (GPG_ERR_NOT_FOUND);
997         else
998           return err;
999       }
1000     err = make_canon_sexp (sexp, &buf, &len);
1001     gcry_sexp_release (sexp);
1002     if (err)
1003       return err;
1004   }
1005   
1006   keytype = agent_private_key_type (buf);
1007   switch (keytype)
1008     {
1009     case PRIVATE_KEY_CLEAR:
1010       break; 
1011     case PRIVATE_KEY_PROTECTED:
1012       /* If we ever require it we could retrieve the comment fields
1013          from such a key. */
1014       break;
1015     case PRIVATE_KEY_SHADOWED:
1016       if (r_shadow_info)
1017         {
1018           const unsigned char *s;
1019           size_t n;
1020
1021           err = agent_get_shadow_info (buf, &s);
1022           if (!err)
1023             {
1024               n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1025               assert (n);
1026               *r_shadow_info = xtrymalloc (n);
1027               if (!*r_shadow_info)
1028                 err = gpg_error_from_syserror ();
1029               else
1030                 memcpy (*r_shadow_info, s, n);
1031             }
1032         }
1033       break;
1034     default:
1035       err = gpg_error (GPG_ERR_BAD_SECKEY);
1036       break;
1037     }
1038
1039   if (!err && r_keytype)
1040     *r_keytype = keytype;
1041
1042   xfree (buf);
1043   return err;
1044 }