Module Name:    src
Committed By:   agc
Date:           Thu Nov 11 00:58:05 UTC 2010

Modified Files:
        src/crypto/external/bsd/netpgp/dist/src/lib: compress.c crypto.h misc.c
            packet-parse.c packet-parse.h packet.h reader.c validate.c
            version.h

Log Message:
Changes to 3.99.15/20101110

+ add support for partial blocks, defined in rfc 4880, and used fairly
extensively by gnupg where the input size may not be known in advance
(e.g. for encrypted compressed data, as produced by default by gpg -e)


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 \
    src/crypto/external/bsd/netpgp/dist/src/lib/compress.c
cvs rdiff -u -r1.27 -r1.28 \
    src/crypto/external/bsd/netpgp/dist/src/lib/crypto.h
cvs rdiff -u -r1.38 -r1.39 src/crypto/external/bsd/netpgp/dist/src/lib/misc.c
cvs rdiff -u -r1.45 -r1.46 \
    src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c
cvs rdiff -u -r1.14 -r1.15 \
    src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.h
cvs rdiff -u -r1.28 -r1.29 \
    src/crypto/external/bsd/netpgp/dist/src/lib/packet.h
cvs rdiff -u -r1.44 -r1.45 \
    src/crypto/external/bsd/netpgp/dist/src/lib/reader.c \
    src/crypto/external/bsd/netpgp/dist/src/lib/version.h
cvs rdiff -u -r1.42 -r1.43 \
    src/crypto/external/bsd/netpgp/dist/src/lib/validate.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/crypto/external/bsd/netpgp/dist/src/lib/compress.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/compress.c:1.19 src/crypto/external/bsd/netpgp/dist/src/lib/compress.c:1.20
--- src/crypto/external/bsd/netpgp/dist/src/lib/compress.c:1.19	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/compress.c	Thu Nov 11 00:58:04 2010
@@ -57,7 +57,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: compress.c,v 1.19 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD: compress.c,v 1.20 2010/11/11 00:58:04 agc Exp $");
 #endif
 
 #ifdef HAVE_ZLIB_H
@@ -112,7 +112,7 @@
  * bzip2_compressed_data_reader
  */
 static int 
-zlib_compressed_data_reader(void *dest, size_t length,
+zlib_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
 			    pgp_error_t **errors,
 			    pgp_reader_t *readinfo,
 			    pgp_cbdata_t *cbinfo)
@@ -164,7 +164,7 @@
 				} else {
 					n = sizeof(z->in);
 				}
