Fix crash when/if gpg-agent dies.
[pwmd.git] / src / agent.c
blob96c0a9793bc68148a5ba6bca3bdc4e31f4519aea
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <pwd.h>
27 #include <sys/types.h>
28 #include <signal.h>
29 #include <sys/wait.h>
30 #include <fcntl.h>
31 #include <dirent.h>
33 #ifdef HAVE_LIMITS_H
34 #include <limits.h>
35 #endif
37 #include "pwmd-error.h"
38 #include "util-misc.h"
39 #include "mem.h"
40 #include "common.h"
41 #include "commands.h"
42 #include "agent.h"
43 #include "util-string.h"
44 #include "mutex.h"
45 #include "rcfile.h"
46 #include "cache.h"
47 #include "cipher.h"
48 #include "crypto.h"
50 static gpg_error_t
51 mem_realloc_cb (void *data, const void *buffer, size_t len)
53 membuf_t *mem = (membuf_t *) data;
54 void *p;
56 if (!buffer)
57 return 0;
59 if ((p = xrealloc (mem->buf, mem->len + len)) == NULL)
60 return 1;
62 mem->buf = p;
63 memcpy ((char *) mem->buf + mem->len, buffer, len);
64 mem->len += len;
65 return 0;
68 static gpg_error_t
69 status_cb (void *data, const char *line)
71 struct agent_s *agent = data;
73 agent->inquire_maxlen = 0;
75 if (!strncmp (line, "INQUIRE_MAXLEN ", 15))
77 agent->inquire_maxlen = atoi (line + 15);
78 if (!agent->client_ctx)
79 return 0;
82 return send_status (agent->client_ctx, STATUS_AGENT, "%s", line);
85 static gpg_error_t
86 assuan_command (struct agent_s *a, char **result,
87 size_t * len, const char *cmd)
89 gpg_error_t rc;
91 a->data.len = 0;
92 a->data.buf = NULL;
93 if (result)
94 *result = NULL;
95 if (len)
96 *len = 0;
98 rc = assuan_transact (a->ctx, cmd, mem_realloc_cb, &a->data,
99 a->inquire_cb, a->inquire_data, status_cb, a);
100 if (rc)
101 xfree (a->data.buf);
102 else
104 if (a->data.buf)
106 mem_realloc_cb (&a->data, "", 1);
107 if (result)
108 *result = (char *) a->data.buf;
109 else
110 xfree (a->data.buf);
112 if (len)
113 *len = a->data.len;
117 return rc;
120 /* This commands are sent from launch_agent() after reconnecting to the agent
121 * and also from the initial client connection. */
122 gpg_error_t
123 send_agent_common_options (struct agent_s *agent)
125 gpg_error_t rc;
127 rc = send_to_agent (agent, NULL, NULL, "OPTION cache-ttl-opt-preset=-1");
128 return rc;
131 static gpg_error_t
132 launch_agent (struct agent_s *agent)
134 gpg_error_t rc;
135 assuan_context_t ctx = NULL;
136 const char *t = NULL;
137 static struct assuan_malloc_hooks mhooks = { xmalloc, xrealloc, xfree };
138 char *s, buf[LINE_MAX];
139 FILE *fp;
141 s = config_get_string ("global", "agent_env_file");
142 if (s)
144 char *ss = expand_homedir (s);
145 char *p;
147 fp = fopen (ss, "r");
148 xfree (ss);
150 if (fp)
152 while ((p = fgets (buf, sizeof (buf), fp)))
154 p = str_chomp (p);
155 if (!strncmp (p, "GPG_AGENT_INFO=", strlen ("GPG_AGENT_INFO=")))
157 setenv ("GPG_AGENT_INFO", p + strlen ("GPG_AGENT_INFO="),
159 break;
163 fclose (fp);
165 else
166 log_write ("%s: %s", s, pwmd_strerror (gpg_error_from_syserror ()));
168 xfree (s);
171 t = getenv ("GPG_AGENT_INFO");
172 if (!t)
173 return gpg_error (GPG_ERR_NO_AGENT);
175 rc = assuan_new_ext (&ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
176 debug_level ? assuan_log_cb : NULL, "AGENT ");
177 if (rc)
178 return rc;
180 char **fields = str_split (t, ":", 0);
181 rc = assuan_socket_connect (ctx, fields[0], ASSUAN_INVALID_PID, 0);
182 strv_free (fields);
183 if (rc)
185 if (ctx)
186 assuan_release (ctx);
187 return rc;
190 if (agent->ctx)
191 assuan_release (agent->ctx);
193 agent->ctx = ctx;
194 rc = send_agent_common_options (agent);
195 if (!rc && agent->pinentry_opts.display)
196 rc = set_agent_option (agent, "display", agent->pinentry_opts.display);
198 if (!rc && agent->pinentry_opts.ttyname)
199 rc = set_agent_option (agent, "ttyname", agent->pinentry_opts.ttyname);
201 if (!rc && agent->pinentry_opts.ttytype)
202 rc = set_agent_option (agent, "ttytype", agent->pinentry_opts.ttytype);
204 if (!rc && agent->pinentry_opts.lc_messages)
205 rc = set_agent_option (agent, "lc-messages",
206 agent->pinentry_opts.lc_messages);
208 if (!rc && agent->pinentry_opts.lc_ctype)
209 rc = set_agent_option (agent, "lc-ctype", agent->pinentry_opts.lc_ctype);
211 return 0;
214 gpg_error_t
215 send_to_agent (struct agent_s * agent, char **result, size_t * len,
216 const char *fmt, ...)
218 gpg_error_t rc = 0;
219 va_list ap;
220 char *cmd;
222 if (!agent->ctx)
224 rc = launch_agent (agent);
225 if (rc)
226 return rc;
229 va_start (ap, fmt);
230 if (str_vasprintf (&cmd, fmt, ap) > 0)
232 rc = assuan_command (agent, result, len, cmd);
233 if (!agent->restart && gpg_err_source (rc) == GPG_ERR_SOURCE_DEFAULT
234 && (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED
235 || gpg_err_code (rc) == GPG_ERR_EPIPE))
237 unsetenv ("GPG_AGENT_INFO");
238 agent->restart = 1;
239 rc = launch_agent (agent);
240 if (!rc)
241 rc = assuan_command (agent, result, len, cmd);
244 agent->restart = 0;
245 xfree (cmd);
247 else
248 rc = GPG_ERR_ENOMEM;
250 va_end (ap);
251 return rc;
254 static void
255 agent_disconnect (struct agent_s *agent)
257 if (!agent)
258 return;
260 if (agent->ctx)
261 assuan_release (agent->ctx);
263 agent->ctx = NULL;
266 void
267 cleanup_agent (struct agent_s *agent)
269 if (!agent)
270 return;
272 pinentry_free_opts (&agent->pinentry_opts);
273 agent_disconnect (agent);
274 xfree (agent);
277 gpg_error_t
278 agent_init (struct agent_s **agent)
280 struct agent_s *new = xcalloc (1, sizeof (struct agent_s));
282 if (!new)
283 return GPG_ERR_ENOMEM;
285 *agent = new;
286 return 0;
289 static gpg_error_t
290 inquire_cb (void *user, const char *keyword)
292 struct inquire_data_s *idata = user;
294 if (!idata->preset && (!strcmp (keyword, "PASSPHRASE")
295 || !strcmp (keyword, "NEW_PASSPHRASE")))
297 return agent_loopback_cb (idata->crypto, keyword);
299 // SAVE --inquire-keyparam
300 else if (idata->preset && !strcmp (keyword, "KEYPARAM"))
302 idata->preset = 0;
303 return agent_loopback_cb (idata->crypto, keyword);
306 if (idata->crypto->agent->inquire_maxlen
307 && idata->len > idata->crypto->agent->inquire_maxlen)
309 log_write (_("Inquired data too large: have=%u, max=%u"), idata->len,
310 idata->crypto->agent->inquire_maxlen);
311 return GPG_ERR_TOO_LARGE;
314 idata->crypto->agent->inquire_maxlen = 0;
315 return assuan_send_data (idata->crypto->agent->ctx, idata->line,
316 idata->len);
319 gpg_error_t
320 agent_extract_key (struct crypto_s *crypto, unsigned char **result,
321 size_t * result_len)
323 gpg_error_t rc;
324 gcry_sexp_t enc_sexp = NULL, tmp_sexp;
325 struct inquire_data_s idata = { 0 };
326 char *hexgrip = NULL;
327 char *key;
328 size_t keylen, keysize;
329 char *tmp;
330 int algo = cipher_to_gcrypt (crypto->hdr.flags);
331 int shadowed;
333 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
334 if (rc)
335 return rc;
337 tmp_sexp = gcry_sexp_find_token (crypto->ciphertext_sexp, "enc-val", 0);
338 if (!tmp_sexp)
339 return GPG_ERR_BAD_DATA;
341 hexgrip = bin2hex (crypto->grip, sizeof (crypto->grip));
342 if (!hexgrip)
344 rc = GPG_ERR_ENOMEM;
345 goto fail;
348 rc = cache_is_shadowed (hexgrip);
349 if (rc && rc != GPG_ERR_NO_DATA)
350 goto fail;
352 shadowed = !rc ? 1 : 0;
353 if (!shadowed)
355 gcry_sexp_t tmp2_sexp = gcry_sexp_cdr (tmp_sexp);
356 gcry_sexp_release (tmp_sexp);
357 tmp_sexp = gcry_sexp_nth (tmp2_sexp, 0);
358 gcry_sexp_release (tmp2_sexp);
359 rc = gcry_sexp_build (&enc_sexp, NULL, "(enc-val (flags pkcs1) %S)",
360 tmp_sexp);
362 else
363 rc = gcry_sexp_build (&enc_sexp, NULL, "%S", tmp_sexp);
365 gcry_sexp_release (tmp_sexp);
366 if (rc)
367 return rc;
369 crypto->agent->inquire_cb = inquire_cb;
370 idata.crypto = crypto;
371 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
372 idata.line = xmalloc (idata.len);
373 if (!idata.line)
375 rc = GPG_ERR_ENOMEM;
376 goto fail;
379 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, idata.line,
380 idata.len);
381 crypto->agent->inquire_data = &idata;
382 gcry_sexp_release (enc_sexp);
383 enc_sexp = NULL;
384 log_write1 (_("Keygrip is %s, bits=%i"), hexgrip,
385 gcry_pk_get_nbits (crypto->pkey_sexp));
386 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEY %s", hexgrip);
387 if (rc)
388 goto fail;
390 if (!crypto->agent->pinentry_opts.desc)
392 tmp =
393 plus_escape (_
394 ("A %s is required to unlock the secret key for the "
395 "encrypted data file \"%s\". Please enter the %s "
396 "below."), shadowed ? "PIN" : _("passphrase"),
397 crypto->filename, shadowed ? "PIN" : _("passphrase"));
399 else
400 tmp = plus_escape (crypto->agent->pinentry_opts.desc);
402 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEYDESC %s", tmp);
403 xfree (tmp);
404 if (rc)
405 goto fail;
407 assuan_begin_confidential (crypto->agent->ctx);
408 rc = send_to_agent (crypto->agent, &key, &keylen, "PKDECRYPT");
409 assuan_end_confidential (crypto->agent->ctx);
410 if (rc)
411 goto fail;
413 rc = gcry_sexp_new (&tmp_sexp, key, keylen, 1);
414 xfree (key);
415 if (rc)
416 goto fail;
418 key = (char *) gcry_sexp_nth_data (tmp_sexp, 1, result_len);
419 if (key)
421 *result = gcry_malloc (*result_len);
422 if (!*result)
423 rc = GPG_ERR_ENOMEM;
424 else
425 memcpy (*result, key, *result_len);
427 else
428 rc = GPG_ERR_BAD_DATA;
430 gcry_sexp_release (tmp_sexp);
432 fail:
433 xfree (idata.line);
434 xfree (hexgrip);
436 if (enc_sexp)
437 gcry_sexp_release (enc_sexp);
439 return rc;
442 gpg_error_t
443 agent_verify (gcry_sexp_t pkey, gcry_sexp_t sig_sexp, const void *data, size_t len)
445 gpg_error_t rc;
446 unsigned hashlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
447 unsigned char *hash;
448 gcry_sexp_t data_sexp;
450 hash = gcry_malloc (hashlen);
451 if (!hash)
452 return GPG_ERR_ENOMEM;
454 gcry_md_hash_buffer (GCRY_MD_SHA256, hash, data, len);
455 rc = gcry_sexp_build (&data_sexp, NULL,
456 "(data (flags pkcs1) (hash sha256 %b))", hashlen,
457 hash);
458 gcry_free (hash);
459 if (!rc)
461 rc = gcry_pk_verify (sig_sexp, data_sexp, pkey);
462 gcry_sexp_release (data_sexp);
465 return rc;
468 gpg_error_t
469 agent_loopback_cb (void *user, const char *keyword)
471 struct crypto_s *crypto = user;
472 gpg_error_t rc;
473 unsigned char *result;
474 size_t len;
475 int keyparam = 0;
477 if (!strcmp (keyword, "KEYPARAM"))
479 keyparam = 1;
480 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
482 else
483 { // PASSPHRASE or NEW_PASSPHRASE
484 assuan_begin_confidential (crypto->client_ctx);
485 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
486 assuan_end_confidential (crypto->client_ctx);
489 if (!rc)
491 if (keyparam && !len)
493 char *tmp = default_key_params (crypto);
495 if (!tmp)
496 return gpg_error (GPG_ERR_ENOMEM);
498 len = strlen (tmp);
499 result = xmalloc (len);
500 memcpy (result, tmp, len);
501 xfree (tmp);
504 pthread_cleanup_push (xfree, result);
506 if (keyparam)
507 rc = assuan_send_data (crypto->agent->ctx, result, len);
508 else
510 assuan_begin_confidential (crypto->agent->ctx);
511 rc = assuan_send_data (crypto->agent->ctx, result, len);
512 assuan_end_confidential (crypto->agent->ctx);
515 pthread_cleanup_pop (1);
517 else if (gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
519 gpg_error_t arc = assuan_write_line (crypto->agent->ctx, "CAN");
521 if (!arc)
523 char *line;
524 size_t len;
526 arc = assuan_read_line (crypto->agent->ctx, &line, &len);
527 if (arc)
528 rc = arc;
530 else
531 rc = arc;
534 return rc;
537 static gpg_error_t
538 sign (gcry_sexp_t * rsexp, const char *sign_hexgrip,
539 struct crypto_s *crypto, const void *data, size_t len)
541 gpg_error_t rc;
542 char *result;
543 char *tmp = sign_hexgrip ? str_dup (sign_hexgrip)
544 : bin2hex (crypto->grip, sizeof (crypto->grip));
546 pthread_cleanup_push (xfree, tmp);
547 log_write1 (_("Signed with keygrip %s"), tmp);
548 rc = send_to_agent (crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
549 pthread_cleanup_pop (1);
550 if (!rc)
552 unsigned char *hash;
553 unsigned hashlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
555 hash = gcry_malloc (hashlen);
556 if (!hash)
557 return GPG_ERR_ENOMEM;
559 gcry_md_hash_buffer (GCRY_MD_SHA256, hash, data, len);
560 tmp = bin2hex (hash, hashlen);
561 gcry_free (hash);
562 pthread_cleanup_push (xfree, tmp);
563 rc = send_to_agent (crypto->agent, NULL, NULL,
564 "SETHASH --hash=sha256 %s", tmp);
565 pthread_cleanup_pop (1);
568 if (!rc)
570 struct inquire_data_s idata = { 0 };
572 idata.crypto = crypto;
573 crypto->agent->inquire_data = &idata;
574 crypto->agent->inquire_cb = inquire_cb;
575 rc = send_to_agent (crypto->agent, &result, &len, "PKSIGN");
576 if (!rc)
578 rc = gcry_sexp_sscan (rsexp, NULL, result, len);
579 xfree (result);
583 return rc;
586 gpg_error_t
587 encrypt_data_file (assuan_context_t ctx, struct crypto_s * crypto,
588 gcry_sexp_t pubkey, gcry_sexp_t sigpkey,
589 const char *filename, const void *xml, size_t len)
591 gpg_error_t rc;
592 void *data = NULL;
593 size_t data_len = 0;
594 void *enc_xml = NULL;
595 size_t enc_xml_len = 0;
596 unsigned char *iv = NULL;
597 size_t iv_len = 0;
598 int algo = cipher_to_gcrypt (crypto->save.hdr.flags);
599 void *key = NULL;
600 size_t keysize;
601 unsigned char sig_grip[20];
602 unsigned char grip[20];
604 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
605 if (rc)
606 return rc;
608 pthread_cleanup_push (gcry_free, key);
609 key = gcry_random_bytes_secure (keysize, GCRY_STRONG_RANDOM);
610 #ifdef HAVE_PTHREAD_TESTCANCEL
611 pthread_testcancel (); // may have been a long operation
612 #endif
613 pthread_cleanup_pop (0);
614 if (!key)
615 return GPG_ERR_ENOMEM;
617 gcry_pk_get_keygrip (pubkey, grip);
618 gcry_pk_get_keygrip (sigpkey, sig_grip);
619 pthread_cleanup_push (xfree, iv);
620 pthread_cleanup_push (gcry_free, key);
621 rc = encrypt_xml (ctx, key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
622 &iv, &iv_len, crypto->save.hdr.iterations);
623 if (!rc)
625 gcry_sexp_t sig_sexp = NULL;
626 char *hexgrip = bin2hex (grip, 20);
628 log_write1 (_("Encrypted with keygrip %s"), hexgrip);
629 xfree (hexgrip);
630 hexgrip = bin2hex (sig_grip, 20);
631 pthread_cleanup_push (gcry_free, enc_xml);
632 rc = sign (&sig_sexp, hexgrip, crypto, enc_xml, enc_xml_len);
633 xfree (hexgrip);
635 if (!rc)
637 rc = agent_verify (sigpkey, sig_sexp, enc_xml, enc_xml_len);
639 if (!rc)
641 gcry_sexp_t tmp_sexp;
643 rc = gcry_sexp_build (&tmp_sexp, NULL,
644 "(data (flags pkcs1) (value %b))",
645 keysize, key);
646 if (!rc)
648 gcry_sexp_t key_sexp;
650 pthread_cleanup_push ((void (*)(void *)) gcry_sexp_release,
651 (void *) sig_sexp);
652 rc = gcry_pk_encrypt (&key_sexp, tmp_sexp, pubkey);
653 pthread_cleanup_pop (0);
654 gcry_sexp_release (tmp_sexp);
656 if (!rc)
658 memcpy (crypto->save.hdr.iv, iv, iv_len);
659 crypto->save.hdr.datalen = enc_xml_len;
660 rc = gcry_sexp_build (&tmp_sexp, NULL, "%S%S", key_sexp,
661 sig_sexp);
662 gcry_sexp_release (key_sexp);
664 if (!rc)
666 data_len = gcry_sexp_sprint (tmp_sexp,
667 GCRYSEXP_FMT_CANON,
668 NULL, 0);
669 data = xmalloc (data_len);
670 if (data)
671 gcry_sexp_sprint (tmp_sexp, GCRYSEXP_FMT_CANON,
672 data, data_len);
673 else
674 rc = GPG_ERR_ENOMEM;
676 gcry_sexp_release (tmp_sexp);
683 pthread_cleanup_pop (0); // enc_xml
685 if (sig_sexp)
686 gcry_sexp_release (sig_sexp);
689 pthread_cleanup_pop (1); // key
690 pthread_cleanup_pop (1); // iv
692 if (!rc)
694 pthread_cleanup_push (gcry_free, enc_xml);
695 rc = write_file (crypto, filename, enc_xml, enc_xml_len, data, data_len,
696 pubkey, sigpkey);
697 pthread_cleanup_pop (1); // enc_xml
698 if (!rc)
699 memcpy (&crypto->hdr, &crypto->save.hdr, sizeof (file_header_t));
702 xfree (data);
703 return rc;
709 gpg_error_t
710 generate_key (struct crypto_s * crypto, char *sexpstr, int empty, int preset)
712 gpg_error_t rc;
713 char *pkey;
714 size_t plen;
716 if (crypto->save.s2k_count)
718 rc = send_to_agent (crypto->agent, NULL, NULL,
719 "OPTION s2k-count=%lu", crypto->save.s2k_count);
720 if (rc)
721 return rc;
724 if (!crypto->agent->inquire_cb)
725 crypto->agent->inquire_cb = inquire_cb;
727 rc = send_to_agent (crypto->agent, &pkey, &plen, "GENKEY %s%s",
728 preset ? "--preset " : "",
729 empty ? "--no-protection" : "");
730 if (rc)
731 return rc;
733 if (crypto->save.pkey)
734 gcry_sexp_release (crypto->save.pkey);
736 crypto->save.pkey = NULL;
737 rc = gcry_sexp_new (&crypto->save.pkey, pkey, plen, 1);
738 if (!rc)
740 unsigned char grip[20];
742 gcry_pk_get_keygrip (crypto->save.pkey, grip);
743 char *hexgrip = bin2hex (grip, sizeof (grip));
744 log_write1 (_("Keygrip is %s"), hexgrip);
745 xfree (hexgrip);
747 if (!crypto->save.sigpkey)
749 gcry_sexp_build ((gcry_sexp_t *) & crypto->save.sigpkey, NULL, "%S",
750 crypto->save.pkey);
754 xfree (pkey);
755 return rc;
758 gpg_error_t
759 set_agent_option (struct agent_s * agent, const char *name, const char *value)
761 return send_to_agent (agent, NULL, NULL, "OPTION %s=%s", name, value);
764 gpg_error_t
765 set_agent_passphrase (struct crypto_s * crypto, const char *key, size_t len)
767 char *hexgrip;
768 struct inquire_data_s idata;
769 gpg_error_t rc;
770 int i;
772 /* This is for use with key files or passphrases obtained from an inquire.
773 * gpg-agent uses strings as passphrases and will truncate the passphrase
774 * at the first encountered null byte. It's only a warning because the
775 * passphrase may belong to a key shared outside of pwmd. */
776 for (i = 0; i < len; i++)
778 if (key[i] == 0)
780 log_write (_("WARNING: keylen=%i, truncated to %i."), len, i);
781 break;
785 hexgrip = bin2hex (crypto->grip, 20);
786 crypto->agent->inquire_cb = inquire_cb;
787 crypto->agent->inquire_data = &idata;
788 idata.crypto = crypto;
789 idata.line = (char *) key, idata.len = len;
790 idata.preset = 1;
791 assuan_begin_confidential (crypto->agent->ctx);
792 rc = send_to_agent (crypto->agent, NULL, NULL,
793 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
794 assuan_end_confidential (crypto->agent->ctx);
795 idata.preset = 0;
796 xfree (hexgrip);
797 return rc;
800 gpg_error_t
801 set_pinentry_mode (struct agent_s * agent, const char *mode)
803 return set_agent_option (agent, "pinentry-mode", mode);
806 gpg_error_t
807 get_pubkey_bin (struct crypto_s * crypto, const unsigned char *grip,
808 gcry_sexp_t * result)
810 char *hexgrip = bin2hex (grip, 20);
811 gpg_error_t rc;
813 if (!hexgrip)
814 return GPG_ERR_ENOMEM;
816 rc = get_pubkey (crypto, hexgrip, result);
817 xfree (hexgrip);
818 return rc;
821 gpg_error_t
822 get_pubkey (struct crypto_s * crypto, const char *grip, gcry_sexp_t * result)
824 char *pkey = NULL;
825 size_t plen;
826 gpg_error_t rc;
828 rc = send_to_agent (crypto->agent, &pkey, &plen, "READKEY %s", grip);
829 if (!rc)
830 rc = gcry_sexp_new (result, pkey, plen, 1);
832 xfree (pkey);
833 return rc;
836 gpg_error_t
837 agent_set_pinentry_options (struct agent_s * agent)
839 gpg_error_t rc = 0;
840 struct pinentry_option_s *opts = &agent->pinentry_opts;
842 if (!opts->display && getenv ("DISPLAY"))
844 rc = set_agent_option (agent, "display", getenv ("DISPLAY"));
845 if (!rc)
847 opts->display = str_dup (getenv ("DISPLAY"));
850 else if (!opts->ttyname && ttyname (STDOUT_FILENO))
852 rc = set_agent_option (agent, "ttyname", ttyname (STDOUT_FILENO));
853 if (!rc)
855 rc = set_agent_option (agent, "ttytype",
856 opts->ttytype ? opts->ttytype : getenv ("TERM"));
857 if (!rc)
859 xfree (opts->ttyname);
860 xfree (opts->ttytype);
861 opts->ttyname = str_dup (ttyname (STDOUT_FILENO));
862 opts->ttytype = str_dup (getenv ("TERM"));
867 return rc;
870 static gpg_error_t
871 inquire_keyfile (void *user, const char *keyword)
873 struct crypto_s *crypto = user;
874 char *filename = crypto->agent->inquire_data2;
875 char *params = crypto->agent->inquire_data3;
876 int fd;
877 struct stat st;
878 unsigned char *buf;
879 size_t len;
880 gpg_error_t rc;
882 if (!strcmp (keyword, "KEYPARAM"))
883 return assuan_send_data (crypto->agent->ctx, params, strlen (params));
885 // This function is only used when generating a new keypair.
886 if (strcmp (keyword, "NEW_PASSPHRASE"))
887 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
889 if (stat (filename, &st) == -1)
890 return gpg_error_from_syserror ();
892 if (crypto->agent->inquire_maxlen
893 && st.st_size > crypto->agent->inquire_maxlen)
895 log_write (_("The passphrase is too large: have=%u, max=%u."),
896 (unsigned) st.st_size, crypto->agent->inquire_maxlen);
897 return GPG_ERR_TOO_LARGE;
900 buf = gcry_malloc_secure (st.st_size);
901 if (!buf)
902 return GPG_ERR_ENOMEM;
904 fd = open (filename, O_RDONLY);
905 if (fd == -1)
906 rc = gpg_error_from_syserror ();
907 else
909 len = read (fd, buf, st.st_size);
910 if (len == st.st_size)
912 assuan_begin_confidential (crypto->agent->ctx);
913 rc = assuan_send_data (crypto->agent->ctx, buf, len);
914 assuan_end_confidential (crypto->agent->ctx);
916 else if (len == -1)
917 rc = gpg_error_from_syserror ();
918 else
919 rc = GPG_ERR_BUFFER_TOO_SHORT;
922 close (fd);
923 gcry_free (buf);
924 return rc;
927 gpg_error_t
928 agent_export_common (struct crypto_s * crypto, const char *hexgrip,
929 const char *sign_hexgrip, int no_passphrase,
930 const void *data, size_t datalen, const char *outfile,
931 const char *keyparams, const char *keyfile)
933 gpg_error_t rc = 0;
935 if (!sign_hexgrip && hexgrip)
936 sign_hexgrip = hexgrip;
938 if (sign_hexgrip)
940 if (crypto->sigpkey_sexp)
941 gcry_sexp_release (crypto->sigpkey_sexp);
943 crypto->sigpkey_sexp = NULL;
944 rc = get_pubkey (crypto, sign_hexgrip, &crypto->save.sigpkey);
945 if (rc)
946 return rc;
948 gcry_pk_get_keygrip (crypto->save.sigpkey, crypto->sign_grip);
951 if (hexgrip)
953 rc = get_pubkey (crypto, hexgrip, &crypto->save.pkey);
954 if (!rc)
955 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
957 else
959 struct inquire_data_s idata = { 0 };
960 char *params = keyparams ? str_dup (keyparams)
961 : default_key_params (crypto);
963 pthread_cleanup_push (xfree, params);
964 log_write (_("Generating a new keypair ..."));
965 if (keyfile)
967 log_write (_("Using passphrase obtained from file '%s'"), keyfile);
968 rc = set_pinentry_mode (crypto->agent, "loopback");
969 crypto->agent->inquire_cb = inquire_keyfile;
970 crypto->agent->inquire_data = crypto;
971 crypto->agent->inquire_data2 = (char *) keyfile;
972 crypto->agent->inquire_data3 = params;
974 else
976 idata.line = params;
977 idata.len = strlen (params);
978 idata.crypto = crypto;
979 crypto->agent->inquire_cb = inquire_cb;
980 crypto->agent->inquire_data = &idata;
983 if (!rc)
985 rc = generate_key (crypto, params, no_passphrase, 1);
986 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
989 (void) set_pinentry_mode (crypto->agent, "ask");
990 pthread_cleanup_pop (1);
993 if (!rc)
995 rc = encrypt_data_file (NULL, crypto, crypto->save.pkey,
996 crypto->save.sigpkey, outfile, data, datalen);
997 if (!rc)
999 char *tmp = bin2hex (crypto->grip, sizeof (crypto->grip));
1001 log_write (_("Success! Keygrip is %s."), tmp);
1002 rc = send_to_agent (crypto->agent, NULL, NULL,
1003 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1004 xfree (tmp);
1006 if (sign_hexgrip)
1008 tmp = bin2hex (crypto->sign_grip, sizeof (crypto->sign_grip));
1009 log_write (_("Signed with keygrip %s."), tmp);
1010 xfree (tmp);
1015 return rc;
1018 char *
1019 default_key_params (struct crypto_s *crypto)
1021 int len = config_get_integer (NULL, "nbits");
1022 char buf[32];
1023 char *algo = config_get_string (NULL, "algo");
1024 char *result;
1026 snprintf (buf, sizeof (buf), "%i", len);
1027 result = str_asprintf ("(genkey (%s (nbits %lu:%i)))", algo, strlen (buf),
1028 len);
1029 xfree (algo);
1030 return result;
1033 gpg_error_t
1034 agent_passwd (struct crypto_s * crypto)
1036 struct inquire_data_s idata = { 0 };
1037 gpg_error_t rc;
1038 char *tmp = bin2hex (crypto->grip, 20);
1040 idata.crypto = crypto;
1041 crypto->agent->inquire_cb = inquire_cb;
1042 crypto->agent->inquire_data = &idata;
1043 rc = send_to_agent (crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1044 xfree (tmp);
1045 return rc;
1048 gpg_error_t
1049 kill_scd (struct agent_s * agent)
1051 gpg_error_t rc = 0;
1053 if (!use_agent)
1054 return 0;
1056 if (config_get_boolean (NULL, "kill_scd"))
1058 rc = send_to_agent (agent, NULL, NULL, "SCD KILLSCD");
1059 if (rc && gpg_err_code (rc) != GPG_ERR_NO_SCDAEMON)
1060 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (rc));
1063 return rc;