summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2005-12-16 16:52:48 +0100
committerWerner Koch <wk@gnupg.org>2005-12-16 16:52:48 +0100
commit38e7c4c50ad8a1026886f975c5a8be2ac8438e35 (patch)
tree1898b6de84e426726dac4338acdb4905572d42c4
parentAdd support for direct pkcs#7 signatures (diff)
downloadgnupg2-38e7c4c50ad8a1026886f975c5a8be2ac8438e35.tar.xz
gnupg2-38e7c4c50ad8a1026886f975c5a8be2ac8438e35.zip
Fixed importing certs created by newer versions of Mozilla.
-rw-r--r--NEWS5
-rw-r--r--TODO4
-rw-r--r--agent/ChangeLog10
-rw-r--r--agent/minip12.c285
-rw-r--r--doc/tools.texi12
-rw-r--r--tools/ChangeLog2
-rw-r--r--tools/Makefile.am6
-rw-r--r--tools/gpgparsemail.c6
-rw-r--r--tools/rfc822parse.c11
9 files changed, 285 insertions, 56 deletions
diff --git a/NEWS b/NEWS
index edf29885d..350920580 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,11 @@ Noteworthy changes in version 1.9.20
* [scdaemon] Support for keypads of some readers. Tested only with
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)
-------------------------------------------------
diff --git a/TODO b/TODO
index 50f58cee9..7a1f989b4 100644
--- a/TODO
+++ b/TODO
@@ -94,3 +94,7 @@ might want to have an agent context for each service request
* sm/
** --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.
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 105178730..0aef39487 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -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>
* minip12.c (p12_parse): Fixed for case that the key object comes
diff --git a/agent/minip12.c b/agent/minip12.c
index 55f3946bf..e65bf0617 100644
--- a/agent/minip12.c
+++ b/agent/minip12.c
@@ -141,7 +141,8 @@ struct tag_info
/* 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
- and SIZE on success. */
+ and SIZE on success. Checks that the encoded length does not
+ exhaust the length of the provided buffer. */
static int
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
-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 rc, i, j;
@@ -241,10 +310,16 @@ string_to_key (int id, char *salt, int iter, const char *pw,
return -1;
}
+ if (saltlen < 8)
+ {
+ log_error ("salt too short\n");
+ return -1;
+ }
+
/* Store salt and password in BUF_I */
p = buf_i;
for(i=0; i < 64; i++)
- *p++ = salt [i%8];
+ *p++ = salt [i%saltlen];
for(i=j=0; i < 64; i += 2)
{
*p++ = 0;
@@ -314,14 +389,14 @@ string_to_key (int id, char *salt, int iter, const char *pw,
static int
-set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
- int keybytes)
+set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter,
+ const char *pw, int keybytes)
{
unsigned char keybuf[24];
int rc;
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;
rc = gcry_cipher_setkey (chd, keybuf, keybytes);
if (rc)
@@ -330,7 +405,7 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
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;
rc = gcry_cipher_setiv (chd, keybuf, 8);
if (rc)
@@ -343,8 +418,8 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, int iter, const char *pw,
static void
-crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
- const char *pw, int cipher_algo, int encrypt)
+crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen,
+ int iter, const char *pw, int cipher_algo, int encrypt)
{
gcry_cipher_hd_t chd;
int rc;
@@ -356,7 +431,7 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
wipememory (buffer, length);
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))
{
wipememory (buffer, length);
@@ -381,18 +456,22 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, int iter,
static int
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 *certcbarg)
{
struct tag_info ti;
const unsigned char *p = buffer;
+ const unsigned char *p_start = buffer;
size_t n = length;
const char *where;
- char salt[8];
+ char salt[16];
+ size_t saltlen;
unsigned int iter;
unsigned char *plain = NULL;
int bad_pass = 0;
+ unsigned char *cram_buffer = NULL;
+ size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
where = "start";
if (parse_tag (&p, &n, &ti))
@@ -449,11 +528,13 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
goto bailout;
if (parse_tag (&p, &n, &ti))
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;
- memcpy (salt, p, 8);
- p += 8;
- n -= 8;
+ saltlen = ti.length;
+ memcpy (salt, p, saltlen);
+ p += saltlen;
+ n -= saltlen;
if (parse_tag (&p, &n, &ti))
goto bailout;
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";
if (parse_tag (&p, &n, &ti))
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;
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;
}
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;
startoffset = 0;
- buffer = p = plain;
+ p_start = p = plain;
/* { */
/* # 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 (cram_buffer);
return 0;
+
bailout:
+ if (r_consumed)
+ *r_consumed = consumed;
gcry_free (plain);
+ gcry_free (cram_buffer);
log_error ("encryptedData error at \"%s\", offset %u\n",
- where, (p - buffer)+startoffset);
+ where, (p - p_start)+startoffset);
if (bad_pass)
{
/* 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 *
parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
- const char *pw)
+ size_t *r_consumed, const char *pw)
{
int rc;
struct tag_info ti;
const unsigned char *p = buffer;
+ const unsigned char *p_start = buffer;
size_t n = length;
const char *where;
- char salt[8];
+ char salt[16];
+ size_t saltlen;
unsigned int iter;
int len;
unsigned char *plain = NULL;
gcry_mpi_t *result = NULL;
int result_count, i;
+ unsigned char *cram_buffer = NULL;
+ size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
where = "start";
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)
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";
if (parse_tag (&p, &n, &ti))
goto bailout;
@@ -709,11 +835,13 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
goto bailout;
if (parse_tag (&p, &n, &ti))
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;
- memcpy (salt, p, 8);
- p += 8;
- n -= 8;
+ saltlen = ti.length;
+ memcpy (salt, p, saltlen);
+ p += saltlen;
+ n -= saltlen;
if (parse_tag (&p, &n, &ti))
goto bailout;
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;
}
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;
startoffset = 0;
- buffer = p = plain;
+ p_start = p = plain;
/* { */
/* # warning debug code is enabled */
@@ -828,6 +957,9 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
if (len)
goto bailout;
+ gcry_free (cram_buffer);
+ if (r_consumed)
+ *r_consumed = consumed;
return result;
bailout:
@@ -838,8 +970,11 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
gcry_mpi_release (result[i]);
gcry_free (result);
}
+ gcry_free (cram_buffer);
log_error ( "data error at \"%s\", offset %u\n",
where, (p - buffer) + startoffset);
+ if (r_consumed)
+ *r_consumed = consumed;
return NULL;
}
@@ -857,10 +992,13 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
{
struct tag_info ti;
const unsigned char *p = buffer;
+ const unsigned char *p_start = buffer;
size_t n = length;
const char *where;
int bagseqlength, len;
+ int bagseqndef, lenndef;
gcry_mpi_t *result = NULL;
+ unsigned char *cram_buffer = NULL;
where = "pfx";
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)
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";
if (parse_tag (&p, &n, &ti))
goto bailout;
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
goto bailout;
+ bagseqndef = ti.ndef;
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";
if (parse_tag (&p, &n, &ti))
goto bailout;
+ if (bagseqndef && ti.class == UNIVERSAL && !ti.tag && !ti.is_constructed)
+ break; /* Ready */
if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE)
goto bailout;
- if (bagseqlength < ti.nhdr)
- goto bailout;
- bagseqlength -= ti.nhdr;
- if (bagseqlength < ti.length)
- goto bailout;
- bagseqlength -= ti.length;
+ if (!bagseqndef)
+ {
+ if (bagseqlength < ti.nhdr)
+ goto bailout;
+ bagseqlength -= ti.nhdr;
+ if (bagseqlength < ti.length)
+ goto bailout;
+ bagseqlength -= ti.length;
+ }
+ lenndef = ti.ndef;
len = ti.length;
if (parse_tag (&p, &n, &ti))
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)
&& !memcmp (p, oid_encryptedData, DIM(oid_encryptedData)))
{
+ size_t consumed = 0;
+
p += DIM(oid_encryptedData);
n -= DIM(oid_encryptedData);
- len -= DIM(oid_encryptedData);
+ if (!lenndef)
+ len -= DIM(oid_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))
goto bailout;
+ if (lenndef)
+ len += consumed;
}
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)
- 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
{
+ size_t consumed = 0;
+
p += DIM(oid_data);
n -= DIM(oid_data);
- len -= DIM(oid_data);
- result = parse_bag_data (p, n, (p-buffer), pw);
+ if (!lenndef)
+ len -= DIM(oid_data);
+ result = parse_bag_data (p, n, (p - p_start), &consumed, pw);
if (!result)
goto bailout;
+ if (lenndef)
+ len += consumed;
}
}
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)
goto bailout;
p += 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;
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. */
+ gcry_free (cram_buffer);
return NULL;
}
@@ -1586,7 +1774,8 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
/* Encrypt it. */
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. */
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. */
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. */
seqlist[seqlistidx].buffer = build_key_bag (buffer, buflen, salt, &n);
diff --git a/doc/tools.texi b/doc/tools.texi
index 850202bd5..d39d950f4 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -14,6 +14,7 @@ GnuPG comes with a couple of smaller tools:
* gpgsm-gencert.sh:: Generate an X.509 certificate request.
* gpg-preset-passphrase:: Put a passphrase into the cache.
* gpg-connect-agent:: Communicate with a running agent.
+* gpgparsemail:: Parse a mail message into an annotated format
* symcryptrun:: Call a simple symmetric encryption tool.
@end menu
@@ -774,6 +775,17 @@ be used to directly connect to any Assuan style socket server.
@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 SYMCRYPTRUN
@c
@node symcryptrun
diff --git a/tools/ChangeLog b/tools/ChangeLog
index 9b2afd42b..b0b7499eb 100644
--- a/tools/ChangeLog
+++ b/tools/ChangeLog
@@ -1,5 +1,7 @@
2005-12-14 Werner Koch <wk@g10code.com>
+ * Makefile.am (bin_PROGRAMS): Build gpgparsemail.
+
* gpgparsemail.c (pkcs7_begin): New.
(parse_message, message_cb): Add support of direct pkcs signatures.
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 508e52bc5..519e87150 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -18,7 +18,6 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
EXTRA_DIST = Manifest watchgnupg.c \
- rfc822parse.c rfc822parse.h gpgparsemail.c \
addgnupghome gpgsm-gencert.sh
AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
@@ -36,7 +35,7 @@ else
symcryptrun =
endif
-bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun}
+bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun} gpgparsemail
if !HAVE_W32_SYSTEM
bin_PROGRAMS += watchgnupg
endif
@@ -46,6 +45,9 @@ gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c
gpgconf_LDADD = ../jnlib/libjnlib.a \
../common/libcommon.a ../gl/libgnu.a @LIBINTL@
+gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h
+gpgparsemail_LDADD =
+
symcryptrun_SOURCES = symcryptrun.c
symcryptrun_LDADD = $(LIBUTIL_LIBS) ../jnlib/libjnlib.a \
../common/libcommon.a ../gl/libgnu.a \
diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c
index dcc38c3b8..da56093c3 100644
--- a/tools/gpgparsemail.c
+++ b/tools/gpgparsemail.c
@@ -21,8 +21,8 @@
/* This utility prints an RFC8222, possible MIME structured, message
in an annotated format with the first column having an indicator
- for the content of the line.. Several options are available to
- scrutinize the message. S/MIME and OpenPGP suuport is included. */
+ for the content of the line. Several options are available to
+ scrutinize the message. S/MIME and OpenPGP support is included. */
#include <stdio.h>
@@ -708,6 +708,8 @@ main (int argc, char **argv)
" --debug enable additional debug output\n"
" --help display this help and exit\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>.");
exit (0);
}
diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c
index df3b2e7a4..303ddad13 100644
--- a/tools/rfc822parse.c
+++ b/tools/rfc822parse.c
@@ -155,7 +155,7 @@ capitalize_header_name (unsigned char *name)
*name = *name - 'A' + 'a';
}
-
+#ifndef HAVE_STPCPY
static char *
stpcpy (char *a,const char *b)
{
@@ -165,6 +165,7 @@ stpcpy (char *a,const char *b)
return (char*)a;
}
+#endif
/* 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. */
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. */
if (!rc)
rc = do_callback (msg, RFC822PARSE_LEVEL_UP);
@@ -523,7 +524,8 @@ rfc822parse_finish (rfc822parse_t msg)
* available.
*
* 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 *
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 specials2[] = "<>@.,;:";
static const char tspecials[] = "/?=<>@,;:\\[]\"()";
- static const char tspecials2[] = "/?=<>@.,;:";
+ static const char tspecials2[] = "/?=<>@.,;:"; /* FIXME: really
+ include '.'?*/
static struct
{
const unsigned char *name;