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) {