2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
28 #include "pwmd-error.h"
33 #include "util-misc.h"
40 #define _(msgid) gettext(msgid)
62 static unsigned char crypto_magic
[5] = "\177PWMD";
65 gz_cleanup (void *arg
)
67 struct gz_s
**gz
= (struct gz_s
**) arg
;
72 if (!(*gz
)->done
&& (*gz
)->out
)
73 gcry_free ((*gz
)->out
);
76 inflateEnd (&(*gz
)->z
);
83 z_alloc (void *data
, unsigned items
, unsigned size
)
85 return gcry_calloc (items
, size
);
89 z_free (void *data
, void *p
)
94 #define ZLIB_BUFSIZE 65536
97 decompress (void *in
, unsigned long insize
, void * *out
,
98 unsigned long *outsize
)
106 gz
= xcalloc (1, sizeof (struct gz_s
));
108 return GPG_ERR_ENOMEM
;
110 gz
->z
.zalloc
= z_alloc
;
111 gz
->z
.zfree
= z_free
;
113 gz
->z
.avail_in
= (uInt
) insize
;
114 gz
->z
.avail_out
= ZLIB_BUFSIZE
;
115 gz
->z
.next_out
= gz
->out
= gcry_malloc (ZLIB_BUFSIZE
);
119 return GPG_ERR_ENOMEM
;
122 zrc
= inflateInit2 (&gz
->z
, 47);
126 return zrc
== Z_MEM_ERROR
? GPG_ERR_ENOMEM
: GPG_ERR_COMPR_ALGO
;
129 memset (&h
, 0, sizeof (gz_header
));
130 h
.comment
= (unsigned char *) buf
;
131 h
.comm_max
= sizeof (buf
);
132 zrc
= inflateGetHeader (&gz
->z
, &h
);
136 return zrc
== Z_MEM_ERROR
? GPG_ERR_ENOMEM
: GPG_ERR_COMPR_ALGO
;
139 zrc
= inflate (&gz
->z
, Z_BLOCK
);
143 return zrc
== Z_MEM_ERROR
? GPG_ERR_ENOMEM
: GPG_ERR_COMPR_ALGO
;
147 insize
= strtoul ((char *) h
.comment
, NULL
, 10);
153 zrc
= inflate (&gz
->z
, Z_FINISH
);
159 if (!gz
->z
.avail_out
)
161 p
= gcry_realloc (gz
->out
, gz
->z
.total_out
+ ZLIB_BUFSIZE
);
169 gz
->z
.next_out
= (unsigned char *) gz
->out
+ gz
->z
.total_out
;
170 gz
->z
.avail_out
= ZLIB_BUFSIZE
;
174 rc
= GPG_ERR_COMPR_ALGO
;
182 rc
= GPG_ERR_COMPR_ALGO
;
187 while (zrc
!= Z_STREAM_END
);
190 *outsize
= gz
->z
.total_out
;
201 decrypt (v2_file_header_t
* fh
, unsigned char *key
,
202 unsigned char **ciphertext
, size_t datalen
, void * *result
,
206 size_t blocksize
, keysize
, len
;
207 int algo
= cipher_to_gcrypt (fh
->flags
);
208 gcry_cipher_hd_t gh
= NULL
;
209 uint64_t iter
= 0ULL;
210 unsigned char *data
= *ciphertext
;
215 /* No encryption iterations. This is a plain (gzipped) file. */
220 return GPG_ERR_CIPHER_ALGO
;
222 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_TEST_ALGO
, NULL
, NULL
);
226 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
230 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_GET_BLKLEN
, NULL
, &blocksize
);
234 rc
= gcry_cipher_open (&gh
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
238 if ((rc
= gcry_cipher_setiv (gh
, fh
->iv
, blocksize
)))
241 if ((rc
= gcry_cipher_setkey (gh
, key
, keysize
)))
244 rc
= gcry_cipher_decrypt (gh
, data
, datalen
, NULL
, 0);
249 if ((rc
= gcry_cipher_setkey (gh
, key
, keysize
)))
252 while (++iter
< fh
->iter
)
254 if ((rc
= gcry_cipher_setiv (gh
, fh
->iv
, blocksize
)))
257 rc
= gcry_cipher_decrypt (gh
, data
, datalen
, NULL
, 0);
264 if (fh
->version
>= 0x218 && fh
->iter
> 0ULL)
266 if (memcmp (data
, crypto_magic
, sizeof (crypto_magic
)))
268 rc
= GPG_ERR_BAD_PASSPHRASE
;
272 len
= sizeof (crypto_magic
);
276 decompress (data
+ len
, datalen
- len
, result
,
277 (unsigned long *) result_len
);
280 if (fh
->version
< 0x218 && rc
== GPG_ERR_COMPR_ALGO
)
281 rc
= GPG_ERR_BAD_PASSPHRASE
;
285 if (strncasecmp ((char *) *result
, "<?xml ", 6) != 0)
290 rc
= GPG_ERR_BAD_PASSPHRASE
;
296 gcry_cipher_close (gh
);
302 read_v2_datafile (const char *filename
, const char *keyfile
,
303 void * *result
, size_t * result_len
, uint16_t * ver
,
309 size_t len
, passphraselen
, datalen
;
311 struct agent_s
*agent
= NULL
;
313 char *passphrase
= NULL
;
314 unsigned char *data
= NULL
;
316 unsigned char *key
= NULL
;
319 if (stat (filename
, &st
) == -1)
320 return gpg_error_from_syserror ();
322 fd
= open (filename
, O_RDONLY
);
324 return gpg_error_from_syserror ();
326 len
= read (fd
, &fh
, sizeof (fh
) - 8);
327 if (len
!= sizeof (fh
) - 8)
329 rc
= GPG_ERR_INV_LENGTH
;
333 if (fh
.version
>= 0x221)
335 len
= read (fd
, &fh
.salt
, 8);
338 rc
= GPG_ERR_INV_LENGTH
;
344 *algo
= cipher_to_gcrypt (fh
.flags
);
347 if (use_agent
&& !keyfile
&& fh
.iter
> 0)
351 rc
= agent_init (&agent
);
355 desc
= plus_escape (_
356 ("A passphrase is required to decrypt the file for "
357 "converting. Please enter the passphrase below."));
358 rc
= agent_set_pinentry_options (agent
);
362 assuan_begin_confidential (agent
->ctx
);
363 rc
= send_to_agent (agent
, &passphrase
, &passphraselen
,
364 "GET_PASSPHRASE --data pwmd:convert + %s %s",
365 _("Passphrase:"), desc
);
366 assuan_end_confidential (agent
->ctx
);
371 passphraselen
--; // null byte
372 send_to_agent (agent
, NULL
, NULL
, "CLEAR_PASSPHRASE pwmd:convert");
373 cleanup_agent (agent
);
376 else if (keyfile
&& fh
.iter
> 0)
378 if (keyfile
&& fh
.iter
> 0)
382 int pfd
= open (keyfile
, O_RDONLY
);
386 rc
= gpg_error_from_syserror ();
390 if (stat (keyfile
, &pst
) == -1)
392 rc
= gpg_error_from_syserror ();
397 passphrase
= xmalloc (pst
.st_size
);
405 passphraselen
= read (pfd
, passphrase
, pst
.st_size
);
407 if (passphraselen
!= pst
.st_size
)
409 rc
= GPG_ERR_INV_LENGTH
;
413 else if (fh
.iter
> 0)
415 rc
= getpin_common (NULL
, filename
, PINENTRY_OPEN
, &passphrase
,
421 key
= gcry_malloc (KEYSIZE
);
428 fp
= fdopen (fd
, "r");
429 len
= st
.st_size
- ftell (fp
);
431 if (fh
.version
>= 0x221 && fh
.version
< 0x0300)
433 rc
= gcry_kdf_derive (passphrase
, passphraselen
, GCRY_KDF_ITERSALTED_S2K
,
434 GCRY_MD_SHA1
, fh
.salt
, 8, 1000, KEYSIZE
, key
);
439 gcry_md_hash_buffer (GCRY_MD_SHA256
, key
, passphrase
, passphraselen
);
441 data
= gcry_malloc (len
);
448 datalen
= read (fd
, data
, len
);
451 rc
= GPG_ERR_INV_LENGTH
;
455 fprintf (stderr
, _("Decrypting ...\n"));
456 rc
= decrypt (&fh
, key
, &data
, datalen
, result
, result_len
);
465 cleanup_agent (agent
);