-				if (!pgp_stacked_limited_read(z->in, n,
+				if (!pgp_stacked_limited_read(stream, z->in, n,
 						z->region,
 						errors, readinfo, cbinfo)) {
 					return -1;
@@ -207,7 +207,7 @@
 #ifdef HAVE_BZLIB_H
 /* \todo remove code duplication between this and zlib_compressed_data_reader */
 static int 
-bzip2_compressed_data_reader(void *dest, size_t length,
+bzip2_compressed_data_reader(pgp_stream_t *stream, void *dest, size_t length,
 			     pgp_error_t **errors,
 			     pgp_reader_t *readinfo,
 			     pgp_cbdata_t *cbinfo)
@@ -249,7 +249,7 @@
 				} else
 					n = sizeof(bz->in);
 
-				if (!pgp_stacked_limited_read(
+				if (!pgp_stacked_limited_read(stream,
 						(uint8_t *) bz->in,
 						n, bz->region,
 						errors, readinfo, cbinfo))

Index: src/crypto/external/bsd/netpgp/dist/src/lib/crypto.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/crypto.h:1.27 src/crypto/external/bsd/netpgp/dist/src/lib/crypto.h:1.28
--- src/crypto/external/bsd/netpgp/dist/src/lib/crypto.h:1.27	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/crypto.h	Thu Nov 11 00:58:04 2010
@@ -300,6 +300,12 @@
 	unsigned		 reading_v3_secret:1;
 	unsigned		 reading_mpi_len:1;
 	unsigned		 exact_read:1;
+	unsigned		 partial_read:1;
+	unsigned		 coalescing:1;
+	/* used for partial length coalescing */
+	unsigned		 virtualc;
+	unsigned		 virtualoff;
+	uint8_t			*virtualpkt;
 };
 
 #endif /* CRYPTO_H_ */

Index: src/crypto/external/bsd/netpgp/dist/src/lib/misc.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/misc.c:1.38 src/crypto/external/bsd/netpgp/dist/src/lib/misc.c:1.39
--- src/crypto/external/bsd/netpgp/dist/src/lib/misc.c:1.38	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/misc.c	Thu Nov 11 00:58:04 2010
@@ -57,7 +57,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: misc.c,v 1.38 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD: misc.c,v 1.39 2010/11/11 00:58:04 agc Exp $");
 #endif
 
 #include <sys/types.h>
@@ -1159,7 +1159,7 @@
 }
 
 static int 
-sum16_reader(void *dest_, size_t length, pgp_error_t **errors,
+sum16_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors,
 	     pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
 	const uint8_t	*dest = dest_;
@@ -1167,7 +1167,7 @@
 	int		 r;
 	int		 n;
 
-	r = pgp_stacked_read(dest_, length, errors, readinfo, cbinfo);
+	r = pgp_stacked_read(stream, dest_, length, errors, readinfo, cbinfo);
 	if (r < 0) {
 		return r;
 	}

Index: src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c:1.45 src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c:1.46
--- src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c:1.45	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c	Thu Nov 11 00:58:04 2010
@@ -58,9 +58,12 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: packet-parse.c,v 1.45 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD: packet-parse.c,v 1.46 2010/11/11 00:58:04 agc Exp $");
 #endif
 
+#include <sys/types.h>
+#include <sys/param.h>
+
 #ifdef HAVE_OPENSSL_CAST_H
 #include <openssl/cast.h>
 #endif
@@ -122,7 +125,7 @@
 		return 0;
 	}
 
-	return pgp_limited_read(data->contents, data->len, subregion,
+	return pgp_limited_read(stream, data->contents, data->len, subregion,
 			&stream->errors, &stream->readinfo, &stream->cbinfo);
 }
 
@@ -161,7 +164,7 @@
 		return 0;
 	}
 	if (len &&
-	    !pgp_limited_read(*str, len, subregion, &stream->errors,
+	    !pgp_limited_read(stream, *str, len, subregion, &stream->errors,
 				     &stream->readinfo, &stream->cbinfo)) {
 		return 0;
 	}
@@ -216,7 +219,7 @@
  */
 
 static int 
-sub_base_read(void *dest, size_t length, pgp_error_t **errors,
+sub_base_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
 	      pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
 	size_t          n;
@@ -228,8 +231,8 @@
 	for (n = 0; n < length;) {
 		int	r;
 
-		r = readinfo->reader((char *) dest + n, length - n, errors,
-				readinfo, cbinfo);
+		r = readinfo->reader(stream, (char *) dest + n, length - n, errors,
+			readinfo, cbinfo);
 		if (r > (int)(length - n)) {
 			(void) fprintf(stderr, "sub_base_read: bad read\n");
 			return 0;
@@ -279,17 +282,17 @@
 }
 
 int 
-pgp_stacked_read(void *dest, size_t length, pgp_error_t **errors,
+pgp_stacked_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
 		 pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
-	return sub_base_read(dest, length, errors, readinfo->next, cbinfo);
+	return sub_base_read(stream, dest, length, errors, readinfo->next, cbinfo);
 }
 
 /* This will do a full read so long as length < MAX_INT */
 static int 
 base_read(uint8_t *dest, size_t length, pgp_stream_t *stream)
 {
-	return sub_base_read(dest, length, &stream->errors, &stream->readinfo,
+	return sub_base_read(stream, dest, length, &stream->errors, &stream->readinfo,
 			     &stream->cbinfo);
 }
 
@@ -299,7 +302,7 @@
  */
 
 static size_t 
-full_read(uint8_t *dest,
+full_read(pgp_stream_t *stream, uint8_t *dest,
 		size_t length,
 		int *last_read,
 		pgp_error_t **errors,
@@ -311,7 +314,7 @@
 				 * == 0 */
 
 	for (t = 0; t < length;) {
-		r = sub_base_read(dest + t, length - t, errors, readinfo,
+		r = sub_base_read(stream, dest + t, length - t, errors, readinfo,
 				cbinfo);
 		if (r <= 0) {
 			*last_read = r;
@@ -391,7 +394,7 @@
  * \return		1 on success, 0 on error
  */
 unsigned 
-pgp_limited_read(uint8_t *dest,
+pgp_limited_read(pgp_stream_t *stream, uint8_t *dest,
 			size_t length,
 			pgp_region_t *region,
 			pgp_error_t **errors,
@@ -406,7 +409,7 @@
 		PGP_ERROR(errors, PGP_E_P_NOT_ENOUGH_DATA, "Not enough data");
 		return 0;
 	}
-	r = full_read(dest, length, &lr, errors, readinfo, cbinfo);
+	r = full_read(stream, dest, length, &lr, errors, readinfo, cbinfo);
 	if (lr < 0) {
 		PGP_ERROR(errors, PGP_E_R_READ_FAILED, "Read failed");
 		return 0;
@@ -432,13 +435,13 @@
    \brief Call pgp_limited_read on next in stack
 */
 unsigned 
-pgp_stacked_limited_read(uint8_t *dest, unsigned length,
+pgp_stacked_limited_read(pgp_stream_t *stream, uint8_t *dest, unsigned length,
 			 pgp_region_t *region,
 			 pgp_error_t **errors,
 			 pgp_reader_t *readinfo,
 			 pgp_cbdata_t *cbinfo)
 {
-	return pgp_limited_read(dest, length, region, errors,
+	return pgp_limited_read(stream, dest, length, region, errors,
 				readinfo->next, cbinfo);
 }
 
@@ -446,7 +449,7 @@
 limread(uint8_t *dest, unsigned length,
 	     pgp_region_t *region, pgp_stream_t *info)
 {
-	return pgp_limited_read(dest, length, region, &info->errors,
+	return pgp_limited_read(info, dest, length, region, &info->errors,
 				&info->readinfo, &info->cbinfo);
 }
 
@@ -692,6 +695,39 @@
 	return 1;
 }
 
+static unsigned read_new_length(unsigned *, pgp_stream_t *);
+
+/* allocate space, read, and stash data away in a virtual pkt */
+static void
+streamread(pgp_stream_t *stream, unsigned c)
+{
+	int	cc;
+
+	stream->virtualpkt = realloc(stream->virtualpkt, stream->virtualc + c);
+	cc = stream->readinfo.reader(stream, &stream->virtualpkt[stream->virtualc],
+		c, &stream->errors, &stream->readinfo, &stream->cbinfo);
+	stream->virtualc += cc;
+}
+
+/* coalesce all the partial blocks together */
+static int
+coalesce_blocks(pgp_stream_t *stream, unsigned length)
+{
+	unsigned	c;
+
+	stream->coalescing = 1;
+	/* already read a partial block length - prime the array */
+	streamread(stream, length);
+	while (read_new_length(&c, stream) && stream->partial_read) {
+		/* length we read is partial - add to end of array */
+		streamread(stream, c);
+	}
+	/* not partial - add the last extent to the end of the array */
+	streamread(stream, c);
+	stream->coalescing = 0;
+	return 1;
+}
+
 /** Read some data with a New-Format length from reader.
  *
  * \sa Internet-Draft RFC4880.txt Section 4.2.2
@@ -707,31 +743,39 @@
 {
 	uint8_t   c;
 
-	if (base_read(&c, 1, stream) != 1)
+	stream->partial_read = 0;
+	if (base_read(&c, 1, stream) != 1) {
 		return 0;
+	}
 	if (c < 192) {
 		/* 1. One-octet packet */
 		*length = c;
 		return 1;
-	} else if (c >= 192 && c <= 223) {
+	}
+	if (c < 224) {
 		/* 2. Two-octet packet */
 		unsigned        t = (c - 192) << 8;
 
-		if (base_read(&c, 1, stream) != 1)
+		if (base_read(&c, 1, stream) != 1) {
 			return 0;
+		}
 		*length = t + c + 192;
 		return 1;
-	} else if (c == 255) {
-		/* 3. Five-Octet packet */
-		return _read_scalar(length, 4, stream);
-	} else if (c >= 224 && c < 255) {
-		/* 4. Partial Body Length */
-		/* XXX - agc - gpg multi-recipient encryption uses this */
-		PGP_ERROR(&stream->errors, PGP_E_UNIMPLEMENTED,
-		"New format Partial Body Length fields not yet implemented");
-		return 0;
 	}
-	return 0;
+	if (c < 255) {
+		/* 3. Partial Body Length */
+		stream->partial_read = 1;
+		*length = 1 << (c & 0x1f);
+		if (!stream->coalescing) {
+			/* we have been called from coalesce_blocks -
+			 * just return with the partial length */
+			coalesce_blocks(stream, *length);
+			*length = stream->virtualc;
+		}
+		return 1;
+	}
+	/* 4. Five-Octet packet */
+	return _read_scalar(length, 4, stream);
 }
 
 /** Read the length information for a new format Packet Tag.
@@ -764,7 +808,7 @@
 		*length = c;
 		return 1;
 	}
-	if (c < 255) {
+	if (c < 224) {
 		unsigned        t = (c - 192) << 8;
 
 		if (!limread(&c, 1, region, stream)) {
@@ -773,6 +817,17 @@
 		*length = t + c + 192;
 		return 1;
 	}
+	if (c < 255) {
+		stream->partial_read = 1;
+		*length = 1 << (c & 0x1f);
+		if (!stream->coalescing) {
+			/* we have been called from coalesce_blocks -
+			 * just return with the partial length */
+			coalesce_blocks(stream, *length);
+			*length = stream->virtualc;
+		}
+		return 1;
+	}
 	return limread_scalar(length, 4, region, stream);
 }
 
@@ -2655,6 +2710,7 @@
 	uint8_t		 	 unencoded_m_buf[1024];
 
 	if (!limread(&c, 1, region, stream)) {
+		(void) fprintf(stderr, "parse_pk_sesskey - can't read char in region\n");
 		return 0;
 	}
 	pkt.u.pk_sesskey.version = c;
@@ -2711,8 +2767,15 @@
 	sesskey.u.get_seckey.seckey = &secret;
 	sesskey.u.get_seckey.pk_sesskey = &pkt.u.pk_sesskey;
 
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "getting secret key via callback\n");
+	}
+
 	CALLBACK(PGP_GET_SECKEY, &stream->cbinfo, &sesskey);
 
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "got secret key via callback\n");
+	}
 	if (!secret) {
 		CALLBACK(PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbinfo,
 			&pkt);
@@ -2728,6 +2791,9 @@
 
 	/* PKA */
 	pkt.u.pk_sesskey.symm_alg = (pgp_symm_alg_t)unencoded_m_buf[0];
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "symm alg %d\n", pkt.u.pk_sesskey.symm_alg);
+	}
 
 	if (!pgp_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) {
 		/* ERR1P */
@@ -2738,6 +2804,9 @@
 		return 0;
 	}
 	k = pgp_key_size(pkt.u.pk_sesskey.symm_alg);
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "key size %d\n", k);
+	}
 
 	if ((unsigned) n != k + 3) {
 		PGP_ERROR_2(&stream->errors, PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN,
@@ -2758,7 +2827,7 @@
 	pkt.u.pk_sesskey.checksum = unencoded_m_buf[k + 1] +
 			(unencoded_m_buf[k + 2] << 8);
 	if (pgp_get_debug_level(__FILE__)) {
-		printf("session key checksum: %2x %2x\n",
+		(void) fprintf(stderr, "session key checksum: %2x %2x\n",
 			unencoded_m_buf[k + 1], unencoded_m_buf[k + 2]);
 	}
 
@@ -2772,8 +2841,15 @@
 		unencoded_m_buf[k + 2]);
 		return 0;
 	}
+
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "getting pk session key via callback\n");
+	}
 	/* all is well */
 	CALLBACK(PGP_PTAG_CT_PK_SESSION_KEY, &stream->cbinfo, &pkt);
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "got pk session key via callback\n");
+	}
 
 	pgp_crypt_any(&stream->decrypt, pkt.u.pk_sesskey.symm_alg);
 	iv = calloc(1, stream->decrypt.blocksize);
