tls: Disable TLS1.1 and CBC cipher suites by default.
[pwmd.git] / src / cache.c
blob7305fe49f554a7e69e3d0d6ae0b71ad8cc7d0396
1 /*
2 Copyright (C) 2006-2019 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
11 Pwmd is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <pthread.h>
26 #include <ctype.h>
27 #include <errno.h>
29 #include "pwmd-error.h"
30 #include <gcrypt.h>
31 #include "mutex.h"
32 #include "cache.h"
33 #include "status.h"
34 #include "mem.h"
35 #include "util-misc.h"
36 #include "util-string.h"
37 #include "agent.h"
38 #include "acl.h"
40 #ifdef HAVE_TIME_H
41 #include <time.h>
42 #endif
44 struct plaintext_s
46 xmlDocPtr plaintext;
47 unsigned refcount;
48 char *filename;
49 int modified;
52 static pthread_mutex_t cache_mutex;
53 static struct slist_s *key_cache;
54 static struct slist_s *plaintext_list;
55 static unsigned char *cache_iv;
56 static unsigned char *cache_key;
57 static size_t cache_blocksize;
58 static size_t cache_keysize;
59 static struct agent_s *cache_agent;
60 static int exiting;
62 void log_write (const char *fmt, ...);
64 static gpg_error_t clear_once (file_cache_t * p, int agent, int force);
65 static int remove_entry (const char *);
66 static void free_entry (file_cache_t * p, int agent);
68 static file_cache_t *
69 get_entry (const char *filename)
71 int t = slist_length (key_cache);
72 int i;
74 if (!filename)
75 return NULL;
77 for (i = 0; i < t; i++)
79 file_cache_t *p = slist_nth_data (key_cache, i);
81 if (!strcmp (p->filename, filename))
82 return p;
85 return NULL;
88 gpg_error_t
89 cache_lock_mutex (void *ctx, const char *filename, long lock_timeout, int add,
90 long timeout)
92 MUTEX_LOCK (&cache_mutex);
93 gpg_error_t rc = 0;
94 file_cache_t *p = get_entry (filename);
96 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
98 if (p)
100 MUTEX_UNLOCK (&cache_mutex);
101 MUTEX_TRYLOCK (ctx, p->mutex, rc, lock_timeout);
102 p->flags |= CACHE_FLAG_LOCKED;
104 else if (add)
106 rc = cache_add_file (filename, NULL, timeout);
107 if (!rc)
109 p = get_entry (filename);
110 MUTEX_UNLOCK (&cache_mutex);
111 if (p)
113 MUTEX_TRYLOCK (ctx, p->mutex, rc, lock_timeout);
114 p->flags |= CACHE_FLAG_LOCKED;
117 else
119 MUTEX_UNLOCK (&cache_mutex);
122 else
124 MUTEX_UNLOCK (&cache_mutex);
127 pthread_cleanup_pop (0);
128 return !p && !rc ? GPG_ERR_NO_DATA : rc;
131 static int
132 remove_entry (const char *filename)
134 MUTEX_LOCK (&cache_mutex);
135 file_cache_t *p = get_entry (filename);
137 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
138 if (p)
140 /* Keep a refcount because another client maybe editing this same new
141 * file. The entry needs to be kept in case the other client SAVE's.
143 p->refcount--;
144 if (!p->refcount)
145 free_entry (p, 0);
148 pthread_cleanup_pop (1);
149 return p ? 1 : 0;
152 static gpg_error_t
153 free_cache_data (file_cache_t *cache, int force)
155 gpg_error_t rc = GPG_ERR_NO_DATA;
156 int i, t;
157 struct client_thread_s *found = NULL;
158 int self = 0;
160 if (!cache->data)
161 return 0;
163 MUTEX_LOCK (&cn_mutex);
164 t = slist_length (cn_thread_list);
166 /* Prevent clearing the cache entry when there are any connected clients
167 * using this cache entry to prevent clearing the plaintext which would cause
168 * cache_plaintext_set() to return GPG_ERR_NO_DATA and prevent CoW commands
169 * from working. */
170 for (i = 0; i < t; i++)
172 struct client_thread_s *thd = slist_nth_data (cn_thread_list, i);
174 if (!thd->cl)
175 continue;
177 if (thd->cl->filename && !strcmp (thd->cl->filename, cache->filename)
178 && !force)
180 cache->defer_clear = 1;
181 MUTEX_UNLOCK (&cn_mutex);
182 return 0;
186 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
187 MUTEX_LOCK (&cache_mutex);
188 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
190 for (i = 0; i < t; i++)
192 struct client_thread_s *thd = slist_nth_data (cn_thread_list, i);
194 if (!thd->cl)
195 continue;
197 self = pthread_equal (pthread_self (), thd->tid);
199 if (thd->cl->filename && !strcmp (thd->cl->filename, cache->filename))
201 if (self)
203 found = thd;
204 continue;
207 /* Continue trying to find a client who has the same file open and
208 * also has a lock. */
209 rc = cache_lock_mutex (thd->cl->ctx, thd->cl->filename, -1, 0, -1);
210 if (!rc)
212 found = thd;
213 break;
218 if (self && (!rc || rc == GPG_ERR_NO_DATA) && found)
219 rc = cache_lock_mutex (found->cl->ctx, found->cl->filename, -1, 0, -1);
221 if (exiting || !rc || rc == GPG_ERR_NO_DATA)
223 cache_free_data_once (cache->data);
224 cache->data = NULL;
225 cache->defer_clear = 0;
226 cache->timeout = (long)-1;
228 if (found)
229 cache_unlock_mutex (found->cl->filename, 0);
231 rc = 0;
234 if (rc)
235 cache->defer_clear = 1;
237 pthread_cleanup_pop (1);
238 pthread_cleanup_pop (1);
239 return rc;
242 gpg_error_t
243 cache_unlock_mutex (const char *filename, int remove)
245 MUTEX_LOCK (&cache_mutex);
246 file_cache_t *p = get_entry (filename);
248 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
250 if (p)
252 MUTEX_UNLOCK (p->mutex);
253 p->flags &= ~CACHE_FLAG_LOCKED;
254 if (remove)
255 remove_entry (filename);
258 pthread_cleanup_pop (1);
259 return p ? 0 : GPG_ERR_NO_DATA;
262 static gpg_error_t
263 get_keyinfo (const char *grip, char ***r_fields)
265 gpg_error_t rc;
266 char *line;
268 rc = agent_command (cache_agent, &line, NULL, "KEYINFO --data %s", grip);
269 if (rc)
270 return rc;
272 *r_fields = str_split (line, " ", 0);
273 xfree (line);
274 return !(*r_fields) ? GPG_ERR_ENOMEM : rc;
277 gpg_error_t
278 cache_is_shadowed (const char *filename)
280 MUTEX_LOCK (&cache_mutex);
281 file_cache_t *f = get_entry (filename);
282 char **p;
283 char **fields = NULL;
284 gpg_error_t rc = GPG_ERR_NO_DATA, trc;
286 if (!f)
287 return GPG_ERR_NOT_FOUND;
289 for (p = f->grip; p && *p; p++)
291 trc = get_keyinfo (*p, &fields);
292 if (!trc && *fields[1] == 'T')
294 rc = 0;
295 break;
297 else if (trc)
299 rc = trc;
300 break;
304 strv_free (fields);
305 fields = NULL;
307 if (rc == GPG_ERR_NO_DATA && f->siggrip)
309 trc = get_keyinfo (f->siggrip, &fields);
310 if (!trc && *fields[1] == 'T')
311 rc = 0;
312 else if (trc)
313 rc = trc;
316 strv_free (fields);
317 MUTEX_UNLOCK (&cache_mutex);
318 return rc;
321 static gpg_error_t
322 test_agent_cache_once (file_cache_t *p, const char *grip)
324 gpg_error_t rc;
325 char **fields = NULL;
327 (void)p;
328 rc = get_keyinfo (grip, &fields);
329 if (rc)
330 return rc;
332 /* Smartcard. */
333 if (*fields[1] == 'T')
334 rc = GPG_ERR_NO_DATA;
335 else
336 rc = isdigit (*fields[4]) || *fields[5] == 'C' ? 0 : GPG_ERR_NO_DATA;
338 strv_free (fields);
339 return rc;
342 /* Test each keygrip in data->(sig)grip for gpg-agent cache status. The file is
343 * considered cached if at least one grip is cached in the agent or one siggrip
344 * is cached in the case of 'sign'.
346 static gpg_error_t
347 test_agent_cache (file_cache_t *data, int sign)
349 gpg_error_t rc = 0;
350 char **p;
352 if ((!data->grip && !sign) || (!data->siggrip && sign))
353 return GPG_ERR_NO_DATA;
355 for (p = data->grip; !sign && p && *p; p++)
357 rc = test_agent_cache_once (data, *p);
358 if (!rc || rc != GPG_ERR_NO_DATA)
359 break;
362 if (!rc && sign)
363 rc = test_agent_cache_once (data, data->siggrip);
365 return rc;
368 static gpg_error_t
369 extract_keygrip_once (struct crypto_s *crypto, char **keyids, int sign,
370 char ***dst)
372 gpgme_key_t *result;
373 gpgme_error_t rc;
374 int i;
375 char **grips = NULL;
377 rc = crypto_list_keys (crypto, keyids, sign, &result);
378 if (rc)
379 return rc;
381 for (i = 0; result[i]; i++)
383 gpgme_subkey_t s;
385 for (s = result[i]->subkeys; s; s = s->next)
387 char **k;
389 if (sign && !s->can_sign)
390 continue;
392 for (k = keyids; *k; k++)
394 if (!strcmp (*k, s->keyid) && s->keygrip)
396 char **tmp;
397 size_t len = strv_length (grips);
399 tmp = xrealloc (grips, len+2 * sizeof (char *));
400 if (!tmp)
402 rc = GPG_ERR_ENOMEM;
403 break;
406 grips = tmp;
407 grips[len] = str_dup (s->keygrip);
408 if (!grips[len])
410 rc = GPG_ERR_ENOMEM;
411 break;
414 grips[++len] = NULL;
420 if (!rc)
422 strv_free (*dst);
423 *dst = grips;
425 else
427 strv_free (grips);
428 grips = NULL;
431 crypto_free_key_list (result);
432 return rc ? rc : grips ? rc : GPG_ERR_NO_DATA;
435 static gpg_error_t
436 extract_keygrips (file_cache_t *data)
438 gpg_error_t rc = 0;
439 struct crypto_s *crypto;
440 char **grips = NULL, **siggrips = NULL;
442 if (!data || !data->data)
443 return 0;
445 rc = crypto_init (&crypto, NULL, NULL, 0, NULL);
446 if (rc)
447 return rc;
449 pthread_cleanup_push ((void *)crypto_free, crypto);
451 if (data->data->pubkey)
452 rc = extract_keygrip_once (crypto, data->data->pubkey, 0, &grips);
454 if (!rc && data->data->sigkey)
456 char **tmp = NULL;
458 strv_printf (&tmp, "%s", data->data->sigkey);
459 rc = extract_keygrip_once (crypto, tmp, 1, &siggrips);
460 strv_free (tmp);
463 if (!rc)
465 strv_free (data->grip);
466 data->grip = grips;
467 xfree (data->siggrip);
468 data->siggrip = NULL;
469 if (siggrips && *siggrips)
470 data->siggrip = str_dup (*siggrips);
471 strv_free (siggrips);
473 else
475 strv_free (grips);
476 strv_free (siggrips);
479 pthread_cleanup_pop (1);
480 return rc;
483 static gpg_error_t
484 iscached (const char *filename, int *defer, int agent, int sign)
486 file_cache_t *p = get_entry (filename);
487 gpg_error_t rc = 0;
489 if (!agent)
491 if (!p || !p->data)
492 return GPG_ERR_NO_DATA;
494 if (defer)
495 *defer = p->defer_clear;
497 return 0;
500 if (!p)
501 return GPG_ERR_NO_DATA;
503 if (defer)
504 *defer = p->defer_clear;
506 if (!rc && (p->grip || p->siggrip))
507 rc = test_agent_cache (p, sign);
508 else if (!rc)
509 rc = GPG_ERR_NO_DATA;
511 return rc;
514 unsigned
515 cache_file_count ()
517 MUTEX_LOCK (&cache_mutex);
518 unsigned total = 0, i, n;
520 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
521 n = slist_length (key_cache);
522 for (i = 0; i < n; i++)
524 file_cache_t *p = slist_nth_data (key_cache, i);
526 if (!iscached (p->filename, NULL, 0, 0))
527 total++;
530 pthread_cleanup_pop (1);
531 return total;
534 void
535 cache_adjust_timeout ()
537 MUTEX_LOCK (&cache_mutex);
538 int t = slist_length (key_cache);
539 int i;
541 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
543 for (i = 0; i < t; i++)
545 file_cache_t *p = slist_nth_data (key_cache, i);
547 if (p->timeout > 0)
548 p->timeout--;
550 /* Test the cache entry timeout for expiration and also whether the file
551 * is a new one (no crc) and without any associated clients (refcount ==
552 * 1) and remove the cache entry accordingly. */
553 if (!p->timeout || (p->defer_clear && p->timeout != (long)-1)
554 || (p->timeout > 0 && p->refcount == 1
555 && (!p->data || !p->data->crc)
556 && !(p->flags & CACHE_FLAG_LOCKED)))
558 /* The file associated with this cache entry may be locked by a
559 * client. Defer freeing this cache entry until the next timeout
560 * check. */
561 gpg_error_t rc = clear_once (p, 1, 0);
563 if (!rc && !p->defer_clear)
565 free_entry (p, 0);
566 t = slist_length (key_cache);
567 send_status_all (STATUS_CACHE, NULL);
572 pthread_cleanup_pop (1);
575 static gpg_error_t
576 set_timeout (const char *filename, long timeout, int defer, int force)
578 MUTEX_LOCK (&cache_mutex);
579 file_cache_t *p = get_entry (filename);
580 gpg_error_t rc = 0;
582 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
584 if (p)
586 p->reset = timeout;
587 if (!p->defer_clear && (p->timeout == -1 || force))
588 p->timeout = timeout;
590 if (!timeout || defer)
592 rc = clear_once (p, 1, 0);
593 if (!rc)
594 send_status_all (STATUS_CACHE, NULL);
597 else
598 rc = GPG_ERR_NOT_FOUND;
600 pthread_cleanup_pop (1);
601 return rc;
604 gpg_error_t
605 cache_set_data (const char *filename, struct cache_data_s *data)
607 MUTEX_LOCK (&cache_mutex);
608 gpg_error_t rc = GPG_ERR_NO_DATA;
609 file_cache_t *p = get_entry (filename);
611 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
613 if (p)
615 xfree (data->filename);
616 data->filename = NULL;
617 if (p->filename)
618 data->filename = str_dup (p->filename);
620 p->data = data;
621 rc = set_timeout (filename, p->reset, p->defer_clear, 0);
622 if (!rc && !p->reset)
624 clear_once (p, 0, 0);
625 send_status_all (STATUS_CACHE, NULL);
627 else if (!rc)
628 rc = extract_keygrips (p);
631 pthread_cleanup_pop (1);
632 return p && !rc ? 0 : rc;
635 struct cache_data_s *
636 cache_get_data (const char *filename, int *defer)
638 MUTEX_LOCK (&cache_mutex);
639 file_cache_t *p = get_entry (filename);
641 if (defer && p)
642 *defer = p->defer_clear;
643 MUTEX_UNLOCK (&cache_mutex);
644 return p ? p->data : NULL;
647 gpg_error_t
648 cache_add_file (const char *filename, struct cache_data_s *data, long timeout)
650 MUTEX_LOCK (&cache_mutex);
651 file_cache_t *p = get_entry (filename);
652 struct slist_s *new;
653 gpg_error_t rc = 0;
655 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
657 if (p)
659 if (data)
661 char *str = p->filename ? str_dup (p->filename) : NULL;
663 if (p->filename && !str)
664 rc = GPG_ERR_ENOMEM;
665 else
667 xfree (data->filename);
668 data->filename = str;
672 if (!rc)
674 p->data = data;
675 p->refcount++;
676 rc = set_timeout (filename, timeout, p->defer_clear, 0);
679 else
681 p = xcalloc (1, sizeof (file_cache_t));
682 if (p)
684 p->mutex = (pthread_mutex_t *) xmalloc (sizeof (pthread_mutex_t));
685 if (p->mutex)
687 pthread_mutexattr_t attr;
688 pthread_mutexattr_init (&attr);
689 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
690 pthread_mutex_init (p->mutex, &attr);
691 pthread_mutexattr_destroy (&attr);
692 p->filename = str_dup (filename);
694 if (data)
696 xfree (data->filename);
697 data->filename = NULL;
698 data->filename = str_dup (p->filename);
701 p->data = data;
702 p->refcount++;
703 new = slist_append (key_cache, p);
704 if (new)
706 key_cache = new;
707 rc = cache_set_timeout(filename, timeout);
709 else
711 pthread_mutex_destroy (p->mutex);
712 xfree (p->mutex);
713 xfree (p->filename);
714 xfree (p);
715 p = NULL;
716 rc = GPG_ERR_ENOMEM;
719 else
721 xfree (p);
722 p = NULL;
723 rc = GPG_ERR_ENOMEM;
726 else
727 rc = GPG_ERR_ENOMEM;
730 if (!rc)
731 rc = extract_keygrips (p);
733 pthread_cleanup_pop (1);
735 if (!rc)
736 send_status_all (STATUS_CACHE, NULL);
738 return rc;
741 gpg_error_t
742 cache_clear_agent_keys (const char *filename, int decrypt, int sign)
744 MUTEX_LOCK (&cache_mutex);
745 gpg_error_t rc = 0;
746 char **key;
747 file_cache_t *p = get_entry (filename);
749 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
751 if (p)
753 for (key = p->grip; decrypt && key && *key; key++)
755 rc = agent_command (cache_agent, NULL, NULL,
756 "CLEAR_PASSPHRASE --mode=normal %s", *key);
757 if (rc)
758 break;
761 if (p->siggrip && sign)
762 rc = agent_command (cache_agent, NULL, NULL,
763 "CLEAR_PASSPHRASE --mode=normal %s", p->siggrip);
765 else
766 rc = GPG_ERR_NOT_FOUND;
768 pthread_cleanup_pop (1);
769 return rc;
772 static gpg_error_t
773 clear_once (file_cache_t *p, int agent, int force)
775 gpg_error_t rc = 0, trc;
777 if (agent)
778 rc = cache_clear_agent_keys (p->filename, 1, 1);
780 trc = free_cache_data (p, force);
781 return rc ? rc : trc;
784 static void
785 free_entry (file_cache_t *p, int agent)
787 gpg_error_t rc;
789 if (!p)
790 return;
792 rc = clear_once (p, agent, 0);
793 if (rc)
794 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
796 if (p->mutex)
798 pthread_mutex_destroy (p->mutex);
799 xfree (p->mutex);
802 strv_free (p->grip);
803 xfree (p->siggrip);
804 xfree (p->filename);
805 key_cache = slist_remove (key_cache, p);
806 xfree (p);
809 gpg_error_t
810 cache_clear (struct client_s *client, const char *filename, int agent,
811 int force)
813 file_cache_t *p;
814 gpg_error_t rc = 0, all_rc = 0;
815 int i, t;
817 MUTEX_LOCK (&cache_mutex);
818 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
820 if (filename)
822 p = get_entry (filename);
823 if (p)
825 rc = clear_once (p, agent, force);
826 if (rc)
827 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
830 else
832 t = slist_length (key_cache);
833 for (i = 0; i < t; i++)
835 p = slist_nth_data (key_cache, i);
837 if (client)
839 assuan_peercred_t peer;
840 int n = client->no_access_param;
842 client->no_access_param = 1;
843 rc = do_validate_peer (client->ctx, p->filename, &peer);
844 client->no_access_param = n;
845 if (rc == GPG_ERR_FORBIDDEN)
846 rc = peer_is_invoker (client);
848 if (rc)
850 all_rc = !all_rc ? rc : all_rc;
851 continue;
855 clear_once (p, agent, 0);
859 pthread_cleanup_pop (1);
860 return filename ? rc : all_rc;
863 gpg_error_t
864 cache_iscached (const char *filename, int *defer, int agent, int sign)
866 gpg_error_t rc;
868 if (!filename)
869 return GPG_ERR_INV_PARAMETER;
871 MUTEX_LOCK (&cache_mutex);
872 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
873 rc = iscached (filename, defer, agent, sign);
875 /* Test if the data file disappeared from the filesystem. */
876 if ((!rc || gpg_err_code (rc) == GPG_ERR_NO_DATA)
877 && access (filename, R_OK) == -1)
879 rc = gpg_error_from_errno (errno);
880 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
882 /* Fixes clearing the cache entry that was created during OPEN when
883 * SAVE'ing a new file. */
884 if ((defer && *defer == 1) || !defer)
886 rc = cache_defer_clear (filename);
887 if (!rc && defer)
888 *defer = 1;
891 rc = GPG_ERR_ENOENT;
895 pthread_cleanup_pop (1);
896 return rc;
899 gpg_error_t
900 cache_defer_clear (const char *filename)
902 MUTEX_LOCK (&cache_mutex);
903 file_cache_t *p = get_entry (filename);
904 gpg_error_t rc = 0;
906 if (!p)
907 rc = GPG_ERR_NOT_FOUND;
908 else
909 p->defer_clear = 1;
911 MUTEX_UNLOCK (&cache_mutex);
912 return rc;
915 gpg_error_t
916 cache_set_timeout (const char *filename, long timeout)
918 return set_timeout (filename, timeout, 0, 1);
921 void
922 cache_deinit ()
924 exiting = 1;
925 MUTEX_LOCK (&cache_mutex);
926 int i, t = slist_length (key_cache);
928 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
929 for (i = 0; i < t; i++)
931 file_cache_t *p = slist_nth_data (key_cache, i);
933 free_entry (p, 1);
934 t = slist_length (key_cache);
935 i = -1;
938 gcry_free (cache_key);
939 xfree (cache_iv);
940 cache_key = NULL;
941 cache_iv = NULL;
942 agent_free (cache_agent);
943 cache_agent = NULL;
944 pthread_cleanup_pop (1);
945 pthread_mutex_destroy (&cache_mutex);
948 void
949 cache_mutex_init ()
951 pthread_mutexattr_t attr;
953 pthread_mutexattr_init (&attr);
954 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
955 pthread_mutex_init (&cache_mutex, &attr);
956 pthread_mutexattr_destroy (&attr);
959 gpg_error_t
960 cache_init ()
962 gpg_error_t rc = 0;
964 rc = agent_init (&cache_agent);
965 if (rc)
967 cache_agent = NULL;
968 return rc;
971 if (!cache_key)
973 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_BLKLEN, NULL,
974 &cache_blocksize);
975 if (rc)
976 return rc;
978 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_KEYLEN, NULL,
979 &cache_keysize);
980 if (rc)
981 return rc;
983 cache_key = gcry_malloc (cache_keysize);
984 if (!cache_key)
985 return GPG_ERR_ENOMEM;
987 cache_iv = xmalloc (cache_blocksize);
988 if (!cache_iv)
990 gcry_free (cache_key);
991 cache_key = NULL;
992 return GPG_ERR_ENOMEM;
995 gcry_create_nonce (cache_key, cache_keysize);
996 gcry_create_nonce (cache_iv, cache_blocksize);
1000 cache_mutex_init ();
1001 return rc;
1004 void
1005 cache_lock ()
1007 MUTEX_LOCK (&cache_mutex);
1010 void
1011 cache_unlock ()
1013 MUTEX_UNLOCK (&cache_mutex);
1016 static void
1017 update_plaintext_pointer (xmlDocPtr plaintext)
1019 unsigned i;
1020 unsigned t;
1022 t = slist_length (key_cache);
1023 for (i = 0; i < t; i++)
1025 file_cache_t *p = slist_nth_data (key_cache, i);
1027 if (p->data && p->data->plaintext == plaintext)
1028 p->data->plaintext = NULL;
1032 void
1033 cache_free_data_once (struct cache_data_s *data)
1035 if (!data)
1036 return;
1038 xfree (data->filename);
1039 strv_free (data->pubkey);
1040 xfree (data->sigkey);
1041 xfree (data->crc);
1042 xfree (data->doc);
1043 xfree (data);
1046 static void
1047 release_cipher (void *arg)
1049 gcry_cipher_close ((gcry_cipher_hd_t) arg);
1052 gpg_error_t
1053 cache_encrypt (struct crypto_s *crypto)
1055 gpg_error_t rc;
1056 gcry_cipher_hd_t h;
1057 size_t len = crypto->plaintext_size;
1059 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
1060 if (rc)
1061 return rc;
1063 if (len % cache_blocksize)
1065 unsigned char *p;
1067 len += cache_blocksize - (len % cache_blocksize);
1068 p = xrealloc (crypto->plaintext, len * sizeof (unsigned char));
1069 if (!p)
1071 gcry_cipher_close (h);
1072 return GPG_ERR_ENOMEM;
1075 crypto->plaintext = p;
1076 memset (&crypto->plaintext[crypto->plaintext_size], 0,
1077 len - crypto->plaintext_size);
1080 pthread_cleanup_push (release_cipher, h);
1081 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
1082 if (!rc)
1084 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
1085 if (!rc)
1087 unsigned char *buf = xmalloc (len);
1089 pthread_cleanup_push (xfree, buf);
1091 if (!buf)
1092 rc = GPG_ERR_ENOMEM;
1094 if (!rc)
1096 rc = gcry_cipher_encrypt (h, buf, len, crypto->plaintext, len);
1097 if (!rc)
1099 xfree (crypto->plaintext);
1100 crypto->plaintext = buf;
1101 crypto->plaintext_size = len;
1105 pthread_cleanup_pop (rc != 0);
1109 pthread_cleanup_pop (1);
1110 return rc;
1113 gpg_error_t
1114 cache_decrypt (struct crypto_s *crypto)
1116 gcry_cipher_hd_t h = NULL;
1117 gpg_error_t rc;
1119 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
1120 if (rc)
1121 return rc;
1123 if (!rc)
1124 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
1126 if (!rc)
1127 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
1129 pthread_cleanup_push (release_cipher, h);
1131 if (!rc)
1133 rc = gcry_cipher_decrypt (h, crypto->plaintext, crypto->plaintext_size,
1134 NULL, 0);
1135 if (rc || strncmp ((char *)crypto->plaintext, "<?xml ", 6))
1137 if (!rc)
1138 rc = GPG_ERR_BAD_DATA;
1142 pthread_cleanup_pop (1);
1143 return rc;
1146 gpg_error_t
1147 cache_kill_scd ()
1149 gpg_error_t rc;
1151 MUTEX_LOCK (&cache_mutex);
1152 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1153 rc = agent_kill_scd (cache_agent);
1154 pthread_cleanup_pop (1);
1155 return rc;
1158 gpg_error_t
1159 cache_agent_command (const char *cmd)
1161 gpg_error_t rc;
1163 MUTEX_LOCK (&cache_mutex);
1164 rc = agent_command (cache_agent, NULL, NULL, "%s", cmd);
1165 MUTEX_UNLOCK (&cache_mutex);
1166 return rc;
1169 void
1170 cache_release_mutex ()
1172 MUTEX_UNLOCK (&cache_mutex);
1175 static gpg_error_t
1176 plaintext_get (struct cache_data_s *data, xmlDocPtr *r_doc)
1178 unsigned i;
1179 unsigned t = slist_length (plaintext_list);
1181 assert (r_doc != NULL);
1183 for (i = 0; i < t; i++)
1185 struct plaintext_s *p = slist_nth_data (plaintext_list, i);
1187 if (!strcmp (p->filename, data->filename) && !p->modified)
1189 *r_doc = p->plaintext;
1190 p->refcount++;
1191 return 0;
1195 return GPG_ERR_NO_DATA;
1198 gpg_error_t
1199 cache_plaintext_get (const char *filename, xmlDocPtr *r_doc)
1201 file_cache_t *p;
1202 gpg_error_t rc = 0;
1204 MUTEX_LOCK (&cache_mutex);
1205 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1207 p = get_entry (filename);
1208 if (p && p->data)
1209 rc = plaintext_get (p->data, r_doc);
1210 else
1211 rc = GPG_ERR_NO_DATA;
1213 pthread_cleanup_pop (1);
1214 return rc;
1217 static gpg_error_t
1218 release_plaintext (xmlDocPtr *plaintext)
1220 unsigned i;
1221 unsigned t;
1223 if (!plaintext)
1224 return GPG_ERR_NO_DATA;
1226 t = slist_length (plaintext_list);
1227 for (i = 0; i < t; i++)
1229 struct plaintext_s *p = slist_nth_data (plaintext_list, i);
1231 if (p->plaintext == *plaintext)
1233 assert (p->refcount > 0);
1234 if (--p->refcount == 0)
1236 xmlFreeDoc (p->plaintext);
1237 xfree (p->filename);
1238 plaintext_list = slist_remove (plaintext_list, p);
1239 xfree (p);
1240 update_plaintext_pointer (*plaintext);
1241 *plaintext = NULL;
1244 return 0;
1248 return GPG_ERR_NO_DATA;
1251 gpg_error_t
1252 cache_plaintext_release (xmlDocPtr *plaintext)
1254 gpg_error_t rc = 0;
1256 MUTEX_LOCK (&cache_mutex);
1257 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1258 rc = release_plaintext (plaintext);
1259 pthread_cleanup_pop (1);
1260 return rc;
1263 gpg_error_t
1264 cache_plaintext_set (const char *filename, xmlDocPtr doc, int modified)
1266 file_cache_t *p;
1267 gpg_error_t rc = 0;
1269 MUTEX_LOCK (&cache_mutex);
1270 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1272 p = get_entry (filename);
1273 if (p && p->data)
1275 struct plaintext_s *s = xcalloc (1, sizeof (struct plaintext_s));
1277 if (s)
1279 s->filename = str_dup (p->data->filename);
1280 if (s->filename)
1282 struct slist_s *l;
1283 int i, t = slist_length (plaintext_list);
1285 /* Prevent cache_plaintext_get() from returning the other
1286 * client's document copy. */
1287 for (i = 0; i < t; i++)
1289 struct plaintext_s *x = slist_nth_data (plaintext_list, i);
1291 if (!strcmp (s->filename, x->filename))
1292 x->modified = 1;
1295 l = slist_append (plaintext_list, s);
1296 if (l)
1298 plaintext_list = l;
1299 s->plaintext = p->data->plaintext = doc;
1300 s->modified = modified;
1301 s->refcount = 1;
1303 else
1305 xfree (s->filename);
1306 rc = GPG_ERR_ENOMEM;
1309 else
1310 rc = GPG_ERR_ENOMEM;
1312 if (rc)
1313 xfree (s);
1315 else
1316 rc = GPG_ERR_ENOMEM;
1318 else
1319 rc = GPG_ERR_NO_DATA;
1321 pthread_cleanup_pop (1);
1322 return rc;