mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* PKCS#12 import now tries several encodings in case the passphrase
was not utf-8 encoded.
This commit is contained in:
parent
9e95c2dff6
commit
083010a53d
3
NEWS
3
NEWS
@ -4,6 +4,9 @@ Noteworthy changes in version 2.0.4
|
|||||||
* The Assuan key listing commands are now also working for systems
|
* The Assuan key listing commands are now also working for systems
|
||||||
without the funopen/fopencookie API.
|
without the funopen/fopencookie API.
|
||||||
|
|
||||||
|
* PKCS#12 import now tries several encodings in case the passphrase
|
||||||
|
was not utf-8 encoded.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 2.0.3 (2007-03-08)
|
Noteworthy changes in version 2.0.3 (2007-03-08)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
4
TODO
4
TODO
@ -83,10 +83,6 @@
|
|||||||
* sm/
|
* sm/
|
||||||
** check that we issue NO_SECKEY xxx if a -u key was not found
|
** check that we issue NO_SECKEY xxx if a -u key was not found
|
||||||
We don't. The messages returned are also wrong (recipient vs. signer).
|
We don't. The messages returned are also wrong (recipient vs. signer).
|
||||||
** cmd_export
|
|
||||||
Does only work on systems with funopen/fopencookie. Changing is
|
|
||||||
easy.
|
|
||||||
|
|
||||||
|
|
||||||
* jnlib/
|
* jnlib/
|
||||||
** provide jnlib_malloc and try to remove all jnlib_xmalloc.
|
** provide jnlib_malloc and try to remove all jnlib_xmalloc.
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2007-03-19 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* minip12.c: Include iconv.h.
|
||||||
|
(decrypt_block): New.
|
||||||
|
(parse_bag_encrypted_data, parse_bag_data): Use it here.
|
||||||
|
(bag_data_p, bag_decrypted_data_p): New helpers.
|
||||||
|
|
||||||
2007-03-06 Werner Koch <wk@g10code.com>
|
2007-03-06 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpg-agent.c (main) <gpgconf>: Add entries for all ttl options.
|
* gpg-agent.c (main) <gpgconf>: Add entries for all ttl options.
|
||||||
@ -1749,7 +1756,8 @@ Fri Aug 18 14:27:14 CEST 2000 Werner Koch <wk@openit.de>
|
|||||||
* Makefile.am: New.
|
* Makefile.am: New.
|
||||||
|
|
||||||
|
|
||||||
Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
Copyright 2001, 2002, 2003, 2004, 2005,
|
||||||
|
2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is free software; as a special exception the author gives
|
This file is free software; as a special exception the author gives
|
||||||
unlimited permission to copy and/or distribute it, with or without
|
unlimited permission to copy and/or distribute it, with or without
|
||||||
|
179
agent/minip12.c
179
agent/minip12.c
@ -27,6 +27,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
|
#include <iconv.h>
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -41,6 +42,12 @@
|
|||||||
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ICONV_CONST
|
||||||
|
#define ICONV_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
UNIVERSAL = 0,
|
UNIVERSAL = 0,
|
||||||
@ -483,6 +490,120 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Decrypt a block of data and try several encodings of the key.
|
||||||
|
CIPHERTEXT is the encrypted data of size LENGTH bytes; PLAINTEXT is
|
||||||
|
a buffer of the same size to receive the decryption result. SALT,
|
||||||
|
SALTLEN, ITER and PW are the information required for decryption
|
||||||
|
and CIPHER_ALGO is the algorithm id to use. CHECK_FNC is a
|
||||||
|
function called with the plaintext and used to check whether the
|
||||||
|
decryption succeeded; i.e. that a correct passphrase has been
|
||||||
|
given. That function shall return true if the decryption has likely
|
||||||
|
succeeded. */
|
||||||
|
static void
|
||||||
|
decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
|
||||||
|
char *salt, size_t saltlen,
|
||||||
|
int iter, const char *pw, int cipher_algo,
|
||||||
|
int (*check_fnc) (const void *, size_t))
|
||||||
|
{
|
||||||
|
static const char const *charsets[] = {
|
||||||
|
"", /* No conversion - use the UTF-8 passphrase direct. */
|
||||||
|
"ISO-8859-1",
|
||||||
|
"ISO-8859-15",
|
||||||
|
"ISO-8859-2",
|
||||||
|
"ISO-8859-3",
|
||||||
|
"ISO-8859-4",
|
||||||
|
"ISO-8859-5",
|
||||||
|
"ISO-8859-6",
|
||||||
|
"ISO-8859-7",
|
||||||
|
"ISO-8859-8",
|
||||||
|
"ISO-8859-9",
|
||||||
|
"KOI8-R",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
int charsetidx = 0;
|
||||||
|
char *convertedpw = NULL; /* Malloced and converted password or NULL. */
|
||||||
|
size_t convertedpwsize = 0; /* Allocated length. */
|
||||||
|
|
||||||
|
for (charsetidx=0; charsets[charsetidx]; charsetidx++)
|
||||||
|
{
|
||||||
|
if (*charsets[charsetidx])
|
||||||
|
{
|
||||||
|
iconv_t cd;
|
||||||
|
const char *inptr;
|
||||||
|
char *outptr;
|
||||||
|
size_t inbytes, outbytes;
|
||||||
|
|
||||||
|
if (!convertedpw)
|
||||||
|
{
|
||||||
|
/* We assume one byte encodings. Thus we can allocate
|
||||||
|
the buffer of the same size as the original
|
||||||
|
passphrase; the result will actually be shorter
|
||||||
|
then. */
|
||||||
|
convertedpwsize = strlen (pw) + 1;
|
||||||
|
convertedpw = gcry_malloc_secure (convertedpwsize);
|
||||||
|
if (!convertedpw)
|
||||||
|
{
|
||||||
|
log_info ("out of secure memory while"
|
||||||
|
" converting passphrase\n");
|
||||||
|
break; /* Give up. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cd = iconv_open (charsets[charsetidx], "utf-8");
|
||||||
|
if (cd == (iconv_t)(-1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
inptr = pw;
|
||||||
|
inbytes = strlen (pw);
|
||||||
|
outptr = convertedpw;
|
||||||
|
outbytes = convertedpwsize - 1;
|
||||||
|
if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
|
||||||
|
&outptr, &outbytes) == (size_t)-1)
|
||||||
|
{
|
||||||
|
iconv_close (cd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*outptr = 0;
|
||||||
|
iconv_close (cd);
|
||||||
|
log_info ("decryption failed; trying charset `%s'\n",
|
||||||
|
charsets[charsetidx]);
|
||||||
|
}
|
||||||
|
memcpy (plaintext, ciphertext, length);
|
||||||
|
crypt_block (plaintext, length, salt, saltlen, iter,
|
||||||
|
convertedpw? convertedpw:pw, cipher_algo, 0);
|
||||||
|
if (check_fnc (plaintext, length))
|
||||||
|
break; /* Decryption succeeded. */
|
||||||
|
}
|
||||||
|
gcry_free (convertedpw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return true if the decryption of an bag_encrypted_data object has
|
||||||
|
likely succeeded. */
|
||||||
|
static int
|
||||||
|
bag_decrypted_data_p (const void *plaintext, size_t length)
|
||||||
|
{
|
||||||
|
struct tag_info ti;
|
||||||
|
const unsigned char *p = plaintext;
|
||||||
|
size_t n = length;
|
||||||
|
|
||||||
|
/* { */
|
||||||
|
/* # warning debug code is enabled */
|
||||||
|
/* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
|
||||||
|
/* if (!fp || fwrite (p, n, 1, fp) != 1) */
|
||||||
|
/* exit (2); */
|
||||||
|
/* fclose (fp); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
if (parse_tag (&p, &n, &ti))
|
||||||
|
return 0;
|
||||||
|
if (ti.class || ti.tag != TAG_SEQUENCE)
|
||||||
|
return 0;
|
||||||
|
if (parse_tag (&p, &n, &ti))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: If R_RESULT is passed as NULL, a key object as already be
|
/* Note: If R_RESULT is passed as NULL, a key object as already be
|
||||||
processed and thus we need to skip it here. */
|
processed and thus we need to skip it here. */
|
||||||
@ -624,23 +745,13 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
log_error ("error allocating decryption buffer\n");
|
log_error ("error allocating decryption buffer\n");
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
memcpy (plain, p, ti.length);
|
decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw,
|
||||||
crypt_block (plain, ti.length, salt, saltlen,
|
is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40,
|
||||||
iter, pw,
|
bag_decrypted_data_p);
|
||||||
is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40,
|
|
||||||
0);
|
|
||||||
n = ti.length;
|
n = ti.length;
|
||||||
startoffset = 0;
|
startoffset = 0;
|
||||||
p_start = p = plain;
|
p_start = p = plain;
|
||||||
|
|
||||||
/* { */
|
|
||||||
/* # warning debug code is enabled */
|
|
||||||
/* FILE *fp = fopen ("tmp-rc2-plain.der", "wb"); */
|
|
||||||
/* if (!fp || fwrite (p, n, 1, fp) != 1) */
|
|
||||||
/* exit (2); */
|
|
||||||
/* fclose (fp); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
where = "outer.outer.seq";
|
where = "outer.outer.seq";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
{
|
{
|
||||||
@ -899,6 +1010,34 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return true if the decryption of a bag_data object has likely
|
||||||
|
succeeded. */
|
||||||
|
static int
|
||||||
|
bag_data_p (const void *plaintext, size_t length)
|
||||||
|
{
|
||||||
|
struct tag_info ti;
|
||||||
|
const unsigned char *p = plaintext;
|
||||||
|
size_t n = length;
|
||||||
|
|
||||||
|
/* { */
|
||||||
|
/* # warning debug code is enabled */
|
||||||
|
/* FILE *fp = fopen ("tmp-3des-plain-key.der", "wb"); */
|
||||||
|
/* if (!fp || fwrite (p, n, 1, fp) != 1) */
|
||||||
|
/* exit (2); */
|
||||||
|
/* fclose (fp); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
|
||||||
|
return 0;
|
||||||
|
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER
|
||||||
|
|| ti.length != 1 || *p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gcry_mpi_t *
|
static gcry_mpi_t *
|
||||||
parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
||||||
size_t *r_consumed, const char *pw)
|
size_t *r_consumed, const char *pw)
|
||||||
@ -1028,22 +1167,14 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
|||||||
log_error ("error allocating decryption buffer\n");
|
log_error ("error allocating decryption buffer\n");
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
memcpy (plain, p, ti.length);
|
|
||||||
consumed += p - p_start + ti.length;
|
consumed += p - p_start + ti.length;
|
||||||
crypt_block (plain, ti.length, salt, saltlen, iter, pw, GCRY_CIPHER_3DES, 0);
|
decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw,
|
||||||
|
GCRY_CIPHER_3DES,
|
||||||
|
bag_data_p);
|
||||||
n = ti.length;
|
n = ti.length;
|
||||||
startoffset = 0;
|
startoffset = 0;
|
||||||
p_start = p = plain;
|
p_start = p = plain;
|
||||||
|
|
||||||
/* { */
|
|
||||||
/* # warning debug code is enabled */
|
|
||||||
/* FILE *fp = fopen ("tmp-rc2-plain-key.der", "wb"); */
|
|
||||||
/* if (!fp || fwrite (p, n, 1, fp) != 1) */
|
|
||||||
/* exit (2); */
|
|
||||||
/* fclose (fp); */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
|
|
||||||
where = "decrypted-text";
|
where = "decrypted-text";
|
||||||
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
|
if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user