agent: Cleanups to prepare implementation of Ed25519.
[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 there; 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 true if KEYPARMS holds an EdDSA key.  */
780 static int
781 is_eddsa (gcry_sexp_t keyparms)
782 {
783   int result = 0;
784   gcry_sexp_t list;
785   const char *s;
786   size_t n;
787   int i;
788
789   list = gcry_sexp_find_token (keyparms, "flags", 0);
790   for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
791     {
792       s = gcry_sexp_nth_data (list, i, &n);
793       if (!s)
794         continue; /* Not a data element. */
795
796       if (n == 5 && !memcmp (s, "eddsa", 5))
797         {
798           result = 1;
799           break;
800         }
801     }
802   gcry_sexp_release (list);
803   return result;
804 }
805
806
807 /* Return the public key algorithm number if S_KEY is a DSA style key.
808    If it is not a DSA style key, return 0.  */
809 int
810 agent_is_dsa_key (gcry_sexp_t s_key)
811 {
812   int result;
813   gcry_sexp_t list;
814   char algoname[6];
815
816   if (!s_key)
817     return 0;
818
819   if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
820     return 0; /* Error - assume it is not an DSA key.  */
821
822   if (!strcmp (algoname, "dsa"))
823     result = GCRY_PK_DSA;
824   else if (!strcmp (algoname, "ecc"))
825     {
826       if (is_eddsa (list))
827         result = 0;
828       else
829         result = GCRY_PK_ECDSA;
830     }
831   else if (!strcmp (algoname, "ecdsa"))
832     result = GCRY_PK_ECDSA;
833   else
834     result = 0;
835
836   gcry_sexp_release (list);
837   return result;
838 }
839
840
841 /* Return true if S_KEY is an EdDSA key as used with curve Ed25519.  */
842 int
843 agent_is_eddsa_key (gcry_sexp_t s_key)
844 {
845   int result;
846   gcry_sexp_t list;
847   char algoname[6];
848
849   if (!s_key)
850     return 0;
851
852   if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
853     return 0; /* Error - assume it is not an EdDSA key.  */
854
855   if (!strcmp (algoname, "ecc") && is_eddsa (list))
856     result = 1;
857   else if (!strcmp (algoname, "eddsa")) /* backward compatibility.  */
858     result = 1;
859   else
860     result = 0;
861
862   gcry_sexp_release (list);
863   return result;
864 }
865
866
867 /* Return the key for the keygrip GRIP.  The result is stored at
868    RESULT.  This function extracts the key from the private key
869    database and returns it as an S-expression object as it is.  On
870    failure an error code is returned and NULL stored at RESULT. */
871 gpg_error_t
872 agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
873                          gcry_sexp_t *result)
874 {
875   gpg_error_t err;
876   gcry_sexp_t s_skey;
877
878   (void)ctrl;
879
880   *result = NULL;
881
882   err = read_key_file (grip, &s_skey);
883   if (!err)
884     *result = s_skey;
885   return err;
886 }
887
888
889 /* Return the public key for the keygrip GRIP.  The result is stored
890    at RESULT.  This function extracts the public key from the private
891    key database.  On failure an error code is returned and NULL stored
892    at RESULT. */
893 gpg_error_t
894 agent_public_key_from_file (ctrl_t ctrl,
895                             const unsigned char *grip,
896                             gcry_sexp_t *result)
897 {
898   gpg_error_t err;
899   int i, idx;
900   gcry_sexp_t s_skey;
901   char algoname[6];
902   char elems[7];
903   gcry_sexp_t uri_sexp, comment_sexp;
904   const char *uri, *comment;
905   size_t uri_length, comment_length;
906   char *format, *p;
907   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
908                            for comment + end-of-list.  */
909   int argidx;
910   gcry_sexp_t list, l2;
911   const char *s;
912   gcry_mpi_t *array;
913
914   (void)ctrl;
915
916   *result = NULL;
917
918   err = read_key_file (grip, &s_skey);
919   if (err)
920     return err;
921
922   err = key_parms_from_sexp (s_skey, &list,
923                             algoname, sizeof algoname,
924                             elems, sizeof elems);
925   if (err)
926     {
927       gcry_sexp_release (s_skey);
928       return err;
929     }
930
931   /* Allocate an array for the parameters and copy them out of the
932      secret key.   FIXME: We should have a generic copy function. */
933   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
934   if (!array)
935     {
936       err = gpg_error_from_syserror ();
937       gcry_sexp_release (list);
938       gcry_sexp_release (s_skey);
939       return err;
940     }
941
942   for (idx=0, s=elems; *s; s++, idx++ )
943     {
944       l2 = gcry_sexp_find_token (list, s, 1);
945       if (!l2)
946         {
947           /* Required parameter not found.  */
948           for (i=0; i<idx; i++)
949             gcry_mpi_release (array[i]);
950           xfree (array);
951           gcry_sexp_release (list);
952           gcry_sexp_release (s_skey);
953           return gpg_error (GPG_ERR_BAD_SECKEY);
954         }
955       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
956       gcry_sexp_release (l2);
957       if (!array[idx])
958         {
959           /* Required parameter is invalid. */
960           for (i=0; i<idx; i++)
961             gcry_mpi_release (array[i]);
962           xfree (array);
963           gcry_sexp_release (list);
964           gcry_sexp_release (s_skey);
965           return gpg_error (GPG_ERR_BAD_SECKEY);
966         }
967     }
968   gcry_sexp_release (list);
969   list = NULL;
970
971   uri = NULL;
972   uri_length = 0;
973   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
974   if (uri_sexp)
975     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
976
977   comment = NULL;
978   comment_length = 0;
979   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
980   if (comment_sexp)
981     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
982
983   gcry_sexp_release (s_skey);
984   s_skey = NULL;
985
986
987   /* FIXME: The following thing is pretty ugly code; we should
988      investigate how to make it cleaner.  Probably code to handle
989      canonical S-expressions in a memory buffer is better suited for
990      such a task.  After all that is what we do in protect.c.  Neeed
991      to find common patterns and write a straightformward API to use
992      them.  */
993   assert (sizeof (size_t) <= sizeof (void*));
994
995   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
996   if (!format)
997     {
998       err = gpg_error_from_syserror ();
999       for (i=0; array[i]; i++)
1000         gcry_mpi_release (array[i]);
1001       xfree (array);
1002       gcry_sexp_release (uri_sexp);
1003       gcry_sexp_release (comment_sexp);
1004       return err;
1005     }
1006
1007   argidx = 0;
1008   p = stpcpy (stpcpy (format, "(public-key("), algoname);
1009   for (idx=0, s=elems; *s; s++, idx++ )
1010     {
1011       *p++ = '(';
1012       *p++ = *s;
1013       p = stpcpy (p, " %m)");
1014       assert (argidx < DIM (args));
1015       args[argidx++] = &array[idx];
1016     }
1017   *p++ = ')';
1018   if (uri)
1019     {
1020       p = stpcpy (p, "(uri %b)");
1021       assert (argidx+1 < DIM (args));
1022       args[argidx++] = (void *)&uri_length;
1023       args[argidx++] = (void *)&uri;
1024     }
1025   if (comment)
1026     {
1027       p = stpcpy (p, "(comment %b)");
1028       assert (argidx+1 < DIM (args));
1029       args[argidx++] = (void *)&comment_length;
1030       args[argidx++] = (void*)&comment;
1031     }
1032   *p++ = ')';
1033   *p = 0;
1034   assert (argidx < DIM (args));
1035   args[argidx] = NULL;
1036
1037   err = gcry_sexp_build_array (&list, NULL, format, args);
1038   xfree (format);
1039   for (i=0; array[i]; i++)
1040     gcry_mpi_release (array[i]);
1041   xfree (array);
1042   gcry_sexp_release (uri_sexp);
1043   gcry_sexp_release (comment_sexp);
1044
1045   if (!err)
1046     *result = list;
1047   return err;
1048 }
1049
1050
1051
1052 /* Check whether the the secret key identified by GRIP is available.
1053    Returns 0 is the key is available.  */
1054 int
1055 agent_key_available (const unsigned char *grip)
1056 {
1057   int result;
1058   char *fname;
1059   char hexgrip[40+4+1];
1060
1061   bin2hex (grip, 20, hexgrip);
1062   strcpy (hexgrip+40, ".key");
1063
1064   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
1065   result = !access (fname, R_OK)? 0 : -1;
1066   xfree (fname);
1067   return result;
1068 }
1069
1070
1071
1072 /* Return the information about the secret key specified by the binary
1073    keygrip GRIP.  If the key is a shadowed one the shadow information
1074    will be stored at the address R_SHADOW_INFO as an allocated
1075    S-expression.  */
1076 gpg_error_t
1077 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
1078                           int *r_keytype, unsigned char **r_shadow_info)
1079 {
1080   gpg_error_t err;
1081   unsigned char *buf;
1082   size_t len;
1083   int keytype;
1084
1085   (void)ctrl;
1086
1087   if (r_keytype)
1088     *r_keytype = PRIVATE_KEY_UNKNOWN;
1089   if (r_shadow_info)
1090     *r_shadow_info = NULL;
1091
1092   {
1093     gcry_sexp_t sexp;
1094
1095     err = read_key_file (grip, &sexp);
1096     if (err)
1097       {
1098         if (gpg_err_code (err) == GPG_ERR_ENOENT)
1099           return gpg_error (GPG_ERR_NOT_FOUND);
1100         else
1101           return err;
1102       }
1103     err = make_canon_sexp (sexp, &buf, &len);
1104     gcry_sexp_release (sexp);
1105     if (err)
1106       return err;
1107   }
1108
1109   keytype = agent_private_key_type (buf);
1110   switch (keytype)
1111     {
1112     case PRIVATE_KEY_CLEAR:
1113       break;
1114     case PRIVATE_KEY_PROTECTED:
1115       /* If we ever require it we could retrieve the comment fields
1116          from such a key. */
1117       break;
1118     case PRIVATE_KEY_SHADOWED:
1119       if (r_shadow_info)
1120         {
1121           const unsigned char *s;
1122           size_t n;
1123
1124           err = agent_get_shadow_info (buf, &s);
1125           if (!err)
1126             {
1127               n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1128               assert (n);
1129               *r_shadow_info = xtrymalloc (n);
1130               if (!*r_shadow_info)
1131                 err = gpg_error_from_syserror ();
1132               else
1133                 memcpy (*r_shadow_info, s, n);
1134             }
1135         }
1136       break;
1137     default:
1138       err = gpg_error (GPG_ERR_BAD_SECKEY);
1139       break;
1140     }
1141
1142   if (!err && r_keytype)
1143     *r_keytype = keytype;
1144
1145   xfree (buf);
1146   return err;
1147 }