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 pased 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. */
302 unprotect (ctrl_t ctrl
, const char *desc_text
,
303 unsigned char **keybuf
, const unsigned char *grip
,
304 cache_mode_t cache_mode
)
306 struct pin_entry_info_s
*pi
;
307 struct try_unprotect_arg_s arg
;
309 unsigned char *result
;
313 bin2hex (grip
, 20, hexgrip
);
315 /* First try to get it from the cache - if there is none or we can't
316 unprotect it, we fall back to ask the user */
317 if (cache_mode
!= CACHE_MODE_IGNORE
)
323 pw
= agent_get_cache (hexgrip
, cache_mode
, &cache_marker
);
326 rc
= agent_unprotect (*keybuf
, pw
, NULL
, &result
, &resultlen
);
327 agent_unlock_cache_entry (&cache_marker
);
337 /* If the pinentry is currently in use, we wait up to 60 seconds
338 for it to close and check the cache again. This solves a common
339 situation where several requests for unprotecting a key have
340 been made but the user is still entering the passphrase for
341 the first request. Because all requests to agent_askpin are
342 serialized they would then pop up one after the other to
343 request the passphrase - despite that the user has already
344 entered it and is then available in the cache. This
345 implementation is not race free but in the worst case the
346 user has to enter the passphrase only once more. */
347 if (pinentry_active_p (ctrl
, 0))
350 if (!pinentry_active_p (ctrl
, 60))
352 /* We need to give the other thread a chance to actually put
353 it into the cache. */
357 /* Timeout - better call pinentry now the plain way. */
361 pi
= gcry_calloc_secure (1, sizeof (*pi
) + 100);
363 return gpg_error_from_syserror ();
364 pi
->max_length
= 100;
365 pi
->min_digits
= 0; /* we want a real passphrase */
368 pi
->check_cb
= try_unprotect_cb
;
370 arg
.protected_key
= *keybuf
;
371 arg
.unprotected_key
= NULL
;
372 arg
.change_required
= 0;
373 pi
->check_cb_arg
= &arg
;
375 rc
= agent_askpin (ctrl
, desc_text
, NULL
, NULL
, pi
);
378 assert (arg
.unprotected_key
);
379 if (arg
.change_required
)
381 size_t canlen
, erroff
;
384 assert (arg
.unprotected_key
);
385 canlen
= gcry_sexp_canon_len (arg
.unprotected_key
, 0, NULL
, NULL
);
386 rc
= gcry_sexp_sscan (&s_skey
, &erroff
,
387 (char*)arg
.unprotected_key
, canlen
);
390 log_error ("failed to build S-Exp (off=%u): %s\n",
391 (unsigned int)erroff
, gpg_strerror (rc
));
392 wipememory (arg
.unprotected_key
, canlen
);
393 xfree (arg
.unprotected_key
);
397 rc
= agent_protect_and_store (ctrl
, s_skey
);
398 gcry_sexp_release (s_skey
);
401 log_error ("changing the passphrase failed: %s\n",
403 wipememory (arg
.unprotected_key
, canlen
);
404 xfree (arg
.unprotected_key
);
409 agent_put_cache (hexgrip
, cache_mode
, pi
->pin
, 0);
411 *keybuf
= arg
.unprotected_key
;
418 /* Read the key identified by GRIP from the private key directory and
419 return it as an gcrypt S-expression object in RESULT. On failure
420 returns an error code and stores NULL at RESULT. */
422 read_key_file (const unsigned char *grip
, gcry_sexp_t
*result
)
429 size_t buflen
, erroff
;
431 char hexgrip
[40+4+1];
435 bin2hex (grip
, 20, hexgrip
);
436 strcpy (hexgrip
+40, ".key");
438 fname
= make_filename (opt
.homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
439 fp
= fopen (fname
, "rb");
442 rc
= gpg_error_from_syserror ();
443 if (gpg_err_code (rc
) != GPG_ERR_ENOENT
)
444 log_error ("can't open `%s': %s\n", fname
, strerror (errno
));
449 if (fstat (fileno(fp
), &st
))
451 rc
= gpg_error_from_syserror ();
452 log_error ("can't stat `%s': %s\n", fname
, strerror (errno
));
459 buf
= xtrymalloc (buflen
+1);
460 if (!buf
|| fread (buf
, buflen
, 1, fp
) != 1)
462 rc
= gpg_error_from_syserror ();
463 log_error ("error reading `%s': %s\n", fname
, strerror (errno
));
470 /* Convert the file into a gcrypt S-expression object. */
471 rc
= gcry_sexp_sscan (&s_skey
, &erroff
, (char*)buf
, buflen
);
477 log_error ("failed to build S-Exp (off=%u): %s\n",
478 (unsigned int)erroff
, gpg_strerror (rc
));
486 /* Return the secret key as an S-Exp in RESULT after locating it using
487 the GRIP. Stores NULL at RESULT if the operation shall be diverted
488 to a token; in this case an allocated S-expression with the
489 shadow_info part from the file is stored at SHADOW_INFO.
490 CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
491 set to present a custom description for the pinentry. */
493 agent_key_from_file (ctrl_t ctrl
, const char *desc_text
,
494 const unsigned char *grip
, unsigned char **shadow_info
,
495 cache_mode_t cache_mode
, gcry_sexp_t
*result
)
499 size_t len
, buflen
, erroff
;
501 int got_shadow_info
= 0;
507 rc
= read_key_file (grip
, &s_skey
);
511 /* For use with the protection functions we also need the key as an
512 canonical encoded S-expression in a buffer. Create this buffer
514 rc
= make_canon_sexp (s_skey
, &buf
, &len
);
518 switch (agent_private_key_type (buf
))
520 case PRIVATE_KEY_CLEAR
:
521 break; /* no unprotection needed */
522 case PRIVATE_KEY_PROTECTED
:
524 gcry_sexp_t comment_sexp
;
525 size_t comment_length
;
526 char *desc_text_final
;
527 const char *comment
= NULL
;
529 /* Note, that we will take the comment as a C string for
530 display purposes; i.e. all stuff beyond a Nul character is
532 comment_sexp
= gcry_sexp_find_token (s_skey
, "comment", 0);
534 comment
= gcry_sexp_nth_data (comment_sexp
, 1, &comment_length
);
541 desc_text_final
= NULL
;
544 if (comment
[comment_length
])
546 /* Not a C-string; create one. We might here allocate
547 more than actually displayed but well, that
548 shouldn't be a problem. */
549 char *tmp
= xtrymalloc (comment_length
+1);
551 rc
= gpg_error_from_syserror ();
554 memcpy (tmp
, comment
, comment_length
);
555 tmp
[comment_length
] = 0;
556 rc
= modify_description (desc_text
, tmp
, &desc_text_final
);
561 rc
= modify_description (desc_text
, comment
, &desc_text_final
);
566 rc
= unprotect (ctrl
, desc_text_final
, &buf
, grip
, cache_mode
);
568 log_error ("failed to unprotect the secret key: %s\n",
572 gcry_sexp_release (comment_sexp
);
573 xfree (desc_text_final
);
576 case PRIVATE_KEY_SHADOWED
:
579 const unsigned char *s
;
582 rc
= agent_get_shadow_info (buf
, &s
);
585 n
= gcry_sexp_canon_len (s
, 0, NULL
,NULL
);
587 *shadow_info
= xtrymalloc (n
);
592 memcpy (*shadow_info
, s
, n
);
598 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc
));
601 rc
= gpg_error (GPG_ERR_UNUSABLE_SECKEY
);
604 log_error ("invalid private key format\n");
605 rc
= gpg_error (GPG_ERR_BAD_SECKEY
);
608 gcry_sexp_release (s_skey
);
610 if (rc
|| got_shadow_info
)
616 buflen
= gcry_sexp_canon_len (buf
, 0, NULL
, NULL
);
617 rc
= gcry_sexp_sscan (&s_skey
, &erroff
, (char*)buf
, buflen
);
618 wipememory (buf
, buflen
);
622 log_error ("failed to build S-Exp (off=%u): %s\n",
623 (unsigned int)erroff
, gpg_strerror (rc
));
633 /* Return the public key for the keygrip GRIP. The result is stored
634 at RESULT. This function extracts the public key from the private
635 key database. On failure an error code is returned and NULL stored
638 agent_public_key_from_file (ctrl_t ctrl
,
639 const unsigned char *grip
,
644 const char *algoname
;
645 gcry_sexp_t uri_sexp
, comment_sexp
;
646 const char *uri
, *comment
;
647 size_t uri_length
, comment_length
;
649 void *args
[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
650 for comment + end-of-list. */
652 gcry_sexp_t list
, l2
;
663 rc
= read_key_file (grip
, &s_skey
);
667 list
= gcry_sexp_find_token (s_skey
, "shadowed-private-key", 0 );
669 list
= gcry_sexp_find_token (s_skey
, "protected-private-key", 0 );
671 list
= gcry_sexp_find_token (s_skey
, "private-key", 0 );
674 log_error ("invalid private key format\n");
675 gcry_sexp_release (s_skey
);
676 return gpg_error (GPG_ERR_BAD_SECKEY
);
679 l2
= gcry_sexp_cadr (list
);
680 gcry_sexp_release (list
);
682 name
= gcry_sexp_nth_data (list
, 0, &n
);
683 if (n
==3 && !memcmp (name
, "rsa", 3))
688 else if (n
==3 && !memcmp (name
, "dsa", 3))
693 else if (n
==3 && !memcmp (name
, "elg", 3))
700 log_error ("unknown private key algorithm\n");
701 gcry_sexp_release (list
);
702 gcry_sexp_release (s_skey
);
703 return gpg_error (GPG_ERR_BAD_SECKEY
);
706 /* Allocate an array for the parameters and copy them out of the
707 secret key. FIXME: We should have a generic copy function. */
708 array
= xtrycalloc (strlen(elems
) + 1, sizeof *array
);
711 rc
= gpg_error_from_syserror ();
712 gcry_sexp_release (list
);
713 gcry_sexp_release (s_skey
);
717 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
719 l2
= gcry_sexp_find_token (list
, s
, 1);
722 /* Required parameter not found. */
723 for (i
=0; i
<idx
; i
++)
724 gcry_mpi_release (array
[i
]);
726 gcry_sexp_release (list
);
727 gcry_sexp_release (s_skey
);
728 return gpg_error (GPG_ERR_BAD_SECKEY
);
730 array
[idx
] = gcry_sexp_nth_mpi (l2
, 1, GCRYMPI_FMT_USG
);
731 gcry_sexp_release (l2
);
734 /* Required parameter is invalid. */
735 for (i
=0; i
<idx
; i
++)
736 gcry_mpi_release (array
[i
]);
738 gcry_sexp_release (list
);
739 gcry_sexp_release (s_skey
);
740 return gpg_error (GPG_ERR_BAD_SECKEY
);
743 gcry_sexp_release (list
);
748 uri_sexp
= gcry_sexp_find_token (s_skey
, "uri", 0);
750 uri
= gcry_sexp_nth_data (uri_sexp
, 1, &uri_length
);
754 comment_sexp
= gcry_sexp_find_token (s_skey
, "comment", 0);
756 comment
= gcry_sexp_nth_data (comment_sexp
, 1, &comment_length
);
758 gcry_sexp_release (s_skey
);
762 /* FIXME: The following thing is pretty ugly code; we should
763 investigate how to make it cleaner. Probably code to handle
764 canonical S-expressions in a memory buffer is better suioted for
765 such a task. After all that is what we do in protect.c. Neeed
766 to find common patterns and write a straightformward API to use
768 assert (sizeof (size_t) <= sizeof (void*));
770 format
= xtrymalloc (15+7*strlen (elems
)+10+15+1+1);
773 rc
= gpg_error_from_syserror ();
774 for (i
=0; array
[i
]; i
++)
775 gcry_mpi_release (array
[i
]);
777 gcry_sexp_release (uri_sexp
);
778 gcry_sexp_release (comment_sexp
);
783 p
= stpcpy (stpcpy (format
, "(public-key("), algoname
);
784 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
788 p
= stpcpy (p
, " %m)");
789 assert (argidx
< DIM (args
));
790 args
[argidx
++] = &array
[idx
];
795 p
= stpcpy (p
, "(uri %b)");
796 assert (argidx
+1 < DIM (args
));
797 args
[argidx
++] = (void *)uri_length
;
798 args
[argidx
++] = (void *)uri
;
802 p
= stpcpy (p
, "(comment %b)");
803 assert (argidx
+1 < DIM (args
));
804 args
[argidx
++] = (void *)comment_length
;
805 args
[argidx
++] = (void*)comment
;
809 assert (argidx
< DIM (args
));
812 rc
= gcry_sexp_build_array (&list
, NULL
, format
, args
);
814 for (i
=0; array
[i
]; i
++)
815 gcry_mpi_release (array
[i
]);
817 gcry_sexp_release (uri_sexp
);
818 gcry_sexp_release (comment_sexp
);
827 /* Return the secret key as an S-Exp after locating it using the grip.
828 Returns NULL if key is not available. 0 = key is available */
830 agent_key_available (const unsigned char *grip
)
834 char hexgrip
[40+4+1];
836 bin2hex (grip
, 20, hexgrip
);
837 strcpy (hexgrip
+40, ".key");
839 fname
= make_filename (opt
.homedir
, GNUPG_PRIVATE_KEYS_DIR
, hexgrip
, NULL
);
840 result
= !access (fname
, R_OK
)? 0 : -1;
847 /* Return the information about the secret key specified by the binary
848 keygrip GRIP. If the key is a shadowed one the shadow information
849 will be stored at the address R_SHADOW_INFO as an allocated
852 agent_key_info_from_file (ctrl_t ctrl
, const unsigned char *grip
,
853 int *r_keytype
, unsigned char **r_shadow_info
)
863 *r_keytype
= PRIVATE_KEY_UNKNOWN
;
865 *r_shadow_info
= NULL
;
870 err
= read_key_file (grip
, &sexp
);
873 if (gpg_err_code (err
) == GPG_ERR_ENOENT
)
874 return gpg_error (GPG_ERR_NOT_FOUND
);
878 err
= make_canon_sexp (sexp
, &buf
, &len
);
879 gcry_sexp_release (sexp
);
884 keytype
= agent_private_key_type (buf
);
887 case PRIVATE_KEY_CLEAR
:
889 case PRIVATE_KEY_PROTECTED
:
890 /* If we ever require it we could retrieve the comment fields
893 case PRIVATE_KEY_SHADOWED
:
896 const unsigned char *s
;
899 err
= agent_get_shadow_info (buf
, &s
);
902 n
= gcry_sexp_canon_len (s
, 0, NULL
, NULL
);
904 *r_shadow_info
= xtrymalloc (n
);
906 err
= gpg_error_from_syserror ();
908 memcpy (*r_shadow_info
, s
, n
);
913 err
= gpg_error (GPG_ERR_BAD_SECKEY
);
917 if (!err
&& r_keytype
)
918 *r_keytype
= keytype
;