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"
38 #include "../common/name-value.h"
44 /* Helper to pass data to the check callback of the unprotect function. */
45 struct try_unprotect_arg_s
48 const unsigned char *protected_key;
49 unsigned char *unprotected_key;
50 int change_required; /* Set by the callback to indicate that the
51 user should change the passphrase. */
56 write_extended_private_key (char *fname, estream_t fp,
57 const void *buf, size_t len)
61 gcry_sexp_t key = NULL;
65 err = nvc_parse_private_key (&pk, &line, fp);
68 log_error ("error parsing '%s' line %d: %s\n",
69 fname, line, gpg_strerror (err));
73 err = gcry_sexp_sscan (&key, NULL, buf, len);
77 err = nvc_set_private_key (pk, key);
81 err = es_fseek (fp, 0, SEEK_SET);
85 err = nvc_write (pk, fp);
88 log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
93 if (ftruncate (es_fileno (fp), es_ftello (fp)))
95 err = gpg_error_from_syserror ();
96 log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err));
103 err = gpg_error_from_syserror ();
104 log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
111 bump_key_eventcounter ();
117 gnupg_remove (fname);
119 gcry_sexp_release (key);
124 /* Write an S-expression formatted key to our key storage. With FORCE
125 passed as true an existing key with the given GRIP will get
128 agent_write_private_key (const unsigned char *grip,
129 const void *buffer, size_t length, int force)
133 char hexgrip[40+4+1];
135 bin2hex (grip, 20, hexgrip);
136 strcpy (hexgrip+40, ".key");
138 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
141 /* FIXME: Write to a temp file first so that write failures during
142 key updates won't lead to a key loss. */
144 if (!force && !access (fname, F_OK))
146 log_error ("secret key file '%s' already exists\n", fname);
148 return gpg_error (GPG_ERR_EEXIST);
151 fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw");
154 gpg_error_t tmperr = gpg_error_from_syserror ();
155 log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
160 /* See if an existing key is in extended format. */
166 if (es_fread (&first, 1, 1, fp) != 1)
168 rc = gpg_error_from_syserror ();
169 log_error ("error reading first byte from '%s': %s\n",
170 fname, strerror (errno));
176 rc = es_fseek (fp, 0, SEEK_SET);
179 log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
187 /* Key is in extended format. */
188 return write_extended_private_key (fname, fp, buffer, length);
192 if (es_fwrite (buffer, length, 1, fp) != 1)
194 gpg_error_t tmperr = gpg_error_from_syserror ();
195 log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
197 gnupg_remove (fname);
202 /* When force is given, the file might have to be truncated. */
203 if (force && ftruncate (es_fileno (fp), es_ftello (fp)))
205 gpg_error_t tmperr = gpg_error_from_syserror ();
206 log_error ("error truncating '%s': %s\n", fname, gpg_strerror (tmperr));
208 gnupg_remove (fname);
215 gpg_error_t tmperr = gpg_error_from_syserror ();
216 log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
217 gnupg_remove (fname);
221 bump_key_eventcounter ();
227 /* Callback function to try the unprotection from the passphrase query
230 try_unprotect_cb (struct pin_entry_info_s *pi)
232 struct try_unprotect_arg_s *arg = pi->check_cb_arg;
233 ctrl_t ctrl = arg->ctrl;
236 gnupg_isotime_t now, protected_at, tmptime;
239 assert (!arg->unprotected_key);
241 arg->change_required = 0;
242 err = agent_unprotect (ctrl, arg->protected_key, pi->pin, protected_at,
243 &arg->unprotected_key, &dummy);
246 if (!opt.max_passphrase_days || ctrl->in_passwd)
247 return 0; /* No regular passphrase change required. */
251 /* No protection date known - must force passphrase change. */
252 desc = xtrystrdup (L_("Note: This passphrase has never been changed.%0A"
253 "Please change it now."));
255 return gpg_error_from_syserror ();
259 gnupg_get_isotime (now);
260 gnupg_copy_time (tmptime, protected_at);
261 err = add_days_to_isotime (tmptime, opt.max_passphrase_days);
264 if (strcmp (now, tmptime) > 0 )
266 /* Passphrase "expired". */
268 (L_("This passphrase has not been changed%%0A"
269 "since %.4s-%.2s-%.2s. Please change it now."),
270 protected_at, protected_at+4, protected_at+6);
272 return gpg_error_from_syserror ();
278 /* Change required. */
279 if (opt.enforce_passphrase_constraints)
281 err = agent_get_confirmation (ctrl, desc,
282 L_("Change passphrase"), NULL, 0);
284 arg->change_required = 1;
288 err = agent_get_confirmation (ctrl, desc,
289 L_("Change passphrase"),
290 L_("I'll change it later"), 0);
292 arg->change_required = 1;
293 else if (gpg_err_code (err) == GPG_ERR_CANCELED
294 || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
304 /* Modify a Key description, replacing certain special format
305 characters. List of currently supported replacements:
307 %% - Replaced by a single %
308 %c - Replaced by the content of COMMENT.
309 %C - Same as %c but put into parentheses.
310 %F - Replaced by an ssh style fingerprint computed from KEY.
312 The functions returns 0 on success or an error code. On success a
313 newly allocated string is stored at the address of RESULT.
316 modify_description (const char *in, const char *comment, const gcry_sexp_t key,
319 size_t comment_length;
325 char *ssh_fpr = NULL;
327 comment_length = strlen (comment);
328 in_len = strlen (in);
330 /* First pass calculates the length, second pass does the actual
334 for (pass=0; pass < 2; pass++)
337 for (i = 0; i < in_len; i++)
351 case 'c': /* Comment. */
354 memcpy (out, comment, comment_length);
355 out += comment_length;
358 out_len += comment_length;
361 case 'C': /* Comment. */
367 memcpy (out, comment, comment_length);
368 out += comment_length;
372 out_len += comment_length + 2;
375 case 'F': /* SSH style fingerprint. */
377 ssh_get_fingerprint_string (key, &ssh_fpr);
381 out = stpcpy (out, ssh_fpr);
383 out_len += strlen (ssh_fpr);
387 default: /* Invalid special sequences are kept as they are. */
398 else if (in[i] == '%')
411 *result = out = xtrymalloc (out_len + 1);
415 return gpg_error_from_syserror ();
421 assert (*result + out_len == out);
428 /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
429 should be the hex encoded keygrip of that key to be used with the
430 caching mechanism. DESC_TEXT may be set to override the default
431 description used for the pinentry. If LOOKUP_TTL is given this
432 function is used to lookup the default ttl. If R_PASSPHRASE is not
433 NULL, the function succeeded and the key was protected the used
434 passphrase (entered or from the cache) is stored there; if not NULL
435 will be stored. The caller needs to free the returned
438 unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
439 unsigned char **keybuf, const unsigned char *grip,
440 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
443 struct pin_entry_info_s *pi;
444 struct try_unprotect_arg_s arg;
446 unsigned char *result;
451 *r_passphrase = NULL;
453 bin2hex (grip, 20, hexgrip);
455 /* Initially try to get it using a cache nonce. */
460 pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
463 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
478 /* First try to get it from the cache - if there is none or we can't
479 unprotect it, we fall back to ask the user */
480 if (cache_mode != CACHE_MODE_IGNORE)
485 pw = agent_get_cache (hexgrip, cache_mode);
488 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
491 if (cache_mode == CACHE_MODE_NORMAL)
492 agent_store_cache_hit (hexgrip);
504 else if (cache_mode == CACHE_MODE_NORMAL)
506 /* The standard use of GPG keys is to have a signing and an
507 encryption subkey. Commonly both use the same
508 passphrase. We try to help the user to enter the
509 passphrase only once by silently trying the last
510 correctly entered passphrase. Checking one additional
511 passphrase should be acceptable; despite the S2K
512 introduced delays. The assumed workflow is:
514 1. Read encrypted message in a MUA and thus enter a
515 passphrase for the encryption subkey.
517 2. Reply to that mail with an encrypted and signed
518 mail, thus entering the passphrase for the signing
521 We can often avoid the passphrase entry in the second
522 step. We do this only in normal mode, so not to
523 interfere with unrelated cache entries. */
524 pw = agent_get_cache (NULL, cache_mode);
527 rc = agent_unprotect (ctrl, *keybuf, pw, NULL,
528 &result, &resultlen);
544 /* If the pinentry is currently in use, we wait up to 60 seconds
545 for it to close and check the cache again. This solves a common
546 situation where several requests for unprotecting a key have
547 been made but the user is still entering the passphrase for
548 the first request. Because all requests to agent_askpin are
549 serialized they would then pop up one after the other to
550 request the passphrase - despite that the user has already
551 entered it and is then available in the cache. This
552 implementation is not race free but in the worst case the
553 user has to enter the passphrase only once more. */
554 if (pinentry_active_p (ctrl, 0))
557 if (!pinentry_active_p (ctrl, 60))
559 /* We need to give the other thread a chance to actually put
560 it into the cache. */
564 /* Timeout - better call pinentry now the plain way. */
568 pi = gcry_calloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
570 return gpg_error_from_syserror ();
571 pi->max_length = MAX_PASSPHRASE_LEN + 1;
572 pi->min_digits = 0; /* we want a real passphrase */
575 pi->check_cb = try_unprotect_cb;
577 arg.protected_key = *keybuf;
578 arg.unprotected_key = NULL;
579 arg.change_required = 0;
580 pi->check_cb_arg = &arg;
582 rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode);
585 assert (arg.unprotected_key);
586 if (arg.change_required)
588 /* The callback told as that the user should change their
589 passphrase. Present the dialog to do. */
590 size_t canlen, erroff;
593 assert (arg.unprotected_key);
594 canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
595 rc = gcry_sexp_sscan (&s_skey, &erroff,
596 (char*)arg.unprotected_key, canlen);
599 log_error ("failed to build S-Exp (off=%u): %s\n",
600 (unsigned int)erroff, gpg_strerror (rc));
601 wipememory (arg.unprotected_key, canlen);
602 xfree (arg.unprotected_key);
606 rc = agent_protect_and_store (ctrl, s_skey, NULL);
607 gcry_sexp_release (s_skey);
610 log_error ("changing the passphrase failed: %s\n",
612 wipememory (arg.unprotected_key, canlen);
613 xfree (arg.unprotected_key);
620 /* Passphrase is fine. */
621 agent_put_cache (hexgrip, cache_mode, pi->pin,
622 lookup_ttl? lookup_ttl (hexgrip) : 0);
623 agent_store_cache_hit (hexgrip);
624 if (r_passphrase && *pi->pin)
625 *r_passphrase = xtrystrdup (pi->pin);
628 *keybuf = arg.unprotected_key;
635 /* Read the key identified by GRIP from the private key directory and
636 return it as an gcrypt S-expression object in RESULT. On failure
637 returns an error code and stores NULL at RESULT. */
639 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
646 size_t buflen, erroff;
648 char hexgrip[40+4+1];
653 bin2hex (grip, 20, hexgrip);
654 strcpy (hexgrip+40, ".key");
656 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
658 fp = es_fopen (fname, "rb");
661 rc = gpg_error_from_syserror ();
662 if (gpg_err_code (rc) != GPG_ERR_ENOENT)
663 log_error ("can't open '%s': %s\n", fname, strerror (errno));
668 if (es_fread (&first, 1, 1, fp) != 1)
670 rc = gpg_error_from_syserror ();
671 log_error ("error reading first byte from '%s': %s\n",
672 fname, strerror (errno));
678 rc = es_fseek (fp, 0, SEEK_SET);
681 log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
689 /* Key is in extended format. */
693 rc = nvc_parse_private_key (&pk, &line, fp);
697 log_error ("error parsing '%s' line %d: %s\n",
698 fname, line, gpg_strerror (rc));
701 rc = nvc_get_private_key (pk, result);
704 log_error ("error getting private key from '%s': %s\n",
705 fname, gpg_strerror (rc));
712 if (fstat (es_fileno (fp), &st))
714 rc = gpg_error_from_syserror ();
715 log_error ("can't stat '%s': %s\n", fname, strerror (errno));
722 buf = xtrymalloc (buflen+1);
725 rc = gpg_error_from_syserror ();
726 log_error ("error allocating %zu bytes for '%s': %s\n",
727 buflen, fname, strerror (errno));
735 if (es_fread (buf, buflen, 1, fp) != 1)
737 rc = gpg_error_from_syserror ();
738 log_error ("error reading %zu bytes from '%s': %s\n",
739 buflen, fname, strerror (errno));
746 /* Convert the file into a gcrypt S-expression object. */
747 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
753 log_error ("failed to build S-Exp (off=%u): %s\n",
754 (unsigned int)erroff, gpg_strerror (rc));
762 /* Remove the key identified by GRIP from the private key directory. */
764 remove_key_file (const unsigned char *grip)
768 char hexgrip[40+4+1];
770 bin2hex (grip, 20, hexgrip);
771 strcpy (hexgrip+40, ".key");
772 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
774 if (gnupg_remove (fname))
775 err = gpg_error_from_syserror ();
781 /* Return the secret key as an S-Exp in RESULT after locating it using
782 the GRIP. If the operation shall be diverted to a token, an
783 allocated S-expression with the shadow_info part from the file is
784 stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO.
785 CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
786 set to present a custom description for the pinentry. LOOKUP_TTL
787 is an optional function to convey a TTL to the cache manager; we do
788 not simply pass the TTL value because the value is only needed if
789 an unprotect action was needed and looking up the TTL may have some
790 overhead (e.g. scanning the sshcontrol file). If a CACHE_NONCE is
791 given that cache item is first tried to get a passphrase. If
792 R_PASSPHRASE is not NULL, the function succeeded and the key was
793 protected the used passphrase (entered or from the cache) is stored
794 there; if not NULL will be stored. The caller needs to free the
795 returned passphrase. */
797 agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
798 const char *desc_text,
799 const unsigned char *grip, unsigned char **shadow_info,
800 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
801 gcry_sexp_t *result, char **r_passphrase)
805 size_t len, buflen, erroff;
812 *r_passphrase = NULL;
814 rc = read_key_file (grip, &s_skey);
817 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
818 rc = gpg_error (GPG_ERR_NO_SECKEY);
822 /* For use with the protection functions we also need the key as an
823 canonical encoded S-expression in a buffer. Create this buffer
825 rc = make_canon_sexp (s_skey, &buf, &len);
829 switch (agent_private_key_type (buf))
831 case PRIVATE_KEY_CLEAR:
832 break; /* no unprotection needed */
833 case PRIVATE_KEY_OPENPGP_NONE:
835 unsigned char *buf_new;
838 rc = agent_unprotect (ctrl, buf, "", NULL, &buf_new, &buf_newlen);
840 log_error ("failed to convert unprotected openpgp key: %s\n",
849 case PRIVATE_KEY_PROTECTED:
851 char *desc_text_final;
852 char *comment = NULL;
854 /* Note, that we will take the comment as a C string for
855 display purposes; i.e. all stuff beyond a Nul character is
858 gcry_sexp_t comment_sexp;
860 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
862 comment = gcry_sexp_nth_string (comment_sexp, 1);
863 gcry_sexp_release (comment_sexp);
866 desc_text_final = NULL;
868 rc = modify_description (desc_text, comment? comment:"", s_skey,
874 rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
875 cache_mode, lookup_ttl, r_passphrase);
877 log_error ("failed to unprotect the secret key: %s\n",
881 xfree (desc_text_final);
884 case PRIVATE_KEY_SHADOWED:
887 const unsigned char *s;
890 rc = agent_get_shadow_info (buf, &s);
893 n = gcry_sexp_canon_len (s, 0, NULL,NULL);
895 *shadow_info = xtrymalloc (n);
900 memcpy (*shadow_info, s, n);
905 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
908 rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
911 log_error ("invalid private key format\n");
912 rc = gpg_error (GPG_ERR_BAD_SECKEY);
915 gcry_sexp_release (s_skey);
922 xfree (*r_passphrase);
923 *r_passphrase = NULL;
928 buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
929 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
930 wipememory (buf, buflen);
934 log_error ("failed to build S-Exp (off=%u): %s\n",
935 (unsigned int)erroff, gpg_strerror (rc));
938 xfree (*r_passphrase);
939 *r_passphrase = NULL;
949 /* Return the string name from the S-expression S_KEY as well as a
950 string describing the names of the parameters. ALGONAMESIZE and
951 ELEMSSIZE give the allocated size of the provided buffers. The
952 buffers may be NULL if not required. If R_LIST is not NULL the top
953 level list will be stored there; the caller needs to release it in
956 key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
957 char *r_algoname, size_t algonamesize,
958 char *r_elems, size_t elemssize)
960 gcry_sexp_t list, l2;
961 const char *name, *algoname, *elems;
967 list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
969 list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
971 list = gcry_sexp_find_token (s_key, "private-key", 0 );
974 log_error ("invalid private key format\n");
975 return gpg_error (GPG_ERR_BAD_SECKEY);
978 l2 = gcry_sexp_cadr (list);
979 gcry_sexp_release (list);
981 name = gcry_sexp_nth_data (list, 0, &n);
982 if (n==3 && !memcmp (name, "rsa", 3))
987 else if (n==3 && !memcmp (name, "dsa", 3))
992 else if (n==3 && !memcmp (name, "ecc", 3))
997 else if (n==5 && !memcmp (name, "ecdsa", 5))
1002 else if (n==4 && !memcmp (name, "ecdh", 4))
1007 else if (n==3 && !memcmp (name, "elg", 3))
1014 log_error ("unknown private key algorithm\n");
1015 gcry_sexp_release (list);
1016 return gpg_error (GPG_ERR_BAD_SECKEY);
1021 if (strlen (algoname) >= algonamesize)
1022 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
1023 strcpy (r_algoname, algoname);
1027 if (strlen (elems) >= elemssize)
1028 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
1029 strcpy (r_elems, elems);
1035 gcry_sexp_release (list);
1041 /* Return true if KEYPARMS holds an EdDSA key. */
1043 is_eddsa (gcry_sexp_t keyparms)
1051 list = gcry_sexp_find_token (keyparms, "flags", 0);
1052 for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
1054 s = gcry_sexp_nth_data (list, i, &n);
1056 continue; /* Not a data element. */
1058 if (n == 5 && !memcmp (s, "eddsa", 5))
1064 gcry_sexp_release (list);
1069 /* Return the public key algorithm number if S_KEY is a DSA style key.
1070 If it is not a DSA style key, return 0. */
1072 agent_is_dsa_key (gcry_sexp_t s_key)
1081 if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
1082 return 0; /* Error - assume it is not an DSA key. */
1084 if (!strcmp (algoname, "dsa"))
1085 result = GCRY_PK_DSA;
1086 else if (!strcmp (algoname, "ecc"))
1088 if (is_eddsa (list))
1091 result = GCRY_PK_ECDSA;
1093 else if (!strcmp (algoname, "ecdsa"))
1094 result = GCRY_PK_ECDSA;
1098 gcry_sexp_release (list);
1103 /* Return true if S_KEY is an EdDSA key as used with curve Ed25519. */
1105 agent_is_eddsa_key (gcry_sexp_t s_key)
1114 if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
1115 return 0; /* Error - assume it is not an EdDSA key. */
1117 if (!strcmp (algoname, "ecc") && is_eddsa (list))
1119 else if (!strcmp (algoname, "eddsa")) /* backward compatibility. */
1124 gcry_sexp_release (list);
1129 /* Return the key for the keygrip GRIP. The result is stored at
1130 RESULT. This function extracts the key from the private key
1131 database and returns it as an S-expression object as it is. On
1132 failure an error code is returned and NULL stored at RESULT. */
1134 agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
1135 gcry_sexp_t *result)
1144 err = read_key_file (grip, &s_skey);
1151 /* Return the public key for the keygrip GRIP. The result is stored
1152 at RESULT. This function extracts the public key from the private
1153 key database. On failure an error code is returned and NULL stored
1156 agent_public_key_from_file (ctrl_t ctrl,
1157 const unsigned char *grip,
1158 gcry_sexp_t *result)
1163 const char *algoname, *elems;
1165 gcry_mpi_t array[10];
1166 gcry_sexp_t curve = NULL;
1167 gcry_sexp_t flags = NULL;
1168 gcry_sexp_t uri_sexp, comment_sexp;
1169 const char *uri, *comment;
1170 size_t uri_length, comment_length;
1172 void *args[2+7+2+2+1]; /* Size is 2 + max. # of elements + 2 for uri + 2
1173 for comment + end-of-list. */
1175 gcry_sexp_t list = NULL;
1182 err = read_key_file (grip, &s_skey);
1186 for (i=0; i < DIM (array); i++)
1189 err = extract_private_key (s_skey, 0, &algoname, &npkey, NULL, &elems,
1190 array, DIM (array), &curve, &flags);
1193 gcry_sexp_release (s_skey);
1199 uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
1201 uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
1205 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1207 comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
1209 gcry_sexp_release (s_skey);
1213 /* FIXME: The following thing is pretty ugly code; we should
1214 investigate how to make it cleaner. Probably code to handle
1215 canonical S-expressions in a memory buffer is better suited for
1216 such a task. After all that is what we do in protect.c. Neeed
1217 to find common patterns and write a straightformward API to use
1219 assert (sizeof (size_t) <= sizeof (void*));
1221 format = xtrymalloc (15+4+7*npkey+10+15+1+1);
1224 err = gpg_error_from_syserror ();
1225 for (i=0; array[i]; i++)
1226 gcry_mpi_release (array[i]);
1227 gcry_sexp_release (curve);
1228 gcry_sexp_release (flags);
1229 gcry_sexp_release (uri_sexp);
1230 gcry_sexp_release (comment_sexp);
1235 p = stpcpy (stpcpy (format, "(public-key("), algoname);
1236 p = stpcpy (p, "%S%S"); /* curve name and flags. */
1237 args[argidx++] = &curve;
1238 args[argidx++] = &flags;
1239 for (idx=0, s=elems; idx < npkey; idx++)
1243 p = stpcpy (p, " %m)");
1244 assert (argidx < DIM (args));
1245 args[argidx++] = &array[idx];
1250 p = stpcpy (p, "(uri %b)");
1251 assert (argidx+1 < DIM (args));
1252 args[argidx++] = (void *)&uri_length;
1253 args[argidx++] = (void *)&uri;
1257 p = stpcpy (p, "(comment %b)");
1258 assert (argidx+1 < DIM (args));
1259 args[argidx++] = (void *)&comment_length;
1260 args[argidx++] = (void*)&comment;
1264 assert (argidx < DIM (args));
1265 args[argidx] = NULL;
1267 err = gcry_sexp_build_array (&list, NULL, format, args);
1269 for (i=0; array[i]; i++)
1270 gcry_mpi_release (array[i]);
1271 gcry_sexp_release (curve);
1272 gcry_sexp_release (flags);
1273 gcry_sexp_release (uri_sexp);
1274 gcry_sexp_release (comment_sexp);
1283 /* Check whether the the secret key identified by GRIP is available.
1284 Returns 0 is the key is available. */
1286 agent_key_available (const unsigned char *grip)
1290 char hexgrip[40+4+1];
1292 bin2hex (grip, 20, hexgrip);
1293 strcpy (hexgrip+40, ".key");
1295 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
1297 result = !access (fname, R_OK)? 0 : -1;
1304 /* Return the information about the secret key specified by the binary
1305 keygrip GRIP. If the key is a shadowed one the shadow information
1306 will be stored at the address R_SHADOW_INFO as an allocated
1309 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
1310 int *r_keytype, unsigned char **r_shadow_info)
1320 *r_keytype = PRIVATE_KEY_UNKNOWN;
1322 *r_shadow_info = NULL;
1327 err = read_key_file (grip, &sexp);
1330 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1331 return gpg_error (GPG_ERR_NOT_FOUND);
1335 err = make_canon_sexp (sexp, &buf, &len);
1336 gcry_sexp_release (sexp);
1341 keytype = agent_private_key_type (buf);
1344 case PRIVATE_KEY_CLEAR:
1345 case PRIVATE_KEY_OPENPGP_NONE:
1347 case PRIVATE_KEY_PROTECTED:
1348 /* If we ever require it we could retrieve the comment fields
1351 case PRIVATE_KEY_SHADOWED:
1354 const unsigned char *s;
1357 err = agent_get_shadow_info (buf, &s);
1360 n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1362 *r_shadow_info = xtrymalloc (n);
1363 if (!*r_shadow_info)
1364 err = gpg_error_from_syserror ();
1366 memcpy (*r_shadow_info, s, n);
1371 err = gpg_error (GPG_ERR_BAD_SECKEY);
1375 if (!err && r_keytype)
1376 *r_keytype = keytype;
1384 /* Delete the key with GRIP from the disk after having asked for
1385 confirmation using DESC_TEXT. If FORCE is set the function won't
1386 require a confirmation via Pinentry or warns if the key is also
1389 Common error codes are:
1392 GPG_ERR_NOT_CONFIRMED
1395 agent_delete_key (ctrl_t ctrl, const char *desc_text,
1396 const unsigned char *grip, int force)
1399 gcry_sexp_t s_skey = NULL;
1400 unsigned char *buf = NULL;
1402 char *desc_text_final = NULL;
1403 char *comment = NULL;
1404 ssh_control_file_t cf = NULL;
1405 char hexgrip[40+4+1];
1406 char *default_desc = NULL;
1408 err = read_key_file (grip, &s_skey);
1409 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1410 err = gpg_error (GPG_ERR_NO_SECKEY);
1414 err = make_canon_sexp (s_skey, &buf, &len);
1418 switch (agent_private_key_type (buf))
1420 case PRIVATE_KEY_CLEAR:
1421 case PRIVATE_KEY_OPENPGP_NONE:
1422 case PRIVATE_KEY_PROTECTED:
1423 bin2hex (grip, 20, hexgrip);
1428 default_desc = xtryasprintf
1429 (L_("Do you really want to delete the key identified by keygrip%%0A"
1430 " %s%%0A %%C%%0A?"), hexgrip);
1431 desc_text = default_desc;
1434 /* Note, that we will take the comment as a C string for
1435 display purposes; i.e. all stuff beyond a Nul character is
1438 gcry_sexp_t comment_sexp;
1440 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1442 comment = gcry_sexp_nth_string (comment_sexp, 1);
1443 gcry_sexp_release (comment_sexp);
1447 err = modify_description (desc_text, comment? comment:"", s_skey,
1452 err = agent_get_confirmation (ctrl, desc_text_final,
1453 L_("Delete key"), L_("No"), 0);
1457 cf = ssh_open_control_file ();
1460 if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
1462 err = agent_get_confirmation
1464 L_("Warning: This key is also listed for use with SSH!\n"
1465 "Deleting the key might remove your ability to "
1466 "access remote machines."),
1467 L_("Delete key"), L_("No"), 0);
1473 err = remove_key_file (grip);
1476 case PRIVATE_KEY_SHADOWED:
1477 err = remove_key_file (grip);
1481 log_error ("invalid private key format\n");
1482 err = gpg_error (GPG_ERR_BAD_SECKEY);
1487 ssh_close_control_file (cf);
1488 gcry_free (comment);
1489 xfree (desc_text_final);
1490 xfree (default_desc);
1492 gcry_sexp_release (s_skey);