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