Fix a few 'gcc -fanalyzer' warnings.
[pwmd.git] / src / pwmd-dump.c
blobe34a2a5ab155fb62d797e3daaafe3a97fe72acf0
1 /*
2 Copyright (C) 2015-2023 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 version 2 as
8 published by the Free Software Foundation.
10 Pwmd is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <stdint.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/time.h>
30 #include <sys/resource.h>
31 #include <errno.h>
32 #include <arpa/inet.h>
33 #include <libxml/tree.h>
34 #include <libxml/parser.h>
35 #include <libxml/xpath.h>
36 #include <err.h>
37 #include <termios.h>
39 #include "pwmd-error.h"
40 #include <gcrypt.h>
42 #ifdef HAVE_SYS_PRCTL_H
43 #include <sys/prctl.h>
44 #endif
46 #ifdef ENABLE_NLS
47 #ifdef HAVE_LOCALE_H
48 #include <locale.h>
49 #endif
50 #endif
52 #ifndef _
53 #include "gettext.h"
54 #define _(msgid) gettext(msgid)
55 #endif
57 #ifdef HAVE_GETOPT_LONG
58 #ifdef HAVE_GETOPT_H
59 #include <getopt.h>
60 #endif
61 #else
62 #include "getopt_long.h"
63 #endif
65 #include "util-string.h"
66 #include "mem.h"
67 #include "version.h"
69 #if 0
70 #ifdef WITH_AGENT
71 #include "agent.h"
72 #endif
73 #endif
75 #define PWMD_CIPHER_OFFSET (1)
76 #define PWMD_CIPHER(n) (PWMD_CIPHER_OFFSET << n)
77 #define PWMD_CIPHER_AES128 PWMD_CIPHER (0)
78 #define PWMD_CIPHER_AES192 PWMD_CIPHER (1)
79 #define PWMD_CIPHER_AES256 PWMD_CIPHER (2)
80 #define PWMD_CIPHER_SERPENT128 PWMD_CIPHER (3)
81 #define PWMD_CIPHER_SERPENT192 PWMD_CIPHER (4)
82 #define PWMD_CIPHER_SERPENT256 PWMD_CIPHER (5)
83 #define PWMD_CIPHER_CAMELLIA128 PWMD_CIPHER (6)
84 #define PWMD_CIPHER_CAMELLIA192 PWMD_CIPHER (7)
85 #define PWMD_CIPHER_CAMELLIA256 PWMD_CIPHER (8)
86 #define PWMD_CIPHER_3DES PWMD_CIPHER (9)
87 #define PWMD_CIPHER_CAST5 PWMD_CIPHER (10)
88 #define PWMD_CIPHER_BLOWFISH PWMD_CIPHER (11)
89 #define PWMD_CIPHER_TWOFISH PWMD_CIPHER (12)
90 #define PWMD_CIPHER_TWOFISH128 PWMD_CIPHER (13)
92 #define PWMD_FLAG_OFFSET (PWMD_CIPHER_OFFSET << 15)
93 #define PWMD_FLAG(n) (PWMD_FLAG_OFFSET << n)
94 #define PWMD_FLAG_PKI PWMD_FLAG (1)
95 #define PWMD_FLAG_NO_PASSPHRASE PWMD_FLAG (2)
97 #define KEYSIZE 32
99 typedef struct
101 uint8_t magic[5];
102 uint32_t version;
103 uint64_t s2k_count;
104 uint64_t flags;
105 uint8_t iv[16];
106 uint8_t salt[8];
107 uint32_t datalen; /* of the encrypted xml */
108 } __attribute__ ((packed)) file_header_t;
110 struct save_s
112 gcry_sexp_t pkey; /* SAVE --keygrip */
113 gcry_sexp_t sigpkey; /* SAVE --sign-keygrip */
114 file_header_t hdr;
117 struct crypto_s
119 //assuan_context_t client_ctx;
120 #ifdef WITH_AGENT
121 struct agent_s *agent;
122 #endif
123 struct save_s save;
124 gcry_sexp_t pkey_sexp;
125 unsigned char grip[20];
126 gcry_sexp_t sigpkey_sexp;
127 unsigned char sign_grip[20];
128 gcry_sexp_t ciphertext_sexp;
129 void *ciphertext;
130 size_t ciphertext_len;
131 void *plaintext;
132 size_t plaintext_len;
133 file_header_t hdr;
134 char *filename; /* the currently opened data file */
137 #define DEFAULT_KDFS2K_ITERATIONS 5000000
138 #define COMPAT_KDFS2K_ITERATIONS 1000
140 const char *reserved_attributes[] = {
141 "_name", "_mtime", "_ctime", "_acl", "_target",
142 NULL
144 static unsigned char crypto_magic[5] = "\177PWMD";
145 static int use_agent;
147 static void set_header_defaults (file_header_t * hdr);
148 static gpg_error_t decrypt_common (struct crypto_s *crypto,
149 const char *filename, const char *keyfile);
150 static gpg_error_t read_data_file (const char *filename,
151 struct crypto_s *crypto);
152 static void cleanup_crypto_stage1 (struct crypto_s *cr);
153 static void cleanup_crypto (struct crypto_s **c);
155 static int
156 cipher_to_gcrypt (int flags)
158 if (flags < 0)
159 return flags;
161 if (flags & PWMD_CIPHER_AES128)
162 return GCRY_CIPHER_AES128;
163 else if (flags & PWMD_CIPHER_AES192)
164 return GCRY_CIPHER_AES192;
165 else if (flags & PWMD_CIPHER_AES256)
166 return GCRY_CIPHER_AES256;
167 else if (flags & PWMD_CIPHER_SERPENT128)
168 return GCRY_CIPHER_SERPENT128;
169 else if (flags & PWMD_CIPHER_SERPENT192)
170 return GCRY_CIPHER_SERPENT192;
171 else if (flags & PWMD_CIPHER_SERPENT256)
172 return GCRY_CIPHER_SERPENT256;
173 else if (flags & PWMD_CIPHER_CAMELLIA128)
174 return GCRY_CIPHER_CAMELLIA128;
175 else if (flags & PWMD_CIPHER_CAMELLIA192)
176 return GCRY_CIPHER_CAMELLIA192;
177 else if (flags & PWMD_CIPHER_CAMELLIA256)
178 return GCRY_CIPHER_CAMELLIA256;
179 else if (flags & PWMD_CIPHER_BLOWFISH)
180 return GCRY_CIPHER_BLOWFISH;
181 else if (flags & PWMD_CIPHER_3DES)
182 return GCRY_CIPHER_3DES;
183 else if (flags & PWMD_CIPHER_CAST5)
184 return GCRY_CIPHER_CAST5;
185 else if (flags & PWMD_CIPHER_TWOFISH)
186 return GCRY_CIPHER_TWOFISH;
187 else if (flags & PWMD_CIPHER_TWOFISH128)
188 return GCRY_CIPHER_TWOFISH128;
190 return -1;
193 static int
194 cipher_string_to_cipher (const char *str)
196 int flags = 0;
198 if (!strcasecmp (str, "aes128"))
199 flags = PWMD_CIPHER_AES128;
200 else if (!strcasecmp (str, "aes192"))
201 flags = PWMD_CIPHER_AES192;
202 else if (!strcasecmp (str, "aes256"))
203 flags = PWMD_CIPHER_AES256;
204 else if (!strcasecmp (str, "serpent128"))
205 flags = PWMD_CIPHER_SERPENT128;
206 else if (!strcasecmp (str, "serpent192"))
207 flags = PWMD_CIPHER_SERPENT192;
208 else if (!strcasecmp (str, "serpent256"))
209 flags = PWMD_CIPHER_SERPENT256;
210 else if (!strcasecmp (str, "camellia128"))
211 flags = PWMD_CIPHER_CAMELLIA128;
212 else if (!strcasecmp (str, "camellia192"))
213 flags = PWMD_CIPHER_CAMELLIA192;
214 else if (!strcasecmp (str, "camellia256"))
215 flags = PWMD_CIPHER_CAMELLIA256;
216 else if (!strcasecmp (str, "blowfish"))
217 flags = PWMD_CIPHER_BLOWFISH;
218 else if (!strcasecmp (str, "cast5"))
219 flags = PWMD_CIPHER_CAST5;
220 else if (!strcasecmp (str, "3des"))
221 flags = PWMD_CIPHER_3DES;
222 else if (!strcasecmp (str, "twofish256"))
223 flags = PWMD_CIPHER_TWOFISH;
224 else if (!strcasecmp (str, "twofish128"))
225 flags = PWMD_CIPHER_TWOFISH128;
226 else
227 return -1;
229 return flags;
232 static void
233 usage (const char *pn, int rc)
235 fprintf(rc == EXIT_SUCCESS ? stdout : stderr,
236 "%s [-hvn] [--force] [-k <filename>] [--xml] <infile> <outfile>\n"
237 " --no-convert, -n don't discard data for elements with targets\n"
238 " --force don't abort when converting\n"
239 " --xml read a raw pwmd XML document\n"
240 " --keyfile, -k file containing the passphrase to use for decryption\n"
241 " --help\n"
242 " --version\n\n"
243 "Use - as <outfile> to write to standard output.\n",
244 pn);
245 exit (rc);
248 static gpg_error_t
249 init_client_crypto (struct crypto_s **crypto)
251 struct crypto_s *new = xcalloc (1, sizeof (struct crypto_s));
252 gpg_error_t rc;
254 if (!new)
256 rc = GPG_ERR_ENOMEM;
257 return rc;
260 #ifdef WITH_AGENT
261 if (use_agent)
263 rc = agent_init (&new->agent);
264 if (!rc)
266 rc = send_agent_common_options (new->agent);
267 if (!rc)
268 rc = agent_set_pinentry_options (new->agent);
271 if (rc)
273 cleanup_agent (new->agent);
274 xfree (new);
275 return rc;
278 #endif
280 set_header_defaults (&new->hdr);
281 *crypto = new;
282 return 0;
285 static gpg_error_t
286 parse_doc (const char *xml, size_t len, xmlDocPtr *result)
288 xmlDocPtr doc;
290 xmlResetLastError ();
291 doc = xmlReadMemory (xml, len, NULL, "UTF-8", XML_PARSE_NOBLANKS);
292 if (!doc && xmlGetLastError ())
293 return GPG_ERR_BAD_DATA;
295 *result = doc;
296 return !doc ? GPG_ERR_ENOMEM : 0;
299 static xmlChar *
300 xml_attribute_value (xmlNodePtr n, xmlChar * attr)
302 xmlAttrPtr a = xmlHasProp (n, attr);
304 if (!a)
305 return NULL;
307 if (!a->children || !a->children->content)
308 return NULL;
310 return xmlGetProp (n, attr);
313 static int
314 xml_reserved_attribute (const char *name)
316 int i;
318 for (i = 0; reserved_attributes[i]; i++)
320 if (!strcmp (name, reserved_attributes[i]))
321 return 1;
324 return 0;
326 static void
327 remove_non_reserved_attributes (xmlNodePtr n)
329 xmlAttrPtr a;
331 for (a = n->properties; a; a = a->next)
333 if (xml_reserved_attribute ((char *)a->name))
334 continue;
336 xmlRemoveProp (a);
340 static gpg_error_t
341 strip_literals (const char *filename, xmlNodePtr n, int force)
343 gpg_error_t rc = 0;
345 for (; n; n = n->next)
347 xmlChar *target;
349 if (n->type != XML_ELEMENT_NODE)
350 continue;
352 if (!xmlStrEqual (n->name, (xmlChar *) "element"))
354 xmlNodePtr tmp = n->next;
356 xmlUnlinkNode (n);
357 xmlFreeNodeList (n);
358 return strip_literals (filename, tmp, force);
361 target = xml_attribute_value (n, (xmlChar *)"_target");
362 if (target)
364 xmlChar lastc = 0, *p;
366 remove_non_reserved_attributes (n);
367 again:
368 for (lastc = 0, p = target; *p;)
370 if (*p == '!' && (p == target || lastc == '\t'))
372 xmlChar *c;
374 c = p;
375 while (*p)
376 *c++ = *++p;
377 *c = 0;
378 goto again;
381 lastc = *p++;
384 if (!xmlSetProp (n, (xmlChar *) "_target", target))
386 xmlFree (target);
387 return GPG_ERR_INV_VALUE;
390 xmlFree (target);
392 if (n->children && !force)
394 fprintf(stderr, _("%s: aborting do to literal child elements (use --force)\n"), filename);
395 return GPG_ERR_CANCELED;
397 else if (n->children)
399 xmlNodePtr tmp = n->children;
401 xmlUnlinkNode (n->children);
402 xmlFreeNodeList (tmp);
406 rc = strip_literals (filename, n->children, force);
407 if (rc)
408 break;
411 return rc;
414 static gpg_error_t
415 recurse_rename_attribute (xmlNodePtr root, const char *old, const char *name)
417 xmlNodePtr n;
418 gpg_error_t rc = 0;
420 for (n = root; n; n = n->next)
422 xmlAttrPtr attr = xmlHasProp (n, (xmlChar *)old);
424 if (attr)
426 xmlChar *a = xml_attribute_value (n, (xmlChar *)old);
428 if (a && !xmlSetProp (n, (xmlChar *) name, a))
429 rc = GPG_ERR_BAD_DATA;
431 xmlFree (a);
433 if (!rc)
435 if (xmlRemoveProp (attr) == -1)
436 rc = GPG_ERR_BAD_DATA;
440 if (rc)
441 break;
443 rc = recurse_rename_attribute (n->children, old, name);
444 if (rc)
445 break;
448 return rc;
451 static gpg_error_t
452 update_to_version (xmlDocPtr doc)
454 xmlNodePtr root = xmlDocGetRootElement (doc);
455 xmlChar *v = xml_attribute_value (root, (xmlChar *)"_version");
456 gpg_error_t rc;
458 // Pwmd 3.2.0 or later. No updates needed ATM.
459 if (v)
461 xmlFree (v);
462 return 0;
465 rc = recurse_rename_attribute (root->children, "target", "_target");
466 if (!rc)
467 rc = recurse_rename_attribute (root->children, "expire", "_expire");
469 if (!rc)
470 rc = recurse_rename_attribute (root->children, "expire_increment", "_age");
472 return rc;
476 main(int argc, char **argv)
478 gpg_error_t rc;
479 int opt, optindex;
480 struct crypto_s *crypto = NULL;
481 char *outfile = NULL, *infile = NULL, *keyfile = NULL;
482 void *key = NULL;
483 enum {
484 OPT_FORCE,
485 OPT_XML
487 const char *optstring = "vhk:n";
488 int convert = 1;
489 int force = 0;
490 int xml = 0;
491 const struct option longopts[] = {
492 {"force", no_argument, 0, 0},
493 {"xml", no_argument, 0, 0},
494 {"no-convert", no_argument, 0, 'n'},
495 {"keyfile", required_argument, 0, 'k'},
496 {"version", no_argument, 0, 'v'},
497 {"help", no_argument, 0, 'h'},
498 {0, 0, 0, 0}
501 #ifndef DEBUG
502 #ifdef HAVE_SETRLIMIT
503 struct rlimit rl;
505 rl.rlim_cur = rl.rlim_max = 0;
507 if (setrlimit (RLIMIT_CORE, &rl) != 0)
508 err (EXIT_FAILURE, "setrlimit()");
509 #endif
511 #ifdef HAVE_PR_SET_DUMPABLE
512 prctl (PR_SET_DUMPABLE, 0);
513 #endif
514 #endif
516 if (!gpgrt_check_version (REQUIRE_LIBGPGERROR_VERSION))
518 fprintf (stderr, _("gpgrt_check_version(): Incompatible libgpg-error. "
519 "Wanted %s, got %s.\n"), REQUIRE_LIBGPGERROR_VERSION,
520 gpgrt_check_version (NULL));
521 exit (EXIT_FAILURE);
524 gpgrt_init ();
525 //gpgrt_set_alloc_func (xrealloc_gpgrt);
527 if (!gcry_check_version (REQUIRE_LIBGCRYPT_VERSION))
529 fprintf (stderr, _("gcry_check_version(): Incompatible libgcrypt. "
530 "Wanted %s, got %s.\n"), REQUIRE_LIBGCRYPT_VERSION,
531 gcry_check_version (NULL));
532 exit (EXIT_FAILURE);
535 gcry_set_allocation_handler (xmalloc, xmalloc, NULL, xrealloc, xfree);
536 xmlMemSetup (xfree, xmalloc, xrealloc, str_dup);
537 xmlInitMemory ();
538 xmlInitGlobals ();
539 xmlInitParser ();
540 xmlXPathInit ();
542 while ((opt = getopt_long (argc, argv, optstring, longopts, &optindex)) != -1)
544 switch (opt)
546 case 'n':
547 convert = 0;
548 break;
549 case 'k':
550 keyfile = optarg;
551 break;
552 case 'h':
553 usage (argv[0], EXIT_SUCCESS);
554 break;
555 case 'v':
556 printf (_("%s\n\n"
557 "Copyright (C) 2015-2023\n"
558 "%s\n"
559 "Released under the terms of the GPL v2. Use at your own risk.\n\n"),
560 PACKAGE_STRING PWMD_GIT_HASH, PACKAGE_BUGREPORT);
561 exit (EXIT_SUCCESS);
562 case 0:
563 switch (optindex)
565 case OPT_FORCE:
566 force = 1;
567 break;
568 case OPT_XML:
569 xml = 1;
570 break;
571 default:
572 usage (argv[0], EXIT_FAILURE);
574 break;
575 default:
576 usage (argv[0], EXIT_FAILURE);
577 break;
581 if (argc - optind != 2)
582 usage (argv[0], EXIT_FAILURE);
584 infile = argv[optind++];
585 outfile = argv[optind];
586 if (strcmp (outfile, "-"))
588 if (access (outfile, R_OK|W_OK) == 0)
590 fprintf(stderr, _("Please remove the existing output file '%s'.\n"),
591 outfile);
592 exit (EXIT_FAILURE);
596 rc = init_client_crypto (&crypto);
597 if (rc)
598 goto fail;
600 if (!xml)
602 rc = decrypt_common (crypto, infile, keyfile);
603 xfree (key);
605 else
607 struct stat st;
608 int fd;
610 fd = open (infile, O_RDONLY);
611 if (fd == -1)
613 rc = gpg_error_from_syserror ();
614 goto fail;
617 if (fstat (fd, &st) == -1)
619 rc = gpg_error_from_syserror ();
620 close (fd);
621 goto fail;
624 crypto->plaintext = gcry_calloc (1, sizeof (char) * st.st_size+1);
625 if (!crypto->plaintext)
627 close (fd);
628 rc = GPG_ERR_ENOMEM;
629 goto fail;
632 crypto->plaintext_len = read (fd, crypto->plaintext, st.st_size);
633 close (fd);
634 if (crypto->plaintext_len != st.st_size)
636 rc = GPG_ERR_UNKNOWN_ERRNO;
637 goto fail;
641 if (!rc)
643 xmlDocPtr doc;
645 rc = parse_doc ((char *) crypto->plaintext, crypto->plaintext_len, &doc);
646 cleanup_crypto (&crypto);
647 if (!rc)
649 xmlChar *buf;
650 int len;
651 xmlNodePtr n;
653 FILE *fp = outfile[0] == '-' && outfile[1] == 0 ? stdout
654 : fopen (outfile, "w");
656 if (!fp)
658 rc = gpg_error_from_syserror ();
659 xmlFreeDoc (doc);
660 goto fail;
663 if (convert)
665 n = xmlDocGetRootElement (doc);
666 rc = strip_literals (infile, n->children, force);
667 if (rc)
669 xmlFreeDoc (doc);
670 goto fail;
673 rc = update_to_version (doc);
674 if (rc)
676 xmlFreeDoc (doc);
677 goto fail;
680 n = xmlDocGetRootElement (doc);
681 if (!xmlSetProp (n, (xmlChar *) "_version",
682 (xmlChar *)PACKAGE_VERSION))
683 rc = GPG_ERR_BAD_DATA;
684 if (rc)
686 xmlFreeDoc (doc);
687 goto fail;
691 xmlDocDumpMemory (doc, &buf, &len);
692 xmlFreeDoc (doc);
693 fprintf (fp, "%s", buf);
694 xmlFree (buf);
695 fclose (fp);
697 else
698 goto fail;
700 else
701 goto fail;
703 cleanup_crypto (&crypto);
704 exit (EXIT_SUCCESS);
706 fail:
707 cleanup_crypto (&crypto);
708 fprintf(stderr, "ERR %u: %s\n", rc, gpg_strerror (rc));
709 exit (EXIT_FAILURE);
712 static gpg_error_t
713 hash_key (int algo, unsigned char *salt, size_t salt_len, const void *key,
714 size_t keylen, void **result, size_t *rlen, uint64_t iterations)
716 gpg_error_t rc;
717 void *tmp;
719 /* Be sure the algorithm is available. */
720 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, rlen);
721 if (rc)
722 return rc;
724 /* Always allocate enough for a 256-bit key although the algorithms
725 themselves may use less. Fixes SAVE --cipher with a different
726 keylen than the previously saved cipher when cached. */
727 *rlen = 32;
728 tmp = xmalloc (*rlen);
729 if (!tmp)
730 return GPG_ERR_ENOMEM;
732 if (!iterations)
733 iterations = DEFAULT_KDFS2K_ITERATIONS;
735 rc = gcry_kdf_derive(key, keylen, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
736 salt, salt_len, iterations, *rlen, tmp);
737 if (!rc)
738 *result = tmp;
739 else
740 xfree (tmp);
742 return rc;
746 * Useful for a large amount of data. Rather than doing all of the data in one
747 * iteration do it in chunks. This lets the command be cancelable rather than
748 * waiting for it to complete.
750 #define CRYPTO_BLOCKSIZE(c) (c * 1024)
751 static gpg_error_t
752 iterate_crypto_once (gcry_cipher_hd_t h, unsigned char *inbuf,
753 size_t insize, size_t blocksize)
755 gpg_error_t rc = 0;
756 off_t len = CRYPTO_BLOCKSIZE (blocksize);
757 void *p = gcry_malloc (len);
758 off_t total = 0;
760 if (!p)
761 return gpg_error (GPG_ERR_ENOMEM);
763 if (insize < CRYPTO_BLOCKSIZE (blocksize))
764 len = insize;
766 pthread_cleanup_push (gcry_free, p);
768 for (;;)
770 unsigned char *inbuf2 = inbuf + total;
771 unsigned char *tmp;
773 if (len + total > insize)
774 len = blocksize;
776 rc = gcry_cipher_decrypt (h, p, len, inbuf2, len);
777 if (rc)
778 break;
780 tmp = inbuf + total;
781 memmove (tmp, p, len);
782 total += len;
783 if (total >= insize)
784 break;
786 #ifdef HAVE_PTHREAD_TESTCANCEL
787 pthread_testcancel ();
788 #endif
791 pthread_cleanup_pop (1);
792 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
793 rc = gpg_error (rc);
795 return rc;
798 static void
799 cleanup_cipher (void *arg)
801 gcry_cipher_close ((gcry_cipher_hd_t) arg);
804 /* Decrypt the XML data. For PKI data files the key is retrieved from
805 * gpg-agent and the signature verified. */
806 static gpg_error_t
807 decrypt_data (struct crypto_s *crypto, unsigned char *salted_key,
808 size_t skeylen)
810 gpg_error_t rc = 0;
811 unsigned char *key = salted_key;
812 gcry_cipher_hd_t h = NULL;
813 size_t blocksize, keysize = 0;
814 int algo = cipher_to_gcrypt (crypto->hdr.flags);
815 void *outbuf = NULL;
816 uint64_t n;
817 #ifdef WITH_AGENT
818 size_t keylen = skeylen;
819 gcry_sexp_t sig_sexp;
821 if (crypto->hdr.flags & PWMD_FLAG_PKI)
823 rc = agent_extract_key (crypto, &key, &keylen);
824 if (rc)
825 return rc;
827 sig_sexp = gcry_sexp_find_token (crypto->ciphertext_sexp, "sig-val", 0);
828 if (!sig_sexp)
830 gcry_free (key);
831 return GPG_ERR_BAD_DATA;
834 rc = agent_verify (crypto->sigpkey_sexp, sig_sexp, crypto->ciphertext,
835 crypto->ciphertext_len);
836 gcry_sexp_release (sig_sexp);
838 #endif
840 (void)skeylen;
841 if (!rc)
843 rc = gcry_cipher_open (&h, algo, GCRY_CIPHER_MODE_CBC, 0);
844 if (!rc)
846 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL,
847 &keysize);
848 if (!rc)
850 rc = gcry_cipher_algo_info (algo, GCRYCTL_GET_BLKLEN, NULL,
851 &blocksize);
852 if (!rc)
854 rc = gcry_cipher_setiv (h, crypto->hdr.iv, blocksize);
855 if (!rc)
857 rc = gcry_cipher_setkey (h, key, keysize);
864 pthread_cleanup_push (cleanup_cipher, rc ? NULL : h);
866 if (!rc)
868 outbuf = gcry_malloc (crypto->hdr.datalen+1);
869 if (!outbuf)
870 rc = GPG_ERR_ENOMEM;
871 else
872 memset (outbuf, 0, crypto->hdr.datalen+1);
875 pthread_cleanup_push (gcry_free, outbuf);
876 #ifdef WITH_AGENT
877 pthread_cleanup_push (gcry_free, key);
878 #endif
880 if (!rc)
882 if (!key)
883 rc = GPG_ERR_INV_PARAMETER;
884 else
886 memcpy (outbuf, crypto->ciphertext, crypto->hdr.datalen);
887 rc = iterate_crypto_once (h, outbuf, crypto->hdr.datalen, blocksize);
890 if (!rc && crypto->hdr.version <= 0x03000e)
892 key[0] ^= 1;
893 rc = gcry_cipher_setkey (h, key, keysize);
897 if (!rc && crypto->hdr.version <= 0x03000e)
899 for (n = 0; !rc && n < crypto->hdr.s2k_count; n++)
901 rc = gcry_cipher_setiv (h, crypto->hdr.iv, blocksize);
902 if (rc)
903 break;
905 rc = iterate_crypto_once (h, outbuf, crypto->hdr.datalen, blocksize);
909 #ifdef WITH_AGENT
910 pthread_cleanup_pop (0);
911 if (crypto->hdr.flags & PWMD_FLAG_PKI)
912 gcry_free (key);
913 else if (key && crypto->hdr.version <= 0x03000e)
914 key[0] ^= 1;
915 #else
916 if (crypto->hdr.version <= 0x03000e && key)
917 key[0] ^= 1;
918 #endif
919 pthread_cleanup_pop (rc ? 1 : 0); /* outbuf */
920 pthread_cleanup_pop (1); /* cipher */
921 if (!rc)
923 char buf[] = "<?xml ";
925 if (memcmp (outbuf, buf, sizeof(buf)-1))
927 gcry_free (outbuf);
928 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
931 crypto->plaintext = outbuf;
932 crypto->plaintext_len = crypto->hdr.datalen;
935 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
936 rc = gpg_error (rc);
938 return rc;
941 static gpg_error_t
942 get_passphrase (const char *filename, const char *keyfile, void **r_key,
943 size_t *r_len)
945 char buf[255] = { 0 };
946 struct termios told, tnew;
948 *r_len = 0;
950 if (keyfile)
952 ssize_t len;
953 struct stat st;
954 int fd;
956 fd = open (keyfile, O_RDONLY);
957 if (fd == -1)
958 return gpg_error_from_syserror ();
960 if (fstat (fd, &st) == -1)
962 gpg_error_t rc = gpg_error_from_syserror ();
964 close (fd);
965 return rc;
968 len = read (fd, buf, sizeof (buf));
969 if (len != st.st_size)
971 close (fd);
972 wipememory (buf, 0, sizeof (buf));
973 return gpg_error_from_syserror ();
976 *r_len = st.st_size ? st.st_size : 1;
977 *r_key = xmalloc (*r_len);
978 if (*r_key)
979 memcpy (*r_key, buf, *r_len);
980 wipememory (buf, 0, sizeof (buf));
981 close (fd);
982 return *r_key ? 0 : GPG_ERR_ENOMEM;
985 if (!isatty (STDIN_FILENO))
986 return GPG_ERR_ENOTTY;
988 if (tcgetattr (STDIN_FILENO, &told) == -1)
989 return gpg_error_from_syserror ();
991 memcpy (&tnew, &told, sizeof (struct termios));
992 tnew.c_lflag &= ~(ECHO);
993 tnew.c_lflag |= ICANON | ECHONL;
994 if (tcsetattr (STDIN_FILENO, TCSANOW, &tnew) == -1)
996 int n = errno;
998 tcsetattr (STDIN_FILENO, TCSANOW, &told);
999 return gpg_error_from_errno (n);
1002 fprintf(stderr, "Passphrase for '%s': ", filename);
1003 if (!fgets (buf, sizeof (buf), stdin))
1005 tcsetattr (STDIN_FILENO, TCSANOW, &told);
1006 return GPG_ERR_EOF;
1009 tcsetattr (STDIN_FILENO, TCSANOW, &told);
1011 if (buf[strlen(buf)-1] == '\n')
1012 buf[strlen(buf)-1] = 0;
1013 *r_len = buf[0] == 0 ? 1 : strlen (buf);
1014 *r_key = str_dup (buf);
1015 wipememory (buf, 0, sizeof (buf));
1016 return 0;
1019 /* Common to both PKI and non-PKI files. */
1020 static gpg_error_t
1021 decrypt_common (struct crypto_s *crypto, const char *filename,
1022 const char *keyfile)
1024 void *key = NULL;
1025 size_t keylen = 0;
1026 gpg_error_t rc = read_data_file (filename, crypto);
1027 int algo = cipher_to_gcrypt (crypto->hdr.flags);
1028 void *skey = NULL;
1029 size_t skeysize = 0;
1031 if (rc)
1032 return rc;
1034 rc = get_passphrase (filename, keyfile, &key, &keylen);
1035 if (rc)
1036 return rc;
1038 if (key)// && !IS_PKI (crypto))
1040 rc = hash_key (algo, crypto->hdr.salt, sizeof(crypto->hdr.salt), key,
1041 keylen, &skey, &skeysize,
1042 crypto->hdr.version <= 0x03000e ? COMPAT_KDFS2K_ITERATIONS : crypto->hdr.s2k_count);
1043 if (rc)
1045 xfree (key);
1046 return rc;
1050 xfree (key);
1051 xfree (crypto->filename);
1052 crypto->filename = str_dup (filename);
1053 rc = decrypt_data (crypto, skey, skeysize);
1054 xfree (skey);
1055 return rc;
1058 static gpg_error_t
1059 read_header (file_header_t *hdr, int fd)
1061 ssize_t len;
1062 uint32_t i;
1063 uint64_t n;
1065 #ifdef WORDS_BIGENDIAN
1066 len = read (fd, &hdr->magic, sizeof(hdr->magic));
1067 if (len == -1)
1068 goto done;
1070 len = read (fd, &hdr->version, sizeof(hdr->version));
1071 if (len == -1)
1072 goto done;
1074 len = read (fd, &hdr->s2k_count, sizeof(hdr->s2k_count));
1075 if (len == -1)
1076 goto done;
1078 len = read (fd, &hdr->flags, sizeof(hdr->flags));
1079 if (len == -1)
1080 goto done;
1082 len = read (fd, &hdr->iv, sizeof(hdr->iv));
1083 if (len == -1)
1084 goto done;
1086 len = read (fd, &hdr->salt, sizeof(hdr->salt));
1087 if (len == -1)
1088 goto done;
1090 len = read (fd, &hdr->datalen, sizeof(hdr->datalen));
1091 if (len == -1)
1092 goto done;
1093 #else
1094 len = read (fd, &hdr->magic, sizeof(hdr->magic));
1095 if (len == -1)
1096 goto done;
1098 len = read (fd, &i, sizeof(hdr->version));
1099 if (len == -1)
1100 goto done;
1101 hdr->version = ntohl (i);
1103 len = read (fd, &n, sizeof(hdr->s2k_count));
1104 if (len == -1)
1105 goto done;
1106 hdr->s2k_count = (((uint64_t) ntohl (n)) << 32) + ntohl (n >> 32);
1108 len = read (fd, &n, sizeof(hdr->flags));
1109 if (len == -1)
1110 goto done;
1111 hdr->flags = (((uint64_t) ntohl (n)) << 32) + ntohl (n >> 32);
1113 len = read (fd, &hdr->iv, sizeof(hdr->iv));
1114 if (len == -1)
1115 goto done;
1117 len = read (fd, &hdr->salt, sizeof(hdr->salt));
1118 if (len == -1)
1119 goto done;
1121 len = read (fd, &i, sizeof(hdr->datalen));
1122 if (len == -1)
1123 goto done;
1124 hdr->datalen = ntohl (i);
1125 #endif
1127 done:
1128 return len == -1 ? gpg_error_from_errno (errno) : 0;
1131 /* Read the header of a data file to determine cipher and other. The
1132 * header is stored big endian in the file and is converted to little
1133 * endian when needed. */
1134 static gpg_error_t
1135 read_data_header (const char *filename, file_header_t * rhdr,
1136 struct stat *rst, int *rfd)
1138 gpg_error_t rc = 0;
1139 struct stat st;
1140 file_header_t hdr;
1141 int fd;
1143 if (rfd)
1144 *rfd = -1;
1146 fd = open (filename, O_RDONLY);
1147 if (fd == -1)
1148 return gpg_error_from_syserror ();
1150 if (fstat (fd, &st) == -1)
1152 rc = gpg_error_from_syserror ();
1153 close (fd);
1154 return rc;
1157 rc = read_header (&hdr, fd);
1158 if (!rc && memcmp (hdr.magic, crypto_magic, sizeof (hdr.magic)))
1159 rc = GPG_ERR_BAD_DATA;
1160 else if (!rc && hdr.version < 0x030000)
1161 rc = GPG_ERR_UNKNOWN_VERSION;
1163 if (rc)
1164 close (fd);
1165 else
1167 if (rhdr)
1168 *rhdr = hdr;
1169 if (rst)
1170 *rst = st;
1171 if (rfd)
1172 *rfd = fd;
1173 else
1174 close (fd);
1177 return gpg_error (rc);
1180 static gpg_error_t
1181 read_data_file (const char *filename, struct crypto_s * crypto)
1183 int fd;
1184 gpg_error_t rc = 0;
1185 size_t len, rlen;
1186 char *buf = NULL;
1187 struct stat st;
1189 if (!filename)
1190 return GPG_ERR_INV_PARAMETER;
1192 cleanup_crypto_stage1 (crypto);
1193 rc = read_data_header (filename, &crypto->hdr, &st, &fd);
1194 if (rc)
1195 return gpg_error (rc);
1197 crypto->ciphertext_len = crypto->hdr.datalen;
1198 crypto->ciphertext = xmalloc (crypto->hdr.datalen);
1199 if (!crypto->ciphertext)
1201 rc = GPG_ERR_ENOMEM;
1202 goto done;
1205 /* The keygrips for PKI files are stored after the header. They are
1206 * stored in the file to let file(1) magic(5) show the grips. */
1207 if (crypto->hdr.flags & PWMD_FLAG_PKI)
1209 rlen = read (fd, crypto->grip, 20);
1210 if (rlen != 20)
1212 rc = rlen == -1 ? gpg_error_from_errno (errno) : GPG_ERR_BAD_DATA;
1213 goto done;
1216 rlen = read (fd, crypto->sign_grip, 20);
1217 if (rlen != 20)
1219 rc = rlen == -1 ? gpg_error_from_errno (errno) : GPG_ERR_BAD_DATA;
1220 goto done;
1224 len = read (fd, crypto->ciphertext, crypto->hdr.datalen);
1225 if (len != crypto->hdr.datalen)
1227 rc = len == -1 ? gpg_error_from_errno (errno) : GPG_ERR_BAD_DATA;
1228 goto done;
1231 if (!(crypto->hdr.flags & PWMD_FLAG_PKI))
1232 goto done;
1234 if (!use_agent)
1236 rc = GPG_ERR_NOT_IMPLEMENTED;
1237 goto done;
1240 #ifdef WITH_AGENT
1241 len = st.st_size - sizeof (file_header_t) - crypto->hdr.datalen - 40;
1242 buf = xmalloc (len);
1243 if (!buf)
1245 rc = GPG_ERR_ENOMEM;
1246 goto done;
1249 /* Remaining data file bytes are the encrypted key and XML. */
1250 rlen = read (fd, buf, len);
1251 if (rlen != len)
1253 rc = rlen == -1 ? gpg_error_from_errno (errno) : GPG_ERR_BAD_DATA;
1254 goto done;
1257 rc = gcry_sexp_new (&crypto->ciphertext_sexp, buf, rlen, 1);
1258 if (rc)
1259 goto done;
1261 if (crypto->pkey_sexp)
1262 gcry_sexp_release (crypto->pkey_sexp);
1264 if (crypto->sigpkey_sexp)
1265 gcry_sexp_release (crypto->sigpkey_sexp);
1267 crypto->pkey_sexp = crypto->sigpkey_sexp = NULL;
1268 rc = get_pubkey_bin (crypto, crypto->grip, &crypto->pkey_sexp);
1269 if (!rc)
1270 rc = get_pubkey_bin (crypto, crypto->sign_grip, &crypto->sigpkey_sexp);
1271 #endif
1273 done:
1274 close (fd);
1275 xfree (buf);
1276 if (rc && gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
1277 rc = gpg_error (rc);
1279 return rc;
1282 static void
1283 cleanup_save (struct save_s *save)
1285 if (!save)
1286 return;
1288 #ifdef WITH_AGENT
1289 if (save->pkey)
1290 gcry_sexp_release (save->pkey);
1292 if (save->sigpkey)
1293 gcry_sexp_release (save->sigpkey);
1294 #endif
1296 memset (save, 0, sizeof (struct save_s));
1299 /* Keep the agent ctx to retain pinentry options which will be freed in
1300 * cleanup_cb(). Also keep .pubkey since it may be needed for a SAVE. */
1301 static void
1302 cleanup_crypto_stage1 (struct crypto_s *cr)
1304 if (!cr)
1305 return;
1307 cleanup_save (&cr->save);
1309 #ifdef WITH_AGENT
1310 if (cr->ciphertext_sexp)
1311 gcry_sexp_release (cr->ciphertext_sexp);
1313 cr->ciphertext_sexp = NULL;
1314 #endif
1316 gcry_free (cr->plaintext);
1317 xfree (cr->ciphertext);
1318 xfree (cr->filename);
1319 cr->filename = NULL;
1320 cr->ciphertext = NULL;
1321 cr->ciphertext_len = 0;
1322 cr->plaintext = NULL;
1323 cr->plaintext_len = 0;
1326 static void
1327 cleanup_crypto_stage2 (struct crypto_s *cr)
1329 if (!cr)
1330 return;
1332 cleanup_crypto_stage1 (cr);
1333 set_header_defaults (&cr->hdr);
1336 static void
1337 cleanup_crypto (struct crypto_s **c)
1339 struct crypto_s *cr = *c;
1341 if (!cr)
1342 return;
1344 cleanup_crypto_stage2 (cr);
1346 #ifdef WITH_AGENT
1347 if (cr->pkey_sexp)
1348 gcry_sexp_release (cr->pkey_sexp);
1350 if (cr->sigpkey_sexp)
1351 gcry_sexp_release (cr->sigpkey_sexp);
1353 if (cr->agent)
1354 cleanup_agent (cr->agent);
1355 #endif
1357 xfree (cr);
1358 *c = NULL;
1361 /* Sets the default cipher values for new files. */
1362 static void
1363 set_header_defaults (file_header_t * hdr)
1365 const char *s = "aes256";
1366 int flags = cipher_string_to_cipher (s);
1368 memset (hdr, 0, sizeof (file_header_t));
1369 memcpy (hdr->magic, crypto_magic, sizeof (hdr->magic));
1370 if (flags == -1)
1371 fprintf(stderr, _("Invalid 'cipher' in configuration file. Using a default of aes256."));
1373 hdr->flags = flags == -1 ? PWMD_CIPHER_AES256 : flags;
1374 hdr->version = VERSION_HEX;
1376 #ifdef WITH_AGENT
1377 if (use_agent)
1378 hdr->flags |= PWMD_FLAG_PKI;
1379 #endif