Keep the GPG_AGENT_INFO environment variable on failure.
[pwmd.git] / src / agent.c
blob3c9a7c03f6cdeb724fad02f7289086dfc6bf26c9
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
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 agent->did_restart = 0;
142 s = config_get_string ("global", "agent_env_file");
143 if (s)
145 char *ss = expand_homedir (s);
146 char *p;
148 fp = fopen (ss, "r");
149 xfree (ss);
151 if (fp)
153 while ((p = fgets (buf, sizeof (buf), fp)))
155 p = str_chomp (p);
156 if (!strncmp (p, "GPG_AGENT_INFO=", strlen ("GPG_AGENT_INFO=")))
158 setenv ("GPG_AGENT_INFO", p + strlen ("GPG_AGENT_INFO="),
160 break;
164 fclose (fp);
166 else
167 log_write ("%s: %s", s, pwmd_strerror (gpg_error_from_syserror ()));
169 xfree (s);
172 t = getenv ("GPG_AGENT_INFO");
173 if (!t)
174 return gpg_error (GPG_ERR_NO_AGENT);
176 rc = assuan_new_ext (&ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
177 debug_level ? assuan_log_cb : NULL, "AGENT ");
178 if (rc)
179 return rc;
181 char **fields = str_split (t, ":", 0);
182 rc = assuan_socket_connect (ctx, fields[0], ASSUAN_INVALID_PID, 0);
183 strv_free (fields);
184 if (rc)
186 if (ctx)
187 assuan_release (ctx);
188 return rc;
191 if (agent->ctx)
192 assuan_release (agent->ctx);
194 agent->ctx = ctx;
195 rc = send_agent_common_options (agent);
196 if (!rc && agent->pinentry_opts.display)
197 rc = set_agent_option (agent, "display", agent->pinentry_opts.display);
199 if (!rc && agent->pinentry_opts.ttyname)
200 rc = set_agent_option (agent, "ttyname", agent->pinentry_opts.ttyname);
202 if (!rc && agent->pinentry_opts.ttytype)
203 rc = set_agent_option (agent, "ttytype", agent->pinentry_opts.ttytype);
205 if (!rc && agent->pinentry_opts.lc_messages)
206 rc = set_agent_option (agent, "lc-messages",
207 agent->pinentry_opts.lc_messages);
209 if (!rc && agent->pinentry_opts.lc_ctype)
210 rc = set_agent_option (agent, "lc-ctype", agent->pinentry_opts.lc_ctype);
212 return 0;
215 gpg_error_t
216 send_to_agent (struct agent_s * agent, char **result, size_t * len,
217 const char *fmt, ...)
219 gpg_error_t rc = 0;
220 va_list ap;
221 char *cmd;
223 if (!agent->ctx)
225 rc = launch_agent (agent);
226 if (rc)
227 return rc;
230 va_start (ap, fmt);
231 if (str_vasprintf (&cmd, fmt, ap) > 0)
233 rc = assuan_command (agent, result, len, cmd);
234 if (!agent->restart && gpg_err_source (rc) == GPG_ERR_SOURCE_DEFAULT
235 && (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED
236 || gpg_err_code (rc) == GPG_ERR_EPIPE))
238 agent->restart = 1;
239 rc = launch_agent (agent);
240 if (!rc)
242 agent->did_restart = 1;
243 rc = assuan_command (agent, result, len, cmd);
247 agent->restart = 0;
248 xfree (cmd);
250 else
251 rc = GPG_ERR_ENOMEM;
253 va_end (ap);
254 return rc;
257 static void
258 agent_disconnect (struct agent_s *agent)
260 if (!agent)
261 return;
263 if (agent->ctx)
264 assuan_release (agent->ctx);
266 agent->ctx = NULL;
269 void
270 cleanup_agent (struct agent_s *agent)
272 if (!agent)
273 return;
275 pinentry_free_opts (&agent->pinentry_opts);
276 agent_disconnect (agent);
277 xfree (agent);
280 gpg_error_t
281 agent_init (struct agent_s **agent)
283 struct agent_s *new = xcalloc (1, sizeof (struct agent_s));
285 if (!new)
286 return GPG_ERR_ENOMEM;
288 *agent = new;
289 return 0;
292 static gpg_error_t
293 inquire_cb (void *user, const char *keyword)
295 struct inquire_data_s *idata = user;
297 if (!idata->preset && (!strcmp (keyword, "PASSPHRASE")
298 || !strcmp (keyword, "NEW_PASSPHRASE")))
300 return agent_loopback_cb (idata->crypto, keyword);
302 // SAVE --inquire-keyparam
303 else if (idata->preset && !strcmp (keyword, "KEYPARAM"))
305 idata->preset = 0;
306 return agent_loopback_cb (idata->crypto, keyword);
309 if (idata->crypto->agent->inquire_maxlen
310 && idata->len > idata->crypto->agent->inquire_maxlen)
312 log_write (_("Inquired data too large: have=%u, max=%u"), idata->len,
313 idata->crypto->agent->inquire_maxlen);
314 return GPG_ERR_TOO_LARGE;
317 idata->crypto->agent->inquire_maxlen = 0;
318 return assuan_send_data (idata->crypto->agent->ctx, idata->line,
319 idata->len);
322 gpg_error_t
323 agent_extract_key (struct crypto_s *crypto, unsigned char **result,
324 size_t * result_len)
326 gpg_error_t rc;
327 gcry_sexp_t enc_sexp = NULL, tmp_sexp;
328 struct inquire_data_s idata = { 0 };
329 char *hexgrip = NULL;
330 char *key;
331 size_t keylen, keysize;
332 char *tmp;
333 int algo = cipher_to_gcrypt (crypto->hdr.flags);
334 int shadowed;
336 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
337 if (rc)
338 return rc;
340 tmp_sexp = gcry_sexp_find_token (crypto->ciphertext_sexp, "enc-val", 0);
341 if (!tmp_sexp)
342 return GPG_ERR_BAD_DATA;
344 hexgrip = bin2hex (crypto->grip, sizeof (crypto->grip));
345 if (!hexgrip)
347 rc = GPG_ERR_ENOMEM;
348 goto fail;
351 rc = cache_is_shadowed (hexgrip);
352 if (rc && rc != GPG_ERR_NO_DATA)
353 goto fail;
355 shadowed = !rc ? 1 : 0;
356 if (!shadowed)
358 gcry_sexp_t tmp2_sexp = gcry_sexp_cdr (tmp_sexp);
359 gcry_sexp_release (tmp_sexp);
360 tmp_sexp = gcry_sexp_nth (tmp2_sexp, 0);
361 gcry_sexp_release (tmp2_sexp);
362 rc = gcry_sexp_build (&enc_sexp, NULL, "(enc-val (flags pkcs1) %S)",
363 tmp_sexp);
365 else
366 rc = gcry_sexp_build (&enc_sexp, NULL, "%S", tmp_sexp);
368 gcry_sexp_release (tmp_sexp);
369 if (rc)
370 return rc;
372 crypto->agent->inquire_cb = inquire_cb;
373 idata.crypto = crypto;
374 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
375 idata.line = xmalloc (idata.len);
376 if (!idata.line)
378 rc = GPG_ERR_ENOMEM;
379 goto fail;
382 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, idata.line,
383 idata.len);
384 crypto->agent->inquire_data = &idata;
385 gcry_sexp_release (enc_sexp);
386 enc_sexp = NULL;
387 log_write1 (_("Keygrip is %s, bits=%i"), hexgrip,
388 gcry_pk_get_nbits (crypto->pkey_sexp));
389 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEY %s", hexgrip);
390 if (rc)
391 goto fail;
393 if (!crypto->agent->pinentry_opts.desc)
395 tmp =
396 plus_escape (_
397 ("A %s is required to unlock the secret key for the "
398 "encrypted data file \"%s\". Please enter the %s "
399 "below."), shadowed ? "PIN" : _("passphrase"),
400 crypto->filename, shadowed ? "PIN" : _("passphrase"));
402 else
403 tmp = plus_escape (crypto->agent->pinentry_opts.desc);
405 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEYDESC %s", tmp);
406 xfree (tmp);
407 if (rc)
408 goto fail;
410 assuan_begin_confidential (crypto->agent->ctx);
411 rc = send_to_agent (crypto->agent, &key, &keylen, "PKDECRYPT");
412 assuan_end_confidential (crypto->agent->ctx);
413 if (rc)
414 goto fail;
416 rc = gcry_sexp_new (&tmp_sexp, key, keylen, 1);
417 xfree (key);
418 if (rc)
419 goto fail;
421 key = (char *) gcry_sexp_nth_data (tmp_sexp, 1, result_len);
422 if (key)
424 *result = gcry_malloc (*result_len);
425 if (!*result)
426 rc = GPG_ERR_ENOMEM;
427 else
428 memcpy (*result, key, *result_len);
430 else
431 rc = GPG_ERR_BAD_DATA;
433 gcry_sexp_release (tmp_sexp);
435 fail:
436 xfree (idata.line);
437 xfree (hexgrip);
439 if (enc_sexp)
440 gcry_sexp_release (enc_sexp);
442 return rc;
445 gpg_error_t
446 agent_verify (gcry_sexp_t pkey, gcry_sexp_t sig_sexp, const void *data, size_t len)
448 gpg_error_t rc;
449 unsigned hashlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
450 unsigned char *hash;
451 gcry_sexp_t data_sexp;
453 hash = gcry_malloc (hashlen);
454 if (!hash)
455 return GPG_ERR_ENOMEM;
457 gcry_md_hash_buffer (GCRY_MD_SHA256, hash, data, len);
458 rc = gcry_sexp_build (&data_sexp, NULL,
459 "(data (flags pkcs1) (hash sha256 %b))", hashlen,
460 hash);
461 gcry_free (hash);
462 if (!rc)
464 rc = gcry_pk_verify (sig_sexp, data_sexp, pkey);
465 gcry_sexp_release (data_sexp);
468 return rc;
471 gpg_error_t
472 agent_loopback_cb (void *user, const char *keyword)
474 struct crypto_s *crypto = user;
475 gpg_error_t rc;
476 unsigned char *result;
477 size_t len;
478 int keyparam = 0;
480 if (!strcmp (keyword, "KEYPARAM"))
482 keyparam = 1;
483 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
485 else
486 { // PASSPHRASE or NEW_PASSPHRASE
487 assuan_begin_confidential (crypto->client_ctx);
488 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
489 assuan_end_confidential (crypto->client_ctx);
492 if (!rc)
494 if (keyparam && !len)
496 char *tmp = default_key_params (crypto);
498 if (!tmp)
499 return gpg_error (GPG_ERR_ENOMEM);
501 len = strlen (tmp);
502 result = xmalloc (len);
503 memcpy (result, tmp, len);
504 xfree (tmp);
507 pthread_cleanup_push (xfree, result);
509 if (keyparam)
510 rc = assuan_send_data (crypto->agent->ctx, result, len);
511 else
513 assuan_begin_confidential (crypto->agent->ctx);
514 rc = assuan_send_data (crypto->agent->ctx, result, len);
515 assuan_end_confidential (crypto->agent->ctx);
518 pthread_cleanup_pop (1);
520 else if (gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
522 gpg_error_t arc = assuan_write_line (crypto->agent->ctx, "CAN");
524 if (!arc)
526 char *line;
527 size_t len;
529 arc = assuan_read_line (crypto->agent->ctx, &line, &len);
530 if (arc)
531 rc = arc;
533 else
534 rc = arc;
537 return rc;
540 static gpg_error_t
541 sign (gcry_sexp_t * rsexp, const char *sign_hexgrip,
542 struct crypto_s *crypto, const void *data, size_t len)
544 gpg_error_t rc;
545 char *result;
546 char *tmp = sign_hexgrip ? str_dup (sign_hexgrip)
547 : bin2hex (crypto->grip, sizeof (crypto->grip));
549 pthread_cleanup_push (xfree, tmp);
550 log_write1 (_("Signed with keygrip %s"), tmp);
551 rc = send_to_agent (crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
552 pthread_cleanup_pop (1);
553 if (!rc)
555 unsigned char *hash;
556 unsigned hashlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
558 hash = gcry_malloc (hashlen);
559 if (!hash)
560 return GPG_ERR_ENOMEM;
562 gcry_md_hash_buffer (GCRY_MD_SHA256, hash, data, len);
563 tmp = bin2hex (hash, hashlen);
564 gcry_free (hash);
565 pthread_cleanup_push (xfree, tmp);
566 rc = send_to_agent (crypto->agent, NULL, NULL,
567 "SETHASH --hash=sha256 %s", tmp);
568 pthread_cleanup_pop (1);
571 if (!rc)
573 struct inquire_data_s idata = { 0 };
575 idata.crypto = crypto;
576 crypto->agent->inquire_data = &idata;
577 crypto->agent->inquire_cb = inquire_cb;
578 rc = send_to_agent (crypto->agent, &result, &len, "PKSIGN");
579 if (!rc)
581 rc = gcry_sexp_sscan (rsexp, NULL, result, len);
582 xfree (result);
586 return rc;
589 gpg_error_t
590 encrypt_data_file (assuan_context_t ctx, struct crypto_s * crypto,
591 gcry_sexp_t pubkey, gcry_sexp_t sigpkey,
592 const char *filename, const void *xml, size_t len)
594 gpg_error_t rc;
595 void *data = NULL;
596 size_t data_len = 0;
597 void *enc_xml = NULL;
598 size_t enc_xml_len = 0;
599 unsigned char *iv = NULL;
600 size_t iv_len = 0;
601 int algo = cipher_to_gcrypt (crypto->save.hdr.flags);
602 void *key = NULL;
603 size_t keysize;
604 unsigned char sig_grip[20];
605 unsigned char grip[20];
607 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
608 if (rc)
609 return rc;
611 pthread_cleanup_push (gcry_free, key);
612 key = gcry_random_bytes_secure (keysize, GCRY_STRONG_RANDOM);
613 #ifdef HAVE_PTHREAD_TESTCANCEL
614 pthread_testcancel (); // may have been a long operation
615 #endif
616 pthread_cleanup_pop (0);
617 if (!key)
618 return GPG_ERR_ENOMEM;
620 gcry_pk_get_keygrip (pubkey, grip);
621 gcry_pk_get_keygrip (sigpkey, sig_grip);
622 pthread_cleanup_push (xfree, iv);
623 pthread_cleanup_push (gcry_free, key);
624 rc = encrypt_xml (ctx, key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
625 &iv, &iv_len, crypto->save.hdr.iterations);
626 if (!rc)
628 gcry_sexp_t sig_sexp = NULL;
629 char *hexgrip = bin2hex (grip, 20);
631 log_write1 (_("Encrypted with keygrip %s"), hexgrip);
632 xfree (hexgrip);
633 hexgrip = bin2hex (sig_grip, 20);
634 pthread_cleanup_push (gcry_free, enc_xml);
635 rc = sign (&sig_sexp, hexgrip, crypto, enc_xml, enc_xml_len);
636 xfree (hexgrip);
638 if (!rc)
640 rc = agent_verify (sigpkey, sig_sexp, enc_xml, enc_xml_len);
642 if (!rc)
644 gcry_sexp_t tmp_sexp;
646 rc = gcry_sexp_build (&tmp_sexp, NULL,
647 "(data (flags pkcs1) (value %b))",
648 keysize, key);
649 if (!rc)
651 gcry_sexp_t key_sexp;
653 pthread_cleanup_push ((void (*)(void *)) gcry_sexp_release,
654 (void *) sig_sexp);
655 rc = gcry_pk_encrypt (&key_sexp, tmp_sexp, pubkey);
656 pthread_cleanup_pop (0);
657 gcry_sexp_release (tmp_sexp);
659 if (!rc)
661 memcpy (crypto->save.hdr.iv, iv, iv_len);
662 crypto->save.hdr.datalen = enc_xml_len;
663 rc = gcry_sexp_build (&tmp_sexp, NULL, "%S%S", key_sexp,
664 sig_sexp);
665 gcry_sexp_release (key_sexp);
667 if (!rc)
669 data_len = gcry_sexp_sprint (tmp_sexp,
670 GCRYSEXP_FMT_CANON,
671 NULL, 0);
672 data = xmalloc (data_len);
673 if (data)
674 gcry_sexp_sprint (tmp_sexp, GCRYSEXP_FMT_CANON,
675 data, data_len);
676 else
677 rc = GPG_ERR_ENOMEM;
679 gcry_sexp_release (tmp_sexp);
686 pthread_cleanup_pop (0); // enc_xml
688 if (sig_sexp)
689 gcry_sexp_release (sig_sexp);
692 pthread_cleanup_pop (1); // key
693 pthread_cleanup_pop (1); // iv
695 if (!rc)
697 pthread_cleanup_push (gcry_free, enc_xml);
698 rc = write_file (crypto, filename, enc_xml, enc_xml_len, data, data_len,
699 pubkey, sigpkey);
700 pthread_cleanup_pop (1); // enc_xml
701 if (!rc)
702 memcpy (&crypto->hdr, &crypto->save.hdr, sizeof (file_header_t));
705 xfree (data);
706 return rc;
712 gpg_error_t
713 generate_key (struct crypto_s * crypto, char *sexpstr, int empty, int preset)
715 gpg_error_t rc;
716 char *pkey;
717 size_t plen;
719 if (crypto->save.s2k_count)
721 rc = send_to_agent (crypto->agent, NULL, NULL,
722 "OPTION s2k-count=%lu", crypto->save.s2k_count);
723 if (rc)
724 return rc;
727 if (!crypto->agent->inquire_cb)
728 crypto->agent->inquire_cb = inquire_cb;
730 rc = send_to_agent (crypto->agent, &pkey, &plen, "GENKEY %s%s",
731 preset ? "--preset " : "",
732 empty ? "--no-protection" : "");
733 if (rc)
734 return rc;
736 if (crypto->save.pkey)
737 gcry_sexp_release (crypto->save.pkey);
739 crypto->save.pkey = NULL;
740 rc = gcry_sexp_new (&crypto->save.pkey, pkey, plen, 1);
741 if (!rc)
743 unsigned char grip[20];
745 gcry_pk_get_keygrip (crypto->save.pkey, grip);
746 char *hexgrip = bin2hex (grip, sizeof (grip));
747 log_write1 (_("Keygrip is %s"), hexgrip);
748 xfree (hexgrip);
750 if (!crypto->save.sigpkey)
752 gcry_sexp_build ((gcry_sexp_t *) & crypto->save.sigpkey, NULL, "%S",
753 crypto->save.pkey);
757 xfree (pkey);
758 return rc;
761 gpg_error_t
762 set_agent_option (struct agent_s * agent, const char *name, const char *value)
764 return send_to_agent (agent, NULL, NULL, "OPTION %s=%s", name, value);
767 gpg_error_t
768 set_agent_passphrase (struct crypto_s * crypto, const char *key, size_t len)
770 char *hexgrip;
771 struct inquire_data_s idata;
772 gpg_error_t rc;
773 int i;
775 /* This is for use with key files or passphrases obtained from an inquire.
776 * gpg-agent uses strings as passphrases and will truncate the passphrase
777 * at the first encountered null byte. It's only a warning because the
778 * passphrase may belong to a key shared outside of pwmd. */
779 for (i = 0; i < len; i++)
781 if (key[i] == 0)
783 log_write (_("WARNING: keylen=%i, truncated to %i."), len, i);
784 break;
788 hexgrip = bin2hex (crypto->grip, 20);
789 crypto->agent->inquire_cb = inquire_cb;
790 crypto->agent->inquire_data = &idata;
791 idata.crypto = crypto;
792 idata.line = (char *) key, idata.len = len;
793 idata.preset = 1;
794 assuan_begin_confidential (crypto->agent->ctx);
795 rc = send_to_agent (crypto->agent, NULL, NULL,
796 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
797 assuan_end_confidential (crypto->agent->ctx);
798 idata.preset = 0;
799 xfree (hexgrip);
800 return rc;
803 gpg_error_t
804 set_pinentry_mode (struct agent_s * agent, const char *mode)
806 return set_agent_option (agent, "pinentry-mode", mode);
809 gpg_error_t
810 get_pubkey_bin (struct crypto_s * crypto, const unsigned char *grip,
811 gcry_sexp_t * result)
813 char *hexgrip = bin2hex (grip, 20);
814 gpg_error_t rc;
816 if (!hexgrip)
817 return GPG_ERR_ENOMEM;
819 rc = get_pubkey (crypto, hexgrip, result);
820 xfree (hexgrip);
821 return rc;
824 gpg_error_t
825 get_pubkey (struct crypto_s * crypto, const char *grip, gcry_sexp_t * result)
827 char *pkey = NULL;
828 size_t plen;
829 gpg_error_t rc;
831 rc = send_to_agent (crypto->agent, &pkey, &plen, "READKEY %s", grip);
832 if (!rc)
833 rc = gcry_sexp_new (result, pkey, plen, 1);
835 xfree (pkey);
836 return rc;
839 gpg_error_t
840 agent_set_pinentry_options (struct agent_s * agent)
842 gpg_error_t rc = 0;
843 struct pinentry_option_s *opts = &agent->pinentry_opts;
845 if (!opts->display && getenv ("DISPLAY"))
847 rc = set_agent_option (agent, "display", getenv ("DISPLAY"));
848 if (!rc)
850 opts->display = str_dup (getenv ("DISPLAY"));
853 else if (!opts->ttyname && ttyname (STDOUT_FILENO))
855 rc = set_agent_option (agent, "ttyname", ttyname (STDOUT_FILENO));
856 if (!rc)
858 rc = set_agent_option (agent, "ttytype",
859 opts->ttytype ? opts->ttytype : getenv ("TERM"));
860 if (!rc)
862 xfree (opts->ttyname);
863 xfree (opts->ttytype);
864 opts->ttyname = str_dup (ttyname (STDOUT_FILENO));
865 opts->ttytype = str_dup (getenv ("TERM"));
870 return rc;
873 static gpg_error_t
874 inquire_keyfile (void *user, const char *keyword)
876 struct crypto_s *crypto = user;
877 char *filename = crypto->agent->inquire_data2;
878 char *params = crypto->agent->inquire_data3;
879 int fd;
880 struct stat st;
881 unsigned char *buf;
882 size_t len;
883 gpg_error_t rc;
885 if (!strcmp (keyword, "KEYPARAM"))
886 return assuan_send_data (crypto->agent->ctx, params, strlen (params));
888 // This function is only used when generating a new keypair.
889 if (strcmp (keyword, "NEW_PASSPHRASE"))
890 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
892 if (stat (filename, &st) == -1)
893 return gpg_error_from_syserror ();
895 if (crypto->agent->inquire_maxlen
896 && st.st_size > crypto->agent->inquire_maxlen)
898 log_write (_("The passphrase is too large: have=%u, max=%u."),
899 (unsigned) st.st_size, crypto->agent->inquire_maxlen);
900 return GPG_ERR_TOO_LARGE;
903 buf = gcry_malloc_secure (st.st_size);
904 if (!buf)
905 return GPG_ERR_ENOMEM;
907 fd = open (filename, O_RDONLY);
908 if (fd == -1)
909 rc = gpg_error_from_syserror ();
910 else
912 len = read (fd, buf, st.st_size);
913 if (len == st.st_size)
915 assuan_begin_confidential (crypto->agent->ctx);
916 rc = assuan_send_data (crypto->agent->ctx, buf, len);
917 assuan_end_confidential (crypto->agent->ctx);
919 else if (len == -1)
920 rc = gpg_error_from_syserror ();
921 else
922 rc = GPG_ERR_BUFFER_TOO_SHORT;
925 close (fd);
926 gcry_free (buf);
927 return rc;
930 gpg_error_t
931 agent_export_common (struct crypto_s * crypto, const char *hexgrip,
932 const char *sign_hexgrip, int no_passphrase,
933 const void *data, size_t datalen, const char *outfile,
934 const char *keyparams, const char *keyfile)
936 gpg_error_t rc = 0;
938 if (!sign_hexgrip && hexgrip)
939 sign_hexgrip = hexgrip;
941 if (sign_hexgrip)
943 if (crypto->sigpkey_sexp)
944 gcry_sexp_release (crypto->sigpkey_sexp);
946 crypto->sigpkey_sexp = NULL;
947 rc = get_pubkey (crypto, sign_hexgrip, &crypto->save.sigpkey);
948 if (rc)
949 return rc;
951 gcry_pk_get_keygrip (crypto->save.sigpkey, crypto->sign_grip);
954 if (hexgrip)
956 rc = get_pubkey (crypto, hexgrip, &crypto->save.pkey);
957 if (!rc)
958 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
960 else
962 struct inquire_data_s idata = { 0 };
963 char *params = keyparams ? str_dup (keyparams)
964 : default_key_params (crypto);
966 pthread_cleanup_push (xfree, params);
967 log_write (_("Generating a new keypair ..."));
968 if (keyfile)
970 log_write (_("Using passphrase obtained from file '%s'"), keyfile);
971 rc = set_pinentry_mode (crypto->agent, "loopback");
972 crypto->agent->inquire_cb = inquire_keyfile;
973 crypto->agent->inquire_data = crypto;
974 crypto->agent->inquire_data2 = (char *) keyfile;
975 crypto->agent->inquire_data3 = params;
977 else
979 idata.line = params;
980 idata.len = strlen (params);
981 idata.crypto = crypto;
982 crypto->agent->inquire_cb = inquire_cb;
983 crypto->agent->inquire_data = &idata;
986 if (!rc)
988 rc = generate_key (crypto, params, no_passphrase, 1);
989 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
992 (void) set_pinentry_mode (crypto->agent, "ask");
993 pthread_cleanup_pop (1);
996 if (!rc)
998 rc = encrypt_data_file (NULL, crypto, crypto->save.pkey,
999 crypto->save.sigpkey, outfile, data, datalen);
1000 if (!rc)
1002 char *tmp = bin2hex (crypto->grip, sizeof (crypto->grip));
1004 log_write (_("Success! Keygrip is %s."), tmp);
1005 rc = send_to_agent (crypto->agent, NULL, NULL,
1006 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1007 xfree (tmp);
1009 if (sign_hexgrip)
1011 tmp = bin2hex (crypto->sign_grip, sizeof (crypto->sign_grip));
1012 log_write (_("Signed with keygrip %s."), tmp);
1013 xfree (tmp);
1018 return rc;
1021 char *
1022 default_key_params (struct crypto_s *crypto)
1024 int len = config_get_integer (NULL, "nbits");
1025 char buf[32];
1026 char *algo = config_get_string (NULL, "algo");
1027 char *result;
1029 snprintf (buf, sizeof (buf), "%i", len);
1030 result = str_asprintf ("(genkey (%s (nbits %lu:%i)))", algo, strlen (buf),
1031 len);
1032 xfree (algo);
1033 return result;
1036 gpg_error_t
1037 agent_passwd (struct crypto_s * crypto)
1039 struct inquire_data_s idata = { 0 };
1040 gpg_error_t rc;
1041 char *tmp = bin2hex (crypto->grip, 20);
1043 idata.crypto = crypto;
1044 crypto->agent->inquire_cb = inquire_cb;
1045 crypto->agent->inquire_data = &idata;
1046 rc = send_to_agent (crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1047 xfree (tmp);
1048 return rc;
1051 gpg_error_t
1052 kill_scd (struct agent_s * agent)
1054 gpg_error_t rc = 0;
1056 if (!use_agent)
1057 return 0;
1059 if (config_get_boolean (NULL, "kill_scd"))
1061 rc = send_to_agent (agent, NULL, NULL, "SCD KILLSCD");
1062 if (rc && gpg_err_code (rc) != GPG_ERR_NO_SCDAEMON)
1063 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (rc));
1066 return rc;