1 /* findkey.c - Locate the secret key
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
3 * 2010, 2011 Free Software Foundation, Inc.
4 * Copyright (C) 2014 Werner Koch
6 * This file is part of GnuPG.
8 * GnuPG is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuPG is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
33 #include <npth.h> /* (we use pth_sleep) */
37 #include "../common/ssh-utils.h"
43 /* Helper to pass data to the check callback of the unprotect function. */
44 struct try_unprotect_arg_s
47 const unsigned char *protected_key;
48 unsigned char *unprotected_key;
49 int change_required; /* Set by the callback to indicate that the
50 user should chnage the passphrase. */
54 /* Write an S-expression formatted key to our key storage. With FORCE
55 passed as true an existing key with the given GRIP will get
58 agent_write_private_key (const unsigned char *grip,
59 const void *buffer, size_t length, int force)
65 bin2hex (grip, 20, hexgrip);
66 strcpy (hexgrip+40, ".key");
68 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
70 /* FIXME: Write to a temp file first so that write failures during
71 key updates won't lead to a key loss. */
73 if (!force && !access (fname, F_OK))
75 log_error ("secret key file '%s' already exists\n", fname);
77 return gpg_error (GPG_ERR_EEXIST);
80 fp = es_fopen (fname, force? "wb,mode=-rw" : "wbx,mode=-rw");
83 gpg_error_t tmperr = gpg_error_from_syserror ();
84 log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
89 if (es_fwrite (buffer, length, 1, fp) != 1)
91 gpg_error_t tmperr = gpg_error_from_syserror ();
92 log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
100 gpg_error_t tmperr = gpg_error_from_syserror ();
101 log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
102 gnupg_remove (fname);
106 bump_key_eventcounter ();
112 /* Callback function to try the unprotection from the passphrase query
115 try_unprotect_cb (struct pin_entry_info_s *pi)
117 struct try_unprotect_arg_s *arg = pi->check_cb_arg;
120 gnupg_isotime_t now, protected_at, tmptime;
123 assert (!arg->unprotected_key);
125 arg->change_required = 0;
126 err = agent_unprotect (arg->ctrl, arg->protected_key, pi->pin, protected_at,
127 &arg->unprotected_key, &dummy);
130 if (!opt.max_passphrase_days || arg->ctrl->in_passwd)
131 return 0; /* No regular passphrase change required. */
135 /* No protection date known - must force passphrase change. */
136 desc = xtrystrdup (_("Note: This passphrase has never been changed.%0A"
137 "Please change it now."));
139 return gpg_error_from_syserror ();
143 gnupg_get_isotime (now);
144 gnupg_copy_time (tmptime, protected_at);
145 err = add_days_to_isotime (tmptime, opt.max_passphrase_days);
148 if (strcmp (now, tmptime) > 0 )
150 /* Passphrase "expired". */
152 (_("This passphrase has not been changed%%0A"
153 "since %.4s-%.2s-%.2s. Please change it now."),
154 protected_at, protected_at+4, protected_at+6);
156 return gpg_error_from_syserror ();
162 /* Change required. */
163 if (opt.enforce_passphrase_constraints)
165 err = agent_get_confirmation (arg->ctrl, desc,
166 _("Change passphrase"), NULL, 0);
168 arg->change_required = 1;
172 err = agent_get_confirmation (arg->ctrl, desc,
173 _("Change passphrase"),
174 _("I'll change it later"), 0);
176 arg->change_required = 1;
177 else if (gpg_err_code (err) == GPG_ERR_CANCELED
178 || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
188 /* Modify a Key description, replacing certain special format
189 characters. List of currently supported replacements:
191 %% - Replaced by a single %
192 %c - Replaced by the content of COMMENT.
193 %C - Same as %c but put into parentheses.
194 %F - Replaced by an ssh style fingerprint computed from KEY.
196 The functions returns 0 on success or an error code. On success a
197 newly allocated string is stored at the address of RESULT.
200 modify_description (const char *in, const char *comment, const gcry_sexp_t key,
203 size_t comment_length;
209 char *ssh_fpr = NULL;
211 comment_length = strlen (comment);
212 in_len = strlen (in);
214 /* First pass calculates the length, second pass does the actual
218 for (pass=0; pass < 2; pass++)
221 for (i = 0; i < in_len; i++)
235 case 'c': /* Comment. */
238 memcpy (out, comment, comment_length);
239 out += comment_length;
242 out_len += comment_length;
245 case 'C': /* Comment. */
251 memcpy (out, comment, comment_length);
252 out += comment_length;
256 out_len += comment_length + 2;
259 case 'F': /* SSH style fingerprint. */
261 ssh_get_fingerprint_string (key, &ssh_fpr);
265 out = stpcpy (out, ssh_fpr);
267 out_len += strlen (ssh_fpr);
271 default: /* Invalid special sequences are kept as they are. */
282 else if (in[i] == '%')
295 *result = out = xtrymalloc (out_len + 1);
299 return gpg_error_from_syserror ();
305 assert (*result + out_len == out);
312 /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
313 should be the hex encoded keygrip of that key to be used with the
314 caching mechanism. DESC_TEXT may be set to override the default
315 description used for the pinentry. If LOOKUP_TTL is given this
316 function is used to lookup the default ttl. If R_PASSPHRASE is not
317 NULL, the function succeeded and the key was protected the used
318 passphrase (entered or from the cache) is stored there; if not NULL
319 will be stored. The caller needs to free the returned
322 unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
323 unsigned char **keybuf, const unsigned char *grip,
324 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
327 struct pin_entry_info_s *pi;
328 struct try_unprotect_arg_s arg;
330 unsigned char *result;
335 *r_passphrase = NULL;
337 bin2hex (grip, 20, hexgrip);
339 /* Initially try to get it using a cache nonce. */
344 pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
347 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
362 /* First try to get it from the cache - if there is none or we can't
363 unprotect it, we fall back to ask the user */
364 if (cache_mode != CACHE_MODE_IGNORE)
369 pw = agent_get_cache (hexgrip, cache_mode);
372 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
375 if (cache_mode == CACHE_MODE_NORMAL)
376 agent_store_cache_hit (hexgrip);
388 else if (cache_mode == CACHE_MODE_NORMAL)
390 /* The standard use of GPG keys is to have a signing and an
391 encryption subkey. Commonly both use the same
392 passphrase. We try to help the user to enter the
393 passphrase only once by silently trying the last
394 correctly entered passphrase. Checking one additional
395 passphrase should be acceptable; despite the S2K
396 introduced delays. The assumed workflow is:
398 1. Read encrypted message in a MUA and thus enter a
399 passphrase for the encryption subkey.
401 2. Reply to that mail with an encrypted and signed
402 mail, thus entering the passphrase for the signing
405 We can often avoid the passphrase entry in the second
406 step. We do this only in normal mode, so not to
407 interfere with unrelated cache entries. */
408 pw = agent_get_cache (NULL, cache_mode);
411 rc = agent_unprotect (ctrl, *keybuf, pw, NULL,
412 &result, &resultlen);
428 /* If the pinentry is currently in use, we wait up to 60 seconds
429 for it to close and check the cache again. This solves a common
430 situation where several requests for unprotecting a key have
431 been made but the user is still entering the passphrase for
432 the first request. Because all requests to agent_askpin are
433 serialized they would then pop up one after the other to
434 request the passphrase - despite that the user has already
435 entered it and is then available in the cache. This
436 implementation is not race free but in the worst case the
437 user has to enter the passphrase only once more. */
438 if (pinentry_active_p (ctrl, 0))
441 if (!pinentry_active_p (ctrl, 60))
443 /* We need to give the other thread a chance to actually put
444 it into the cache. */
448 /* Timeout - better call pinentry now the plain way. */
452 pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
454 return gpg_error_from_syserror ();
455 pi->max_length = 100;
456 pi->min_digits = 0; /* we want a real passphrase */
459 pi->check_cb = try_unprotect_cb;
461 arg.protected_key = *keybuf;
462 arg.unprotected_key = NULL;
463 arg.change_required = 0;
464 pi->check_cb_arg = &arg;
466 rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi);
469 assert (arg.unprotected_key);
470 if (arg.change_required)
472 size_t canlen, erroff;
475 assert (arg.unprotected_key);
476 canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
477 rc = gcry_sexp_sscan (&s_skey, &erroff,
478 (char*)arg.unprotected_key, canlen);
481 log_error ("failed to build S-Exp (off=%u): %s\n",
482 (unsigned int)erroff, gpg_strerror (rc));
483 wipememory (arg.unprotected_key, canlen);
484 xfree (arg.unprotected_key);
488 rc = agent_protect_and_store (ctrl, s_skey, NULL);
489 gcry_sexp_release (s_skey);
492 log_error ("changing the passphrase failed: %s\n",
494 wipememory (arg.unprotected_key, canlen);
495 xfree (arg.unprotected_key);
502 agent_put_cache (hexgrip, cache_mode, pi->pin,
503 lookup_ttl? lookup_ttl (hexgrip) : 0);
504 agent_store_cache_hit (hexgrip);
505 if (r_passphrase && *pi->pin)
506 *r_passphrase = xtrystrdup (pi->pin);
509 *keybuf = arg.unprotected_key;
516 /* Read the key identified by GRIP from the private key directory and
517 return it as an gcrypt S-expression object in RESULT. On failure
518 returns an error code and stores NULL at RESULT. */
520 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
527 size_t buflen, erroff;
529 char hexgrip[40+4+1];
533 bin2hex (grip, 20, hexgrip);
534 strcpy (hexgrip+40, ".key");
536 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
537 fp = es_fopen (fname, "rb");
540 rc = gpg_error_from_syserror ();
541 if (gpg_err_code (rc) != GPG_ERR_ENOENT)
542 log_error ("can't open '%s': %s\n", fname, strerror (errno));
547 if (fstat (es_fileno (fp), &st))
549 rc = gpg_error_from_syserror ();
550 log_error ("can't stat '%s': %s\n", fname, strerror (errno));
557 buf = xtrymalloc (buflen+1);
560 rc = gpg_error_from_syserror ();
561 log_error ("error allocating %zu bytes for '%s': %s\n",
562 buflen, fname, strerror (errno));
570 if (es_fread (buf, buflen, 1, fp) != 1)
572 rc = gpg_error_from_syserror ();
573 log_error ("error reading %zu bytes from '%s': %s\n",
574 buflen, fname, strerror (errno));
581 /* Convert the file into a gcrypt S-expression object. */
582 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
588 log_error ("failed to build S-Exp (off=%u): %s\n",
589 (unsigned int)erroff, gpg_strerror (rc));
597 /* Remove the key identified by GRIP from the private key directory. */
599 remove_key_file (const unsigned char *grip)
603 char hexgrip[40+4+1];
605 bin2hex (grip, 20, hexgrip);
606 strcpy (hexgrip+40, ".key");
607 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
608 if (gnupg_remove (fname))
609 err = gpg_error_from_syserror ();
615 /* Return the secret key as an S-Exp in RESULT after locating it using
616 the GRIP. If the operation shall be diverted to a token, an
617 allocated S-expression with the shadow_info part from the file is
618 stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO.
619 CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
620 set to present a custom description for the pinentry. LOOKUP_TTL
621 is an optional function to convey a TTL to the cache manager; we do
622 not simply pass the TTL value because the value is only needed if
623 an unprotect action was needed and looking up the TTL may have some
624 overhead (e.g. scanning the sshcontrol file). If a CACHE_NONCE is
625 given that cache item is first tried to get a passphrase. If
626 R_PASSPHRASE is not NULL, the function succeeded and the key was
627 protected the used passphrase (entered or from the cache) is stored
628 there; if not NULL will be stored. The caller needs to free the
629 returned passphrase. */
631 agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
632 const char *desc_text,
633 const unsigned char *grip, unsigned char **shadow_info,
634 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
635 gcry_sexp_t *result, char **r_passphrase)
639 size_t len, buflen, erroff;
646 *r_passphrase = NULL;
648 rc = read_key_file (grip, &s_skey);
651 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
652 rc = gpg_error (GPG_ERR_NO_SECKEY);
656 /* For use with the protection functions we also need the key as an
657 canonical encoded S-expression in a buffer. Create this buffer
659 rc = make_canon_sexp (s_skey, &buf, &len);
663 switch (agent_private_key_type (buf))
665 case PRIVATE_KEY_CLEAR:
666 break; /* no unprotection needed */
667 case PRIVATE_KEY_PROTECTED:
669 char *desc_text_final;
670 char *comment = NULL;
672 /* Note, that we will take the comment as a C string for
673 display purposes; i.e. all stuff beyond a Nul character is
676 gcry_sexp_t comment_sexp;
678 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
680 comment = gcry_sexp_nth_string (comment_sexp, 1);
681 gcry_sexp_release (comment_sexp);
684 desc_text_final = NULL;
686 rc = modify_description (desc_text, comment? comment:"", s_skey,
692 rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
693 cache_mode, lookup_ttl, r_passphrase);
695 log_error ("failed to unprotect the secret key: %s\n",
699 xfree (desc_text_final);
702 case PRIVATE_KEY_SHADOWED:
705 const unsigned char *s;
708 rc = agent_get_shadow_info (buf, &s);
711 n = gcry_sexp_canon_len (s, 0, NULL,NULL);
713 *shadow_info = xtrymalloc (n);
718 memcpy (*shadow_info, s, n);
723 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
726 rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
729 log_error ("invalid private key format\n");
730 rc = gpg_error (GPG_ERR_BAD_SECKEY);
733 gcry_sexp_release (s_skey);
740 xfree (*r_passphrase);
741 *r_passphrase = NULL;
746 buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
747 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
748 wipememory (buf, buflen);
752 log_error ("failed to build S-Exp (off=%u): %s\n",
753 (unsigned int)erroff, gpg_strerror (rc));
756 xfree (*r_passphrase);
757 *r_passphrase = NULL;
767 /* Return the string name from the S-expression S_KEY as well as a
768 string describing the names of the parameters. ALGONAMESIZE and
769 ELEMSSIZE give the allocated size of the provided buffers. The
770 buffers may be NULL if not required. If R_LIST is not NULL the top
771 level list will be stored there; the caller needs to release it in
774 key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
775 char *r_algoname, size_t algonamesize,
776 char *r_elems, size_t elemssize)
778 gcry_sexp_t list, l2;
779 const char *name, *algoname, *elems;
785 list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
787 list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
789 list = gcry_sexp_find_token (s_key, "private-key", 0 );
792 log_error ("invalid private key format\n");
793 return gpg_error (GPG_ERR_BAD_SECKEY);
796 l2 = gcry_sexp_cadr (list);
797 gcry_sexp_release (list);
799 name = gcry_sexp_nth_data (list, 0, &n);
800 if (n==3 && !memcmp (name, "rsa", 3))
805 else if (n==3 && !memcmp (name, "dsa", 3))
810 else if (n==3 && !memcmp (name, "ecc", 3))
815 else if (n==5 && !memcmp (name, "ecdsa", 5))
820 else if (n==4 && !memcmp (name, "ecdh", 4))
825 else if (n==3 && !memcmp (name, "elg", 3))
832 log_error ("unknown private key algorithm\n");
833 gcry_sexp_release (list);
834 return gpg_error (GPG_ERR_BAD_SECKEY);
839 if (strlen (algoname) >= algonamesize)
840 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
841 strcpy (r_algoname, algoname);
845 if (strlen (elems) >= elemssize)
846 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
847 strcpy (r_elems, elems);
853 gcry_sexp_release (list);
859 /* Return true if KEYPARMS holds an EdDSA key. */
861 is_eddsa (gcry_sexp_t keyparms)
869 list = gcry_sexp_find_token (keyparms, "flags", 0);
870 for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
872 s = gcry_sexp_nth_data (list, i, &n);
874 continue; /* Not a data element. */
876 if (n == 5 && !memcmp (s, "eddsa", 5))
882 gcry_sexp_release (list);
887 /* Return the public key algorithm number if S_KEY is a DSA style key.
888 If it is not a DSA style key, return 0. */
890 agent_is_dsa_key (gcry_sexp_t s_key)
899 if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
900 return 0; /* Error - assume it is not an DSA key. */
902 if (!strcmp (algoname, "dsa"))
903 result = GCRY_PK_DSA;
904 else if (!strcmp (algoname, "ecc"))
909 result = GCRY_PK_ECDSA;
911 else if (!strcmp (algoname, "ecdsa"))
912 result = GCRY_PK_ECDSA;
916 gcry_sexp_release (list);
921 /* Return true if S_KEY is an EdDSA key as used with curve Ed25519. */
923 agent_is_eddsa_key (gcry_sexp_t s_key)
932 if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
933 return 0; /* Error - assume it is not an EdDSA key. */
935 if (!strcmp (algoname, "ecc") && is_eddsa (list))
937 else if (!strcmp (algoname, "eddsa")) /* backward compatibility. */
942 gcry_sexp_release (list);
947 /* Return the key for the keygrip GRIP. The result is stored at
948 RESULT. This function extracts the key from the private key
949 database and returns it as an S-expression object as it is. On
950 failure an error code is returned and NULL stored at RESULT. */
952 agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
962 err = read_key_file (grip, &s_skey);
969 /* Return the public key for the keygrip GRIP. The result is stored
970 at RESULT. This function extracts the public key from the private
971 key database. On failure an error code is returned and NULL stored
974 agent_public_key_from_file (ctrl_t ctrl,
975 const unsigned char *grip,
983 gcry_sexp_t uri_sexp, comment_sexp;
984 const char *uri, *comment;
985 size_t uri_length, comment_length;
987 void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
988 for comment + end-of-list. */
990 gcry_sexp_t list, l2;
998 err = read_key_file (grip, &s_skey);
1002 err = key_parms_from_sexp (s_skey, &list,
1003 algoname, sizeof algoname,
1004 elems, sizeof elems);
1007 gcry_sexp_release (s_skey);
1011 /* Allocate an array for the parameters and copy them out of the
1012 secret key. FIXME: We should have a generic copy function. */
1013 array = xtrycalloc (strlen(elems) + 1, sizeof *array);
1016 err = gpg_error_from_syserror ();
1017 gcry_sexp_release (list);
1018 gcry_sexp_release (s_skey);
1022 for (idx=0, s=elems; *s; s++, idx++ )
1024 l2 = gcry_sexp_find_token (list, s, 1);
1027 /* Required parameter not found. */
1028 for (i=0; i<idx; i++)
1029 gcry_mpi_release (array[i]);
1031 gcry_sexp_release (list);
1032 gcry_sexp_release (s_skey);
1033 return gpg_error (GPG_ERR_BAD_SECKEY);
1035 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
1036 gcry_sexp_release (l2);
1039 /* Required parameter is invalid. */
1040 for (i=0; i<idx; i++)
1041 gcry_mpi_release (array[i]);
1043 gcry_sexp_release (list);
1044 gcry_sexp_release (s_skey);
1045 return gpg_error (GPG_ERR_BAD_SECKEY);
1048 gcry_sexp_release (list);
1053 uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
1055 uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
1059 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1061 comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
1063 gcry_sexp_release (s_skey);
1067 /* FIXME: The following thing is pretty ugly code; we should
1068 investigate how to make it cleaner. Probably code to handle
1069 canonical S-expressions in a memory buffer is better suited for
1070 such a task. After all that is what we do in protect.c. Neeed
1071 to find common patterns and write a straightformward API to use
1073 assert (sizeof (size_t) <= sizeof (void*));
1075 format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
1078 err = gpg_error_from_syserror ();
1079 for (i=0; array[i]; i++)
1080 gcry_mpi_release (array[i]);
1082 gcry_sexp_release (uri_sexp);
1083 gcry_sexp_release (comment_sexp);
1088 p = stpcpy (stpcpy (format, "(public-key("), algoname);
1089 for (idx=0, s=elems; *s; s++, idx++ )
1093 p = stpcpy (p, " %m)");
1094 assert (argidx < DIM (args));
1095 args[argidx++] = &array[idx];
1100 p = stpcpy (p, "(uri %b)");
1101 assert (argidx+1 < DIM (args));
1102 args[argidx++] = (void *)&uri_length;
1103 args[argidx++] = (void *)&uri;
1107 p = stpcpy (p, "(comment %b)");
1108 assert (argidx+1 < DIM (args));
1109 args[argidx++] = (void *)&comment_length;
1110 args[argidx++] = (void*)&comment;
1114 assert (argidx < DIM (args));
1115 args[argidx] = NULL;
1117 err = gcry_sexp_build_array (&list, NULL, format, args);
1119 for (i=0; array[i]; i++)
1120 gcry_mpi_release (array[i]);
1122 gcry_sexp_release (uri_sexp);
1123 gcry_sexp_release (comment_sexp);
1132 /* Check whether the the secret key identified by GRIP is available.
1133 Returns 0 is the key is available. */
1135 agent_key_available (const unsigned char *grip)
1139 char hexgrip[40+4+1];
1141 bin2hex (grip, 20, hexgrip);
1142 strcpy (hexgrip+40, ".key");
1144 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
1145 result = !access (fname, R_OK)? 0 : -1;
1152 /* Return the information about the secret key specified by the binary
1153 keygrip GRIP. If the key is a shadowed one the shadow information
1154 will be stored at the address R_SHADOW_INFO as an allocated
1157 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
1158 int *r_keytype, unsigned char **r_shadow_info)
1168 *r_keytype = PRIVATE_KEY_UNKNOWN;
1170 *r_shadow_info = NULL;
1175 err = read_key_file (grip, &sexp);
1178 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1179 return gpg_error (GPG_ERR_NOT_FOUND);
1183 err = make_canon_sexp (sexp, &buf, &len);
1184 gcry_sexp_release (sexp);
1189 keytype = agent_private_key_type (buf);
1192 case PRIVATE_KEY_CLEAR:
1194 case PRIVATE_KEY_PROTECTED:
1195 /* If we ever require it we could retrieve the comment fields
1198 case PRIVATE_KEY_SHADOWED:
1201 const unsigned char *s;
1204 err = agent_get_shadow_info (buf, &s);
1207 n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1209 *r_shadow_info = xtrymalloc (n);
1210 if (!*r_shadow_info)
1211 err = gpg_error_from_syserror ();
1213 memcpy (*r_shadow_info, s, n);
1218 err = gpg_error (GPG_ERR_BAD_SECKEY);
1222 if (!err && r_keytype)
1223 *r_keytype = keytype;
1231 /* Delete the key with GRIP from the disk after having asked for
1232 confirmation using DESC_TEXT. Common error codes are:
1235 GPG_ERR_NOT_CONFIRMED
1238 agent_delete_key (ctrl_t ctrl, const char *desc_text,
1239 const unsigned char *grip)
1242 gcry_sexp_t s_skey = NULL;
1243 unsigned char *buf = NULL;
1245 char *desc_text_final = NULL;
1246 char *comment = NULL;
1247 ssh_control_file_t cf = NULL;
1248 char hexgrip[40+4+1];
1249 char *default_desc = NULL;
1251 err = read_key_file (grip, &s_skey);
1252 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1253 err = gpg_error (GPG_ERR_NO_SECKEY);
1257 err = make_canon_sexp (s_skey, &buf, &len);
1261 switch (agent_private_key_type (buf))
1263 case PRIVATE_KEY_CLEAR:
1264 case PRIVATE_KEY_PROTECTED:
1266 bin2hex (grip, 20, hexgrip);
1269 default_desc = xtryasprintf
1270 ("Do you really want to delete the key identified by keygrip%%0A"
1271 " %s%%0A %%C%%0A?", hexgrip);
1272 desc_text = default_desc;
1275 /* Note, that we will take the comment as a C string for
1276 display purposes; i.e. all stuff beyond a Nul character is
1279 gcry_sexp_t comment_sexp;
1281 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1283 comment = gcry_sexp_nth_string (comment_sexp, 1);
1284 gcry_sexp_release (comment_sexp);
1288 err = modify_description (desc_text, comment? comment:"", s_skey,
1293 err = agent_get_confirmation (ctrl, desc_text_final,
1294 _("Delete key"), _("No"), 0);
1298 cf = ssh_open_control_file ();
1301 if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
1303 err = agent_get_confirmation
1305 _("Warning: This key is also listed for use with SSH!\n"
1306 "Deleting the key might remove your ability to "
1307 "access remote machines."),
1308 _("Delete key"), _("No"), 0);
1314 err = remove_key_file (grip);
1318 case PRIVATE_KEY_SHADOWED:
1319 err = gpg_error (GPG_ERR_KEY_ON_CARD);
1323 log_error ("invalid private key format\n");
1324 err = gpg_error (GPG_ERR_BAD_SECKEY);
1329 ssh_close_control_file (cf);
1330 gcry_free (comment);
1331 xfree (desc_text_final);
1332 xfree (default_desc);
1334 gcry_sexp_release (s_skey);