mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Fixed importing certs created by newer versions of Mozilla.
This commit is contained in:
parent
f80ad71f1c
commit
38e7c4c50a
5
NEWS
5
NEWS
@ -4,6 +4,11 @@ Noteworthy changes in version 1.9.20
|
|||||||
* [scdaemon] Support for keypads of some readers. Tested only with
|
* [scdaemon] Support for keypads of some readers. Tested only with
|
||||||
SPR532. New option --disable-keypad.
|
SPR532. New option --disable-keypad.
|
||||||
|
|
||||||
|
* New debug tool gpgparsemail.
|
||||||
|
|
||||||
|
* Importing pkcs#12 files created be recent versions of Mozilla works
|
||||||
|
again.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 1.9.19 (2005-09-12)
|
Noteworthy changes in version 1.9.19 (2005-09-12)
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
4
TODO
4
TODO
@ -94,3 +94,7 @@ might want to have an agent context for each service request
|
|||||||
|
|
||||||
* sm/
|
* sm/
|
||||||
** --include-certs is as of now still a dummy command line option
|
** --include-certs is as of now still a dummy command line option
|
||||||
|
** check that we issue NO_SECKEY xxx if a -u key was not found
|
||||||
|
|
||||||
|
* gpg/
|
||||||
|
** issue a NO_SECKEY xxxx if a -u key was not found.
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
2005-12-16 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* minip12.c (cram_octet_string): New
|
||||||
|
(p12_parse): Use it for NDEFed bags.
|
||||||
|
(parse_bag_data): Ditto.
|
||||||
|
(string_to_key, set_key_iv, crypt_block): New arg SALTLEN.
|
||||||
|
(p12_build): Use old value 8 for new arg.
|
||||||
|
(parse_bag_encrypted_data, parse_bag_data): Allow for salts of 8
|
||||||
|
to 16 bytes. Add new arg R_CONSUMED.
|
||||||
|
|
||||||
2005-11-24 Werner Koch <wk@g10code.com>
|
2005-11-24 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* minip12.c (p12_parse): Fixed for case that the key object comes
|
* minip12.c (p12_parse): Fixed for case that the key object comes
|
||||||
|
285
agent/minip12.c
285
agent/minip12.c
@ -141,7 +141,8 @@ struct tag_info
|
|||||||
|
|
||||||
/* Parse the buffer at the address BUFFER which is of SIZE and return
|
/* Parse the buffer at the address BUFFER which is of SIZE and return
|
||||||
the tag and the length part from the TLV triplet. Update BUFFER
|
the tag and the length part from the TLV triplet. Update BUFFER
|
||||||
and SIZE on success. */
|
and SIZE on success. Checks that the encoded length does not
|
||||||
|
exhaust the length of the provided buffer. */
|
||||||
static int
|
static int
|
||||||
parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
|
parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
|
||||||
{
|
{
|
||||||
@ -221,8 +222,76 @@ parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Given an ASN.1 chunk of a structure like:
|
||||||
|
|
||||||
|
24 NDEF: OCTET STRING -- This is not passed to us
|
||||||
|
04 1: OCTET STRING -- INPUT point s to here
|
||||||
|
: 30
|
||||||
|
04 1: OCTET STRING
|
||||||
|
: 80
|
||||||
|
[...]
|
||||||
|
04 2: OCTET STRING
|
||||||
|
: 00 00
|
||||||
|
: } -- This denotes a Null tag and are the last
|
||||||
|
-- two bytes in INPUT.
|
||||||
|
|
||||||
|
Create a new buffer with the content of that octet string. INPUT
|
||||||
|
is the orginal buffer with a length as stored at LENGTH. Returns
|
||||||
|
NULL on error or a new malloced buffer with the length of this new
|
||||||
|
buffer stored at LENGTH and the number of bytes parsed from input
|
||||||
|
are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is
|
||||||
|
allowed to be passed as NULL if the caller is not interested in
|
||||||
|
this value. */
|
||||||
|
static unsigned char *
|
||||||
|
cram_octet_string (const unsigned char *input, size_t *length,
|
||||||
|
size_t *input_consumed)
|
||||||
|
{
|
||||||
|
const unsigned char *s = input;
|
||||||
|
size_t n = *length;
|
||||||
|
unsigned char *output, *d;
|
||||||
|
struct tag_info ti;
|
||||||
|
|
||||||
|
/* Allocate output buf. We know that it won't be longer than the
|
||||||
|
input buffer. */
|
||||||
|
d = output = gcry_malloc (n);
|
||||||
|
if (!output)
|
||||||
|
goto bailout;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (parse_tag (&s, &n, &ti))
|
||||||
|
goto bailout;
|
||||||
|
if (ti.class == UNIVERSAL && ti.tag == TAG_OCTET_STRING
|
||||||
|
&& !ti.ndef && !ti.is_constructed)
|
||||||
|
{
|
||||||
|
memcpy (d, s, ti.length);
|
||||||
|
s += ti.length;
|
||||||
|
d += ti.length;
|
||||||
|
n -= ti.length;
|
||||||
|
}
|
||||||
|
else if (ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
|
||||||
|
break; /* Ready */
|
||||||
|
else
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
*length = d - output;
|
||||||
|
if (input_consumed)
|
||||||
|
*input_consumed += s - input;
|
||||||
|
return output;
|
||||||
|
|
||||||
|
bailout:
|
||||||
|
if (input_consumed)
|
||||||
|
*input_consumed += s - input;
|
||||||
|
gcry_free (output);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
string_to_key (int id, char *salt, int iter, const char *pw,
|
string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw,
|
||||||
int req_keylen, unsigned char *keybuf)
|
int req_keylen, unsigned char *keybuf)
|
||||||
{
|
{
|
||||||
int rc, i, j;
|
int rc, i, j;
|
||||||
@ -241,10 +310,16 @@ string_to_key (int id, char *salt, int iter, const char *pw,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (saltlen < 8)
|
||||||
|
{
|
||||||
|
log_error ("salt too short\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Store salt and password in BUF_I */
|
/* Store salt and password in BUF_I */
|
||||||
p = buf_i;
|
p = buf_i;
|
||||||
for(i=0; i < 64; i++)
|
for(i=0; i < 64; i++)
|
||||||
*p++ = salt [i%8];
|
*p++ = salt [i%saltlen];
|
||||||
for(i=j=0; i < 64; i += 2)
|
for(i=j=0; i < 64; i += 2)
|
||||||
{
|
{
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
@ -314,14 +389,14 @@ string_to_key (int id, char *salt, int iter, const char *pw,
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
|
set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
|
||||||
int keybytes)
|
const char *pw, int keybytes)
|
||||||
{
|
{
|
||||||
unsigned char keybuf[24];
|
unsigned char keybuf[24];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert (keybytes == 5 || keybytes == 24);
|
assert (keybytes == 5 || keybytes == 24);
|
||||||
if (string_to_key (1, salt, iter, pw, keybytes, keybuf))
|
if (string_to_key (1, salt, saltlen, iter, pw, keybytes, keybuf))
|
||||||
return -1;
|
return -1;
|
||||||
rc = gcry_cipher_setkey (chd, keybuf, keybytes);
|
rc = gcry_cipher_setkey (chd, keybuf, keybytes);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -330,7 +405,7 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_to_key (2, salt, iter, pw, 8, keybuf))
|
if (string_to_key (2, salt, saltlen, iter, pw, 8, keybuf))
|
||||||
return -1;
|
return -1;
|
||||||
rc = gcry_cipher_setiv (chd, keybuf, 8);
|
rc = gcry_cipher_setiv (chd, keybuf, 8);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -343,8 +418,8 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
|
crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
|
||||||
const char *pw, int cipher_algo, int encrypt)
|
int iter, const char *pw, int cipher_algo, int encrypt)
|
||||||
{
|
{
|
||||||
gcry_cipher_hd_t chd;
|
gcry_cipher_hd_t chd;
|
||||||
int rc;
|
int rc;
|
||||||
@ -356,7 +431,7 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
|
|||||||
wipememory (buffer, length);
|
wipememory (buffer, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (set_key_iv (chd, salt, iter, pw,
|
if (set_key_iv (chd, salt, saltlen, iter, pw,
|
||||||
cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
|
cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24))
|
||||||
{
|
{
|
||||||
wipememory (buffer, length);
|
wipememory (buffer, length);
|
||||||
@ -381,18 +456,22 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
||||||
int startoffset, const char *pw,
|
int startoffset, size_t *r_consumed, const char *pw,
|
||||||
void (*certcb)(void*, const unsigned char*, size_t),
|
void (*certcb)(void*, const unsigned char*, size_t),
|
||||||
void *certcbarg)
|
void *certcbarg)
|
||||||
{
|
{
|
||||||
struct tag_info ti;
|
struct tag_info ti;
|
||||||
const unsigned char *p = buffer;
|
const unsigned char *p = buffer;
|
||||||
|
const unsigned char *p_start = buffer;
|
||||||
size_t n = length;
|
size_t n = length;
|
||||||
const char *where;
|
const char *where;
|
||||||
char salt[8];
|
char salt[16];
|
||||||
|
size_t saltlen;
|
||||||
unsigned int iter;
|
unsigned int iter;
|
||||||
unsigned char *plain = NULL;
|
unsigned char *plain = NULL;
|
||||||
int bad_pass = 0;
|
int bad_pass = 0;
|
||||||
|
unsigned char *cram_buffer = NULL;
|
||||||
|
size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
|
||||||
|
|
||||||
where = "start";
|
where = "start";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
@ -449,11 +528,13 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 )
|
if (ti.class || ti.tag != TAG_OCTET_STRING
|
||||||
|
|| ti.length < 8 || ti.length > 16 )
|
||||||
goto bailout;
|
goto bailout;
|
||||||
memcpy (salt, p, 8);
|
saltlen = ti.length;
|
||||||
p += 8;
|
memcpy (salt, p, saltlen);
|
||||||
n -= 8;
|
p += saltlen;
|
||||||
|
n -= saltlen;
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
|
if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
|
||||||
@ -468,7 +549,25 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
where = "rc2-ciphertext";
|
where = "rc2-ciphertext";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
if (ti.class != CONTEXT || ti.tag != 0 || !ti.length )
|
|
||||||
|
consumed = p - p_start;
|
||||||
|
if (ti.class == CONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
|
||||||
|
{
|
||||||
|
/* Mozilla exported certs now come with single byte chunks of
|
||||||
|
octect strings. (Mozilla Firefox 1.0.4). Arghh. */
|
||||||
|
where = "cram-rc2-ciphertext";
|
||||||
|
cram_buffer = cram_octet_string ( p, &n, &consumed);
|
||||||
|
if (!cram_buffer)
|
||||||
|
goto bailout;
|
||||||
|
p = p_start = cram_buffer;
|
||||||
|
if (r_consumed)
|
||||||
|
*r_consumed = consumed;
|
||||||
|
r_consumed = NULL; /* Ugly hack to not update that value any further. */
|
||||||
|
ti.length = n;
|
||||||
|
}
|
||||||
|
else if (ti.class == CONTEXT && ti.tag == 0 && ti.length )
|
||||||
|
;
|
||||||
|
else
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
log_info ("%lu bytes of RC2 encrypted text\n", ti.length);
|
log_info ("%lu bytes of RC2 encrypted text\n", ti.length);
|
||||||
@ -480,10 +579,11 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
memcpy (plain, p, ti.length);
|
memcpy (plain, p, ti.length);
|
||||||
crypt_block (plain, ti.length, salt, iter, pw, GCRY_CIPHER_RFC2268_40, 0);
|
crypt_block (plain, ti.length, salt, saltlen,
|
||||||
|
iter, pw, GCRY_CIPHER_RFC2268_40, 0);
|
||||||
n = ti.length;
|
n = ti.length;
|
||||||
startoffset = 0;
|
startoffset = 0;
|
||||||
buffer = p = plain;
|
p_start = p = plain;
|
||||||
|
|
||||||
/* { */
|
/* { */
|
||||||
/* # warning debug code is enabled */
|
/* # warning debug code is enabled */
|
||||||
@ -615,13 +715,19 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r_consumed)
|
||||||
|
*r_consumed = consumed;
|
||||||
gcry_free (plain);
|
gcry_free (plain);
|
||||||
|
gcry_free (cram_buffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bailout:
|
bailout:
|
||||||
|
if (r_consumed)
|
||||||
|
*r_consumed = consumed;
|
||||||
gcry_free (plain);
|
gcry_free (plain);
|
||||||
|
gcry_free (cram_buffer);
|
||||||
log_error ("encryptedData error at \"%s\", offset %u\n",
|
log_error ("encryptedData error at \"%s\", offset %u\n",
|
||||||
where, (p - buffer)+startoffset);
|
where, (p - p_start)+startoffset);
|
||||||
if (bad_pass)
|
if (bad_pass)
|
||||||
{
|
{
|
||||||
/* Note, that the following string might be used by other programs
|
/* Note, that the following string might be used by other programs
|
||||||
@ -634,19 +740,23 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
|
|||||||
|
|
||||||
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,
|
||||||
const char *pw)
|
size_t *r_consumed, const char *pw)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct tag_info ti;
|
struct tag_info ti;
|
||||||
const unsigned char *p = buffer;
|
const unsigned char *p = buffer;
|
||||||
|
const unsigned char *p_start = buffer;
|
||||||
size_t n = length;
|
size_t n = length;
|
||||||
const char *where;
|
const char *where;
|
||||||
char salt[8];
|
char salt[16];
|
||||||
|
size_t saltlen;
|
||||||
unsigned int iter;
|
unsigned int iter;
|
||||||
int len;
|
int len;
|
||||||
unsigned char *plain = NULL;
|
unsigned char *plain = NULL;
|
||||||
gcry_mpi_t *result = NULL;
|
gcry_mpi_t *result = NULL;
|
||||||
int result_count, i;
|
int result_count, i;
|
||||||
|
unsigned char *cram_buffer = NULL;
|
||||||
|
size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
|
||||||
|
|
||||||
where = "start";
|
where = "start";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
@ -658,6 +768,22 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
|||||||
if (ti.class || ti.tag != TAG_OCTET_STRING)
|
if (ti.class || ti.tag != TAG_OCTET_STRING)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
|
consumed = p - p_start;
|
||||||
|
if (ti.is_constructed && ti.ndef)
|
||||||
|
{
|
||||||
|
/* Mozilla exported certs now come with single byte chunks of
|
||||||
|
octect strings. (Mozilla Firefox 1.0.4). Arghh. */
|
||||||
|
where = "cram-data.outersegs";
|
||||||
|
cram_buffer = cram_octet_string ( p, &n, &consumed);
|
||||||
|
if (!cram_buffer)
|
||||||
|
goto bailout;
|
||||||
|
p = p_start = cram_buffer;
|
||||||
|
if (r_consumed)
|
||||||
|
*r_consumed = consumed;
|
||||||
|
r_consumed = NULL; /* Ugly hack to not update that value any further. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
where = "data.outerseqs";
|
where = "data.outerseqs";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
@ -709,11 +835,13 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 )
|
if (ti.class || ti.tag != TAG_OCTET_STRING
|
||||||
|
|| ti.length < 8 || ti.length > 16)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
memcpy (salt, p, 8);
|
saltlen = ti.length;
|
||||||
p += 8;
|
memcpy (salt, p, saltlen);
|
||||||
n -= 8;
|
p += saltlen;
|
||||||
|
n -= saltlen;
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
|
if (ti.class || ti.tag != TAG_INTEGER || !ti.length )
|
||||||
@ -740,10 +868,11 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
memcpy (plain, p, ti.length);
|
memcpy (plain, p, ti.length);
|
||||||
crypt_block (plain, ti.length, salt, iter, pw, GCRY_CIPHER_3DES, 0);
|
consumed += p - p_start + ti.length;
|
||||||
|
crypt_block (plain, ti.length, salt, saltlen, iter, pw, GCRY_CIPHER_3DES, 0);
|
||||||
n = ti.length;
|
n = ti.length;
|
||||||
startoffset = 0;
|
startoffset = 0;
|
||||||
buffer = p = plain;
|
p_start = p = plain;
|
||||||
|
|
||||||
/* { */
|
/* { */
|
||||||
/* # warning debug code is enabled */
|
/* # warning debug code is enabled */
|
||||||
@ -828,6 +957,9 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
|||||||
if (len)
|
if (len)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
|
gcry_free (cram_buffer);
|
||||||
|
if (r_consumed)
|
||||||
|
*r_consumed = consumed;
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
bailout:
|
bailout:
|
||||||
@ -838,8 +970,11 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
|
|||||||
gcry_mpi_release (result[i]);
|
gcry_mpi_release (result[i]);
|
||||||
gcry_free (result);
|
gcry_free (result);
|
||||||
}
|
}
|
||||||
|
gcry_free (cram_buffer);
|
||||||
log_error ( "data error at \"%s\", offset %u\n",
|
log_error ( "data error at \"%s\", offset %u\n",
|
||||||
where, (p - buffer) + startoffset);
|
where, (p - buffer) + startoffset);
|
||||||
|
if (r_consumed)
|
||||||
|
*r_consumed = consumed;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -857,10 +992,13 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
|
|||||||
{
|
{
|
||||||
struct tag_info ti;
|
struct tag_info ti;
|
||||||
const unsigned char *p = buffer;
|
const unsigned char *p = buffer;
|
||||||
|
const unsigned char *p_start = buffer;
|
||||||
size_t n = length;
|
size_t n = length;
|
||||||
const char *where;
|
const char *where;
|
||||||
int bagseqlength, len;
|
int bagseqlength, len;
|
||||||
|
int bagseqndef, lenndef;
|
||||||
gcry_mpi_t *result = NULL;
|
gcry_mpi_t *result = NULL;
|
||||||
|
unsigned char *cram_buffer = NULL;
|
||||||
|
|
||||||
where = "pfx";
|
where = "pfx";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
@ -897,71 +1035,121 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
|
|||||||
if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
|
if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
|
if (ti.is_constructed && ti.ndef)
|
||||||
|
{
|
||||||
|
/* Mozilla exported certs now come with single byte chunks of
|
||||||
|
octect strings. (Mozilla Firefox 1.0.4). Arghh. */
|
||||||
|
where = "cram-bags";
|
||||||
|
cram_buffer = cram_octet_string ( p, &n, NULL);
|
||||||
|
if (!cram_buffer)
|
||||||
|
goto bailout;
|
||||||
|
p = p_start = cram_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
where = "bags";
|
where = "bags";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
|
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
bagseqndef = ti.ndef;
|
||||||
bagseqlength = ti.length;
|
bagseqlength = ti.length;
|
||||||
while (bagseqlength)
|
while (bagseqlength || bagseqndef)
|
||||||
{
|
{
|
||||||
/*log_debug ( "at offset %u\n", (p - buffer));*/
|
log_debug ( "at offset %u\n", (p - p_start));
|
||||||
where = "bag-sequence";
|
where = "bag-sequence";
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
|
||||||
|
break; /* Ready */
|
||||||
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
|
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
if (bagseqlength < ti.nhdr)
|
if (!bagseqndef)
|
||||||
goto bailout;
|
{
|
||||||
bagseqlength -= ti.nhdr;
|
if (bagseqlength < ti.nhdr)
|
||||||
if (bagseqlength < ti.length)
|
goto bailout;
|
||||||
goto bailout;
|
bagseqlength -= ti.nhdr;
|
||||||
bagseqlength -= ti.length;
|
if (bagseqlength < ti.length)
|
||||||
|
goto bailout;
|
||||||
|
bagseqlength -= ti.length;
|
||||||
|
}
|
||||||
|
lenndef = ti.ndef;
|
||||||
len = ti.length;
|
len = ti.length;
|
||||||
|
|
||||||
if (parse_tag (&p, &n, &ti))
|
if (parse_tag (&p, &n, &ti))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
len -= ti.nhdr;
|
if (lenndef)
|
||||||
|
len = ti.nhdr;
|
||||||
|
else
|
||||||
|
len -= ti.nhdr;
|
||||||
|
|
||||||
if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
|
if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData)
|
||||||
&& !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
|
&& !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
|
||||||
{
|
{
|
||||||
|
size_t consumed = 0;
|
||||||
|
|
||||||
p += DIM(oid_encryptedData);
|
p += DIM(oid_encryptedData);
|
||||||
n -= DIM(oid_encryptedData);
|
n -= DIM(oid_encryptedData);
|
||||||
len -= DIM(oid_encryptedData);
|
if (!lenndef)
|
||||||
|
len -= DIM(oid_encryptedData);
|
||||||
where = "bag.encryptedData";
|
where = "bag.encryptedData";
|
||||||
if (parse_bag_encrypted_data (p, n, (p - buffer), pw,
|
if (parse_bag_encrypted_data (p, n, (p - p_start), &consumed, pw,
|
||||||
certcb, certcbarg))
|
certcb, certcbarg))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
if (lenndef)
|
||||||
|
len += consumed;
|
||||||
}
|
}
|
||||||
else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
|
else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
|
||||||
&& !memcmp (p, oid_data, DIM(oid_data)))
|
&& !memcmp (p, oid_data, DIM(oid_data)))
|
||||||
{
|
{
|
||||||
if (result)
|
if (result)
|
||||||
log_info ("already got an data object, skipping next one\n");
|
{
|
||||||
|
log_info ("already got an data object, skipping next one\n");
|
||||||
|
p += ti.length;
|
||||||
|
n -= ti.length;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
size_t consumed = 0;
|
||||||
|
|
||||||
p += DIM(oid_data);
|
p += DIM(oid_data);
|
||||||
n -= DIM(oid_data);
|
n -= DIM(oid_data);
|
||||||
len -= DIM(oid_data);
|
if (!lenndef)
|
||||||
result = parse_bag_data (p, n, (p-buffer), pw);
|
len -= DIM(oid_data);
|
||||||
|
result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
|
||||||
if (!result)
|
if (!result)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
if (lenndef)
|
||||||
|
len += consumed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_info ( "unknown bag type - skipped\n");
|
{
|
||||||
|
log_info ("unknown bag type - skipped\n");
|
||||||
|
p += ti.length;
|
||||||
|
n -= ti.length;
|
||||||
|
}
|
||||||
|
|
||||||
if (len < 0 || len > n)
|
if (len < 0 || len > n)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
p += len;
|
p += len;
|
||||||
n -= len;
|
n -= len;
|
||||||
|
if (lenndef)
|
||||||
|
{
|
||||||
|
/* Need to skip the Null Tag. */
|
||||||
|
if (parse_tag (&p, &n, &ti))
|
||||||
|
goto bailout;
|
||||||
|
if (!(ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed))
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcry_free (cram_buffer);
|
||||||
return result;
|
return result;
|
||||||
bailout:
|
bailout:
|
||||||
log_error ("error at \"%s\", offset %u\n", where, (p - buffer));
|
log_error ("error at \"%s\", offset %u\n", where, (p - p_start));
|
||||||
/* fixme: need to release RESULT. */
|
/* fixme: need to release RESULT. */
|
||||||
|
gcry_free (cram_buffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1586,7 +1774,8 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
|
|||||||
|
|
||||||
/* Encrypt it. */
|
/* Encrypt it. */
|
||||||
gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
|
gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
|
||||||
crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_RFC2268_40, 1);
|
crypt_block (buffer, buflen, salt, 8, 2048, pw,
|
||||||
|
GCRY_CIPHER_RFC2268_40, 1);
|
||||||
|
|
||||||
/* Encode the encrypted stuff into a bag. */
|
/* Encode the encrypted stuff into a bag. */
|
||||||
seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
|
seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n);
|
||||||
@ -1607,7 +1796,7 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
|
|||||||
|
|
||||||
/* Encrypt it. */
|
/* Encrypt it. */
|
||||||
gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
|
gcry_randomize (salt, 8, GCRY_STRONG_RANDOM);
|
||||||
crypt_block (buffer, buflen, salt, 2048, pw, GCRY_CIPHER_3DES, 1);
|
crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1);
|
||||||
|
|
||||||
/* Encode the encrypted stuff into a bag. */
|
/* Encode the encrypted stuff into a bag. */
|
||||||
seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
|
seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
|
||||||
|
@ -14,6 +14,7 @@ GnuPG comes with a couple of smaller tools:
|
|||||||
* gpgsm-gencert.sh:: Generate an X.509 certificate request.
|
* gpgsm-gencert.sh:: Generate an X.509 certificate request.
|
||||||
* gpg-preset-passphrase:: Put a passphrase into the cache.
|
* gpg-preset-passphrase:: Put a passphrase into the cache.
|
||||||
* gpg-connect-agent:: Communicate with a running agent.
|
* gpg-connect-agent:: Communicate with a running agent.
|
||||||
|
* gpgparsemail:: Parse a mail message into an annotated format
|
||||||
* symcryptrun:: Call a simple symmetric encryption tool.
|
* symcryptrun:: Call a simple symmetric encryption tool.
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@ -773,6 +774,17 @@ be used to directly connect to any Assuan style socket server.
|
|||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@c
|
||||||
|
@c GPGPARSEMAIL
|
||||||
|
@c
|
||||||
|
@node gpgparsemail
|
||||||
|
@section Parse a mail message into an annotated format
|
||||||
|
|
||||||
|
The @command{gpgparsemail} is a utility currentlu only useful for
|
||||||
|
debugging. Run it with @code{--help} for usage information.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@c SYMCRYPTRUN
|
@c SYMCRYPTRUN
|
||||||
@c
|
@c
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
2005-12-14 Werner Koch <wk@g10code.com>
|
2005-12-14 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* Makefile.am (bin_PROGRAMS): Build gpgparsemail.
|
||||||
|
|
||||||
* gpgparsemail.c (pkcs7_begin): New.
|
* gpgparsemail.c (pkcs7_begin): New.
|
||||||
(parse_message, message_cb): Add support of direct pkcs signatures.
|
(parse_message, message_cb): Add support of direct pkcs signatures.
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
EXTRA_DIST = Manifest watchgnupg.c \
|
EXTRA_DIST = Manifest watchgnupg.c \
|
||||||
rfc822parse.c rfc822parse.h gpgparsemail.c \
|
|
||||||
addgnupghome gpgsm-gencert.sh
|
addgnupghome gpgsm-gencert.sh
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
|
AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
|
||||||
@ -36,7 +35,7 @@ else
|
|||||||
symcryptrun =
|
symcryptrun =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun}
|
bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun} gpgparsemail
|
||||||
if !HAVE_W32_SYSTEM
|
if !HAVE_W32_SYSTEM
|
||||||
bin_PROGRAMS += watchgnupg
|
bin_PROGRAMS += watchgnupg
|
||||||
endif
|
endif
|
||||||
@ -46,6 +45,9 @@ gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c
|
|||||||
gpgconf_LDADD = ../jnlib/libjnlib.a \
|
gpgconf_LDADD = ../jnlib/libjnlib.a \
|
||||||
../common/libcommon.a ../gl/libgnu.a @LIBINTL@
|
../common/libcommon.a ../gl/libgnu.a @LIBINTL@
|
||||||
|
|
||||||
|
gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h
|
||||||
|
gpgparsemail_LDADD =
|
||||||
|
|
||||||
symcryptrun_SOURCES = symcryptrun.c
|
symcryptrun_SOURCES = symcryptrun.c
|
||||||
symcryptrun_LDADD = $(LIBUTIL_LIBS) ../jnlib/libjnlib.a \
|
symcryptrun_LDADD = $(LIBUTIL_LIBS) ../jnlib/libjnlib.a \
|
||||||
../common/libcommon.a ../gl/libgnu.a \
|
../common/libcommon.a ../gl/libgnu.a \
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
/* This utility prints an RFC8222, possible MIME structured, message
|
/* This utility prints an RFC8222, possible MIME structured, message
|
||||||
in an annotated format with the first column having an indicator
|
in an annotated format with the first column having an indicator
|
||||||
for the content of the line.. Several options are available to
|
for the content of the line. Several options are available to
|
||||||
scrutinize the message. S/MIME and OpenPGP suuport is included. */
|
scrutinize the message. S/MIME and OpenPGP support is included. */
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -708,6 +708,8 @@ main (int argc, char **argv)
|
|||||||
" --debug enable additional debug output\n"
|
" --debug enable additional debug output\n"
|
||||||
" --help display this help and exit\n\n"
|
" --help display this help and exit\n\n"
|
||||||
"With no FILE, or when FILE is -, read standard input.\n\n"
|
"With no FILE, or when FILE is -, read standard input.\n\n"
|
||||||
|
"WARNING: This tool is under development.\n"
|
||||||
|
" The semantics may change without notice\n\n"
|
||||||
"Report bugs to <bug-gnupg@gnu.org>.");
|
"Report bugs to <bug-gnupg@gnu.org>.");
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ capitalize_header_name (unsigned char *name)
|
|||||||
*name = *name - 'A' + 'a';
|
*name = *name - 'A' + 'a';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_STPCPY
|
||||||
static char *
|
static char *
|
||||||
stpcpy (char *a,const char *b)
|
stpcpy (char *a,const char *b)
|
||||||
{
|
{
|
||||||
@ -165,6 +165,7 @@ stpcpy (char *a,const char *b)
|
|||||||
|
|
||||||
return (char*)a;
|
return (char*)a;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* If a callback has been registerd, call it for the event of type
|
/* If a callback has been registerd, call it for the event of type
|
||||||
@ -474,7 +475,7 @@ insert_body (rfc822parse_t msg, const unsigned char *line, size_t length)
|
|||||||
msg->boundary = NULL; /* No current boundary anymore. */
|
msg->boundary = NULL; /* No current boundary anymore. */
|
||||||
set_current_part_to_parent (msg);
|
set_current_part_to_parent (msg);
|
||||||
|
|
||||||
/* Fixme: The next should acctually be sent right before the
|
/* Fixme: The next should actually be send right before the
|
||||||
next boundary, so that we can mark the epilogue. */
|
next boundary, so that we can mark the epilogue. */
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = do_callback (msg, RFC822PARSE_LEVEL_UP);
|
rc = do_callback (msg, RFC822PARSE_LEVEL_UP);
|
||||||
@ -523,7 +524,8 @@ rfc822parse_finish (rfc822parse_t msg)
|
|||||||
* available.
|
* available.
|
||||||
*
|
*
|
||||||
* If VALUEOFF is not NULL it will receive the offset of the first non
|
* If VALUEOFF is not NULL it will receive the offset of the first non
|
||||||
* space character in th value of the line.
|
* space character in the value part of the line (i.e. after the first
|
||||||
|
* colon).
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
rfc822parse_get_field (rfc822parse_t msg, const char *name, int which,
|
rfc822parse_get_field (rfc822parse_t msg, const char *name, int which,
|
||||||
@ -758,7 +760,8 @@ parse_field (HDR_LINE hdr)
|
|||||||
static const char specials[] = "<>@.,;:\\[]\"()";
|
static const char specials[] = "<>@.,;:\\[]\"()";
|
||||||
static const char specials2[] = "<>@.,;:";
|
static const char specials2[] = "<>@.,;:";
|
||||||
static const char tspecials[] = "/?=<>@,;:\\[]\"()";
|
static const char tspecials[] = "/?=<>@,;:\\[]\"()";
|
||||||
static const char tspecials2[] = "/?=<>@.,;:";
|
static const char tspecials2[] = "/?=<>@.,;:"; /* FIXME: really
|
||||||
|
include '.'?*/
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
const unsigned char *name;
|
const unsigned char *name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user