2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
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/>.
29 #include "pwmd-error.h"
34 #include "util-misc.h"
41 #define _(msgid) gettext(msgid)
63 static unsigned char crypto_magic
[5] = "\177PWMD";
66 gz_cleanup (void *arg
)
68 struct gz_s
**gz
= (struct gz_s
**) arg
;
73 if (!(*gz
)->done
&& (*gz
)->out
)
74 gcry_free ((*gz
)->out
);
77 inflateEnd (&(*gz
)->z
);
84 z_alloc (void *data
, unsigned items
, unsigned size
)
86 return gcry_calloc (items
, size
);
90 z_free (void *data
, void *p
)
95 #define ZLIB_BUFSIZE 65536
98 decompress (void *in
, unsigned long insize
, void * *out
,
99 unsigned long *outsize
)
107 gz
= xcalloc (1, sizeof (struct gz_s
));
109 return GPG_ERR_ENOMEM
;
111 gz
->z
.zalloc
= z_alloc
;
112 gz
->z
.zfree
= z_free
;
114 gz
->z
.avail_in
= (uInt
) insize
;
115 gz
->z
.avail_out
= ZLIB_BUFSIZE
;
116 gz
->z
.next_out
= gz
->out
= gcry_malloc (ZLIB_BUFSIZE
);
120 return GPG_ERR_ENOMEM
;
123 zrc
= inflateInit2 (&gz
->z
, 47);
127 return zrc
== Z_MEM_ERROR
? GPG_ERR_ENOMEM
: GPG_ERR_COMPR_ALGO
;
130 memset (&h
, 0, sizeof (gz_header
));
131 h
.comment
= (unsigned char *) buf
;
132 h
.comm_max
= sizeof (buf
);
133 zrc
= inflateGetHeader (&gz
->z
, &h
);
137 return zrc
== Z_MEM_ERROR
? GPG_ERR_ENOMEM
: GPG_ERR_COMPR_ALGO
;
140 zrc
= inflate (&gz
->z
, Z_BLOCK
);
144 return zrc
== Z_MEM_ERROR
? GPG_ERR_ENOMEM
: GPG_ERR_COMPR_ALGO
;
148 insize
= strtoul ((char *) h
.comment
, NULL
, 10);
154 zrc
= inflate (&gz
->z
, Z_FINISH
);
160 if (!gz
->z
.avail_out
)
162 p
= gcry_realloc (gz
->out
, gz
->z
.total_out
+ ZLIB_BUFSIZE
);
170 gz
->z
.next_out
= (unsigned char *) gz
->out
+ gz
->z
.total_out
;
171 gz
->z
.avail_out
= ZLIB_BUFSIZE
;
175 rc
= GPG_ERR_COMPR_ALGO
;
183 rc
= GPG_ERR_COMPR_ALGO
;
188 while (zrc
!= Z_STREAM_END
);
191 *outsize
= gz
->z
.total_out
;
202 decrypt (v2_file_header_t
* fh
, unsigned char *key
,
203 unsigned char **ciphertext
, size_t datalen
, void * *result
,
207 size_t blocksize
, keysize
, len
;
208 int algo
= cipher_to_gcrypt (fh
->flags
);
209 gcry_cipher_hd_t gh
= NULL
;
210 uint64_t iter
= 0ULL;
211 unsigned char *data
= *ciphertext
;
216 /* No encryption iterations. This is a plain (gzipped) file. */
221 return GPG_ERR_CIPHER_ALGO
;
223 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_TEST_ALGO
, NULL
, NULL
);
227 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_GET_KEYLEN
, NULL
, &keysize
);
231 rc
= gcry_cipher_algo_info (algo
, GCRYCTL_GET_BLKLEN
, NULL
, &blocksize
);
235 rc
= gcry_cipher_open (&gh
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
239 if ((rc
= gcry_cipher_setiv (gh
, fh
->iv
, blocksize
)))
242 if ((rc
= gcry_cipher_setkey (gh
, key
, keysize
)))
245 rc
= gcry_cipher_decrypt (gh
, data
, datalen
, NULL
, 0);
250 if ((rc
= gcry_cipher_setkey (gh
, key
, keysize
)))
253 while (++iter
< fh
->iter
)
255 if ((rc
= gcry_cipher_setiv (gh
, fh
->iv
, blocksize
)))
258 rc
= gcry_cipher_decrypt (gh
, data
, datalen
, NULL
, 0);
265 if (fh
->version
>= 0x218 && fh
->iter
> 0ULL)
267 if (memcmp (data
, crypto_magic
, sizeof (crypto_magic
)))
269 rc
= GPG_ERR_BAD_PASSPHRASE
;
273 len
= sizeof (crypto_magic
);
277 decompress (data
+ len
, datalen
- len
, result
,
278 (unsigned long *) result_len
);
281 if (fh
->version
< 0x218 && rc
== GPG_ERR_COMPR_ALGO
)
282 rc
= GPG_ERR_BAD_PASSPHRASE
;
286 if (strncasecmp ((char *) *result
, "<?xml ", 6) != 0)
291 rc
= GPG_ERR_BAD_PASSPHRASE
;
297 gcry_cipher_close (gh
);
303 read_v2_datafile (const char *filename
, const char *keyfile
,
304 void * *result
, size_t * result_len
, uint16_t * ver
,
310 size_t len
, passphraselen
= 0, datalen
;
312 struct agent_s
*agent
= NULL
;
314 char *passphrase
= NULL
;
315 unsigned char *data
= NULL
;
317 unsigned char *key
= NULL
;
320 if (stat (filename
, &st
) == -1)
321 return gpg_error_from_errno (errno
);
323 fd
= open (filename
, O_RDONLY
);
325 return gpg_error_from_errno (errno
);
327 len
= read (fd
, &fh
, sizeof (fh
) - 8);
328 if (len
!= sizeof (fh
) - 8)
330 rc
= GPG_ERR_INV_LENGTH
;
334 if (fh
.version
>= 0x221)
336 len
= read (fd
, &fh
.salt
, 8);
339 rc
= GPG_ERR_INV_LENGTH
;
345 *algo
= cipher_to_gcrypt (fh
.flags
);
348 if (use_agent
&& !keyfile
&& fh
.iter
> 0)
352 rc
= agent_init (&agent
);
356 desc
= plus_escape (_
357 ("A passphrase is required to decrypt the file for "
358 "converting. Please enter the passphrase below."));
359 rc
= agent_set_pinentry_options (agent
);
363 assuan_begin_confidential (agent
->ctx
);
364 rc
= send_to_agent (agent
, &passphrase
, &passphraselen
,
365 "GET_PASSPHRASE --data pwmd:convert + %s %s",
366 _("Passphrase:"), desc
);
367 assuan_end_confidential (agent
->ctx
);
372 passphraselen
--; // null byte
373 send_to_agent (agent
, NULL
, NULL
, "CLEAR_PASSPHRASE pwmd:convert");
374 cleanup_agent (agent
);
377 else if (keyfile
&& fh
.iter
> 0)
379 if (keyfile
&& fh
.iter
> 0)
383 int pfd
= open (keyfile
, O_RDONLY
);
387 rc
= gpg_error_from_errno (errno
);
391 if (stat (keyfile
, &pst
) == -1)
393 rc
= gpg_error_from_errno (errno
);
398 passphrase
= xmalloc (pst
.st_size
);
406 passphraselen
= read (pfd
, passphrase
, pst
.st_size
);
408 if (passphraselen
!= pst
.st_size
)
410 rc
= GPG_ERR_INV_LENGTH
;
414 else if (fh
.iter
> 0)
416 rc
= getpin_common (NULL
, filename
, PINENTRY_OPEN
, &passphrase
,
422 key
= gcry_malloc (KEYSIZE
);
429 fp
= fdopen (fd
, "r");
430 len
= st
.st_size
- ftell (fp
);
432 if (fh
.version
>= 0x221 && fh
.version
< 0x0300)
434 rc
= gcry_kdf_derive (passphrase
, passphraselen
, GCRY_KDF_ITERSALTED_S2K
,
435 GCRY_MD_SHA1
, fh
.salt
, 8, 1000, KEYSIZE
, key
);
440 gcry_md_hash_buffer (GCRY_MD_SHA256
, key
, passphrase
, passphraselen
);
442 data
= gcry_malloc (len
);
449 datalen
= read (fd
, data
, len
);
452 rc
= GPG_ERR_INV_LENGTH
;
456 fprintf (stderr
, _("Decrypting ...\n"));
457 rc
= decrypt (&fh
, key
, &data
, datalen
, result
, result_len
);
466 cleanup_agent (agent
);