agent: Fix agent_is_eddsa_key.
[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.  Stores NULL at RESULT if the operation shall be diverted
541    to a token; in this case an allocated S-expression with the
542    shadow_info part from the file is 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   int got_shadow_info = 0;
566
567   *result = NULL;
568   if (shadow_info)
569     *shadow_info = NULL;
570   if (r_passphrase)
571     *r_passphrase = NULL;
572
573   rc = read_key_file (grip, &s_skey);
574   if (rc)
575     return rc;
576
577   /* For use with the protection functions we also need the key as an
578      canonical encoded S-expression in a buffer.  Create this buffer
579      now.  */
580   rc = make_canon_sexp (s_skey, &buf, &len);
581   if (rc)
582     return rc;
583
584   switch (agent_private_key_type (buf))
585     {
586     case PRIVATE_KEY_CLEAR:
587       break; /* no unprotection needed */
588     case PRIVATE_KEY_PROTECTED:
589       {
590         char *desc_text_final;
591         char *comment = NULL;
592
593         /* Note, that we will take the comment as a C string for
594            display purposes; i.e. all stuff beyond a Nul character is
595            ignored.  */
596         {
597           gcry_sexp_t comment_sexp;
598
599           comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
600           if (comment_sexp)
601             comment = gcry_sexp_nth_string (comment_sexp, 1);
602           gcry_sexp_release (comment_sexp);
603         }
604
605         desc_text_final = NULL;
606         if (desc_text)
607           rc = modify_description (desc_text, comment? comment:"", s_skey,
608                                    &desc_text_final);
609         gcry_free (comment);
610
611         if (!rc)
612           {
613             rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
614                             cache_mode, lookup_ttl, r_passphrase);
615             if (rc)
616               log_error ("failed to unprotect the secret key: %s\n",
617                          gpg_strerror (rc));
618           }
619
620         xfree (desc_text_final);
621       }
622       break;
623     case PRIVATE_KEY_SHADOWED:
624       if (shadow_info)
625         {
626           const unsigned char *s;
627           size_t n;
628
629           rc = agent_get_shadow_info (buf, &s);
630           if (!rc)
631             {
632               n = gcry_sexp_canon_len (s, 0, NULL,NULL);
633               assert (n);
634               *shadow_info = xtrymalloc (n);
635               if (!*shadow_info)
636                 rc = out_of_core ();
637               else
638                 {
639                   memcpy (*shadow_info, s, n);
640                   rc = 0;
641                   got_shadow_info = 1;
642                 }
643             }
644           if (rc)
645             log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
646         }
647       else
648         rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
649       break;
650     default:
651       log_error ("invalid private key format\n");
652       rc = gpg_error (GPG_ERR_BAD_SECKEY);
653       break;
654     }
655   gcry_sexp_release (s_skey);
656   s_skey = NULL;
657   if (rc || got_shadow_info)
658     {
659       xfree (buf);
660       if (r_passphrase)
661         {
662           xfree (*r_passphrase);
663           *r_passphrase = NULL;
664         }
665       return rc;
666     }
667
668   buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
669   rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
670   wipememory (buf, buflen);
671   xfree (buf);
672   if (rc)
673     {
674       log_error ("failed to build S-Exp (off=%u): %s\n",
675                  (unsigned int)erroff, gpg_strerror (rc));
676       if (r_passphrase)
677         {
678           xfree (*r_passphrase);
679           *r_passphrase = NULL;
680         }
681       return rc;
682     }
683
684   *result = s_skey;
685   return 0;
686 }
687
688
689 /* Return the string name from the S-expression S_KEY as well as a
690    string describing the names of the parameters.  ALGONAMESIZE and
691    ELEMSSIZE give the allocated size of the provided buffers.  The
692    buffers may be NULL if not required.  If R_LIST is not NULL the top
693    level list will be stored tehre; the caller needs to release it in
694    this case.  */
695 static gpg_error_t
696 key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
697                      char *r_algoname, size_t algonamesize,
698                      char *r_elems, size_t elemssize)
699 {
700   gcry_sexp_t list, l2;
701   const char *name, *algoname, *elems;
702   size_t n;
703
704   if (r_list)
705     *r_list = NULL;
706
707   list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
708   if (!list)
709     list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
710   if (!list)
711     list = gcry_sexp_find_token (s_key, "private-key", 0 );
712   if (!list)
713     {
714       log_error ("invalid private key format\n");
715       return gpg_error (GPG_ERR_BAD_SECKEY);
716     }
717
718   l2 = gcry_sexp_cadr (list);
719   gcry_sexp_release (list);
720   list = l2;
721   name = gcry_sexp_nth_data (list, 0, &n);
722   if (n==3 && !memcmp (name, "rsa", 3))
723     {
724       algoname = "rsa";
725       elems = "ne";
726     }
727   else if (n==3 && !memcmp (name, "dsa", 3))
728     {
729       algoname = "dsa";
730       elems = "pqgy";
731     }
732   else if (n==3 && !memcmp (name, "ecc", 3))
733     {
734       algoname = "ecc";
735       elems = "pabgnq";
736     }
737   else if (n==5 && !memcmp (name, "ecdsa", 5))
738     {
739       algoname = "ecdsa";
740       elems = "pabgnq";
741     }
742   else if (n==4 && !memcmp (name, "ecdh", 4))
743     {
744       algoname = "ecdh";
745       elems = "pabgnq";
746     }
747   else if (n==3 && !memcmp (name, "elg", 3))
748     {
749       algoname = "elg";
750       elems = "pgy";
751     }
752   else
753     {
754       log_error ("unknown private key algorithm\n");
755       gcry_sexp_release (list);
756       return gpg_error (GPG_ERR_BAD_SECKEY);
757     }
758
759   if (r_algoname)
760     {
761       if (strlen (algoname) >= algonamesize)
762         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
763       strcpy (r_algoname, algoname);
764     }
765   if (r_elems)
766     {
767       if (strlen (elems) >= elemssize)
768         return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
769       strcpy (r_elems, elems);
770     }
771
772   if (r_list)
773     *r_list = list;
774   else
775     gcry_sexp_release (list);
776
777   return 0;
778 }
779
780
781 /* Return the public key algorithm number if S_KEY is a DSA style key.
782    If it is not a DSA style key, return 0.  */
783 int
784 agent_is_dsa_key (gcry_sexp_t s_key)
785 {
786   char algoname[6];
787
788   if (!s_key)
789     return 0;
790
791   if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
792     return 0; /* Error - assume it is not an DSA key.  */
793
794   if (!strcmp (algoname, "dsa"))
795     return GCRY_PK_DSA;
796   else if (!strcmp (algoname, "ecc"))
797     return GCRY_PK_ECDSA; /* FIXME: Check for the EdDSA flag.  */
798   else if (!strcmp (algoname, "ecdsa"))
799     return GCRY_PK_ECDSA;
800   else
801     return 0;
802 }
803
804
805 /* Return true if S_KEY is an EdDSA key as used with curve Ed25519.  */
806 int
807 agent_is_eddsa_key (gcry_sexp_t s_key)
808 {
809   char algoname[6];
810
811   if (!s_key)
812     return 0;
813
814   if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
815     return 0; /* Error - assume it is not an EdDSA key.  */
816
817   if (!strcmp (algoname, "eddsa"))
818     return 1;
819   else
820     return 0;
821 }
822
823
824 /* Return the key for the keygrip GRIP.  The result is stored at
825    RESULT.  This function extracts the key from the private key
826    database and returns it as an S-expression object as it is.  On
827    failure an error code is returned and NULL stored at RESULT. */
828 gpg_error_t
829 agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
830                          gcry_sexp_t *result)
831 {
832   gpg_error_t err;
833   gcry_sexp_t s_skey;
834
835   (void)ctrl;
836
837   *result = NULL;
838
839   err = read_key_file (grip, &s_skey);
840   if (!err)
841     *result = s_skey;
842   return err;
843 }
844
845
846 /* Return the public key for the keygrip GRIP.  The result is stored
847    at RESULT.  This function extracts the public key from the private
848    key database.  On failure an error code is returned and NULL stored
849    at RESULT. */
850 gpg_error_t
851 agent_public_key_from_file (ctrl_t ctrl,
852                             const unsigned char *grip,
853                             gcry_sexp_t *result)
854 {
855   gpg_error_t err;
856   int i, idx;
857   gcry_sexp_t s_skey;
858   char algoname[6];
859   char elems[7];
860   gcry_sexp_t uri_sexp, comment_sexp;
861   const char *uri, *comment;
862   size_t uri_length, comment_length;
863   char *format, *p;
864   void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
865                            for comment + end-of-list.  */
866   int argidx;
867   gcry_sexp_t list, l2;
868   const char *s;
869   gcry_mpi_t *array;
870
871   (void)ctrl;
872
873   *result = NULL;
874
875   err = read_key_file (grip, &s_skey);
876   if (err)
877     return err;
878
879   err = key_parms_from_sexp (s_skey, &list,
880                             algoname, sizeof algoname,
881                             elems, sizeof elems);
882   if (err)
883     {
884       gcry_sexp_release (s_skey);
885       return err;
886     }
887
888   /* Allocate an array for the parameters and copy them out of the
889      secret key.   FIXME: We should have a generic copy function. */
890   array = xtrycalloc (strlen(elems) + 1, sizeof *array);
891   if (!array)
892     {
893       err = gpg_error_from_syserror ();
894       gcry_sexp_release (list);
895       gcry_sexp_release (s_skey);
896       return err;
897     }
898
899   for (idx=0, s=elems; *s; s++, idx++ )
900     {
901       l2 = gcry_sexp_find_token (list, s, 1);
902       if (!l2)
903         {
904           /* Required parameter not found.  */
905           for (i=0; i<idx; i++)
906             gcry_mpi_release (array[i]);
907           xfree (array);
908           gcry_sexp_release (list);
909           gcry_sexp_release (s_skey);
910           return gpg_error (GPG_ERR_BAD_SECKEY);
911         }
912       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
913       gcry_sexp_release (l2);
914       if (!array[idx])
915         {
916           /* Required parameter is invalid. */
917           for (i=0; i<idx; i++)
918             gcry_mpi_release (array[i]);
919           xfree (array);
920           gcry_sexp_release (list);
921           gcry_sexp_release (s_skey);
922           return gpg_error (GPG_ERR_BAD_SECKEY);
923         }
924     }
925   gcry_sexp_release (list);
926   list = NULL;
927
928   uri = NULL;
929   uri_length = 0;
930   uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
931   if (uri_sexp)
932     uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
933
934   comment = NULL;
935   comment_length = 0;
936   comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
937   if (comment_sexp)
938     comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
939
940   gcry_sexp_release (s_skey);
941   s_skey = NULL;
942
943
944   /* FIXME: The following thing is pretty ugly code; we should
945      investigate how to make it cleaner.  Probably code to handle
946      canonical S-expressions in a memory buffer is better suited for
947      such a task.  After all that is what we do in protect.c.  Neeed
948      to find common patterns and write a straightformward API to use
949      them.  */
950   assert (sizeof (size_t) <= sizeof (void*));
951
952   format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
953   if (!format)
954     {
955       err = gpg_error_from_syserror ();
956       for (i=0; array[i]; i++)
957         gcry_mpi_release (array[i]);
958       xfree (array);
959       gcry_sexp_release (uri_sexp);
960       gcry_sexp_release (comment_sexp);
961       return err;
962     }
963
964   argidx = 0;
965   p = stpcpy (stpcpy (format, "(public-key("), algoname);
966   for (idx=0, s=elems; *s; s++, idx++ )
967     {
968       *p++ = '(';
969       *p++ = *s;
970       p = stpcpy (p, " %m)");
971       assert (argidx < DIM (args));
972       args[argidx++] = &array[idx];
973     }
974   *p++ = ')';
975   if (uri)
976     {
977       p = stpcpy (p, "(uri %b)");
978       assert (argidx+1 < DIM (args));
979       args[argidx++] = (void *)&uri_length;
980       args[argidx++] = (void *)&uri;
981     }
982   if (comment)
983     {
984       p = stpcpy (p, "(comment %b)");
985       assert (argidx+1 < DIM (args));
986       args[argidx++] = (void *)&comment_length;
987       args[argidx++] = (void*)&comment;
988     }
989   *p++ = ')';
990   *p = 0;
991   assert (argidx < DIM (args));
992   args[argidx] = NULL;
993
994   err = gcry_sexp_build_array (&list, NULL, format, args);
995   xfree (format);
996   for (i=0; array[i]; i++)
997     gcry_mpi_release (array[i]);
998   xfree (array);
999   gcry_sexp_release (uri_sexp);
1000   gcry_sexp_release (comment_sexp);
1001
1002   if (!err)
1003     *result = list;
1004   return err;
1005 }
1006
1007
1008
1009 /* Check whether the the secret key identified by GRIP is available.
1010    Returns 0 is the key is available.  */
1011 int
1012 agent_key_available (const unsigned char *grip)
1013 {
1014   int result;
1015   char *fname;
1016   char hexgrip[40+4+1];
1017
1018   bin2hex (grip, 20, hexgrip);
1019   strcpy (hexgrip+40, ".key");
1020
1021   fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
1022   result = !access (fname, R_OK)? 0 : -1;
1023   xfree (fname);
1024   return result;
1025 }
1026
1027
1028
1029 /* Return the information about the secret key specified by the binary
1030    keygrip GRIP.  If the key is a shadowed one the shadow information
1031    will be stored at the address R_SHADOW_INFO as an allocated
1032    S-expression.  */
1033 gpg_error_t
1034 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
1035                           int *r_keytype, unsigned char **r_shadow_info)
1036 {
1037   gpg_error_t err;
1038   unsigned char *buf;
1039   size_t len;
1040   int keytype;
1041
1042   (void)ctrl;
1043
1044   if (r_keytype)
1045     *r_keytype = PRIVATE_KEY_UNKNOWN;
1046   if (r_shadow_info)
1047     *r_shadow_info = NULL;
1048
1049   {
1050     gcry_sexp_t sexp;
1051
1052     err = read_key_file (grip, &sexp);
1053     if (err)
1054       {
1055         if (gpg_err_code (err) == GPG_ERR_ENOENT)
1056           return gpg_error (GPG_ERR_NOT_FOUND);
1057         else
1058           return err;
1059       }
1060     err = make_canon_sexp (sexp, &buf, &len);
1061     gcry_sexp_release (sexp);
1062     if (err)
1063       return err;
1064   }
1065
1066   keytype = agent_private_key_type (buf);
1067   switch (keytype)
1068     {
1069     case PRIVATE_KEY_CLEAR:
1070       break;
1071     case PRIVATE_KEY_PROTECTED:
1072       /* If we ever require it we could retrieve the comment fields
1073          from such a key. */
1074       break;
1075     case PRIVATE_KEY_SHADOWED:
1076       if (r_shadow_info)
1077         {
1078           const unsigned char *s;
1079           size_t n;
1080
1081           err = agent_get_shadow_info (buf, &s);
1082           if (!err)
1083             {
1084               n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1085               assert (n);
1086               *r_shadow_info = xtrymalloc (n);
1087               if (!*r_shadow_info)
1088                 err = gpg_error_from_syserror ();
1089               else
1090                 memcpy (*r_shadow_info, s, n);
1091             }
1092         }
1093       break;
1094     default:
1095       err = gpg_error (GPG_ERR_BAD_SECKEY);
1096       break;
1097     }
1098
1099   if (!err && r_keytype)
1100     *r_keytype = keytype;
1101
1102   xfree (buf);
1103   return err;
1104 }