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