Fix build for Android.
[pwmd.git] / src / agent.c
blob6ff520d2ed0b1cf5b0d52cb6d9511b0b9d991c9b
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 /* Forward status messages from gpg-agent to the client. */
69 static gpg_error_t
70 status_cb (void *data, const char *line)
72 struct agent_s *agent = data;
74 agent->inquire_maxlen = 0;
76 if (!strncmp (line, "INQUIRE_MAXLEN ", 15))
78 agent->inquire_maxlen = atoi (line + 15);
79 if (!agent->client_ctx)
80 return 0;
83 return send_status (agent->client_ctx, STATUS_AGENT, "%s", line);
86 static gpg_error_t
87 assuan_command (struct agent_s *a, char **result,
88 size_t * len, const char *cmd)
90 gpg_error_t rc;
92 a->data.len = 0;
93 a->data.buf = NULL;
94 if (result)
95 *result = NULL;
96 if (len)
97 *len = 0;
99 rc = assuan_transact (a->ctx, cmd, mem_realloc_cb, &a->data,
100 a->inquire_cb, a->inquire_data, status_cb, a);
101 if (rc)
102 xfree (a->data.buf);
103 else
105 if (a->data.buf)
107 mem_realloc_cb (&a->data, "", 1);
108 if (result)
109 *result = (char *) a->data.buf;
110 else
111 xfree (a->data.buf);
113 if (len)
114 *len = a->data.len;
118 return rc;
121 /* This commands are sent from launch_agent() after reconnecting to the agent
122 * and also from the initial client connection. */
123 gpg_error_t
124 send_agent_common_options (struct agent_s *agent)
126 gpg_error_t rc;
128 rc = send_to_agent (agent, NULL, NULL, "OPTION cache-ttl-opt-preset=-1");
129 return rc;
132 static gpg_error_t
133 launch_agent (struct agent_s *agent)
135 gpg_error_t rc;
136 assuan_context_t ctx = NULL;
137 const char *t = NULL;
138 static struct assuan_malloc_hooks mhooks = { xmalloc, xrealloc, xfree };
139 char *s, buf[LINE_MAX];
140 FILE *fp;
142 agent->did_restart = 0;
143 s = config_get_string ("global", "agent_env_file");
144 if (s)
146 char *ss = expand_homedir (s);
147 char *p;
149 fp = fopen (ss, "r");
150 xfree (ss);
152 if (fp)
154 while ((p = fgets (buf, sizeof (buf), fp)))
156 p = str_chomp (p);
157 if (!strncmp (p, "GPG_AGENT_INFO=", strlen ("GPG_AGENT_INFO=")))
159 setenv ("GPG_AGENT_INFO", p + strlen ("GPG_AGENT_INFO="),
161 break;
165 fclose (fp);
167 else
168 log_write ("%s: %s", s, pwmd_strerror (gpg_error_from_errno (errno)));
170 xfree (s);
173 t = getenv ("GPG_AGENT_INFO");
174 if (!t)
175 return gpg_error (GPG_ERR_NO_AGENT);
177 rc = assuan_new_ext (&ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
178 debug_level ? assuan_log_cb : NULL, "AGENT ");
179 if (rc)
180 return rc;
182 char **fields = str_split (t, ":", 0);
183 rc = assuan_socket_connect (ctx, fields[0], ASSUAN_INVALID_PID, 0);
184 strv_free (fields);
185 if (rc)
187 if (ctx)
188 assuan_release (ctx);
189 return rc;
192 if (agent->ctx)
193 assuan_release (agent->ctx);
195 agent->ctx = ctx;
196 rc = send_agent_common_options (agent);
197 if (!rc && agent->pinentry_opts.display)
198 rc = set_agent_option (agent, "display", agent->pinentry_opts.display);
200 if (!rc && agent->pinentry_opts.ttyname)
201 rc = set_agent_option (agent, "ttyname", agent->pinentry_opts.ttyname);
203 if (!rc && agent->pinentry_opts.ttytype)
204 rc = set_agent_option (agent, "ttytype", agent->pinentry_opts.ttytype);
206 if (!rc && agent->pinentry_opts.lc_messages)
207 rc = set_agent_option (agent, "lc-messages",
208 agent->pinentry_opts.lc_messages);
210 if (!rc && agent->pinentry_opts.lc_ctype)
211 rc = set_agent_option (agent, "lc-ctype", agent->pinentry_opts.lc_ctype);
213 return 0;
216 gpg_error_t
217 send_to_agent (struct agent_s * agent, char **result, size_t * len,
218 const char *fmt, ...)
220 gpg_error_t rc = 0;
221 va_list ap;
222 char *cmd;
224 if (!agent->ctx)
226 rc = launch_agent (agent);
227 if (rc)
228 return rc;
231 va_start (ap, fmt);
232 if (str_vasprintf (&cmd, fmt, ap) > 0)
234 rc = assuan_command (agent, result, len, cmd);
235 if (!agent->restart && gpg_err_source (rc) == GPG_ERR_SOURCE_DEFAULT
236 && (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED
237 || gpg_err_code (rc) == GPG_ERR_EPIPE))
239 log_write (_ ("gpg-agent connection died (rc=%i), reconnecting"), rc);
240 agent->restart = 1;
241 rc = launch_agent (agent);
242 if (!rc)
244 agent->did_restart = 1;
245 rc = assuan_command (agent, result, len, cmd);
249 agent->restart = 0;
250 xfree (cmd);
252 else
253 rc = GPG_ERR_ENOMEM;
255 va_end (ap);
256 return rc;
259 static void
260 agent_disconnect (struct agent_s *agent)
262 if (!agent)
263 return;
265 if (agent->ctx)
266 assuan_release (agent->ctx);
268 agent->ctx = NULL;
271 void
272 cleanup_agent (struct agent_s *agent)
274 if (!agent)
275 return;
277 pinentry_free_opts (&agent->pinentry_opts);
278 agent_disconnect (agent);
279 xfree (agent);
282 gpg_error_t
283 agent_init (struct agent_s **agent)
285 struct agent_s *new = xcalloc (1, sizeof (struct agent_s));
287 if (!new)
288 return GPG_ERR_ENOMEM;
290 *agent = new;
291 return 0;
294 static gpg_error_t
295 inquire_cb (void *user, const char *keyword)
297 struct inquire_data_s *idata = user;
299 if (!idata->preset && (!strcmp (keyword, "PASSPHRASE")
300 || !strcmp (keyword, "NEW_PASSPHRASE")))
302 return agent_loopback_cb (idata->crypto, keyword);
304 // SAVE --inquire-keyparam
305 else if (idata->preset && !strcmp (keyword, "KEYPARAM"))
307 idata->preset = 0;
308 return agent_loopback_cb (idata->crypto, keyword);
311 if (idata->crypto->agent->inquire_maxlen
312 && idata->len > idata->crypto->agent->inquire_maxlen)
314 log_write (_("Inquired data too large: have=%u, max=%u"), idata->len,
315 idata->crypto->agent->inquire_maxlen);
316 return GPG_ERR_TOO_LARGE;
319 idata->crypto->agent->inquire_maxlen = 0;
320 return assuan_send_data (idata->crypto->agent->ctx, idata->line,
321 idata->len);
324 /* Retrieve the passphrase needed to decrypt the XML from the secret
325 * key using gpg-agent. */
326 gpg_error_t
327 agent_extract_key (struct crypto_s *crypto, unsigned char **result,
328 size_t * result_len)
330 gpg_error_t rc;
331 gcry_sexp_t enc_sexp = NULL, tmp_sexp;
332 struct inquire_data_s idata = { 0 };
333 char *hexgrip = NULL;
334 char *key;
335 size_t keylen, keysize;
336 char *tmp;
337 int algo = cipher_to_gcrypt (crypto->hdr.flags);
338 int shadowed;
340 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
341 if (rc)
342 return rc;
344 tmp_sexp = gcry_sexp_find_token (crypto->ciphertext_sexp, "enc-val", 0);
345 if (!tmp_sexp)
346 return gpg_error (GPG_ERR_BAD_DATA);
348 hexgrip = bin2hex (crypto->grip, sizeof (crypto->grip));
349 if (!hexgrip)
351 rc = GPG_ERR_ENOMEM;
352 goto fail;
355 rc = cache_is_shadowed (hexgrip);
356 if (rc && rc != GPG_ERR_NO_DATA)
357 goto fail;
359 shadowed = !rc ? 1 : 0;
360 if (!shadowed)
362 /* The key is not on a smartcard. */
363 gcry_sexp_t tmp2_sexp = gcry_sexp_cdr (tmp_sexp);
364 gcry_sexp_release (tmp_sexp);
365 tmp_sexp = gcry_sexp_nth (tmp2_sexp, 0);
366 gcry_sexp_release (tmp2_sexp);
367 rc = gcry_sexp_build (&enc_sexp, NULL, "(enc-val (flags pkcs1) %S)",
368 tmp_sexp);
370 else
371 rc = gcry_sexp_build (&enc_sexp, NULL, "%S", tmp_sexp);
373 gcry_sexp_release (tmp_sexp);
374 if (rc)
375 return rc;
377 crypto->agent->inquire_cb = inquire_cb;
378 idata.crypto = crypto;
379 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
380 idata.line = xmalloc (idata.len);
381 if (!idata.line)
383 rc = GPG_ERR_ENOMEM;
384 goto fail;
387 idata.len = gcry_sexp_sprint (enc_sexp, GCRYSEXP_FMT_CANON, idata.line,
388 idata.len);
389 crypto->agent->inquire_data = &idata;
390 gcry_sexp_release (enc_sexp);
391 enc_sexp = NULL;
392 log_write1 (_("Keygrip is %s, bits=%i"), hexgrip,
393 gcry_pk_get_nbits (crypto->pkey_sexp));
394 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEY %s", hexgrip);
395 if (rc)
396 goto fail;
398 if (!crypto->agent->pinentry_opts.desc)
400 tmp =
401 plus_escape (_
402 ("A %s is required to unlock the secret key for the "
403 "encrypted data file \"%s\". Please enter the %s "
404 "below."), shadowed ? "PIN" : _("passphrase"),
405 crypto->filename, shadowed ? "PIN" : _("passphrase"));
407 else
408 tmp = plus_escape (crypto->agent->pinentry_opts.desc);
410 rc = send_to_agent (crypto->agent, NULL, NULL, "SETKEYDESC %s", tmp);
411 xfree (tmp);
412 if (rc)
413 goto fail;
415 assuan_begin_confidential (crypto->agent->ctx);
416 rc = send_to_agent (crypto->agent, &key, &keylen, "PKDECRYPT");
417 assuan_end_confidential (crypto->agent->ctx);
418 if (rc)
419 goto fail;
421 rc = gcry_sexp_new (&tmp_sexp, key, keylen, 1);
422 xfree (key);
423 if (rc)
424 goto fail;
426 key = (char *) gcry_sexp_nth_data (tmp_sexp, 1, result_len);
427 if (key)
429 *result = gcry_malloc (*result_len);
430 if (!*result)
431 rc = GPG_ERR_ENOMEM;
432 else
433 memcpy (*result, key, *result_len);
435 else
436 rc = GPG_ERR_BAD_DATA;
438 gcry_sexp_release (tmp_sexp);
440 fail:
441 xfree (idata.line);
442 xfree (hexgrip);
444 if (enc_sexp)
445 gcry_sexp_release (enc_sexp);
447 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
448 rc = gpg_error (rc);
450 return rc;
453 // FIXME
454 /* Return an error for public key algorithms other than RSA or
455 * DSA. Others are supported by libgcrypt but I dont know what to do
456 * for ECDA or ELG. Key generation works as does signing but
457 * decryption fails for unsupported algorithms so disable them. */
458 static gpg_error_t
459 get_key_info (gcry_sexp_t pubkey, char **hash_str, int *hash_type,
460 size_t *len, int *pk_algo)
462 unsigned nbits = gcry_pk_get_nbits (pubkey);
463 gcry_sexp_t sexp, tmp;
464 char *algo;
465 gpg_error_t rc = 0;
467 tmp = gcry_sexp_find_token (pubkey, "public-key", 0);
468 if(!tmp)
469 return GPG_ERR_NO_PUBKEY;
471 sexp = gcry_sexp_nth (tmp, 1);
472 gcry_sexp_release (tmp);
473 algo = gcry_sexp_nth_string (sexp, 0);
474 gcry_sexp_release (sexp);
476 if (!algo)
478 return GPG_ERR_BAD_PUBKEY;
481 if (!strcmp (algo, "rsa"))
483 *pk_algo = GCRY_PK_RSA;
484 *hash_str = "sha256";
485 *hash_type = GCRY_MD_SHA256;
486 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
488 else if (!strcmp (algo, "dsa"))
490 *pk_algo = GCRY_PK_DSA;
491 switch (nbits)
493 default:
494 case 512 ... 1024:
495 *hash_str = "sha1";
496 *hash_type = GCRY_MD_SHA1;
497 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
498 break;
499 case 2048:
500 *hash_str = "sha224";
501 *hash_type = GCRY_MD_SHA224;
502 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA224);
503 break;
504 case 3072:
505 *hash_str = "sha256";
506 *hash_type = GCRY_MD_SHA256;
507 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
508 break;
509 case 7680:
510 *hash_str = "sha384";
511 *hash_type = GCRY_MD_SHA384;
512 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA384);
513 break;
514 case 15360:
515 *hash_str = "sha512";
516 *hash_type = GCRY_MD_SHA512;
517 *len = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
518 break;
521 else
522 rc = GPG_ERR_UNSUPPORTED_ALGORITHM;
524 gcry_free (algo);
525 return rc;
528 gpg_error_t
529 agent_verify (gcry_sexp_t pkey, gcry_sexp_t sig_sexp, const void *data,
530 size_t len)
532 size_t hashlen;
533 int pk_algo;
534 unsigned char *hash;
535 gcry_sexp_t data_sexp;
536 char *hash_str = NULL;
537 int hash_type;
538 gpg_error_t rc = get_key_info (pkey, &hash_str, &hash_type, &hashlen,
539 &pk_algo);
541 if (rc)
542 return rc;
544 hash = gcry_malloc (hashlen);
545 if (!hash)
546 return GPG_ERR_ENOMEM;
548 gcry_md_hash_buffer (hash_type, hash, data, len);
549 if (pk_algo == GCRY_PK_RSA)
550 rc = gcry_sexp_build (&data_sexp, NULL,
551 "(data (flags pkcs1) (hash %s %b))", hash_str,
552 hashlen, hash);
553 else
554 rc = gcry_sexp_build (&data_sexp, NULL,
555 "(data (flags raw) (value %b))", hashlen, hash);
557 gcry_free (hash);
558 if (!rc)
560 rc = gcry_pk_verify (sig_sexp, data_sexp, pkey);
561 gcry_sexp_release (data_sexp);
564 return rc;
567 /* Inquire data from the client. The inquire initiated from gpg-agent. */
568 gpg_error_t
569 agent_loopback_cb (void *user, const char *keyword)
571 struct crypto_s *crypto = user;
572 gpg_error_t rc;
573 unsigned char *result;
574 size_t len;
575 int keyparam = 0;
577 if (!strcmp (keyword, "KEYPARAM"))
579 keyparam = 1;
580 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
582 else
583 { // PASSPHRASE or NEW_PASSPHRASE
584 assuan_begin_confidential (crypto->client_ctx);
585 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
586 assuan_end_confidential (crypto->client_ctx);
588 if (!rc && len == 1 && *result == 0)
589 len = 0;
592 if (!rc)
594 if (keyparam && !len)
596 char *tmp = default_key_params (crypto);
598 if (!tmp)
599 return gpg_error (GPG_ERR_ENOMEM);
601 len = strlen (tmp);
602 result = xmalloc (len);
603 memcpy (result, tmp, len);
604 xfree (tmp);
607 pthread_cleanup_push (xfree, result);
609 if (keyparam)
610 rc = assuan_send_data (crypto->agent->ctx, result, len);
611 else
613 assuan_begin_confidential (crypto->agent->ctx);
614 rc = assuan_send_data (crypto->agent->ctx, result, len);
615 assuan_end_confidential (crypto->agent->ctx);
618 pthread_cleanup_pop (1);
620 else if (gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
622 gpg_error_t arc = assuan_write_line (crypto->agent->ctx, "CAN");
624 if (!arc)
626 char *line;
627 size_t len;
629 arc = assuan_read_line (crypto->agent->ctx, &line, &len);
630 if (arc)
631 rc = arc;
633 else
634 rc = arc;
637 return rc;
640 static gpg_error_t
641 sign (gcry_sexp_t * rsexp, gcry_sexp_t sigpkey, struct crypto_s *crypto,
642 const void *data, size_t len)
644 gpg_error_t rc;
645 char *result;
646 unsigned char grip[20];
647 char *tmp;
649 gcry_pk_get_keygrip (sigpkey, grip);
650 tmp = bin2hex (grip, sizeof(grip));
651 pthread_cleanup_push (xfree, tmp);
652 log_write1 (_("Signed with keygrip %s"), tmp);
653 rc = send_to_agent (crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
654 pthread_cleanup_pop (1);
655 if (!rc)
657 unsigned char *hash;
658 size_t hashlen;
659 char *hash_str = NULL;
660 int hash_type;
661 int pk_algo;
663 rc = get_key_info (sigpkey, &hash_str, &hash_type, &hashlen, &pk_algo);
664 if (!rc)
666 hash = gcry_malloc (hashlen);
667 if (!hash)
668 rc = gpg_error (GPG_ERR_ENOMEM);
670 if (!rc)
672 gcry_md_hash_buffer (hash_type, hash, data, len);
673 tmp = bin2hex (hash, hashlen);
674 gcry_free (hash);
675 pthread_cleanup_push (xfree, tmp);
676 rc = send_to_agent (crypto->agent, NULL, NULL,
677 "SETHASH --hash=%s %s", hash_str, tmp);
678 pthread_cleanup_pop (1);
683 if (rc)
684 return rc;
686 if (!rc)
688 struct inquire_data_s idata = { 0 };
690 idata.crypto = crypto;
691 crypto->agent->inquire_data = &idata;
692 crypto->agent->inquire_cb = inquire_cb;
693 rc = send_to_agent (crypto->agent, &result, &len, "PKSIGN");
694 if (!rc)
696 rc = gcry_sexp_sscan (rsexp, NULL, result, len);
697 xfree (result);
701 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
702 rc = gpg_error (rc);
704 return rc;
707 /* Encrypt the data file to 'pubkey' and sign with 'sigpkey'. */
708 gpg_error_t
709 encrypt_data_file (assuan_context_t ctx, struct crypto_s * crypto,
710 gcry_sexp_t pubkey, gcry_sexp_t sigpkey,
711 const char *filename, const void *xml, size_t len)
713 gpg_error_t rc;
714 void *data = NULL;
715 size_t data_len = 0;
716 void *enc_xml = NULL;
717 size_t enc_xml_len = 0;
718 unsigned char *iv = NULL;
719 size_t iv_len = 0;
720 int algo = cipher_to_gcrypt (crypto->save.hdr.flags);
721 void *key = NULL;
722 size_t keysize;
723 unsigned char sig_grip[20];
724 unsigned char grip[20];
726 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
727 if (rc)
728 return rc;
730 pthread_cleanup_push (gcry_free, key);
731 key = gcry_random_bytes_secure (keysize, GCRY_STRONG_RANDOM);
732 #ifdef HAVE_PTHREAD_TESTCANCEL
733 pthread_testcancel (); // may have been a long operation
734 #endif
735 pthread_cleanup_pop (0);
736 if (!key)
737 return gpg_error (GPG_ERR_ENOMEM);
739 gcry_pk_get_keygrip (pubkey, grip);
740 gcry_pk_get_keygrip (sigpkey, sig_grip);
741 pthread_cleanup_push (gcry_free, key);
742 rc = encrypt_xml (ctx, key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
743 &iv, &iv_len, crypto->save.hdr.iterations);
744 if (!rc)
746 gcry_sexp_t sig_sexp = NULL;
747 char *hexgrip = bin2hex (grip, 20);
749 pthread_cleanup_push (xfree, iv);
750 log_write1 (_("Encrypted with keygrip %s"), hexgrip);
751 xfree (hexgrip);
752 hexgrip = bin2hex (sig_grip, 20);
753 pthread_cleanup_push (gcry_free, enc_xml);
754 rc = sign (&sig_sexp, sigpkey, crypto, enc_xml, enc_xml_len);
755 xfree (hexgrip);
757 if (!rc)
759 rc = agent_verify (sigpkey, sig_sexp, enc_xml, enc_xml_len);
760 if (!rc)
762 gcry_sexp_t tmp_sexp;
764 rc = gcry_sexp_build (&tmp_sexp, NULL,
765 "(data (flags pkcs1) (value %b))",
766 keysize, key);
767 if (!rc)
769 gcry_sexp_t key_sexp;
771 pthread_cleanup_push ((void (*)(void *)) gcry_sexp_release,
772 (void *) sig_sexp);
773 rc = gcry_pk_encrypt (&key_sexp, tmp_sexp, pubkey);
774 pthread_cleanup_pop (0);
775 gcry_sexp_release (tmp_sexp);
777 if (!rc)
779 memcpy (crypto->save.hdr.iv, iv, iv_len);
780 crypto->save.hdr.datalen = enc_xml_len;
781 rc = gcry_sexp_build (&tmp_sexp, NULL, "%S%S", key_sexp,
782 sig_sexp);
783 gcry_sexp_release (key_sexp);
785 if (!rc)
787 data_len = gcry_sexp_sprint (tmp_sexp,
788 GCRYSEXP_FMT_CANON,
789 NULL, 0);
790 data = xmalloc (data_len);
791 if (data)
792 gcry_sexp_sprint (tmp_sexp, GCRYSEXP_FMT_CANON,
793 data, data_len);
794 else
795 rc = GPG_ERR_ENOMEM;
797 gcry_sexp_release (tmp_sexp);
804 pthread_cleanup_pop (0); // enc_xml
805 pthread_cleanup_pop (1); // iv
807 if (sig_sexp)
808 gcry_sexp_release (sig_sexp);
811 pthread_cleanup_pop (1); // key
813 if (!rc)
815 pthread_cleanup_push (gcry_free, enc_xml);
816 rc = write_file (crypto, filename, enc_xml, enc_xml_len, data, data_len,
817 pubkey, sigpkey);
818 pthread_cleanup_pop (1); // enc_xml
819 if (!rc)
820 memcpy (&crypto->hdr, &crypto->save.hdr, sizeof (file_header_t));
823 xfree (data);
824 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
825 rc = gpg_error (rc);
827 return rc;
830 /* Generated a new keypair from the key parameters in 'sexpstr'. */
831 gpg_error_t
832 generate_key (struct crypto_s * crypto, char *sexpstr, int empty, int preset)
834 gpg_error_t rc;
835 char *pkey;
836 size_t plen;
838 if (crypto->save.s2k_count)
840 rc = send_to_agent (crypto->agent, NULL, NULL,
841 "OPTION s2k-count=%lu", crypto->save.s2k_count);
842 if (rc)
843 return rc;
846 if (!crypto->agent->inquire_cb)
847 crypto->agent->inquire_cb = inquire_cb;
849 rc = send_to_agent (crypto->agent, &pkey, &plen, "GENKEY %s%s",
850 preset ? "--preset " : "",
851 empty ? "--no-protection" : "");
852 if (rc)
853 return rc;
855 if (crypto->save.pkey)
856 gcry_sexp_release (crypto->save.pkey);
858 crypto->save.pkey = NULL;
859 rc = gcry_sexp_new (&crypto->save.pkey, pkey, plen, 1);
860 if (!rc)
862 unsigned char grip[20];
864 gcry_pk_get_keygrip (crypto->save.pkey, grip);
865 char *hexgrip = bin2hex (grip, sizeof (grip));
866 log_write (_("Keygrip is %s"), hexgrip);
867 xfree (hexgrip);
869 if (!crypto->save.sigpkey)
871 gcry_sexp_build ((gcry_sexp_t *) & crypto->save.sigpkey, NULL, "%S",
872 crypto->save.pkey);
876 xfree (pkey);
877 return rc;
880 gpg_error_t
881 set_agent_option (struct agent_s * agent, const char *name, const char *value)
883 return send_to_agent (agent, NULL, NULL, "OPTION %s=%s", name, value);
886 gpg_error_t
887 set_agent_passphrase (struct crypto_s * crypto, const char *key, size_t len)
889 char *hexgrip;
890 struct inquire_data_s idata;
891 gpg_error_t rc;
892 int i;
894 /* This is for use with key files or passphrases obtained from an inquire.
895 * gpg-agent uses strings as passphrases and will truncate the passphrase
896 * at the first encountered null byte. It's only a warning because the
897 * passphrase may belong to a key shared outside of pwmd. */
898 for (i = 0; i < len; i++)
900 if (key[i] == 0)
902 log_write (_("WARNING: keylen=%i, truncated to %i."), len, i);
903 break;
907 hexgrip = bin2hex (crypto->grip, 20);
908 crypto->agent->inquire_cb = inquire_cb;
909 crypto->agent->inquire_data = &idata;
910 idata.crypto = crypto;
911 idata.line = (char *) key, idata.len = len;
912 idata.preset = 1;
913 assuan_begin_confidential (crypto->agent->ctx);
914 rc = send_to_agent (crypto->agent, NULL, NULL,
915 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
916 assuan_end_confidential (crypto->agent->ctx);
917 idata.preset = 0;
918 xfree (hexgrip);
919 return rc;
922 gpg_error_t
923 set_pinentry_mode (struct agent_s * agent, const char *mode)
925 return set_agent_option (agent, "pinentry-mode", mode);
928 gpg_error_t
929 get_pubkey_bin (struct crypto_s * crypto, const unsigned char *grip,
930 gcry_sexp_t * result)
932 char *hexgrip = bin2hex (grip, 20);
933 gpg_error_t rc;
935 if (!hexgrip)
936 return GPG_ERR_ENOMEM;
938 rc = get_pubkey (crypto, hexgrip, result);
939 xfree (hexgrip);
940 return rc;
943 gpg_error_t
944 get_pubkey (struct crypto_s * crypto, const char *grip, gcry_sexp_t * result)
946 char *pkey = NULL;
947 size_t plen;
948 gpg_error_t rc;
950 rc = send_to_agent (crypto->agent, &pkey, &plen, "READKEY %s", grip);
951 if (!rc)
952 rc = gcry_sexp_new (result, pkey, plen, 1);
954 xfree (pkey);
955 return rc;
958 gpg_error_t
959 agent_set_pinentry_options (struct agent_s * agent)
961 gpg_error_t rc = 0;
962 struct pinentry_option_s *opts = &agent->pinentry_opts;
964 if (!opts->display && getenv ("DISPLAY"))
966 rc = set_agent_option (agent, "display", getenv ("DISPLAY"));
967 if (!rc)
969 opts->display = str_dup (getenv ("DISPLAY"));
972 else if (!opts->ttyname && ttyname (STDOUT_FILENO))
974 rc = set_agent_option (agent, "ttyname", ttyname (STDOUT_FILENO));
975 if (!rc)
977 rc = set_agent_option (agent, "ttytype",
978 opts->ttytype ? opts->ttytype : getenv ("TERM"));
979 if (!rc)
981 xfree (opts->ttyname);
982 xfree (opts->ttytype);
983 opts->ttyname = str_dup (ttyname (STDOUT_FILENO));
984 opts->ttytype = str_dup (getenv ("TERM"));
989 return rc;
992 static gpg_error_t
993 inquire_keyfile (void *user, const char *keyword)
995 struct crypto_s *crypto = user;
996 char *filename = crypto->agent->inquire_data2;
997 char *params = crypto->agent->inquire_data3;
998 int fd;
999 struct stat st;
1000 unsigned char *buf;
1001 size_t len;
1002 gpg_error_t rc;
1004 if (!strcmp (keyword, "KEYPARAM"))
1005 return assuan_send_data (crypto->agent->ctx, params, strlen (params));
1007 // This function is only used when generating a new keypair.
1008 if (strcmp (keyword, "NEW_PASSPHRASE"))
1009 return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
1011 if (stat (filename, &st) == -1)
1012 return gpg_error_from_errno (errno);
1014 if (crypto->agent->inquire_maxlen
1015 && st.st_size > crypto->agent->inquire_maxlen)
1017 log_write (_("The passphrase is too large: have=%u, max=%u."),
1018 (unsigned) st.st_size, crypto->agent->inquire_maxlen);
1019 return GPG_ERR_TOO_LARGE;
1022 buf = gcry_malloc_secure (st.st_size);
1023 if (!buf)
1024 return GPG_ERR_ENOMEM;
1026 fd = open (filename, O_RDONLY);
1027 if (fd == -1)
1028 rc = gpg_error_from_errno (errno);
1029 else
1031 len = read (fd, buf, st.st_size);
1032 if (len == st.st_size)
1034 assuan_begin_confidential (crypto->agent->ctx);
1035 rc = assuan_send_data (crypto->agent->ctx, buf, len);
1036 assuan_end_confidential (crypto->agent->ctx);
1038 else if (len == -1)
1039 rc = gpg_error_from_errno (errno);
1040 else
1041 rc = GPG_ERR_BUFFER_TOO_SHORT;
1044 close (fd);
1045 gcry_free (buf);
1046 return rc;
1049 gpg_error_t
1050 agent_export_common (struct crypto_s * crypto, const char *hexgrip,
1051 const char *sign_hexgrip, int no_passphrase,
1052 const void *data, size_t datalen, const char *outfile,
1053 const char *keyparams, const char *keyfile)
1055 gpg_error_t rc = 0;
1057 if (!sign_hexgrip && hexgrip)
1058 sign_hexgrip = hexgrip;
1060 if (sign_hexgrip)
1062 if (crypto->sigpkey_sexp)
1063 gcry_sexp_release (crypto->sigpkey_sexp);
1065 crypto->sigpkey_sexp = NULL;
1066 rc = get_pubkey (crypto, sign_hexgrip, &crypto->save.sigpkey);
1067 if (rc)
1068 return rc;
1070 gcry_pk_get_keygrip (crypto->save.sigpkey, crypto->sign_grip);
1073 if (hexgrip)
1075 rc = get_pubkey (crypto, hexgrip, &crypto->save.pkey);
1076 if (!rc)
1077 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
1079 else
1081 struct inquire_data_s idata = { 0 };
1082 char *params = keyparams ? str_dup (keyparams)
1083 : default_key_params (crypto);
1085 pthread_cleanup_push (xfree, params);
1086 log_write (_("Generating a new keypair ..."));
1087 if (keyfile)
1089 log_write (_("Using passphrase obtained from file '%s'"), keyfile);
1090 rc = set_pinentry_mode (crypto->agent, "loopback");
1091 crypto->agent->inquire_cb = inquire_keyfile;
1092 crypto->agent->inquire_data = crypto;
1093 crypto->agent->inquire_data2 = (char *) keyfile;
1094 crypto->agent->inquire_data3 = params;
1096 else
1098 idata.line = params;
1099 idata.len = strlen (params);
1100 idata.crypto = crypto;
1101 crypto->agent->inquire_cb = inquire_cb;
1102 crypto->agent->inquire_data = &idata;
1105 if (!rc)
1107 rc = generate_key (crypto, params, no_passphrase, 1);
1108 if (!rc)
1109 gcry_pk_get_keygrip (crypto->save.pkey, crypto->grip);
1112 (void) set_pinentry_mode (crypto->agent, "ask");
1113 pthread_cleanup_pop (1);
1116 if (!rc)
1118 rc = encrypt_data_file (NULL, crypto, crypto->save.pkey,
1119 crypto->save.sigpkey, outfile, data, datalen);
1120 if (!rc)
1122 char *tmp = bin2hex (crypto->grip, sizeof (crypto->grip));
1124 log_write (_("Success! Keygrip is %s."), tmp);
1125 rc = send_to_agent (crypto->agent, NULL, NULL,
1126 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1127 xfree (tmp);
1129 if (sign_hexgrip)
1131 tmp = bin2hex (crypto->sign_grip, sizeof (crypto->sign_grip));
1132 log_write (_("Signed with keygrip %s."), tmp);
1133 xfree (tmp);
1138 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
1139 rc = gpg_error (rc);
1141 return rc;
1144 char *
1145 default_key_params (struct crypto_s *crypto)
1147 return config_get_string (NULL, "keyparam");
1150 gpg_error_t
1151 agent_passwd (struct crypto_s * crypto)
1153 struct inquire_data_s idata = { 0 };
1154 gpg_error_t rc;
1155 char *tmp = bin2hex (crypto->grip, 20);
1157 idata.crypto = crypto;
1158 crypto->agent->inquire_cb = inquire_cb;
1159 crypto->agent->inquire_data = &idata;
1160 rc = send_to_agent (crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1161 xfree (tmp);
1162 return rc;
1165 gpg_error_t
1166 kill_scd (struct agent_s * agent)
1168 gpg_error_t rc = 0;
1170 if (!use_agent)
1171 return 0;
1173 if (config_get_boolean (NULL, "kill_scd"))
1175 rc = send_to_agent (agent, NULL, NULL, "SCD KILLSCD");
1176 if (rc && gpg_err_code (rc) != GPG_ERR_NO_SCDAEMON)
1177 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (rc));
1180 return rc;