@@ -2858,6 +2934,9 @@
 
 	decrypt = pgp_get_decrypt(stream);
 	if (decrypt) {
+		if (pgp_get_debug_level(__FILE__)) {
+			(void) fprintf(stderr, "pgp_decrypt_se_ip_data: decrypt: num %d, alg %d, blocksize %d, keysize %d\n", decrypt->num, decrypt->alg, decrypt->blocksize, decrypt->keysize);
+		}
 		pgp_reader_push_decrypt(stream, decrypt, region);
 		pgp_reader_push_se_ip_data(stream, decrypt, region);
 
@@ -2868,6 +2947,9 @@
 	} else {
 		pgp_packet_t pkt;
 
+		if (pgp_get_debug_level(__FILE__)) {
+			(void) fprintf(stderr, "pgp_decrypt_se_ip_data: no decrypt\n");
+		}
 		while (region->readc < region->length) {
 			unsigned        len;
 
@@ -2923,12 +3005,19 @@
 		return 0;
 	}
 	pkt.u.se_ip_data_header = c;
-
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "parse_se_ip_data: data header %d\n", c);
+	}
 	if (pkt.u.se_ip_data_header != PGP_SE_IP_DATA_VERSION) {
 		(void) fprintf(stderr, "parse_se_ip_data: bad version\n");
 		return 0;
 	}
 
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
+			region->readc, region->length);
+		hexdump(stderr, "compressed region", stream->virtualpkt, stream->virtualc);
+	}
 	/*
 	 * The content of an encrypted data packet is more OpenPGP packets
 	 * once decrypted, so recursively handle them
@@ -2985,8 +3074,8 @@
 
 	if (pgp_get_debug_level(__FILE__)) {
 		(void) fprintf(stderr,
-			"pgp_parse_packet: base_read returned %d\n",
-			ret);
+			"pgp_parse_packet: base_read returned %d, ptag %d\n",
+			ret, ptag);
 	}
 
 	/* errors in the base read are effectively EOF. */

