Portability fixes. Mostly for Android.
[pwmd.git] / src / agent.c
blob91d6bb4099d35958b37287a4a9cb9fd8cb55338d
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <pwd.h>
27 #include <sys/types.h>
28 #include <signal.h>
29 #include <sys/wait.h>
30 #include <fcntl.h>
31 #include <dirent.h>
33 #include "pwmd-error.h"
34 #include "mem.h"
35 #include "common.h"
36 #include "commands.h"
37 #include "agent.h"
38 #include "util-misc.h"
39 #include "util-string.h"
40 #include "mutex.h"
41 #include "rcfile.h"
42 #include "cache.h"
43 #include "cipher.h"
45 #ifdef WITH_LIBACL
46 #include <acl/libacl.h>
47 #endif
49 #ifdef HAVE_LIMITS_H
50 #include <limits.h>
51 #endif
53 static uint8_t pwmd_magic[5] = { '\177', 'P', 'W', 'M', 'D' };
55 static gpg_error_t mem_realloc_cb(void *data, const void *buffer, size_t len)
57 membuf_t *mem = (membuf_t *)data;
58 void *p;
60 if (!buffer)
61 return 0;
63 if ((p = xrealloc(mem->buf, mem->len + len)) == NULL)
64 return 1;
66 mem->buf = p;
67 memcpy((char *)mem->buf + mem->len, buffer, len);
68 mem->len += len;
69 return 0;
72 static gpg_error_t status_cb(void * data, const char *line)
74 struct agent_s *agent = data;
76 agent->inquire_maxlen = 0;
78 if (!strncmp(line, "INQUIRE_MAXLEN ", 15)) {
79 agent->inquire_maxlen = atoi(line+15);
80 if (!agent->client_ctx)
81 return 0;
84 return send_status(agent->client_ctx, STATUS_AGENT, "%s", line);
87 static gpg_error_t 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;
98 rc = assuan_transact(a->ctx, cmd, mem_realloc_cb, &a->data,
99 a->inquire_cb, a->inquire_data, status_cb, a);
101 if (rc)
102 xfree(a->data.buf);
103 else {
104 if (a->data.buf) {
105 mem_realloc_cb(&a->data, "", 1);
106 if (result)
107 *result = (char *)a->data.buf;
108 else
109 xfree(a->data.buf);
111 if (len)
112 *len = a->data.len;
116 return rc;
119 /* This commands are sent from launch_agent() after reconnecting to the agent
120 * and also from the initial client connection. */
121 static gpg_error_t send_agent_common_options(struct agent_s *agent)
123 gpg_error_t rc;
125 rc = send_to_agent(agent, NULL, NULL, "OPTION cache-ttl-opt-preset=-1");
126 return rc;
129 static gpg_error_t launch_agent(struct agent_s *agent)
131 gpg_error_t rc;
132 assuan_context_t ctx;
133 const char *t = NULL;
134 static struct assuan_malloc_hooks mhooks = { xmalloc, xrealloc, xfree };
135 char *s, buf[LINE_MAX];
136 FILE *fp;
138 s = config_get_string("global", "agent_env_file");
139 if (s) {
140 char *ss = expand_homedir(s);
142 xfree(s);
143 fp = fopen(ss, "r");
144 xfree(ss);
146 if (fp) {
147 while ((s = fgets(buf, sizeof(buf), fp))) {
148 s = str_chomp(s);
149 if (!strncmp(s, "GPG_AGENT_INFO=", strlen("GPG_AGENT_INFO="))) {
150 setenv("GPG_AGENT_INFO", s+strlen("GPG_AGENT_INFO="), 1);
151 break;
155 fclose(fp);
157 else
158 log_write("%s: %s", s, pwmd_strerror(gpg_error_from_syserror()));
161 t = getenv("GPG_AGENT_INFO");
162 if (!t)
163 return gpg_err_code(GPG_ERR_NO_AGENT);
165 rc = assuan_new_ext(&ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
166 debug_level ? assuan_log_cb : NULL, "AGENT ");
167 if (rc)
168 return rc;
170 char **fields = str_split(t, ":", 0);
171 rc = assuan_socket_connect(ctx, fields[0], ASSUAN_INVALID_PID, 0);
172 strv_free(fields);
173 if (rc) {
174 assuan_release(ctx);
175 return rc;
178 if (agent->ctx) {
179 /* Restore the previous agent settings for this new context. */
180 assuan_release(agent->ctx);
181 agent->ctx = ctx;
182 rc = send_agent_common_options(agent);
183 if (!rc && agent->display)
184 rc = set_agent_option(agent, "display", agent->display);
186 if (!rc && agent->ttyname)
187 rc = set_agent_option(agent, "ttyname", agent->ttyname);
189 if (!rc && agent->ttytype)
190 rc = set_agent_option(agent, "ttytype", agent->ttytype);
192 if (!rc && agent->lc_messages)
193 rc = set_agent_option(agent, "lc-messages", agent->lc_messages);
195 if (!rc && agent->lc_ctype)
196 rc = set_agent_option(agent, "lc-ctype", agent->lc_ctype);
199 agent->ctx = ctx;
200 return 0;
203 gpg_error_t send_to_agent(struct agent_s *agent, char **result, size_t *len,
204 const char *fmt, ...)
206 gpg_error_t rc = 0;
207 va_list ap;
208 char *cmd;
210 if (!agent->ctx) {
211 rc = launch_agent(agent);
212 if (rc)
213 return rc;
216 va_start(ap, fmt);
217 if (str_vasprintf(&cmd, fmt, ap) > 0) {
218 rc = assuan_command(agent, result, len, cmd);
219 if (!agent->restart && gpg_err_source(rc) == GPG_ERR_SOURCE_DEFAULT
220 && (gpg_err_code(rc) == GPG_ERR_ASS_CONNECT_FAILED
221 || gpg_err_code(rc) == GPG_ERR_EPIPE)) {
222 unsetenv("GPG_AGENT_INFO");
223 agent->restart = 1;
224 rc = launch_agent(agent);
225 if (!rc)
226 rc = assuan_command(agent, result, len, cmd);
229 agent->restart = 0;
230 xfree(cmd);
232 else
233 rc = GPG_ERR_ENOMEM;
235 va_end(ap);
236 return rc;
239 static void agent_disconnect(struct agent_s *agent)
241 if (!agent)
242 return;
244 if (agent->ctx)
245 assuan_release(agent->ctx);
247 agent->ctx = NULL;
250 void cleanup_agent(struct agent_s *agent)
252 if (!agent)
253 return;
255 xfree(agent->desc);
256 xfree(agent->display);
257 xfree(agent->ttyname);
258 xfree(agent->ttytype);
259 xfree(agent->lc_messages);
260 xfree(agent->lc_ctype);
262 if (agent->ctx)
263 agent_disconnect(agent);
265 xfree(agent);
268 gpg_error_t agent_init(struct agent_s **agent)
270 struct agent_s *new = xcalloc(1, sizeof(struct agent_s));
272 if (!new)
273 return GPG_ERR_ENOMEM;
275 *agent = new;
276 return 0;
279 void set_header_defaults(file_header_t *hdr)
281 char *s = config_get_string(NULL, "cipher");
282 int flags = cipher_string_to_cipher(s);
284 xfree(s);
285 memset(hdr, 0, sizeof(file_header_t));
286 memcpy(hdr->magic, pwmd_magic, sizeof(hdr->magic));
287 if (flags == -1)
288 log_write(_("Invalid 'cipher' in configuration file. Using a default of aes256."));
289 hdr->flags = flags == -1 ? PWMD_CIPHER_AES256 : flags;
290 hdr->version = VERSION_HEX;
293 gpg_error_t read_data_header(const char *filename, file_header_t *rhdr,
294 struct stat *rst, int *rfd)
296 gpg_error_t rc = 0;
297 size_t len;
298 struct stat st;
299 file_header_t hdr;
300 int fd;
302 if (lstat(filename, &st) == -1)
303 return gpg_error_from_syserror();
305 if (!S_ISREG(st.st_mode))
306 return GPG_ERR_ENOANO;
308 fd = open(filename, O_RDONLY);
309 if (fd == -1)
310 return gpg_error_from_syserror();
312 len = read(fd, &hdr, sizeof(file_header_t));
313 if (len != sizeof(file_header_t))
314 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
316 if (!rc && memcmp(hdr.magic, pwmd_magic, sizeof(hdr.magic)))
317 rc = GPG_ERR_BAD_DATA;
318 else if (hdr.version < 0x030000)
319 rc = GPG_ERR_UNKNOWN_VERSION;
321 if (rc)
322 close(fd);
323 else {
324 if (rhdr)
325 *rhdr = hdr;
326 if (rst)
327 *rst = st;
328 if (rfd)
329 *rfd = fd;
330 else
331 close(fd);
334 return rc;
337 gpg_error_t read_data_file(const char *filename, struct crypto_s *crypto)
339 int fd;
340 gpg_error_t rc = 0;
341 size_t len, rlen;
342 char *buf = NULL;
343 struct stat st;
345 cleanup_crypto_stage1(crypto);
346 rc = read_data_header(filename, &crypto->hdr, &st, &fd);
347 if (rc)
348 return rc;
350 crypto->ciphertext_len = crypto->hdr.datalen;
351 crypto->ciphertext = xmalloc(crypto->hdr.datalen);
352 if (!crypto->ciphertext) {
353 rc = GPG_ERR_ENOMEM;
354 goto fail;
357 rlen = read(fd, crypto->grip, 20);
358 if (rlen != 20) {
359 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
360 goto fail;
363 rlen = read(fd, crypto->sign_grip, 20);
364 if (rlen != 20) {
365 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
366 goto fail;
369 len = read(fd, crypto->ciphertext, crypto->hdr.datalen);
370 if (len != crypto->hdr.datalen) {
371 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
372 goto fail;
375 len = st.st_size-sizeof(file_header_t)-crypto->hdr.datalen-40;
376 buf = xmalloc(len);
377 if (!buf) {
378 rc = GPG_ERR_ENOMEM;
379 goto fail;
382 rlen = read(fd, buf, len);
383 if (rlen != len) {
384 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
385 goto fail;
388 rc = gcry_sexp_new(&crypto->ciphertext_sexp, buf, rlen, 1);
389 if (rc)
390 goto fail;
392 if (crypto->pkey_sexp)
393 gcry_sexp_release(crypto->pkey_sexp);
395 if (crypto->sigpkey_sexp)
396 gcry_sexp_release(crypto->sigpkey_sexp);
398 crypto->pkey_sexp = crypto->sigpkey_sexp = NULL;
399 rc = get_pubkey_bin(crypto, crypto->grip, &crypto->pkey_sexp);
400 if (!rc)
401 rc = get_pubkey_bin(crypto, crypto->sign_grip, &crypto->sigpkey_sexp);
403 fail:
404 close(fd);
405 xfree(buf);
406 return rc;
409 static gpg_error_t inquire_cb(void * user, const char *keyword)
411 struct inquire_data_s *idata = user;
413 if (!idata->preset && (!strcmp(keyword, "PASSPHRASE")
414 || !strcmp(keyword, "NEW_PASSPHRASE"))) {
415 return agent_loopback_cb(idata->crypto, keyword);
417 // SAVE --inquire-keyparam
418 else if (idata->preset && !strcmp(keyword, "KEYPARAM")) {
419 idata->preset = 0;
420 return agent_loopback_cb(idata->crypto, keyword);
423 if (idata->crypto->agent->inquire_maxlen
424 && idata->len > idata->crypto->agent->inquire_maxlen) {
425 log_write(_("Inquired data too large: have=%u, max=%u"), idata->len,
426 idata->crypto->agent->inquire_maxlen);
427 return GPG_ERR_TOO_LARGE;
430 idata->crypto->agent->inquire_maxlen = 0;
431 return assuan_send_data(idata->crypto->agent->ctx, idata->line, idata->len);
434 static gpg_error_t extract_key(struct crypto_s *crypto, unsigned char **result,
435 size_t *result_len)
437 gpg_error_t rc;
438 gcry_sexp_t enc_sexp = NULL, tmp_sexp;
439 struct inquire_data_s idata = {0};
440 char *hexgrip = NULL;
441 char *key;
442 size_t keylen, keysize;
443 char *tmp;
444 int algo = cipher_to_gcrypt(crypto->hdr.flags);
445 int shadowed;
447 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
448 if (rc)
449 return rc;
451 tmp_sexp = gcry_sexp_find_token(crypto->ciphertext_sexp, "enc-val", 0);
452 if (!tmp_sexp)
453 return GPG_ERR_BAD_DATA;
455 hexgrip = bin2hex(crypto->grip, sizeof(crypto->grip));
456 if (!hexgrip) {
457 rc = GPG_ERR_ENOMEM;
458 goto fail;
461 rc = cache_is_shadowed(hexgrip);
462 if (rc && rc != GPG_ERR_NO_DATA)
463 goto fail;
465 shadowed = !rc ? 1 : 0;
466 if (!shadowed) {
467 gcry_sexp_t tmp2_sexp = gcry_sexp_cdr(tmp_sexp);
468 gcry_sexp_release(tmp_sexp);
469 tmp_sexp = gcry_sexp_nth(tmp2_sexp, 0);
470 gcry_sexp_release(tmp2_sexp);
471 rc = gcry_sexp_build(&enc_sexp, NULL, "(enc-val (flags pkcs1) %S)",
472 tmp_sexp);
474 else
475 rc = gcry_sexp_build(&enc_sexp, NULL, "%S", tmp_sexp);
477 gcry_sexp_release(tmp_sexp);
478 if (rc)
479 return rc;
481 crypto->agent->inquire_cb = inquire_cb;
482 idata.crypto = crypto;
483 idata.len = gcry_sexp_sprint(enc_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
484 idata.line = xmalloc(idata.len);
485 if (!idata.line) {
486 rc = GPG_ERR_ENOMEM;
487 goto fail;
490 idata.len = gcry_sexp_sprint(enc_sexp, GCRYSEXP_FMT_CANON, idata.line,
491 idata.len);
492 crypto->agent->inquire_data = &idata;
493 gcry_sexp_release(enc_sexp);
494 enc_sexp = NULL;
495 log_write1(_("Keygrip is %s, bits=%i"), hexgrip,
496 gcry_pk_get_nbits(crypto->pkey_sexp));
497 rc = send_to_agent(crypto->agent, NULL, NULL, "SETKEY %s", hexgrip);
498 if (rc)
499 goto fail;
501 if (!crypto->agent->desc) {
502 tmp = plus_escape(_(
503 "A %s is required to unlock the secret key for the "
504 "encrypted data file \"%s\". Please enter the %s "
505 "below."),
506 shadowed ? "PIN" : _("passphrase"), crypto->filename,
507 shadowed ? "PIN" : _("passphrase"));
509 else
510 tmp = plus_escape(crypto->agent->desc);
512 rc = send_to_agent(crypto->agent, NULL, NULL, "SETKEYDESC %s", tmp);
513 xfree(tmp);
514 if (rc)
515 goto fail;
517 assuan_begin_confidential(crypto->agent->ctx);
518 rc = send_to_agent(crypto->agent, &key, &keylen, "PKDECRYPT");
519 assuan_end_confidential(crypto->agent->ctx);
520 if (rc)
521 goto fail;
523 rc = gcry_sexp_new(&tmp_sexp, key, keylen, 1);
524 xfree(key);
525 if (rc)
526 goto fail;
528 key = (char *)gcry_sexp_nth_data(tmp_sexp, 1, result_len);
529 if (key) {
530 *result = gcry_malloc(*result_len);
531 if (!*result)
532 rc = GPG_ERR_ENOMEM;
533 else
534 memcpy(*result, key, *result_len);
536 else
537 rc = GPG_ERR_BAD_DATA;
539 gcry_sexp_release(tmp_sexp);
541 fail:
542 xfree(idata.line);
543 xfree(hexgrip);
545 if (enc_sexp)
546 gcry_sexp_release(enc_sexp);
548 return rc;
551 static gpg_error_t verify(gcry_sexp_t pkey, gcry_sexp_t sig_sexp,
552 const void * data, size_t len)
554 gpg_error_t rc;
555 unsigned hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
556 unsigned char *hash;
557 gcry_sexp_t data_sexp;
559 hash = gcry_malloc(hashlen);
560 if (!hash)
561 return GPG_ERR_ENOMEM;
563 gcry_md_hash_buffer(GCRY_MD_SHA256, hash, data, len);
564 rc = gcry_sexp_build(&data_sexp, NULL,
565 "(data (flags pkcs1) (hash sha256 %b))", hashlen, hash);
566 gcry_free(hash);
567 if (!rc) {
568 rc = gcry_pk_verify(sig_sexp, data_sexp, pkey);
569 gcry_sexp_release(data_sexp);
572 return rc;
575 #define CRYPTO_BLOCKSIZE(c) (blocksize * 1024)
578 * Useful for a large amount of data. Rather than doing all of the data in one
579 * iteration do it in chunks. This lets the command be cancelable rather than
580 * waiting for it to complete.
582 static gpg_error_t iterate_crypto_once(gcry_cipher_hd_t h, unsigned char *inbuf,
583 size_t insize, size_t blocksize, status_msg_t which)
585 gpg_error_t rc = 0;
586 off_t len = CRYPTO_BLOCKSIZE(blocksize);
587 void * p = gcry_malloc(len);
588 off_t total = 0;
589 unsigned char *inbuf2;
591 if (!p)
592 return GPG_ERR_ENOMEM;
594 if (insize < CRYPTO_BLOCKSIZE(blocksize))
595 len = insize;
597 pthread_cleanup_push(gcry_free, p);
599 for (;;) {
600 inbuf2 = inbuf+total;
601 unsigned char *tmp;
603 if (len + total > insize)
604 len = blocksize;
606 if (which == STATUS_ENCRYPT)
607 rc = gcry_cipher_encrypt(h, p, len, inbuf2, len);
608 else
609 rc = gcry_cipher_decrypt(h, p, len, inbuf2, len);
611 if (rc)
612 break;
614 tmp = inbuf+total;
615 memmove(tmp, p, len);
616 total += len;
617 if (total >= insize)
618 break;
620 #ifdef HAVE_PTHREAD_TESTCANCEL
621 pthread_testcancel();
622 #endif
625 pthread_cleanup_pop(1);
626 return rc;
629 static void cleanup_cipher(void *arg)
631 gcry_cipher_close((gcry_cipher_hd_t)arg);
634 gpg_error_t decrypt_data(assuan_context_t ctx, struct crypto_s *crypto)
636 gpg_error_t rc;
637 unsigned char *key = NULL;
638 size_t keylen = 0;
639 gcry_cipher_hd_t h = NULL;
640 size_t blocksize, keysize;
641 int algo = cipher_to_gcrypt(crypto->hdr.flags);
642 void * outbuf = NULL;
643 gcry_sexp_t sig_sexp;
644 uint64_t n = crypto->hdr.iterations;
645 long progress = 0;
647 rc = extract_key(crypto, &key, &keylen);
648 if (rc)
649 return rc;
651 sig_sexp = gcry_sexp_find_token(crypto->ciphertext_sexp, "sig-val", 0);
652 if (!sig_sexp) {
653 gcry_free(key);
654 return GPG_ERR_BAD_DATA;
657 pthread_cleanup_push(gcry_free, key);
658 rc = verify(crypto->sigpkey_sexp, sig_sexp, crypto->ciphertext, crypto->ciphertext_len);
659 gcry_sexp_release(sig_sexp);
661 if (!rc) {
662 rc = gcry_cipher_open(&h, algo, GCRY_CIPHER_MODE_CBC, 0);
663 if (!rc) {
664 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL,
665 &keysize);
666 if (!rc) {
667 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, NULL,
668 &blocksize);
669 if (!rc) {
670 rc = gcry_cipher_setiv(h, crypto->hdr.iv,
671 sizeof(crypto->hdr.iv));
672 if (!rc) {
673 rc = gcry_cipher_setkey(h, key, keylen);
680 pthread_cleanup_push(cleanup_cipher, rc ? NULL : h);
682 if (!rc) {
683 outbuf = gcry_malloc(crypto->hdr.datalen);
684 if (!outbuf)
685 rc = GPG_ERR_ENOMEM;
688 pthread_cleanup_push(gcry_free, outbuf);
690 if (!rc) {
691 memcpy(outbuf, crypto->ciphertext, crypto->hdr.datalen);
692 rc = iterate_crypto_once(h, outbuf, crypto->hdr.datalen, blocksize,
693 STATUS_DECRYPT);
694 if (!rc) {
695 key[0] ^= 1;
696 rc = gcry_cipher_setkey(h, key, keylen);
700 if (!rc) {
701 progress = config_get_long(NULL, "cipher_progress");
702 if (progress == -1)
703 progress = strtol(DEFAULT_ITERATION_PROGRESS, NULL, 10);
706 if (!rc && ctx && crypto->hdr.iterations)
707 rc = send_status(ctx, STATUS_DECRYPT, "%llu %llu", 0,
708 crypto->hdr.iterations);
710 for (n = 0; !rc && n < crypto->hdr.iterations; n++) {
711 if (ctx && !(n%progress)) {
712 rc = send_status(ctx, STATUS_DECRYPT, "%llu %llu", n,
713 crypto->hdr.iterations);
714 if (rc)
715 break;
718 rc = gcry_cipher_setiv(h, crypto->hdr.iv, sizeof(crypto->hdr.iv));
719 if (rc)
720 break;
722 rc = iterate_crypto_once(h, outbuf, crypto->hdr.datalen, blocksize,
723 STATUS_DECRYPT);
726 if (!rc && ctx && crypto->hdr.iterations)
727 rc = send_status(ctx, STATUS_DECRYPT, "%llu %llu", n,
728 crypto->hdr.iterations);
730 pthread_cleanup_pop(rc ? 1 : 0); // outbuf
731 pthread_cleanup_pop(1); // cipher
732 pthread_cleanup_pop(1); // key
733 if (!rc) {
734 crypto->plaintext = outbuf;
735 crypto->plaintext_len = crypto->hdr.datalen;
738 return rc;
741 gpg_error_t decrypt_xml(struct crypto_s *crypto, const void * data,
742 size_t len)
744 gcry_cipher_hd_t h = NULL;
745 gpg_error_t rc;
747 rc = gcry_cipher_open(&h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
748 if (rc)
749 return rc;
751 gcry_free(crypto->plaintext);
752 crypto->plaintext = gcry_malloc(len);
753 if (!crypto->plaintext) {
754 rc = GPG_ERR_ENOMEM;
755 goto done;
758 rc = gcry_cipher_setiv(h, cache_iv, cache_blocksize);
759 if (rc)
760 goto done;
762 rc = gcry_cipher_setkey(h, cache_key, cache_keysize);
763 if (rc)
764 goto done;
766 rc = gcry_cipher_decrypt(h, crypto->plaintext, len, data, len);
767 if (rc) {
768 gcry_free(crypto->plaintext);
769 crypto->plaintext = NULL;
772 crypto->plaintext_len = len;
774 done:
775 if (h)
776 gcry_cipher_close(h);
778 return rc;
781 gpg_error_t encrypt_xml(assuan_context_t ctx, void * key, size_t keylen,
782 int algo, const void * xml, size_t len, void * *result, size_t
783 *result_len, unsigned char **iv, size_t *iv_len, uint64_t iter)
785 gpg_error_t rc;
786 gcry_cipher_hd_t h;
787 size_t blocksize, keysize;
788 void * inbuf = NULL;
789 size_t olen = len;
790 uint64_t n;
791 long progress;
792 unsigned char *tmpkey = NULL;
793 int free_iv = *(iv_len) == 0;
795 rc = gcry_cipher_open(&h, algo, GCRY_CIPHER_MODE_CBC, 0);
796 if (rc)
797 return rc;
799 pthread_cleanup_push(cleanup_cipher, h);
800 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
801 if (!rc)
802 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, NULL, &blocksize);
804 if (!rc && *(iv_len) == 0) {
805 *(iv) = xmalloc(blocksize);
806 if (!*(iv))
807 rc = GPG_ERR_ENOMEM;
809 gcry_create_nonce(*(iv), blocksize);
812 pthread_cleanup_push(xfree, *(iv_len) == 0 ? *(iv) : NULL);
813 if (!rc) {
814 *iv_len = blocksize;
815 tmpkey = gcry_malloc(keylen);
816 if (!tmpkey)
817 rc = GPG_ERR_ENOMEM;
820 pthread_cleanup_push(gcry_free, tmpkey);
822 if (!rc) {
823 memcpy(tmpkey, key, keylen);
824 tmpkey[0] ^= 1;
825 rc = gcry_cipher_setkey(h, tmpkey, keylen);
826 if (!rc) {
827 if (len%blocksize)
828 len += blocksize-(len%blocksize);
832 if (!rc) {
833 inbuf = gcry_malloc(len);
834 if (!inbuf)
835 rc = GPG_ERR_ENOMEM;
838 pthread_cleanup_push(gcry_free, inbuf);
840 if (!rc) {
841 memset(inbuf, 0, len);
842 memcpy(inbuf, xml, olen);
843 progress = config_get_long(NULL, "cipher_progress");
844 if (progress == -1)
845 progress = strtol(DEFAULT_ITERATION_PROGRESS, NULL, 10);
847 if (!rc && ctx && iter)
848 rc = send_status(ctx, STATUS_ENCRYPT, "%llu %llu", 0, iter);
850 for (n = 0; !rc && n < iter; n++) {
851 if (ctx && !(n%progress)) {
852 rc = send_status(ctx, STATUS_ENCRYPT, "%llu %llu", n, iter);
853 if (rc)
854 break;
857 rc = gcry_cipher_setiv(h, *(iv), blocksize);
858 if (rc)
859 break;
861 rc = iterate_crypto_once(h, inbuf, len, blocksize, STATUS_ENCRYPT);
865 if (!rc && ctx && iter)
866 rc = send_status(ctx, STATUS_ENCRYPT, "%llu %llu", n, iter);
868 if (!rc) {
869 /* Do at least one iteration. */
870 rc = gcry_cipher_setiv(h, *(iv), blocksize);
871 if (!rc) {
872 rc = gcry_cipher_setkey(h, key, keylen);
873 if (!rc)
874 rc = iterate_crypto_once(h, inbuf, len, blocksize,
875 STATUS_ENCRYPT);
879 pthread_cleanup_pop(rc ? 1 : 0); // inbuf
880 pthread_cleanup_pop(1); // tmpkey
881 pthread_cleanup_pop(rc && free_iv ? 1 : 0); // iv
882 pthread_cleanup_pop(1); // cipher
883 *result = rc ? NULL : inbuf;
884 *result_len = len;
885 return rc;
888 gpg_error_t agent_loopback_cb(void * user, const char *keyword)
890 struct crypto_s *crypto = user;
891 gpg_error_t rc;
892 unsigned char *result;
893 size_t len;
894 int keyparam = 0;
896 if (!strcmp(keyword, "KEYPARAM")) {
897 keyparam = 1;
898 rc = assuan_inquire(crypto->client_ctx, keyword, &result, &len, 0);
900 else { // PASSPHRASE or NEW_PASSPHRASE
901 assuan_begin_confidential(crypto->client_ctx);
902 rc = assuan_inquire(crypto->client_ctx, keyword, &result, &len, 0);
903 assuan_end_confidential(crypto->client_ctx);
906 if (!rc) {
907 if (keyparam && !len) {
908 char *tmp = default_key_params(crypto);
910 if (!tmp)
911 return gpg_error(GPG_ERR_ENOMEM);
913 len = strlen(tmp);
914 result = xmalloc(len);
915 memcpy(result, tmp, len);
916 xfree(tmp);
919 pthread_cleanup_push(xfree, result);
921 if (keyparam)
922 rc = assuan_send_data(crypto->agent->ctx, result, len);
923 else {
924 assuan_begin_confidential(crypto->agent->ctx);
925 rc = assuan_send_data(crypto->agent->ctx, result, len);
926 assuan_end_confidential(crypto->agent->ctx);
929 pthread_cleanup_pop(1);
931 else if (gpg_err_code(rc) == GPG_ERR_ASS_CANCELED) {
932 gpg_error_t arc = assuan_write_line(crypto->agent->ctx, "CAN");
934 if (!arc) {
935 char *line;
936 size_t len;
938 arc = assuan_read_line(crypto->agent->ctx, &line, &len);
939 if (arc)
940 rc = arc;
942 else
943 rc = arc;
946 return rc;
949 static gpg_error_t sign(gcry_sexp_t *rsexp, const char *sign_hexgrip,
950 struct crypto_s *crypto, const void * data, size_t len)
952 gpg_error_t rc;
953 char *result;
954 char *tmp = sign_hexgrip ? str_dup(sign_hexgrip)
955 : bin2hex(crypto->grip, sizeof(crypto->grip));
957 pthread_cleanup_push(xfree, tmp);
958 log_write1(_("Signed with keygrip %s"), tmp);
959 rc = send_to_agent(crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
960 pthread_cleanup_pop(1);
961 if (!rc) {
962 unsigned char *hash;
963 unsigned hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
965 hash = gcry_malloc(hashlen);
966 if (!hash)
967 return GPG_ERR_ENOMEM;
969 gcry_md_hash_buffer(GCRY_MD_SHA256, hash, data, len);
970 tmp = bin2hex(hash, hashlen);
971 gcry_free(hash);
972 pthread_cleanup_push(xfree, tmp);
973 rc = send_to_agent(crypto->agent, NULL, NULL,
974 "SETHASH --hash=sha256 %s", tmp);
975 pthread_cleanup_pop(1);
978 if (!rc) {
979 struct inquire_data_s idata = {0};
981 idata.crypto = crypto;
982 crypto->agent->inquire_data = &idata;
983 crypto->agent->inquire_cb = inquire_cb;
984 rc = send_to_agent(crypto->agent, &result, &len, "PKSIGN");
985 if (!rc) {
986 rc = gcry_sexp_sscan(rsexp, NULL, result, len);
987 xfree(result);
991 return rc;
994 #ifdef WITH_LIBACL
995 static void cleanup_acl(void *arg)
997 acl_t acl = *(acl_t *)arg;
999 if (acl)
1000 acl_free(acl);
1002 #endif
1004 static gpg_error_t write_file(struct crypto_s *crypto, const char *filename,
1005 void * data, size_t data_len, void * sexp, size_t sexp_len,
1006 gcry_sexp_t pubkey, gcry_sexp_t sigpkey)
1008 char tmp[FILENAME_MAX] = { 0 };
1009 mode_t mode = 0;
1010 struct stat st;
1011 int fd;
1012 gpg_error_t rc = 0;
1013 size_t len;
1014 #ifdef WITH_LIBACL
1015 acl_t acl = NULL;
1016 #endif
1018 if (filename) {
1019 if (lstat(filename, &st) == 0) {
1020 mode = st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
1022 if (!(mode & S_IWUSR))
1023 return GPG_ERR_EACCES;
1025 else if (errno != ENOENT)
1026 return gpg_error_from_syserror();
1028 snprintf(tmp, sizeof(tmp), "%s.XXXXXX", filename);
1029 fd = mkstemp(tmp);
1030 if (fd == -1) {
1031 rc = gpg_error_from_syserror();
1032 log_write("%s: %s", tmp, pwmd_strerror(rc));
1033 return rc;
1036 else {
1037 // xml_import() or convert_file() from command line.
1038 fd = STDOUT_FILENO;
1041 pthread_cleanup_push(cleanup_unlink_cb, tmp);
1042 crypto->save.hdr.version = VERSION_HEX;
1043 len = write(fd, &crypto->save.hdr, sizeof(file_header_t));
1044 if (len == sizeof(file_header_t)) {
1045 unsigned char grip[20];
1047 gcry_pk_get_keygrip(pubkey, grip);
1048 len = write(fd, grip, sizeof(grip));
1049 if (len == sizeof(grip)) {
1050 gcry_pk_get_keygrip(sigpkey, grip);
1051 len = write(fd, grip, sizeof(grip));
1052 if (len == sizeof(grip)) {
1053 len = write(fd, data, data_len);
1054 if (len == data_len) {
1055 len = write(fd, sexp, sexp_len);
1056 if (len != sexp_len)
1057 rc = gpg_error_from_syserror();
1059 else
1060 rc = gpg_error_from_syserror();
1063 else
1064 rc = gpg_error_from_syserror();
1066 else
1067 rc = gpg_error_from_syserror();
1069 #ifdef WITH_LIBACL
1070 pthread_cleanup_push(cleanup_acl, &acl);
1071 #endif
1072 if (!rc) {
1073 if (fsync(fd) != -1) {
1074 if (filename && close(fd) != -1) {
1075 #ifdef WITH_LIBACL
1076 acl = acl_get_file(filename, ACL_TYPE_ACCESS);
1077 if (!acl && errno == ENOENT)
1078 acl = acl_get_file(".", ACL_TYPE_DEFAULT);
1079 if (!acl)
1080 log_write("ACL: %s: %s", filename,
1081 pwmd_strerror(gpg_error_from_syserror()));
1082 #endif
1084 if (mode && config_get_boolean(filename, "backup")) {
1085 char tmp2[FILENAME_MAX];
1087 snprintf(tmp2, sizeof(tmp2), "%s.backup", filename);
1088 if (rename(filename, tmp2) == -1)
1089 rc = gpg_error_from_syserror();
1092 else if (filename)
1093 rc = gpg_error_from_syserror();
1095 else
1096 rc = gpg_error_from_syserror();
1099 if (!rc) {
1100 if (filename && rename(tmp, filename) != -1) {
1101 tmp[0] = 0;
1102 if (filename && mode)
1103 chmod(filename, mode);
1105 #ifdef WITH_LIBACL
1106 if (acl && acl_set_file(filename, ACL_TYPE_ACCESS, acl))
1107 log_write("ACL: %s: %s", filename,
1108 pwmd_strerror(gpg_error_from_syserror()));
1109 #endif
1111 else
1112 rc = gpg_error_from_syserror();
1115 #ifdef WITH_LIBACL
1116 pthread_cleanup_pop(1);
1117 #endif
1118 pthread_cleanup_pop(rc ? 1 : 0); // unlink
1119 return rc;
1122 gpg_error_t encrypt_data_file(assuan_context_t ctx, struct crypto_s *crypto,
1123 gcry_sexp_t pubkey, gcry_sexp_t sigpkey, const char *filename, const
1124 void * xml, size_t len)
1126 gpg_error_t rc;
1127 void * data = NULL;
1128 size_t data_len = 0;
1129 void * enc_xml = NULL;
1130 size_t enc_xml_len = 0;
1131 unsigned char *iv = NULL;
1132 size_t iv_len = 0;
1133 int algo = cipher_to_gcrypt(crypto->save.hdr.flags);
1134 void * key = NULL;
1135 size_t keysize;
1136 unsigned char sig_grip[20];
1137 unsigned char grip[20];
1139 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
1140 if (rc)
1141 return rc;
1143 pthread_cleanup_push(gcry_free, key);
1144 key = gcry_random_bytes_secure(keysize, GCRY_STRONG_RANDOM);
1145 #ifdef HAVE_PTHREAD_TESTCANCEL
1146 pthread_testcancel(); // may have been a long operation
1147 #endif
1148 pthread_cleanup_pop(0);
1149 if (!key)
1150 return GPG_ERR_ENOMEM;
1152 gcry_pk_get_keygrip(pubkey, grip);
1153 gcry_pk_get_keygrip(sigpkey, sig_grip);
1154 pthread_cleanup_push(xfree, iv);
1155 pthread_cleanup_push(gcry_free, key);
1156 rc = encrypt_xml(ctx, key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
1157 &iv, &iv_len, crypto->save.hdr.iterations);
1158 if (!rc) {
1159 gcry_sexp_t sig_sexp = NULL;
1160 char *hexgrip = bin2hex(grip, 20);
1162 log_write1(_("Encrypted with keygrip %s"), hexgrip);
1163 xfree(hexgrip);
1164 hexgrip = bin2hex(sig_grip, 20);
1165 pthread_cleanup_push(gcry_free, enc_xml);
1166 rc = sign(&sig_sexp, hexgrip, crypto, enc_xml, enc_xml_len);
1167 xfree(hexgrip);
1169 if (!rc) {
1170 rc = verify(sigpkey, sig_sexp, enc_xml, enc_xml_len);
1172 if (!rc) {
1173 gcry_sexp_t tmp_sexp;
1175 rc = gcry_sexp_build(&tmp_sexp, NULL,
1176 "(data (flags pkcs1) (value %b))", keysize, key);
1177 if (!rc) {
1178 gcry_sexp_t key_sexp;
1180 pthread_cleanup_push((void (*)(void*))gcry_sexp_release,
1181 (void *)sig_sexp);
1182 rc = gcry_pk_encrypt(&key_sexp, tmp_sexp, pubkey);
1183 pthread_cleanup_pop(0);
1184 gcry_sexp_release(tmp_sexp);
1186 if (!rc) {
1187 memcpy(crypto->save.hdr.iv, iv, iv_len);
1188 crypto->save.hdr.datalen = enc_xml_len;
1189 rc = gcry_sexp_build(&tmp_sexp, NULL, "%S%S", key_sexp,
1190 sig_sexp);
1191 gcry_sexp_release(key_sexp);
1193 if (!rc) {
1194 data_len = gcry_sexp_sprint(tmp_sexp,
1195 GCRYSEXP_FMT_CANON, NULL, 0);
1196 data = xmalloc(data_len);
1197 if (data)
1198 gcry_sexp_sprint(tmp_sexp, GCRYSEXP_FMT_CANON,
1199 data, data_len);
1200 else
1201 rc = GPG_ERR_ENOMEM;
1203 gcry_sexp_release(tmp_sexp);
1210 pthread_cleanup_pop(0); // enc_xml
1212 if (sig_sexp)
1213 gcry_sexp_release(sig_sexp);
1216 pthread_cleanup_pop(1); // key
1217 pthread_cleanup_pop(1); // iv
1219 if (!rc) {
1220 pthread_cleanup_push(gcry_free, enc_xml);
1221 rc = write_file(crypto, filename, enc_xml, enc_xml_len, data, data_len,
1222 pubkey, sigpkey);
1223 pthread_cleanup_pop(1); // enc_xml
1224 if (!rc)
1225 memcpy(&crypto->hdr, &crypto->save.hdr, sizeof(file_header_t));
1228 xfree(data);
1229 return rc;
1232 void cleanup_save(struct save_s *save)
1234 if (!save)
1235 return;
1237 if (save->pkey)
1238 gcry_sexp_release(save->pkey);
1240 if (save->sigpkey)
1241 gcry_sexp_release(save->sigpkey);
1243 memset(save, 0, sizeof(struct save_s));
1246 /* Keep the agent ctx to retain pinentry options which will be freed in
1247 * cleanup_cb(). Also keep .pubkey since it may be needed for a SAVE. */
1248 void cleanup_crypto_stage1(struct crypto_s *cr)
1250 if (!cr)
1251 return;
1253 cleanup_save(&cr->save);
1255 if (cr->ciphertext_sexp)
1256 gcry_sexp_release(cr->ciphertext_sexp);
1258 if (cr->plaintext)
1259 gcry_free(cr->plaintext);
1261 xfree(cr->ciphertext);
1262 xfree(cr->filename);
1263 cr->filename = NULL;
1264 cr->ciphertext_sexp = NULL;
1265 cr->ciphertext = NULL;
1266 cr->ciphertext_len = 0;
1267 cr->plaintext = NULL;
1268 cr->plaintext_len = 0;
1271 void cleanup_crypto_stage2(struct crypto_s *cr)
1273 if (!cr)
1274 return;
1276 cleanup_crypto_stage1(cr);
1277 set_header_defaults(&cr->hdr);
1280 void cleanup_crypto(struct crypto_s **c)
1282 struct crypto_s *cr = *c;
1284 if (!cr)
1285 return;
1287 cleanup_crypto_stage2(cr);
1289 if (cr->pkey_sexp)
1290 gcry_sexp_release(cr->pkey_sexp);
1292 if (cr->sigpkey_sexp)
1293 gcry_sexp_release(cr->sigpkey_sexp);
1295 if (cr->agent)
1296 cleanup_agent(cr->agent);
1298 xfree(cr);
1299 *c = NULL;
1302 gpg_error_t init_client_crypto(struct crypto_s **crypto)
1304 struct crypto_s *new = xcalloc(1, sizeof(struct crypto_s));
1305 gpg_error_t rc;
1307 if (!new) {
1308 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
1309 return GPG_ERR_ENOMEM;
1312 rc = agent_init(&new->agent);
1313 if (!rc) {
1314 rc = send_agent_common_options(new->agent);
1315 if (!rc)
1316 rc = set_pinentry_options(new->agent);
1319 if (rc) {
1320 xfree(new);
1321 return rc;
1324 set_header_defaults(&new->hdr);
1325 *crypto = new;
1326 return 0;
1329 gpg_error_t generate_key(struct crypto_s *crypto, char *sexpstr,
1330 int empty, int preset)
1332 gpg_error_t rc;
1333 char *pkey;
1334 size_t plen;
1336 if (crypto->save.s2k_count) {
1337 rc = send_to_agent(crypto->agent, NULL, NULL,
1338 "OPTION s2k-count=%lu", crypto->save.s2k_count);
1339 if (rc)
1340 return rc;
1343 if (!crypto->agent->inquire_cb)
1344 crypto->agent->inquire_cb = inquire_cb;
1346 rc = send_to_agent(crypto->agent, &pkey, &plen, "GENKEY %s%s",
1347 preset ? "--preset " : "",
1348 empty ? "--no-protection" : "");
1349 if (rc)
1350 return rc;
1352 if (crypto->save.pkey)
1353 gcry_sexp_release(crypto->save.pkey);
1355 crypto->save.pkey = NULL;
1356 rc = gcry_sexp_new(&crypto->save.pkey, pkey, plen, 1);
1357 if (!rc) {
1358 unsigned char grip[20];
1360 gcry_pk_get_keygrip(crypto->save.pkey, grip);
1361 char *hexgrip = bin2hex(grip, sizeof(grip));
1362 log_write1(_("Keygrip is %s"), hexgrip);
1363 xfree(hexgrip);
1365 if (!crypto->save.sigpkey) {
1366 gcry_sexp_build((gcry_sexp_t *)&crypto->save.sigpkey, NULL, "%S",
1367 crypto->save.pkey);
1371 xfree(pkey);
1372 return rc;
1375 gpg_error_t set_agent_option(struct agent_s *agent, const char *name,
1376 const char *value)
1378 return send_to_agent(agent, NULL, NULL, "OPTION %s=%s", name, value);
1381 gpg_error_t set_agent_passphrase(struct crypto_s *crypto, const char *key,
1382 size_t len)
1384 char *hexgrip;
1385 struct inquire_data_s idata;
1386 gpg_error_t rc;
1387 int i;
1389 /* This is for use with key files or passphrases obtained from an inquire.
1390 * gpg-agent uses strings as passphrases and will truncate the passphrase
1391 * at the first encountered null byte. It's only a warning because the
1392 * passphrase may belong to a key shared outside of pwmd. */
1393 for (i = 0; i < len; i++) {
1394 if (key[i] == 0) {
1395 log_write(_("WARNING: keylen=%i, truncated to %i."), len, i);
1396 break;
1400 hexgrip = bin2hex(crypto->grip, 20);
1401 crypto->agent->inquire_cb = inquire_cb;
1402 crypto->agent->inquire_data = &idata;
1403 idata.crypto = crypto;
1404 idata.line = (char *)key,
1405 idata.len = len;
1406 idata.preset = 1;
1407 assuan_begin_confidential(crypto->agent->ctx);
1408 rc = send_to_agent(crypto->agent, NULL, NULL,
1409 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
1410 assuan_end_confidential(crypto->agent->ctx);
1411 idata.preset = 0;
1412 xfree(hexgrip);
1413 return rc;
1416 gpg_error_t set_pinentry_mode(struct agent_s *agent, const char *mode)
1418 return set_agent_option(agent, "pinentry-mode", mode);
1421 gpg_error_t get_pubkey_bin(struct crypto_s *crypto, const unsigned char *grip,
1422 gcry_sexp_t *result)
1424 char *hexgrip = bin2hex(grip, 20);
1425 gpg_error_t rc;
1427 if (!hexgrip)
1428 return GPG_ERR_ENOMEM;
1430 rc = get_pubkey(crypto, hexgrip, result);
1431 xfree(hexgrip);
1432 return rc;
1435 gpg_error_t get_pubkey(struct crypto_s *crypto, const char *grip,
1436 gcry_sexp_t *result)
1438 char *pkey = NULL;
1439 size_t plen;
1440 gpg_error_t rc;
1442 rc = send_to_agent(crypto->agent, &pkey, &plen, "READKEY %s", grip);
1443 if (!rc)
1444 rc = gcry_sexp_new(result, pkey, plen, 1);
1446 xfree(pkey);
1447 return rc;
1450 gpg_error_t set_pinentry_options(struct agent_s *agent)
1452 gpg_error_t rc = 0;
1454 if (getenv("DISPLAY")) {
1455 rc = set_agent_option(agent, "display", getenv("DISPLAY"));
1456 if (!rc) {
1457 xfree(agent->display);
1458 agent->display = str_dup(getenv("DISPLAY"));
1461 else if (ttyname(STDOUT_FILENO)) {
1462 rc = set_agent_option(agent, "ttyname", ttyname(STDOUT_FILENO));
1463 if (!rc) {
1464 rc = set_agent_option(agent, "ttytype", getenv("TERM"));
1465 if (!rc) {
1466 xfree(agent->ttyname);
1467 xfree(agent->ttytype);
1468 agent->ttyname = str_dup(ttyname(STDOUT_FILENO));
1469 agent->ttytype = str_dup(getenv("TERM"));
1474 return rc;
1477 static gpg_error_t inquire_keyfile(void * user, const char *keyword)
1479 struct crypto_s *crypto = user;
1480 char *filename = crypto->agent->inquire_data2;
1481 char *params = crypto->agent->inquire_data3;
1482 int fd;
1483 struct stat st;
1484 unsigned char *buf;
1485 size_t len;
1486 gpg_error_t rc;
1488 if (!strcmp(keyword, "KEYPARAM"))
1489 return assuan_send_data(crypto->agent->ctx, params, strlen(params));
1491 // This function is only used when generating a new keypair.
1492 if (strcmp(keyword, "NEW_PASSPHRASE"))
1493 return gpg_error(GPG_ERR_ASS_UNKNOWN_INQUIRE);
1495 if (stat(filename, &st) == -1)
1496 return gpg_error_from_syserror();
1498 if (crypto->agent->inquire_maxlen
1499 && st.st_size > crypto->agent->inquire_maxlen) {
1500 log_write(_("The passphrase is too large: have=%u, max=%u."),
1501 (unsigned)st.st_size, crypto->agent->inquire_maxlen);
1502 return GPG_ERR_TOO_LARGE;
1505 buf = gcry_malloc_secure(st.st_size);
1506 if (!buf)
1507 return GPG_ERR_ENOMEM;
1509 fd = open(filename, O_RDONLY);
1510 if (fd == -1)
1511 rc = gpg_error_from_syserror();
1512 else {
1513 len = read(fd, buf, st.st_size);
1514 if (len == st.st_size) {
1515 assuan_begin_confidential(crypto->agent->ctx);
1516 rc = assuan_send_data(crypto->agent->ctx, buf, len);
1517 assuan_end_confidential(crypto->agent->ctx);
1519 else if (len == -1)
1520 rc = gpg_error_from_syserror();
1521 else
1522 rc = GPG_ERR_BUFFER_TOO_SHORT;
1525 close(fd);
1526 gcry_free(buf);
1527 return rc;
1530 gpg_error_t export_common(struct crypto_s *crypto, const char *hexgrip,
1531 const char *sign_hexgrip, int no_passphrase,
1532 const void * data, size_t datalen, const char *outfile,
1533 const char *keyparams, const char *keyfile)
1535 gpg_error_t rc = 0;
1537 if (!sign_hexgrip && hexgrip)
1538 sign_hexgrip = hexgrip;
1540 if (sign_hexgrip) {
1541 if (crypto->sigpkey_sexp)
1542 gcry_sexp_release(crypto->sigpkey_sexp);
1544 crypto->sigpkey_sexp = NULL;
1545 rc = get_pubkey(crypto, sign_hexgrip, &crypto->save.sigpkey);
1546 if (rc)
1547 return rc;
1549 gcry_pk_get_keygrip(crypto->save.sigpkey, crypto->sign_grip);
1552 if (hexgrip) {
1553 rc = get_pubkey(crypto, hexgrip, &crypto->save.pkey);
1554 if (!rc)
1555 gcry_pk_get_keygrip(crypto->save.pkey, crypto->grip);
1557 else {
1558 struct inquire_data_s idata = {0};
1559 char *params = keyparams ? str_dup(keyparams)
1560 : default_key_params(crypto);
1562 pthread_cleanup_push(xfree, params);
1563 log_write(_("Generating a new keypair ..."));
1564 if (keyfile) {
1565 log_write(_("Using passphrase obtained from file '%s'"), keyfile);
1566 rc = set_pinentry_mode(crypto->agent, "loopback");
1567 crypto->agent->inquire_cb = inquire_keyfile;
1568 crypto->agent->inquire_data = crypto;
1569 crypto->agent->inquire_data2 = (char *)keyfile;
1570 crypto->agent->inquire_data3 = params;
1572 else {
1573 idata.line = params;
1574 idata.len = strlen(params);
1575 idata.crypto = crypto;
1576 crypto->agent->inquire_cb = inquire_cb;
1577 crypto->agent->inquire_data = &idata;
1580 if (!rc) {
1581 rc = generate_key(crypto, params, no_passphrase, 1);
1582 gcry_pk_get_keygrip(crypto->save.pkey, crypto->grip);
1585 (void)set_pinentry_mode(crypto->agent, "ask");
1586 pthread_cleanup_pop(1);
1589 if (!rc) {
1590 rc = encrypt_data_file(NULL, crypto, crypto->save.pkey,
1591 crypto->save.sigpkey, outfile, data, datalen);
1592 if (!rc) {
1593 char *tmp = bin2hex(crypto->grip, sizeof(crypto->grip));
1595 log_write(_("Success! Keygrip is %s."), tmp);
1596 rc = send_to_agent(crypto->agent, NULL, NULL,
1597 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1598 xfree(tmp);
1600 if (sign_hexgrip) {
1601 tmp = bin2hex(crypto->sign_grip, sizeof(crypto->sign_grip));
1602 log_write(_("Signed with keygrip %s."), tmp);
1603 xfree(tmp);
1608 return rc;
1611 char *default_key_params(struct crypto_s *crypto)
1613 int len = config_get_integer(NULL, "nbits");
1614 char buf[32];
1615 char *algo = config_get_string(NULL, "algo");
1616 char *result;
1618 snprintf(buf, sizeof(buf), "%i", len);
1619 result = str_asprintf("(genkey (%s (nbits %lu:%i)))", algo, strlen(buf),
1620 len);
1621 xfree(algo);
1622 return result;
1625 gpg_error_t agent_passwd(struct crypto_s *crypto)
1627 struct inquire_data_s idata = {0};
1628 gpg_error_t rc;
1629 char *tmp = bin2hex(crypto->grip, 20);
1631 idata.crypto = crypto;
1632 crypto->agent->inquire_cb = inquire_cb;
1633 crypto->agent->inquire_data = &idata;
1634 rc = send_to_agent(crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1635 xfree(tmp);
1636 return rc;
1639 gpg_error_t kill_scd(struct agent_s *agent)
1641 gpg_error_t rc = 0;
1643 if (config_get_boolean(NULL, "kill_scd")) {
1644 rc = send_to_agent(agent, NULL, NULL, "SCD KILLSCD");
1645 if (rc && gpg_err_code(rc) != GPG_ERR_NO_SCDAEMON)
1646 log_write("%s: %s", __FUNCTION__, pwmd_strerror(rc));
1649 return rc;