Fix cancellation of gpgme without pthread_cancel.
[libpwmd.git] / src / cache.c
blob14538f94a5be392abeb1fd1a8402c77d25133736
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 <unistd.h>
27 #include <pthread.h>
28 #include <ctype.h>
29 #include <errno.h>
31 #include "pwmd-error.h"
32 #include <gcrypt.h>
33 #include "mutex.h"
34 #include "cache.h"
35 #include "status.h"
36 #include "mem.h"
37 #include "util-misc.h"
38 #include "util-string.h"
39 #include "agent.h"
41 #ifdef HAVE_TIME_H
42 #include <time.h>
43 #endif
45 static pthread_mutex_t cache_mutex;
46 static struct slist_s *key_cache;
47 static unsigned char *cache_iv;
48 static unsigned char *cache_key;
49 static size_t cache_blocksize;
50 static size_t cache_keysize;
51 struct agent_s *cache_agent;
53 extern void log_write (const char *fmt, ...);
55 static gpg_error_t clear_once (file_cache_t * p, int agent);
56 static int remove_entry (const char *);
57 static void free_entry (file_cache_t * p, int agent);
59 static file_cache_t *
60 get_entry (const char *filename)
62 int t = slist_length (key_cache);
63 int i;
65 if (!filename)
66 return NULL;
68 for (i = 0; i < t; i++)
70 file_cache_t *p = slist_nth_data (key_cache, i);
72 if (!strcmp (p->filename, filename))
73 return p;
76 return NULL;
79 gpg_error_t
80 cache_lock_mutex (void *ctx, const char *filename, long lock_timeout, int add,
81 int timeout)
83 MUTEX_LOCK (&cache_mutex);
84 gpg_error_t rc = 0;
85 file_cache_t *p = get_entry (filename);
87 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
89 if (p)
91 MUTEX_UNLOCK (&cache_mutex);
92 MUTEX_TRYLOCK (ctx, p->mutex, rc, lock_timeout);
94 else if (add)
96 rc = cache_add_file (filename, NULL, timeout);
97 if (!rc)
99 p = get_entry (filename);
100 MUTEX_UNLOCK (&cache_mutex);
101 MUTEX_TRYLOCK (ctx, p->mutex, rc, lock_timeout);
103 else
105 MUTEX_UNLOCK (&cache_mutex);
108 else
110 MUTEX_UNLOCK (&cache_mutex);
113 pthread_cleanup_pop (0);
114 return !p && !rc ? GPG_ERR_NO_DATA : rc;
117 static int
118 remove_entry (const char *filename)
120 MUTEX_LOCK (&cache_mutex);
121 file_cache_t *p = get_entry (filename);
123 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
124 if (p)
126 /* Keep a refcount because another client maybe editing this same new
127 * file. The entry needs to be kept in case the other client SAVE's.
129 p->refcount--;
130 if (!p->refcount)
131 free_entry (p, 0);
134 pthread_cleanup_pop (1);
135 return p ? 1 : 0;
138 static gpg_error_t
139 free_cache_data (file_cache_t * cache)
141 gpg_error_t rc = GPG_ERR_NO_DATA;
142 int i, t;
143 struct client_thread_s *found = NULL;
144 int self = 0;
146 if (!cache->data)
147 return 0;
149 MUTEX_LOCK (&cache_mutex);
150 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
151 MUTEX_LOCK (&cn_mutex);
152 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
154 t = slist_length (cn_thread_list);
155 for (i = 0; i < t; i++)
157 struct client_thread_s *thd = slist_nth_data (cn_thread_list, i);
159 if (!thd->cl)
160 continue;
162 self = pthread_equal (pthread_self (), thd->tid);
164 if (thd->cl->filename && !strcmp (thd->cl->filename, cache->filename))
166 if (self)
168 found = thd;
169 continue;
172 /* Continue trying to find a client who has the same file open and
173 * also has a lock. */
174 rc = cache_lock_mutex (thd->cl->ctx, thd->cl->filename, -1, 0, -1);
175 if (!rc)
177 found = thd;
178 break;
183 if (self && (!rc || rc == GPG_ERR_NO_DATA) && found)
184 rc = cache_lock_mutex (found->cl->ctx, found->cl->filename, -1, 0, -1);
186 if (exiting || !rc || rc == GPG_ERR_NO_DATA)
188 cache_free_data_once (cache->data);
189 cache->data = NULL;
190 cache->defer_clear = 0;
191 cache->timeout = -1;
193 if (found)
194 cache_unlock_mutex (found->cl->filename, 0);
196 rc = 0;
199 if (rc)
200 cache->defer_clear = 1;
202 pthread_cleanup_pop (1);
203 pthread_cleanup_pop (1);
204 return rc;
207 gpg_error_t
208 cache_unlock_mutex (const char *filename, int remove)
210 MUTEX_LOCK (&cache_mutex);
211 file_cache_t *p = get_entry (filename);
213 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
215 if (p)
217 MUTEX_UNLOCK (p->mutex);
218 if (remove)
219 remove_entry (filename);
222 pthread_cleanup_pop (1);
223 return p ? 0 : GPG_ERR_NO_DATA;
226 static gpg_error_t
227 test_agent_cache_once (file_cache_t *p, const char *grip)
229 gpg_error_t rc;
230 char *line;
232 rc = agent_command (cache_agent, &line, NULL, "KEYINFO --data %s", grip);
233 if (!rc)
235 char **fields = str_split (line, " ", 0);
237 /* Smartcard. */
238 if (*fields[1] == 'T')
239 rc = GPG_ERR_NO_DATA;
240 else
241 rc = isdigit (*fields[4]) || *fields[5] == 'C' ? 0 : GPG_ERR_NO_DATA;
243 strv_free (fields);
244 xfree (line);
247 return rc;
250 /* Test each keygrip in data->(sig)grip for gpg-agent cache status. The file is
251 * considered cached if at least one grip is cached in the agent or one siggrip
252 * is cached in the case of 'sign'.
254 static gpg_error_t
255 test_agent_cache (file_cache_t *data, int sign)
257 gpg_error_t rc = 0;
258 char **p;
260 if ((!data->grip && !sign) || (!data->siggrip && sign))
261 return GPG_ERR_NO_DATA;
263 for (p = data->grip; !sign && p && *p; p++)
265 rc = test_agent_cache_once (data, *p);
266 if (!rc || rc != GPG_ERR_NO_DATA)
267 break;
270 if (!rc && sign)
272 for (p = data->siggrip; p && *p; p++)
274 rc = test_agent_cache_once (data, *p);
275 if (!rc || rc != GPG_ERR_NO_DATA)
276 break;
280 return rc;
283 static gpg_error_t
284 extract_keygrip_once (struct crypto_s *crypto, char **keyids, int sign,
285 char ***dst)
287 gpgme_key_t *result;
288 gpgme_error_t rc;
289 int i;
290 char **grips = NULL;
292 rc = crypto_list_keys (crypto, keyids, sign, &result);
293 if (rc)
294 return rc;
296 for (i = 0; result[i]; i++)
298 gpgme_subkey_t s;
300 for (s = result[i]->subkeys; s; s = s->next)
302 char **k;
304 if (sign && !s->can_sign)
305 continue;
307 for (k = keyids; *k; k++)
309 if (!strcmp (*k, s->keyid) && s->keygrip)
311 char **tmp;
312 size_t len = strv_length (grips);
314 tmp = xrealloc (grips, len+2 * sizeof (char *));
315 if (!tmp)
317 rc = GPG_ERR_ENOMEM;
318 break;
321 grips = tmp;
322 grips[len] = str_dup (s->keygrip);
323 if (!grips[len])
325 rc = GPG_ERR_ENOMEM;
326 break;
329 grips[++len] = NULL;
335 if (!rc)
337 strv_free (*dst);
338 *dst = grips;
340 else
342 strv_free (grips);
343 grips = NULL;
346 crypto_free_key_list (result);
347 return rc ? rc : grips ? rc : GPG_ERR_NO_DATA;
350 static gpg_error_t
351 extract_keygrips (file_cache_t *data)
353 gpg_error_t rc = 0;
354 struct crypto_s *crypto;
355 char **grips = NULL, **siggrips = NULL;
357 if (!data || !data->data)
358 return 0;
360 rc = crypto_init (&crypto, NULL, NULL, 0, NULL);
361 if (rc)
362 return rc;
364 pthread_cleanup_push ((void *)crypto_free, crypto);
366 if (data->data->pubkey)
367 rc = extract_keygrip_once (crypto, data->data->pubkey, 0, &grips);
369 if (!rc && data->data->sigkey)
370 rc = extract_keygrip_once (crypto, data->data->sigkey, 1, &siggrips);
372 if (!rc)
374 strv_free (data->grip);
375 data->grip = grips;
376 strv_free (data->siggrip);
377 data->siggrip = siggrips;
379 else
381 strv_free (grips);
382 strv_free (siggrips);
385 pthread_cleanup_pop (1);
386 return rc;
389 static gpg_error_t
390 iscached (const char *filename, int *defer, int agent, int sign)
392 file_cache_t *p = get_entry (filename);
393 gpg_error_t rc = 0;
395 if (!agent)
397 if (!p || !p->data)
398 return GPG_ERR_NO_DATA;
400 if (defer)
401 *defer = p->defer_clear;
403 return 0;
406 if (!p)
407 return GPG_ERR_NO_DATA;
409 if (defer)
410 *defer = p->defer_clear;
412 if (!rc && (p->grip || p->siggrip))
413 rc = test_agent_cache (p, sign);
414 else if (!rc)
415 rc = GPG_ERR_NO_DATA;
417 return rc;
420 unsigned
421 cache_file_count ()
423 MUTEX_LOCK (&cache_mutex);
424 unsigned total = 0, i, n;
426 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
427 n = slist_length (key_cache);
428 for (i = 0; i < n; i++)
430 file_cache_t *p = slist_nth_data (key_cache, i);
432 if (!iscached (p->filename, NULL, 0, 0))
433 total++;
436 pthread_cleanup_pop (1);
437 return total;
440 void
441 cache_adjust_timeout ()
443 MUTEX_LOCK (&cache_mutex);
444 int t = slist_length (key_cache);
445 int i;
447 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
449 for (i = 0; i < t; i++)
451 file_cache_t *p = slist_nth_data (key_cache, i);
453 if (p->timeout > 0)
454 p->timeout--;
456 if (!p->timeout || (p->defer_clear && p->timeout != -1))
458 /* The file associated with this cache entry may be locked by a
459 * client. Defer freeing this cache entry until the next timeout
460 * check. */
461 if (!clear_once (p, 1))
462 send_status_all (STATUS_CACHE, NULL);
466 pthread_cleanup_pop (1);
469 static gpg_error_t
470 set_timeout (const char *filename, int timeout, int defer, int force)
472 MUTEX_LOCK (&cache_mutex);
473 file_cache_t *p = get_entry (filename);
474 gpg_error_t rc = 0;
476 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
478 if (!p)
480 MUTEX_UNLOCK (&cache_mutex);
481 return GPG_ERR_NOT_FOUND;
484 p->reset = timeout;
485 if (!p->defer_clear && (p->timeout == -1 || force))
486 p->timeout = timeout;
488 if (!timeout || defer)
490 rc = clear_once (p, 1);
491 if (!rc)
492 send_status_all (STATUS_CACHE, NULL);
495 pthread_cleanup_pop (1);
496 return rc;
499 gpg_error_t
500 cache_set_data (const char *filename, struct cache_data_s * data)
502 MUTEX_LOCK (&cache_mutex);
503 gpg_error_t rc = GPG_ERR_NO_DATA;
504 file_cache_t *p = get_entry (filename);
506 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
508 if (p)
510 p->data = data;
511 rc = set_timeout (filename, p->reset, p->defer_clear, 0);
512 if (!rc && !p->reset)
514 clear_once (p, 0);
515 send_status_all (STATUS_CACHE, NULL);
517 else if (!rc)
518 rc = extract_keygrips (p);
521 pthread_cleanup_pop (1);
522 return p && !rc ? 0 : rc;
525 struct cache_data_s *
526 cache_get_data (const char *filename)
528 MUTEX_LOCK (&cache_mutex);
529 file_cache_t *p = get_entry (filename);
531 MUTEX_UNLOCK (&cache_mutex);
532 return p ? p->data : NULL;
535 gpg_error_t
536 cache_add_file (const char *filename, struct cache_data_s *data, int timeout)
538 MUTEX_LOCK (&cache_mutex);
539 file_cache_t *p = get_entry (filename);
540 struct slist_s *new;
541 gpg_error_t rc = 0;
543 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
545 if (p)
547 p->data = data;
548 p->refcount++;
549 rc = set_timeout (filename, timeout, p->defer_clear, 0);
550 MUTEX_UNLOCK (&cache_mutex);
551 send_status_all (STATUS_CACHE, NULL);
553 if (!rc)
554 rc = extract_keygrips (p);
556 return rc;
559 p = xcalloc (1, sizeof (file_cache_t));
560 if (!p)
562 MUTEX_UNLOCK (&cache_mutex);
563 return GPG_ERR_ENOMEM;
566 p->mutex = (pthread_mutex_t *) xmalloc (sizeof (pthread_mutex_t));
567 if (!p->mutex)
569 xfree (p);
570 MUTEX_UNLOCK (&cache_mutex);
571 return GPG_ERR_ENOMEM;
574 pthread_mutexattr_t attr;
575 pthread_mutexattr_init (&attr);
576 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
577 pthread_mutex_init (p->mutex, &attr);
578 pthread_mutexattr_destroy (&attr);
579 p->filename = str_dup (filename);
580 p->data = data;
581 p->refcount++;
582 new = slist_append (key_cache, p);
583 if (!new)
585 pthread_mutex_destroy (p->mutex);
586 xfree (p->mutex);
587 xfree (p);
588 MUTEX_UNLOCK (&cache_mutex);
589 return GPG_ERR_ENOMEM;
592 key_cache = new;
593 rc = cache_set_timeout(filename, timeout);
594 pthread_cleanup_pop (1);
595 send_status_all (STATUS_CACHE, NULL);
597 if (!rc)
598 rc = extract_keygrips (p);
600 return rc;
603 gpg_error_t
604 cache_clear_agent_keys (const char *filename, int decrypt, int sign)
606 MUTEX_LOCK (&cache_mutex);
607 gpg_error_t rc = 0;
608 char **key;
609 file_cache_t *p = get_entry (filename);
611 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
613 if (!p)
615 MUTEX_UNLOCK (&cache_mutex);
616 return GPG_ERR_NOT_FOUND;
619 for (key = p->grip; decrypt && key && *key; key++)
621 rc = agent_command (cache_agent, NULL, NULL,
622 "CLEAR_PASSPHRASE --mode=normal %s", *key);
623 if (rc)
624 break;
627 for (key = p->siggrip; sign && key && *key; key++)
629 rc = agent_command (cache_agent, NULL, NULL,
630 "CLEAR_PASSPHRASE --mode=normal %s", *key);
631 if (rc)
632 break;
635 pthread_cleanup_pop (1);
636 return rc;
639 static gpg_error_t
640 clear_once (file_cache_t *p, int agent)
642 gpg_error_t rc = 0, trc;
644 if (agent)
645 rc = cache_clear_agent_keys (p->filename, 1, 1);
647 trc = free_cache_data (p);
648 return rc ? rc : trc;
651 static void
652 free_entry (file_cache_t *p, int agent)
654 gpg_error_t rc;
656 if (!p)
657 return;
659 rc = clear_once (p, agent);
660 if (rc)
661 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
663 if (p->mutex)
665 pthread_mutex_destroy (p->mutex);
666 xfree (p->mutex);
669 strv_free (p->grip);
670 strv_free (p->siggrip);
671 xfree (p->filename);
672 key_cache = slist_remove (key_cache, p);
673 xfree (p);
676 gpg_error_t
677 cache_clear (struct client_s *client, const char *filename, int agent)
679 file_cache_t *p;
680 gpg_error_t rc = 0, all_rc = 0;
681 int i, t;
683 MUTEX_LOCK (&cache_mutex);
684 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
686 if (filename)
688 p = get_entry (filename);
689 if (!p)
691 MUTEX_UNLOCK (&cache_mutex);
692 return 0;
695 rc = clear_once (p, agent);
696 MUTEX_UNLOCK (&cache_mutex);
697 if (rc)
698 log_write ("%s(): %s", __FUNCTION__, pwmd_strerror (rc));
700 return rc;
703 t = slist_length (key_cache);
704 for (i = 0; i < t; i++)
706 p = slist_nth_data (key_cache, i);
708 if (client)
710 assuan_peercred_t peer;
711 int n = client->no_access_param;
713 client->no_access_param = 1;
714 rc = do_validate_peer (client->ctx, p->filename, &peer);
715 client->no_access_param = n;
716 if (rc == GPG_ERR_FORBIDDEN)
717 rc = peer_is_invoker (client);
719 if (rc)
721 all_rc = !all_rc ? rc : all_rc;
722 continue;
726 clear_once (p, agent);
729 pthread_cleanup_pop (1);
730 return all_rc;
733 gpg_error_t
734 cache_iscached (const char *filename, int *defer, int agent, int sign)
736 gpg_error_t rc;
738 if (!filename)
739 return GPG_ERR_INV_PARAMETER;
741 MUTEX_LOCK (&cache_mutex);
742 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
743 rc = iscached (filename, defer, agent, sign);
745 /* Test if the data file disappeared from the filesystem. */
746 if ((!rc || gpg_err_code (rc) == GPG_ERR_NO_DATA)
747 && access (filename, R_OK) == -1)
749 rc = gpg_error_from_errno (errno);
750 if (gpg_err_code (rc) == GPG_ERR_ENOENT)
752 /* Fixes clearing the cache entry that was created during OPEN when
753 * SAVE'ing a new file. */
754 if ((defer && *defer == 1) || !defer)
756 rc = cache_defer_clear (filename);
757 if (!rc && defer)
758 *defer = 1;
761 rc = GPG_ERR_ENOENT;
765 pthread_cleanup_pop (1);
766 return rc;
769 gpg_error_t
770 cache_defer_clear (const char *filename)
772 MUTEX_LOCK (&cache_mutex);
773 file_cache_t *p = get_entry (filename);
774 gpg_error_t rc = 0;
776 if (!p)
777 rc = GPG_ERR_NOT_FOUND;
778 else
779 p->defer_clear = 1;
781 MUTEX_UNLOCK (&cache_mutex);
782 return rc;
785 gpg_error_t
786 cache_set_timeout (const char *filename, int timeout)
788 return set_timeout (filename, timeout, 0, 1);
791 void
792 cache_deinit ()
794 MUTEX_LOCK (&cache_mutex);
795 int i, t = slist_length (key_cache);
797 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
798 for (i = 0; i < t; i++)
800 file_cache_t *p = slist_nth_data (key_cache, i);
802 free_entry (p, 1);
803 t = slist_length (key_cache);
804 i = -1;
807 gcry_free (cache_key);
808 xfree (cache_iv);
809 cache_key = NULL;
810 cache_iv = NULL;
811 agent_free (cache_agent);
812 cache_agent = NULL;
813 pthread_cleanup_pop (1);
814 pthread_mutex_destroy (&cache_mutex);
817 void
818 cache_mutex_init ()
820 pthread_mutexattr_t attr;
822 pthread_mutexattr_init (&attr);
823 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
824 pthread_mutex_init (&cache_mutex, &attr);
825 pthread_mutexattr_destroy (&attr);
828 gpg_error_t
829 cache_init ()
831 gpg_error_t rc = 0;
833 rc = agent_init (&cache_agent);
834 if (rc)
836 cache_agent = NULL;
837 return rc;
840 if (!cache_key)
842 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_BLKLEN, NULL,
843 &cache_blocksize);
844 if (rc)
845 return rc;
847 rc = gcry_cipher_algo_info (GCRY_CIPHER_AES, GCRYCTL_GET_KEYLEN, NULL,
848 &cache_keysize);
849 if (rc)
850 return rc;
852 cache_key = gcry_malloc (cache_keysize);
853 if (!cache_key)
854 return GPG_ERR_ENOMEM;
856 cache_iv = xmalloc (cache_blocksize);
857 if (!cache_iv)
859 gcry_free (cache_key);
860 cache_key = NULL;
861 return GPG_ERR_ENOMEM;
864 gcry_create_nonce (cache_key, cache_keysize);
865 gcry_create_nonce (cache_iv, cache_blocksize);
869 cache_mutex_init ();
870 return rc;
873 void
874 cache_lock ()
876 MUTEX_LOCK (&cache_mutex);
879 void
880 cache_unlock ()
882 MUTEX_UNLOCK (&cache_mutex);
885 void
886 cache_free_data_once (struct cache_data_s *data)
888 if (!data)
889 return;
891 strv_free (data->pubkey);
892 strv_free (data->sigkey);
893 xfree (data->crc);
894 xfree (data->doc);
895 xfree (data);
898 static void
899 release_cipher (void *arg)
901 gcry_cipher_close ((gcry_cipher_hd_t) arg);
904 gpg_error_t
905 cache_encrypt (struct crypto_s *crypto)
907 gpg_error_t rc;
908 gcry_cipher_hd_t h;
909 size_t len = crypto->plaintext_size;
911 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
912 if (rc)
913 return rc;
915 if (len % cache_blocksize)
917 unsigned char *p;
919 len += cache_blocksize - (len % cache_blocksize);
920 p = xrealloc (crypto->plaintext, len * sizeof (unsigned char));
921 if (!p)
923 gcry_cipher_close (h);
924 return GPG_ERR_ENOMEM;
927 crypto->plaintext = p;
928 memset (&crypto->plaintext[crypto->plaintext_size], 0,
929 len - crypto->plaintext_size);
932 pthread_cleanup_push (release_cipher, h);
933 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
934 if (!rc)
936 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
937 if (!rc)
939 unsigned char *buf = xmalloc (len);
941 pthread_cleanup_push (xfree, buf);
943 if (!buf)
944 rc = GPG_ERR_ENOMEM;
946 if (!rc)
948 rc = gcry_cipher_encrypt (h, buf, len, crypto->plaintext, len);
949 if (!rc)
951 xfree (crypto->plaintext);
952 crypto->plaintext = buf;
953 crypto->plaintext_size = len;
957 pthread_cleanup_pop (rc != 0);
961 pthread_cleanup_pop (1);
962 return rc;
965 gpg_error_t
966 cache_decrypt (struct crypto_s *crypto)
968 gcry_cipher_hd_t h = NULL;
969 gpg_error_t rc;
971 rc = gcry_cipher_open (&h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
972 if (rc)
973 return rc;
975 if (!rc)
976 rc = gcry_cipher_setiv (h, cache_iv, cache_blocksize);
978 if (!rc)
979 rc = gcry_cipher_setkey (h, cache_key, cache_keysize);
981 pthread_cleanup_push (release_cipher, h);
983 if (!rc)
985 rc = gcry_cipher_decrypt (h, crypto->plaintext, crypto->plaintext_size,
986 NULL, 0);
987 if (rc || strncmp ((char *)crypto->plaintext, "<?xml ", 6))
989 if (!rc)
990 rc = GPG_ERR_BAD_DATA;
994 pthread_cleanup_pop (1);
995 return rc;
998 gpg_error_t
999 cache_kill_scd ()
1001 gpg_error_t rc;
1003 MUTEX_LOCK (&cache_mutex);
1004 pthread_cleanup_push (release_mutex_cb, &cache_mutex);
1005 rc = agent_kill_scd (cache_agent);
1006 pthread_cleanup_pop (1);
1007 return rc;
1010 void
1011 cache_release_mutex ()
1013 MUTEX_UNLOCK (&cache_mutex);