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/private-keys.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 = pkc_parse (&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 = pkc_set_private_key (pk, key);
81 err = es_fseek (fp, 0, SEEK_SET);
85 err = pkc_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 (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
140 /* FIXME: Write to a temp file first so that write failures during
141 key updates won't lead to a key loss. */
143 if (!force && !access (fname, F_OK))
145 log_error ("secret key file '%s' already exists\n", fname);
147 return gpg_error (GPG_ERR_EEXIST);
150 fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw");
153 gpg_error_t tmperr = gpg_error_from_syserror ();
154 log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
159 /* See if an existing key is in extended format. */
165 if (es_fread (&first, 1, 1, fp) != 1)
167 rc = gpg_error_from_syserror ();
168 log_error ("error reading first byte from '%s': %s\n",
169 fname, strerror (errno));
175 rc = es_fseek (fp, 0, SEEK_SET);
178 log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
186 /* Key is in extended format. */
187 return write_extended_private_key (fname, fp, buffer, length);
191 if (es_fwrite (buffer, length, 1, fp) != 1)
193 gpg_error_t tmperr = gpg_error_from_syserror ();
194 log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
196 gnupg_remove (fname);
201 /* When force is given, the file might have to be truncated. */
202 if (force && ftruncate (es_fileno (fp), es_ftello (fp)))
204 gpg_error_t tmperr = gpg_error_from_syserror ();
205 log_error ("error truncating '%s': %s\n", fname, gpg_strerror (tmperr));
207 gnupg_remove (fname);
214 gpg_error_t tmperr = gpg_error_from_syserror ();
215 log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
216 gnupg_remove (fname);
220 bump_key_eventcounter ();
226 /* Callback function to try the unprotection from the passphrase query
229 try_unprotect_cb (struct pin_entry_info_s *pi)
231 struct try_unprotect_arg_s *arg = pi->check_cb_arg;
232 ctrl_t ctrl = arg->ctrl;
235 gnupg_isotime_t now, protected_at, tmptime;
238 assert (!arg->unprotected_key);
240 arg->change_required = 0;
241 err = agent_unprotect (ctrl, arg->protected_key, pi->pin, protected_at,
242 &arg->unprotected_key, &dummy);
245 if (!opt.max_passphrase_days || ctrl->in_passwd)
246 return 0; /* No regular passphrase change required. */
250 /* No protection date known - must force passphrase change. */
251 desc = xtrystrdup (L_("Note: This passphrase has never been changed.%0A"
252 "Please change it now."));
254 return gpg_error_from_syserror ();
258 gnupg_get_isotime (now);
259 gnupg_copy_time (tmptime, protected_at);
260 err = add_days_to_isotime (tmptime, opt.max_passphrase_days);
263 if (strcmp (now, tmptime) > 0 )
265 /* Passphrase "expired". */
267 (L_("This passphrase has not been changed%%0A"
268 "since %.4s-%.2s-%.2s. Please change it now."),
269 protected_at, protected_at+4, protected_at+6);
271 return gpg_error_from_syserror ();
277 /* Change required. */
278 if (opt.enforce_passphrase_constraints)
280 err = agent_get_confirmation (ctrl, desc,
281 L_("Change passphrase"), NULL, 0);
283 arg->change_required = 1;
287 err = agent_get_confirmation (ctrl, desc,
288 L_("Change passphrase"),
289 L_("I'll change it later"), 0);
291 arg->change_required = 1;
292 else if (gpg_err_code (err) == GPG_ERR_CANCELED
293 || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
303 /* Modify a Key description, replacing certain special format
304 characters. List of currently supported replacements:
306 %% - Replaced by a single %
307 %c - Replaced by the content of COMMENT.
308 %C - Same as %c but put into parentheses.
309 %F - Replaced by an ssh style fingerprint computed from KEY.
311 The functions returns 0 on success or an error code. On success a
312 newly allocated string is stored at the address of RESULT.
315 modify_description (const char *in, const char *comment, const gcry_sexp_t key,
318 size_t comment_length;
324 char *ssh_fpr = NULL;
326 comment_length = strlen (comment);
327 in_len = strlen (in);
329 /* First pass calculates the length, second pass does the actual
333 for (pass=0; pass < 2; pass++)
336 for (i = 0; i < in_len; i++)
350 case 'c': /* Comment. */
353 memcpy (out, comment, comment_length);
354 out += comment_length;
357 out_len += comment_length;
360 case 'C': /* Comment. */
366 memcpy (out, comment, comment_length);
367 out += comment_length;
371 out_len += comment_length + 2;
374 case 'F': /* SSH style fingerprint. */
376 ssh_get_fingerprint_string (key, &ssh_fpr);
380 out = stpcpy (out, ssh_fpr);
382 out_len += strlen (ssh_fpr);
386 default: /* Invalid special sequences are kept as they are. */
397 else if (in[i] == '%')
410 *result = out = xtrymalloc (out_len + 1);
414 return gpg_error_from_syserror ();
420 assert (*result + out_len == out);
427 /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
428 should be the hex encoded keygrip of that key to be used with the
429 caching mechanism. DESC_TEXT may be set to override the default
430 description used for the pinentry. If LOOKUP_TTL is given this
431 function is used to lookup the default ttl. If R_PASSPHRASE is not
432 NULL, the function succeeded and the key was protected the used
433 passphrase (entered or from the cache) is stored there; if not NULL
434 will be stored. The caller needs to free the returned
437 unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
438 unsigned char **keybuf, const unsigned char *grip,
439 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
442 struct pin_entry_info_s *pi;
443 struct try_unprotect_arg_s arg;
445 unsigned char *result;
450 *r_passphrase = NULL;
452 bin2hex (grip, 20, hexgrip);
454 /* Initially try to get it using a cache nonce. */
459 pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE);
462 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
477 /* First try to get it from the cache - if there is none or we can't
478 unprotect it, we fall back to ask the user */
479 if (cache_mode != CACHE_MODE_IGNORE)
484 pw = agent_get_cache (hexgrip, cache_mode);
487 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
490 if (cache_mode == CACHE_MODE_NORMAL)
491 agent_store_cache_hit (hexgrip);
503 else if (cache_mode == CACHE_MODE_NORMAL)
505 /* The standard use of GPG keys is to have a signing and an
506 encryption subkey. Commonly both use the same
507 passphrase. We try to help the user to enter the
508 passphrase only once by silently trying the last
509 correctly entered passphrase. Checking one additional
510 passphrase should be acceptable; despite the S2K
511 introduced delays. The assumed workflow is:
513 1. Read encrypted message in a MUA and thus enter a
514 passphrase for the encryption subkey.
516 2. Reply to that mail with an encrypted and signed
517 mail, thus entering the passphrase for the signing
520 We can often avoid the passphrase entry in the second
521 step. We do this only in normal mode, so not to
522 interfere with unrelated cache entries. */
523 pw = agent_get_cache (NULL, cache_mode);
526 rc = agent_unprotect (ctrl, *keybuf, pw, NULL,
527 &result, &resultlen);
543 /* If the pinentry is currently in use, we wait up to 60 seconds
544 for it to close and check the cache again. This solves a common
545 situation where several requests for unprotecting a key have
546 been made but the user is still entering the passphrase for
547 the first request. Because all requests to agent_askpin are
548 serialized they would then pop up one after the other to
549 request the passphrase - despite that the user has already
550 entered it and is then available in the cache. This
551 implementation is not race free but in the worst case the
552 user has to enter the passphrase only once more. */
553 if (pinentry_active_p (ctrl, 0))
556 if (!pinentry_active_p (ctrl, 60))
558 /* We need to give the other thread a chance to actually put
559 it into the cache. */
563 /* Timeout - better call pinentry now the plain way. */
567 pi = gcry_calloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
569 return gpg_error_from_syserror ();
570 pi->max_length = MAX_PASSPHRASE_LEN + 1;
571 pi->min_digits = 0; /* we want a real passphrase */
574 pi->check_cb = try_unprotect_cb;
576 arg.protected_key = *keybuf;
577 arg.unprotected_key = NULL;
578 arg.change_required = 0;
579 pi->check_cb_arg = &arg;
581 rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode);
584 assert (arg.unprotected_key);
585 if (arg.change_required)
587 /* The callback told as that the user should change their
588 passphrase. Present the dialog to do. */
589 size_t canlen, erroff;
592 assert (arg.unprotected_key);
593 canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
594 rc = gcry_sexp_sscan (&s_skey, &erroff,
595 (char*)arg.unprotected_key, canlen);
598 log_error ("failed to build S-Exp (off=%u): %s\n",
599 (unsigned int)erroff, gpg_strerror (rc));
600 wipememory (arg.unprotected_key, canlen);
601 xfree (arg.unprotected_key);
605 rc = agent_protect_and_store (ctrl, s_skey, NULL);
606 gcry_sexp_release (s_skey);
609 log_error ("changing the passphrase failed: %s\n",
611 wipememory (arg.unprotected_key, canlen);
612 xfree (arg.unprotected_key);
619 /* Passphrase is fine. */
620 agent_put_cache (hexgrip, cache_mode, pi->pin,
621 lookup_ttl? lookup_ttl (hexgrip) : 0);
622 agent_store_cache_hit (hexgrip);
623 if (r_passphrase && *pi->pin)
624 *r_passphrase = xtrystrdup (pi->pin);
627 *keybuf = arg.unprotected_key;
634 /* Read the key identified by GRIP from the private key directory and
635 return it as an gcrypt S-expression object in RESULT. On failure
636 returns an error code and stores NULL at RESULT. */
638 read_key_file (const unsigned char *grip, gcry_sexp_t *result)
645 size_t buflen, erroff;
647 char hexgrip[40+4+1];
652 bin2hex (grip, 20, hexgrip);
653 strcpy (hexgrip+40, ".key");
655 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
656 fp = es_fopen (fname, "rb");
659 rc = gpg_error_from_syserror ();
660 if (gpg_err_code (rc) != GPG_ERR_ENOENT)
661 log_error ("can't open '%s': %s\n", fname, strerror (errno));
666 if (es_fread (&first, 1, 1, fp) != 1)
668 rc = gpg_error_from_syserror ();
669 log_error ("error reading first byte from '%s': %s\n",
670 fname, strerror (errno));
676 rc = es_fseek (fp, 0, SEEK_SET);
679 log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
687 /* Key is in extended format. */
691 rc = pkc_parse (&pk, &line, fp);
695 log_error ("error parsing '%s' line %d: %s\n",
696 fname, line, gpg_strerror (rc));
699 rc = pkc_get_private_key (pk, result);
702 log_error ("error getting private key from '%s': %s\n",
703 fname, gpg_strerror (rc));
710 if (fstat (es_fileno (fp), &st))
712 rc = gpg_error_from_syserror ();
713 log_error ("can't stat '%s': %s\n", fname, strerror (errno));
720 buf = xtrymalloc (buflen+1);
723 rc = gpg_error_from_syserror ();
724 log_error ("error allocating %zu bytes for '%s': %s\n",
725 buflen, fname, strerror (errno));
733 if (es_fread (buf, buflen, 1, fp) != 1)
735 rc = gpg_error_from_syserror ();
736 log_error ("error reading %zu bytes from '%s': %s\n",
737 buflen, fname, strerror (errno));
744 /* Convert the file into a gcrypt S-expression object. */
745 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
751 log_error ("failed to build S-Exp (off=%u): %s\n",
752 (unsigned int)erroff, gpg_strerror (rc));
760 /* Remove the key identified by GRIP from the private key directory. */
762 remove_key_file (const unsigned char *grip)
766 char hexgrip[40+4+1];
768 bin2hex (grip, 20, hexgrip);
769 strcpy (hexgrip+40, ".key");
770 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
771 if (gnupg_remove (fname))
772 err = gpg_error_from_syserror ();
778 /* Return the secret key as an S-Exp in RESULT after locating it using
779 the GRIP. If the operation shall be diverted to a token, an
780 allocated S-expression with the shadow_info part from the file is
781 stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO.
782 CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
783 set to present a custom description for the pinentry. LOOKUP_TTL
784 is an optional function to convey a TTL to the cache manager; we do
785 not simply pass the TTL value because the value is only needed if
786 an unprotect action was needed and looking up the TTL may have some
787 overhead (e.g. scanning the sshcontrol file). If a CACHE_NONCE is
788 given that cache item is first tried to get a passphrase. If
789 R_PASSPHRASE is not NULL, the function succeeded and the key was
790 protected the used passphrase (entered or from the cache) is stored
791 there; if not NULL will be stored. The caller needs to free the
792 returned passphrase. */
794 agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
795 const char *desc_text,
796 const unsigned char *grip, unsigned char **shadow_info,
797 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
798 gcry_sexp_t *result, char **r_passphrase)
802 size_t len, buflen, erroff;
809 *r_passphrase = NULL;
811 rc = read_key_file (grip, &s_skey);
814 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
815 rc = gpg_error (GPG_ERR_NO_SECKEY);
819 /* For use with the protection functions we also need the key as an
820 canonical encoded S-expression in a buffer. Create this buffer
822 rc = make_canon_sexp (s_skey, &buf, &len);
826 switch (agent_private_key_type (buf))
828 case PRIVATE_KEY_CLEAR:
829 break; /* no unprotection needed */
830 case PRIVATE_KEY_OPENPGP_NONE:
832 unsigned char *buf_new;
835 rc = agent_unprotect (ctrl, buf, "", NULL, &buf_new, &buf_newlen);
837 log_error ("failed to convert unprotected openpgp key: %s\n",
846 case PRIVATE_KEY_PROTECTED:
848 char *desc_text_final;
849 char *comment = NULL;
851 /* Note, that we will take the comment as a C string for
852 display purposes; i.e. all stuff beyond a Nul character is
855 gcry_sexp_t comment_sexp;
857 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
859 comment = gcry_sexp_nth_string (comment_sexp, 1);
860 gcry_sexp_release (comment_sexp);
863 desc_text_final = NULL;
865 rc = modify_description (desc_text, comment? comment:"", s_skey,
871 rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
872 cache_mode, lookup_ttl, r_passphrase);
874 log_error ("failed to unprotect the secret key: %s\n",
878 xfree (desc_text_final);
881 case PRIVATE_KEY_SHADOWED:
884 const unsigned char *s;
887 rc = agent_get_shadow_info (buf, &s);
890 n = gcry_sexp_canon_len (s, 0, NULL,NULL);
892 *shadow_info = xtrymalloc (n);
897 memcpy (*shadow_info, s, n);
902 log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc));
905 rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
908 log_error ("invalid private key format\n");
909 rc = gpg_error (GPG_ERR_BAD_SECKEY);
912 gcry_sexp_release (s_skey);
919 xfree (*r_passphrase);
920 *r_passphrase = NULL;
925 buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL);
926 rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
927 wipememory (buf, buflen);
931 log_error ("failed to build S-Exp (off=%u): %s\n",
932 (unsigned int)erroff, gpg_strerror (rc));
935 xfree (*r_passphrase);
936 *r_passphrase = NULL;
946 /* Return the string name from the S-expression S_KEY as well as a
947 string describing the names of the parameters. ALGONAMESIZE and
948 ELEMSSIZE give the allocated size of the provided buffers. The
949 buffers may be NULL if not required. If R_LIST is not NULL the top
950 level list will be stored there; the caller needs to release it in
953 key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
954 char *r_algoname, size_t algonamesize,
955 char *r_elems, size_t elemssize)
957 gcry_sexp_t list, l2;
958 const char *name, *algoname, *elems;
964 list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
966 list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
968 list = gcry_sexp_find_token (s_key, "private-key", 0 );
971 log_error ("invalid private key format\n");
972 return gpg_error (GPG_ERR_BAD_SECKEY);
975 l2 = gcry_sexp_cadr (list);
976 gcry_sexp_release (list);
978 name = gcry_sexp_nth_data (list, 0, &n);
979 if (n==3 && !memcmp (name, "rsa", 3))
984 else if (n==3 && !memcmp (name, "dsa", 3))
989 else if (n==3 && !memcmp (name, "ecc", 3))
994 else if (n==5 && !memcmp (name, "ecdsa", 5))
999 else if (n==4 && !memcmp (name, "ecdh", 4))
1004 else if (n==3 && !memcmp (name, "elg", 3))
1011 log_error ("unknown private key algorithm\n");
1012 gcry_sexp_release (list);
1013 return gpg_error (GPG_ERR_BAD_SECKEY);
1018 if (strlen (algoname) >= algonamesize)
1019 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
1020 strcpy (r_algoname, algoname);
1024 if (strlen (elems) >= elemssize)
1025 return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
1026 strcpy (r_elems, elems);
1032 gcry_sexp_release (list);
1038 /* Return true if KEYPARMS holds an EdDSA key. */
1040 is_eddsa (gcry_sexp_t keyparms)
1048 list = gcry_sexp_find_token (keyparms, "flags", 0);
1049 for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
1051 s = gcry_sexp_nth_data (list, i, &n);
1053 continue; /* Not a data element. */
1055 if (n == 5 && !memcmp (s, "eddsa", 5))
1061 gcry_sexp_release (list);
1066 /* Return the public key algorithm number if S_KEY is a DSA style key.
1067 If it is not a DSA style key, return 0. */
1069 agent_is_dsa_key (gcry_sexp_t s_key)
1078 if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
1079 return 0; /* Error - assume it is not an DSA key. */
1081 if (!strcmp (algoname, "dsa"))
1082 result = GCRY_PK_DSA;
1083 else if (!strcmp (algoname, "ecc"))
1085 if (is_eddsa (list))
1088 result = GCRY_PK_ECDSA;
1090 else if (!strcmp (algoname, "ecdsa"))
1091 result = GCRY_PK_ECDSA;
1095 gcry_sexp_release (list);
1100 /* Return true if S_KEY is an EdDSA key as used with curve Ed25519. */
1102 agent_is_eddsa_key (gcry_sexp_t s_key)
1111 if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
1112 return 0; /* Error - assume it is not an EdDSA key. */
1114 if (!strcmp (algoname, "ecc") && is_eddsa (list))
1116 else if (!strcmp (algoname, "eddsa")) /* backward compatibility. */
1121 gcry_sexp_release (list);
1126 /* Return the key for the keygrip GRIP. The result is stored at
1127 RESULT. This function extracts the key from the private key
1128 database and returns it as an S-expression object as it is. On
1129 failure an error code is returned and NULL stored at RESULT. */
1131 agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
1132 gcry_sexp_t *result)
1141 err = read_key_file (grip, &s_skey);
1148 /* Return the public key for the keygrip GRIP. The result is stored
1149 at RESULT. This function extracts the public key from the private
1150 key database. On failure an error code is returned and NULL stored
1153 agent_public_key_from_file (ctrl_t ctrl,
1154 const unsigned char *grip,
1155 gcry_sexp_t *result)
1160 const char *algoname, *elems;
1162 gcry_mpi_t array[10];
1163 gcry_sexp_t curve = NULL;
1164 gcry_sexp_t flags = NULL;
1165 gcry_sexp_t uri_sexp, comment_sexp;
1166 const char *uri, *comment;
1167 size_t uri_length, comment_length;
1169 void *args[2+7+2+2+1]; /* Size is 2 + max. # of elements + 2 for uri + 2
1170 for comment + end-of-list. */
1172 gcry_sexp_t list = NULL;
1179 err = read_key_file (grip, &s_skey);
1183 for (i=0; i < DIM (array); i++)
1186 err = extract_private_key (s_skey, 0, &algoname, &npkey, NULL, &elems,
1187 array, DIM (array), &curve, &flags);
1190 gcry_sexp_release (s_skey);
1196 uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
1198 uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
1202 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1204 comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
1206 gcry_sexp_release (s_skey);
1210 /* FIXME: The following thing is pretty ugly code; we should
1211 investigate how to make it cleaner. Probably code to handle
1212 canonical S-expressions in a memory buffer is better suited for
1213 such a task. After all that is what we do in protect.c. Neeed
1214 to find common patterns and write a straightformward API to use
1216 assert (sizeof (size_t) <= sizeof (void*));
1218 format = xtrymalloc (15+4+7*npkey+10+15+1+1);
1221 err = gpg_error_from_syserror ();
1222 for (i=0; array[i]; i++)
1223 gcry_mpi_release (array[i]);
1224 gcry_sexp_release (curve);
1225 gcry_sexp_release (flags);
1226 gcry_sexp_release (uri_sexp);
1227 gcry_sexp_release (comment_sexp);
1232 p = stpcpy (stpcpy (format, "(public-key("), algoname);
1233 p = stpcpy (p, "%S%S"); /* curve name and flags. */
1234 args[argidx++] = &curve;
1235 args[argidx++] = &flags;
1236 for (idx=0, s=elems; idx < npkey; idx++)
1240 p = stpcpy (p, " %m)");
1241 assert (argidx < DIM (args));
1242 args[argidx++] = &array[idx];
1247 p = stpcpy (p, "(uri %b)");
1248 assert (argidx+1 < DIM (args));
1249 args[argidx++] = (void *)&uri_length;
1250 args[argidx++] = (void *)&uri;
1254 p = stpcpy (p, "(comment %b)");
1255 assert (argidx+1 < DIM (args));
1256 args[argidx++] = (void *)&comment_length;
1257 args[argidx++] = (void*)&comment;
1261 assert (argidx < DIM (args));
1262 args[argidx] = NULL;
1264 err = gcry_sexp_build_array (&list, NULL, format, args);
1266 for (i=0; array[i]; i++)
1267 gcry_mpi_release (array[i]);
1268 gcry_sexp_release (curve);
1269 gcry_sexp_release (flags);
1270 gcry_sexp_release (uri_sexp);
1271 gcry_sexp_release (comment_sexp);
1280 /* Check whether the the secret key identified by GRIP is available.
1281 Returns 0 is the key is available. */
1283 agent_key_available (const unsigned char *grip)
1287 char hexgrip[40+4+1];
1289 bin2hex (grip, 20, hexgrip);
1290 strcpy (hexgrip+40, ".key");
1292 fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);
1293 result = !access (fname, R_OK)? 0 : -1;
1300 /* Return the information about the secret key specified by the binary
1301 keygrip GRIP. If the key is a shadowed one the shadow information
1302 will be stored at the address R_SHADOW_INFO as an allocated
1305 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
1306 int *r_keytype, unsigned char **r_shadow_info)
1316 *r_keytype = PRIVATE_KEY_UNKNOWN;
1318 *r_shadow_info = NULL;
1323 err = read_key_file (grip, &sexp);
1326 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1327 return gpg_error (GPG_ERR_NOT_FOUND);
1331 err = make_canon_sexp (sexp, &buf, &len);
1332 gcry_sexp_release (sexp);
1337 keytype = agent_private_key_type (buf);
1340 case PRIVATE_KEY_CLEAR:
1341 case PRIVATE_KEY_OPENPGP_NONE:
1343 case PRIVATE_KEY_PROTECTED:
1344 /* If we ever require it we could retrieve the comment fields
1347 case PRIVATE_KEY_SHADOWED:
1350 const unsigned char *s;
1353 err = agent_get_shadow_info (buf, &s);
1356 n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1358 *r_shadow_info = xtrymalloc (n);
1359 if (!*r_shadow_info)
1360 err = gpg_error_from_syserror ();
1362 memcpy (*r_shadow_info, s, n);
1367 err = gpg_error (GPG_ERR_BAD_SECKEY);
1371 if (!err && r_keytype)
1372 *r_keytype = keytype;
1380 /* Delete the key with GRIP from the disk after having asked for
1381 confirmation using DESC_TEXT. If FORCE is set the function won't
1382 require a confirmation via Pinentry or warns if the key is also
1385 Common error codes are:
1388 GPG_ERR_NOT_CONFIRMED
1391 agent_delete_key (ctrl_t ctrl, const char *desc_text,
1392 const unsigned char *grip, int force)
1395 gcry_sexp_t s_skey = NULL;
1396 unsigned char *buf = NULL;
1398 char *desc_text_final = NULL;
1399 char *comment = NULL;
1400 ssh_control_file_t cf = NULL;
1401 char hexgrip[40+4+1];
1402 char *default_desc = NULL;
1404 err = read_key_file (grip, &s_skey);
1405 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1406 err = gpg_error (GPG_ERR_NO_SECKEY);
1410 err = make_canon_sexp (s_skey, &buf, &len);
1414 switch (agent_private_key_type (buf))
1416 case PRIVATE_KEY_CLEAR:
1417 case PRIVATE_KEY_OPENPGP_NONE:
1418 case PRIVATE_KEY_PROTECTED:
1419 bin2hex (grip, 20, hexgrip);
1424 default_desc = xtryasprintf
1425 (L_("Do you really want to delete the key identified by keygrip%%0A"
1426 " %s%%0A %%C%%0A?"), hexgrip);
1427 desc_text = default_desc;
1430 /* Note, that we will take the comment as a C string for
1431 display purposes; i.e. all stuff beyond a Nul character is
1434 gcry_sexp_t comment_sexp;
1436 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1438 comment = gcry_sexp_nth_string (comment_sexp, 1);
1439 gcry_sexp_release (comment_sexp);
1443 err = modify_description (desc_text, comment? comment:"", s_skey,
1448 err = agent_get_confirmation (ctrl, desc_text_final,
1449 L_("Delete key"), L_("No"), 0);
1453 cf = ssh_open_control_file ();
1456 if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
1458 err = agent_get_confirmation
1460 L_("Warning: This key is also listed for use with SSH!\n"
1461 "Deleting the key might remove your ability to "
1462 "access remote machines."),
1463 L_("Delete key"), L_("No"), 0);
1469 err = remove_key_file (grip);
1472 case PRIVATE_KEY_SHADOWED:
1473 err = remove_key_file (grip);
1477 log_error ("invalid private key format\n");
1478 err = gpg_error (GPG_ERR_BAD_SECKEY);
1483 ssh_close_control_file (cf);
1484 gcry_free (comment);
1485 xfree (desc_text_final);
1486 xfree (default_desc);
1488 gcry_sexp_release (s_skey);