1 /* findkey.c - Locate the secret key
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3 * 2007 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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/>.
32 #include <pth.h> /* (we use pth_sleep) */
41 /* Helper to pass data to the check callback of the unprotect function. */
42 struct try_unprotect_arg_s
45 const unsigned char *protected_key
;
46 unsigned char *unprotected_key
;
47 int change_required
; /* Set by the callback to indicate that the
48 user should chnage the passphrase. */
52 /* Write an S-expression formatted key to our key storage. With FORCE
53 passed as true an existing key with the given GRIP will get
56 agent_write_private_key (const unsigned char *grip
,
57 const void *buffer
, size_t length
, int force
)
64 bin2hex (grip
, 20, hexgrip
);
65 strcpy (hexgrip
+40, ".key");
67 fname
= make_filename (opt
.homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
69 if (!force
&& !access (fname
, F_OK
))
71 log_error ("secret key file `%s' already exists\n", fname
);
73 return gpg_error (GPG_ERR_GENERAL
);
76 /* In FORCE mode we would like to create FNAME but only if it does
77 not already exist. We cannot make this guarantee just using
78 POSIX (GNU provides the "x" opentype for fopen, however, this is
79 not portable). Thus, we use the more flexible open function and
80 then use fdopen to obtain a stream. */
81 fd
= open (fname
, force
? (O_CREAT
| O_TRUNC
| O_WRONLY
| O_BINARY
)
82 : (O_CREAT
| O_EXCL
| O_WRONLY
| O_BINARY
),
84 #ifndef HAVE_W32_SYSTEM
92 fp
= fdopen (fd
, "wb");
103 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
104 log_error ("can't create `%s': %s\n", fname
, strerror (errno
));
109 if (fwrite (buffer
, length
, 1, fp
) != 1)
111 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
112 log_error ("error writing `%s': %s\n", fname
, strerror (errno
));
120 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
121 log_error ("error closing `%s': %s\n", fname
, strerror (errno
));
126 bump_key_eventcounter ();
132 /* Callback function to try the unprotection from the passpharse query
135 try_unprotect_cb (struct pin_entry_info_s
*pi
)
137 struct try_unprotect_arg_s
*arg
= pi
->check_cb_arg
;
140 gnupg_isotime_t now
, protected_at
, tmptime
;
143 assert (!arg
->unprotected_key
);
145 arg
->change_required
= 0;
146 err
= agent_unprotect (arg
->protected_key
, pi
->pin
, protected_at
,
147 &arg
->unprotected_key
, &dummy
);
150 if (!opt
.max_passphrase_days
|| arg
->ctrl
->in_passwd
)
151 return 0; /* No regular passphrase change required. */
155 /* No protection date known - must force passphrase change. */
156 desc
= xtrystrdup (_("Note: This passphrase has never been changed.%0A"
157 "Please change it now."));
159 return gpg_error_from_syserror ();
163 gnupg_get_isotime (now
);
164 gnupg_copy_time (tmptime
, protected_at
);
165 err
= add_days_to_isotime (tmptime
, opt
.max_passphrase_days
);
168 if (strcmp (now
, tmptime
) > 0 )
170 /* Passphrase "expired". */
172 (_("This passphrase has not been changed%%0A"
173 "since %.4s-%.2s-%.2s. Please change it now."),
174 protected_at
, protected_at
+4, protected_at
+6);
176 return gpg_error_from_syserror ();
182 /* Change required. */
183 if (opt
.enforce_passphrase_constraints
)
185 err
= agent_get_confirmation (arg
->ctrl
, desc
,
186 _("Change passphrase"), NULL
);
188 arg
->change_required
= 1;
192 err
= agent_get_confirmation (arg
->ctrl
, desc
,
193 _("Change passphrase"),
194 _("I'll change it later"));
196 arg
->change_required
= 1;
197 else if (gpg_err_code (err
) == GPG_ERR_CANCELED
)
207 /* Modify a Key description, replacing certain special format
208 characters. List of currently supported replacements:
210 %% - Replaced by a single %
211 %c - Replaced by the content of COMMENT.
213 The functions returns 0 on success or an error code. On success a
214 newly allocated string is stored at the address of RESULT.
217 modify_description (const char *in
, const char *comment
, char **result
)
219 size_t comment_length
;
226 comment_length
= strlen (comment
);
227 in_len
= strlen (in
);
229 /* First pass calculates the length, second pass does the actual
233 for (pass
=0; pass
< 2; pass
++)
236 for (i
= 0; i
< in_len
; i
++)
250 case 'c': /* Comment. */
253 memcpy (out
, comment
, comment_length
);
254 out
+= comment_length
;
257 out_len
+= comment_length
;
260 default: /* Invalid special sequences are kept as they are. */
271 else if (in
[i
] == '%')
284 *result
= out
= xtrymalloc (out_len
+ 1);
286 return gpg_error_from_syserror ();
291 assert (*result
+ out_len
== out
);
297 /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
298 should be the hex encoded keygrip of that key to be used with the
299 caching mechanism. DESC_TEXT may be set to override the default
300 description used for the pinentry. If LOOKUP_TTL is given this
301 function is used to lookup the default ttl. */
303 unprotect (ctrl_t ctrl
, const char *desc_text
,
304 unsigned char **keybuf
, const unsigned char *grip
,
305 cache_mode_t cache_mode
, lookup_ttl_t lookup_ttl
)
307 struct pin_entry_info_s
*pi
;
308 struct try_unprotect_arg_s arg
;
310 unsigned char *result
;
314 bin2hex (grip
, 20, hexgrip
);
316 /* First try to get it from the cache - if there is none or we can't
317 unprotect it, we fall back to ask the user */
318 if (cache_mode
!= CACHE_MODE_IGNORE
)
324 pw
= agent_get_cache (hexgrip
, cache_mode
, &cache_marker
);
327 rc
= agent_unprotect (*keybuf
, pw
, NULL
, &result
, &resultlen
);
328 agent_unlock_cache_entry (&cache_marker
);
338 /* If the pinentry is currently in use, we wait up to 60 seconds
339 for it to close and check the cache again. This solves a common
340 situation where several requests for unprotecting a key have
341 been made but the user is still entering the passphrase for
342 the first request. Because all requests to agent_askpin are
343 serialized they would then pop up one after the other to
344 request the passphrase - despite that the user has already
345 entered it and is then available in the cache. This
346 implementation is not race free but in the worst case the
347 user has to enter the passphrase only once more. */
348 if (pinentry_active_p (ctrl
, 0))
351 if (!pinentry_active_p (ctrl
, 60))
353 /* We need to give the other thread a chance to actually put
354 it into the cache. */
358 /* Timeout - better call pinentry now the plain way. */
362 pi
= gcry_calloc_secure (1, sizeof (*pi
) + 100);
364 return gpg_error_from_syserror ();
365 pi
->max_length
= 100;
366 pi
->min_digits
= 0; /* we want a real passphrase */
369 pi
->check_cb
= try_unprotect_cb
;
371 arg
.protected_key
= *keybuf
;
372 arg
.unprotected_key
= NULL
;
373 arg
.change_required
= 0;
374 pi
->check_cb_arg
= &arg
;
376 rc
= agent_askpin (ctrl
, desc_text
, NULL
, NULL
, pi
);
379 assert (arg
.unprotected_key
);
380 if (arg
.change_required
)
382 size_t canlen
, erroff
;
385 assert (arg
.unprotected_key
);
386 canlen
= gcry_sexp_canon_len (arg
.unprotected_key
, 0, NULL
, NULL
);
387 rc
= gcry_sexp_sscan (&s_skey
, &erroff
,
388 (char*)arg
.unprotected_key
, canlen
);
391 log_error ("failed to build S-Exp (off=%u): %s\n",
392 (unsigned int)erroff
, gpg_strerror (rc
));
393 wipememory (arg
.unprotected_key
, canlen
);
394 xfree (arg
.unprotected_key
);
398 rc
= agent_protect_and_store (ctrl
, s_skey
);
399 gcry_sexp_release (s_skey
);
402 log_error ("changing the passphrase failed: %s\n",
404 wipememory (arg
.unprotected_key
, canlen
);
405 xfree (arg
.unprotected_key
);
410 agent_put_cache (hexgrip
, cache_mode
, pi
->pin
,
411 lookup_ttl
? lookup_ttl (hexgrip
) : 0);
413 *keybuf
= arg
.unprotected_key
;
420 /* Read the key identified by GRIP from the private key directory and
421 return it as an gcrypt S-expression object in RESULT. On failure
422 returns an error code and stores NULL at RESULT. */
424 read_key_file (const unsigned char *grip
, gcry_sexp_t
*result
)
431 size_t buflen
, erroff
;
433 char hexgrip
[40+4+1];
437 bin2hex (grip
, 20, hexgrip
);
438 strcpy (hexgrip
+40, ".key");
440 fname
= make_filename (opt
.homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
441 fp
= fopen (fname
, "rb");
444 rc
= gpg_error_from_syserror ();
445 if (gpg_err_code (rc
) != GPG_ERR_ENOENT
)
446 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
451 if (fstat (fileno(fp
), &st
))
453 rc
= gpg_error_from_syserror ();
454 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
461 buf
= xtrymalloc (buflen
+1);
462 if (!buf
|| fread (buf
, buflen
, 1, fp
) != 1)
464 rc
= gpg_error_from_syserror ();
465 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
472 /* Convert the file into a gcrypt S-expression object. */
473 rc
= gcry_sexp_sscan (&s_skey
, &erroff
, (char*)buf
, buflen
);
479 log_error ("failed to build S-Exp (off=%u): %s\n",
480 (unsigned int)erroff
, gpg_strerror (rc
));
488 /* Return the secret key as an S-Exp in RESULT after locating it using
489 the GRIP. Stores NULL at RESULT if the operation shall be diverted
490 to a token; in this case an allocated S-expression with the
491 shadow_info part from the file is stored at SHADOW_INFO.
492 CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
493 set to present a custom description for the pinentry. LOOKUP_TTL
494 is an optional function to convey a TTL to the cache manager; we do
495 not simply pass the TTL value because the value is only needed if an
496 unprotect action was needed and looking up the TTL may have some
497 overhead (e.g. scanning the sshcontrol file). */
499 agent_key_from_file (ctrl_t ctrl
, const char *desc_text
,
500 const unsigned char *grip
, unsigned char **shadow_info
,
501 cache_mode_t cache_mode
, lookup_ttl_t lookup_ttl
,
506 size_t len
, buflen
, erroff
;
508 int got_shadow_info
= 0;
514 rc
= read_key_file (grip
, &s_skey
);
518 /* For use with the protection functions we also need the key as an
519 canonical encoded S-expression in a buffer. Create this buffer
521 rc
= make_canon_sexp (s_skey
, &buf
, &len
);
525 switch (agent_private_key_type (buf
))
527 case PRIVATE_KEY_CLEAR
:
528 break; /* no unprotection needed */
529 case PRIVATE_KEY_PROTECTED
:
531 gcry_sexp_t comment_sexp
;
532 size_t comment_length
;
533 char *desc_text_final
;
534 const char *comment
= NULL
;
536 /* Note, that we will take the comment as a C string for
537 display purposes; i.e. all stuff beyond a Nul character is
539 comment_sexp
= gcry_sexp_find_token (s_skey
, "comment", 0);
541 comment
= gcry_sexp_nth_data (comment_sexp
, 1, &comment_length
);
548 desc_text_final
= NULL
;
551 if (comment
[comment_length
])
553 /* Not a C-string; create one. We might here allocate
554 more than actually displayed but well, that
555 shouldn't be a problem. */
556 char *tmp
= xtrymalloc (comment_length
+1);
558 rc
= gpg_error_from_syserror ();
561 memcpy (tmp
, comment
, comment_length
);
562 tmp
[comment_length
] = 0;
563 rc
= modify_description (desc_text
, tmp
, &desc_text_final
);
568 rc
= modify_description (desc_text
, comment
, &desc_text_final
);
573 rc
= unprotect (ctrl
, desc_text_final
, &buf
, grip
,
574 cache_mode
, lookup_ttl
);
576 log_error ("failed to unprotect the secret key: %s\n",
580 gcry_sexp_release (comment_sexp
);
581 xfree (desc_text_final
);
584 case PRIVATE_KEY_SHADOWED
:
587 const unsigned char *s
;
590 rc
= agent_get_shadow_info (buf
, &s
);
593 n
= gcry_sexp_canon_len (s
, 0, NULL
,NULL
);
595 *shadow_info
= xtrymalloc (n
);
600 memcpy (*shadow_info
, s
, n
);
606 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc
));
609 rc
= gpg_error (GPG_ERR_UNUSABLE_SECKEY
);
612 log_error ("invalid private key format\n");
613 rc
= gpg_error (GPG_ERR_BAD_SECKEY
);
616 gcry_sexp_release (s_skey
);
618 if (rc
|| got_shadow_info
)
624 buflen
= gcry_sexp_canon_len (buf
, 0, NULL
, NULL
);
625 rc
= gcry_sexp_sscan (&s_skey
, &erroff
, (char*)buf
, buflen
);
626 wipememory (buf
, buflen
);
630 log_error ("failed to build S-Exp (off=%u): %s\n",
631 (unsigned int)erroff
, gpg_strerror (rc
));
641 /* Return the public key for the keygrip GRIP. The result is stored
642 at RESULT. This function extracts the public key from the private
643 key database. On failure an error code is returned and NULL stored
646 agent_public_key_from_file (ctrl_t ctrl
,
647 const unsigned char *grip
,
652 const char *algoname
;
653 gcry_sexp_t uri_sexp
, comment_sexp
;
654 const char *uri
, *comment
;
655 size_t uri_length
, comment_length
;
657 void *args
[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
658 for comment + end-of-list. */
660 gcry_sexp_t list
, l2
;
671 rc
= read_key_file (grip
, &s_skey
);
675 list
= gcry_sexp_find_token (s_skey
, "shadowed-private-key", 0 );
677 list
= gcry_sexp_find_token (s_skey
, "protected-private-key", 0 );
679 list
= gcry_sexp_find_token (s_skey
, "private-key", 0 );
682 log_error ("invalid private key format\n");
683 gcry_sexp_release (s_skey
);
684 return gpg_error (GPG_ERR_BAD_SECKEY
);
687 l2
= gcry_sexp_cadr (list
);
688 gcry_sexp_release (list
);
690 name
= gcry_sexp_nth_data (list
, 0, &n
);
691 if (n
==3 && !memcmp (name
, "rsa", 3))
696 else if (n
==3 && !memcmp (name
, "dsa", 3))
701 else if (n
==3 && !memcmp (name
, "elg", 3))
708 log_error ("unknown private key algorithm\n");
709 gcry_sexp_release (list
);
710 gcry_sexp_release (s_skey
);
711 return gpg_error (GPG_ERR_BAD_SECKEY
);
714 /* Allocate an array for the parameters and copy them out of the
715 secret key. FIXME: We should have a generic copy function. */
716 array
= xtrycalloc (strlen(elems
) + 1, sizeof *array
);
719 rc
= gpg_error_from_syserror ();
720 gcry_sexp_release (list
);
721 gcry_sexp_release (s_skey
);
725 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
727 l2
= gcry_sexp_find_token (list
, s
, 1);
730 /* Required parameter not found. */
731 for (i
=0; i
<idx
; i
++)
732 gcry_mpi_release (array
[i
]);
734 gcry_sexp_release (list
);
735 gcry_sexp_release (s_skey
);
736 return gpg_error (GPG_ERR_BAD_SECKEY
);
738 array
[idx
] = gcry_sexp_nth_mpi (l2
, 1, GCRYMPI_FMT_USG
);
739 gcry_sexp_release (l2
);
742 /* Required parameter is invalid. */
743 for (i
=0; i
<idx
; i
++)
744 gcry_mpi_release (array
[i
]);
746 gcry_sexp_release (list
);
747 gcry_sexp_release (s_skey
);
748 return gpg_error (GPG_ERR_BAD_SECKEY
);
751 gcry_sexp_release (list
);
756 uri_sexp
= gcry_sexp_find_token (s_skey
, "uri", 0);
758 uri
= gcry_sexp_nth_data (uri_sexp
, 1, &uri_length
);
762 comment_sexp
= gcry_sexp_find_token (s_skey
, "comment", 0);
764 comment
= gcry_sexp_nth_data (comment_sexp
, 1, &comment_length
);
766 gcry_sexp_release (s_skey
);
770 /* FIXME: The following thing is pretty ugly code; we should
771 investigate how to make it cleaner. Probably code to handle
772 canonical S-expressions in a memory buffer is better suioted for
773 such a task. After all that is what we do in protect.c. Neeed
774 to find common patterns and write a straightformward API to use
776 assert (sizeof (size_t) <= sizeof (void*));
778 format
= xtrymalloc (15+7*strlen (elems
)+10+15+1+1);
781 rc
= gpg_error_from_syserror ();
782 for (i
=0; array
[i
]; i
++)
783 gcry_mpi_release (array
[i
]);
785 gcry_sexp_release (uri_sexp
);
786 gcry_sexp_release (comment_sexp
);
791 p
= stpcpy (stpcpy (format
, "(public-key("), algoname
);
792 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
796 p
= stpcpy (p
, " %m)");
797 assert (argidx
< DIM (args
));
798 args
[argidx
++] = &array
[idx
];
803 p
= stpcpy (p
, "(uri %b)");
804 assert (argidx
+1 < DIM (args
));
805 args
[argidx
++] = (void *)uri_length
;
806 args
[argidx
++] = (void *)uri
;
810 p
= stpcpy (p
, "(comment %b)");
811 assert (argidx
+1 < DIM (args
));
812 args
[argidx
++] = (void *)comment_length
;
813 args
[argidx
++] = (void*)comment
;
817 assert (argidx
< DIM (args
));
820 rc
= gcry_sexp_build_array (&list
, NULL
, format
, args
);
822 for (i
=0; array
[i
]; i
++)
823 gcry_mpi_release (array
[i
]);
825 gcry_sexp_release (uri_sexp
);
826 gcry_sexp_release (comment_sexp
);
835 /* Return the secret key as an S-Exp after locating it using the grip.
836 Returns NULL if key is not available. 0 = key is available */
838 agent_key_available (const unsigned char *grip
)
842 char hexgrip
[40+4+1];
844 bin2hex (grip
, 20, hexgrip
);
845 strcpy (hexgrip
+40, ".key");
847 fname
= make_filename (opt
.homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
848 result
= !access (fname
, R_OK
)? 0 : -1;
855 /* Return the information about the secret key specified by the binary
856 keygrip GRIP. If the key is a shadowed one the shadow information
857 will be stored at the address R_SHADOW_INFO as an allocated
860 agent_key_info_from_file (ctrl_t ctrl
, const unsigned char *grip
,
861 int *r_keytype
, unsigned char **r_shadow_info
)
871 *r_keytype
= PRIVATE_KEY_UNKNOWN
;
873 *r_shadow_info
= NULL
;
878 err
= read_key_file (grip
, &sexp
);
881 if (gpg_err_code (err
) == GPG_ERR_ENOENT
)
882 return gpg_error (GPG_ERR_NOT_FOUND
);
886 err
= make_canon_sexp (sexp
, &buf
, &len
);
887 gcry_sexp_release (sexp
);
892 keytype
= agent_private_key_type (buf
);
895 case PRIVATE_KEY_CLEAR
:
897 case PRIVATE_KEY_PROTECTED
:
898 /* If we ever require it we could retrieve the comment fields
901 case PRIVATE_KEY_SHADOWED
:
904 const unsigned char *s
;
907 err
= agent_get_shadow_info (buf
, &s
);
910 n
= gcry_sexp_canon_len (s
, 0, NULL
, NULL
);
912 *r_shadow_info
= xtrymalloc (n
);
914 err
= gpg_error_from_syserror ();
916 memcpy (*r_shadow_info
, s
, n
);
921 err
= gpg_error (GPG_ERR_BAD_SECKEY
);
925 if (!err
&& r_keytype
)
926 *r_keytype
= keytype
;