Update NEWS.
[pwmd.git] / src / crypto.c
blob0e7dae98318a93d93e68fbd40dc2efd49d37f080
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
3 2016
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 <stdio.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <pthread.h>
32 #ifdef WITH_LIBACL
33 #include <sys/acl.h>
34 #endif
36 #include "pwmd-error.h"
37 #include "util-misc.h"
38 #include "common.h"
39 #include "rcfile.h"
40 #include "crypto.h"
41 #include "cache.h"
42 #include "mem.h"
43 #include "util-string.h"
44 #include "rcfile.h"
45 #include "mutex.h"
47 static unsigned keepalive;
48 static pthread_mutex_t crypto_mutex = PTHREAD_MUTEX_INITIALIZER;
50 #define BUFSIZE 4096
52 #define STATUS_TIMEOUT_INIT(crypto) \
53 do { \
54 crypto->status_timeout = time (NULL); \
55 crypto->progress_rc = 0; \
56 } while (0)
58 #define STATUS_TIMEOUT_TEST(crypto, rc, s, line) \
59 do { \
60 time_t now = time (NULL); \
61 if (now - crypto->status_timeout >= keepalive && crypto->client_ctx) { \
62 rc = send_status (crypto->client_ctx, s, line); \
63 crypto->status_timeout = now; \
64 } \
65 } while (0)
67 #if 0
68 static gpgme_error_t
69 show_key_output (gpgme_key_t key)
71 gpgme_subkey_t keyp; // first is primary
73 for (keyp = key->subkeys; keyp; keyp = keyp->next)
75 fprintf(stderr, "keyid: %s, revoked: %i, expired: %i, disabled: %i, invalid: %i,"
76 "encrypt: %i, sign: %i, cert: %i, auth: %i, secret: %i\n",
77 keyp->keyid, keyp->revoked, keyp->expired, keyp->disabled,
78 keyp->invalid, keyp->can_encrypt, keyp->can_sign,
79 keyp->can_certify, keyp->can_authenticate, keyp->secret);
82 return 0;
84 #endif
86 static gpg_error_t
87 get_password (const char *keyfile, unsigned char **result, size_t *len)
89 struct stat st;
90 int fd;
91 unsigned char *buf = NULL;
92 gpg_error_t rc = 0;
94 log_write (_ ("obtaining passphrase from passphrase file"));
95 rc = open_check_file (keyfile, &fd, &st, 0);
96 if (rc)
97 return rc;
99 buf = xmalloc (st.st_size+1);
100 if (buf)
102 size_t rlen = read (fd, buf, st.st_size);
104 if (rlen != st.st_size)
105 rc = GPG_ERR_ASS_READ_ERROR;
106 else
108 buf[rlen] = 0;
109 if (rlen && strlen ((char *)buf) != rlen)
110 rc = GPG_ERR_INV_PASSPHRASE;
112 if (!rc)
114 *result = buf;
115 *len = rlen;
119 else
120 rc = GPG_ERR_ENOMEM;
122 close (fd);
123 if (rc)
124 xfree (buf);
126 return rc;
129 static gpgme_error_t
130 status_cb (void *data, const char *keyword, const char *args)
132 struct crypto_s *crypto = data;
134 // Cache pushing.
135 if (!crypto->client_ctx)
136 return 0;
138 if (!strcmp (keyword, "INQUIRE_MAXLEN") &&
139 (crypto->flags & CRYPTO_FLAG_KEYFILE))
140 return 0;
142 return assuan_write_status (crypto->client_ctx, keyword, args);
145 static gpgme_error_t
146 passphrase_cb (void *data, const char *hint, const char *info, int bad, int fd)
148 struct crypto_s *crypto = data;
149 unsigned char *result = NULL;
150 size_t len;
151 gpg_error_t rc = 0;
153 if (crypto->flags & CRYPTO_FLAG_KEYFILE)
154 rc = get_password (crypto->keyfile, &result, &len);
155 else
157 if (hint)
158 rc = assuan_write_status (crypto->client_ctx, "PASSPHRASE_HINT", hint);
160 if (!rc && info)
161 rc = assuan_write_status (crypto->client_ctx, "PASSPHRASE_INFO", info);
163 if (!rc)
165 const char *keyword = "PASSPHRASE";
167 if (!bad && crypto->flags & CRYPTO_FLAG_PASSWD_SIGN)
168 keyword = "SIGN_PASSPHRASE";
169 else if (!bad && crypto->flags & CRYPTO_FLAG_PASSWD_NEW)
171 crypto->flags |= CRYPTO_FLAG_PASSWD_SIGN;
172 keyword = "NEW_PASSPHRASE";
174 else if (!bad && crypto->flags & CRYPTO_FLAG_PASSWD)
175 crypto->flags |= CRYPTO_FLAG_PASSWD_NEW;
176 else if (!bad && crypto->flags & CRYPTO_FLAG_NEWFILE)
178 keyword = "NEW_PASSPHRASE";
179 if (crypto->save.sigkey)
180 crypto->flags |= CRYPTO_FLAG_PASSWD_SIGN;
183 rc = assuan_inquire (crypto->client_ctx, keyword, &result, &len, 0);
187 if (!rc)
189 pthread_cleanup_push ((void *)xfree, result);
191 if (!len)
192 gpgme_io_writen (fd, "\n", 1);
193 else
195 int nl = result[len-1] == '\n';
196 int ret;
198 ret = gpgme_io_writen (fd, result, len);
199 if (!ret && !nl)
200 gpgme_io_writen (fd, "\n", 1);
201 else if (ret)
202 rc = GPG_ERR_CANCELED;
205 pthread_cleanup_pop (1);
208 return rc;
211 static void
212 progress_cb (void *data, const char *what, int type, int current, int total)
214 struct crypto_s *crypto = data;
216 crypto->progress_rc = send_status (crypto->client_ctx, STATUS_GPGME,
217 "%s %i %i %i", what, type, current, total);
220 gpgme_error_t
221 crypto_data_to_buf (const gpgme_data_t data, unsigned char **result,
222 size_t *rlen)
224 off_t ret = gpgme_data_seek (data, 0, SEEK_SET);
225 gpgme_error_t rc;
226 size_t total = 0, size = BUFSIZE;
227 unsigned char *buf = NULL;
229 *result = NULL;
230 *rlen = 0;
232 if (ret == -1)
233 return gpg_error_from_syserror ();
235 buf = xmalloc (size);
236 if (!buf)
237 return GPG_ERR_ENOMEM;
241 ret = gpgme_data_read (data, &buf[total], BUFSIZE);
242 if (ret > 0)
244 unsigned char *p;
246 total += ret;
247 size += BUFSIZE;
248 p = xrealloc (buf, size * sizeof (unsigned char));
249 if (!p)
251 xfree (buf);
252 return GPG_ERR_ENOMEM;
255 buf = p;
257 } while (ret > 0);
259 if (ret == -1)
261 rc = gpgme_err_code_from_syserror ();
262 xfree (buf);
263 return rc;
266 if (!total)
267 xfree (buf);
268 else
269 *result = buf;
271 *rlen = total;
272 return 0;
275 gpgme_error_t
276 crypto_list_keys (struct crypto_s *crypto, char *keys[], int secret,
277 gpgme_key_t **result)
279 gpgme_error_t rc;
280 gpgme_key_t key = NULL, *res = NULL;
281 size_t total = 0;
283 rc = gpgme_op_keylist_ext_start (crypto->ctx, (const char **)keys, secret, 0);
284 if (rc)
285 return rc;
287 STATUS_TIMEOUT_INIT (crypto);
290 gpgme_key_t *p;
292 pthread_cleanup_push ((void *)crypto_free_key_list, res);
293 rc = gpgme_op_keylist_next (crypto->ctx, &key);
294 pthread_cleanup_pop (0);
295 if (rc && gpgme_err_code(rc) != GPG_ERR_EOF)
296 break;
298 if (rc)
300 rc = 0;
301 break;
304 p = xrealloc (res, (total+2) * sizeof (gpgme_key_t));
305 if (!p)
307 rc = GPG_ERR_ENOMEM;
308 break;
311 res = p;
312 res[total++] = key;
313 res[total] = NULL;
314 pthread_cleanup_push ((void *)crypto_free_key_list, res);
315 STATUS_TIMEOUT_TEST (crypto, rc, STATUS_KEEPALIVE, NULL);
316 pthread_cleanup_pop (0);
317 } while (!rc);
319 if (!rc)
321 rc = gpgme_op_keylist_end (crypto->ctx);
322 if (!rc)
324 *result = res;
325 rc = total ? 0 : secret ? GPG_ERR_NO_SECKEY : GPG_ERR_NO_PUBKEY;
328 else
329 crypto_free_key_list (res);
331 return rc;
334 void
335 crypto_free_save (struct save_s *save)
337 if (!save)
338 return;
340 strv_free (save->pubkey);
341 xfree (save->sigkey);
342 xfree (save->userid);
343 xfree (save->algo);
344 crypto_free_key_list (save->mainkey);
346 memset (save, 0, sizeof (struct save_s));
349 static gpg_error_t
350 crypto_kill_scd ()
352 return cache_kill_scd ();
355 static void
356 free_gpgme_data_cb (void *data)
358 gpgme_data_t d = data;
359 char *t;
360 size_t len;
362 if (!data)
363 return;
365 t = gpgme_data_release_and_get_mem (d, &len);
366 if (t)
367 wipememory (t, 0, len);
369 gpgme_free (t);
372 void
373 crypto_free_non_keys (struct crypto_s *crypto)
375 if (!crypto)
376 return;
378 if (crypto->ctx)
379 gpgme_release (crypto->ctx);
381 crypto->ctx = NULL;
382 xfree (crypto->plaintext);
383 crypto->plaintext = NULL;
384 crypto->plaintext_size = 0;
386 if (crypto->cipher)
387 free_gpgme_data_cb (crypto->cipher);
389 crypto->cipher = NULL;
390 crypto_free_save (&crypto->save);
391 xfree (crypto->keyfile);
392 crypto->keyfile = NULL;
393 crypto->flags &= ~CRYPTO_FLAG_KEYFILE;
394 (void)crypto_kill_scd ();
397 void
398 crypto_free (struct crypto_s *crypto)
400 if (!crypto)
401 return;
403 crypto_free_non_keys (crypto);
404 strv_free (crypto->pubkey);
405 xfree (crypto->sigkey);
406 xfree (crypto->filename);
407 xfree (crypto);
410 gpgme_error_t
411 crypto_init_ctx (struct crypto_s *crypto, int no_pinentry,
412 char *passphrase_file)
414 gpgme_ctx_t ctx;
415 gpgme_keylist_mode_t keylist_mode;
416 gpgme_error_t rc;
418 rc = gpgme_new (&ctx);
419 if (rc)
420 return rc;
422 rc = gpgme_set_protocol (ctx, GPGME_PROTOCOL_OPENPGP);
423 if (!rc)
425 keylist_mode = gpgme_get_keylist_mode (ctx);
426 keylist_mode |= GPGME_KEYLIST_MODE_LOCAL|GPGME_KEYLIST_MODE_WITH_SECRET;
427 rc = gpgme_set_keylist_mode (ctx, keylist_mode);
428 if (!rc)
430 if (no_pinentry || passphrase_file)
431 rc = gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
432 else
433 rc = gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_DEFAULT);
435 if (!rc)
437 gpgme_set_passphrase_cb (ctx, passphrase_cb, crypto);
438 gpgme_set_progress_cb (ctx, progress_cb, crypto);
439 gpgme_set_status_cb (ctx, status_cb, crypto);
440 crypto->ctx = ctx;
441 crypto->flags = 0;
444 if (passphrase_file)
446 crypto->keyfile = passphrase_file;
447 crypto->flags |= CRYPTO_FLAG_KEYFILE;
452 if (rc)
453 gpgme_release (ctx);
455 return rc;
458 void
459 crypto_set_keepalive ()
461 keepalive = config_get_integer ("global", "keepalive_interval");
464 gpg_error_t
465 crypto_init (struct crypto_s **crypto, void *ctx, const char *filename,
466 int no_pinentry, char *passphrase_file)
468 struct crypto_s *new = xcalloc (1, sizeof (struct crypto_s));
469 gpgme_error_t rc;
471 crypto_set_keepalive ();
473 if (!new)
474 return GPG_ERR_ENOMEM;
476 rc = crypto_init_ctx (new, no_pinentry, passphrase_file);
477 if (rc)
478 goto fail;
480 if (filename)
482 new->filename = str_dup (filename);
483 if (!new->filename)
485 rc = GPG_ERR_ENOMEM;
486 goto fail;
490 new->client_ctx = ctx;
491 *crypto = new;
492 return 0;
494 fail:
495 crypto_free (new);
496 return rc;
499 /* Converts a 40 byte key id to the 16 byte form. Needed for comparison of
500 * gpgme_recipient_t.keyid. */
501 gpg_error_t
502 crypto_keyid_to_16b_once (char *key)
504 size_t len = strlen (key);
506 if (len < 16)
507 return GPG_ERR_INV_ARG;
509 memmove (&key[0], &key[len-16], 16);
510 key[16] = 0;
511 return 0;
514 gpg_error_t
515 crypto_keyid_to_16b (char **keys)
517 char **p;
519 for (p = keys; p && *p; p++)
521 gpg_error_t rc = crypto_keyid_to_16b_once (*p);
522 if (rc)
523 return rc;
526 return 0;
529 gpgme_error_t
530 crypto_decrypt (struct client_s *client, struct crypto_s *crypto)
532 gpgme_data_t plain;
533 gpgme_error_t rc;
534 gpgme_data_t cipher;
535 int fd = -1;
536 struct stat st;
537 char **new_recipients = NULL;
538 char **new_signers = NULL;
539 char **pp;
540 gpgme_decrypt_result_t result;
542 rc = gpgme_data_new (&plain);
543 if (rc)
544 return rc;
546 pthread_cleanup_push ((void *)free_gpgme_data_cb, plain);
547 rc = open_check_file (crypto->filename, &fd, &st, 1);
548 if (!rc)
550 pthread_cleanup_push ((void *)close_fd_cb, &fd);
551 rc = gpgme_data_new_from_fd (&cipher, fd);
552 if (!rc)
554 pthread_cleanup_push ((void *)free_gpgme_data_cb, cipher);
555 rc = send_status (client ? client->ctx : NULL, STATUS_DECRYPT, NULL);
556 if (!rc)
558 MUTEX_TRYLOCK (client->ctx, &crypto_mutex, rc,
559 client->lock_timeout);
560 if (!rc)
562 pthread_cleanup_push (release_mutex_cb, &crypto_mutex);
563 rc = gpgme_op_decrypt_verify_start (crypto->ctx, cipher, plain);
564 if (!rc)
566 STATUS_TIMEOUT_INIT(crypto);
569 if (!rc && crypto->progress_rc)
570 rc = crypto->progress_rc;
571 if (!rc)
572 STATUS_TIMEOUT_TEST (crypto, rc, STATUS_DECRYPT, NULL);
573 TEST_CANCEL ();
574 } while (!rc && !gpgme_wait (crypto->ctx, &rc, 0) && !rc);
576 pthread_cleanup_pop (1); // release_mutex_cb
579 pthread_cleanup_pop (1); // free_gpgme_data_cb (cipher)
582 pthread_cleanup_pop (1); // close (fd)
585 pthread_cleanup_pop (0); // free_gpgme_data_cb (plain)
587 if (rc)
589 free_gpgme_data_cb (plain);
590 return rc;
593 pthread_cleanup_push ((void *)free_gpgme_data_cb, plain);
594 result = gpgme_op_decrypt_result (crypto->ctx);
595 if (!result->unsupported_algorithm && !result->wrong_key_usage)
597 gpgme_recipient_t r;
599 for (r = result->recipients; r; r = r->next)
601 pthread_cleanup_push ((void *)strv_free, new_recipients);
602 log_write1 (_ ("%s: recipient: %s, status=%u"),
603 crypto->filename, r->keyid, r->status);
604 pthread_cleanup_pop (0);
605 pp = strv_cat(new_recipients, str_dup (r->keyid));
606 if (!pp)
608 rc = GPG_ERR_ENOMEM;
609 break;
612 new_recipients = pp;
615 else if (result->wrong_key_usage)
616 rc = GPG_ERR_WRONG_KEY_USAGE;
617 else if (result->unsupported_algorithm)
618 rc = GPG_ERR_UNSUPPORTED_ALGORITHM;
620 if (!rc)
622 gpgme_verify_result_t verify;
623 gpgme_signature_t s;
625 verify = gpgme_op_verify_result (crypto->ctx);
627 for (s = verify->signatures; s; s = s->next)
629 pthread_cleanup_push ((void *)strv_free, new_signers);
630 log_write1 (_ ("%s: signer: %s, status=%u"),
631 crypto->filename, s->fpr, s->status);
632 pthread_cleanup_pop (0);
633 if (s->status || s->wrong_key_usage
634 || !(s->summary & GPGME_SIGSUM_VALID))
635 continue;
637 pp = strv_cat (new_signers, str_dup (s->fpr));
638 if (!pp)
640 rc = GPG_ERR_ENOMEM;
641 break;
644 new_signers = pp;
647 if (verify->signatures && !new_signers)
648 rc = GPG_ERR_BAD_SIGNATURE;
650 if (!rc)
652 xfree (crypto->plaintext);
653 crypto->plaintext = NULL;
654 crypto->plaintext_size = 0;
655 pthread_cleanup_push ((void *)strv_free, new_recipients);
656 pthread_cleanup_push ((void *)strv_free, new_signers);
657 rc = crypto_data_to_buf (plain, &crypto->plaintext,
658 &crypto->plaintext_size);
659 pthread_cleanup_pop (0);
660 pthread_cleanup_pop (0);
661 if (!rc)
663 strv_free (crypto->pubkey);
664 crypto->pubkey = new_recipients;
665 crypto_keyid_to_16b (crypto->pubkey);
667 xfree (crypto->sigkey);
668 crypto->sigkey = NULL;
669 if (new_signers)
671 crypto->sigkey = str_dup (*new_signers);
672 strv_free (new_signers);
673 crypto_keyid_to_16b_once (crypto->sigkey);
679 if (rc)
681 strv_free (new_recipients);
682 strv_free (new_signers);
685 pthread_cleanup_pop (1); // free_gpgme_data_cb (plain)
686 return rc;
689 void
690 crypto_free_key_list (gpgme_key_t *keys)
692 int i;
694 for (i = 0; keys && keys[i]; i++)
695 gpgme_key_unref (keys[i]);
697 xfree (keys);
700 /* Removes strings in 'prune' from 'a'. */
701 static char **
702 prune_keys (char **a, char **prune)
704 char **p;
706 for (p = prune; p && *p; p++)
708 char **ap;
710 for (ap = a; ap && *ap; ap++)
712 if (!strcmp (*ap, *p))
714 while (*ap)
716 *ap = *(ap+1);
717 ap++;
723 return a;
726 static void
727 remove_duplicates (char **a)
729 char **p;
731 for (p = a; p && *p; p++)
733 char **t;
735 for (t = p+1; t && *t; t++)
737 if (!strcmp (*p, *t))
739 char *tmp = *t;
741 while (*(t+1))
743 *t = *(t+1);
744 t++;
747 *t = NULL;
748 xfree (tmp);
749 remove_duplicates (a);
750 return;
756 gpgme_error_t
757 crypto_encrypt (struct client_s *client, struct crypto_s *crypto)
759 gpgme_error_t rc;
760 gpgme_data_t cipher = NULL;
761 gpgme_key_t *keys = NULL;
762 gpgme_key_t *sigkeys = NULL;
763 unsigned flags = 0;
764 int sign = 0;
766 if (!(crypto->flags & CRYPTO_FLAG_SYMMETRIC))
768 crypto_keyid_to_16b (crypto->save.pubkey);
769 remove_duplicates (crypto->save.pubkey);
770 rc = crypto_list_keys (crypto, crypto->save.pubkey, 0, &keys);
771 if (rc)
772 return rc;
775 pthread_cleanup_push ((void *)crypto_free_key_list, keys);
776 rc = gpgme_data_new (&cipher);
777 pthread_cleanup_push ((void *)free_gpgme_data_cb, cipher);
778 if (!rc)
779 rc = gpgme_data_set_file_name (cipher, crypto->filename);
781 if (!rc && crypto->save.sigkey)
783 char **tmp = NULL;
785 crypto_keyid_to_16b_once (crypto->save.sigkey);
786 strv_printf (&tmp, "%s", crypto->save.sigkey);
787 pthread_cleanup_push ((void *)strv_free, tmp);
788 rc = crypto_list_keys (crypto, tmp, 1, &sigkeys);
789 pthread_cleanup_pop (1);
790 if (gpg_err_code (rc) == GPG_ERR_NO_DATA)
791 rc = 0;
794 if (!rc)
796 gpgme_data_t plain = NULL;
798 pthread_cleanup_push ((void *)crypto_free_key_list, sigkeys);
799 rc = gpgme_data_new_from_mem (&plain, (char *)crypto->plaintext,
800 crypto->plaintext_size, 0);
801 pthread_cleanup_push ((void *)free_gpgme_data_cb, plain);
802 if (!rc)
804 int i;
806 gpgme_signers_clear (crypto->ctx);
808 for (i = 0; sigkeys && sigkeys[i]; i++)
809 gpgme_signers_add (crypto->ctx, sigkeys[i]);
812 if (!rc)
814 gpgme_data_set_encoding (cipher, GPGME_DATA_ENCODING_ARMOR);
815 rc = send_status (client ? client->ctx : NULL, STATUS_ENCRYPT, NULL);
818 if (!rc)
820 int f = config_get_boolean ("global", "encrypt_to");
822 if (!f)
823 flags |= GPGME_ENCRYPT_NO_ENCRYPT_TO;
825 f = config_get_boolean ("global", "always_trust");
826 if (f)
827 flags |= GPGME_ENCRYPT_ALWAYS_TRUST;
829 if (!(crypto->flags & CRYPTO_FLAG_SYMMETRIC)
830 || (crypto->flags & CRYPTO_FLAG_SYMMETRIC && sigkeys))
831 sign = 1;
834 if (!rc)
835 MUTEX_TRYLOCK (client->ctx, &crypto_mutex, rc, client->lock_timeout);
837 if (!rc)
839 pthread_cleanup_push (release_mutex_cb, &crypto_mutex);
840 if (sign)
841 rc = gpgme_op_encrypt_sign_start (crypto->ctx, keys, flags, plain,
842 cipher);
843 else
844 rc = gpgme_op_encrypt_start (crypto->ctx, NULL, flags, plain,
845 cipher);
846 if (!rc)
848 STATUS_TIMEOUT_INIT (crypto);
851 if (!rc && crypto->progress_rc)
852 rc = crypto->progress_rc;
853 if (!rc)
854 STATUS_TIMEOUT_TEST (crypto, rc, STATUS_ENCRYPT, NULL);
855 TEST_CANCEL();
856 } while (!rc && !gpgme_wait (crypto->ctx, &rc, 0) && !rc);
858 pthread_cleanup_pop (1);
860 if (!rc)
862 gpgme_encrypt_result_t result;
863 gpgme_sign_result_t sresult;
864 gpgme_invalid_key_t inv;
865 gpgme_new_signature_t sigs;
866 char **prune = NULL;
867 char **p = NULL;
869 result = gpgme_op_encrypt_result (crypto->ctx);
870 inv = result->invalid_recipients;
871 while (inv)
873 pthread_cleanup_push ((void *)strv_free, prune);
874 log_write1 (_ ("%s: invalid recipient: %s, rc=%u"),
875 crypto->filename, inv->fpr, inv->reason);
876 pthread_cleanup_pop (0);
877 p = strv_cat (prune, str_dup(inv->fpr));
878 if (!p)
880 rc = GPG_ERR_ENOMEM;
881 strv_free (prune);
882 break;
885 prune = p;
886 inv = inv->next;
889 if (prune)
891 p = prune_keys (crypto->save.pubkey, prune);
892 crypto->save.pubkey = p;
893 strv_free (prune);
896 crypto_keyid_to_16b (crypto->save.pubkey);
897 sresult = gpgme_op_sign_result (crypto->ctx);
898 inv = sresult ? sresult->invalid_signers : NULL;
899 while (!rc && inv)
901 log_write1 (_ ("%s: invalid signer: %s, rc=%u"),
902 crypto->filename, inv->fpr, inv->reason);
903 inv = inv->next;
906 sigs = sresult ? sresult->signatures : NULL;
907 if (!rc && sigs)
909 p = NULL;
911 while (sigs)
913 char **pp;
915 pthread_cleanup_push ((void *)strv_free, p);
916 log_write1 (_ ("%s: signer: %s"), crypto->filename,
917 sigs->fpr);
918 pthread_cleanup_pop (0);
920 pp = strv_cat (p, str_dup (sigs->fpr));
921 if (!pp)
923 rc = GPG_ERR_ENOMEM;
924 strv_free (p);
925 break;
928 p = pp;
929 sigs = sigs->next;
932 if (!rc)
934 xfree (crypto->save.sigkey);
935 crypto->save.sigkey = str_dup (*p);
936 strv_free (p);
937 crypto_keyid_to_16b_once (crypto->save.sigkey);
938 crypto->cipher = cipher;
941 else if (!rc && crypto->flags & CRYPTO_FLAG_SYMMETRIC)
943 crypto->cipher = cipher;
945 else if (!rc)
947 if (!(crypto->flags & CRYPTO_FLAG_SYMMETRIC)
948 || (crypto->flags & CRYPTO_FLAG_SYMMETRIC && sigkeys))
949 rc = GPG_ERR_NO_SIGNATURE_SCHEME;
954 pthread_cleanup_pop (1); // free_gpgme_data_cb (plain)
955 pthread_cleanup_pop (1); // crypto_free_key_list (sigkeys)
958 pthread_cleanup_pop (0); // free_gpgme_data_cb (cipher)
959 pthread_cleanup_pop (1); // crypto_free_key_list (keys)
961 if (rc)
962 free_gpgme_data_cb (cipher);
964 return rc;
967 gpgme_error_t
968 crypto_passwd (struct client_s *client, struct crypto_s *crypto)
970 gpgme_error_t rc;
971 gpgme_key_t *keys = NULL;
973 /* Use SAVE instead for symmetric files. */
974 rc = crypto_is_symmetric (client->filename);
975 if (!rc || rc != GPG_ERR_BAD_DATA)
976 return !rc ? GPG_ERR_NOT_SUPPORTED : rc;
978 rc = crypto_list_keys (crypto, crypto->pubkey, 1, &keys);
979 if (rc)
980 return rc;
982 crypto->flags |= CRYPTO_FLAG_PASSWD;
983 pthread_cleanup_push ((void *)crypto_free_key_list, keys);
984 rc = send_status (client->ctx, STATUS_KEEPALIVE, NULL);
985 if (!rc)
986 MUTEX_TRYLOCK (client->ctx, &crypto_mutex, rc, client->lock_timeout);
988 if (!rc)
990 pthread_cleanup_push (release_mutex_cb, &crypto_mutex);
991 rc = gpgme_op_passwd_start (crypto->ctx, keys[0], 0);
992 if (!rc)
994 STATUS_TIMEOUT_INIT (crypto);
997 if (!rc && crypto->progress_rc)
998 rc = crypto->progress_rc;
999 if (!rc)
1000 STATUS_TIMEOUT_TEST (crypto, rc, STATUS_KEEPALIVE, NULL);
1001 TEST_CANCEL();
1002 } while (!rc && !gpgme_wait (crypto->ctx, &rc, 0) && !rc);
1004 pthread_cleanup_pop (1);
1007 pthread_cleanup_pop (1);
1008 return rc;
1011 /* Generate a new key pair. The resulting keyid's are stored in crypto->save.
1013 gpgme_error_t
1014 crypto_genkey (struct client_s *client, struct crypto_s *crypto)
1016 gpgme_error_t rc;
1018 rc = send_status (client ? client->ctx : NULL, STATUS_GENKEY, NULL);
1019 if (!rc)
1020 MUTEX_TRYLOCK ((client ? client->ctx : NULL), &crypto_mutex, rc,
1021 (client ? client->lock_timeout : 0));
1023 if (!rc)
1025 pthread_cleanup_push (release_mutex_cb, &crypto_mutex);
1026 if (crypto->save.mainkey)
1028 rc = gpgme_op_createsubkey_start (crypto->ctx,
1029 crypto->save.mainkey[0],
1030 crypto->save.algo,
1032 crypto->save.expire,
1033 crypto->save.flags);
1035 else
1037 rc = gpgme_op_createkey_start (crypto->ctx,
1038 crypto->save.userid,
1039 crypto->save.algo,
1041 crypto->save.expire,
1042 NULL,
1043 crypto->save.flags);
1046 if (!rc)
1048 STATUS_TIMEOUT_INIT (crypto);
1051 if (!rc && crypto->progress_rc)
1052 rc = crypto->progress_rc;
1053 if (!rc)
1054 STATUS_TIMEOUT_TEST (crypto, rc, STATUS_GENKEY, NULL);
1055 TEST_CANCEL();
1056 } while (!rc && !gpgme_wait (crypto->ctx, &rc, 0) && !rc);
1058 pthread_cleanup_pop (1);
1061 if (!rc)
1063 gpgme_key_t *keys = NULL;
1064 gpgme_genkey_result_t result;
1066 result = gpgme_op_genkey_result (crypto->ctx);
1067 xfree (crypto->save.sigkey);
1068 crypto->save.sigkey = str_dup (result->fpr);
1069 crypto_keyid_to_16b_once (crypto->save.sigkey);
1071 if (!rc)
1073 char **tmp = NULL;
1075 strv_printf (&tmp, "%s", crypto->save.sigkey);
1076 pthread_cleanup_push ((void *)strv_free, tmp);
1077 rc = crypto_list_keys (crypto, tmp, 1, &keys);
1078 pthread_cleanup_pop (1);
1081 if (!rc)
1083 gpgme_subkey_t key = keys[0]->subkeys;
1085 for (; key; key = key->next)
1087 if (key->can_encrypt)
1088 break;
1091 pthread_cleanup_push ((void *)crypto_free_key_list, keys);
1092 rc = send_status (client ? client->ctx : NULL, STATUS_GENKEY, "%s %s",
1093 crypto->save.sigkey, key ? key->fpr : "");
1094 if (!rc && key)
1096 crypto->save.pubkey = strv_cat (crypto->save.pubkey,
1097 str_dup (key->fpr));
1098 crypto_keyid_to_16b (crypto->save.pubkey);
1101 pthread_cleanup_pop (1);
1105 return rc;
1108 #ifdef WITH_LIBACL
1109 static void
1110 acl_free_cb (void *arg)
1112 acl_t acl = arg ? (acl_t) arg : NULL;
1114 if (acl)
1115 acl_free (acl);
1117 #endif
1119 /* The advisory lock should be obtained before calling this function. */
1120 gpg_error_t
1121 crypto_write_file (struct crypto_s *crypto, unsigned char **r_crc,
1122 size_t *r_crclen)
1124 unsigned char *buf;
1125 size_t size, len;
1126 int fd;
1127 gpg_error_t rc;
1128 char tmp[PATH_MAX];
1129 struct stat st;
1130 mode_t mode = 0600;
1131 #ifdef WITH_LIBACL
1132 acl_t acl = NULL;
1133 #endif
1135 if (crypto->filename)
1137 if (lstat (crypto->filename, &st) == 0)
1139 mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
1141 if (!(mode & S_IWUSR))
1142 return GPG_ERR_EACCES;
1144 else if (errno != ENOENT)
1145 return gpg_error_from_errno (errno);
1147 snprintf (tmp, sizeof (tmp), "%s.XXXXXX", crypto->filename);
1148 mode_t tmode = umask (0600);
1149 fd = mkstemp (tmp);
1150 if (fd == -1)
1152 rc = gpg_error_from_errno (errno);
1153 umask (tmode);
1154 log_write ("%s: %s", tmp, pwmd_strerror (rc));
1155 return rc;
1158 umask (tmode);
1160 else
1161 fd = STDOUT_FILENO;
1163 rc = crypto_data_to_buf (crypto->cipher, &buf, &size);
1164 if (rc)
1166 if (crypto->filename)
1167 close (fd);
1168 return rc;
1171 pthread_cleanup_push ((void *)close_fd_cb, &fd);
1172 if (r_crc)
1173 rc = get_checksum_memory (buf, size, r_crc, r_crclen);
1175 if (!rc)
1177 pthread_cleanup_push ((void *)xfree, buf);
1178 len = write (fd, buf, size);
1179 pthread_cleanup_pop (1);
1180 if (len != size)
1181 rc = gpg_error_from_errno (errno);
1184 if (!rc)
1186 if (fsync (fd) != -1)
1188 if (crypto->filename && close (fd) != -1)
1190 #ifdef WITH_LIBACL
1191 acl = acl_get_file (crypto->filename, ACL_TYPE_ACCESS);
1192 if (!acl && errno == ENOENT)
1193 acl = acl_get_file (".", ACL_TYPE_DEFAULT);
1194 if (!acl)
1195 log_write ("ACL: %s: %s", crypto->filename,
1196 pwmd_strerror (gpg_error_from_errno (errno)));
1197 pthread_cleanup_push ((void *)acl_free_cb, acl);
1198 #endif
1200 fd = -1;
1201 if (config_get_boolean (crypto->filename, "backup"))
1203 char tmp2[PATH_MAX];
1205 snprintf (tmp2, sizeof (tmp2), "%s.backup", crypto->filename);
1206 if (rename (crypto->filename, tmp2) == -1)
1207 if (errno != ENOENT)
1208 rc = gpg_error_from_errno (errno);
1211 if (!rc && rename (tmp, crypto->filename) == -1)
1212 rc = gpg_error_from_errno (errno);
1214 if (!rc)
1216 if (chmod (crypto->filename, mode) == -1)
1217 log_write ("%s(%u): %s", __FILE__, __LINE__,
1218 pwmd_strerror (gpg_error_from_syserror ()));
1220 #ifdef WITH_LIBACL
1221 if (!rc && acl && acl_set_file (crypto->filename,
1222 ACL_TYPE_ACCESS, acl))
1223 log_write ("ACL: %s: %s", crypto->filename,
1224 pwmd_strerror (gpg_error_from_errno (errno)));
1225 pthread_cleanup_pop (1);
1226 #endif
1228 else if (crypto->filename)
1229 rc = gpg_error_from_errno (errno);
1231 if (!rc && fd != -1)
1233 char *datadir = str_asprintf ("%s/data", homedir);
1235 if (datadir)
1237 int dfd = open (datadir, O_RDONLY);
1239 if (dfd != -1)
1241 if (fsync (dfd) == -1)
1242 log_write ("%s %d: %s", __FILE__, __LINE__,
1243 pwmd_strerror (errno));
1245 close (dfd);
1247 else
1248 log_write ("%s %d: %s", __FILE__, __LINE__,
1249 pwmd_strerror (errno));
1251 xfree (datadir);
1255 else
1256 rc = gpg_error_from_errno (errno);
1259 pthread_cleanup_pop (0); // close (fd)
1260 if (fd != -1)
1261 close (fd);
1263 return rc;
1266 char *
1267 crypto_key_info (const gpgme_key_t key)
1269 struct string_s *string = string_new (NULL), *s;
1270 char *line = NULL;
1271 unsigned n, u;
1272 gpgme_subkey_t subkey;
1273 gpgme_user_id_t uid;
1275 if (!string)
1276 return NULL;
1278 for (u = 0, uid = key->uids; uid; uid = uid->next)
1279 u++;
1281 for (n = 0, subkey = key->subkeys; subkey; subkey = subkey->next)
1282 n++;
1284 s = string_append_printf (string, "%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%i:%s:%s:%s:%i:%u:%u",
1285 key->revoked, key->expired, key->disabled,
1286 key->invalid, key->can_encrypt, key->can_sign,
1287 key->can_certify, key->secret,
1288 key->can_authenticate, key->is_qualified,
1289 key->protocol,
1290 key->issuer_serial ? key->issuer_serial : "",
1291 key->issuer_name ? key->issuer_name : "",
1292 key->chain_id ? key->chain_id : "",
1293 key->owner_trust, u, n);
1294 if (!s)
1296 string_free (string, 1);
1297 return NULL;
1300 string = s;
1301 for (subkey = key->subkeys; subkey; subkey = subkey->next)
1303 char *tmp;
1305 s = string_append_printf (string, ":%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%u:%i:%u",
1306 subkey->revoked, subkey->expired,
1307 subkey->disabled, subkey->invalid,
1308 subkey->can_encrypt, subkey->can_sign,
1309 subkey->can_certify, subkey->secret,
1310 subkey->can_authenticate, subkey->is_qualified,
1311 subkey->is_cardkey, subkey->pubkey_algo,
1312 subkey->length);
1313 if (!s)
1315 string_free (string, 1);
1316 return NULL;
1319 string = s;
1320 s = string_append_printf (string, ":%s:%s:%s:%li:%li:%s",
1321 subkey->keyid, subkey->fpr,
1322 subkey->keygrip ? subkey->keygrip : "",
1323 subkey->timestamp, subkey->expires,
1324 subkey->card_number ? subkey->card_number : "0");
1325 if (!s)
1327 string_free (string, 1);
1328 return NULL;
1331 string = s;
1332 tmp = gnupg_escape (subkey->curve);
1333 s = string_append_printf (string, ":%s", tmp ? tmp : "");
1334 xfree (tmp);
1335 if (!s)
1337 string_free (string, 1);
1338 return NULL;
1341 string = s;
1344 for (uid = key->uids; uid; uid = uid->next)
1346 char *userid, *name, *email, *comment;
1348 userid = gnupg_escape (uid->uid);
1349 name = gnupg_escape (uid->name);
1350 email = gnupg_escape (uid->email);
1351 comment = gnupg_escape (uid->comment);
1352 s = string_append_printf (string, ":%u:%u:%u:%s:%s:%s:%s",
1353 uid->revoked, uid->invalid, uid->validity,
1354 userid ? userid : "",
1355 name ? name : "",
1356 email ? email : "",
1357 comment ? comment : "");
1358 xfree (userid);
1359 xfree (name);
1360 xfree (email);
1361 xfree (comment);
1362 if (!s)
1364 string_free (string, 1);
1365 return NULL;
1368 string = s;
1371 line = string->str;
1372 string_free (string, 0);
1373 return line;
1376 gpg_error_t
1377 crypto_try_decrypt (struct client_s *client, int no_pinentry)
1379 struct crypto_s *crypto;
1380 gpg_error_t rc;
1381 char *keyfile = config_get_string (client->filename, "passphrase_file");
1383 rc = crypto_init (&crypto, client->ctx, client->filename, no_pinentry,
1384 keyfile);
1385 if (!rc)
1387 pthread_cleanup_push ((void *)crypto_free, crypto);
1388 rc = crypto_decrypt (client, crypto);
1389 pthread_cleanup_pop (1);
1391 else
1392 xfree (keyfile);
1394 return rc;
1397 /* The advisory lock should be obtained before calling this function. */
1398 gpg_error_t
1399 crypto_is_symmetric (const char *filename)
1401 int fd;
1402 uint8_t magic[2];
1403 ssize_t len;
1404 gpg_error_t rc;
1406 rc = open_check_file (filename, &fd, NULL, 1);
1407 if (rc)
1408 return rc;
1410 len = read (fd, &magic, sizeof(magic));
1411 close (fd);
1412 if (len != sizeof (magic))
1413 return GPG_ERR_INV_VALUE;
1415 // Always read as big endian.
1416 if (magic[0] != 0x8c || magic[1] != 0x0d)
1417 return GPG_ERR_BAD_DATA;
1419 return 0;
1422 gpg_error_t
1423 crypto_delete_key (struct client_s *client, struct crypto_s *crypto,
1424 const gpgme_key_t key, int secret)
1426 gpg_error_t rc;
1428 STATUS_TIMEOUT_INIT (crypto);
1429 rc = send_status (client->ctx, STATUS_DECRYPT, NULL);
1430 if (!rc)
1431 rc = gpgme_op_delete_start (crypto->ctx, key, secret);
1433 if (rc)
1434 return rc;
1438 if (!rc && crypto->progress_rc)
1439 rc = crypto->progress_rc;
1441 if (!rc)
1442 STATUS_TIMEOUT_TEST (crypto, rc, STATUS_DECRYPT, NULL);
1444 if (rc)
1445 break;
1446 } while (!gpgme_wait (crypto->ctx, &rc, 0) && !rc);
1448 return rc;