Index: src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.h:1.14 src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.h:1.15
--- src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.h:1.14	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.h	Thu Nov 11 00:58:04 2010
@@ -107,7 +107,7 @@
    to read more than INT_MAX in one go.
 
  */
-typedef int pgp_reader_func_t(void *, size_t, pgp_error_t **,
+typedef int pgp_reader_func_t(pgp_stream_t *, void *, size_t, pgp_error_t **,
 				pgp_reader_t *, pgp_cbdata_t *);
 
 typedef void pgp_reader_destroyer_t(pgp_reader_t *);
@@ -147,10 +147,10 @@
 void pgp_parse_options(pgp_stream_t *, pgp_content_enum,
 			pgp_parse_type_t);
 
-unsigned pgp_limited_read(uint8_t *, size_t, pgp_region_t *,
+unsigned pgp_limited_read(pgp_stream_t *, uint8_t *, size_t, pgp_region_t *,
 			pgp_error_t **, pgp_reader_t *,
 			pgp_cbdata_t *);
-unsigned pgp_stacked_limited_read(uint8_t *, unsigned,
+unsigned pgp_stacked_limited_read(pgp_stream_t *, uint8_t *, unsigned,
 			pgp_region_t *, pgp_error_t **,
 			pgp_reader_t *, pgp_cbdata_t *);
 void pgp_parse_hash_init(pgp_stream_t *, pgp_hash_alg_t,

Index: src/crypto/external/bsd/netpgp/dist/src/lib/packet.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/packet.h:1.28 src/crypto/external/bsd/netpgp/dist/src/lib/packet.h:1.29
--- src/crypto/external/bsd/netpgp/dist/src/lib/packet.h:1.28	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/packet.h	Thu Nov 11 00:58:04 2010
@@ -669,7 +669,7 @@
 /** Signature Subpacket : Signature Target */
 typedef struct pgp_ss_sig_target_t {
 	pgp_pubkey_alg_t	pka_alg;
-	pgp_hash_alg_t	hash_alg;
+	pgp_hash_alg_t		hash_alg;
 	pgp_data_t		hash;
 } pgp_ss_sig_target_t;
 
@@ -690,8 +690,8 @@
 /** pgp_one_pass_sig_t */
 typedef struct {
 	uint8_t			version;
-	pgp_sig_type_t	sig_type;
-	pgp_hash_alg_t	hash_alg;
+	pgp_sig_type_t		sig_type;
+	pgp_hash_alg_t		hash_alg;
 	pgp_pubkey_alg_t	key_alg;
 	uint8_t			keyid[PGP_KEY_ID_SIZE];
 	unsigned		nested;

Index: src/crypto/external/bsd/netpgp/dist/src/lib/reader.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/reader.c:1.44 src/crypto/external/bsd/netpgp/dist/src/lib/reader.c:1.45
--- src/crypto/external/bsd/netpgp/dist/src/lib/reader.c:1.44	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/reader.c	Thu Nov 11 00:58:04 2010
@@ -54,7 +54,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: reader.c,v 1.44 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD: reader.c,v 1.45 2010/11/11 00:58:04 agc Exp $");
 #endif
 
 #include <sys/types.h>
@@ -134,6 +134,26 @@
 #include "netpgpdefs.h"
 #include "netpgpdigest.h"
 
+/* data from partial blocks is queued up in virtual block in stream */
+static int
+read_partial_data(pgp_stream_t *stream, void *dest, size_t length)
+{
+	unsigned	n;
+
+	if (pgp_get_debug_level(__FILE__)) {
+		(void) fprintf(stderr, "fd_reader: coalesced data, off %d\n",
+				stream->virtualoff);
+	}
+	n = MIN(stream->virtualc - stream->virtualoff, length);
+	(void) memcpy(dest, &stream->virtualpkt[stream->virtualoff], n);
+	stream->virtualoff += n;
+	if (stream->virtualoff == stream->virtualc) {
+		free(stream->virtualpkt);
+		stream->virtualpkt = NULL;
+		stream->virtualc = stream->virtualoff = 0;
+	}
+	return (int)n;
+}
 
 /* get a pass phrase from the user */
 int
@@ -419,7 +439,7 @@
 }
 
 static int 
-read_char(dearmour_t *dearmour,
+read_char(pgp_stream_t *stream, dearmour_t *dearmour,
 		pgp_error_t **errors,
 		pgp_reader_t *readinfo,
 		pgp_cbdata_t *cbinfo,
@@ -434,7 +454,7 @@
 				free(dearmour->pushback);
 				dearmour->pushback = NULL;
 			}
-		} else if (pgp_stacked_read(&c, 1, errors, readinfo,
+		} else if (pgp_stacked_read(stream, &c, 1, errors, readinfo,
 					cbinfo) != 1) {
 			return -1;
 		}
@@ -445,7 +465,7 @@
 }
 
 static int 
-eat_whitespace(int first,
+eat_whitespace(pgp_stream_t *stream, int first,
 	       dearmour_t *dearmour,
 	       pgp_error_t **errors,
 	       pgp_reader_t *readinfo,
@@ -455,13 +475,13 @@
 	int             c = first;
 
 	while (c == ' ' || c == '\t') {
-		c = read_char(dearmour, errors, readinfo, cbinfo, skip);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, skip);
 	}
 	return c;
 }
 
 static int 
-read_and_eat_whitespace(dearmour_t *dearmour,
+read_and_eat_whitespace(pgp_stream_t *stream, dearmour_t *dearmour,
 			pgp_error_t **errors,
 			pgp_reader_t *readinfo,
 			pgp_cbdata_t *cbinfo,
@@ -470,7 +490,7 @@
 	int             c;
 
 	do {
-		c = read_char(dearmour, errors, readinfo, cbinfo, skip);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, skip);
 	} while (c == ' ' || c == '\t');
 	return c;
 }
@@ -489,7 +509,7 @@
 }
 
 static int 
-unarmoured_read_char(dearmour_t *dearmour,
+unarmoured_read_char(pgp_stream_t *stream, dearmour_t *dearmour,
 			pgp_error_t **errors,
 			pgp_reader_t *readinfo,
 			pgp_cbdata_t *cbinfo,
@@ -498,7 +518,7 @@
 	int             c;
 
 	do {
-		c = read_char(dearmour, errors, readinfo, cbinfo, 0);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
 		if (c < 0) {
 			return c;
 		}
@@ -554,7 +574,7 @@
  * as line terminators
  */
 static int 
-process_dash_escaped(dearmour_t *dearmour,
+process_dash_escaped(pgp_stream_t *stream, dearmour_t *dearmour,
 			pgp_error_t **errors,
 			pgp_reader_t *readinfo,
 			pgp_cbdata_t *cbinfo)
@@ -606,12 +626,12 @@
 		int             c;
 		unsigned        count;
 
-		c = read_char(dearmour, errors, readinfo, cbinfo, 1);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
 		if (c < 0) {
 			return -1;
 		}
 		if (dearmour->prev_nl && c == '-') {
-			if ((c = read_char(dearmour, errors, readinfo, cbinfo,
+			if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo,
 						0)) < 0) {
 				return -1;
 			}
@@ -622,7 +642,7 @@
 						"Bad dash-escaping");
 				}
 				for (count = 2; count < 5; ++count) {
-					if ((c = read_char(dearmour, errors,
+					if ((c = read_char(stream, dearmour, errors,
 						readinfo, cbinfo, 0)) < 0) {
 						return -1;
 					}
@@ -636,7 +656,7 @@
 				break;
 			}
 			/* otherwise we read the next character */
-			if ((c = read_char(dearmour, errors, readinfo, cbinfo,
+			if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo,
 						0)) < 0) {
 				return -1;
 			}
@@ -717,7 +737,7 @@
 
 /* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */
 static int 
-parse_headers(dearmour_t *dearmour, pgp_error_t **errors,
+parse_headers(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
 	      pgp_reader_t * readinfo, pgp_cbdata_t * cbinfo)
 {
 	unsigned        nbuf;
@@ -735,7 +755,7 @@
 	for (;;) {
 		int             c;
 
-		if ((c = read_char(dearmour, errors, readinfo, cbinfo, 1)) < 0) {
+		if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1)) < 0) {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "Unexpected EOF");
 			ret = -1;
 			break;
@@ -815,7 +835,7 @@
 }
 
 static int 
-read4(dearmour_t *dearmour, pgp_error_t **errors,
+read4(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
       pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo,
       int *pc, unsigned *pn, uint32_t *pl)
 {
@@ -823,7 +843,7 @@
 	uint32_t   l = 0;
 
 	for (n = 0; n < 4; ++n) {
-		c = read_char(dearmour, errors, readinfo, cbinfo, 1);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
 		if (c < 0) {
 			dearmour->eof64 = 1;
 			return -1;
@@ -870,12 +890,12 @@
 }
 
 static int 
-decode64(dearmour_t *dearmour, pgp_error_t **errors,
+decode64(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
 	 pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
 	unsigned        n;
 	int             n2;
-	uint32_t   l;
+	uint32_t	l;
 	int             c;
 	int             ret;
 
@@ -884,7 +904,7 @@
 		return 0;
 	}
 
-	ret = read4(dearmour, errors, readinfo, cbinfo, &c, &n, &l);
+	ret = read4(stream, dearmour, errors, readinfo, cbinfo, &c, &n, &l);
 	if (ret < 0) {
 		PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "Badly formed base64");
 		return 0;
@@ -907,7 +927,7 @@
 		dearmour->buffered = 1;
 		dearmour->eof64 = 1;
 		l >>= 4;
-		c = read_char(dearmour, errors, readinfo, cbinfo, 0);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
 		if (c != '=') {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 					"Badly terminated base64");
@@ -939,14 +959,14 @@
 			(void) fprintf(stderr, "decode64: bad c (=)\n");
 			return 0;
 		}
-		c = read_and_eat_whitespace(dearmour, errors, readinfo, cbinfo,
+		c = read_and_eat_whitespace(stream, dearmour, errors, readinfo, cbinfo,
 				1);
 		if (c != '\n') {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 				"No newline at base64 end");
 			return 0;
 		}
-		c = read_char(dearmour, errors, readinfo, cbinfo, 0);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
 		if (c != '=') {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 				"No checksum at base64 end");
@@ -955,23 +975,23 @@
 	}
 	if (c == '=') {
 		/* now we are at the checksum */
-		ret = read4(dearmour, errors, readinfo, cbinfo, &c, &n,
+		ret = read4(stream, dearmour, errors, readinfo, cbinfo, &c, &n,
 				&dearmour->read_checksum);
 		if (ret < 0 || n != 4) {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 					"Error in checksum");
 			return 0;
 		}
-		c = read_char(dearmour, errors, readinfo, cbinfo, 1);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
 		if (dearmour->allow_trailing_whitespace)
-			c = eat_whitespace(c, dearmour, errors, readinfo, cbinfo,
+			c = eat_whitespace(stream, c, dearmour, errors, readinfo, cbinfo,
 					1);
 		if (c != '\n') {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 					"Badly terminated checksum");
 			return 0;
 		}
-		c = read_char(dearmour, errors, readinfo, cbinfo, 0);
+		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
 		if (c != '-') {
 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 					"Bad base64 trailer (2)");
@@ -980,7 +1000,7 @@
 	}
 	if (c == '-') {
 		for (n = 0; n < 4; ++n)
-			if (read_char(dearmour, errors, readinfo, cbinfo,
+			if (read_char(stream, dearmour, errors, readinfo, cbinfo,
 						0) != '-') {
 				PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
 						"Bad base64 trailer");
@@ -1024,7 +1044,7 @@
 /* packets... it also calls back for the text between the blocks. */
 
 static int 
-armoured_data_reader(void *dest_, size_t length, pgp_error_t **errors,
+armoured_data_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors,
 		     pgp_reader_t *readinfo,
 		     pgp_cbdata_t *cbinfo)
 {
@@ -1061,7 +1081,7 @@
 			 * it is just an EOF (and not a BLOCK_END)
 			 */
 			while (!dearmour->seen_nl) {
-				if ((c = unarmoured_read_char(dearmour, errors,
+				if ((c = unarmoured_read_char(stream, dearmour, errors,
 						readinfo, cbinfo, 1)) < 0) {
 					return 0;
 				}
@@ -1075,7 +1095,7 @@
 			flush(dearmour, cbinfo);
 			/* Find and consume the 5 leading '-' */
 			for (count = 0; count < 5; ++count) {
-				if ((c = unarmoured_read_char(dearmour, errors,
+				if ((c = unarmoured_read_char(stream, dearmour, errors,
 						readinfo, cbinfo, 0)) < 0) {
 					return 0;
 				}
@@ -1086,7 +1106,7 @@
 
 			/* Now find the block type */
 			for (n = 0; n < sizeof(buf) - 1;) {
-				if ((c = unarmoured_read_char(dearmour, errors,
+				if ((c = unarmoured_read_char(stream, dearmour, errors,
 						readinfo, cbinfo, 0)) < 0) {
 					return 0;
 				}
@@ -1103,7 +1123,7 @@
 
 			/* Consume trailing '-' */
 			for (count = 1; count < 5; ++count) {
-				if ((c = unarmoured_read_char(dearmour, errors,
+				if ((c = unarmoured_read_char(stream, dearmour, errors,
 						readinfo, cbinfo, 0)) < 0) {
 					return 0;
 				}
@@ -1114,12 +1134,12 @@
 			}
 
 			/* Consume final NL */
-			if ((c = unarmoured_read_char(dearmour, errors, readinfo,
+			if ((c = unarmoured_read_char(stream, dearmour, errors, readinfo,
 						cbinfo, 1)) < 0) {
 				return 0;
 			}
 			if (dearmour->allow_trailing_whitespace) {
-				if ((c = eat_whitespace(c, dearmour, errors,
+				if ((c = eat_whitespace(stream, c, dearmour, errors,
 						readinfo, cbinfo, 1)) < 0) {
 					return 0;
 				}
@@ -1139,7 +1159,7 @@
 			 * But now we've seen a header line, then errors are
 			 * EARLY_EOF
 			 */
-			if ((ret = parse_headers(dearmour, errors, readinfo,
+			if ((ret = parse_headers(stream, dearmour, errors, readinfo,
 					cbinfo)) <= 0) {
 				return -1;
 			}
@@ -1155,7 +1175,7 @@
 				CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER,
 					cbinfo,
 					&content);
-				ret = process_dash_escaped(dearmour, errors,
+				ret = process_dash_escaped(stream, dearmour, errors,
 						readinfo, cbinfo);
 				if (ret <= 0) {
 					return ret;
@@ -1177,7 +1197,7 @@
 			while (length > 0) {
 				if (!dearmour->buffered) {
 					if (!dearmour->eof64) {
-						ret = decode64(dearmour,
+						ret = decode64(stream, dearmour,
 							errors, readinfo, cbinfo);
 						if (ret <= 0) {
 							return ret;
@@ -1214,7 +1234,7 @@
 
 		case AT_TRAILER_NAME:
 			for (n = 0; n < sizeof(buf) - 1;) {
-				if ((c = read_char(dearmour, errors, readinfo,
+				if ((c = read_char(stream, dearmour, errors, readinfo,
 						cbinfo, 0)) < 0) {
 					return -1;
 				}
@@ -1237,7 +1257,7 @@
 
 			/* Consume trailing '-' */
 			for (count = 1; count < 5; ++count) {
-				if ((c = read_char(dearmour, errors, readinfo,
+				if ((c = read_char(stream, dearmour, errors, readinfo,
 						cbinfo, 0)) < 0) {
 					return -1;
 				}
@@ -1249,12 +1269,12 @@
 			}
 
 			/* Consume final NL */
-			if ((c = read_char(dearmour, errors, readinfo, cbinfo,
+			if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo,
 						1)) < 0) {
 				return -1;
 			}
 			if (dearmour->allow_trailing_whitespace) {
-				if ((c = eat_whitespace(c, dearmour, errors,
+				if ((c = eat_whitespace(stream, c, dearmour, errors,
 						readinfo, cbinfo, 1)) < 0) {
 					return 0;
 				}
@@ -1270,7 +1290,7 @@
 						errors)) {
 					return -1;
 				}
-				if ((ret = parse_headers(dearmour, errors,
+				if ((ret = parse_headers(stream, dearmour, errors,
 						readinfo, cbinfo)) <= 0) {
 					return ret;
 				}
@@ -1375,7 +1395,7 @@
 } encrypted_t;
 
 static int 
-encrypted_data_reader(void *dest,
+encrypted_data_reader(pgp_stream_t *stream, void *dest,
 			size_t length,
 			pgp_error_t **errors,
 			pgp_reader_t *readinfo,
@@ -1454,7 +1474,7 @@
 				n = (unsigned)length;
 			}
 
-			if (!pgp_stacked_limited_read(buffer, n,
+			if (!pgp_stacked_limited_read(stream, buffer, n,
 				encrypted->region, errors, readinfo, cbinfo)) {
 				return -1;
 			}
@@ -1551,7 +1571,7 @@
   Then passes up plaintext as requested
 */
 static int 
-se_ip_data_reader(void *dest_,
+se_ip_data_reader(pgp_stream_t *stream, void *dest_,
 			size_t len,
 			pgp_error_t **errors,
 			pgp_reader_t *readinfo,
@@ -1592,7 +1612,7 @@
 		}
 
 		/* read entire SE IP packet */
-		if (!pgp_stacked_limited_read(buf, decrypted_region.length,
+		if (!pgp_stacked_limited_read(stream, buf, decrypted_region.length,
 				&decrypted_region, errors, readinfo, cbinfo)) {
 			free(buf);
 			return -1;
@@ -1744,7 +1764,7 @@
  * PGP_R_EARLY_EOF and PGP_R_ERROR push errors on the stack
  */
 static int 
-fd_reader(void *dest, size_t length, pgp_error_t **errors,
+fd_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
 	  pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
 	mmap_reader_t	*reader;
@@ -1752,9 +1772,14 @@
 
 	__PGP_USED(cbinfo);
 	reader = pgp_reader_get_arg(readinfo);
-	n = (int)read(reader->fd, dest, length);
-	if (n == 0)
+	if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
+		n = read_partial_data(stream, dest, length);
+	} else {
+		n = (int)read(reader->fd, dest, length);
+	}
+	if (n == 0) {
 		return 0;
+	}
 	if (n < 0) {
 		PGP_SYSTEM_ERROR_1(errors, PGP_E_R_READ_FAILED, "read",
 				   "file descriptor %d", reader->fd);
@@ -1796,7 +1821,7 @@
 } reader_mem_t;
 
 static int 
-mem_reader(void *dest, size_t length, pgp_error_t **errors,
+mem_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
 	   pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
 	reader_mem_t *reader = pgp_reader_get_arg(readinfo);
@@ -1804,18 +1829,20 @@
 
 	__PGP_USED(cbinfo);
 	__PGP_USED(errors);
-
-	if (reader->offset + length > reader->length)
-		n = (unsigned)(reader->length - reader->offset);
-	else
-		n = (unsigned)length;
-
-	if (n == (unsigned)0)
-		return 0;
-
-	memcpy(dest, reader->buffer + reader->offset, n);
-	reader->offset += n;
-
+	if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
+		n = read_partial_data(stream, dest, length);
+	} else {
+		if (reader->offset + length > reader->length) {
+			n = (unsigned)(reader->length - reader->offset);
+		} else {
+			n = (unsigned)length;
+		}
+		if (n == (unsigned)0) {
+			return 0;
+		}
+		memcpy(dest, reader->buffer + reader->offset, n);
+		reader->offset += n;
+	}
 	return n;
 }
 
@@ -2266,7 +2293,7 @@
 /**************************************************************************/
 
 static int 
-hash_reader(void *dest,
+hash_reader(pgp_stream_t *stream, void *dest,
 		size_t length,
 		pgp_error_t **errors,
 		pgp_reader_t *readinfo,
@@ -2275,7 +2302,7 @@
 	pgp_hash_t	*hash = pgp_reader_get_arg(readinfo);
 	int		 r;
 	
-	r = pgp_stacked_read(dest, length, errors, readinfo, cbinfo);
+	r = pgp_stacked_read(stream, dest, length, errors, readinfo, cbinfo);
 	if (r <= 0) {
 		return r;
 	}
@@ -2310,7 +2337,7 @@
 
 /* read memory from the previously mmap-ed file */
 static int 
-mmap_reader(void *dest, size_t length, pgp_error_t **errors,
+mmap_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
 	  pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
 {
 	mmap_reader_t	*mem = pgp_reader_get_arg(readinfo);
@@ -2319,10 +2346,14 @@
 
 	__PGP_USED(errors);
 	__PGP_USED(cbinfo);
-	n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
-	if (n > 0) {
-		(void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
-		mem->offset += n;
+	if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
+		n = read_partial_data(stream, dest, length);
+	} else {
+		n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
+		if (n > 0) {
+			(void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
+			mem->offset += n;
+		}
 	}
 	return (int)n;
 }
Index: src/crypto/external/bsd/netpgp/dist/src/lib/version.h
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/version.h:1.44 src/crypto/external/bsd/netpgp/dist/src/lib/version.h:1.45
--- src/crypto/external/bsd/netpgp/dist/src/lib/version.h:1.44	Sun Nov  7 08:40:00 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/version.h	Thu Nov 11 00:58:05 2010
@@ -58,7 +58,7 @@
 #endif
 
 /* development versions have .99 suffix */
-#define NETPGP_BASE_VERSION	"3.99.14"
+#define NETPGP_BASE_VERSION	"3.99.15"
 
 #define NETPGP_VERSION_CAT(a, b)	"NetPGP portable " a "/[" b "]"
 #define NETPGP_VERSION_STRING \

Index: src/crypto/external/bsd/netpgp/dist/src/lib/validate.c
diff -u src/crypto/external/bsd/netpgp/dist/src/lib/validate.c:1.42 src/crypto/external/bsd/netpgp/dist/src/lib/validate.c:1.43
--- src/crypto/external/bsd/netpgp/dist/src/lib/validate.c:1.42	Sun Nov  7 08:39:59 2010
+++ src/crypto/external/bsd/netpgp/dist/src/lib/validate.c	Thu Nov 11 00:58:04 2010
@@ -54,7 +54,7 @@
 
 #if defined(__NetBSD__)
 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: validate.c,v 1.42 2010/11/07 08:39:59 agc Exp $");
+__RCSID("$NetBSD: validate.c,v 1.43 2010/11/11 00:58:04 agc Exp $");
 #endif
 
 #include <sys/types.h>
@@ -90,12 +90,13 @@
 
 
 static int 
-keydata_reader(void *dest, size_t length, pgp_error_t **errors,
+keydata_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
 	       pgp_reader_t *readinfo,
 	       pgp_cbdata_t *cbinfo)
 {
 	validate_reader_t *reader = pgp_reader_get_arg(readinfo);
 
+	__PGP_USED(stream);
 	__PGP_USED(errors);
 	__PGP_USED(cbinfo);
 	if (reader->offset == reader->key->packets[reader->packet].length) {

Reply via email to