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, 2019 Werner Koch
5 *
6 * This file is part of GnuPG.
7 *
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.
12 *
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.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <npth.h> /* (we use pth_sleep) */
32
33 #include "agent.h"
34 #include "../common/i18n.h"
35 #include "../common/ssh-utils.h"
36 #include "../common/name-value.h"
37
38 #ifndef O_BINARY
39 #define O_BINARY 0
40 #endif
41
42 /* Helper to pass data to the check callback of the unprotect function. */
43 struct try_unprotect_arg_s
44 {
45 ctrl_t ctrl;
46 const unsigned char *protected_key;
47 unsigned char *unprotected_key;
48 int change_required; /* Set by the callback to indicate that the
49 user should change the passphrase. */
50 };
51
52
53 /* Repalce all linefeeds in STRING by "%0A" and return a new malloced
54 * string. May return NULL on memory error. */
55 static char *
linefeed_to_percent0A(const char * string)56 linefeed_to_percent0A (const char *string)
57 {
58 const char *s;
59 size_t n;
60 char *buf, *p;
61
62 for (n=0, s=string; *s; s++)
63 if (*s == '\n')
64 n += 3;
65 else
66 n++;
67 p = buf = xtrymalloc (n+1);
68 if (!buf)
69 return NULL;
70 for (s=string; *s; s++)
71 if (*s == '\n')
72 {
73 memcpy (p, "%0A", 3);
74 p += 3;
75 }
76 else
77 *p++ = *s;
78 *p = 0;
79 return buf;
80 }
81
82
83 /* Note: Ownership of FNAME and FP are moved to this function. */
84 static gpg_error_t
write_extended_private_key(char * fname,estream_t fp,int update,int newkey,const void * buf,size_t len,const char * serialno,const char * keyref,time_t timestamp)85 write_extended_private_key (char *fname, estream_t fp, int update, int newkey,
86 const void *buf, size_t len,
87 const char *serialno, const char *keyref,
88 time_t timestamp)
89 {
90 gpg_error_t err;
91 nvc_t pk = NULL;
92 gcry_sexp_t key = NULL;
93 int remove = 0;
94 char *token = NULL;
95
96 if (update)
97 {
98 int line;
99
100 err = nvc_parse_private_key (&pk, &line, fp);
101 if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
102 {
103 log_error ("error parsing '%s' line %d: %s\n",
104 fname, line, gpg_strerror (err));
105 goto leave;
106 }
107 }
108 else
109 {
110 pk = nvc_new_private_key ();
111 if (!pk)
112 {
113 err = gpg_error_from_syserror ();
114 goto leave;
115 }
116 }
117 es_clearerr (fp);
118
119 err = gcry_sexp_sscan (&key, NULL, buf, len);
120 if (err)
121 goto leave;
122
123 err = nvc_set_private_key (pk, key);
124 if (err)
125 goto leave;
126
127 /* If requested write a Token line. */
128 if (serialno && keyref)
129 {
130 nve_t item;
131 const char *s;
132
133 token = strconcat (serialno, " ", keyref, NULL);
134 if (!token)
135 {
136 err = gpg_error_from_syserror ();
137 goto leave;
138 }
139
140 /* fixme: the strcmp should compare only the first two strings. */
141 for (item = nvc_lookup (pk, "Token:");
142 item;
143 item = nve_next_value (item, "Token:"))
144 if ((s = nve_value (item)) && !strcmp (s, token))
145 break;
146 if (!item)
147 {
148 /* No token or no token with that value exists. Add a new
149 * one so that keys which have been stored on several cards
150 * are well supported. */
151 err = nvc_add (pk, "Token:", token);
152 if (err)
153 goto leave;
154 }
155 }
156
157 /* If a timestamp has been supplied and the key is new write a
158 * creation timestamp. (We douple check that there is no Created
159 * item yet.)*/
160 if (timestamp && newkey && !nvc_lookup (pk, "Created:"))
161 {
162 gnupg_isotime_t timebuf;
163
164 epoch2isotime (timebuf, timestamp);
165 err = nvc_add (pk, "Created:", timebuf);
166 if (err)
167 goto leave;
168 }
169
170
171 err = es_fseek (fp, 0, SEEK_SET);
172 if (err)
173 goto leave;
174
175 err = nvc_write (pk, fp);
176 if (err)
177 {
178 log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
179 remove = 1;
180 goto leave;
181 }
182
183 if (ftruncate (es_fileno (fp), es_ftello (fp)))
184 {
185 err = gpg_error_from_syserror ();
186 log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err));
187 remove = 1;
188 goto leave;
189 }
190
191 if (es_fclose (fp))
192 {
193 err = gpg_error_from_syserror ();
194 log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
195 remove = 1;
196 goto leave;
197 }
198 else
199 fp = NULL;
200
201 bump_key_eventcounter ();
202
203 leave:
204 es_fclose (fp);
205 if (remove)
206 gnupg_remove (fname);
207 xfree (fname);
208 gcry_sexp_release (key);
209 nvc_release (pk);
210 xfree (token);
211 return err;
212 }
213
214 /* Write an S-expression formatted key to our key storage. With FORCE
215 * passed as true an existing key with the given GRIP will get
216 * overwritten. If SERIALNO and KEYREF are given a Token line is
217 * added to the key if the extended format is used. If TIMESTAMP is
218 * not zero and the key doies not yet exists it will be recorded as
219 * creation date. */
220 int
agent_write_private_key(const unsigned char * grip,const void * buffer,size_t length,int force,const char * serialno,const char * keyref,time_t timestamp)221 agent_write_private_key (const unsigned char *grip,
222 const void *buffer, size_t length, int force,
223 const char *serialno, const char *keyref,
224 time_t timestamp)
225 {
226 char *fname;
227 estream_t fp;
228 char hexgrip[40+4+1];
229
230 bin2hex (grip, 20, hexgrip);
231 strcpy (hexgrip+40, ".key");
232
233 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
234 hexgrip, NULL);
235
236 /* FIXME: Write to a temp file first so that write failures during
237 key updates won't lead to a key loss. */
238
239 if (!force && !gnupg_access (fname, F_OK))
240 {
241 log_error ("secret key file '%s' already exists\n", fname);
242 xfree (fname);
243 return gpg_error (GPG_ERR_EEXIST);
244 }
245
246 fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw");
247 if (!fp)
248 {
249 gpg_error_t tmperr = gpg_error_from_syserror ();
250
251 if (force && gpg_err_code (tmperr) == GPG_ERR_ENOENT)
252 {
253 fp = es_fopen (fname, "wbx,mode=-rw");
254 if (!fp)
255 tmperr = gpg_error_from_syserror ();
256 }
257 if (!fp)
258 {
259 log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
260 xfree (fname);
261 return tmperr;
262 }
263 }
264 else if (force)
265 {
266 gpg_error_t rc;
267 char first;
268
269 /* See if an existing key is in extended format. */
270 if (es_fread (&first, 1, 1, fp) != 1)
271 {
272 rc = gpg_error_from_syserror ();
273 log_error ("error reading first byte from '%s': %s\n",
274 fname, strerror (errno));
275 xfree (fname);
276 es_fclose (fp);
277 return rc;
278 }
279
280 rc = es_fseek (fp, 0, SEEK_SET);
281 if (rc)
282 {
283 log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
284 xfree (fname);
285 es_fclose (fp);
286 return rc;
287 }
288
289 if (first != '(')
290 {
291 /* Key is already in the extended format. */
292 return write_extended_private_key (fname, fp, 1, 0, buffer, length,
293 serialno, keyref, timestamp);
294 }
295 if (first == '(' && opt.enable_extended_key_format)
296 {
297 /* Key is in the old format - but we want the extended format. */
298 return write_extended_private_key (fname, fp, 0, 0, buffer, length,
299 serialno, keyref, timestamp);
300 }
301 }
302
303 if (opt.enable_extended_key_format)
304 return write_extended_private_key (fname, fp, 0, 1, buffer, length,
305 serialno, keyref, timestamp);
306
307 if (es_fwrite (buffer, length, 1, fp) != 1)
308 {
309 gpg_error_t tmperr = gpg_error_from_syserror ();
310 log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
311 es_fclose (fp);
312 gnupg_remove (fname);
313 xfree (fname);
314 return tmperr;
315 }
316
317 /* When force is given, the file might have to be truncated. */
318 if (force && ftruncate (es_fileno (fp), es_ftello (fp)))
319 {
320 gpg_error_t tmperr = gpg_error_from_syserror ();
321 log_error ("error truncating '%s': %s\n", fname, gpg_strerror (tmperr));
322 es_fclose (fp);
323 gnupg_remove (fname);
324 xfree (fname);
325 return tmperr;
326 }
327
328 if (es_fclose (fp))
329 {
330 gpg_error_t tmperr = gpg_error_from_syserror ();
331 log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
332 gnupg_remove (fname);
333 xfree (fname);
334 return tmperr;
335 }
336 bump_key_eventcounter ();
337 xfree (fname);
338 return 0;
339 }
340
341
342 /* Callback function to try the unprotection from the passphrase query
343 code. */
344 static gpg_error_t
try_unprotect_cb(struct pin_entry_info_s * pi)345 try_unprotect_cb (struct pin_entry_info_s *pi)
346 {
347 struct try_unprotect_arg_s *arg = pi->check_cb_arg;
348 ctrl_t ctrl = arg->ctrl;
349 size_t dummy;
350 gpg_error_t err;
351 gnupg_isotime_t now, protected_at, tmptime;
352 char *desc = NULL;
353
354 log_assert (!arg->unprotected_key);
355
356 arg->change_required = 0;
357 err = agent_unprotect (ctrl, arg->protected_key, pi->pin, protected_at,
358 &arg->unprotected_key, &dummy);
359 if (err)
360 return err;
361 if (!opt.max_passphrase_days || ctrl->in_passwd)
362 return 0; /* No regular passphrase change required. */
363
364 if (!*protected_at)
365 {
366 /* No protection date known - must force passphrase change. */
367 desc = xtrystrdup (L_("Note: This passphrase has never been changed.%0A"
368 "Please change it now."));
369 if (!desc)
370 return gpg_error_from_syserror ();
371 }
372 else
373 {
374 gnupg_get_isotime (now);
375 gnupg_copy_time (tmptime, protected_at);
376 err = add_days_to_isotime (tmptime, opt.max_passphrase_days);
377 if (err)
378 return err;
379 if (strcmp (now, tmptime) > 0 )
380 {
381 /* Passphrase "expired". */
382 desc = xtryasprintf
383 (L_("This passphrase has not been changed%%0A"
384 "since %.4s-%.2s-%.2s. Please change it now."),
385 protected_at, protected_at+4, protected_at+6);
386 if (!desc)
387 return gpg_error_from_syserror ();
388 }
389 }
390
391 if (desc)
392 {
393 /* Change required. */
394 if (opt.enforce_passphrase_constraints)
395 {
396 err = agent_get_confirmation (ctrl, desc,
397 L_("Change passphrase"), NULL, 0);
398 if (!err)
399 arg->change_required = 1;
400 }
401 else
402 {
403 err = agent_get_confirmation (ctrl, desc,
404 L_("Change passphrase"),
405 L_("I'll change it later"), 0);
406 if (!err)
407 arg->change_required = 1;
408 else if (gpg_err_code (err) == GPG_ERR_CANCELED
409 || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
410 err = 0;
411 }
412 xfree (desc);
413 }
414
415 return err;
416 }
417
418
419 /* Return true if the STRING has an %C or %c expando. */
420 static int
has_comment_expando(const char * string)421 has_comment_expando (const char *string)
422 {
423 const char *s;
424 int percent = 0;
425
426 if (!string)
427 return 0;
428
429 for (s = string; *s; s++)
430 {
431 if (percent)
432 {
433 if (*s == 'c' || *s == 'C')
434 return 1;
435 percent = 0;
436 }
437 else if (*s == '%')
438 percent = 1;
439 }
440 return 0;
441 }
442
443
444
445
446 /* Modify a Key description, replacing certain special format
447 characters. List of currently supported replacements:
448
449 %% - Replaced by a single %
450 %c - Replaced by the content of COMMENT.
451 %C - Same as %c but put into parentheses.
452 %F - Replaced by an ssh style fingerprint computed from KEY.
453
454 The functions returns 0 on success or an error code. On success a
455 newly allocated string is stored at the address of RESULT.
456 */
457 gpg_error_t
agent_modify_description(const char * in,const char * comment,const gcry_sexp_t key,char ** result)458 agent_modify_description (const char *in, const char *comment,
459 const gcry_sexp_t key, char **result)
460 {
461 size_t comment_length;
462 size_t in_len;
463 size_t out_len;
464 char *out;
465 size_t i;
466 int special, pass;
467 char *ssh_fpr = NULL;
468 char *p;
469
470 *result = NULL;
471
472 if (!comment)
473 comment = "";
474
475 comment_length = strlen (comment);
476 in_len = strlen (in);
477
478 /* First pass calculates the length, second pass does the actual
479 copying. */
480 /* FIXME: This can be simplified by using es_fopenmem. */
481 out = NULL;
482 out_len = 0;
483 for (pass=0; pass < 2; pass++)
484 {
485 special = 0;
486 for (i = 0; i < in_len; i++)
487 {
488 if (special)
489 {
490 special = 0;
491 switch (in[i])
492 {
493 case '%':
494 if (out)
495 *out++ = '%';
496 else
497 out_len++;
498 break;
499
500 case 'c': /* Comment. */
501 if (out)
502 {
503 memcpy (out, comment, comment_length);
504 out += comment_length;
505 }
506 else
507 out_len += comment_length;
508 break;
509
510 case 'C': /* Comment. */
511 if (!comment_length)
512 ;
513 else if (out)
514 {
515 *out++ = '(';
516 memcpy (out, comment, comment_length);
517 out += comment_length;
518 *out++ = ')';
519 }
520 else
521 out_len += comment_length + 2;
522 break;
523
524 case 'F': /* SSH style fingerprint. */
525 if (!ssh_fpr && key)
526 ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest,
527 &ssh_fpr);
528 if (ssh_fpr)
529 {
530 if (out)
531 out = stpcpy (out, ssh_fpr);
532 else
533 out_len += strlen (ssh_fpr);
534 }
535 break;
536
537 default: /* Invalid special sequences are kept as they are. */
538 if (out)
539 {
540 *out++ = '%';
541 *out++ = in[i];
542 }
543 else
544 out_len+=2;
545 break;
546 }
547 }
548 else if (in[i] == '%')
549 special = 1;
550 else
551 {
552 if (out)
553 *out++ = in[i];
554 else
555 out_len++;
556 }
557 }
558
559 if (!pass)
560 {
561 *result = out = xtrymalloc (out_len + 1);
562 if (!out)
563 {
564 xfree (ssh_fpr);
565 return gpg_error_from_syserror ();
566 }
567 }
568 }
569
570 *out = 0;
571 log_assert (*result + out_len == out);
572 xfree (ssh_fpr);
573
574 /* The ssh prompt may sometimes end in
575 * "...%0A ()"
576 * The empty parentheses doesn't look very good. We use this hack
577 * here to remove them as well as the indentation spaces. */
578 p = *result;
579 i = strlen (p);
580 if (i > 2 && !strcmp (p + i - 2, "()"))
581 {
582 p += i - 2;
583 *p-- = 0;
584 while (p > *result && spacep (p))
585 *p-- = 0;
586 }
587
588 return 0;
589 }
590
591
592
593 /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
594 should be the hex encoded keygrip of that key to be used with the
595 caching mechanism. DESC_TEXT may be set to override the default
596 description used for the pinentry. If LOOKUP_TTL is given this
597 function is used to lookup the default ttl. If R_PASSPHRASE is not
598 NULL, the function succeeded and the key was protected the used
599 passphrase (entered or from the cache) is stored there; if not NULL
600 will be stored. The caller needs to free the returned
601 passphrase. */
602 static gpg_error_t
unprotect(ctrl_t ctrl,const char * cache_nonce,const char * desc_text,unsigned char ** keybuf,const unsigned char * grip,cache_mode_t cache_mode,lookup_ttl_t lookup_ttl,char ** r_passphrase)603 unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
604 unsigned char **keybuf, const unsigned char *grip,
605 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
606 char **r_passphrase)
607 {
608 struct pin_entry_info_s *pi;
609 struct try_unprotect_arg_s arg;
610 int rc;
611 unsigned char *result;
612 size_t resultlen;
613 char hexgrip[40+1];
614
615 if (r_passphrase)
616 *r_passphrase = NULL;
617
618 bin2hex (grip, 20, hexgrip);
619
620 /* Initially try to get it using a cache nonce. */
621 if (cache_nonce)
622 {
623 char *pw;
624
625 pw = agent_get_cache (ctrl, cache_nonce, CACHE_MODE_NONCE);
626 if (pw)
627 {
628 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
629 if (!rc)
630 {
631 if (r_passphrase)
632 *r_passphrase = pw;
633 else
634 xfree (pw);
635 xfree (*keybuf);
636 *keybuf = result;
637 return 0;
638 }
639 xfree (pw);
640 }
641 }
642
643 /* First try to get it from the cache - if there is none or we can't
644 unprotect it, we fall back to ask the user */
645 if (cache_mode != CACHE_MODE_IGNORE)
646 {
647 char *pw;
648
649 retry:
650 pw = agent_get_cache (ctrl, hexgrip, cache_mode);
651 if (pw)
652 {
653 rc = agent_unprotect (ctrl, *keybuf, pw, NULL, &result, &resultlen);
654 if (!rc)
655 {
656 if (cache_mode == CACHE_MODE_NORMAL)
657 agent_store_cache_hit (hexgrip);
658 if (r_passphrase)
659 *r_passphrase = pw;
660 else
661 xfree (pw);
662 xfree (*keybuf);
663 *keybuf = result;
664 return 0;
665 }
666 xfree (pw);
667 }
668 else if (cache_mode == CACHE_MODE_NORMAL)
669 {
670 /* The standard use of GPG keys is to have a signing and an
671 encryption subkey. Commonly both use the same
672 passphrase. We try to help the user to enter the
673 passphrase only once by silently trying the last
674 correctly entered passphrase. Checking one additional
675 passphrase should be acceptable; despite the S2K
676 introduced delays. The assumed workflow is:
677
678 1. Read encrypted message in a MUA and thus enter a
679 passphrase for the encryption subkey.
680
681 2. Reply to that mail with an encrypted and signed
682 mail, thus entering the passphrase for the signing
683 subkey.
684
685 We can often avoid the passphrase entry in the second
686 step. We do this only in normal mode, so not to
687 interfere with unrelated cache entries. */
688 pw = agent_get_cache (ctrl, NULL, cache_mode);
689 if (pw)
690 {
691 rc = agent_unprotect (ctrl, *keybuf, pw, NULL,
692 &result, &resultlen);
693 if (!rc)
694 {
695 if (r_passphrase)
696 *r_passphrase = pw;
697 else
698 xfree (pw);
699 xfree (*keybuf);
700 *keybuf = result;
701 return 0;
702 }
703 xfree (pw);
704 }
705 }
706
707 /* If the pinentry is currently in use, we wait up to 60 seconds
708 for it to close and check the cache again. This solves a common
709 situation where several requests for unprotecting a key have
710 been made but the user is still entering the passphrase for
711 the first request. Because all requests to agent_askpin are
712 serialized they would then pop up one after the other to
713 request the passphrase - despite that the user has already
714 entered it and is then available in the cache. This
715 implementation is not race free but in the worst case the
716 user has to enter the passphrase only once more. */
717 if (pinentry_active_p (ctrl, 0))
718 {
719 /* Active - wait */
720 if (!pinentry_active_p (ctrl, 60))
721 {
722 /* We need to give the other thread a chance to actually put
723 it into the cache. */
724 gnupg_sleep (1);
725 goto retry;
726 }
727 /* Timeout - better call pinentry now the plain way. */
728 }
729 }
730
731 pi = gcry_calloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
732 if (!pi)
733 return gpg_error_from_syserror ();
734 pi->max_length = MAX_PASSPHRASE_LEN + 1;
735 pi->min_digits = 0; /* we want a real passphrase */
736 pi->max_digits = 16;
737 pi->max_tries = 3;
738 pi->check_cb = try_unprotect_cb;
739 arg.ctrl = ctrl;
740 arg.protected_key = *keybuf;
741 arg.unprotected_key = NULL;
742 arg.change_required = 0;
743 pi->check_cb_arg = &arg;
744
745 rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode);
746 if (rc)
747 {
748 if ((pi->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
749 {
750 log_error ("Clearing pinentry cache which caused error %s\n",
751 gpg_strerror (rc));
752
753 agent_clear_passphrase (ctrl, hexgrip, cache_mode);
754 }
755 }
756 else
757 {
758 log_assert (arg.unprotected_key);
759 if (arg.change_required)
760 {
761 /* The callback told as that the user should change their
762 passphrase. Present the dialog to do. */
763 size_t canlen, erroff;
764 gcry_sexp_t s_skey;
765
766 log_assert (arg.unprotected_key);
767 canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL);
768 rc = gcry_sexp_sscan (&s_skey, &erroff,
769 (char*)arg.unprotected_key, canlen);
770 if (rc)
771 {
772 log_error ("failed to build S-Exp (off=%u): %s\n",
773 (unsigned int)erroff, gpg_strerror (rc));
774 wipememory (arg.unprotected_key, canlen);
775 xfree (arg.unprotected_key);
776 xfree (pi);
777 return rc;
778 }
779 rc = agent_protect_and_store (ctrl, s_skey, NULL);
780 gcry_sexp_release (s_skey);
781 if (rc)
782 {
783 log_error ("changing the passphrase failed: %s\n",
784 gpg_strerror (rc));
785 wipememory (arg.unprotected_key, canlen);
786 xfree (arg.unprotected_key);
787 xfree (pi);
788 return rc;
789 }
790 }
791 else
792 {
793 /* Passphrase is fine. */
794 agent_put_cache (ctrl, hexgrip, cache_mode, pi->pin,
795 lookup_ttl? lookup_ttl (hexgrip) : 0);
796 agent_store_cache_hit (hexgrip);
797 if (r_passphrase && *pi->pin)
798 *r_passphrase = xtrystrdup (pi->pin);
799 }
800 xfree (*keybuf);
801 *keybuf = arg.unprotected_key;
802 }
803 xfree (pi);
804 return rc;
805 }
806
807
808 /* Read the key identified by GRIP from the private key directory and
809 * return it as an gcrypt S-expression object in RESULT. If R_KEYMETA
810 * is not NULl and the extended key format is used, the meta data
811 * items are stored there. However the "Key:" item is removed from
812 * it. On failure returns an error code and stores NULL at RESULT and
813 * R_KEYMETA. */
814 static gpg_error_t
read_key_file(const unsigned char * grip,gcry_sexp_t * result,nvc_t * r_keymeta)815 read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta)
816 {
817 gpg_error_t err;
818 char *fname;
819 estream_t fp;
820 struct stat st;
821 unsigned char *buf;
822 size_t buflen, erroff;
823 gcry_sexp_t s_skey;
824 char hexgrip[40+4+1];
825 char first;
826
827 *result = NULL;
828 if (r_keymeta)
829 *r_keymeta = NULL;
830
831 bin2hex (grip, 20, hexgrip);
832 strcpy (hexgrip+40, ".key");
833
834 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
835 hexgrip, NULL);
836 fp = es_fopen (fname, "rb");
837 if (!fp)
838 {
839 err = gpg_error_from_syserror ();
840 if (gpg_err_code (err) != GPG_ERR_ENOENT)
841 log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
842 xfree (fname);
843 return err;
844 }
845
846 if (es_fread (&first, 1, 1, fp) != 1)
847 {
848 err = gpg_error_from_syserror ();
849 log_error ("error reading first byte from '%s': %s\n",
850 fname, gpg_strerror (err));
851 xfree (fname);
852 es_fclose (fp);
853 return err;
854 }
855
856 if (es_fseek (fp, 0, SEEK_SET))
857 {
858 err = gpg_error_from_syserror ();
859 log_error ("error seeking in '%s': %s\n", fname, gpg_strerror (err));
860 xfree (fname);
861 es_fclose (fp);
862 return err;
863 }
864
865 if (first != '(')
866 {
867 /* Key is in extended format. */
868 nvc_t pk = NULL;
869 int line;
870
871 err = nvc_parse_private_key (&pk, &line, fp);
872 es_fclose (fp);
873
874 if (err)
875 log_error ("error parsing '%s' line %d: %s\n",
876 fname, line, gpg_strerror (err));
877 else
878 {
879 err = nvc_get_private_key (pk, result);
880 if (err)
881 log_error ("error getting private key from '%s': %s\n",
882 fname, gpg_strerror (err));
883 else
884 nvc_delete_named (pk, "Key:");
885 }
886
887 if (!err && r_keymeta)
888 *r_keymeta = pk;
889 else
890 nvc_release (pk);
891 xfree (fname);
892 return err;
893 }
894
895 if (fstat (es_fileno (fp), &st))
896 {
897 err = gpg_error_from_syserror ();
898 log_error ("can't stat '%s': %s\n", fname, gpg_strerror (err));
899 xfree (fname);
900 es_fclose (fp);
901 return err;
902 }
903
904 buflen = st.st_size;
905 buf = xtrymalloc (buflen+1);
906 if (!buf)
907 {
908 err = gpg_error_from_syserror ();
909 log_error ("error allocating %zu bytes for '%s': %s\n",
910 buflen, fname, gpg_strerror (err));
911 xfree (fname);
912 es_fclose (fp);
913 xfree (buf);
914 return err;
915
916 }
917
918 if (es_fread (buf, buflen, 1, fp) != 1)
919 {
920 err = gpg_error_from_syserror ();
921 log_error ("error reading %zu bytes from '%s': %s\n",
922 buflen, fname, gpg_strerror (err));
923 xfree (fname);
924 es_fclose (fp);
925 xfree (buf);
926 return err;
927 }
928
929 /* Convert the file into a gcrypt S-expression object. */
930 err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen);
931 xfree (fname);
932 es_fclose (fp);
933 xfree (buf);
934 if (err)
935 {
936 log_error ("failed to build S-Exp (off=%u): %s\n",
937 (unsigned int)erroff, gpg_strerror (err));
938 return err;
939 }
940 *result = s_skey;
941 return 0;
942 }
943
944
945 /* Remove the key identified by GRIP from the private key directory. */
946 static gpg_error_t
remove_key_file(const unsigned char * grip)947 remove_key_file (const unsigned char *grip)
948 {
949 gpg_error_t err = 0;
950 char *fname;
951 char hexgrip[40+4+1];
952
953 bin2hex (grip, 20, hexgrip);
954 strcpy (hexgrip+40, ".key");
955 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
956 hexgrip, NULL);
957 if (gnupg_remove (fname))
958 err = gpg_error_from_syserror ();
959 xfree (fname);
960 return err;
961 }
962
963
964 /* Return the secret key as an S-Exp in RESULT after locating it using
965 the GRIP. If the operation shall be diverted to a token, an
966 allocated S-expression with the shadow_info part from the file is
967 stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO.
968 CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
969 set to present a custom description for the pinentry. LOOKUP_TTL
970 is an optional function to convey a TTL to the cache manager; we do
971 not simply pass the TTL value because the value is only needed if
972 an unprotect action was needed and looking up the TTL may have some
973 overhead (e.g. scanning the sshcontrol file). If a CACHE_NONCE is
974 given that cache item is first tried to get a passphrase. If
975 R_PASSPHRASE is not NULL, the function succeeded and the key was
976 protected the used passphrase (entered or from the cache) is stored
977 there; if not NULL will be stored. The caller needs to free the
978 returned passphrase. */
979 gpg_error_t
agent_key_from_file(ctrl_t ctrl,const char * cache_nonce,const char * desc_text,const unsigned char * grip,unsigned char ** shadow_info,cache_mode_t cache_mode,lookup_ttl_t lookup_ttl,gcry_sexp_t * result,char ** r_passphrase)980 agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
981 const char *desc_text,
982 const unsigned char *grip, unsigned char **shadow_info,
983 cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
984 gcry_sexp_t *result, char **r_passphrase)
985 {
986 gpg_error_t err;
987 unsigned char *buf;
988 size_t len, erroff;
989 gcry_sexp_t s_skey;
990 nvc_t keymeta = NULL;
991 char *desc_text_buffer = NULL; /* Used in case we extend DESC_TEXT. */
992
993 *result = NULL;
994 if (shadow_info)
995 *shadow_info = NULL;
996 if (r_passphrase)
997 *r_passphrase = NULL;
998
999 err = read_key_file (grip, &s_skey, &keymeta);
1000 if (err)
1001 {
1002 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1003 err = gpg_error (GPG_ERR_NO_SECKEY);
1004 return err;
1005 }
1006
1007 /* For use with the protection functions we also need the key as an
1008 canonical encoded S-expression in a buffer. Create this buffer
1009 now. */
1010 err = make_canon_sexp (s_skey, &buf, &len);
1011 if (err)
1012 {
1013 nvc_release (keymeta);
1014 xfree (desc_text_buffer);
1015 return err;
1016 }
1017
1018 switch (agent_private_key_type (buf))
1019 {
1020 case PRIVATE_KEY_CLEAR:
1021 break; /* no unprotection needed */
1022 case PRIVATE_KEY_OPENPGP_NONE:
1023 {
1024 unsigned char *buf_new;
1025 size_t buf_newlen;
1026
1027 err = agent_unprotect (ctrl, buf, "", NULL, &buf_new, &buf_newlen);
1028 if (err)
1029 log_error ("failed to convert unprotected openpgp key: %s\n",
1030 gpg_strerror (err));
1031 else
1032 {
1033 xfree (buf);
1034 buf = buf_new;
1035 }
1036 }
1037 break;
1038 case PRIVATE_KEY_PROTECTED:
1039 {
1040 char *desc_text_final;
1041 char *comment_buffer = NULL;
1042 const char *comment = NULL;
1043
1044 /* Note, that we will take the comment as a C string for
1045 * display purposes; i.e. all stuff beyond a Nul character is
1046 * ignored. If a "Label" entry is available in the meta data
1047 * this is used instead of the s-expression comment. */
1048 if (keymeta && (comment = nvc_get_string (keymeta, "Label:")))
1049 {
1050 if (strchr (comment, '\n')
1051 && (comment_buffer = linefeed_to_percent0A (comment)))
1052 comment = comment_buffer;
1053 /* In case DESC_TEXT has no escape pattern for a comment
1054 * we append one. */
1055 if (desc_text && !has_comment_expando (desc_text))
1056 {
1057 desc_text_buffer = strconcat (desc_text, "%0A%C", NULL);
1058 if (desc_text_buffer)
1059 desc_text = desc_text_buffer;
1060 }
1061 }
1062 else
1063 {
1064 gcry_sexp_t comment_sexp;
1065
1066 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1067 if (comment_sexp)
1068 comment_buffer = gcry_sexp_nth_string (comment_sexp, 1);
1069 gcry_sexp_release (comment_sexp);
1070 comment = comment_buffer;
1071 }
1072
1073 desc_text_final = NULL;
1074 if (desc_text)
1075 err = agent_modify_description (desc_text, comment, s_skey,
1076 &desc_text_final);
1077 gcry_free (comment_buffer);
1078
1079 if (!err)
1080 {
1081 err = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
1082 cache_mode, lookup_ttl, r_passphrase);
1083 if (err)
1084 log_error ("failed to unprotect the secret key: %s\n",
1085 gpg_strerror (err));
1086 }
1087
1088 xfree (desc_text_final);
1089 }
1090 break;
1091 case PRIVATE_KEY_SHADOWED:
1092 if (shadow_info)
1093 {
1094 const unsigned char *s;
1095 size_t n;
1096
1097 err = agent_get_shadow_info (buf, &s);
1098 if (!err)
1099 {
1100 n = gcry_sexp_canon_len (s, 0, NULL,NULL);
1101 log_assert (n);
1102 *shadow_info = xtrymalloc (n);
1103 if (!*shadow_info)
1104 err = out_of_core ();
1105 else
1106 {
1107 memcpy (*shadow_info, s, n);
1108 err = 0;
1109 }
1110 }
1111 if (err)
1112 log_error ("get_shadow_info failed: %s\n", gpg_strerror (err));
1113 }
1114 else
1115 err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
1116 break;
1117 default:
1118 log_error ("invalid private key format\n");
1119 err = gpg_error (GPG_ERR_BAD_SECKEY);
1120 break;
1121 }
1122 gcry_sexp_release (s_skey);
1123 s_skey = NULL;
1124 if (err)
1125 {
1126 xfree (buf);
1127 if (r_passphrase)
1128 {
1129 xfree (*r_passphrase);
1130 *r_passphrase = NULL;
1131 }
1132 nvc_release (keymeta);
1133 xfree (desc_text_buffer);
1134 return err;
1135 }
1136
1137 err = sexp_sscan_private_key (result, &erroff, buf);
1138 xfree (buf);
1139 nvc_release (keymeta);
1140 xfree (desc_text_buffer);
1141 if (err)
1142 {
1143 log_error ("failed to build S-Exp (off=%u): %s\n",
1144 (unsigned int)erroff, gpg_strerror (err));
1145 if (r_passphrase)
1146 {
1147 xfree (*r_passphrase);
1148 *r_passphrase = NULL;
1149 }
1150 }
1151
1152 return err;
1153 }
1154
1155
1156 /* Return the key for the keygrip GRIP. The result is stored at
1157 RESULT. This function extracts the key from the private key
1158 database and returns it as an S-expression object as it is. On
1159 failure an error code is returned and NULL stored at RESULT. */
1160 gpg_error_t
agent_raw_key_from_file(ctrl_t ctrl,const unsigned char * grip,gcry_sexp_t * result)1161 agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip,
1162 gcry_sexp_t *result)
1163 {
1164 gpg_error_t err;
1165 gcry_sexp_t s_skey;
1166
1167 (void)ctrl;
1168
1169 *result = NULL;
1170
1171 err = read_key_file (grip, &s_skey, NULL);
1172 if (!err)
1173 *result = s_skey;
1174 return err;
1175 }
1176
1177
1178 /* Return the public key for the keygrip GRIP. The result is stored
1179 at RESULT. This function extracts the public key from the private
1180 key database. On failure an error code is returned and NULL stored
1181 at RESULT. */
1182 gpg_error_t
agent_public_key_from_file(ctrl_t ctrl,const unsigned char * grip,gcry_sexp_t * result)1183 agent_public_key_from_file (ctrl_t ctrl,
1184 const unsigned char *grip,
1185 gcry_sexp_t *result)
1186 {
1187 gpg_error_t err;
1188 int i, idx;
1189 gcry_sexp_t s_skey;
1190 const char *algoname, *elems;
1191 int npkey;
1192 gcry_mpi_t array[10];
1193 gcry_sexp_t curve = NULL;
1194 gcry_sexp_t flags = NULL;
1195 gcry_sexp_t uri_sexp, comment_sexp;
1196 const char *uri, *comment;
1197 size_t uri_length, comment_length;
1198 int uri_intlen, comment_intlen;
1199 membuf_t format_mb;
1200 char *format;
1201 void *args[2+7+2+2+1]; /* Size is 2 + max. # of elements + 2 for uri + 2
1202 for comment + end-of-list. */
1203 int argidx;
1204 gcry_sexp_t list = NULL;
1205 const char *s;
1206
1207 (void)ctrl;
1208
1209 *result = NULL;
1210
1211 err = read_key_file (grip, &s_skey, NULL);
1212 if (err)
1213 return err;
1214
1215 for (i=0; i < DIM (array); i++)
1216 array[i] = NULL;
1217
1218 err = extract_private_key (s_skey, 0, &algoname, &npkey, NULL, &elems,
1219 array, DIM (array), &curve, &flags);
1220 if (err)
1221 {
1222 gcry_sexp_release (s_skey);
1223 return err;
1224 }
1225
1226 uri = NULL;
1227 uri_length = 0;
1228 uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0);
1229 if (uri_sexp)
1230 uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length);
1231
1232 comment = NULL;
1233 comment_length = 0;
1234 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1235 if (comment_sexp)
1236 comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length);
1237
1238 gcry_sexp_release (s_skey);
1239 s_skey = NULL;
1240
1241
1242 log_assert (sizeof (size_t) <= sizeof (void*));
1243
1244 init_membuf (&format_mb, 256);
1245 argidx = 0;
1246 put_membuf_printf (&format_mb, "(public-key(%s%%S%%S", algoname);
1247 args[argidx++] = &curve;
1248 args[argidx++] = &flags;
1249 for (idx=0, s=elems; idx < npkey; idx++)
1250 {
1251 put_membuf_printf (&format_mb, "(%c %%m)", *s++);
1252 log_assert (argidx < DIM (args));
1253 args[argidx++] = &array[idx];
1254 }
1255 put_membuf_str (&format_mb, ")");
1256 if (uri)
1257 {
1258 put_membuf_str (&format_mb, "(uri %b)");
1259 log_assert (argidx+1 < DIM (args));
1260 uri_intlen = (int)uri_length;
1261 args[argidx++] = (void *)&uri_intlen;
1262 args[argidx++] = (void *)&uri;
1263 }
1264 if (comment)
1265 {
1266 put_membuf_str (&format_mb, "(comment %b)");
1267 log_assert (argidx+1 < DIM (args));
1268 comment_intlen = (int)comment_length;
1269 args[argidx++] = (void *)&comment_intlen;
1270 args[argidx++] = (void *)&comment;
1271 }
1272 put_membuf (&format_mb, ")", 2);
1273 log_assert (argidx < DIM (args));
1274 args[argidx] = NULL;
1275
1276 format = get_membuf (&format_mb, NULL);
1277 if (!format)
1278 {
1279 err = gpg_error_from_syserror ();
1280 for (i=0; array[i]; i++)
1281 gcry_mpi_release (array[i]);
1282 gcry_sexp_release (curve);
1283 gcry_sexp_release (flags);
1284 gcry_sexp_release (uri_sexp);
1285 gcry_sexp_release (comment_sexp);
1286 return err;
1287 }
1288
1289 err = gcry_sexp_build_array (&list, NULL, format, args);
1290 xfree (format);
1291 for (i=0; array[i]; i++)
1292 gcry_mpi_release (array[i]);
1293 gcry_sexp_release (curve);
1294 gcry_sexp_release (flags);
1295 gcry_sexp_release (uri_sexp);
1296 gcry_sexp_release (comment_sexp);
1297
1298 if (!err)
1299 *result = list;
1300 return err;
1301 }
1302
1303
1304 /* Check whether the secret key identified by GRIP is available.
1305 Returns 0 is the key is available. */
1306 int
agent_key_available(const unsigned char * grip)1307 agent_key_available (const unsigned char *grip)
1308 {
1309 int result;
1310 char *fname;
1311 char hexgrip[40+4+1];
1312
1313 bin2hex (grip, 20, hexgrip);
1314 strcpy (hexgrip+40, ".key");
1315
1316 fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR,
1317 hexgrip, NULL);
1318 result = !gnupg_access (fname, R_OK)? 0 : -1;
1319 xfree (fname);
1320 return result;
1321 }
1322
1323
1324
1325 /* Return the information about the secret key specified by the binary
1326 keygrip GRIP. If the key is a shadowed one the shadow information
1327 will be stored at the address R_SHADOW_INFO as an allocated
1328 S-expression. */
1329 gpg_error_t
agent_key_info_from_file(ctrl_t ctrl,const unsigned char * grip,int * r_keytype,unsigned char ** r_shadow_info,unsigned char ** r_shadow_info_type)1330 agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
1331 int *r_keytype, unsigned char **r_shadow_info,
1332 unsigned char **r_shadow_info_type)
1333 {
1334 gpg_error_t err;
1335 unsigned char *buf;
1336 size_t len;
1337 int keytype;
1338
1339 (void)ctrl;
1340
1341 if (r_keytype)
1342 *r_keytype = PRIVATE_KEY_UNKNOWN;
1343 if (r_shadow_info)
1344 *r_shadow_info = NULL;
1345
1346 {
1347 gcry_sexp_t sexp;
1348
1349 err = read_key_file (grip, &sexp, NULL);
1350 if (err)
1351 {
1352 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1353 return gpg_error (GPG_ERR_NOT_FOUND);
1354 else
1355 return err;
1356 }
1357 err = make_canon_sexp (sexp, &buf, &len);
1358 gcry_sexp_release (sexp);
1359 if (err)
1360 return err;
1361 }
1362
1363 keytype = agent_private_key_type (buf);
1364 switch (keytype)
1365 {
1366 case PRIVATE_KEY_CLEAR:
1367 case PRIVATE_KEY_OPENPGP_NONE:
1368 break;
1369 case PRIVATE_KEY_PROTECTED:
1370 /* If we ever require it we could retrieve the comment fields
1371 from such a key. */
1372 break;
1373 case PRIVATE_KEY_SHADOWED:
1374 if (r_shadow_info)
1375 {
1376 const unsigned char *s;
1377 size_t n;
1378
1379 err = agent_get_shadow_info_type (buf, &s, r_shadow_info_type);
1380 if (!err)
1381 {
1382 n = gcry_sexp_canon_len (s, 0, NULL, NULL);
1383 log_assert (n);
1384 *r_shadow_info = xtrymalloc (n);
1385 if (!*r_shadow_info)
1386 err = gpg_error_from_syserror ();
1387 else
1388 memcpy (*r_shadow_info, s, n);
1389 }
1390 }
1391 break;
1392 default:
1393 err = gpg_error (GPG_ERR_BAD_SECKEY);
1394 break;
1395 }
1396
1397 if (!err && r_keytype)
1398 *r_keytype = keytype;
1399
1400 xfree (buf);
1401 return err;
1402 }
1403
1404
1405
1406 /* Delete the key with GRIP from the disk after having asked for
1407 * confirmation using DESC_TEXT. If FORCE is set the function won't
1408 * require a confirmation via Pinentry or warns if the key is also
1409 * used by ssh. If ONLY_STUBS is set only stub keys (references to
1410 * smartcards) will be affected.
1411 *
1412 * Common error codes are:
1413 * GPG_ERR_NO_SECKEY
1414 * GPG_ERR_KEY_ON_CARD
1415 * GPG_ERR_NOT_CONFIRMED
1416 * GPG_ERR_FORBIDDEN - Not a stub key and ONLY_STUBS requested.
1417 */
1418 gpg_error_t
agent_delete_key(ctrl_t ctrl,const char * desc_text,const unsigned char * grip,int force,int only_stubs)1419 agent_delete_key (ctrl_t ctrl, const char *desc_text,
1420 const unsigned char *grip, int force, int only_stubs)
1421 {
1422 gpg_error_t err;
1423 gcry_sexp_t s_skey = NULL;
1424 unsigned char *buf = NULL;
1425 size_t len;
1426 char *desc_text_final = NULL;
1427 char *comment = NULL;
1428 ssh_control_file_t cf = NULL;
1429 char hexgrip[40+4+1];
1430 char *default_desc = NULL;
1431 int key_type;
1432
1433 err = read_key_file (grip, &s_skey, NULL);
1434 if (gpg_err_code (err) == GPG_ERR_ENOENT)
1435 err = gpg_error (GPG_ERR_NO_SECKEY);
1436 if (err)
1437 goto leave;
1438
1439 err = make_canon_sexp (s_skey, &buf, &len);
1440 if (err)
1441 goto leave;
1442
1443 key_type = agent_private_key_type (buf);
1444 if (only_stubs && key_type != PRIVATE_KEY_SHADOWED)
1445 {
1446 err = gpg_error (GPG_ERR_FORBIDDEN);
1447 goto leave;
1448 }
1449
1450 switch (key_type)
1451 {
1452 case PRIVATE_KEY_CLEAR:
1453 case PRIVATE_KEY_OPENPGP_NONE:
1454 case PRIVATE_KEY_PROTECTED:
1455 bin2hex (grip, 20, hexgrip);
1456 if (!force)
1457 {
1458 if (!desc_text)
1459 {
1460 default_desc = xtryasprintf
1461 (L_("Do you really want to delete the key identified by keygrip%%0A"
1462 " %s%%0A %%C%%0A?"), hexgrip);
1463 desc_text = default_desc;
1464 }
1465
1466 /* Note, that we will take the comment as a C string for
1467 display purposes; i.e. all stuff beyond a Nul character is
1468 ignored. */
1469 {
1470 gcry_sexp_t comment_sexp;
1471
1472 comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0);
1473 if (comment_sexp)
1474 comment = gcry_sexp_nth_string (comment_sexp, 1);
1475 gcry_sexp_release (comment_sexp);
1476 }
1477
1478 if (desc_text)
1479 err = agent_modify_description (desc_text, comment, s_skey,
1480 &desc_text_final);
1481 if (err)
1482 goto leave;
1483
1484 err = agent_get_confirmation (ctrl, desc_text_final,
1485 L_("Delete key"), L_("No"), 0);
1486 if (err)
1487 goto leave;
1488
1489 cf = ssh_open_control_file ();
1490 if (cf)
1491 {
1492 if (!ssh_search_control_file (cf, hexgrip, NULL, NULL, NULL))
1493 {
1494 err = agent_get_confirmation
1495 (ctrl,
1496 L_("Warning: This key is also listed for use with SSH!\n"
1497 "Deleting the key might remove your ability to "
1498 "access remote machines."),
1499 L_("Delete key"), L_("No"), 0);
1500 if (err)
1501 goto leave;
1502 }
1503 }
1504 }
1505 err = remove_key_file (grip);
1506 break;
1507
1508 case PRIVATE_KEY_SHADOWED:
1509 err = remove_key_file (grip);
1510 break;
1511
1512 default:
1513 log_error ("invalid private key format\n");
1514 err = gpg_error (GPG_ERR_BAD_SECKEY);
1515 break;
1516 }
1517
1518 leave:
1519 ssh_close_control_file (cf);
1520 gcry_free (comment);
1521 xfree (desc_text_final);
1522 xfree (default_desc);
1523 xfree (buf);
1524 gcry_sexp_release (s_skey);
1525 return err;
1526 }
1527
1528
1529 /* Write an S-expression formatted shadow key to our key storage.
1530 Shadow key is created by an S-expression public key in PKBUF and
1531 card's SERIALNO and the IDSTRING. With FORCE passed as true an
1532 existing key with the given GRIP will get overwritten. */
1533 gpg_error_t
agent_write_shadow_key(const unsigned char * grip,const char * serialno,const char * keyid,const unsigned char * pkbuf,int force)1534 agent_write_shadow_key (const unsigned char *grip,
1535 const char *serialno, const char *keyid,
1536 const unsigned char *pkbuf, int force)
1537 {
1538 gpg_error_t err;
1539 unsigned char *shadow_info;
1540 unsigned char *shdkey;
1541 size_t len;
1542
1543 /* Just in case some caller did not parse the stuff correctly, skip
1544 * leading spaces. */
1545 while (spacep (serialno))
1546 serialno++;
1547 while (spacep (keyid))
1548 keyid++;
1549
1550 shadow_info = make_shadow_info (serialno, keyid);
1551 if (!shadow_info)
1552 return gpg_error_from_syserror ();
1553
1554 err = agent_shadow_key (pkbuf, shadow_info, &shdkey);
1555 xfree (shadow_info);
1556 if (err)
1557 {
1558 log_error ("shadowing the key failed: %s\n", gpg_strerror (err));
1559 return err;
1560 }
1561
1562 len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
1563 err = agent_write_private_key (grip, shdkey, len, force, serialno, keyid, 0);
1564 xfree (shdkey);
1565 if (err)
1566 log_error ("error writing key: %s\n", gpg_strerror (err));
1567
1568 return err;
1569 }
1570