Use the user-defined hexgrip when signing.
[pwmd.git] / src / agent.c
bloba3002876603d69d88e5762d35e4041cf0ce0bcd2
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 Ben Kibbey <bjk@luxsci.net>
6 This file is part of pwmd.
8 Pwmd is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 Pwmd is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <stdlib.h>
26 #include <glib.h>
27 #include <glib/gprintf.h>
28 #include <glib/gstdio.h>
29 #include <errno.h>
30 #include <pwd.h>
31 #include <signal.h>
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 #include <fcntl.h>
35 #include <dirent.h>
36 #include "pwmd-error.h"
37 #include "mem.h"
38 #include "common.h"
39 #include "commands.h"
40 #include "agent.h"
41 #include "misc.h"
42 #include "mutex.h"
43 #include "rcfile.h"
44 #include "cache.h"
45 #include "cipher.h"
47 #ifdef WITH_LIBACL
48 #include <acl/libacl.h>
49 #endif
51 #ifdef __FreeBSD__
52 #include <sys/types.h>
53 #include <signal.h>
54 #endif
56 static guint8 pwmd_magic[5] = { '\177', 'P', 'W', 'M', 'D' };
58 static gpg_error_t mem_realloc_cb(void *data, const void *buffer, size_t len)
60 membuf_t *mem = (membuf_t *)data;
61 void *p;
63 if (!buffer)
64 return 0;
66 if ((p = xrealloc(mem->buf, mem->len + len)) == NULL)
67 return 1;
69 mem->buf = p;
70 memcpy((char *)mem->buf + mem->len, buffer, len);
71 mem->len += len;
72 return 0;
75 static gpg_error_t status_cb(gpointer data, const gchar *line)
77 struct agent_s *agent = data;
79 agent->inquire_maxlen = 0;
81 if (!strncmp(line, "INQUIRE_MAXLEN ", 15)) {
82 agent->inquire_maxlen = atoi(line+15);
83 if (!agent->client_ctx)
84 return 0;
87 return send_status(agent->client_ctx, STATUS_AGENT, "%s", line);
90 static gpg_error_t assuan_command(struct agent_s *a, gchar **result,
91 gsize *len, const gchar *cmd)
93 gpg_error_t rc;
95 a->data.len = 0;
96 a->data.buf = NULL;
97 if (result)
98 *result = NULL;
99 if (len)
100 *len = 0;
101 rc = assuan_transact(a->ctx, cmd, mem_realloc_cb, &a->data,
102 a->inquire_cb, a->inquire_data, status_cb, a);
104 if (rc)
105 xfree(a->data.buf);
106 else {
107 if (a->data.buf) {
108 mem_realloc_cb(&a->data, "", 1);
109 if (result)
110 *result = (gchar *)a->data.buf;
111 else
112 xfree(a->data.buf);
114 if (len)
115 *len = a->data.len;
119 return rc;
122 /* This commands are sent from launch_agent() after reconnecting to the agent
123 * and also from the initial client connection. */
124 static gpg_error_t 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 launch_agent(struct agent_s *agent)
134 gpg_error_t rc;
135 assuan_context_t ctx;
136 const gchar *t = NULL;
137 static struct assuan_malloc_hooks mhooks = { xmalloc, xrealloc, xfree };
138 gchar *s, buf[LINE_MAX];
139 FILE *fp;
141 s = get_key_file_string("global", "agent_env_file");
142 if (s) {
143 gchar *ss = expand_homedir(s);
145 g_free(s);
146 fp = fopen(ss, "r");
147 g_free(ss);
149 if (fp) {
150 while ((s = fgets(buf, sizeof(buf), fp))) {
151 s = g_strchomp(s);
152 if (g_str_has_prefix(s, "GPG_AGENT_INFO=")) {
153 g_setenv("GPG_AGENT_INFO", s+strlen("GPG_AGENT_INFO="), TRUE);
154 break;
158 fclose(fp);
160 else
161 log_write("%s: %s", s, pwmd_strerror(gpg_error_from_syserror()));
164 t = g_getenv("GPG_AGENT_INFO");
165 if (!t)
166 return gpg_err_code(GPG_ERR_NO_AGENT);
168 rc = assuan_new_ext(&ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
169 debug_level ? assuan_log_cb : NULL, "AGENT ");
170 if (rc)
171 return rc;
173 gchar **fields = g_strsplit(t, ":", 0);
174 rc = assuan_socket_connect(ctx, fields[0], ASSUAN_INVALID_PID, 0);
175 g_strfreev(fields);
176 if (rc) {
177 assuan_release(ctx);
178 return rc;
181 if (agent->ctx) {
182 /* Restore the previous agent settings for this new context. */
183 assuan_release(agent->ctx);
184 agent->ctx = ctx;
185 rc = send_agent_common_options(agent);
186 if (!rc && agent->display)
187 rc = set_agent_option(agent, "display", agent->display);
189 if (!rc && agent->ttyname)
190 rc = set_agent_option(agent, "ttyname", agent->ttyname);
192 if (!rc && agent->ttytype)
193 rc = set_agent_option(agent, "ttytype", agent->ttytype);
195 if (!rc && agent->lc_messages)
196 rc = set_agent_option(agent, "lc-messages", agent->lc_messages);
198 if (!rc && agent->lc_ctype)
199 rc = set_agent_option(agent, "lc-ctype", agent->lc_ctype);
202 agent->ctx = ctx;
203 return 0;
206 gpg_error_t send_to_agent(struct agent_s *agent, gchar **result, gsize *len,
207 const gchar *fmt, ...)
209 gpg_error_t rc = 0;
210 va_list ap;
211 gchar *cmd;
213 if (!agent->ctx) {
214 rc = launch_agent(agent);
215 if (rc)
216 return rc;
219 va_start(ap, fmt);
220 if (g_vasprintf(&cmd, fmt, ap) > 0) {
221 rc = assuan_command(agent, result, len, cmd);
222 if (!agent->restart && gpg_err_source(rc) == GPG_ERR_SOURCE_DEFAULT
223 && (gpg_err_code(rc) == GPG_ERR_ASS_CONNECT_FAILED
224 || gpg_err_code(rc) == GPG_ERR_EPIPE)) {
225 g_unsetenv("GPG_AGENT_INFO");
226 agent->restart = TRUE;
227 rc = launch_agent(agent);
228 if (!rc)
229 rc = assuan_command(agent, result, len, cmd);
232 agent->restart = FALSE;
233 g_free(cmd);
235 else
236 rc = GPG_ERR_ENOMEM;
238 va_end(ap);
239 return rc;
242 static void agent_disconnect(struct agent_s *agent)
244 if (!agent)
245 return;
247 if (agent->ctx)
248 assuan_release(agent->ctx);
250 agent->ctx = NULL;
253 void cleanup_agent(struct agent_s *agent)
255 if (!agent)
256 return;
258 g_free(agent->desc);
259 g_free(agent->display);
260 g_free(agent->ttyname);
261 g_free(agent->ttytype);
262 g_free(agent->lc_messages);
263 g_free(agent->lc_ctype);
265 if (agent->ctx)
266 agent_disconnect(agent);
268 g_free(agent);
271 gpg_error_t agent_init(struct agent_s **agent)
273 struct agent_s *new = g_malloc0(sizeof(struct agent_s));
275 if (!new)
276 return GPG_ERR_ENOMEM;
278 *agent = new;
279 return 0;
282 void set_header_defaults(file_header_t *hdr)
284 gchar *s = get_key_file_string(NULL, "cipher");
285 gint flags = cipher_string_to_cipher(s);
287 g_free(s);
288 memset(hdr, 0, sizeof(file_header_t));
289 memcpy(hdr->magic, pwmd_magic, sizeof(hdr->magic));
290 if (flags == -1)
291 log_write(_("Invalid 'cipher' in configuration file. Using a default of aes256."));
292 hdr->flags = flags == -1 ? PWMD_CIPHER_AES256 : flags;
293 hdr->version = VERSION_HEX;
296 gpg_error_t read_data_header(const gchar *filename, file_header_t *rhdr,
297 struct stat *rst, gint *rfd)
299 gpg_error_t rc = 0;
300 gsize len;
301 struct stat st;
302 file_header_t hdr;
303 gint fd;
305 if (g_lstat(filename, &st) == -1)
306 return gpg_error_from_syserror();
308 if (!S_ISREG(st.st_mode))
309 return GPG_ERR_ENOANO;
311 fd = open(filename, O_RDONLY);
312 if (fd == -1)
313 return gpg_error_from_syserror();
315 len = read(fd, &hdr, sizeof(file_header_t));
316 if (len != sizeof(file_header_t))
317 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
319 if (!rc && memcmp(hdr.magic, pwmd_magic, sizeof(hdr.magic)))
320 rc = GPG_ERR_BAD_DATA;
321 else if (hdr.version < 0x030000)
322 rc = GPG_ERR_UNKNOWN_VERSION;
324 if (rc)
325 close(fd);
326 else {
327 if (rhdr)
328 *rhdr = hdr;
329 if (rst)
330 *rst = st;
331 if (rfd)
332 *rfd = fd;
333 else
334 close(fd);
337 return rc;
340 gpg_error_t read_data_file(const gchar *filename, struct crypto_s *crypto)
342 gint fd;
343 gpg_error_t rc = 0;
344 gsize len, rlen;
345 gchar *buf = NULL;
347 cleanup_crypto_stage1(crypto);
348 rc = read_data_header(filename, &crypto->hdr, &crypto->st, &fd);
349 if (rc)
350 return rc;
352 crypto->ciphertext_len = crypto->hdr.datalen;
353 crypto->ciphertext = g_malloc(crypto->hdr.datalen);
354 if (!crypto->ciphertext) {
355 rc = GPG_ERR_ENOMEM;
356 goto fail;
359 len = read(fd, crypto->ciphertext, crypto->hdr.datalen);
360 if (len != crypto->hdr.datalen) {
361 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
362 goto fail;
365 rlen = read(fd, crypto->grip, 20);
366 if (rlen != 20) {
367 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
368 goto fail;
371 rlen = read(fd, crypto->sign_grip, 20);
372 if (rlen != 20) {
373 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
374 goto fail;
377 len = crypto->st.st_size-sizeof(file_header_t)-crypto->hdr.datalen-40;
378 buf = g_malloc(len);
379 if (!buf) {
380 rc = GPG_ERR_ENOMEM;
381 goto fail;
384 rlen = read(fd, buf, len);
385 if (rlen != len) {
386 rc = rc == -1 ? gpg_error_from_syserror() : GPG_ERR_BAD_DATA;
387 goto fail;
390 rc = gcry_sexp_new(&crypto->ciphertext_sexp, buf, rlen, 1);
391 if (rc)
392 goto fail;
394 if (crypto->pkey_sexp)
395 gcry_sexp_release(crypto->pkey_sexp);
397 if (crypto->sigpkey_sexp)
398 gcry_sexp_release(crypto->sigpkey_sexp);
400 crypto->pkey_sexp = crypto->sigpkey_sexp = NULL;
401 rc = get_pubkey_bin(crypto, crypto->grip, &crypto->pkey_sexp);
402 if (!rc)
403 rc = get_pubkey_bin(crypto, crypto->sign_grip, &crypto->sigpkey_sexp);
405 fail:
406 close(fd);
407 g_free(buf);
408 return rc;
411 static gpg_error_t inquire_cb(gpointer user, const char *keyword)
413 struct inquire_data_s *idata = user;
415 if (!idata->preset && (!g_strcmp0(keyword, "PASSPHRASE")
416 || !g_strcmp0(keyword, "NEW_PASSPHRASE"))) {
417 return agent_loopback_cb(idata->crypto, keyword);
419 // SAVE --inquire-keyparam
420 else if (idata->preset && !g_strcmp0(keyword, "KEYPARAM")) {
421 idata->preset = FALSE;
422 return agent_loopback_cb(idata->crypto, keyword);
425 if (idata->crypto->agent->inquire_maxlen
426 && idata->len > idata->crypto->agent->inquire_maxlen) {
427 log_write(_("Inquired data too large: have=%u, max=%u"), idata->len,
428 idata->crypto->agent->inquire_maxlen);
429 return GPG_ERR_TOO_LARGE;
432 idata->crypto->agent->inquire_maxlen = 0;
433 return assuan_send_data(idata->crypto->agent->ctx, idata->line, idata->len);
436 static gpg_error_t extract_key(struct crypto_s *crypto, guchar **result,
437 gsize *result_len)
439 gpg_error_t rc;
440 gcry_sexp_t enc_sexp = NULL, tmp_sexp;
441 struct inquire_data_s idata = {0};
442 gchar *hexgrip = NULL;
443 gchar *key;
444 gsize keylen, keysize;
445 gchar *tmp;
446 gint algo = cipher_to_gcrypt(crypto->hdr.flags);
447 gboolean shadowed;
449 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
450 if (rc)
451 return rc;
453 tmp_sexp = gcry_sexp_find_token(crypto->ciphertext_sexp, "enc-val", 0);
454 if (!tmp_sexp)
455 return GPG_ERR_BAD_DATA;
457 hexgrip = bin2hex(crypto->grip, sizeof(crypto->grip));
458 if (!hexgrip) {
459 rc = GPG_ERR_ENOMEM;
460 goto fail;
463 rc = cache_is_shadowed(hexgrip);
464 if (rc && rc != GPG_ERR_NO_DATA)
465 goto fail;
467 shadowed = !rc ? TRUE : FALSE;
468 if (!shadowed) {
469 gcry_sexp_t tmp2_sexp = gcry_sexp_cdr(tmp_sexp);
470 gcry_sexp_release(tmp_sexp);
471 tmp_sexp = gcry_sexp_nth(tmp2_sexp, 0);
472 gcry_sexp_release(tmp2_sexp);
473 rc = gcry_sexp_build(&enc_sexp, NULL, "(enc-val (flags pkcs1) %S)",
474 tmp_sexp);
476 else
477 rc = gcry_sexp_build(&enc_sexp, NULL, "%S", tmp_sexp);
479 gcry_sexp_release(tmp_sexp);
480 if (rc)
481 return rc;
483 crypto->agent->inquire_cb = inquire_cb;
484 idata.crypto = crypto;
485 idata.len = gcry_sexp_sprint(enc_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
486 idata.line = g_malloc(idata.len);
487 if (!idata.line) {
488 rc = GPG_ERR_ENOMEM;
489 goto fail;
492 idata.len = gcry_sexp_sprint(enc_sexp, GCRYSEXP_FMT_CANON, idata.line,
493 idata.len);
494 crypto->agent->inquire_data = &idata;
495 gcry_sexp_release(enc_sexp);
496 enc_sexp = NULL;
497 log_write1(_("Keygrip is %s, bits=%i"), hexgrip,
498 gcry_pk_get_nbits(crypto->pkey_sexp));
499 rc = send_to_agent(crypto->agent, NULL, NULL, "SETKEY %s", hexgrip);
500 if (rc)
501 goto fail;
503 if (!crypto->agent->desc) {
504 tmp = plus_escape(_(
505 "A %s is required to unlock the secret key for the "
506 "encrypted data file \"%s\". Please enter the %s "
507 "below."),
508 shadowed ? "PIN" : _("passphrase"), crypto->filename,
509 shadowed ? "PIN" : _("passphrase"));
511 else
512 tmp = plus_escape(crypto->agent->desc);
514 rc = send_to_agent(crypto->agent, NULL, NULL, "SETKEYDESC %s", tmp);
515 g_free(tmp);
516 if (rc)
517 goto fail;
519 assuan_begin_confidential(crypto->agent->ctx);
520 rc = send_to_agent(crypto->agent, &key, &keylen, "PKDECRYPT");
521 assuan_end_confidential(crypto->agent->ctx);
522 if (rc)
523 goto fail;
525 rc = gcry_sexp_new(&tmp_sexp, key, keylen, 1);
526 xfree(key);
527 if (rc)
528 goto fail;
530 key = (gchar *)gcry_sexp_nth_data(tmp_sexp, 1, result_len);
531 if (key) {
532 *result = gcry_malloc(*result_len);
533 if (!*result)
534 rc = GPG_ERR_ENOMEM;
535 else
536 memcpy(*result, key, *result_len);
538 else
539 rc = GPG_ERR_BAD_DATA;
541 gcry_sexp_release(tmp_sexp);
543 fail:
544 g_free(idata.line);
545 g_free(hexgrip);
547 if (enc_sexp)
548 gcry_sexp_release(enc_sexp);
550 return rc;
553 static gpg_error_t verify(gcry_sexp_t pkey, gcry_sexp_t sig_sexp,
554 const gpointer data, gsize len)
556 gpg_error_t rc;
557 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
558 guchar *hash;
559 gcry_sexp_t data_sexp;
561 hash = gcry_malloc(hashlen);
562 if (!hash)
563 return GPG_ERR_ENOMEM;
565 gcry_md_hash_buffer(GCRY_MD_SHA256, hash, data, len);
566 rc = gcry_sexp_build(&data_sexp, NULL,
567 "(data (flags pkcs1) (hash sha256 %b))", hashlen, hash);
568 gcry_free(hash);
569 if (!rc) {
570 rc = gcry_pk_verify(sig_sexp, data_sexp, pkey);
571 gcry_sexp_release(data_sexp);
574 return rc;
577 gpg_error_t decrypt_data(struct crypto_s *crypto)
579 gpg_error_t rc;
580 guchar *key = NULL;
581 gsize keylen = 0;
582 gcry_cipher_hd_t h = NULL;
583 gsize blocksize, keysize;
584 gint algo = cipher_to_gcrypt(crypto->hdr.flags);
585 gpointer outbuf = NULL;
586 gcry_sexp_t sig_sexp;
588 rc = extract_key(crypto, &key, &keylen);
589 if (rc)
590 return rc;
592 sig_sexp = gcry_sexp_find_token(crypto->ciphertext_sexp, "sig-val", 0);
593 if (!sig_sexp) {
594 rc = GPG_ERR_BAD_DATA;
595 goto fail;
598 rc = verify(crypto->sigpkey_sexp, sig_sexp, crypto->ciphertext, crypto->ciphertext_len);
599 gcry_sexp_release(sig_sexp);
600 if (rc)
601 goto fail;
603 rc = gcry_cipher_open(&h, algo, GCRY_CIPHER_MODE_CBC, 0);
604 if (rc)
605 goto fail;
607 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
608 if (rc)
609 goto fail;
610 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, NULL, &blocksize);
611 if (rc)
612 goto fail;
614 rc = gcry_cipher_setiv(h, crypto->hdr.iv, sizeof(crypto->hdr.iv));
615 if (rc)
616 goto fail;
618 rc = gcry_cipher_setkey(h, key, keylen);
619 if (rc)
620 goto fail;
622 outbuf = gcry_malloc(crypto->hdr.datalen);
623 if (!outbuf) {
624 rc = GPG_ERR_ENOMEM;
625 goto fail;
628 rc = gcry_cipher_decrypt(h, outbuf, crypto->hdr.datalen,
629 crypto->ciphertext, crypto->hdr.datalen);
630 if (rc)
631 gcry_free(outbuf);
632 else {
633 crypto->plaintext = outbuf;
634 crypto->plaintext_len = crypto->hdr.datalen;
637 fail:
638 gcry_free(key);
639 gcry_cipher_close(h);
640 return rc;
643 static gpg_error_t encrypt_xml(gpointer key, gsize keylen, gint algo,
644 const gpointer xml, gsize len, gpointer *result, gsize *result_len,
645 guchar **iv, gsize *iv_len)
647 gpg_error_t rc;
648 gcry_cipher_hd_t h;
649 gsize blocksize, keysize;
650 gpointer inbuf = NULL;
651 gsize olen = len;
653 rc = gcry_cipher_open(&h, algo, GCRY_CIPHER_MODE_CBC, 0);
654 if (rc)
655 return rc;
657 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
658 if (rc)
659 goto fail;
661 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, NULL, &blocksize);
662 if (rc)
663 goto fail;
665 *(iv) = g_malloc(blocksize);
666 if (!*(iv))
667 goto fail;
669 *iv_len = blocksize;
670 gcry_create_nonce(*(iv), blocksize);
671 rc = gcry_cipher_setiv(h, *(iv), blocksize);
672 if (rc)
673 goto fail;
675 rc = gcry_cipher_setkey(h, key, keylen);
676 if (rc)
677 goto fail;
679 if (len%blocksize)
680 len += blocksize-(len%blocksize);
682 inbuf = gcry_malloc(len);
683 if (!inbuf) {
684 rc = GPG_ERR_ENOMEM;
685 goto fail;
688 memset(inbuf, 0, len);
689 memcpy(inbuf, xml, olen);
690 rc = gcry_cipher_encrypt(h, inbuf, len, NULL, 0);
691 if (rc)
692 goto fail;
694 *result = inbuf;
695 *result_len = len;
696 gcry_cipher_close(h);
697 return 0;
699 fail:
700 if (*(iv))
701 g_free(iv);
703 if (inbuf)
704 gcry_free(inbuf);
706 gcry_cipher_close(h);
707 return rc;
710 gpg_error_t agent_loopback_cb(gpointer user, const gchar *keyword)
712 struct crypto_s *crypto = user;
713 gpg_error_t rc;
714 guchar *result;
715 gsize len;
716 gboolean keyparam = FALSE;
718 if (!g_strcmp0(keyword, "KEYPARAM")) {
719 keyparam = TRUE;
720 rc = assuan_inquire(crypto->client_ctx, keyword, &result, &len, 0);
722 else { // PASSPHRASE or NEW_PASSPHRASE
723 assuan_begin_confidential(crypto->client_ctx);
724 rc = assuan_inquire(crypto->client_ctx, keyword, &result, &len, 0);
725 assuan_end_confidential(crypto->client_ctx);
728 if (!rc) {
729 if (keyparam && !len) {
730 gchar *tmp = default_key_params(crypto);
732 if (!tmp)
733 return gpg_error(GPG_ERR_ENOMEM);
735 len = strlen(tmp);
736 result = xmalloc(len);
737 memcpy(result, tmp, len);
738 g_free(tmp);
741 pthread_cleanup_push(xfree, result);
743 if (keyparam)
744 rc = assuan_send_data(crypto->agent->ctx, result, len);
745 else {
746 assuan_begin_confidential(crypto->agent->ctx);
747 rc = assuan_send_data(crypto->agent->ctx, result, len);
748 assuan_end_confidential(crypto->agent->ctx);
751 pthread_cleanup_pop(1);
753 else if (gpg_err_code(rc) == GPG_ERR_ASS_CANCELED) {
754 gpg_error_t arc = assuan_write_line(crypto->agent->ctx, "CAN");
756 if (!arc) {
757 char *line;
758 size_t len;
760 arc = assuan_read_line(crypto->agent->ctx, &line, &len);
761 if (arc)
762 rc = arc;
764 else
765 rc = arc;
768 return rc;
771 static gpg_error_t sign(gcry_sexp_t *rsexp, const gchar *sign_hexgrip,
772 struct crypto_s *crypto, const gpointer data, gsize len)
774 gpg_error_t rc;
775 gchar *result;
776 gchar *tmp = sign_hexgrip ? g_strdup(sign_hexgrip)
777 : bin2hex(crypto->grip, sizeof(crypto->grip));
779 pthread_cleanup_push(g_free, tmp);
780 log_write1(_("Sign keygrip is %s"), tmp);
781 rc = send_to_agent(crypto->agent, NULL, NULL, "SIGKEY %s", tmp);
782 pthread_cleanup_pop(1);
783 if (!rc) {
784 guchar *hash;
785 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
787 hash = gcry_malloc(hashlen);
788 if (!hash)
789 return GPG_ERR_ENOMEM;
791 gcry_md_hash_buffer(GCRY_MD_SHA256, hash, data, len);
792 tmp = bin2hex(hash, hashlen);
793 gcry_free(hash);
794 pthread_cleanup_push(g_free, tmp);
795 rc = send_to_agent(crypto->agent, NULL, NULL,
796 "SETHASH --hash=sha256 %s", tmp);
797 pthread_cleanup_pop(1);
800 if (!rc) {
801 struct inquire_data_s idata = {0};
803 idata.crypto = crypto;
804 crypto->agent->inquire_data = &idata;
805 crypto->agent->inquire_cb = inquire_cb;
806 rc = send_to_agent(crypto->agent, &result, &len, "PKSIGN");
807 if (!rc) {
808 rc = gcry_sexp_sscan(rsexp, NULL, result, len);
809 xfree(result);
813 return rc;
816 static gpg_error_t write_file(struct crypto_s *crypto, const gchar *filename,
817 gpointer data, gsize data_len, gpointer sexp, gsize sexp_len)
819 gchar tmp[FILENAME_MAX] = { 0 };
820 mode_t mode = 0;
821 struct stat st;
822 gint fd;
823 gpg_error_t rc = 0;
824 gsize len;
825 #ifdef WITH_LIBACL
826 acl_t acl = NULL;
827 #endif
829 if (filename) {
830 if (g_lstat(filename, &st) == 0) {
831 mode = st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
833 if (!(mode & S_IWUSR))
834 return GPG_ERR_EACCES;
836 else if (errno != ENOENT)
837 return gpg_error_from_syserror();
839 g_snprintf(tmp, sizeof(tmp), "%s.XXXXXX", filename);
840 #if GLIB_CHECK_VERSION(2, 22, 0)
841 fd = g_mkstemp_full(tmp, O_WRONLY, 0600);
842 #else
843 fd = mkstemp(tmp);
844 #endif
845 if (fd == -1) {
846 rc = gpg_error_from_syserror();
847 log_write("%s: %s", tmp, pwmd_strerror(rc));
848 return rc;
851 else {
852 // xml_import() or convert_file() from command line.
853 fd = STDOUT_FILENO;
856 pthread_cleanup_push(cleanup_unlink_cb, tmp);
857 crypto->save.hdr.version = VERSION_HEX;
858 len = write(fd, &crypto->save.hdr, sizeof(file_header_t));
859 if (len == sizeof(file_header_t)) {
860 len = write(fd, data, data_len);
861 if (len == data_len) {
862 len = write(fd, sexp, sexp_len);
863 if (len != sexp_len)
864 rc = gpg_error_from_syserror();
866 else
867 rc = gpg_error_from_syserror();
869 else
870 rc = gpg_error_from_syserror();
872 #ifdef WITH_LIBACL
873 pthread_cleanup_push(acl_free, acl);
874 #endif
875 if (!rc) {
876 if (fsync(fd) != -1) {
877 if (filename && close(fd) != -1) {
878 if (mode && get_key_file_boolean(filename, "backup")) {
879 gchar tmp2[FILENAME_MAX];
881 g_snprintf(tmp2, sizeof(tmp2), "%s.backup", filename);
882 #ifdef WITH_LIBACL
883 acl = acl_get_file(filename, ACL_TYPE_ACCESS);
884 if (!acl)
885 log_write("ACL: %s: %s", filename,
886 pwmd_strerror(gpg_error_from_syserror()));
887 #endif
889 if (g_rename(filename, tmp2) == -1)
890 rc = gpg_error_from_syserror();
892 else if (filename) {
893 #ifdef WITH_LIBACL
894 acl = acl_get_file(".", ACL_TYPE_DEFAULT);
895 if (!acl)
896 log_write("ACL: %s: %s", filename,
897 pwmd_strerror(gpg_error_from_syserror()));
898 #endif
901 else if (filename)
902 rc = gpg_error_from_syserror();
904 else
905 rc = gpg_error_from_syserror();
908 if (!rc) {
909 if (filename && g_rename(tmp, filename) != -1) {
910 tmp[0] = 0;
911 if (filename && mode)
912 g_chmod(filename, mode);
914 #ifdef WITH_LIBACL
915 if (filename && acl && acl_set_file(filename, ACL_TYPE_ACCESS, acl))
916 log_write("ACL: %s: %s", filename,
917 pwmd_strerror(gpg_error_from_syserror()));
918 #endif
920 /* Be sure the file entry has been written to disk. On FreeBSD I
921 * noticed delays causing a following command to return
922 * GPG_ERR_CHECKSUM. Recommended from fsync(2) (Linux).
924 DIR *dir;
925 gchar *path;
926 gchar *s = get_key_file_string("global", "data_directory");
928 path = expand_homedir(s);
929 g_free(s);
930 dir = opendir(path);
931 g_free(path);
932 if (dir) {
933 fd = dirfd(dir);
934 if (fd != -1)
935 fsync(fd);
936 else
937 rc = gpg_error_from_syserror();
939 closedir(dir);
941 else
942 rc = gpg_error_from_syserror();
944 else
945 rc = gpg_error_from_syserror();
948 #ifdef WITH_LIBACL
949 pthread_cleanup_pop(1);
950 #endif
951 pthread_cleanup_pop(rc ? 1 : 0); // unlink
952 return rc;
955 gpg_error_t encrypt_data_file(struct crypto_s *crypto, gcry_sexp_t pubkey,
956 gcry_sexp_t sigpkey, const gchar *filename, const gpointer xml,
957 gsize len)
959 gpg_error_t rc;
960 gpointer data = NULL;
961 gsize data_len = 0;
962 gpointer enc_xml = NULL;
963 gsize enc_xml_len = 0;
964 guchar *iv = NULL;
965 gsize iv_len = 0;
966 gint algo = cipher_to_gcrypt(crypto->save.hdr.flags);
967 gpointer key = NULL;
968 gsize keysize;
969 guchar sig_grip[20];
970 guchar grip[20];
972 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL, &keysize);
973 if (rc)
974 return rc;
976 pthread_cleanup_push(gcry_free, key);
977 key = gcry_random_bytes_secure(keysize, GCRY_STRONG_RANDOM);
978 pthread_testcancel(); // may have been a long operation
979 pthread_cleanup_pop(0);
980 if (!key)
981 return GPG_ERR_ENOMEM;
983 gcry_pk_get_keygrip(pubkey, grip);
984 gcry_pk_get_keygrip(sigpkey, sig_grip);
985 pthread_cleanup_push(g_free, iv);
986 pthread_cleanup_push(gcry_free, key);
987 rc = encrypt_xml(key, keysize, algo, xml, len, &enc_xml, &enc_xml_len,
988 &iv, &iv_len);
989 if (!rc) {
990 gcry_sexp_t sig_sexp = NULL;
991 gchar *hexgrip = bin2hex(sig_grip, 20);
993 pthread_cleanup_push(gcry_free, enc_xml);
994 rc = sign(&sig_sexp, hexgrip, crypto, enc_xml, enc_xml_len);
995 g_free(hexgrip);
997 if (!rc) {
998 rc = verify(sigpkey, sig_sexp, enc_xml, enc_xml_len);
1000 if (!rc) {
1001 gcry_sexp_t tmp_sexp;
1003 rc = gcry_sexp_build(&tmp_sexp, NULL,
1004 "(data (flags pkcs1) (value %b))", keysize, key);
1005 if (!rc) {
1006 gcry_sexp_t key_sexp;
1008 pthread_cleanup_push((void (*)(void*))gcry_sexp_release,
1009 (void *)sig_sexp);
1010 rc = gcry_pk_encrypt(&key_sexp, tmp_sexp, pubkey);
1011 pthread_cleanup_pop(0);
1012 gcry_sexp_release(tmp_sexp);
1014 if (!rc) {
1015 memcpy(crypto->save.hdr.iv, iv, iv_len);
1016 crypto->save.hdr.datalen = enc_xml_len;
1017 rc = gcry_sexp_build(&tmp_sexp, NULL, "%S%S", key_sexp,
1018 sig_sexp);
1019 gcry_sexp_release(key_sexp);
1021 if (!rc) {
1022 data_len = gcry_sexp_sprint(tmp_sexp,
1023 GCRYSEXP_FMT_CANON, NULL, 0);
1024 data = g_malloc(data_len+40); // +40 for keygrips
1025 if (data) {
1026 gcry_sexp_sprint(tmp_sexp, GCRYSEXP_FMT_CANON,
1027 data+40, data_len);
1028 data_len += 40;
1030 else
1031 rc = GPG_ERR_ENOMEM;
1033 gcry_sexp_release(tmp_sexp);
1040 pthread_cleanup_pop(0); // enc_xml
1042 if (sig_sexp)
1043 gcry_sexp_release(sig_sexp);
1046 pthread_cleanup_pop(1); // key
1047 pthread_cleanup_pop(1); // iv
1049 if (!rc) {
1050 pthread_cleanup_push(gcry_free, enc_xml);
1051 memcpy(data, grip, 20);
1052 memcpy(data+20, sig_grip, 20);
1053 rc = write_file(crypto, filename, enc_xml, enc_xml_len, data, data_len);
1054 pthread_cleanup_pop(1); // enc_xml
1055 if (!rc) {
1056 if (filename)
1057 g_lstat(filename, &crypto->st);
1059 memcpy(&crypto->hdr, &crypto->save.hdr, sizeof(file_header_t));
1063 g_free(data);
1064 return rc;
1067 void cleanup_save(struct save_s *save)
1069 if (!save)
1070 return;
1072 if (save->pkey)
1073 gcry_sexp_release(save->pkey);
1075 if (save->sigpkey)
1076 gcry_sexp_release(save->sigpkey);
1078 memset(save, 0, sizeof(struct save_s));
1081 /* Keep the agent ctx to retain pinentry options which will be freed in
1082 * cleanup_cb(). Also keep .pubkey since it may be needed for a SAVE. */
1083 void cleanup_crypto_stage1(struct crypto_s *cr)
1085 if (!cr)
1086 return;
1088 cleanup_save(&cr->save);
1090 if (cr->ciphertext_sexp)
1091 gcry_sexp_release(cr->ciphertext_sexp);
1093 if (cr->plaintext)
1094 gcry_free(cr->plaintext);
1096 g_free(cr->ciphertext);
1097 g_free(cr->filename);
1098 cr->filename = NULL;
1099 cr->ciphertext_sexp = NULL;
1100 cr->ciphertext = NULL;
1101 cr->ciphertext_len = 0;
1102 cr->plaintext = NULL;
1103 cr->plaintext_len = 0;
1106 void cleanup_crypto_stage2(struct crypto_s *cr)
1108 if (!cr)
1109 return;
1111 cleanup_crypto_stage1(cr);
1112 set_header_defaults(&cr->hdr);
1115 void cleanup_crypto(struct crypto_s **c)
1117 struct crypto_s *cr = *c;
1119 if (!cr)
1120 return;
1122 cleanup_crypto_stage2(cr);
1124 if (cr->pkey_sexp)
1125 gcry_sexp_release(cr->pkey_sexp);
1127 if (cr->sigpkey_sexp)
1128 gcry_sexp_release(cr->sigpkey_sexp);
1130 if (cr->agent)
1131 cleanup_agent(cr->agent);
1133 g_free(cr);
1134 *c = NULL;
1137 gpg_error_t init_client_crypto(struct crypto_s **crypto)
1139 struct crypto_s *new = g_malloc0(sizeof(struct crypto_s));
1140 gpg_error_t rc;
1142 if (!new) {
1143 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
1144 return GPG_ERR_ENOMEM;
1147 rc = agent_init(&new->agent);
1148 if (!rc) {
1149 rc = send_agent_common_options(new->agent);
1150 if (!rc)
1151 rc = set_pinentry_options(new->agent);
1154 if (rc) {
1155 g_free(new);
1156 return rc;
1159 set_header_defaults(&new->hdr);
1160 *crypto = new;
1161 return 0;
1164 gpg_error_t generate_key(struct crypto_s *crypto, gchar *sexpstr,
1165 gboolean empty, gboolean preset)
1167 gpg_error_t rc;
1168 gchar *pkey;
1169 gsize plen;
1171 if (crypto->save.s2k_count) {
1172 rc = send_to_agent(crypto->agent, NULL, NULL,
1173 "OPTION s2k-count=%lu", crypto->save.s2k_count);
1174 if (rc)
1175 return rc;
1178 if (!crypto->agent->inquire_cb)
1179 crypto->agent->inquire_cb = inquire_cb;
1181 rc = send_to_agent(crypto->agent, &pkey, &plen, "GENKEY %s%s",
1182 preset ? "--preset " : "",
1183 empty ? "--no-protection" : "");
1184 if (rc)
1185 return rc;
1187 if (crypto->save.pkey)
1188 gcry_sexp_release(crypto->save.pkey);
1190 crypto->save.pkey = NULL;
1191 rc = gcry_sexp_new(&crypto->save.pkey, pkey, plen, 1);
1192 if (!rc) {
1193 guchar grip[20];
1195 gcry_pk_get_keygrip(crypto->save.pkey, grip);
1196 gchar *hexgrip = bin2hex(grip, sizeof(grip));
1197 log_write1(_("Keygrip is %s"), hexgrip);
1198 g_free(hexgrip);
1200 if (!crypto->save.sigpkey) {
1201 gcry_sexp_build((gcry_sexp_t *)&crypto->save.sigpkey, NULL, "%S",
1202 crypto->save.pkey);
1206 xfree(pkey);
1207 return rc;
1210 gpg_error_t set_agent_option(struct agent_s *agent, const gchar *name,
1211 const gchar *value)
1213 return send_to_agent(agent, NULL, NULL, "OPTION %s=%s", name, value);
1216 gpg_error_t set_agent_passphrase(struct crypto_s *crypto, const gchar *key,
1217 gsize len)
1219 gchar *hexgrip;
1220 struct inquire_data_s idata;
1221 gpg_error_t rc;
1222 gint i;
1224 /* This is for use with key files or passphrases obtained from an inquire.
1225 * gpg-agent uses strings as passphrases and will truncate the passphrase
1226 * at the first encountered null byte. It's only a warning because the
1227 * passphrase may belong to a key shared outside of pwmd. */
1228 for (i = 0; i < len; i++) {
1229 if (key[i] == 0) {
1230 log_write(_("WARNING: keylen=%i, truncated to %i."), len, i);
1231 break;
1235 hexgrip = bin2hex(crypto->grip, 20);
1236 crypto->agent->inquire_cb = inquire_cb;
1237 crypto->agent->inquire_data = &idata;
1238 idata.crypto = crypto;
1239 idata.line = (gchar *)key,
1240 idata.len = len;
1241 idata.preset = TRUE;
1242 assuan_begin_confidential(crypto->agent->ctx);
1243 rc = send_to_agent(crypto->agent, NULL, NULL,
1244 "PRESET_PASSPHRASE --inquire %s -1", hexgrip);
1245 assuan_end_confidential(crypto->agent->ctx);
1246 idata.preset = FALSE;
1247 g_free(hexgrip);
1248 return rc;
1251 gpg_error_t set_pinentry_mode(struct agent_s *agent, const gchar *mode)
1253 return set_agent_option(agent, "pinentry-mode", mode);
1256 gpg_error_t get_pubkey_bin(struct crypto_s *crypto, const guchar *grip,
1257 gcry_sexp_t *result)
1259 gchar *hexgrip = bin2hex(grip, 20);
1260 gpg_error_t rc;
1262 if (!hexgrip)
1263 return GPG_ERR_ENOMEM;
1265 rc = get_pubkey(crypto, hexgrip, result);
1266 g_free(hexgrip);
1267 return rc;
1270 gpg_error_t get_pubkey(struct crypto_s *crypto, const gchar *grip,
1271 gcry_sexp_t *result)
1273 gchar *pkey = NULL;
1274 gsize plen;
1275 gpg_error_t rc;
1277 rc = send_to_agent(crypto->agent, &pkey, &plen, "READKEY %s", grip);
1278 if (!rc)
1279 rc = gcry_sexp_new(result, pkey, plen, 1);
1281 xfree(pkey);
1282 return rc;
1285 gpg_error_t set_pinentry_options(struct agent_s *agent)
1287 gpg_error_t rc = 0;
1289 if (getenv("DISPLAY")) {
1290 rc = set_agent_option(agent, "display", getenv("DISPLAY"));
1291 if (!rc) {
1292 g_free(agent->display);
1293 agent->display = g_strdup(getenv("DISPLAY"));
1296 else if (ttyname(STDOUT_FILENO)) {
1297 rc = set_agent_option(agent, "ttyname", ttyname(STDOUT_FILENO));
1298 if (!rc) {
1299 rc = set_agent_option(agent, "ttytype", getenv("TERM"));
1300 if (!rc) {
1301 g_free(agent->ttyname);
1302 g_free(agent->ttytype);
1303 agent->ttyname = g_strdup(ttyname(STDOUT_FILENO));
1304 agent->ttytype = g_strdup(getenv("TERM"));
1309 return rc;
1312 static gpg_error_t inquire_keyfile(gpointer user, const gchar *keyword)
1314 struct crypto_s *crypto = user;
1315 gchar *filename = crypto->agent->inquire_data2;
1316 gchar *params = crypto->agent->inquire_data3;
1317 gint fd;
1318 struct stat st;
1319 guchar *buf;
1320 gsize len;
1321 gpg_error_t rc;
1323 if (!g_strcmp0(keyword, "KEYPARAM"))
1324 return assuan_send_data(crypto->agent->ctx, params, strlen(params));
1326 // This function is only used when generating a new keypair.
1327 if (g_strcmp0(keyword, "NEW_PASSPHRASE"))
1328 return gpg_error(GPG_ERR_ASS_UNKNOWN_INQUIRE);
1330 if (stat(filename, &st) == -1)
1331 return gpg_error_from_syserror();
1333 if (crypto->agent->inquire_maxlen
1334 && st.st_size > crypto->agent->inquire_maxlen) {
1335 log_write(_("The passphrase is too large: have=%u, max=%u."),
1336 (unsigned)st.st_size, crypto->agent->inquire_maxlen);
1337 return GPG_ERR_TOO_LARGE;
1340 buf = gcry_malloc_secure(st.st_size);
1341 if (!buf)
1342 return GPG_ERR_ENOMEM;
1344 fd = open(filename, O_RDONLY);
1345 if (fd == -1)
1346 rc = gpg_error_from_syserror();
1347 else {
1348 len = read(fd, buf, st.st_size);
1349 if (len == st.st_size) {
1350 assuan_begin_confidential(crypto->agent->ctx);
1351 rc = assuan_send_data(crypto->agent->ctx, buf, len);
1352 assuan_end_confidential(crypto->agent->ctx);
1354 else if (len == -1)
1355 rc = gpg_error_from_syserror();
1356 else
1357 rc = GPG_ERR_BUFFER_TOO_SHORT;
1360 close(fd);
1361 gcry_free(buf);
1362 return rc;
1365 gpg_error_t export_common(struct crypto_s *crypto, const gchar *hexgrip,
1366 const gchar *sign_hexgrip, gboolean no_passphrase,
1367 const gpointer data, gsize datalen, const gchar *outfile,
1368 const gchar *keyparams, const gchar *keyfile)
1370 gpg_error_t rc = 0;
1372 if (!sign_hexgrip && hexgrip)
1373 sign_hexgrip = hexgrip;
1375 if (sign_hexgrip) {
1376 if (crypto->sigpkey_sexp)
1377 gcry_sexp_release(crypto->sigpkey_sexp);
1379 crypto->sigpkey_sexp = NULL;
1380 rc = get_pubkey(crypto, sign_hexgrip, &crypto->save.sigpkey);
1381 if (rc)
1382 return rc;
1384 gcry_pk_get_keygrip(crypto->save.sigpkey, crypto->sign_grip);
1387 if (hexgrip) {
1388 rc = get_pubkey(crypto, hexgrip, &crypto->save.pkey);
1389 if (!rc)
1390 gcry_pk_get_keygrip(crypto->save.pkey, crypto->grip);
1392 else {
1393 struct inquire_data_s idata = {0};
1394 gchar *params = keyparams ? g_strdup(keyparams)
1395 : default_key_params(crypto);
1397 pthread_cleanup_push(g_free, params);
1398 log_write(_("Generating a new keypair ..."));
1399 if (keyfile) {
1400 log_write(N_("Using passphrase obtained from file '%s'"), keyfile);
1401 rc = set_pinentry_mode(crypto->agent, "loopback");
1402 crypto->agent->inquire_cb = inquire_keyfile;
1403 crypto->agent->inquire_data = crypto;
1404 crypto->agent->inquire_data2 = (gchar *)keyfile;
1405 crypto->agent->inquire_data3 = params;
1407 else {
1408 idata.line = params;
1409 idata.len = strlen(params);
1410 idata.crypto = crypto;
1411 crypto->agent->inquire_cb = inquire_cb;
1412 crypto->agent->inquire_data = &idata;
1415 if (!rc) {
1416 rc = generate_key(crypto, params, no_passphrase, TRUE);
1417 gcry_pk_get_keygrip(crypto->save.pkey, crypto->grip);
1420 (void)set_pinentry_mode(crypto->agent, "ask");
1421 pthread_cleanup_pop(1);
1424 if (!rc) {
1425 rc = encrypt_data_file(crypto, crypto->save.pkey, crypto->save.sigpkey,
1426 outfile, data, datalen);
1427 if (!rc) {
1428 gchar *tmp = bin2hex(crypto->grip, sizeof(crypto->grip));
1430 log_write(_("Success! Keygrip is %s."), tmp);
1431 rc = send_to_agent(crypto->agent, NULL, NULL,
1432 "CLEAR_PASSPHRASE --mode=normal %s", tmp);
1433 g_free(tmp);
1435 if (sign_hexgrip) {
1436 tmp = bin2hex(crypto->sign_grip, sizeof(crypto->sign_grip));
1437 log_write(_("Signed with keygrip %s."), tmp);
1438 g_free(tmp);
1443 return rc;
1446 gchar *default_key_params(struct crypto_s *crypto)
1448 gint len = get_key_file_integer(NULL, "nbits");
1449 gchar buf[32];
1450 gchar *algo = get_key_file_string(NULL, "algo");
1451 gchar *result;
1453 g_snprintf(buf, sizeof(buf), "%i", len);
1454 result = g_strdup_printf("(genkey (%s (nbits %lu:%i)))", algo, strlen(buf),
1455 len);
1456 g_free(algo);
1457 return result;
1460 gpg_error_t agent_passwd(struct crypto_s *crypto)
1462 struct inquire_data_s idata = {0};
1463 gpg_error_t rc;
1464 gchar *tmp = bin2hex(crypto->grip, 20);
1466 idata.crypto = crypto;
1467 crypto->agent->inquire_cb = inquire_cb;
1468 crypto->agent->inquire_data = &idata;
1469 rc = send_to_agent(crypto->agent, NULL, NULL, "PASSWD --preset %s", tmp);
1470 g_free(tmp);
1471 return rc;