Return GPG_ERR_UNSUPPORTED_ALGORITHM.
[pwmd.git] / src / agent.c
blob87a5f319c984be4eae0f4d0513787087b205b20f
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;
456 gpg_error_t rc = 0;
458 tmp = gcry_sexp_find_token (pubkey, "public-key", 0);
459 if(!tmp)
460 return GPG_ERR_NO_PUBKEY;
462 sexp = gcry_sexp_nth (tmp, 1);
463 gcry_sexp_release (tmp);
464 algo = gcry_sexp_nth_string (sexp, 0);
465 gcry_sexp_release (sexp);
467 if (!algo)
469 return GPG_ERR_BAD_PUBKEY;
472 if (!strcmp (algo, "rsa"))
474 *pk_algo = GCRY_PK_RSA;
475 *hash_str = "sha256";
476 *hash_type = GCRY_MD_SHA256;
477 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
479 else if (!strcmp (algo, "dsa"))
481 *pk_algo = GCRY_PK_DSA;
482 switch (nbits)
484 default:
485 case 512 ... 1024:
486 *hash_str = "sha1";
487 *hash_type = GCRY_MD_SHA1;
488 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
489 break;
490 case 2048:
491 *hash_str = "sha224";
492 *hash_type = GCRY_MD_SHA224;
493 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA224);
494 break;
495 case 3072:
496 *hash_str = "sha256";
497 *hash_type = GCRY_MD_SHA256;
498 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
499 break;
500 case 7680:
501 *hash_str = "sha384";
502 *hash_type = GCRY_MD_SHA384;
503 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA384);
504 break;
505 case 15360:
506 *hash_str = "sha512";
507 *hash_type = GCRY_MD_SHA512;
508 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
509 break;
512 else
513 rc = GPG_ERR_UNSUPPORTED_ALGORITHM;
515 gcry_free (algo);
516 return rc;
519 gpg_error_t
520 agent_verify (gcry_sexp_t pkey, gcry_sexp_t sig_sexp, const void *data,
521 size_t len)
523 size_t hashlen;
524 int pk_algo;
525 unsigned char *hash;
526 gcry_sexp_t data_sexp;
527 char *hash_str = NULL;
528 int hash_type;
529 gpg_error_t rc = get_key_info (pkey, &hash_str, &hash_type, &hashlen,
530 &pk_algo);
532 if (rc)
533 return rc;
535 hash = gcry_malloc (hashlen);
536 if (!hash)
537 return GPG_ERR_ENOMEM;
539 gcry_md_hash_buffer (hash_type, hash, data, len);
540 if (pk_algo == GCRY_PK_RSA)
541 rc = gcry_sexp_build (&data_sexp, NULL,
542 "(data (flags pkcs1) (hash %s %b))", hash_str,
543 hashlen, hash);
544 else
545 rc = gcry_sexp_build (&data_sexp, NULL,
546 "(data (flags raw) (value %b))", hashlen, hash);
548 gcry_free (hash);
549 if (!rc)
551 rc = gcry_pk_verify (sig_sexp, data_sexp, pkey);
552 gcry_sexp_release (data_sexp);
555 return rc;
558 gpg_error_t
559 agent_loopback_cb (void *user, const char *keyword)
561 struct crypto_s *crypto = user;
562 gpg_error_t rc;
563 unsigned char *result;
564 size_t len;
565 int keyparam = 0;
567 if (!strcmp (keyword, "KEYPARAM"))
569 keyparam = 1;
570 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
572 else
573 { // PASSPHRASE or NEW_PASSPHRASE
574 assuan_begin_confidential (crypto->client_ctx);
575 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
576 assuan_end_confidential (crypto->client_ctx);
578 if (!rc && len == 1 && *result == 0)
579 len = 0;
582 if (!rc)
584 if (keyparam && !len)
586 char *tmp = default_key_params (crypto);
588 if (!tmp)
589 return gpg_error (GPG_ERR_ENOMEM);
591 len = strlen (tmp);
592 result = xmalloc (len);
593 memcpy (result, tmp, len);
594 xfree (tmp);
597 pthread_cleanup_push (xfree, result);
599 if (keyparam)
600 rc = assuan_send_data (crypto->agent->ctx, result, len);
601 else
603 assuan_begin_confidential (crypto->agent->ctx);
604 rc = assuan_send_data (crypto->agent->ctx, result, len);
605 assuan_end_confidential (crypto->agent->ctx);
608 pthread_cleanup_pop (1);
610 else if (gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
612 gpg_error_t arc = assuan_write_line (crypto->agent->ctx, "CAN");
614 if (!arc)
616 char *line;
617 size_t len;
619 arc = assuan_read_line (crypto->agent->ctx, &line, &len);
620 if (arc)
621 rc = arc;
623 else
624 rc = arc;
627 return rc;
630 static gpg_error_t
631 sign (gcry_sexp_t * rsexp, gcry_sexp_t sigpkey, struct crypto_s *crypto,
632 const void *data, size_t len)
634 gpg_error_t rc;
635 char *result;
636 unsigned char grip[20];
637 char *tmp;
639 gcry_pk_get_keygrip (sigpkey, grip);
640 tmp = bin2hex (grip, sizeof(grip));
641 pthread_cleanup_push (xfree, tmp);
642 log_write1 (_("Signed with keygrip %s"), tmp);
643 rc = send_to_agent (crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
644 pthread_cleanup_pop (1);
645 if (!rc)
647 unsigned char *hash;
648 size_t hashlen;
649 char *hash_str = NULL;
650 int hash_type;
651 int pk_algo;
653 rc = get_key_info (sigpkey, &hash_str, &hash_type, &hashlen, &pk_algo);
654 if (!rc)
656 hash = gcry_malloc (hashlen);
657 if (!hash)
658 rc = gpg_error (GPG_ERR_ENOMEM);
660 if (!rc)
662 gcry_md_hash_buffer (hash_type, hash, data, len);
663 tmp = bin2hex (hash, hashlen);
664 gcry_free (hash);
665 pthread_cleanup_push (xfree, tmp);
666 rc = send_to_agent (crypto->agent, NULL, NULL,
667 "SETHASH --hash=%s %s", hash_str, tmp);
668 pthread_cleanup_pop (1);
673 if (rc)
674 return rc;
676 if (!rc)
678 struct inquire_data_s idata = { 0 };
680 idata.crypto = crypto;
681 crypto->agent->inquire_data = &idata;
682 crypto->agent->inquire_cb = inquire_cb;
683 rc = send_to_agent (crypto->agent, &result, &len, "PKSIGN");
684 if (!rc)
686 rc = gcry_sexp_sscan (rsexp, NULL, result, len);
687 xfree (result);
691 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
692 rc = gpg_error (rc);
694 return rc;
697 gpg_error_t
698 encrypt_data_file (assuan_context_t ctx, struct crypto_s * crypto,
699 gcry_sexp_t pubkey, gcry_sexp_t sigpkey,
700 const char *filename, const void *xml, size_t len)
702 gpg_error_t rc;
703 void *data = NULL;
704 size_t data_len = 0;
705 void *enc_xml = NULL;
706 size_t enc_xml_len = 0;
707 unsigned char *iv = NULL;
708 size_t iv_len = 0;
709 int algo = cipher_to_gcrypt (crypto->save.hdr.flags);
710 void *key = NULL;
711 size_t keysize;
712 unsigned char sig_grip[20];
713 unsigned char grip[20];
715 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
716 if (rc)
717 return rc;
719 pthread_cleanup_push (gcry_free, key);
720 key = gcry_random_bytes_secure (keysize, GCRY_STRONG_RANDOM);
721 #ifdef HAVE_PTHREAD_TESTCANCEL
722 pthread_testcancel (); // may have been a long operation
723 #endif
724 pthread_cleanup_pop (0);
725 if (!key)
726 return gpg_error (GPG_ERR_ENOMEM);
728 gcry_pk_get_keygrip (pubkey, grip);
729 gcry_pk_get_keygrip (sigpkey, sig_grip);
730 pthread_cleanup_push (gcry_free, key);
731 rc = encrypt_xml (ctx, key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
732 &iv, &iv_len, crypto->save.hdr.iterations);
733 if (!rc)
735 gcry_sexp_t sig_sexp = NULL;
736 char *hexgrip = bin2hex (grip, 20);
738 pthread_cleanup_push (xfree, iv);
739 log_write1 (_("Encrypted with keygrip %s"), hexgrip);
740 xfree (hexgrip);
741 hexgrip = bin2hex (sig_grip, 20);
742 pthread_cleanup_push (gcry_free, enc_xml);
743 rc = sign (&sig_sexp, sigpkey, crypto, enc_xml, enc_xml_len);
744 xfree (hexgrip);
746 if (!rc)
748 rc = agent_verify (sigpkey, sig_sexp, enc_xml, enc_xml_len);
749 if (!rc)
751 gcry_sexp_t tmp_sexp;
753 rc = gcry_sexp_build (&tmp_sexp, NULL,
754 "(data (flags pkcs1) (value %b))",
755 keysize, key);
756 if (!rc)
758 gcry_sexp_t key_sexp;
760 pthread_cleanup_push ((void (*)(void *)) gcry_sexp_release,
761 (void *) sig_sexp);
762 rc = gcry_pk_encrypt (&key_sexp, tmp_sexp, pubkey);
763 pthread_cleanup_pop (0);
764 gcry_sexp_release (tmp_sexp);
766 if (!rc)
768 memcpy (crypto->save.hdr.iv, iv, iv_len);
769 crypto->save.hdr.datalen = enc_xml_len;
770 rc = gcry_sexp_build (&tmp_sexp, NULL, "%S%S", key_sexp,
771 sig_sexp);
772 gcry_sexp_release (key_sexp);
774 if (!rc)
776 data_len = gcry_sexp_sprint (tmp_sexp,
777 GCRYSEXP_FMT_CANON,
778 NULL, 0);
779 data = xmalloc (data_len);
780 if (data)
781 gcry_sexp_sprint (tmp_sexp, GCRYSEXP_FMT_CANON,
782 data, data_len);
783 else
784 rc = GPG_ERR_ENOMEM;
786 gcry_sexp_release (tmp_sexp);
793 pthread_cleanup_pop (0); // enc_xml
794 pthread_cleanup_pop (1); // iv
796 if (sig_sexp)
797 gcry_sexp_release (sig_sexp);
800 pthread_cleanup_pop (1); // key
802 if (!rc)
804 pthread_cleanup_push (gcry_free, enc_xml);
805 rc = write_file (crypto, filename, enc_xml, enc_xml_len, data, data_len,
806 pubkey, sigpkey);
807 pthread_cleanup_pop (1); // enc_xml
808 if (!rc)
809 memcpy (&crypto->hdr, &crypto->save.hdr, sizeof (file_header_t));
812 xfree (data);
813 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
814 rc = gpg_error (rc);
816 return rc;
819 gpg_error_t
820 generate_key (struct crypto_s * crypto, char *sexpstr, int empty, int preset)
822 gpg_error_t rc;
823 char *pkey;
824 size_t plen;
826 if (crypto->save.s2k_count)
828 rc = send_to_agent (crypto->agent, NULL, NULL,
829 "OPTION s2k-count=%lu", crypto->save.s2k_count);
830 if (rc)
831 return rc;
834 if (!crypto->agent->inquire_cb)
835 crypto->agent->inquire_cb = inquire_cb;
837 rc = send_to_agent (crypto->agent, &pkey, &plen, "GENKEY %s%s",
838 preset ? "--preset " : "",
839 empty ? "--no-protection" : "");
840 if (rc)
841 return rc;
843 if (crypto->save.pkey)
844 gcry_sexp_release (crypto->save.pkey);
846 crypto->save.pkey = NULL;
847 rc = gcry_sexp_new (&crypto->save.pkey, pkey, plen, 1);
848 if (!rc)
850 unsigned char grip[20];
852 gcry_pk_get_keygrip (crypto->save.pkey, grip);
853 char *hexgrip = bin2hex (grip, sizeof (grip));
854 log_write (_("Keygrip is %s"), hexgrip);
855 xfree (hexgrip);
857 if (!crypto->save.sigpkey)
859 gcry_sexp_build ((gcry_sexp_t *) & crypto->save.sigpkey, NULL, "%S",
860 crypto->save.pkey);
864 xfree (pkey);
865 return rc;
868 gpg_error_t
869 set_agent_option (struct agent_s * agent, const char *name, const char *value)
871 return send_to_agent (agent, NULL, NULL, "OPTION %s=%s", name, value);
874 gpg_error_t
875 set_agent_passphrase (struct crypto_s * crypto, const char *key, size_t len)
877 char *hexgrip;
878 struct inquire_data_s idata;
879 gpg_error_t rc;
880 int i;
882 /* This is for use with key files or passphrases obtained from an inquire.
883 * gpg-agent uses strings as passphrases and will truncate the passphrase
884 * at the first encountered null byte. It's only a warning because the
885 * passphrase may belong to a key shared outside of pwmd. */
886 for (i = 0; i < len; i++)
888 if (key[i] == 0)
890 log_write (_("WARNING: keylen=%i, truncated to %i."), len, i);
891 break;
895 hexgrip = bin2hex (crypto->grip, 20);
896 crypto->agent->inquire_cb = inquire_cb;
897 crypto->agent->inquire_data = &idata;
898 idata.crypto = crypto;
899 idata.line = (char *) key, idata.len = len;
900 idata.preset = 1;
901 assuan_begin_confidential (crypto->agent->ctx);
902 rc = send_to_agent (crypto->agent, NULL, NULL,
903 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
904 assuan_end_confidential (crypto->agent->ctx);
905 idata.preset = 0;
906 xfree (hexgrip);
907 return rc;
910 gpg_error_t
911 set_pinentry_mode (struct agent_s * agent, const char *mode)
913 return set_agent_option (agent, "pinentry-mode", mode);
916 gpg_error_t
917 get_pubkey_bin (struct crypto_s * crypto, const unsigned char *grip,
918 gcry_sexp_t * result)
920 char *hexgrip = bin2hex (grip, 20);
921 gpg_error_t rc;
923 if (!hexgrip)
924 return GPG_ERR_ENOMEM;
926 rc = get_pubkey (crypto, hexgrip, result);
927 xfree (hexgrip);
928 return rc;
931 gpg_error_t
932 get_pubkey (struct crypto_s * crypto, const char *grip, gcry_sexp_t * result)
934 char *pkey = NULL;
935 size_t plen;
936 gpg_error_t rc;
938 rc = send_to_agent (crypto->agent, &pkey, &plen, "READKEY %s", grip);
939 if (!rc)
940 rc = gcry_sexp_new (result, pkey, plen, 1);
942 xfree (pkey);
943 return rc;
946 gpg_error_t
947 agent_set_pinentry_options (struct agent_s * agent)
949 gpg_error_t rc = 0;
950 struct pinentry_option_s *opts = &agent->pinentry_opts;
952 if (!opts->display && getenv ("DISPLAY"))
954 rc = set_agent_option (agent, "display", getenv ("DISPLAY"));
955 if (!rc)
957 opts->display = str_dup (getenv ("DISPLAY"));
960 else if (!opts->ttyname && ttyname (STDOUT_FILENO))
962 rc = set_agent_option (agent, "ttyname", ttyname (STDOUT_FILENO));
963 if (!rc)
965 rc = set_agent_option (agent, "ttytype",
966 opts->ttytype ? opts->ttytype : getenv ("TERM"));
967 if (!rc)
969 xfree (opts->ttyname);
970 xfree (opts->ttytype);
971 opts->ttyname = str_dup (ttyname (STDOUT_FILENO));
972 opts->ttytype = str_dup (getenv ("TERM"));
977 return rc;
980 static gpg_error_t
981 inquire_keyfile (void *user, const char *keyword)
983 struct crypto_s *crypto = user;
984 char *filename = crypto->agent->inquire_data2;
985 char *params = crypto->agent->inquire_data3;
986 int fd;
987 struct stat st;
988 unsigned char *buf;
989 size_t len;
990 gpg_error_t rc;
992 if (!strcmp (keyword, "KEYPARAM"))
993 return assuan_send_data (crypto->agent->ctx, params, strlen (params));
995 // This function is only used when generating a new keypair.
996 if (strcmp (keyword, "NEW_PASSPHRASE"))
997 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
999 if (stat (filename, &st) == -1)
1000 return gpg_error_from_syserror ();
1002 if (crypto->agent->inquire_maxlen
1003 && st.st_size > crypto->agent->inquire_maxlen)
1005 log_write (_("The passphrase is too large: have=%u, max=%u."),
1006 (unsigned) st.st_size, crypto->agent->inquire_maxlen);
1007 return GPG_ERR_TOO_LARGE;
1010 buf = gcry_malloc_secure (st.st_size);
1011 if (!buf)
1012 return GPG_ERR_ENOMEM;
1014 fd = open (filename, O_RDONLY);
1015 if (fd == -1)
1016 rc = gpg_error_from_syserror ();
1017 else
1019 len = read (fd, buf, st.st_size);
1020 if (len == st.st_size)
1022 assuan_begin_confidential (crypto->agent->ctx);
1023 rc = assuan_send_data (crypto->agent->ctx, buf, len);
1024 assuan_end_confidential (crypto->agent->ctx);
1026 else if (len == -1)
1027 rc = gpg_error_from_syserror ();
1028 else
1029 rc = GPG_ERR_BUFFER_TOO_SHORT;
1032 close (fd);
1033 gcry_free (buf);
1034 return rc;
1037 gpg_error_t
1038 agent_export_common (struct crypto_s * crypto, const char *hexgrip,
1039 const char *sign_hexgrip, int no_passphrase,
1040 const void *data, size_t datalen, const char *outfile,
1041 const char *keyparams, const char *keyfile)
1043 gpg_error_t rc = 0;
1045 if (!sign_hexgrip && hexgrip)
1046 sign_hexgrip = hexgrip;
1048 if (sign_hexgrip)
1050 if (crypto->sigpkey_sexp)
1051 gcry_sexp_release (crypto->sigpkey_sexp);
1053 crypto->sigpkey_sexp = NULL;
1054 rc = get_pubkey (crypto, sign_hexgrip, &crypto->save.sigpkey);
1055 if (rc)
1056 return rc;
1058 gcry_pk_get_keygrip (crypto->save.sigpkey, crypto->sign_grip);
1061 if (hexgrip)
1063 rc = get_pubkey (crypto, hexgrip, &crypto->save.pkey);
1064 if (!rc)
1065 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
1067 else
1069 struct inquire_data_s idata = { 0 };
1070 char *params = keyparams ? str_dup (keyparams)
1071 : default_key_params (crypto);
1073 pthread_cleanup_push (xfree, params);
1074 log_write (_("Generating a new keypair ..."));
1075 if (keyfile)
1077 log_write (_("Using passphrase obtained from file '%s'"), keyfile);
1078 rc = set_pinentry_mode (crypto->agent, "loopback");
1079 crypto->agent->inquire_cb = inquire_keyfile;
1080 crypto->agent->inquire_data = crypto;
1081 crypto->agent->inquire_data2 = (char *) keyfile;
1082 crypto->agent->inquire_data3 = params;
1084 else
1086 idata.line = params;
1087 idata.len = strlen (params);
1088 idata.crypto = crypto;
1089 crypto->agent->inquire_cb = inquire_cb;
1090 crypto->agent->inquire_data = &idata;
1093 if (!rc)
1095 rc = generate_key (crypto, params, no_passphrase, 1);
1096 if (!rc)
1097 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
1100 (void) set_pinentry_mode (crypto->agent, "ask");
1101 pthread_cleanup_pop (1);
1104 if (!rc)
1106 rc = encrypt_data_file (NULL, crypto, crypto->save.pkey,
1107 crypto->save.sigpkey, outfile, data, datalen);
1108 if (!rc)
1110 char *tmp = bin2hex (crypto->grip, sizeof (crypto->grip));
1112 log_write (_("Success! Keygrip is %s."), tmp);
1113 rc = send_to_agent (crypto->agent, NULL, NULL,
1114 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1115 xfree (tmp);
1117 if (sign_hexgrip)
1119 tmp = bin2hex (crypto->sign_grip, sizeof (crypto->sign_grip));
1120 log_write (_("Signed with keygrip %s."), tmp);
1121 xfree (tmp);
1126 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
1127 rc = gpg_error (rc);
1129 return rc;
1132 char *
1133 default_key_params (struct crypto_s *crypto)
1135 return config_get_string (NULL, "keyparam");
1138 gpg_error_t
1139 agent_passwd (struct crypto_s * crypto)
1141 struct inquire_data_s idata = { 0 };
1142 gpg_error_t rc;
1143 char *tmp = bin2hex (crypto->grip, 20);
1145 idata.crypto = crypto;
1146 crypto->agent->inquire_cb = inquire_cb;
1147 crypto->agent->inquire_data = &idata;
1148 rc = send_to_agent (crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1149 xfree (tmp);
1150 return rc;
1153 gpg_error_t
1154 kill_scd (struct agent_s * agent)
1156 gpg_error_t rc = 0;
1158 if (!use_agent)
1159 return 0;
1161 if (config_get_boolean (NULL, "kill_scd"))
1163 rc = send_to_agent (agent, NULL, NULL, "SCD KILLSCD");
1164 if (rc && gpg_err_code (rc) != GPG_ERR_NO_SCDAEMON)
1165 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (rc));
1168 return rc;