Nuked almost all trailing white space.
[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==5 && !memcmp (name, "ecdsa", 5))
730     {
731       algoname = "ecdsa";
732       elems = "pabgnq";
733     }
734   else if (n==4 && !memcmp (name, "ecdh", 4))
735     {
736       algoname = "ecdh";
737       elems = "pabgnq";
738     }
739   else if (n==3 && !memcmp (name, "elg", 3))
740     {
741       algoname = "elg";
742       elems = "pgy";
743     }
744   else
745     {
746       log_error ("unknown private key algorithm\n");
747       gcry_sexp_release (list);
748       return gpg_error (GPG_ERR_BAD_SECKEY);
749     }
750
751   if (r_algoname)
752     {
753       if (strlen (algoname) >= algonamesize)
754         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
755       strcpy (r_algoname, algoname);
756     }
757   if (r_elems)
758     {
759       if (strlen (elems) >= elemssize)
760         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
761       strcpy (r_elems, elems);
762     }
763
764   if (r_list)
765     *r_list = list;
766   else
767     gcry_sexp_release (list);
768
769   return 0;
770 }
771
772
773 /* Return the public key algorithm number if S_KEY is a DSA style key.
774    If it is not a DSA style key, return 0.  */
775 int
776 agent_is_dsa_key (gcry_sexp_t s_key)
777 {
778   char algoname[6];
779
780   if (!s_key)
781     return 0;
782
783   if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
784     return 0; /* Error - assume it is not an DSA key.  */
785
786   if (!strcmp (algoname, "dsa"))
787     return GCRY_PK_DSA;
788   else if (!strcmp (algoname, "ecdsa"))
789     return GCRY_PK_ECDSA;
790   else
791     return 0;
792 }
793
794
795
796 /* Return the public key for the keygrip GRIP.  The result is stored
797    at RESULT.  This function extracts the public key from the private
798    key database.  On failure an error code is returned and NULL stored
799    at RESULT. */
800 gpg_error_t
801 agent_public_key_from_file (ctrl_t ctrl,
802                             const unsigned char *grip,
803                             gcry_sexp_t *result)
804 {
805   gpg_error_t err;
806   int i, idx;
807   gcry_sexp_t s_skey;
808   char algoname[6];
809   char elems[6];
810   gcry_sexp_t uri_sexp, comment_sexp;
811   const char *uri, *comment;
812   size_t uri_length, comment_length;
813   char *format, *p;
814   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
815                            for comment + end-of-list.  */
816   int argidx;
817   gcry_sexp_t list, l2;
818   const char *s;
819   gcry_mpi_t *array;
820
821   (void)ctrl;
822
823   *result = NULL;
824
825   err = read_key_file (grip, &s_skey);
826   if (err)
827     return err;
828
829   err = key_parms_from_sexp (s_skey, &list,
830                             algoname, sizeof algoname,
831                             elems, sizeof elems);
832   if (err)
833     {
834       gcry_sexp_release (s_skey);
835       return err;
836     }
837
838   /* Allocate an array for the parameters and copy them out of the
839      secret key.   FIXME: We should have a generic copy function. */
840   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
841   if (!array)
842     {
843       err = gpg_error_from_syserror ();
844       gcry_sexp_release (list);
845       gcry_sexp_release (s_skey);
846       return err;
847     }
848
849   for (idx=0, s=elems; *s; s++, idx++ )
850     {
851       l2 = gcry_sexp_find_token (list, s, 1);
852       if (!l2)
853         {
854           /* Required parameter not found.  */
855           for (i=0; i<idx; i++)
856             gcry_mpi_release (array[i]);
857           xfree (array);
858           gcry_sexp_release (list);
859           gcry_sexp_release (s_skey);
860           return gpg_error (GPG_ERR_BAD_SECKEY);
861         }
862       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
863       gcry_sexp_release (l2);
864       if (!array[idx])
865         {
866           /* Required parameter is invalid. */
867           for (i=0; i<idx; i++)
868             gcry_mpi_release (array[i]);
869           xfree (array);
870           gcry_sexp_release (list);
871           gcry_sexp_release (s_skey);
872           return gpg_error (GPG_ERR_BAD_SECKEY);
873         }
874     }
875   gcry_sexp_release (list);
876   list = NULL;
877
878   uri = NULL;
879   uri_length = 0;
880   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
881   if (uri_sexp)
882     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
883
884   comment = NULL;
885   comment_length = 0;
886   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
887   if (comment_sexp)
888     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
889
890   gcry_sexp_release (s_skey);
891   s_skey = NULL;
892
893
894   /* FIXME: The following thing is pretty ugly code; we should
895      investigate how to make it cleaner.  Probably code to handle
896      canonical S-expressions in a memory buffer is better suited for
897      such a task.  After all that is what we do in protect.c.  Neeed
898      to find common patterns and write a straightformward API to use
899      them.  */
900   assert (sizeof (size_t) <= sizeof (void*));
901
902   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
903   if (!format)
904     {
905       err = gpg_error_from_syserror ();
906       for (i=0; array[i]; i++)
907         gcry_mpi_release (array[i]);
908       xfree (array);
909       gcry_sexp_release (uri_sexp);
910       gcry_sexp_release (comment_sexp);
911       return err;
912     }
913
914   argidx = 0;
915   p = stpcpy (stpcpy (format, "(public-key("), algoname);
916   for (idx=0, s=elems; *s; s++, idx++ )
917     {
918       *p++ = '(';
919       *p++ = *s;
920       p = stpcpy (p, " %m)");
921       assert (argidx < DIM (args));
922       args[argidx++] = &array[idx];
923     }
924   *p++ = ')';
925   if (uri)
926     {
927       p = stpcpy (p, "(uri %b)");
928       assert (argidx+1 < DIM (args));
929       args[argidx++] = (void *)uri_length;
930       args[argidx++] = (void *)uri;
931     }
932   if (comment)
933     {
934       p = stpcpy (p, "(comment %b)");
935       assert (argidx+1 < DIM (args));
936       args[argidx++] = (void *)comment_length;
937       args[argidx++] = (void*)comment;
938     }
939   *p++ = ')';
940   *p = 0;
941   assert (argidx < DIM (args));
942   args[argidx] = NULL;
943
944   err = gcry_sexp_build_array (&list, NULL, format, args);
945   xfree (format);
946   for (i=0; array[i]; i++)
947     gcry_mpi_release (array[i]);
948   xfree (array);
949   gcry_sexp_release (uri_sexp);
950   gcry_sexp_release (comment_sexp);
951
952   if (!err)
953     *result = list;
954   return err;
955 }
956
957
958
959 /* Check whether the the secret key identified by GRIP is available.
960    Returns 0 is the key is available.  */
961 int
962 agent_key_available (const unsigned char *grip)
963 {
964   int result;
965   char *fname;
966   char hexgrip[40+4+1];
967
968   bin2hex (grip, 20, hexgrip);
969   strcpy (hexgrip+40, ".key");
970
971   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
972   result = !access (fname, R_OK)? 0 : -1;
973   xfree (fname);
974   return result;
975 }
976
977
978
979 /* Return the information about the secret key specified by the binary
980    keygrip GRIP.  If the key is a shadowed one the shadow information
981    will be stored at the address R_SHADOW_INFO as an allocated
982    S-expression.  */
983 gpg_error_t
984 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
985                           int *r_keytype, unsigned char **r_shadow_info)
986 {
987   gpg_error_t err;
988   unsigned char *buf;
989   size_t len;
990   int keytype;
991
992   (void)ctrl;
993
994   if (r_keytype)
995     *r_keytype = PRIVATE_KEY_UNKNOWN;
996   if (r_shadow_info)
997     *r_shadow_info = NULL;
998
999   {
1000     gcry_sexp_t sexp;
1001
1002     err = read_key_file (grip, &sexp);
1003     if (err)
1004       {
1005         if (gpg_err_code (err) == GPG_ERR_ENOENT)
1006           return gpg_error (GPG_ERR_NOT_FOUND);
1007         else
1008           return err;
1009       }
1010     err = make_canon_sexp (sexp, &buf, &len);
1011     gcry_sexp_release (sexp);
1012     if (err)
1013       return err;
1014   }
1015
1016   keytype = agent_private_key_type (buf);
1017   switch (keytype)
1018     {
1019     case PRIVATE_KEY_CLEAR:
1020       break;
1021     case PRIVATE_KEY_PROTECTED:
1022       /* If we ever require it we could retrieve the comment fields
1023          from such a key. */
1024       break;
1025     case PRIVATE_KEY_SHADOWED:
1026       if (r_shadow_info)
1027         {
1028           const unsigned char *s;
1029           size_t n;
1030
1031           err = agent_get_shadow_info (buf, &s);
1032           if (!err)
1033             {
1034               n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1035               assert (n);
1036               *r_shadow_info = xtrymalloc (n);
1037               if (!*r_shadow_info)
1038                 err = gpg_error_from_syserror ();
1039               else
1040                 memcpy (*r_shadow_info, s, n);
1041             }
1042         }
1043       break;
1044     default:
1045       err = gpg_error (GPG_ERR_BAD_SECKEY);
1046       break;
1047     }
1048
1049   if (!err && r_keytype)
1050     *r_keytype = keytype;
1051
1052   xfree (buf);
1053   return err;
1054 }