* gpg.texi (GPG Configuration Options): Make http_proxy option
[gnupg.git] / agent / findkey.c
blob1510a908150b8e41261242213839db7101eba5d1
1 /* findkey.c - locate the secret key
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <fcntl.h>
29 #include <assert.h>
30 #include <unistd.h>
31 #include <sys/stat.h>
32 #include <assert.h>
33 #include <pth.h> /* (we use pth_sleep) */
35 #include "agent.h"
37 /* Helper to pass data to the check callback of the unprotect function. */
38 struct try_unprotect_arg_s {
39 const unsigned char *protected_key;
40 unsigned char *unprotected_key;
44 /* Write an S-expression formatted key to our key storage. With FORCE
45 pased as true an existing key with the given GRIP will get
46 overwritten. */
47 int
48 agent_write_private_key (const unsigned char *grip,
49 const void *buffer, size_t length, int force)
51 int i;
52 char *fname;
53 FILE *fp;
54 char hexgrip[40+4+1];
55 int fd;
57 for (i=0; i < 20; i++)
58 sprintf (hexgrip+2*i, "%02X", grip[i]);
59 strcpy (hexgrip+40, ".key");
61 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
63 if (!force && !access (fname, F_OK))
65 log_error ("secret key file `%s' already exists\n", fname);
66 xfree (fname);
67 return gpg_error (GPG_ERR_GENERAL);
70 /* In FORCE mode we would like to create FNAME but only if it does
71 not already exist. We cannot make this guarantee just using
72 POSIX (GNU provides the "x" opentype for fopen, however, this is
73 not portable). Thus, we use the more flexible open function and
74 then use fdopen to obtain a stream. */
75 fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY)
76 : (O_CREAT | O_EXCL | O_WRONLY),
77 S_IRUSR | S_IWUSR
78 #ifndef HAVE_W32_SYSTEM
79 | S_IRGRP
80 #endif
82 if (fd < 0)
83 fp = NULL;
84 else
86 fp = fdopen (fd, "wb");
87 if (!fp)
89 int save_e = errno;
90 close (fd);
91 errno = save_e;
95 if (!fp)
97 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
98 log_error ("can't create `%s': %s\n", fname, strerror (errno));
99 xfree (fname);
100 return tmperr;
103 if (fwrite (buffer, length, 1, fp) != 1)
105 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
106 log_error ("error writing `%s': %s\n", fname, strerror (errno));
107 fclose (fp);
108 remove (fname);
109 xfree (fname);
110 return tmperr;
112 if ( fclose (fp) )
114 gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
115 log_error ("error closing `%s': %s\n", fname, strerror (errno));
116 remove (fname);
117 xfree (fname);
118 return tmperr;
120 bump_key_eventcounter ();
121 xfree (fname);
122 return 0;
126 /* Callback function to try the unprotection from the passpharse query
127 code. */
128 static int
129 try_unprotect_cb (struct pin_entry_info_s *pi)
131 struct try_unprotect_arg_s *arg = pi->check_cb_arg;
132 size_t dummy;
134 assert (!arg->unprotected_key);
135 return agent_unprotect (arg->protected_key, pi->pin,
136 &arg->unprotected_key, &dummy);
140 /* Modify a Key description, replacing certain special format
141 characters. List of currently supported replacements:
143 %% - Replaced by a single %
144 %c - Replaced by the content of COMMENT.
146 The functions returns 0 on success or an error code. On success a
147 newly allocated string is stored at the address of RESULT.
149 static gpg_error_t
150 modify_description (const char *in, const char *comment, char **result)
152 size_t comment_length;
153 size_t in_len;
154 size_t out_len;
155 char *out;
156 size_t i;
157 int special, pass;
159 comment_length = strlen (comment);
160 in_len = strlen (in);
162 /* First pass calculates the length, second pass does the actual
163 copying. */
164 out = NULL;
165 out_len = 0;
166 for (pass=0; pass < 2; pass++)
168 special = 0;
169 for (i = 0; i < in_len; i++)
171 if (special)
173 special = 0;
174 switch (in[i])
176 case '%':
177 if (out)
178 *out++ = '%';
179 else
180 out_len++;
181 break;
183 case 'c': /* Comment. */
184 if (out)
186 memcpy (out, comment, comment_length);
187 out += comment_length;
189 else
190 out_len += comment_length;
191 break;
193 default: /* Invalid special sequences are kept as they are. */
194 if (out)
196 *out++ = '%';
197 *out++ = in[i];
199 else
200 out_len+=2;
201 break;
204 else if (in[i] == '%')
205 special = 1;
206 else
208 if (out)
209 *out++ = in[i];
210 else
211 out_len++;
215 if (!pass)
217 *result = out = xtrymalloc (out_len + 1);
218 if (!out)
219 return gpg_error_from_syserror ();
223 *out = 0;
224 assert (*result + out_len == out);
225 return 0;
230 /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
231 should be the hex encoded keygrip of that key to be used with the
232 caching mechanism. DESC_TEXT may be set to override the default
233 description used for the pinentry. */
234 static int
235 unprotect (ctrl_t ctrl, const char *desc_text,
236 unsigned char **keybuf, const unsigned char *grip,
237 cache_mode_t cache_mode)
239 struct pin_entry_info_s *pi;
240 struct try_unprotect_arg_s arg;
241 int rc, i;
242 unsigned char *result;
243 size_t resultlen;
244 char hexgrip[40+1];
246 for (i=0; i < 20; i++)
247 sprintf (hexgrip+2*i, "%02X", grip[i]);
248 hexgrip[40] = 0;
250 /* First try to get it from the cache - if there is none or we can't
251 unprotect it, we fall back to ask the user */
252 if (cache_mode != CACHE_MODE_IGNORE)
254 void *cache_marker;
255 const char *pw;
257 retry:
258 pw = agent_get_cache (hexgrip, cache_mode, &cache_marker);
259 if (pw)
261 rc = agent_unprotect (*keybuf, pw, &result, &resultlen);
262 agent_unlock_cache_entry (&cache_marker);
263 if (!rc)
265 xfree (*keybuf);
266 *keybuf = result;
267 return 0;
269 rc = 0;
272 /* If the pinentry is currently in use, we wait up to 60 seconds
273 for it close and check the cache again. This solves a common
274 situation where several requests for unprotecting a key have
275 been made but the user is still entering the passphrase for
276 the first request. Because all requests to agent_askpin are
277 serialized they would then pop up one after the other to
278 request the passphrase - despite that the user has already
279 entered it and is then available in the cache. This
280 implementation is not race free but in the worst case the
281 user has to enter the passphrase only once more. */
282 if (pinentry_active_p (ctrl, 0))
284 /* Active - wait */
285 if (!pinentry_active_p (ctrl, 60))
287 /* We need to give the other thread a chance to actually put
288 it into the cache. */
289 pth_sleep (1);
290 goto retry;
292 /* Timeout - better call pinentry now the plain way. */
296 pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
297 if (!pi)
298 return gpg_error_from_syserror ();
299 pi->max_length = 100;
300 pi->min_digits = 0; /* we want a real passphrase */
301 pi->max_digits = 8;
302 pi->max_tries = 3;
303 pi->check_cb = try_unprotect_cb;
304 arg.protected_key = *keybuf;
305 arg.unprotected_key = NULL;
306 pi->check_cb_arg = &arg;
308 rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
309 if (!rc)
311 assert (arg.unprotected_key);
312 agent_put_cache (hexgrip, cache_mode, pi->pin, 0);
313 xfree (*keybuf);
314 *keybuf = arg.unprotected_key;
316 xfree (pi);
317 return rc;
321 /* Read the key identified by GRIP from the private key directory and
322 return it as an gcrypt S-expression object in RESULT. On failure
323 returns an error code and stores NULL at RESULT. */
324 static gpg_error_t
325 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
327 int i, rc;
328 char *fname;
329 FILE *fp;
330 struct stat st;
331 unsigned char *buf;
332 size_t buflen, erroff;
333 gcry_sexp_t s_skey;
334 char hexgrip[40+4+1];
336 *result = NULL;
338 for (i=0; i < 20; i++)
339 sprintf (hexgrip+2*i, "%02X", grip[i]);
340 strcpy (hexgrip+40, ".key");
342 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
343 fp = fopen (fname, "rb");
344 if (!fp)
346 rc = gpg_error_from_syserror ();
347 log_error ("can't open `%s': %s\n", fname, strerror (errno));
348 xfree (fname);
349 return rc;
352 if (fstat (fileno(fp), &st))
354 rc = gpg_error_from_syserror ();
355 log_error ("can't stat `%s': %s\n", fname, strerror (errno));
356 xfree (fname);
357 fclose (fp);
358 return rc;
361 buflen = st.st_size;
362 buf = xtrymalloc (buflen+1);
363 if (!buf || fread (buf, buflen, 1, fp) != 1)
365 rc = gpg_error_from_syserror ();
366 log_error ("error reading `%s': %s\n", fname, strerror (errno));
367 xfree (fname);
368 fclose (fp);
369 xfree (buf);
370 return rc;
373 /* Convert the file into a gcrypt S-expression object. */
374 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
375 xfree (fname);
376 fclose (fp);
377 xfree (buf);
378 if (rc)
380 log_error ("failed to build S-Exp (off=%u): %s\n",
381 (unsigned int)erroff, gpg_strerror (rc));
382 return rc;
384 *result = s_skey;
385 return 0;
389 /* Return the secret key as an S-Exp in RESULT after locating it using
390 the grip. Returns NULL in RESULT if the operation should be
391 diverted to a token; SHADOW_INFO will point then to an allocated
392 S-Expression with the shadow_info part from the file. CACHE_MODE
393 defines now the cache shall be used. DESC_TEXT may be set to
394 present a custom description for the pinentry. */
395 gpg_error_t
396 agent_key_from_file (ctrl_t ctrl, const char *desc_text,
397 const unsigned char *grip, unsigned char **shadow_info,
398 cache_mode_t cache_mode, gcry_sexp_t *result)
400 int rc;
401 unsigned char *buf;
402 size_t len, buflen, erroff;
403 gcry_sexp_t s_skey;
404 int got_shadow_info = 0;
406 *result = NULL;
407 if (shadow_info)
408 *shadow_info = NULL;
410 rc = read_key_file (grip, &s_skey);
411 if (rc)
412 return rc;
414 /* For use with the protection functions we also need the key as an
415 canonical encoded S-expression in abuffer. Create this buffer
416 now. */
417 len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
418 assert (len);
419 buf = xtrymalloc (len);
420 if (!buf)
422 rc = gpg_error_from_syserror ();
423 gcry_sexp_release (s_skey);
424 return rc;
426 len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len);
427 assert (len);
430 switch (agent_private_key_type (buf))
432 case PRIVATE_KEY_CLEAR:
433 break; /* no unprotection needed */
434 case PRIVATE_KEY_PROTECTED:
436 gcry_sexp_t comment_sexp;
437 size_t comment_length;
438 char *desc_text_final;
439 const char *comment = NULL;
441 /* Note, that we will take the comment as a C string for
442 display purposes; i.e. all stuff beyond a Nul character is
443 ignored. */
444 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
445 if (comment_sexp)
446 comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
447 if (!comment)
449 comment = "";
450 comment_length = 0;
453 desc_text_final = NULL;
454 if (desc_text)
456 if (comment[comment_length])
458 /* Not a C-string; create one. We might here allocate
459 more than actually displayed but well, that
460 shouldn't be a problem. */
461 char *tmp = xtrymalloc (comment_length+1);
462 if (!tmp)
463 rc = gpg_error_from_syserror ();
464 else
466 memcpy (tmp, comment, comment_length);
467 tmp[comment_length] = 0;
468 rc = modify_description (desc_text, tmp, &desc_text_final);
469 xfree (tmp);
472 else
473 rc = modify_description (desc_text, comment, &desc_text_final);
476 if (!rc)
478 rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode);
479 if (rc)
480 log_error ("failed to unprotect the secret key: %s\n",
481 gpg_strerror (rc));
484 gcry_sexp_release (comment_sexp);
485 xfree (desc_text_final);
487 break;
488 case PRIVATE_KEY_SHADOWED:
489 if (shadow_info)
491 const unsigned char *s;
492 size_t n;
494 rc = agent_get_shadow_info (buf, &s);
495 if (!rc)
497 n = gcry_sexp_canon_len (s, 0, NULL,NULL);
498 assert (n);
499 *shadow_info = xtrymalloc (n);
500 if (!*shadow_info)
501 rc = out_of_core ();
502 else
504 memcpy (*shadow_info, s, n);
505 rc = 0;
506 got_shadow_info = 1;
509 if (rc)
510 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
512 else
513 rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
514 break;
515 default:
516 log_error ("invalid private key format\n");
517 rc = gpg_error (GPG_ERR_BAD_SECKEY);
518 break;
520 gcry_sexp_release (s_skey);
521 s_skey = NULL;
522 if (rc || got_shadow_info)
524 xfree (buf);
525 return rc;
528 buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
529 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
530 wipememory (buf, buflen);
531 xfree (buf);
532 if (rc)
534 log_error ("failed to build S-Exp (off=%u): %s\n",
535 (unsigned int)erroff, gpg_strerror (rc));
536 return rc;
539 *result = s_skey;
540 return 0;
545 /* Return the public key for the keygrip GRIP. The result is stored
546 at RESULT. This function extracts the public key from the private
547 key database. On failure an error code is returned and NULL stored
548 at RESULT. */
549 gpg_error_t
550 agent_public_key_from_file (ctrl_t ctrl,
551 const unsigned char *grip,
552 gcry_sexp_t *result)
554 int i, idx, rc;
555 gcry_sexp_t s_skey;
556 const char *algoname;
557 gcry_sexp_t uri_sexp, comment_sexp;
558 const char *uri, *comment;
559 size_t uri_length, comment_length;
560 char *format, *p;
561 void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
562 for comment + end-of-list. */
563 int argidx;
564 gcry_sexp_t list, l2;
565 const char *name;
566 const char *s;
567 size_t n;
568 const char *elems;
569 gcry_mpi_t *array;
571 *result = NULL;
573 rc = read_key_file (grip, &s_skey);
574 if (rc)
575 return rc;
577 list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
578 if (!list)
579 list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
580 if (!list)
581 list = gcry_sexp_find_token (s_skey, "private-key", 0 );
582 if (!list)
584 log_error ("invalid private key format\n");
585 gcry_sexp_release (s_skey);
586 return gpg_error (GPG_ERR_BAD_SECKEY);
589 l2 = gcry_sexp_cadr (list);
590 gcry_sexp_release (list);
591 list = l2;
592 name = gcry_sexp_nth_data (list, 0, &n);
593 if (n==3 && !memcmp (name, "rsa", 3))
595 algoname = "rsa";
596 elems = "ne";
598 else if (n==3 && !memcmp (name, "dsa", 3))
600 algoname = "dsa";
601 elems = "pqgy";
603 else if (n==3 && !memcmp (name, "elg", 3))
605 algoname = "elg";
606 elems = "pgy";
608 else
610 log_error ("unknown private key algorithm\n");
611 gcry_sexp_release (list);
612 gcry_sexp_release (s_skey);
613 return gpg_error (GPG_ERR_BAD_SECKEY);
616 /* Allocate an array for the parameters and copy them out of the
617 secret key. FIXME: We should have a generic copy function. */
618 array = xtrycalloc (strlen(elems) + 1, sizeof *array);
619 if (!array)
621 rc = gpg_error_from_syserror ();
622 gcry_sexp_release (list);
623 gcry_sexp_release (s_skey);
624 return rc;
627 for (idx=0, s=elems; *s; s++, idx++ )
629 l2 = gcry_sexp_find_token (list, s, 1);
630 if (!l2)
632 /* Required parameter not found. */
633 for (i=0; i<idx; i++)
634 gcry_mpi_release (array[i]);
635 xfree (array);
636 gcry_sexp_release (list);
637 gcry_sexp_release (s_skey);
638 return gpg_error (GPG_ERR_BAD_SECKEY);
640 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
641 gcry_sexp_release (l2);
642 if (!array[idx])
644 /* Required parameter is invalid. */
645 for (i=0; i<idx; i++)
646 gcry_mpi_release (array[i]);
647 xfree (array);
648 gcry_sexp_release (list);
649 gcry_sexp_release (s_skey);
650 return gpg_error (GPG_ERR_BAD_SECKEY);
653 gcry_sexp_release (list);
654 list = NULL;
656 uri = NULL;
657 uri_length = 0;
658 uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
659 if (uri_sexp)
660 uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
662 comment = NULL;
663 comment_length = 0;
664 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
665 if (comment_sexp)
666 comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
668 gcry_sexp_release (s_skey);
669 s_skey = NULL;
672 /* FIXME: The following thing is pretty ugly code; we should
673 investigate how to make it cleaner. Probably code to handle
674 canonical S-expressions in a memory buffer is better suioted for
675 such a task. After all that is what we do in protect.c. Neeed
676 to find common patterns and write a straightformward API to use
677 them. */
678 assert (sizeof (size_t) <= sizeof (void*));
680 format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
681 if (!format)
683 rc = gpg_error_from_syserror ();
684 for (i=0; array[i]; i++)
685 gcry_mpi_release (array[i]);
686 xfree (array);
687 gcry_sexp_release (uri_sexp);
688 gcry_sexp_release (comment_sexp);
689 return rc;
692 argidx = 0;
693 p = stpcpy (stpcpy (format, "(public-key("), algoname);
694 for (idx=0, s=elems; *s; s++, idx++ )
696 *p++ = '(';
697 *p++ = *s;
698 p = stpcpy (p, " %m)");
699 assert (argidx < DIM (args));
700 args[argidx++] = &array[idx];
702 *p++ = ')';
703 if (uri)
705 p = stpcpy (p, "(uri %b)");
706 assert (argidx+1 < DIM (args));
707 args[argidx++] = (void *)uri_length;
708 args[argidx++] = (void *)uri;
710 if (comment)
712 p = stpcpy (p, "(comment %b)");
713 assert (argidx+1 < DIM (args));
714 args[argidx++] = (void *)comment_length;
715 args[argidx++] = (void*)comment;
717 *p++ = ')';
718 *p = 0;
719 assert (argidx < DIM (args));
720 args[argidx] = NULL;
722 rc = gcry_sexp_build_array (&list, NULL, format, args);
723 xfree (format);
724 for (i=0; array[i]; i++)
725 gcry_mpi_release (array[i]);
726 xfree (array);
727 gcry_sexp_release (uri_sexp);
728 gcry_sexp_release (comment_sexp);
730 if (!rc)
731 *result = list;
732 return rc;
737 /* Return the secret key as an S-Exp after locating it using the grip.
738 Returns NULL if key is not available. 0 = key is available */
740 agent_key_available (const unsigned char *grip)
742 int i;
743 char *fname;
744 char hexgrip[40+4+1];
746 for (i=0; i < 20; i++)
747 sprintf (hexgrip+2*i, "%02X", grip[i]);
748 strcpy (hexgrip+40, ".key");
750 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
751 i = !access (fname, R_OK)? 0 : -1;
752 xfree (fname);
753 return i;