Exporting secret keys via gpg-agent is now basically supported.
[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             err = 0;
174         }
175       xfree (desc);
176     }
177
178   return 0;
179 }
180
181
182 /* Modify a Key description, replacing certain special format
183    characters.  List of currently supported replacements:
184
185    %% - Replaced by a single %
186    %c - Replaced by the content of COMMENT.
187
188    The functions returns 0 on success or an error code.  On success a
189    newly allocated string is stored at the address of RESULT.
190  */
191 static gpg_error_t
192 modify_description (const char *in, const char *comment, char **result)
193 {
194   size_t comment_length;
195   size_t in_len;
196   size_t out_len;
197   char *out;
198   size_t i;
199   int special, pass;
200
201   comment_length = strlen (comment);
202   in_len  = strlen (in);
203
204   /* First pass calculates the length, second pass does the actual
205      copying.  */
206   out = NULL;
207   out_len = 0;
208   for (pass=0; pass < 2; pass++)
209     {
210       special = 0;
211       for (i = 0; i < in_len; i++)
212         {
213           if (special)
214             {
215               special = 0;
216               switch (in[i])
217                 {
218                 case '%':
219                   if (out)
220                     *out++ = '%';
221                   else
222                     out_len++;
223                   break;
224
225                 case 'c': /* Comment.  */
226                   if (out)
227                     {
228                       memcpy (out, comment, comment_length);
229                       out += comment_length;
230                     }
231                   else
232                     out_len += comment_length;
233                   break;
234
235                 default: /* Invalid special sequences are kept as they are. */
236                   if (out)
237                     {
238                       *out++ = '%';
239                       *out++ = in[i];
240                     }
241                   else
242                     out_len+=2;
243                   break;
244                 }
245             }
246           else if (in[i] == '%')
247             special = 1;
248           else
249             {
250               if (out)
251                 *out++ = in[i];
252               else
253                 out_len++;
254             }
255         }
256       
257       if (!pass)
258         {
259           *result = out = xtrymalloc (out_len + 1);
260           if (!out)
261             return gpg_error_from_syserror ();
262         }
263     }
264
265   *out = 0;
266   assert (*result + out_len == out);
267   return 0;
268 }
269
270   
271
272 /* Unprotect the canconical encoded S-expression key in KEYBUF.  GRIP
273    should be the hex encoded keygrip of that key to be used with the
274    caching mechanism. DESC_TEXT may be set to override the default
275    description used for the pinentry.  If LOOKUP_TTL is given this
276    function is used to lookup the default ttl.  If R_PASSPHRASE is not
277    NULL, the function succeeded and the key was protected the used
278    passphrase (entered or from the cache) is stored there; if not NULL
279    will be stored.  The caller needs to free the returned
280    passphrase. */
281 static int
282 unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
283            unsigned char **keybuf, const unsigned char *grip, 
284            cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
285            char **r_passphrase)
286 {
287   struct pin_entry_info_s *pi;
288   struct try_unprotect_arg_s arg;
289   int rc;
290   unsigned char *result;
291   size_t resultlen;
292   char hexgrip[40+1];
293   int fully_canceled;
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, &fully_canceled);
387   if (gpg_err_code (rc) == GPG_ERR_CANCELED && fully_canceled)
388     rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
389   if (!rc)
390     {
391       assert (arg.unprotected_key);
392       if (arg.change_required)
393         {
394           size_t canlen, erroff;
395           gcry_sexp_t s_skey;
396           
397           assert (arg.unprotected_key);
398           canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
399           rc = gcry_sexp_sscan (&s_skey, &erroff,
400                                 (char*)arg.unprotected_key, canlen);
401           if (rc)
402             {
403               log_error ("failed to build S-Exp (off=%u): %s\n",
404                          (unsigned int)erroff, gpg_strerror (rc));
405               wipememory (arg.unprotected_key, canlen);
406               xfree (arg.unprotected_key);
407               xfree (pi);
408               return rc;
409             }
410           rc = agent_protect_and_store (ctrl, s_skey);
411           gcry_sexp_release (s_skey);
412           if (rc)
413             {
414               log_error ("changing the passphrase failed: %s\n", 
415                          gpg_strerror (rc));
416               wipememory (arg.unprotected_key, canlen);
417               xfree (arg.unprotected_key);
418               xfree (pi);
419               return rc;
420             }
421         }
422       else
423         {
424           agent_put_cache (hexgrip, cache_mode, pi->pin, 
425                            lookup_ttl? lookup_ttl (hexgrip) : 0);
426           if (r_passphrase && *pi->pin)
427             *r_passphrase = xtrystrdup (pi->pin);
428         }
429       xfree (*keybuf);
430       *keybuf = arg.unprotected_key;
431     }
432   xfree (pi);
433   return rc;
434 }
435
436
437 /* Read the key identified by GRIP from the private key directory and
438    return it as an gcrypt S-expression object in RESULT.  On failure
439    returns an error code and stores NULL at RESULT. */
440 static gpg_error_t
441 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
442 {
443   int rc;
444   char *fname;
445   estream_t fp;
446   struct stat st;
447   unsigned char *buf;
448   size_t buflen, erroff;
449   gcry_sexp_t s_skey;
450   char hexgrip[40+4+1];
451   
452   *result = NULL;
453
454   bin2hex (grip, 20, hexgrip);
455   strcpy (hexgrip+40, ".key");
456
457   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
458   fp = es_fopen (fname, "rb");
459   if (!fp)
460     {
461       rc = gpg_error_from_syserror ();
462       if (gpg_err_code (rc) != GPG_ERR_ENOENT)
463         log_error ("can't open `%s': %s\n", fname, strerror (errno));
464       xfree (fname);
465       return rc;
466     }
467   
468   if (fstat (es_fileno (fp), &st))
469     {
470       rc = gpg_error_from_syserror ();
471       log_error ("can't stat `%s': %s\n", fname, strerror (errno));
472       xfree (fname);
473       es_fclose (fp);
474       return rc;
475     }
476
477   buflen = st.st_size;
478   buf = xtrymalloc (buflen+1);
479   if (!buf)
480     {
481       rc = gpg_error_from_syserror ();
482       log_error ("error allocating %zu bytes for `%s': %s\n",
483                  buflen, fname, strerror (errno));
484       xfree (fname);
485       es_fclose (fp);
486       xfree (buf);
487       return rc;
488
489     }
490
491   if (es_fread (buf, buflen, 1, fp) != 1)
492     {
493       rc = gpg_error_from_syserror ();
494       log_error ("error reading %zu bytes from `%s': %s\n", 
495                  buflen, fname, strerror (errno));
496       xfree (fname);
497       es_fclose (fp);
498       xfree (buf);
499       return rc;
500     }
501
502   /* Convert the file into a gcrypt S-expression object.  */
503   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
504   xfree (fname);
505   es_fclose (fp);
506   xfree (buf);
507   if (rc)
508     {
509       log_error ("failed to build S-Exp (off=%u): %s\n",
510                  (unsigned int)erroff, gpg_strerror (rc));
511       return rc;
512     }
513   *result = s_skey;
514   return 0;
515 }
516
517
518 /* Return the secret key as an S-Exp in RESULT after locating it using
519    the GRIP.  Stores NULL at RESULT if the operation shall be diverted
520    to a token; in this case an allocated S-expression with the
521    shadow_info part from the file is stored at SHADOW_INFO.
522    CACHE_MODE defines now the cache shall be used.  DESC_TEXT may be
523    set to present a custom description for the pinentry.  LOOKUP_TTL
524    is an optional function to convey a TTL to the cache manager; we do
525    not simply pass the TTL value because the value is only needed if
526    an unprotect action was needed and looking up the TTL may have some
527    overhead (e.g. scanning the sshcontrol file).  If a CACHE_NONCE is
528    given that cache item is first tried to get a passphrase.  If
529    R_PASSPHRASE is not NULL, the function succeeded and the key was
530    protected the used passphrase (entered or from the cache) is stored
531    there; if not NULL will be stored.  The caller needs to free the
532    returned passphrase.   */
533 gpg_error_t
534 agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
535                      const char *desc_text,
536                      const unsigned char *grip, unsigned char **shadow_info,
537                      cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
538                      gcry_sexp_t *result, char **r_passphrase)
539 {
540   int rc;
541   unsigned char *buf;
542   size_t len, buflen, erroff;
543   gcry_sexp_t s_skey;
544   int got_shadow_info = 0;
545   
546   *result = NULL;
547   if (shadow_info)
548     *shadow_info = NULL;
549   if (r_passphrase)
550     *r_passphrase = NULL;
551
552   rc = read_key_file (grip, &s_skey);
553   if (rc)
554     return rc;
555
556   /* For use with the protection functions we also need the key as an
557      canonical encoded S-expression in a buffer.  Create this buffer
558      now.  */
559   rc = make_canon_sexp (s_skey, &buf, &len);
560   if (rc)
561     return rc;
562
563   switch (agent_private_key_type (buf))
564     {
565     case PRIVATE_KEY_CLEAR:
566       break; /* no unprotection needed */
567     case PRIVATE_KEY_PROTECTED:
568       {
569         gcry_sexp_t comment_sexp;
570         size_t comment_length;
571         char *desc_text_final;
572         const char *comment = NULL;
573
574         /* Note, that we will take the comment as a C string for
575            display purposes; i.e. all stuff beyond a Nul character is
576            ignored.  */
577         comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
578         if (comment_sexp)
579           comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
580         if (!comment)
581           {
582             comment = "";
583             comment_length = 0;
584           }
585
586         desc_text_final = NULL;
587         if (desc_text)
588           {
589             if (comment[comment_length])
590               {
591                 /* Not a C-string; create one.  We might here allocate
592                    more than actually displayed but well, that
593                    shouldn't be a problem.  */
594                 char *tmp = xtrymalloc (comment_length+1);
595                 if (!tmp)
596                   rc = gpg_error_from_syserror ();
597                 else
598                   {
599                     memcpy (tmp, comment, comment_length);
600                     tmp[comment_length] = 0;
601                     rc = modify_description (desc_text, tmp, &desc_text_final);
602                     xfree (tmp);
603                   }
604               }
605             else
606               rc = modify_description (desc_text, comment, &desc_text_final);
607           }
608
609         if (!rc)
610           {
611             rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
612                             cache_mode, lookup_ttl, r_passphrase);
613             if (rc)
614               log_error ("failed to unprotect the secret key: %s\n",
615                          gpg_strerror (rc));
616           }
617         
618         gcry_sexp_release (comment_sexp);
619         xfree (desc_text_final);
620       }
621       break;
622     case PRIVATE_KEY_SHADOWED:
623       if (shadow_info)
624         {
625           const unsigned char *s;
626           size_t n;
627
628           rc = agent_get_shadow_info (buf, &s);
629           if (!rc)
630             {
631               n = gcry_sexp_canon_len (s, 0, NULL,NULL);
632               assert (n);
633               *shadow_info = xtrymalloc (n);
634               if (!*shadow_info)
635                 rc = out_of_core ();
636               else
637                 {
638                   memcpy (*shadow_info, s, n);
639                   rc = 0;
640                   got_shadow_info = 1;
641                 }
642             }
643           if (rc)
644             log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
645         }
646       else
647         rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
648       break;
649     default:
650       log_error ("invalid private key format\n");
651       rc = gpg_error (GPG_ERR_BAD_SECKEY);
652       break;
653     }
654   gcry_sexp_release (s_skey);
655   s_skey = NULL;
656   if (rc || got_shadow_info)
657     {
658       xfree (buf);
659       if (r_passphrase)
660         {
661           xfree (*r_passphrase);
662           *r_passphrase = NULL;
663         }
664       return rc;
665     }
666
667   buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
668   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
669   wipememory (buf, buflen);
670   xfree (buf);
671   if (rc)
672     {
673       log_error ("failed to build S-Exp (off=%u): %s\n",
674                  (unsigned int)erroff, gpg_strerror (rc));
675       if (r_passphrase)
676         {
677           xfree (*r_passphrase);
678           *r_passphrase = NULL;
679         }
680       return rc;
681     }
682
683   *result = s_skey;
684   return 0;
685 }
686
687
688 /* Return the string name from the S-expression S_KEY as well as a
689    string describing the names of the parameters.  ALGONAMESIZE and
690    ELEMSSIZE give the allocated size of the provided buffers.  The
691    buffers may be NULL if not required.  If R_LIST is not NULL the top
692    level list will be stored tehre; the caller needs to release it in
693    this case.  */
694 static gpg_error_t
695 key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
696                      char *r_algoname, size_t algonamesize,
697                      char *r_elems, size_t elemssize)
698 {
699   gcry_sexp_t list, l2;
700   const char *name, *algoname, *elems;
701   size_t n;
702
703   if (r_list)
704     *r_list = NULL;
705
706   list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
707   if (!list)
708     list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
709   if (!list)
710     list = gcry_sexp_find_token (s_key, "private-key", 0 );
711   if (!list)
712     {
713       log_error ("invalid private key format\n");
714       return gpg_error (GPG_ERR_BAD_SECKEY);
715     }
716
717   l2 = gcry_sexp_cadr (list);
718   gcry_sexp_release (list);
719   list = l2;
720   name = gcry_sexp_nth_data (list, 0, &n);
721   if (n==3 && !memcmp (name, "rsa", 3))
722     {
723       algoname = "rsa";
724       elems = "ne";
725     }
726   else if (n==3 && !memcmp (name, "dsa", 3))
727     {
728       algoname = "dsa";
729       elems = "pqgy";
730     }
731   else if (n==3 && !memcmp (name, "elg", 3))
732     {
733       algoname = "elg";
734       elems = "pgy";
735     }
736   else
737     {
738       log_error ("unknown private key algorithm\n");
739       gcry_sexp_release (list);
740       return gpg_error (GPG_ERR_BAD_SECKEY);
741     }
742
743   if (r_algoname)
744     {
745       if (strlen (algoname) >= algonamesize)
746         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
747       strcpy (r_algoname, algoname);
748     } 
749   if (r_elems)
750     {
751       if (strlen (elems) >= elemssize)
752         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
753       strcpy (r_elems, elems);
754     }
755
756   if (r_list)
757     *r_list = list;
758   else
759     gcry_sexp_release (list);
760       
761   return 0;
762 }
763
764
765 /* Return the public key algorithm number if S_KEY is a DSA style key.
766    If it is not a DSA style key, return 0.  */
767 int 
768 agent_is_dsa_key (gcry_sexp_t s_key)
769 {
770   char algoname[6];
771
772   if (!s_key)
773     return 0;
774
775   if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
776     return 0; /* Error - assume it is not an DSA key.  */
777
778   if (!strcmp (algoname, "dsa"))
779     return GCRY_PK_DSA;
780   else if (!strcmp (algoname, "ecdsa"))
781     return GCRY_PK_ECDSA;
782   else
783     return 0;
784 }
785
786
787
788 /* Return the public key for the keygrip GRIP.  The result is stored
789    at RESULT.  This function extracts the public key from the private
790    key database.  On failure an error code is returned and NULL stored
791    at RESULT. */
792 gpg_error_t
793 agent_public_key_from_file (ctrl_t ctrl, 
794                             const unsigned char *grip,
795                             gcry_sexp_t *result)
796 {
797   gpg_error_t err;
798   int i, idx;
799   gcry_sexp_t s_skey;
800   char algoname[6];
801   char elems[6];
802   gcry_sexp_t uri_sexp, comment_sexp;
803   const char *uri, *comment;
804   size_t uri_length, comment_length;
805   char *format, *p;
806   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
807                            for comment + end-of-list.  */
808   int argidx;
809   gcry_sexp_t list, l2;
810   const char *s;
811   gcry_mpi_t *array;
812
813   (void)ctrl;
814
815   *result = NULL;
816
817   err = read_key_file (grip, &s_skey);
818   if (err)
819     return err;
820
821   err = key_parms_from_sexp (s_skey, &list, 
822                             algoname, sizeof algoname,
823                             elems, sizeof elems);
824   if (err)
825     {
826       gcry_sexp_release (s_skey);
827       return err;
828     }
829
830   /* Allocate an array for the parameters and copy them out of the
831      secret key.   FIXME: We should have a generic copy function. */
832   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
833   if (!array)
834     {
835       err = gpg_error_from_syserror ();
836       gcry_sexp_release (list);
837       gcry_sexp_release (s_skey);
838       return err;
839     }
840
841   for (idx=0, s=elems; *s; s++, idx++ ) 
842     {
843       l2 = gcry_sexp_find_token (list, s, 1);
844       if (!l2)
845         {
846           /* Required parameter not found.  */
847           for (i=0; i<idx; i++)
848             gcry_mpi_release (array[i]);
849           xfree (array);
850           gcry_sexp_release (list);
851           gcry_sexp_release (s_skey);
852           return gpg_error (GPG_ERR_BAD_SECKEY);
853         }
854       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
855       gcry_sexp_release (l2);
856       if (!array[idx])
857         {
858           /* Required parameter is invalid. */
859           for (i=0; i<idx; i++)
860             gcry_mpi_release (array[i]);
861           xfree (array);
862           gcry_sexp_release (list);
863           gcry_sexp_release (s_skey);
864           return gpg_error (GPG_ERR_BAD_SECKEY);
865         }
866     }
867   gcry_sexp_release (list);
868   list = NULL;
869
870   uri = NULL;
871   uri_length = 0;
872   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
873   if (uri_sexp)
874     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
875
876   comment = NULL;
877   comment_length = 0;
878   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
879   if (comment_sexp)
880     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
881
882   gcry_sexp_release (s_skey);
883   s_skey = NULL;
884
885
886   /* FIXME: The following thing is pretty ugly code; we should
887      investigate how to make it cleaner.  Probably code to handle
888      canonical S-expressions in a memory buffer is better suited for
889      such a task.  After all that is what we do in protect.c.  Neeed
890      to find common patterns and write a straightformward API to use
891      them.  */
892   assert (sizeof (size_t) <= sizeof (void*));
893
894   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
895   if (!format)
896     {
897       err = gpg_error_from_syserror ();
898       for (i=0; array[i]; i++)
899         gcry_mpi_release (array[i]);
900       xfree (array);
901       gcry_sexp_release (uri_sexp);
902       gcry_sexp_release (comment_sexp);
903       return err;
904     }
905
906   argidx = 0;
907   p = stpcpy (stpcpy (format, "(public-key("), algoname);
908   for (idx=0, s=elems; *s; s++, idx++ ) 
909     {
910       *p++ = '(';
911       *p++ = *s;
912       p = stpcpy (p, " %m)");
913       assert (argidx < DIM (args));
914       args[argidx++] = &array[idx];
915     }
916   *p++ = ')';
917   if (uri)
918     {
919       p = stpcpy (p, "(uri %b)");
920       assert (argidx+1 < DIM (args));
921       args[argidx++] = (void *)uri_length;
922       args[argidx++] = (void *)uri;
923     }
924   if (comment)
925     {
926       p = stpcpy (p, "(comment %b)");
927       assert (argidx+1 < DIM (args));
928       args[argidx++] = (void *)comment_length;
929       args[argidx++] = (void*)comment;
930     }
931   *p++ = ')';
932   *p = 0;
933   assert (argidx < DIM (args));
934   args[argidx] = NULL;
935     
936   err = gcry_sexp_build_array (&list, NULL, format, args);
937   xfree (format);
938   for (i=0; array[i]; i++)
939     gcry_mpi_release (array[i]);
940   xfree (array);
941   gcry_sexp_release (uri_sexp);
942   gcry_sexp_release (comment_sexp);
943
944   if (!err)
945     *result = list;
946   return err;
947 }
948
949
950
951 /* Check whether the the secret key identified by GRIP is available.
952    Returns 0 is the key is available.  */
953 int
954 agent_key_available (const unsigned char *grip)
955 {
956   int result;
957   char *fname;
958   char hexgrip[40+4+1];
959   
960   bin2hex (grip, 20, hexgrip);
961   strcpy (hexgrip+40, ".key");
962
963   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
964   result = !access (fname, R_OK)? 0 : -1;
965   xfree (fname);
966   return result;
967 }
968
969
970
971 /* Return the information about the secret key specified by the binary
972    keygrip GRIP.  If the key is a shadowed one the shadow information
973    will be stored at the address R_SHADOW_INFO as an allocated
974    S-expression.  */
975 gpg_error_t
976 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
977                           int *r_keytype, unsigned char **r_shadow_info)
978 {
979   gpg_error_t err;
980   unsigned char *buf;
981   size_t len;
982   int keytype;
983
984   (void)ctrl;
985   
986   if (r_keytype)
987     *r_keytype = PRIVATE_KEY_UNKNOWN;
988   if (r_shadow_info)
989     *r_shadow_info = NULL;
990
991   {
992     gcry_sexp_t sexp;
993     
994     err = read_key_file (grip, &sexp);
995     if (err)
996       {
997         if (gpg_err_code (err) == GPG_ERR_ENOENT)
998           return gpg_error (GPG_ERR_NOT_FOUND);
999         else
1000           return err;
1001       }
1002     err = make_canon_sexp (sexp, &buf, &len);
1003     gcry_sexp_release (sexp);
1004     if (err)
1005       return err;
1006   }
1007   
1008   keytype = agent_private_key_type (buf);
1009   switch (keytype)
1010     {
1011     case PRIVATE_KEY_CLEAR:
1012       break; 
1013     case PRIVATE_KEY_PROTECTED:
1014       /* If we ever require it we could retrieve the comment fields
1015          from such a key. */
1016       break;
1017     case PRIVATE_KEY_SHADOWED:
1018       if (r_shadow_info)
1019         {
1020           const unsigned char *s;
1021           size_t n;
1022
1023           err = agent_get_shadow_info (buf, &s);
1024           if (!err)
1025             {
1026               n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1027               assert (n);
1028               *r_shadow_info = xtrymalloc (n);
1029               if (!*r_shadow_info)
1030                 err = gpg_error_from_syserror ();
1031               else
1032                 memcpy (*r_shadow_info, s, n);
1033             }
1034         }
1035       break;
1036     default:
1037       err = gpg_error (GPG_ERR_BAD_SECKEY);
1038       break;
1039     }
1040
1041   if (!err && r_keytype)
1042     *r_keytype = keytype;
1043
1044   xfree (buf);
1045   return err;
1046 }