Fix signing and verification when using DSA keys.
[pwmd.git] / src / agent.c
blob4f0e469764d30ef52ff5fa466392a1d060572ce4
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 log_write (_ ("gpg-agent connection died (rc=%i), reconnecting"), rc);
239 agent->restart = 1;
240 rc = launch_agent (agent);
241 if (!rc)
243 agent->did_restart = 1;
244 rc = assuan_command (agent, result, len, cmd);
248 agent->restart = 0;
249 xfree (cmd);
251 else
252 rc = GPG_ERR_ENOMEM;
254 va_end (ap);
255 return rc;
258 static void
259 agent_disconnect (struct agent_s *agent)
261 if (!agent)
262 return;
264 if (agent->ctx)
265 assuan_release (agent->ctx);
267 agent->ctx = NULL;
270 void
271 cleanup_agent (struct agent_s *agent)
273 if (!agent)
274 return;
276 pinentry_free_opts (&agent->pinentry_opts);
277 agent_disconnect (agent);
278 xfree (agent);
281 gpg_error_t
282 agent_init (struct agent_s **agent)
284 struct agent_s *new = xcalloc (1, sizeof (struct agent_s));
286 if (!new)
287 return GPG_ERR_ENOMEM;
289 *agent = new;
290 return 0;
293 static gpg_error_t
294 inquire_cb (void *user, const char *keyword)
296 struct inquire_data_s *idata = user;
298 if (!idata->preset && (!strcmp (keyword, "PASSPHRASE")
299 || !strcmp (keyword, "NEW_PASSPHRASE")))
301 return agent_loopback_cb (idata->crypto, keyword);
303 // SAVE --inquire-keyparam
304 else if (idata->preset && !strcmp (keyword, "KEYPARAM"))
306 idata->preset = 0;
307 return agent_loopback_cb (idata->crypto, keyword);
310 if (idata->crypto->agent->inquire_maxlen
311 && idata->len > idata->crypto->agent->inquire_maxlen)
313 log_write (_("Inquired data too large: have=%u, max=%u"), idata->len,
314 idata->crypto->agent->inquire_maxlen);
315 return GPG_ERR_TOO_LARGE;
318 idata->crypto->agent->inquire_maxlen = 0;
319 return assuan_send_data (idata->crypto->agent->ctx, idata->line,
320 idata->len);
323 gpg_error_t
324 agent_extract_key (struct crypto_s *crypto, unsigned char **result,
325 size_t * result_len)
327 gpg_error_t rc;
328 gcry_sexp_t enc_sexp = NULL, tmp_sexp;
329 struct inquire_data_s idata = { 0 };
330 char *hexgrip = NULL;
331 char *key;
332 size_t keylen, keysize;
333 char *tmp;
334 int algo = cipher_to_gcrypt (crypto->hdr.flags);
335 int shadowed;
337 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
338 if (rc)
339 return rc;
341 tmp_sexp = gcry_sexp_find_token (crypto->ciphertext_sexp, "enc-val", 0);
342 if (!tmp_sexp)
343 return gpg_error (GPG_ERR_BAD_DATA);
345 hexgrip = bin2hex (crypto->grip, sizeof (crypto->grip));
346 if (!hexgrip)
348 rc = GPG_ERR_ENOMEM;
349 goto fail;
352 rc = cache_is_shadowed (hexgrip);
353 if (rc && rc != GPG_ERR_NO_DATA)
354 goto fail;
356 shadowed = !rc ? 1 : 0;
357 if (!shadowed)
359 gcry_sexp_t tmp2_sexp = gcry_sexp_cdr (tmp_sexp);
360 gcry_sexp_release (tmp_sexp);
361 tmp_sexp = gcry_sexp_nth (tmp2_sexp, 0);
362 gcry_sexp_release (tmp2_sexp);
363 rc = gcry_sexp_build (&enc_sexp, NULL, "(enc-val (flags pkcs1) %S)",
364 tmp_sexp);
366 else
367 rc = gcry_sexp_build (&enc_sexp, NULL, "%S", tmp_sexp);
369 gcry_sexp_release (tmp_sexp);
370 if (rc)
371 return rc;
373 crypto->agent->inquire_cb = inquire_cb;
374 idata.crypto = crypto;
375 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
376 idata.line = xmalloc (idata.len);
377 if (!idata.line)
379 rc = GPG_ERR_ENOMEM;
380 goto fail;
383 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, idata.line,
384 idata.len);
385 crypto->agent->inquire_data = &idata;
386 gcry_sexp_release (enc_sexp);
387 enc_sexp = NULL;
388 log_write1 (_("Keygrip is %s, bits=%i"), hexgrip,
389 gcry_pk_get_nbits (crypto->pkey_sexp));
390 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEY %s", hexgrip);
391 if (rc)
392 goto fail;
394 if (!crypto->agent->pinentry_opts.desc)
396 tmp =
397 plus_escape (_
398 ("A %s is required to unlock the secret key for the "
399 "encrypted data file \"%s\". Please enter the %s "
400 "below."), shadowed ? "PIN" : _("passphrase"),
401 crypto->filename, shadowed ? "PIN" : _("passphrase"));
403 else
404 tmp = plus_escape (crypto->agent->pinentry_opts.desc);
406 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEYDESC %s", tmp);
407 xfree (tmp);
408 if (rc)
409 goto fail;
411 assuan_begin_confidential (crypto->agent->ctx);
412 rc = send_to_agent (crypto->agent, &key, &keylen, "PKDECRYPT");
413 assuan_end_confidential (crypto->agent->ctx);
414 if (rc)
415 goto fail;
417 rc = gcry_sexp_new (&tmp_sexp, key, keylen, 1);
418 xfree (key);
419 if (rc)
420 goto fail;
422 key = (char *) gcry_sexp_nth_data (tmp_sexp, 1, result_len);
423 if (key)
425 *result = gcry_malloc (*result_len);
426 if (!*result)
427 rc = GPG_ERR_ENOMEM;
428 else
429 memcpy (*result, key, *result_len);
431 else
432 rc = GPG_ERR_BAD_DATA;
434 gcry_sexp_release (tmp_sexp);
436 fail:
437 xfree (idata.line);
438 xfree (hexgrip);
440 if (enc_sexp)
441 gcry_sexp_release (enc_sexp);
443 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
444 rc = gpg_error (rc);
446 return rc;
449 static gpg_error_t
450 get_key_info (gcry_sexp_t pubkey, char **hash_str, int *hash_type,
451 size_t *len, int *pk_algo)
453 unsigned nbits = gcry_pk_get_nbits (pubkey);
454 gcry_sexp_t sexp, tmp;
455 char *algo;
457 tmp = gcry_sexp_find_token (pubkey, "public-key", 0);
458 if(!tmp)
459 return GPG_ERR_NO_PUBKEY;
461 sexp = gcry_sexp_nth (tmp, 1);
462 gcry_sexp_release (tmp);
463 algo = gcry_sexp_nth_string (sexp, 0);
464 gcry_sexp_release (sexp);
466 if (!algo)
468 return GPG_ERR_BAD_PUBKEY;
471 if (!strcmp (algo, "rsa"))
473 *pk_algo = GCRY_PK_RSA;
474 *hash_str = "sha256";
475 *hash_type = GCRY_MD_SHA256;
476 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
478 else if (!strcmp (algo, "dsa") || !strcmp (algo, "elg"))
480 if (!strcmp (algo, "dsa"))
481 *pk_algo = GCRY_PK_DSA;
482 else
483 *pk_algo = GCRY_PK_ELG;
485 switch (nbits)
487 default:
488 case 512 ... 1024:
489 *hash_str = "sha1";
490 *hash_type = GCRY_MD_SHA1;
491 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
492 break;
493 case 2048:
494 *hash_str = "sha224";
495 *hash_type = GCRY_MD_SHA224;
496 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA224);
497 break;
498 case 3072:
499 *hash_str = "sha256";
500 *hash_type = GCRY_MD_SHA256;
501 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
502 break;
503 case 7680:
504 *hash_str = "sha384";
505 *hash_type = GCRY_MD_SHA384;
506 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA384);
507 break;
508 case 15360:
509 *hash_str = "sha512";
510 *hash_type = GCRY_MD_SHA512;
511 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
512 break;
516 gcry_free (algo);
517 return 0;
520 gpg_error_t
521 agent_verify (gcry_sexp_t pkey, gcry_sexp_t sig_sexp, const void *data,
522 size_t len)
524 size_t hashlen;
525 int pk_algo;
526 unsigned char *hash;
527 gcry_sexp_t data_sexp;
528 char *hash_str = NULL;
529 int hash_type;
530 gpg_error_t rc = get_key_info (pkey, &hash_str, &hash_type, &hashlen,
531 &pk_algo);
533 if (rc)
534 return rc;
536 hash = gcry_malloc (hashlen);
537 if (!hash)
538 return GPG_ERR_ENOMEM;
540 gcry_md_hash_buffer (hash_type, hash, data, len);
541 if (pk_algo == GCRY_PK_RSA)
542 rc = gcry_sexp_build (&data_sexp, NULL,
543 "(data (flags pkcs1) (hash %s %b))", hash_str,
544 hashlen, hash);
545 else
546 rc = gcry_sexp_build (&data_sexp, NULL,
547 "(data (flags raw) (value %b))", hashlen, hash);
549 gcry_free (hash);
550 if (!rc)
552 rc = gcry_pk_verify (sig_sexp, data_sexp, pkey);
553 gcry_sexp_release (data_sexp);
556 return rc;
559 gpg_error_t
560 agent_loopback_cb (void *user, const char *keyword)
562 struct crypto_s *crypto = user;
563 gpg_error_t rc;
564 unsigned char *result;
565 size_t len;
566 int keyparam = 0;
568 if (!strcmp (keyword, "KEYPARAM"))
570 keyparam = 1;
571 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
573 else
574 { // PASSPHRASE or NEW_PASSPHRASE
575 assuan_begin_confidential (crypto->client_ctx);
576 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
577 assuan_end_confidential (crypto->client_ctx);
579 if (!rc && len == 1 && *result == 0)
580 len = 0;
583 if (!rc)
585 if (keyparam && !len)
587 char *tmp = default_key_params (crypto);
589 if (!tmp)
590 return gpg_error (GPG_ERR_ENOMEM);
592 len = strlen (tmp);
593 result = xmalloc (len);
594 memcpy (result, tmp, len);
595 xfree (tmp);
598 pthread_cleanup_push (xfree, result);
600 if (keyparam)
601 rc = assuan_send_data (crypto->agent->ctx, result, len);
602 else
604 assuan_begin_confidential (crypto->agent->ctx);
605 rc = assuan_send_data (crypto->agent->ctx, result, len);
606 assuan_end_confidential (crypto->agent->ctx);
609 pthread_cleanup_pop (1);
611 else if (gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
613 gpg_error_t arc = assuan_write_line (crypto->agent->ctx, "CAN");
615 if (!arc)
617 char *line;
618 size_t len;
620 arc = assuan_read_line (crypto->agent->ctx, &line, &len);
621 if (arc)
622 rc = arc;
624 else
625 rc = arc;
628 return rc;
631 static gpg_error_t
632 sign (gcry_sexp_t * rsexp, gcry_sexp_t sigpkey, struct crypto_s *crypto,
633 const void *data, size_t len)
635 gpg_error_t rc;
636 char *result;
637 unsigned char grip[20];
638 char *tmp;
640 gcry_pk_get_keygrip (sigpkey, grip);
641 tmp = bin2hex (grip, sizeof(grip));
642 pthread_cleanup_push (xfree, tmp);
643 log_write1 (_("Signed with keygrip %s"), tmp);
644 rc = send_to_agent (crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
645 pthread_cleanup_pop (1);
646 if (!rc)
648 unsigned char *hash;
649 size_t hashlen;
650 char *hash_str = NULL;
651 int hash_type;
652 int pk_algo;
654 rc = get_key_info (sigpkey, &hash_str, &hash_type, &hashlen, &pk_algo);
655 if (!rc)
657 hash = gcry_malloc (hashlen);
658 if (!hash)
659 rc = gpg_error (GPG_ERR_ENOMEM);
661 if (!rc)
663 gcry_md_hash_buffer (hash_type, hash, data, len);
664 tmp = bin2hex (hash, hashlen);
665 gcry_free (hash);
666 pthread_cleanup_push (xfree, tmp);
667 rc = send_to_agent (crypto->agent, NULL, NULL,
668 "SETHASH --hash=%s %s", hash_str, tmp);
669 pthread_cleanup_pop (1);
674 if (rc)
675 return rc;
677 if (!rc)
679 struct inquire_data_s idata = { 0 };
681 idata.crypto = crypto;
682 crypto->agent->inquire_data = &idata;
683 crypto->agent->inquire_cb = inquire_cb;
684 rc = send_to_agent (crypto->agent, &result, &len, "PKSIGN");
685 if (!rc)
687 rc = gcry_sexp_sscan (rsexp, NULL, result, len);
688 xfree (result);
692 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
693 rc = gpg_error (rc);
695 return rc;
698 gpg_error_t
699 encrypt_data_file (assuan_context_t ctx, struct crypto_s * crypto,
700 gcry_sexp_t pubkey, gcry_sexp_t sigpkey,
701 const char *filename, const void *xml, size_t len)
703 gpg_error_t rc;
704 void *data = NULL;
705 size_t data_len = 0;
706 void *enc_xml = NULL;
707 size_t enc_xml_len = 0;
708 unsigned char *iv = NULL;
709 size_t iv_len = 0;
710 int algo = cipher_to_gcrypt (crypto->save.hdr.flags);
711 void *key = NULL;
712 size_t keysize;
713 unsigned char sig_grip[20];
714 unsigned char grip[20];
716 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
717 if (rc)
718 return rc;
720 pthread_cleanup_push (gcry_free, key);
721 key = gcry_random_bytes_secure (keysize, GCRY_STRONG_RANDOM);
722 #ifdef HAVE_PTHREAD_TESTCANCEL
723 pthread_testcancel (); // may have been a long operation
724 #endif
725 pthread_cleanup_pop (0);
726 if (!key)
727 return gpg_error (GPG_ERR_ENOMEM);
729 gcry_pk_get_keygrip (pubkey, grip);
730 gcry_pk_get_keygrip (sigpkey, sig_grip);
731 pthread_cleanup_push (gcry_free, key);
732 rc = encrypt_xml (ctx, key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
733 &iv, &iv_len, crypto->save.hdr.iterations);
734 if (!rc)
736 gcry_sexp_t sig_sexp = NULL;
737 char *hexgrip = bin2hex (grip, 20);
739 pthread_cleanup_push (xfree, iv);
740 log_write1 (_("Encrypted with keygrip %s"), hexgrip);
741 xfree (hexgrip);
742 hexgrip = bin2hex (sig_grip, 20);
743 pthread_cleanup_push (gcry_free, enc_xml);
744 rc = sign (&sig_sexp, sigpkey, crypto, enc_xml, enc_xml_len);
745 xfree (hexgrip);
747 if (!rc)
749 rc = agent_verify (sigpkey, sig_sexp, enc_xml, enc_xml_len);
750 if (!rc)
752 gcry_sexp_t tmp_sexp;
754 rc = gcry_sexp_build (&tmp_sexp, NULL,
755 "(data (flags pkcs1) (value %b))",
756 keysize, key);
757 if (!rc)
759 gcry_sexp_t key_sexp;
761 pthread_cleanup_push ((void (*)(void *)) gcry_sexp_release,
762 (void *) sig_sexp);
763 rc = gcry_pk_encrypt (&key_sexp, tmp_sexp, pubkey);
764 pthread_cleanup_pop (0);
765 gcry_sexp_release (tmp_sexp);
767 if (!rc)
769 memcpy (crypto->save.hdr.iv, iv, iv_len);
770 crypto->save.hdr.datalen = enc_xml_len;
771 rc = gcry_sexp_build (&tmp_sexp, NULL, "%S%S", key_sexp,
772 sig_sexp);
773 gcry_sexp_release (key_sexp);
775 if (!rc)
777 data_len = gcry_sexp_sprint (tmp_sexp,
778 GCRYSEXP_FMT_CANON,
779 NULL, 0);
780 data = xmalloc (data_len);
781 if (data)
782 gcry_sexp_sprint (tmp_sexp, GCRYSEXP_FMT_CANON,
783 data, data_len);
784 else
785 rc = GPG_ERR_ENOMEM;
787 gcry_sexp_release (tmp_sexp);
794 pthread_cleanup_pop (0); // enc_xml
795 pthread_cleanup_pop (1); // iv
797 if (sig_sexp)
798 gcry_sexp_release (sig_sexp);
801 pthread_cleanup_pop (1); // key
803 if (!rc)
805 pthread_cleanup_push (gcry_free, enc_xml);
806 rc = write_file (crypto, filename, enc_xml, enc_xml_len, data, data_len,
807 pubkey, sigpkey);
808 pthread_cleanup_pop (1); // enc_xml
809 if (!rc)
810 memcpy (&crypto->hdr, &crypto->save.hdr, sizeof (file_header_t));
813 xfree (data);
814 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
815 rc = gpg_error (rc);
817 return rc;
820 gpg_error_t
821 generate_key (struct crypto_s * crypto, char *sexpstr, int empty, int preset)
823 gpg_error_t rc;
824 char *pkey;
825 size_t plen;
827 if (crypto->save.s2k_count)
829 rc = send_to_agent (crypto->agent, NULL, NULL,
830 "OPTION s2k-count=%lu", crypto->save.s2k_count);
831 if (rc)
832 return rc;
835 if (!crypto->agent->inquire_cb)
836 crypto->agent->inquire_cb = inquire_cb;
838 rc = send_to_agent (crypto->agent, &pkey, &plen, "GENKEY %s%s",
839 preset ? "--preset " : "",
840 empty ? "--no-protection" : "");
841 if (rc)
842 return rc;
844 if (crypto->save.pkey)
845 gcry_sexp_release (crypto->save.pkey);
847 crypto->save.pkey = NULL;
848 rc = gcry_sexp_new (&crypto->save.pkey, pkey, plen, 1);
849 if (!rc)
851 unsigned char grip[20];
853 gcry_pk_get_keygrip (crypto->save.pkey, grip);
854 char *hexgrip = bin2hex (grip, sizeof (grip));
855 log_write (_("Keygrip is %s"), hexgrip);
856 xfree (hexgrip);
858 if (!crypto->save.sigpkey)
860 gcry_sexp_build ((gcry_sexp_t *) & crypto->save.sigpkey, NULL, "%S",
861 crypto->save.pkey);
865 xfree (pkey);
866 return rc;
869 gpg_error_t
870 set_agent_option (struct agent_s * agent, const char *name, const char *value)
872 return send_to_agent (agent, NULL, NULL, "OPTION %s=%s", name, value);
875 gpg_error_t
876 set_agent_passphrase (struct crypto_s * crypto, const char *key, size_t len)
878 char *hexgrip;
879 struct inquire_data_s idata;
880 gpg_error_t rc;
881 int i;
883 /* This is for use with key files or passphrases obtained from an inquire.
884 * gpg-agent uses strings as passphrases and will truncate the passphrase
885 * at the first encountered null byte. It's only a warning because the
886 * passphrase may belong to a key shared outside of pwmd. */
887 for (i = 0; i < len; i++)
889 if (key[i] == 0)
891 log_write (_("WARNING: keylen=%i, truncated to %i."), len, i);
892 break;
896 hexgrip = bin2hex (crypto->grip, 20);
897 crypto->agent->inquire_cb = inquire_cb;
898 crypto->agent->inquire_data = &idata;
899 idata.crypto = crypto;
900 idata.line = (char *) key, idata.len = len;
901 idata.preset = 1;
902 assuan_begin_confidential (crypto->agent->ctx);
903 rc = send_to_agent (crypto->agent, NULL, NULL,
904 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
905 assuan_end_confidential (crypto->agent->ctx);
906 idata.preset = 0;
907 xfree (hexgrip);
908 return rc;
911 gpg_error_t
912 set_pinentry_mode (struct agent_s * agent, const char *mode)
914 return set_agent_option (agent, "pinentry-mode", mode);
917 gpg_error_t
918 get_pubkey_bin (struct crypto_s * crypto, const unsigned char *grip,
919 gcry_sexp_t * result)
921 char *hexgrip = bin2hex (grip, 20);
922 gpg_error_t rc;
924 if (!hexgrip)
925 return GPG_ERR_ENOMEM;
927 rc = get_pubkey (crypto, hexgrip, result);
928 xfree (hexgrip);
929 return rc;
932 gpg_error_t
933 get_pubkey (struct crypto_s * crypto, const char *grip, gcry_sexp_t * result)
935 char *pkey = NULL;
936 size_t plen;
937 gpg_error_t rc;
939 rc = send_to_agent (crypto->agent, &pkey, &plen, "READKEY %s", grip);
940 if (!rc)
941 rc = gcry_sexp_new (result, pkey, plen, 1);
943 xfree (pkey);
944 return rc;
947 gpg_error_t
948 agent_set_pinentry_options (struct agent_s * agent)
950 gpg_error_t rc = 0;
951 struct pinentry_option_s *opts = &agent->pinentry_opts;
953 if (!opts->display && getenv ("DISPLAY"))
955 rc = set_agent_option (agent, "display", getenv ("DISPLAY"));
956 if (!rc)
958 opts->display = str_dup (getenv ("DISPLAY"));
961 else if (!opts->ttyname && ttyname (STDOUT_FILENO))
963 rc = set_agent_option (agent, "ttyname", ttyname (STDOUT_FILENO));
964 if (!rc)
966 rc = set_agent_option (agent, "ttytype",
967 opts->ttytype ? opts->ttytype : getenv ("TERM"));
968 if (!rc)
970 xfree (opts->ttyname);
971 xfree (opts->ttytype);
972 opts->ttyname = str_dup (ttyname (STDOUT_FILENO));
973 opts->ttytype = str_dup (getenv ("TERM"));
978 return rc;
981 static gpg_error_t
982 inquire_keyfile (void *user, const char *keyword)
984 struct crypto_s *crypto = user;
985 char *filename = crypto->agent->inquire_data2;
986 char *params = crypto->agent->inquire_data3;
987 int fd;
988 struct stat st;
989 unsigned char *buf;
990 size_t len;
991 gpg_error_t rc;
993 if (!strcmp (keyword, "KEYPARAM"))
994 return assuan_send_data (crypto->agent->ctx, params, strlen (params));
996 // This function is only used when generating a new keypair.
997 if (strcmp (keyword, "NEW_PASSPHRASE"))
998 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
1000 if (stat (filename, &st) == -1)
1001 return gpg_error_from_syserror ();
1003 if (crypto->agent->inquire_maxlen
1004 && st.st_size > crypto->agent->inquire_maxlen)
1006 log_write (_("The passphrase is too large: have=%u, max=%u."),
1007 (unsigned) st.st_size, crypto->agent->inquire_maxlen);
1008 return GPG_ERR_TOO_LARGE;
1011 buf = gcry_malloc_secure (st.st_size);
1012 if (!buf)
1013 return GPG_ERR_ENOMEM;
1015 fd = open (filename, O_RDONLY);
1016 if (fd == -1)
1017 rc = gpg_error_from_syserror ();
1018 else
1020 len = read (fd, buf, st.st_size);
1021 if (len == st.st_size)
1023 assuan_begin_confidential (crypto->agent->ctx);
1024 rc = assuan_send_data (crypto->agent->ctx, buf, len);
1025 assuan_end_confidential (crypto->agent->ctx);
1027 else if (len == -1)
1028 rc = gpg_error_from_syserror ();
1029 else
1030 rc = GPG_ERR_BUFFER_TOO_SHORT;
1033 close (fd);
1034 gcry_free (buf);
1035 return rc;
1038 gpg_error_t
1039 agent_export_common (struct crypto_s * crypto, const char *hexgrip,
1040 const char *sign_hexgrip, int no_passphrase,
1041 const void *data, size_t datalen, const char *outfile,
1042 const char *keyparams, const char *keyfile)
1044 gpg_error_t rc = 0;
1046 if (!sign_hexgrip && hexgrip)
1047 sign_hexgrip = hexgrip;
1049 if (sign_hexgrip)
1051 if (crypto->sigpkey_sexp)
1052 gcry_sexp_release (crypto->sigpkey_sexp);
1054 crypto->sigpkey_sexp = NULL;
1055 rc = get_pubkey (crypto, sign_hexgrip, &crypto->save.sigpkey);
1056 if (rc)
1057 return rc;
1059 gcry_pk_get_keygrip (crypto->save.sigpkey, crypto->sign_grip);
1062 if (hexgrip)
1064 rc = get_pubkey (crypto, hexgrip, &crypto->save.pkey);
1065 if (!rc)
1066 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
1068 else
1070 struct inquire_data_s idata = { 0 };
1071 char *params = keyparams ? str_dup (keyparams)
1072 : default_key_params (crypto);
1074 pthread_cleanup_push (xfree, params);
1075 log_write (_("Generating a new keypair ..."));
1076 if (keyfile)
1078 log_write (_("Using passphrase obtained from file '%s'"), keyfile);
1079 rc = set_pinentry_mode (crypto->agent, "loopback");
1080 crypto->agent->inquire_cb = inquire_keyfile;
1081 crypto->agent->inquire_data = crypto;
1082 crypto->agent->inquire_data2 = (char *) keyfile;
1083 crypto->agent->inquire_data3 = params;
1085 else
1087 idata.line = params;
1088 idata.len = strlen (params);
1089 idata.crypto = crypto;
1090 crypto->agent->inquire_cb = inquire_cb;
1091 crypto->agent->inquire_data = &idata;
1094 if (!rc)
1096 rc = generate_key (crypto, params, no_passphrase, 1);
1097 if (!rc)
1098 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
1101 (void) set_pinentry_mode (crypto->agent, "ask");
1102 pthread_cleanup_pop (1);
1105 if (!rc)
1107 rc = encrypt_data_file (NULL, crypto, crypto->save.pkey,
1108 crypto->save.sigpkey, outfile, data, datalen);
1109 if (!rc)
1111 char *tmp = bin2hex (crypto->grip, sizeof (crypto->grip));
1113 log_write (_("Success! Keygrip is %s."), tmp);
1114 rc = send_to_agent (crypto->agent, NULL, NULL,
1115 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1116 xfree (tmp);
1118 if (sign_hexgrip)
1120 tmp = bin2hex (crypto->sign_grip, sizeof (crypto->sign_grip));
1121 log_write (_("Signed with keygrip %s."), tmp);
1122 xfree (tmp);
1127 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
1128 rc = gpg_error (rc);
1130 return rc;
1133 char *
1134 default_key_params (struct crypto_s *crypto)
1136 int len = config_get_integer (NULL, "nbits");
1137 char buf[32];
1138 char *algo = config_get_string (NULL, "algo");
1139 char *result;
1141 snprintf (buf, sizeof (buf), "%i", len);
1142 result = str_asprintf ("(genkey (%s (nbits %lu:%i)))", algo, strlen (buf),
1143 len);
1144 xfree (algo);
1145 return result;
1148 gpg_error_t
1149 agent_passwd (struct crypto_s * crypto)
1151 struct inquire_data_s idata = { 0 };
1152 gpg_error_t rc;
1153 char *tmp = bin2hex (crypto->grip, 20);
1155 idata.crypto = crypto;
1156 crypto->agent->inquire_cb = inquire_cb;
1157 crypto->agent->inquire_data = &idata;
1158 rc = send_to_agent (crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1159 xfree (tmp);
1160 return rc;
1163 gpg_error_t
1164 kill_scd (struct agent_s * agent)
1166 gpg_error_t rc = 0;
1168 if (!use_agent)
1169 return 0;
1171 if (config_get_boolean (NULL, "kill_scd"))
1173 rc = send_to_agent (agent, NULL, NULL, "SCD KILLSCD");
1174 if (rc && gpg_err_code (rc) != GPG_ERR_NO_SCDAEMON)
1175 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (rc));
1178 return rc;