xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c (revision 0294a66b694d2a57b43f64b66c7a4aee89316c4e)
12232f800Sagc /*-
22232f800Sagc  * Copyright (c) 2009 The NetBSD Foundation, Inc.
32232f800Sagc  * All rights reserved.
42232f800Sagc  *
52232f800Sagc  * This code is derived from software contributed to The NetBSD Foundation
62232f800Sagc  * by Alistair Crooks (agc@NetBSD.org)
72232f800Sagc  *
82232f800Sagc  * Redistribution and use in source and binary forms, with or without
92232f800Sagc  * modification, are permitted provided that the following conditions
102232f800Sagc  * are met:
112232f800Sagc  * 1. Redistributions of source code must retain the above copyright
122232f800Sagc  *    notice, this list of conditions and the following disclaimer.
132232f800Sagc  * 2. Redistributions in binary form must reproduce the above copyright
142232f800Sagc  *    notice, this list of conditions and the following disclaimer in the
152232f800Sagc  *    documentation and/or other materials provided with the distribution.
162232f800Sagc  *
172232f800Sagc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
182232f800Sagc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
192232f800Sagc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
202232f800Sagc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
212232f800Sagc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
222232f800Sagc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
232232f800Sagc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
242232f800Sagc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
252232f800Sagc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
262232f800Sagc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
272232f800Sagc  * POSSIBILITY OF SUCH DAMAGE.
282232f800Sagc  */
2993bf6008Sagc /*
3093bf6008Sagc  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
3193bf6008Sagc  * All rights reserved.
3293bf6008Sagc  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
3393bf6008Sagc  * their moral rights under the UK Copyright Design and Patents Act 1988 to
3493bf6008Sagc  * be recorded as the authors of this copyright work.
3593bf6008Sagc  *
3693bf6008Sagc  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
3793bf6008Sagc  * use this file except in compliance with the License.
3893bf6008Sagc  *
3993bf6008Sagc  * You may obtain a copy of the License at
4093bf6008Sagc  *     http://www.apache.org/licenses/LICENSE-2.0
4193bf6008Sagc  *
4293bf6008Sagc  * Unless required by applicable law or agreed to in writing, software
4393bf6008Sagc  * distributed under the License is distributed on an "AS IS" BASIS,
4493bf6008Sagc  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4593bf6008Sagc  *
4693bf6008Sagc  * See the License for the specific language governing permissions and
4793bf6008Sagc  * limitations under the License.
4893bf6008Sagc  */
4993bf6008Sagc 
5093bf6008Sagc /** \file
5193bf6008Sagc  * \brief Parser for OpenPGP packets
5293bf6008Sagc  */
5393bf6008Sagc #include "config.h"
5493bf6008Sagc 
5557324b9fSagc #ifdef HAVE_SYS_CDEFS_H
5657324b9fSagc #include <sys/cdefs.h>
5757324b9fSagc #endif
5857324b9fSagc 
5957324b9fSagc #if defined(__NetBSD__)
6057324b9fSagc __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
61*0294a66bSjhigh __RCSID("$NetBSD: packet-parse.c,v 1.54 2022/08/26 19:18:38 jhigh Exp $");
6257324b9fSagc #endif
6357324b9fSagc 
64b0df0a22Sagc #include <sys/types.h>
65b0df0a22Sagc #include <sys/param.h>
66b0df0a22Sagc 
6793bf6008Sagc #ifdef HAVE_OPENSSL_CAST_H
6893bf6008Sagc #include <openssl/cast.h>
6993bf6008Sagc #endif
7093bf6008Sagc 
7193bf6008Sagc #include <stdarg.h>
7293bf6008Sagc #include <stdlib.h>
7393bf6008Sagc #include <string.h>
7493bf6008Sagc 
7593bf6008Sagc #ifdef HAVE_UNISTD_H
7693bf6008Sagc #include <unistd.h>
7793bf6008Sagc #endif
7893bf6008Sagc 
7993bf6008Sagc #ifdef HAVE_LIMITS_H
8093bf6008Sagc #include <limits.h>
8193bf6008Sagc #endif
8293bf6008Sagc 
834b3a3e18Sagc #include "packet.h"
844b3a3e18Sagc #include "packet-parse.h"
854b3a3e18Sagc #include "keyring.h"
864b3a3e18Sagc #include "errors.h"
874b3a3e18Sagc #include "packet-show.h"
884b3a3e18Sagc #include "create.h"
894b3a3e18Sagc #include "readerwriter.h"
904b3a3e18Sagc #include "netpgpdefs.h"
914b3a3e18Sagc #include "crypto.h"
926715e11aSagc #include "netpgpdigest.h"
934b3a3e18Sagc 
94efdd9dbaSagc #define ERRP(cbinfo, cont, err)	do {					\
95d427c17dSagc 	cont.u.error = err;						\
96fc1f8641Sagc 	CALLBACK(PGP_PARSER_ERROR, cbinfo, &cont);			\
974b3a3e18Sagc 	return 0;							\
9893bf6008Sagc 	/*NOTREACHED*/							\
9993bf6008Sagc } while(/*CONSTCOND*/0)
10093bf6008Sagc 
10193bf6008Sagc /**
1026715e11aSagc  * limread_data reads the specified amount of the subregion's data
10393bf6008Sagc  * into a data_t structure
10493bf6008Sagc  *
10593bf6008Sagc  * \param data	Empty structure which will be filled with data
10693bf6008Sagc  * \param len	Number of octets to read
10793bf6008Sagc  * \param subregion
10841335e2dSagc  * \param stream	How to parse
10993bf6008Sagc  *
11093bf6008Sagc  * \return 1 on success, 0 on failure
11193bf6008Sagc  */
11293bf6008Sagc static int
limread_data(pgp_data_t * data,unsigned len,pgp_region_t * subregion,pgp_stream_t * stream)113fc1f8641Sagc limread_data(pgp_data_t *data, unsigned len,
114fc1f8641Sagc 		  pgp_region_t *subregion, pgp_stream_t *stream)
11593bf6008Sagc {
11693bf6008Sagc 	data->len = len;
11793bf6008Sagc 
11857324b9fSagc 	if (subregion->length - subregion->readc < len) {
1196715e11aSagc 		(void) fprintf(stderr, "limread_data: bad length\n");
120ed0df671Sagc 		return 0;
121ed0df671Sagc 	}
12293bf6008Sagc 
12393bf6008Sagc 	data->contents = calloc(1, data->len);
1246715e11aSagc 	if (!data->contents) {
12593bf6008Sagc 		return 0;
1266715e11aSagc 	}
12793bf6008Sagc 
128b0df0a22Sagc 	return pgp_limited_read(stream, data->contents, data->len, subregion,
12941335e2dSagc 			&stream->errors, &stream->readinfo, &stream->cbinfo);
13093bf6008Sagc }
13193bf6008Sagc 
13293bf6008Sagc /**
13393bf6008Sagc  * read_data reads the remainder of the subregion's data
13493bf6008Sagc  * into a data_t structure
13593bf6008Sagc  *
13693bf6008Sagc  * \param data
13793bf6008Sagc  * \param subregion
13841335e2dSagc  * \param stream
13993bf6008Sagc  *
14093bf6008Sagc  * \return 1 on success, 0 on failure
14193bf6008Sagc  */
14293bf6008Sagc static int
read_data(pgp_data_t * data,pgp_region_t * region,pgp_stream_t * stream)143fc1f8641Sagc read_data(pgp_data_t *data, pgp_region_t *region, pgp_stream_t *stream)
14493bf6008Sagc {
145d21b929eSagc 	int	cc;
14693bf6008Sagc 
147d21b929eSagc 	cc = region->length - region->readc;
14841335e2dSagc 	return (cc >= 0) ? limread_data(data, (unsigned)cc, region, stream) : 0;
14993bf6008Sagc }
15093bf6008Sagc 
15193bf6008Sagc /**
15293bf6008Sagc  * Reads the remainder of the subregion as a string.
15393bf6008Sagc  * It is the user's responsibility to free the memory allocated here.
15493bf6008Sagc  */
15593bf6008Sagc 
15693bf6008Sagc static int
read_unsig_str(uint8_t ** str,pgp_region_t * subregion,pgp_stream_t * stream)157fc1f8641Sagc read_unsig_str(uint8_t **str, pgp_region_t *subregion,
158fc1f8641Sagc 		     pgp_stream_t *stream)
15993bf6008Sagc {
16057036e70Sagc 	size_t	len;
16193bf6008Sagc 
16257324b9fSagc 	len = subregion->length - subregion->readc;
1636715e11aSagc 	if ((*str = calloc(1, len + 1)) == NULL) {
16493bf6008Sagc 		return 0;
1656715e11aSagc 	}
1666715e11aSagc 	if (len &&
167b0df0a22Sagc 	    !pgp_limited_read(stream, *str, len, subregion, &stream->errors,
16841335e2dSagc 				     &stream->readinfo, &stream->cbinfo)) {
16993bf6008Sagc 		return 0;
1706715e11aSagc 	}
17193bf6008Sagc 	(*str)[len] = '\0';
17293bf6008Sagc 	return 1;
17393bf6008Sagc }
17493bf6008Sagc 
17593bf6008Sagc static int
read_string(char ** str,pgp_region_t * subregion,pgp_stream_t * stream)176fc1f8641Sagc read_string(char **str, pgp_region_t *subregion, pgp_stream_t *stream)
17793bf6008Sagc {
178b15ec256Sagc 	return read_unsig_str((uint8_t **) str, subregion, stream);
17993bf6008Sagc }
18093bf6008Sagc 
18193bf6008Sagc void
pgp_init_subregion(pgp_region_t * subregion,pgp_region_t * region)182fc1f8641Sagc pgp_init_subregion(pgp_region_t *subregion, pgp_region_t *region)
18393bf6008Sagc {
18493bf6008Sagc 	(void) memset(subregion, 0x0, sizeof(*subregion));
18593bf6008Sagc 	subregion->parent = region;
18693bf6008Sagc }
18793bf6008Sagc 
18893bf6008Sagc /*
189fc1f8641Sagc  * XXX: replace pgp_ptag_t with something more appropriate for limiting reads
19093bf6008Sagc  */
19193bf6008Sagc 
19293bf6008Sagc /**
19393bf6008Sagc  * low-level function to read data from reader function
19493bf6008Sagc  *
19593bf6008Sagc  * Use this function, rather than calling the reader directly.
19693bf6008Sagc  *
19741335e2dSagc  * If the accumulate flag is set in *stream, the function
19893bf6008Sagc  * adds the read data to the accumulated data, and updates
19993bf6008Sagc  * the accumulated length. This is useful if, for example,
20093bf6008Sagc  * the application wants access to the raw data as well as the
20193bf6008Sagc  * parsed data.
20293bf6008Sagc  *
20393bf6008Sagc  * This function will also try to read the entire amount asked for, but not
20493bf6008Sagc  * if it is over INT_MAX. Obviously many callers will know that they
20593bf6008Sagc  * never ask for that much and so can avoid the extra complexity of
20693bf6008Sagc  * dealing with return codes and filled-in lengths.
20793bf6008Sagc  *
20893bf6008Sagc  * \param *dest
20993bf6008Sagc  * \param *plength
21093bf6008Sagc  * \param flags
21141335e2dSagc  * \param *stream
21293bf6008Sagc  *
213fc1f8641Sagc  * \return PGP_R_OK
214fc1f8641Sagc  * \return PGP_R_PARTIAL_READ
215fc1f8641Sagc  * \return PGP_R_EOF
216fc1f8641Sagc  * \return PGP_R_EARLY_EOF
21793bf6008Sagc  *
218fc1f8641Sagc  * \sa #pgp_reader_ret_t for details of return codes
21993bf6008Sagc  */
22093bf6008Sagc 
22193bf6008Sagc static int
sub_base_read(pgp_stream_t * stream,void * dest,size_t length,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)222b0df0a22Sagc sub_base_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
223fc1f8641Sagc 	      pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
22493bf6008Sagc {
22593bf6008Sagc 	size_t          n;
22693bf6008Sagc 
22793bf6008Sagc 	/* reading more than this would look like an error */
22893bf6008Sagc 	if (length > INT_MAX)
22993bf6008Sagc 		length = INT_MAX;
23093bf6008Sagc 
23193bf6008Sagc 	for (n = 0; n < length;) {
2326715e11aSagc 		int	r;
23393bf6008Sagc 
234b0df0a22Sagc 		r = readinfo->reader(stream, (char *) dest + n, length - n, errors,
2356715e11aSagc 			readinfo, cbinfo);
236ed0df671Sagc 		if (r > (int)(length - n)) {
237ed0df671Sagc 			(void) fprintf(stderr, "sub_base_read: bad read\n");
238ed0df671Sagc 			return 0;
239ed0df671Sagc 		}
2406715e11aSagc 		if (r < 0) {
24193bf6008Sagc 			return r;
2426715e11aSagc 		}
2436715e11aSagc 		if (r == 0) {
24493bf6008Sagc 			break;
2456715e11aSagc 		}
24657036e70Sagc 		n += (unsigned)r;
24793bf6008Sagc 	}
24893bf6008Sagc 
2496715e11aSagc 	if (n == 0) {
25093bf6008Sagc 		return 0;
2516715e11aSagc 	}
2522232f800Sagc 	if (readinfo->accumulate) {
2532232f800Sagc 		if (readinfo->asize < readinfo->alength) {
254ed0df671Sagc 			(void) fprintf(stderr, "sub_base_read: bad size\n");
255ed0df671Sagc 			return 0;
256ed0df671Sagc 		}
2572232f800Sagc 		if (readinfo->alength + n > readinfo->asize) {
258b15ec256Sagc 			uint8_t	*temp;
25957036e70Sagc 
2603f685a78Sagc 			readinfo->asize = (readinfo->asize * 2) + (unsigned)n;
26157036e70Sagc 			temp = realloc(readinfo->accumulated, readinfo->asize);
26257036e70Sagc 			if (temp == NULL) {
26357036e70Sagc 				(void) fprintf(stderr,
26457036e70Sagc 					"sub_base_read: bad alloc\n");
26557036e70Sagc 				return 0;
26657036e70Sagc 			}
26757036e70Sagc 			readinfo->accumulated = temp;
26893bf6008Sagc 		}
2692232f800Sagc 		if (readinfo->asize < readinfo->alength + n) {
270ed0df671Sagc 			(void) fprintf(stderr, "sub_base_read: bad realloc\n");
271ed0df671Sagc 			return 0;
272ed0df671Sagc 		}
2736715e11aSagc 		(void) memcpy(readinfo->accumulated + readinfo->alength, dest,
2746715e11aSagc 				n);
27593bf6008Sagc 	}
27693bf6008Sagc 	/* we track length anyway, because it is used for packet offsets */
2773f685a78Sagc 	readinfo->alength += (unsigned)n;
27893bf6008Sagc 	/* and also the position */
2793f685a78Sagc 	readinfo->position += (unsigned)n;
28093bf6008Sagc 
2813f685a78Sagc 	return (int)n;
28293bf6008Sagc }
28393bf6008Sagc 
28493bf6008Sagc int
pgp_stacked_read(pgp_stream_t * stream,void * dest,size_t length,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)285b0df0a22Sagc pgp_stacked_read(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
286fc1f8641Sagc 		 pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
28793bf6008Sagc {
288b0df0a22Sagc 	return sub_base_read(stream, dest, length, errors, readinfo->next, cbinfo);
28993bf6008Sagc }
29093bf6008Sagc 
29193bf6008Sagc /* This will do a full read so long as length < MAX_INT */
29293bf6008Sagc static int
base_read(uint8_t * dest,size_t length,pgp_stream_t * stream)293fc1f8641Sagc base_read(uint8_t *dest, size_t length, pgp_stream_t *stream)
29493bf6008Sagc {
295b0df0a22Sagc 	return sub_base_read(stream, dest, length, &stream->errors, &stream->readinfo,
29641335e2dSagc 			     &stream->cbinfo);
29793bf6008Sagc }
29893bf6008Sagc 
29993bf6008Sagc /*
30093bf6008Sagc  * Read a full size_t's worth. If the return is < than length, then
30193bf6008Sagc  * *last_read tells you why - < 0 for an error, == 0 for EOF
30293bf6008Sagc  */
30393bf6008Sagc 
30493bf6008Sagc static size_t
full_read(pgp_stream_t * stream,uint8_t * dest,size_t length,int * last_read,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)305b0df0a22Sagc full_read(pgp_stream_t *stream, uint8_t *dest,
30657324b9fSagc 		size_t length,
30757324b9fSagc 		int *last_read,
308fc1f8641Sagc 		pgp_error_t **errors,
309fc1f8641Sagc 		pgp_reader_t *readinfo,
310fc1f8641Sagc 		pgp_cbdata_t *cbinfo)
31193bf6008Sagc {
31293bf6008Sagc 	size_t          t;
31393bf6008Sagc 	int             r = 0;	/* preset in case some loon calls with length
31493bf6008Sagc 				 * == 0 */
31593bf6008Sagc 
31693bf6008Sagc 	for (t = 0; t < length;) {
317b0df0a22Sagc 		r = sub_base_read(stream, dest + t, length - t, errors, readinfo,
31857324b9fSagc 				cbinfo);
31993bf6008Sagc 		if (r <= 0) {
32093bf6008Sagc 			*last_read = r;
32193bf6008Sagc 			return t;
32293bf6008Sagc 		}
32357036e70Sagc 		t += (size_t)r;
32493bf6008Sagc 	}
32593bf6008Sagc 
32693bf6008Sagc 	*last_read = r;
32793bf6008Sagc 
32893bf6008Sagc 	return t;
32993bf6008Sagc }
33093bf6008Sagc 
33193bf6008Sagc 
33293bf6008Sagc 
33393bf6008Sagc /** Read a scalar value of selected length from reader.
33493bf6008Sagc  *
33593bf6008Sagc  * Read an unsigned scalar value from reader in Big Endian representation.
33693bf6008Sagc  *
33793bf6008Sagc  * This function does not know or care about packet boundaries. It
33893bf6008Sagc  * also assumes that an EOF is an error.
33993bf6008Sagc  *
34093bf6008Sagc  * \param *result	The scalar value is stored here
34193bf6008Sagc  * \param *reader	Our reader
34293bf6008Sagc  * \param length	How many bytes to read
3434b3a3e18Sagc  * \return		1 on success, 0 on failure
34493bf6008Sagc  */
3454b3a3e18Sagc static unsigned
_read_scalar(unsigned * result,unsigned length,pgp_stream_t * stream)34693bf6008Sagc _read_scalar(unsigned *result, unsigned length,
347fc1f8641Sagc 	     pgp_stream_t *stream)
34893bf6008Sagc {
34993bf6008Sagc 	unsigned        t = 0;
35093bf6008Sagc 
351ed0df671Sagc 	if (length > sizeof(*result)) {
352ed0df671Sagc 		(void) fprintf(stderr, "_read_scalar: bad length\n");
353ed0df671Sagc 		return 0;
354ed0df671Sagc 	}
35593bf6008Sagc 
35693bf6008Sagc 	while (length--) {
357b15ec256Sagc 		uint8_t	c;
35893bf6008Sagc 		int	r;
35993bf6008Sagc 
36041335e2dSagc 		r = base_read(&c, 1, stream);
36193bf6008Sagc 		if (r != 1)
3624b3a3e18Sagc 			return 0;
36357324b9fSagc 		t = (t << 8) + c;
36493bf6008Sagc 	}
36593bf6008Sagc 
36693bf6008Sagc 	*result = t;
3674b3a3e18Sagc 	return 1;
36893bf6008Sagc }
36993bf6008Sagc 
37093bf6008Sagc /**
37193bf6008Sagc  * \ingroup Core_ReadPackets
37293bf6008Sagc  * \brief Read bytes from a region within the packet.
37393bf6008Sagc  *
37493bf6008Sagc  * Read length bytes into the buffer pointed to by *dest.
37593bf6008Sagc  * Make sure we do not read over the packet boundary.
376fc1f8641Sagc  * Updates the Packet Tag's pgp_ptag_t::readc.
37793bf6008Sagc  *
37893bf6008Sagc  * If length would make us read over the packet boundary, or if
37993bf6008Sagc  * reading fails, we call the callback with an error.
38093bf6008Sagc  *
38193bf6008Sagc  * Note that if the region is indeterminate, this can return a short
38293bf6008Sagc  * read - check region->last_read for the length. EOF is indicated by
38393bf6008Sagc  * a success return and region->last_read == 0 in this case (for a
38493bf6008Sagc  * region of known length, EOF is an error).
38593bf6008Sagc  *
38693bf6008Sagc  * This function makes sure to respect packet boundaries.
38793bf6008Sagc  *
38893bf6008Sagc  * \param dest		The destination buffer
38993bf6008Sagc  * \param length	How many bytes to read
39093bf6008Sagc  * \param region	Pointer to packet region
39193bf6008Sagc  * \param errors    Error stack
3922232f800Sagc  * \param readinfo		Reader info
39393bf6008Sagc  * \param cbinfo	Callback info
3944b3a3e18Sagc  * \return		1 on success, 0 on error
39593bf6008Sagc  */
3964b3a3e18Sagc unsigned
pgp_limited_read(pgp_stream_t * stream,uint8_t * dest,size_t length,pgp_region_t * region,pgp_error_t ** errors,pgp_reader_t * readinfo,pgp_cbdata_t * cbinfo)397b0df0a22Sagc pgp_limited_read(pgp_stream_t *stream, uint8_t *dest,
39857324b9fSagc 			size_t length,
399fc1f8641Sagc 			pgp_region_t *region,
400fc1f8641Sagc 			pgp_error_t **errors,
401fc1f8641Sagc 			pgp_reader_t *readinfo,
402fc1f8641Sagc 			pgp_cbdata_t *cbinfo)
40393bf6008Sagc {
40493bf6008Sagc 	size_t	r;
40593bf6008Sagc 	int	lr;
40693bf6008Sagc 
40757324b9fSagc 	if (!region->indeterminate &&
40857324b9fSagc 	    region->readc + length > region->length) {
40994fcde8eSchristos 		PGP_ERROR_1(errors, PGP_E_P_NOT_ENOUGH_DATA, "%s",
41094fcde8eSchristos 		    "Not enough data");
4114b3a3e18Sagc 		return 0;
41293bf6008Sagc 	}
413b0df0a22Sagc 	r = full_read(stream, dest, length, &lr, errors, readinfo, cbinfo);
41493bf6008Sagc 	if (lr < 0) {
41594fcde8eSchristos 		PGP_ERROR_1(errors, PGP_E_R_READ_FAILED, "%s", "Read failed");
4164b3a3e18Sagc 		return 0;
41793bf6008Sagc 	}
41893bf6008Sagc 	if (!region->indeterminate && r != length) {
41994fcde8eSchristos 		PGP_ERROR_1(errors, PGP_E_R_READ_FAILED, "%s", "Read failed");
4204b3a3e18Sagc 		return 0;
42193bf6008Sagc 	}
4223f685a78Sagc 	region->last_read = (unsigned)r;
42393bf6008Sagc 	do {
4243f685a78Sagc 		region->readc += (unsigned)r;
425ed0df671Sagc 		if (region->parent && region->length > region->parent->length) {
426ed0df671Sagc 			(void) fprintf(stderr,
427ed0df671Sagc 				"ops_limited_read: bad length\n");
4284b3a3e18Sagc 			return 0;
429ed0df671Sagc 		}
430efdd9dbaSagc 	} while ((region = region->parent) != NULL);
4314b3a3e18Sagc 	return 1;
43293bf6008Sagc }
43393bf6008Sagc 
43493bf6008Sagc /**
43593bf6008Sagc    \ingroup Core_ReadPackets
436fc1f8641Sagc    \brief Call pgp_limited_read on next in stack
43793bf6008Sagc */
4384b3a3e18Sagc unsigned
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)439b0df0a22Sagc pgp_stacked_limited_read(pgp_stream_t *stream, uint8_t *dest, unsigned length,
440fc1f8641Sagc 			 pgp_region_t *region,
441fc1f8641Sagc 			 pgp_error_t **errors,
442fc1f8641Sagc 			 pgp_reader_t *readinfo,
443fc1f8641Sagc 			 pgp_cbdata_t *cbinfo)
44493bf6008Sagc {
445b0df0a22Sagc 	return pgp_limited_read(stream, dest, length, region, errors,
44657324b9fSagc 				readinfo->next, cbinfo);
44793bf6008Sagc }
44893bf6008Sagc 
4494b3a3e18Sagc static unsigned
limread(uint8_t * dest,unsigned length,pgp_region_t * region,pgp_stream_t * info)450b15ec256Sagc limread(uint8_t *dest, unsigned length,
451fc1f8641Sagc 	     pgp_region_t *region, pgp_stream_t *info)
45293bf6008Sagc {
453b0df0a22Sagc 	return pgp_limited_read(info, dest, length, region, &info->errors,
4542232f800Sagc 				&info->readinfo, &info->cbinfo);
45593bf6008Sagc }
45693bf6008Sagc 
4574b3a3e18Sagc static unsigned
exact_limread(uint8_t * dest,unsigned len,pgp_region_t * region,pgp_stream_t * stream)458b15ec256Sagc exact_limread(uint8_t *dest, unsigned len,
459fc1f8641Sagc 		   pgp_region_t *region,
460fc1f8641Sagc 		   pgp_stream_t *stream)
46193bf6008Sagc {
4624b3a3e18Sagc 	unsigned   ret;
46393bf6008Sagc 
46441335e2dSagc 	stream->exact_read = 1;
46541335e2dSagc 	ret = limread(dest, len, region, stream);
46641335e2dSagc 	stream->exact_read = 0;
46793bf6008Sagc 	return ret;
46893bf6008Sagc }
46993bf6008Sagc 
47093bf6008Sagc /** Skip over length bytes of this packet.
47193bf6008Sagc  *
4726715e11aSagc  * Calls limread() to skip over some data.
47393bf6008Sagc  *
47493bf6008Sagc  * This function makes sure to respect packet boundaries.
47593bf6008Sagc  *
47693bf6008Sagc  * \param length	How many bytes to skip
47793bf6008Sagc  * \param *region	Pointer to packet region
47841335e2dSagc  * \param *stream	How to parse
479fc1f8641Sagc  * \return		1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()).
48093bf6008Sagc  */
48193bf6008Sagc static int
limskip(unsigned length,pgp_region_t * region,pgp_stream_t * stream)482fc1f8641Sagc limskip(unsigned length, pgp_region_t *region, pgp_stream_t *stream)
48393bf6008Sagc {
484b15ec256Sagc 	uint8_t   buf[NETPGP_BUFSIZ];
48593bf6008Sagc 
48657324b9fSagc 	while (length > 0) {
487efdd9dbaSagc 		unsigned	n = length % NETPGP_BUFSIZ;
488efdd9dbaSagc 
48941335e2dSagc 		if (!limread(buf, n, region, stream)) {
49093bf6008Sagc 			return 0;
4916715e11aSagc 		}
49293bf6008Sagc 		length -= n;
49393bf6008Sagc 	}
49493bf6008Sagc 	return 1;
49593bf6008Sagc }
49693bf6008Sagc 
49793bf6008Sagc /** Read a scalar.
49893bf6008Sagc  *
49993bf6008Sagc  * Read a big-endian scalar of length bytes, respecting packet
5006715e11aSagc  * boundaries (by calling limread() to read the raw data).
50193bf6008Sagc  *
50293bf6008Sagc  * This function makes sure to respect packet boundaries.
50393bf6008Sagc  *
50493bf6008Sagc  * \param *dest		The scalar value is stored here
50593bf6008Sagc  * \param length	How many bytes make up this scalar (at most 4)
50693bf6008Sagc  * \param *region	Pointer to current packet region
50741335e2dSagc  * \param *stream	How to parse
50893bf6008Sagc  * \param *cb		The callback
509fc1f8641Sagc  * \return		1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()).
51093bf6008Sagc  *
51193bf6008Sagc  * \see RFC4880 3.1
51293bf6008Sagc  */
51393bf6008Sagc static int
limread_scalar(unsigned * dest,unsigned len,pgp_region_t * region,pgp_stream_t * stream)5146715e11aSagc limread_scalar(unsigned *dest,
5156715e11aSagc 			unsigned len,
516fc1f8641Sagc 			pgp_region_t *region,
517fc1f8641Sagc 			pgp_stream_t *stream)
51893bf6008Sagc {
519b15ec256Sagc 	uint8_t		c[4] = "";
52093bf6008Sagc 	unsigned        t;
52193bf6008Sagc 	unsigned        n;
52293bf6008Sagc 
5236715e11aSagc 	if (len > 4) {
5246715e11aSagc 		(void) fprintf(stderr, "limread_scalar: bad length\n");
525ed0df671Sagc 		return 0;
526ed0df671Sagc 	}
527ed0df671Sagc 	/*LINTED*/
528ed0df671Sagc 	if (/*CONSTCOND*/sizeof(*dest) < 4) {
5296715e11aSagc 		(void) fprintf(stderr, "limread_scalar: bad dest\n");
530ed0df671Sagc 		return 0;
531ed0df671Sagc 	}
53241335e2dSagc 	if (!limread(c, len, region, stream)) {
53393bf6008Sagc 		return 0;
5346715e11aSagc 	}
5356715e11aSagc 	for (t = 0, n = 0; n < len; ++n) {
53693bf6008Sagc 		t = (t << 8) + c[n];
5376715e11aSagc 	}
53893bf6008Sagc 	*dest = t;
53993bf6008Sagc 	return 1;
54093bf6008Sagc }
54193bf6008Sagc 
54293bf6008Sagc /** Read a scalar.
54393bf6008Sagc  *
54493bf6008Sagc  * Read a big-endian scalar of length bytes, respecting packet
5456715e11aSagc  * boundaries (by calling limread() to read the raw data).
54693bf6008Sagc  *
54793bf6008Sagc  * The value read is stored in a size_t, which is a different size
54893bf6008Sagc  * from an unsigned on some platforms.
54993bf6008Sagc  *
55093bf6008Sagc  * This function makes sure to respect packet boundaries.
55193bf6008Sagc  *
55293bf6008Sagc  * \param *dest		The scalar value is stored here
55393bf6008Sagc  * \param length	How many bytes make up this scalar (at most 4)
55493bf6008Sagc  * \param *region	Pointer to current packet region
55541335e2dSagc  * \param *stream	How to parse
55693bf6008Sagc  * \param *cb		The callback
557fc1f8641Sagc  * \return		1 on success, 0 on error (calls the cb with PGP_PARSER_ERROR in limread()).
55893bf6008Sagc  *
55993bf6008Sagc  * \see RFC4880 3.1
56093bf6008Sagc  */
56193bf6008Sagc static int
limread_size_t(size_t * dest,unsigned length,pgp_region_t * region,pgp_stream_t * stream)5626715e11aSagc limread_size_t(size_t *dest,
56357324b9fSagc 				unsigned length,
564fc1f8641Sagc 				pgp_region_t *region,
565fc1f8641Sagc 				pgp_stream_t *stream)
56693bf6008Sagc {
56793bf6008Sagc 	unsigned        tmp;
56893bf6008Sagc 
56993bf6008Sagc 	/*
57093bf6008Sagc 	 * Note that because the scalar is at most 4 bytes, we don't care if
57193bf6008Sagc 	 * size_t is bigger than usigned
57293bf6008Sagc 	 */
57341335e2dSagc 	if (!limread_scalar(&tmp, length, region, stream))
57493bf6008Sagc 		return 0;
57593bf6008Sagc 
57693bf6008Sagc 	*dest = tmp;
57793bf6008Sagc 	return 1;
57893bf6008Sagc }
57993bf6008Sagc 
58093bf6008Sagc /** Read a timestamp.
58193bf6008Sagc  *
58293bf6008Sagc  * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch (1.1.1970).  They are stored in an unsigned scalar
58393bf6008Sagc  * of 4 bytes.
58493bf6008Sagc  *
5856715e11aSagc  * This function reads the timestamp using limread_scalar().
58693bf6008Sagc  *
58793bf6008Sagc  * This function makes sure to respect packet boundaries.
58893bf6008Sagc  *
58993bf6008Sagc  * \param *dest		The timestamp is stored here
59093bf6008Sagc  * \param *ptag		Pointer to current packet's Packet Tag.
59193bf6008Sagc  * \param *reader	Our reader
59293bf6008Sagc  * \param *cb		The callback
5936715e11aSagc  * \return		see limread_scalar()
59493bf6008Sagc  *
59593bf6008Sagc  * \see RFC4880 3.5
59693bf6008Sagc  */
59793bf6008Sagc static int
limited_read_time(time_t * dest,pgp_region_t * region,pgp_stream_t * stream)598fc1f8641Sagc limited_read_time(time_t *dest, pgp_region_t *region,
599fc1f8641Sagc 		  pgp_stream_t *stream)
60093bf6008Sagc {
601b15ec256Sagc 	uint8_t	c;
60293bf6008Sagc 	time_t	mytime = 0;
60357036e70Sagc 	int	i;
604efdd9dbaSagc 
605efdd9dbaSagc 	/*
606efdd9dbaSagc          * Cannot assume that time_t is 4 octets long -
607efdd9dbaSagc 	 * SunOS 5.10 and NetBSD both have 64-bit time_ts.
608efdd9dbaSagc          */
609aa732d73Sagc 	if (/* CONSTCOND */sizeof(time_t) == 4) {
61041335e2dSagc 		return limread_scalar((unsigned *)(void *)dest, 4, region, stream);
611efdd9dbaSagc 	}
61293bf6008Sagc 	for (i = 0; i < 4; i++) {
61341335e2dSagc 		if (!limread(&c, 1, region, stream)) {
61493bf6008Sagc 			return 0;
6156715e11aSagc 		}
61657324b9fSagc 		mytime = (mytime << 8) + c;
61793bf6008Sagc 	}
61893bf6008Sagc 	*dest = mytime;
61993bf6008Sagc 	return 1;
62093bf6008Sagc }
62193bf6008Sagc 
62293bf6008Sagc /**
62393bf6008Sagc  * \ingroup Core_MPI
62493bf6008Sagc  * Read a multiprecision integer.
62593bf6008Sagc  *
62693bf6008Sagc  * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts.  First there is a 2 byte scalar
62793bf6008Sagc  * indicating the length of the following MPI in Bits.  Then follow the bits that make up the actual number, most
62893bf6008Sagc  * significant bits first (Big Endian).  The most significant bit in the MPI is supposed to be 1 (unless the MPI is
62993bf6008Sagc  * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted).
63093bf6008Sagc  *
63193bf6008Sagc  * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are
63293bf6008Sagc  * supposed to be cleared - I guess. XXX - does anything actually say so?
63393bf6008Sagc  *
63493bf6008Sagc  * This function makes sure to respect packet boundaries.
63593bf6008Sagc  *
63693bf6008Sagc  * \param **pgn		return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed
63793bf6008Sagc  * 				by the caller XXX right ben?
63893bf6008Sagc  * \param *ptag		Pointer to current packet's Packet Tag.
63993bf6008Sagc  * \param *reader	Our reader
64093bf6008Sagc  * \param *cb		The callback
6416715e11aSagc  * \return		1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
642fc1f8641Sagc  * 				 see comment below - the callback is called with a PGP_PARSER_ERROR in case of an error)
64393bf6008Sagc  *
64493bf6008Sagc  * \see RFC4880 3.2
64593bf6008Sagc  */
64693bf6008Sagc static int
limread_mpi(BIGNUM ** pbn,pgp_region_t * region,pgp_stream_t * stream)647fc1f8641Sagc limread_mpi(BIGNUM **pbn, pgp_region_t *region, pgp_stream_t *stream)
64893bf6008Sagc {
649b15ec256Sagc 	uint8_t   buf[NETPGP_BUFSIZ] = "";
650efdd9dbaSagc 					/* an MPI has a 2 byte length part.
65193bf6008Sagc 					 * Length is given in bits, so the
65293bf6008Sagc 					 * largest we should ever need for
65393bf6008Sagc 					 * the buffer is NETPGP_BUFSIZ bytes. */
654efdd9dbaSagc 	unsigned        length;
655efdd9dbaSagc 	unsigned        nonzero;
6564b3a3e18Sagc 	unsigned	ret;
65793bf6008Sagc 
65841335e2dSagc 	stream->reading_mpi_len = 1;
65957036e70Sagc 	ret = (unsigned)limread_scalar(&length, 2, region, stream);
66093bf6008Sagc 
66141335e2dSagc 	stream->reading_mpi_len = 0;
66293bf6008Sagc 	if (!ret)
66393bf6008Sagc 		return 0;
66493bf6008Sagc 
66593bf6008Sagc 	nonzero = length & 7;	/* there should be this many zero bits in the
66693bf6008Sagc 				 * MS byte */
66793bf6008Sagc 	if (!nonzero)
66893bf6008Sagc 		nonzero = 8;
66993bf6008Sagc 	length = (length + 7) / 8;
67093bf6008Sagc 
67193bf6008Sagc 	if (length == 0) {
67293bf6008Sagc 		/* if we try to read a length of 0, then fail */
673fc1f8641Sagc 		if (pgp_get_debug_level(__FILE__)) {
6746715e11aSagc 			(void) fprintf(stderr, "limread_mpi: 0 length\n");
67593bf6008Sagc 		}
67693bf6008Sagc 		return 0;
67793bf6008Sagc 	}
678ed0df671Sagc 	if (length > NETPGP_BUFSIZ) {
6796715e11aSagc 		(void) fprintf(stderr, "limread_mpi: bad length\n");
680ed0df671Sagc 		return 0;
681ed0df671Sagc 	}
68241335e2dSagc 	if (!limread(buf, length, region, stream)) {
68393bf6008Sagc 		return 0;
6846715e11aSagc 	}
685efdd9dbaSagc 	if (((unsigned)buf[0] >> nonzero) != 0 ||
686efdd9dbaSagc 	    !((unsigned)buf[0] & (1U << (nonzero - 1U)))) {
68794fcde8eSchristos 		PGP_ERROR_1(&stream->errors, PGP_E_P_MPI_FORMAT_ERROR,
68894fcde8eSchristos 		    "%s", "MPI Format error");
689efdd9dbaSagc 		/* XXX: Ben, one part of
69093bf6008Sagc 		 * this constraint does
69193bf6008Sagc 		 * not apply to
69293bf6008Sagc 		 * encrypted MPIs the
69393bf6008Sagc 		 * draft says. -- peter */
69493bf6008Sagc 		return 0;
69593bf6008Sagc 	}
696efdd9dbaSagc 	*pbn = BN_bin2bn(buf, (int)length, NULL);
69793bf6008Sagc 	return 1;
69893bf6008Sagc }
69993bf6008Sagc 
700b0df0a22Sagc static unsigned read_new_length(unsigned *, pgp_stream_t *);
701b0df0a22Sagc 
702b0df0a22Sagc /* allocate space, read, and stash data away in a virtual pkt */
703b0df0a22Sagc static void
streamread(pgp_stream_t * stream,unsigned c)704b0df0a22Sagc streamread(pgp_stream_t *stream, unsigned c)
705b0df0a22Sagc {
706b0df0a22Sagc 	int	cc;
707b0df0a22Sagc 
708b0df0a22Sagc 	stream->virtualpkt = realloc(stream->virtualpkt, stream->virtualc + c);
709b0df0a22Sagc 	cc = stream->readinfo.reader(stream, &stream->virtualpkt[stream->virtualc],
710b0df0a22Sagc 		c, &stream->errors, &stream->readinfo, &stream->cbinfo);
711b0df0a22Sagc 	stream->virtualc += cc;
712b0df0a22Sagc }
713b0df0a22Sagc 
714b0df0a22Sagc /* coalesce all the partial blocks together */
715b0df0a22Sagc static int
coalesce_blocks(pgp_stream_t * stream,unsigned length)716b0df0a22Sagc coalesce_blocks(pgp_stream_t *stream, unsigned length)
717b0df0a22Sagc {
718b0df0a22Sagc 	unsigned	c;
719b0df0a22Sagc 
720b0df0a22Sagc 	stream->coalescing = 1;
721b0df0a22Sagc 	/* already read a partial block length - prime the array */
722b0df0a22Sagc 	streamread(stream, length);
723b0df0a22Sagc 	while (read_new_length(&c, stream) && stream->partial_read) {
724b0df0a22Sagc 		/* length we read is partial - add to end of array */
725b0df0a22Sagc 		streamread(stream, c);
726b0df0a22Sagc 	}
727b0df0a22Sagc 	/* not partial - add the last extent to the end of the array */
728b0df0a22Sagc 	streamread(stream, c);
729b0df0a22Sagc 	stream->coalescing = 0;
730b0df0a22Sagc 	return 1;
731b0df0a22Sagc }
732b0df0a22Sagc 
73393bf6008Sagc /** Read some data with a New-Format length from reader.
73493bf6008Sagc  *
73593bf6008Sagc  * \sa Internet-Draft RFC4880.txt Section 4.2.2
73693bf6008Sagc  *
73793bf6008Sagc  * \param *length	Where the decoded length will be put
73841335e2dSagc  * \param *stream	How to parse
7394b3a3e18Sagc  * \return		1 if OK, else 0
74093bf6008Sagc  *
74193bf6008Sagc  */
74293bf6008Sagc 
7434b3a3e18Sagc static unsigned
read_new_length(unsigned * length,pgp_stream_t * stream)744fc1f8641Sagc read_new_length(unsigned *length, pgp_stream_t *stream)
74593bf6008Sagc {
746b15ec256Sagc 	uint8_t   c;
74793bf6008Sagc 
748b0df0a22Sagc 	stream->partial_read = 0;
749b0df0a22Sagc 	if (base_read(&c, 1, stream) != 1) {
7504b3a3e18Sagc 		return 0;
751b0df0a22Sagc 	}
75257324b9fSagc 	if (c < 192) {
75393bf6008Sagc 		/* 1. One-octet packet */
75457324b9fSagc 		*length = c;
7554b3a3e18Sagc 		return 1;
756b0df0a22Sagc 	}
757b0df0a22Sagc 	if (c < 224) {
75893bf6008Sagc 		/* 2. Two-octet packet */
75957324b9fSagc 		unsigned        t = (c - 192) << 8;
76093bf6008Sagc 
761b0df0a22Sagc 		if (base_read(&c, 1, stream) != 1) {
7624b3a3e18Sagc 			return 0;
76393bf6008Sagc 		}
764b0df0a22Sagc 		*length = t + c + 192;
765b0df0a22Sagc 		return 1;
766b0df0a22Sagc 	}
767b0df0a22Sagc 	if (c < 255) {
768b0df0a22Sagc 		/* 3. Partial Body Length */
769b0df0a22Sagc 		stream->partial_read = 1;
770b0df0a22Sagc 		*length = 1 << (c & 0x1f);
771b0df0a22Sagc 		if (!stream->coalescing) {
772b0df0a22Sagc 			/* we have been called from coalesce_blocks -
773b0df0a22Sagc 			 * just return with the partial length */
774b0df0a22Sagc 			coalesce_blocks(stream, *length);
775b0df0a22Sagc 			*length = stream->virtualc;
776b0df0a22Sagc 		}
777b0df0a22Sagc 		return 1;
778b0df0a22Sagc 	}
779b0df0a22Sagc 	/* 4. Five-Octet packet */
780b0df0a22Sagc 	return _read_scalar(length, 4, stream);
78193bf6008Sagc }
78293bf6008Sagc 
78393bf6008Sagc /** Read the length information for a new format Packet Tag.
78493bf6008Sagc  *
78593bf6008Sagc  * New style Packet Tags encode the length in one to five octets.  This function reads the right amount of bytes and
78693bf6008Sagc  * decodes it to the proper length information.
78793bf6008Sagc  *
78893bf6008Sagc  * This function makes sure to respect packet boundaries.
78993bf6008Sagc  *
79093bf6008Sagc  * \param *length	return the length here
79193bf6008Sagc  * \param *ptag		Pointer to current packet's Packet Tag.
79293bf6008Sagc  * \param *reader	Our reader
79393bf6008Sagc  * \param *cb		The callback
7946715e11aSagc  * \return		1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
79593bf6008Sagc  * 				 see comment below)
79693bf6008Sagc  *
79793bf6008Sagc  * \see RFC4880 4.2.2
798fc1f8641Sagc  * \see pgp_ptag_t
79993bf6008Sagc  */
80093bf6008Sagc static int
limited_read_new_length(unsigned * length,pgp_region_t * region,pgp_stream_t * stream)801fc1f8641Sagc limited_read_new_length(unsigned *length, pgp_region_t *region,
802fc1f8641Sagc 			pgp_stream_t *stream)
80393bf6008Sagc {
804b15ec256Sagc 	uint8_t   c = 0x0;
80593bf6008Sagc 
80641335e2dSagc 	if (!limread(&c, 1, region, stream)) {
80793bf6008Sagc 		return 0;
80857324b9fSagc 	}
80957324b9fSagc 	if (c < 192) {
81057324b9fSagc 		*length = c;
81193bf6008Sagc 		return 1;
81293bf6008Sagc 	}
813b0df0a22Sagc 	if (c < 224) {
81457324b9fSagc 		unsigned        t = (c - 192) << 8;
81593bf6008Sagc 
81641335e2dSagc 		if (!limread(&c, 1, region, stream)) {
81793bf6008Sagc 			return 0;
8186715e11aSagc 		}
81957324b9fSagc 		*length = t + c + 192;
82093bf6008Sagc 		return 1;
82193bf6008Sagc 	}
822b0df0a22Sagc 	if (c < 255) {
823b0df0a22Sagc 		stream->partial_read = 1;
824b0df0a22Sagc 		*length = 1 << (c & 0x1f);
825b0df0a22Sagc 		if (!stream->coalescing) {
826b0df0a22Sagc 			/* we have been called from coalesce_blocks -
827b0df0a22Sagc 			 * just return with the partial length */
828b0df0a22Sagc 			coalesce_blocks(stream, *length);
829b0df0a22Sagc 			*length = stream->virtualc;
830b0df0a22Sagc 		}
831b0df0a22Sagc 		return 1;
832b0df0a22Sagc 	}
83341335e2dSagc 	return limread_scalar(length, 4, region, stream);
83493bf6008Sagc }
83593bf6008Sagc 
83693bf6008Sagc /**
83793bf6008Sagc \ingroup Core_Create
83893bf6008Sagc \brief Free allocated memory
83993bf6008Sagc */
840d427c17dSagc void
pgp_data_free(pgp_data_t * data)841fc1f8641Sagc pgp_data_free(pgp_data_t *data)
84293bf6008Sagc {
84357036e70Sagc 	free(data->contents);
84493bf6008Sagc 	data->contents = NULL;
84593bf6008Sagc 	data->len = 0;
84693bf6008Sagc }
84793bf6008Sagc 
84893bf6008Sagc /**
84993bf6008Sagc \ingroup Core_Create
85093bf6008Sagc \brief Free allocated memory
85193bf6008Sagc */
85293bf6008Sagc static void
string_free(char ** str)85393bf6008Sagc string_free(char **str)
85493bf6008Sagc {
85557036e70Sagc 	free(*str);
85693bf6008Sagc 	*str = NULL;
85793bf6008Sagc }
85893bf6008Sagc 
85993bf6008Sagc /**
86093bf6008Sagc \ingroup Core_Create
86193bf6008Sagc \brief Free allocated memory
86293bf6008Sagc */
86393bf6008Sagc /* ! Free packet memory, set pointer to NULL */
86493bf6008Sagc void
pgp_subpacket_free(pgp_subpacket_t * packet)865fc1f8641Sagc pgp_subpacket_free(pgp_subpacket_t *packet)
86693bf6008Sagc {
86757036e70Sagc 	free(packet->raw);
86893bf6008Sagc 	packet->raw = NULL;
8693118701fSmlelstv 	packet->tag = PGP_PTAG_CT_RESERVED;
87093bf6008Sagc }
87193bf6008Sagc 
87293bf6008Sagc /**
87393bf6008Sagc \ingroup Core_Create
87493bf6008Sagc \brief Free allocated memory
87593bf6008Sagc */
87693bf6008Sagc static void
headers_free(pgp_headers_t * headers)877e2c60ad1Sagc headers_free(pgp_headers_t *headers)
87893bf6008Sagc {
87993bf6008Sagc 	unsigned        n;
88093bf6008Sagc 
8812232f800Sagc 	for (n = 0; n < headers->headerc; ++n) {
88257036e70Sagc 		free(headers->headers[n].key);
88357036e70Sagc 		free(headers->headers[n].value);
88493bf6008Sagc 	}
88557036e70Sagc 	free(headers->headers);
88693bf6008Sagc 	headers->headers = NULL;
88793bf6008Sagc }
88893bf6008Sagc 
88993bf6008Sagc /**
89093bf6008Sagc \ingroup Core_Create
89193bf6008Sagc \brief Free allocated memory
89293bf6008Sagc */
89393bf6008Sagc static void
cleartext_trailer_free(struct pgp_hash_t ** trailer)8946b3f1171Sagc cleartext_trailer_free(struct pgp_hash_t **trailer)
89593bf6008Sagc {
896d427c17dSagc 	free(*trailer);
897d427c17dSagc 	*trailer = NULL;
89893bf6008Sagc }
89993bf6008Sagc 
90093bf6008Sagc /**
90193bf6008Sagc \ingroup Core_Create
90293bf6008Sagc \brief Free allocated memory
90393bf6008Sagc */
90493bf6008Sagc static void
cmd_get_passphrase_free(pgp_seckey_passphrase_t * skp)905e2c60ad1Sagc cmd_get_passphrase_free(pgp_seckey_passphrase_t *skp)
90693bf6008Sagc {
90793bf6008Sagc 	if (skp->passphrase && *skp->passphrase) {
90857036e70Sagc 		free(*skp->passphrase);
90993bf6008Sagc 		*skp->passphrase = NULL;
91093bf6008Sagc 	}
91193bf6008Sagc }
91293bf6008Sagc 
91393bf6008Sagc /**
91493bf6008Sagc \ingroup Core_Create
91593bf6008Sagc \brief Free allocated memory
91693bf6008Sagc */
91793bf6008Sagc static void
free_BN(BIGNUM ** pp)91893bf6008Sagc free_BN(BIGNUM **pp)
91993bf6008Sagc {
92093bf6008Sagc 	BN_free(*pp);
92193bf6008Sagc 	*pp = NULL;
92293bf6008Sagc }
92393bf6008Sagc 
92493bf6008Sagc /**
92593bf6008Sagc  * \ingroup Core_Create
92693bf6008Sagc  * \brief Free the memory used when parsing a signature
92793bf6008Sagc  * \param sig
92893bf6008Sagc  */
929efdd9dbaSagc static void
sig_free(pgp_sig_t * sig)930fc1f8641Sagc sig_free(pgp_sig_t *sig)
93193bf6008Sagc {
9322232f800Sagc 	switch (sig->info.key_alg) {
933fc1f8641Sagc 	case PGP_PKA_RSA:
934fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
9353326c4c5Sagc 		free_BN(&sig->info.sig.rsa.sig);
93693bf6008Sagc 		break;
93793bf6008Sagc 
938fc1f8641Sagc 	case PGP_PKA_DSA:
9393326c4c5Sagc 		free_BN(&sig->info.sig.dsa.r);
9403326c4c5Sagc 		free_BN(&sig->info.sig.dsa.s);
94193bf6008Sagc 		break;
94293bf6008Sagc 
943*0294a66bSjhigh 	case PGP_PKA_ECDSA:
944*0294a66bSjhigh 		free_BN(&sig->info.sig.ecdsa.r);
945*0294a66bSjhigh 		free_BN(&sig->info.sig.ecdsa.s);
946*0294a66bSjhigh 		break;
947*0294a66bSjhigh 
948fc1f8641Sagc 	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
9493326c4c5Sagc 		free_BN(&sig->info.sig.elgamal.r);
9503326c4c5Sagc 		free_BN(&sig->info.sig.elgamal.s);
95193bf6008Sagc 		break;
95293bf6008Sagc 
953fc1f8641Sagc 	case PGP_PKA_PRIVATE00:
954fc1f8641Sagc 	case PGP_PKA_PRIVATE01:
955fc1f8641Sagc 	case PGP_PKA_PRIVATE02:
956fc1f8641Sagc 	case PGP_PKA_PRIVATE03:
957fc1f8641Sagc 	case PGP_PKA_PRIVATE04:
958fc1f8641Sagc 	case PGP_PKA_PRIVATE05:
959fc1f8641Sagc 	case PGP_PKA_PRIVATE06:
960fc1f8641Sagc 	case PGP_PKA_PRIVATE07:
961fc1f8641Sagc 	case PGP_PKA_PRIVATE08:
962fc1f8641Sagc 	case PGP_PKA_PRIVATE09:
963fc1f8641Sagc 	case PGP_PKA_PRIVATE10:
964fc1f8641Sagc 		pgp_data_free(&sig->info.sig.unknown);
96593bf6008Sagc 		break;
96693bf6008Sagc 
96793bf6008Sagc 	default:
9683326c4c5Sagc 		(void) fprintf(stderr, "sig_free: bad sig type\n");
96993bf6008Sagc 	}
97093bf6008Sagc }
97193bf6008Sagc 
97293bf6008Sagc /**
97393bf6008Sagc \ingroup Core_Create
97493bf6008Sagc \brief Free allocated memory
97593bf6008Sagc */
97693bf6008Sagc /* ! Free any memory allocated when parsing the packet content */
97793bf6008Sagc void
pgp_parser_content_free(pgp_packet_t * c)978fc1f8641Sagc pgp_parser_content_free(pgp_packet_t *c)
97993bf6008Sagc {
98093bf6008Sagc 	switch (c->tag) {
981fc1f8641Sagc 	case PGP_PARSER_PTAG:
982fc1f8641Sagc 	case PGP_PTAG_CT_COMPRESSED:
983fc1f8641Sagc 	case PGP_PTAG_SS_CREATION_TIME:
984fc1f8641Sagc 	case PGP_PTAG_SS_EXPIRATION_TIME:
985fc1f8641Sagc 	case PGP_PTAG_SS_KEY_EXPIRY:
986fc1f8641Sagc 	case PGP_PTAG_SS_TRUST:
987fc1f8641Sagc 	case PGP_PTAG_SS_ISSUER_KEY_ID:
988fc1f8641Sagc 	case PGP_PTAG_CT_1_PASS_SIG:
989fc1f8641Sagc 	case PGP_PTAG_SS_PRIMARY_USER_ID:
990fc1f8641Sagc 	case PGP_PTAG_SS_REVOCABLE:
991fc1f8641Sagc 	case PGP_PTAG_SS_REVOCATION_KEY:
992ce6d35b1Sjhigh 	case PGP_PTAG_SS_ISSUER_FINGERPRINT:
993fc1f8641Sagc 	case PGP_PTAG_CT_LITDATA_HEADER:
994fc1f8641Sagc 	case PGP_PTAG_CT_LITDATA_BODY:
995fc1f8641Sagc 	case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
996fc1f8641Sagc 	case PGP_PTAG_CT_UNARMOURED_TEXT:
997fc1f8641Sagc 	case PGP_PTAG_CT_ARMOUR_TRAILER:
998fc1f8641Sagc 	case PGP_PTAG_CT_SIGNATURE_HEADER:
999fc1f8641Sagc 	case PGP_PTAG_CT_SE_DATA_HEADER:
1000fc1f8641Sagc 	case PGP_PTAG_CT_SE_IP_DATA_HEADER:
1001fc1f8641Sagc 	case PGP_PTAG_CT_SE_IP_DATA_BODY:
1002fc1f8641Sagc 	case PGP_PTAG_CT_MDC:
1003fc1f8641Sagc 	case PGP_GET_SECKEY:
100493bf6008Sagc 		break;
100593bf6008Sagc 
1006fc1f8641Sagc 	case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1007e2c60ad1Sagc 		headers_free(&c->u.cleartext_head);
100893bf6008Sagc 		break;
100993bf6008Sagc 
1010fc1f8641Sagc 	case PGP_PTAG_CT_ARMOUR_HEADER:
1011e2c60ad1Sagc 		headers_free(&c->u.armour_header.headers);
101293bf6008Sagc 		break;
101393bf6008Sagc 
1014fc1f8641Sagc 	case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
10152232f800Sagc 		cleartext_trailer_free(&c->u.cleartext_trailer);
101693bf6008Sagc 		break;
101793bf6008Sagc 
1018fc1f8641Sagc 	case PGP_PTAG_CT_TRUST:
1019fc1f8641Sagc 		pgp_data_free(&c->u.trust);
102093bf6008Sagc 		break;
102193bf6008Sagc 
1022fc1f8641Sagc 	case PGP_PTAG_CT_SIGNATURE:
1023fc1f8641Sagc 	case PGP_PTAG_CT_SIGNATURE_FOOTER:
10243326c4c5Sagc 		sig_free(&c->u.sig);
102593bf6008Sagc 		break;
102693bf6008Sagc 
1027fc1f8641Sagc 	case PGP_PTAG_CT_PUBLIC_KEY:
1028fc1f8641Sagc 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
1029fc1f8641Sagc 		pgp_pubkey_free(&c->u.pubkey);
103093bf6008Sagc 		break;
103193bf6008Sagc 
1032fc1f8641Sagc 	case PGP_PTAG_CT_USER_ID:
1033fc1f8641Sagc 		pgp_userid_free(&c->u.userid);
103493bf6008Sagc 		break;
103593bf6008Sagc 
1036fc1f8641Sagc 	case PGP_PTAG_SS_SIGNERS_USER_ID:
1037fc1f8641Sagc 		pgp_userid_free(&c->u.ss_signer);
103893bf6008Sagc 		break;
103993bf6008Sagc 
1040fc1f8641Sagc 	case PGP_PTAG_CT_USER_ATTR:
1041fc1f8641Sagc 		pgp_data_free(&c->u.userattr);
104293bf6008Sagc 		break;
104393bf6008Sagc 
1044fc1f8641Sagc 	case PGP_PTAG_SS_PREFERRED_SKA:
1045fc1f8641Sagc 		pgp_data_free(&c->u.ss_skapref);
104693bf6008Sagc 		break;
104793bf6008Sagc 
1048fc1f8641Sagc 	case PGP_PTAG_SS_PREFERRED_HASH:
1049fc1f8641Sagc 		pgp_data_free(&c->u.ss_hashpref);
105093bf6008Sagc 		break;
105193bf6008Sagc 
1052fc1f8641Sagc 	case PGP_PTAG_SS_PREF_COMPRESS:
1053fc1f8641Sagc 		pgp_data_free(&c->u.ss_zpref);
105493bf6008Sagc 		break;
105593bf6008Sagc 
1056fc1f8641Sagc 	case PGP_PTAG_SS_KEY_FLAGS:
1057fc1f8641Sagc 		pgp_data_free(&c->u.ss_key_flags);
105893bf6008Sagc 		break;
105993bf6008Sagc 
1060fc1f8641Sagc 	case PGP_PTAG_SS_KEYSERV_PREFS:
1061fc1f8641Sagc 		pgp_data_free(&c->u.ss_key_server_prefs);
106293bf6008Sagc 		break;
106393bf6008Sagc 
1064fc1f8641Sagc 	case PGP_PTAG_SS_FEATURES:
1065fc1f8641Sagc 		pgp_data_free(&c->u.ss_features);
106693bf6008Sagc 		break;
106793bf6008Sagc 
1068fc1f8641Sagc 	case PGP_PTAG_SS_NOTATION_DATA:
1069fc1f8641Sagc 		pgp_data_free(&c->u.ss_notation.name);
1070fc1f8641Sagc 		pgp_data_free(&c->u.ss_notation.value);
107193bf6008Sagc 		break;
107293bf6008Sagc 
1073fc1f8641Sagc 	case PGP_PTAG_SS_REGEXP:
1074d427c17dSagc 		string_free(&c->u.ss_regexp);
107593bf6008Sagc 		break;
107693bf6008Sagc 
1077fc1f8641Sagc 	case PGP_PTAG_SS_POLICY_URI:
1078d427c17dSagc 		string_free(&c->u.ss_policy);
107993bf6008Sagc 		break;
108093bf6008Sagc 
1081fc1f8641Sagc 	case PGP_PTAG_SS_PREF_KEYSERV:
1082d427c17dSagc 		string_free(&c->u.ss_keyserv);
108393bf6008Sagc 		break;
108493bf6008Sagc 
1085fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED00:
1086fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED01:
1087fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED02:
1088fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED03:
1089fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED04:
1090fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED05:
1091fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED06:
1092fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED07:
1093fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED08:
1094fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED09:
1095fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED10:
1096fc1f8641Sagc 		pgp_data_free(&c->u.ss_userdef);
109793bf6008Sagc 		break;
109893bf6008Sagc 
1099fc1f8641Sagc 	case PGP_PTAG_SS_RESERVED:
1100fc1f8641Sagc 		pgp_data_free(&c->u.ss_unknown);
110193bf6008Sagc 		break;
110293bf6008Sagc 
1103fc1f8641Sagc 	case PGP_PTAG_SS_REVOCATION_REASON:
1104d427c17dSagc 		string_free(&c->u.ss_revocation.reason);
110593bf6008Sagc 		break;
110693bf6008Sagc 
1107fc1f8641Sagc 	case PGP_PTAG_SS_EMBEDDED_SIGNATURE:
1108fc1f8641Sagc 		pgp_data_free(&c->u.ss_embedded_sig);
110993bf6008Sagc 		break;
111093bf6008Sagc 
1111fc1f8641Sagc 	case PGP_PARSER_PACKET_END:
1112fc1f8641Sagc 		pgp_subpacket_free(&c->u.packet);
111393bf6008Sagc 		break;
111493bf6008Sagc 
1115fc1f8641Sagc 	case PGP_PARSER_ERROR:
1116fc1f8641Sagc 	case PGP_PARSER_ERRCODE:
111793bf6008Sagc 		break;
111893bf6008Sagc 
1119fc1f8641Sagc 	case PGP_PTAG_CT_SECRET_KEY:
1120fc1f8641Sagc 	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
1121fc1f8641Sagc 		pgp_seckey_free(&c->u.seckey);
112293bf6008Sagc 		break;
112393bf6008Sagc 
1124fc1f8641Sagc 	case PGP_PTAG_CT_PK_SESSION_KEY:
1125fc1f8641Sagc 	case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1126fc1f8641Sagc 		pgp_pk_sesskey_free(&c->u.pk_sesskey);
112793bf6008Sagc 		break;
112893bf6008Sagc 
1129fc1f8641Sagc 	case PGP_GET_PASSPHRASE:
1130e2c60ad1Sagc 		cmd_get_passphrase_free(&c->u.skey_passphrase);
113193bf6008Sagc 		break;
113293bf6008Sagc 
113393bf6008Sagc 	default:
113493bf6008Sagc 		fprintf(stderr, "Can't free %d (0x%x)\n", c->tag, c->tag);
113593bf6008Sagc 	}
113693bf6008Sagc }
113793bf6008Sagc 
113893bf6008Sagc /**
113993bf6008Sagc \ingroup Core_Create
114093bf6008Sagc \brief Free allocated memory
114193bf6008Sagc */
114293bf6008Sagc void
pgp_pk_sesskey_free(pgp_pk_sesskey_t * sk)1143fc1f8641Sagc pgp_pk_sesskey_free(pgp_pk_sesskey_t *sk)
114493bf6008Sagc {
11452232f800Sagc 	switch (sk->alg) {
1146fc1f8641Sagc 	case PGP_PKA_RSA:
114741335e2dSagc 		free_BN(&sk->params.rsa.encrypted_m);
114893bf6008Sagc 		break;
114993bf6008Sagc 
1150fc1f8641Sagc 	case PGP_PKA_ELGAMAL:
115141335e2dSagc 		free_BN(&sk->params.elgamal.g_to_k);
115241335e2dSagc 		free_BN(&sk->params.elgamal.encrypted_m);
115393bf6008Sagc 		break;
115493bf6008Sagc 
115593bf6008Sagc 	default:
1156fc1f8641Sagc 		(void) fprintf(stderr, "pgp_pk_sesskey_free: bad alg\n");
1157ed0df671Sagc 		break;
115893bf6008Sagc 	}
115993bf6008Sagc }
116093bf6008Sagc 
116193bf6008Sagc /**
116293bf6008Sagc \ingroup Core_Create
116393bf6008Sagc \brief Free allocated memory
116493bf6008Sagc */
116593bf6008Sagc /* ! Free the memory used when parsing a public key */
116693bf6008Sagc void
pgp_pubkey_free(pgp_pubkey_t * p)1167fc1f8641Sagc pgp_pubkey_free(pgp_pubkey_t *p)
116893bf6008Sagc {
11692232f800Sagc 	switch (p->alg) {
1170fc1f8641Sagc 	case PGP_PKA_RSA:
1171fc1f8641Sagc 	case PGP_PKA_RSA_ENCRYPT_ONLY:
1172fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
117393bf6008Sagc 		free_BN(&p->key.rsa.n);
117493bf6008Sagc 		free_BN(&p->key.rsa.e);
117593bf6008Sagc 		break;
117693bf6008Sagc 
1177fc1f8641Sagc 	case PGP_PKA_DSA:
117893bf6008Sagc 		free_BN(&p->key.dsa.p);
117993bf6008Sagc 		free_BN(&p->key.dsa.q);
118093bf6008Sagc 		free_BN(&p->key.dsa.g);
118193bf6008Sagc 		free_BN(&p->key.dsa.y);
118293bf6008Sagc 		break;
118393bf6008Sagc 
1184*0294a66bSjhigh 	case PGP_PKA_ECDSA:
1185*0294a66bSjhigh 		free_BN(&p->key.ecdsa.p);
1186*0294a66bSjhigh 		break;
1187*0294a66bSjhigh 
1188fc1f8641Sagc 	case PGP_PKA_ELGAMAL:
1189fc1f8641Sagc 	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
119093bf6008Sagc 		free_BN(&p->key.elgamal.p);
119193bf6008Sagc 		free_BN(&p->key.elgamal.g);
119293bf6008Sagc 		free_BN(&p->key.elgamal.y);
119393bf6008Sagc 		break;
119493bf6008Sagc 
1195fc1f8641Sagc 	case PGP_PKA_NOTHING:
119693bf6008Sagc 		/* nothing to free */
119793bf6008Sagc 		break;
119893bf6008Sagc 
119993bf6008Sagc 	default:
1200fc1f8641Sagc 		(void) fprintf(stderr, "pgp_pubkey_free: bad alg\n");
120193bf6008Sagc 	}
120293bf6008Sagc }
120393bf6008Sagc 
120493bf6008Sagc /**
120593bf6008Sagc    \ingroup Core_ReadPackets
120693bf6008Sagc */
120793bf6008Sagc static int
parse_pubkey_data(pgp_pubkey_t * key,pgp_region_t * region,pgp_stream_t * stream)1208fc1f8641Sagc parse_pubkey_data(pgp_pubkey_t *key, pgp_region_t *region,
1209fc1f8641Sagc 		      pgp_stream_t *stream)
121093bf6008Sagc {
1211b15ec256Sagc 	uint8_t   c = 0x0;
121293bf6008Sagc 
121357324b9fSagc 	if (region->readc != 0) {
1214ed0df671Sagc 		/* We should not have read anything so far */
12153326c4c5Sagc 		(void) fprintf(stderr, "parse_pubkey_data: bad length\n");
1216ed0df671Sagc 		return 0;
1217ed0df671Sagc 	}
121841335e2dSagc 	if (!limread(&c, 1, region, stream)) {
121993bf6008Sagc 		return 0;
1220bcfd8565Sagc 	}
1221fc1f8641Sagc 	key->version = (pgp_version_t)c;
122257036e70Sagc 	switch (key->version) {
1223fc1f8641Sagc 	case PGP_V2:
1224fc1f8641Sagc 	case PGP_V3:
1225fc1f8641Sagc 	case PGP_V4:
122657036e70Sagc 		break;
122757036e70Sagc 	default:
1228fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_PUBLIC_KEY_VRSN,
122993bf6008Sagc 			    "Bad public key version (0x%02x)", key->version);
123093bf6008Sagc 		return 0;
123193bf6008Sagc 	}
123241335e2dSagc 	if (!limited_read_time(&key->birthtime, region, stream)) {
123393bf6008Sagc 		return 0;
1234bcfd8565Sagc 	}
123593bf6008Sagc 
123693bf6008Sagc 	key->days_valid = 0;
1237bcfd8565Sagc 	if ((key->version == 2 || key->version == 3) &&
123841335e2dSagc 	    !limread_scalar(&key->days_valid, 2, region, stream)) {
123993bf6008Sagc 		return 0;
1240bcfd8565Sagc 	}
124193bf6008Sagc 
124241335e2dSagc 	if (!limread(&c, 1, region, stream)) {
124393bf6008Sagc 		return 0;
12446715e11aSagc 	}
124557324b9fSagc 	key->alg = c;
124693bf6008Sagc 
12472232f800Sagc 	switch (key->alg) {
1248fc1f8641Sagc 	case PGP_PKA_DSA:
124941335e2dSagc 		if (!limread_mpi(&key->key.dsa.p, region, stream) ||
125041335e2dSagc 		    !limread_mpi(&key->key.dsa.q, region, stream) ||
125141335e2dSagc 		    !limread_mpi(&key->key.dsa.g, region, stream) ||
125241335e2dSagc 		    !limread_mpi(&key->key.dsa.y, region, stream)) {
125393bf6008Sagc 			return 0;
1254bcfd8565Sagc 		}
125593bf6008Sagc 		break;
125693bf6008Sagc 
1257*0294a66bSjhigh 	case PGP_PKA_ECDSA:
1258*0294a66bSjhigh 		if (!limread(&key->key.ecdsa.len, 1, region, stream) ||
1259*0294a66bSjhigh 		    !limread(key->key.ecdsa.oid, key->key.ecdsa.len, region, stream) ||
1260*0294a66bSjhigh 		    !limread_mpi(&key->key.ecdsa.p, region, stream)) {
1261*0294a66bSjhigh 			return 0;
1262*0294a66bSjhigh 		}
1263*0294a66bSjhigh 		break;
1264*0294a66bSjhigh 
1265fc1f8641Sagc 	case PGP_PKA_RSA:
1266fc1f8641Sagc 	case PGP_PKA_RSA_ENCRYPT_ONLY:
1267fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
126841335e2dSagc 		if (!limread_mpi(&key->key.rsa.n, region, stream) ||
126941335e2dSagc 		    !limread_mpi(&key->key.rsa.e, region, stream)) {
127093bf6008Sagc 			return 0;
1271bcfd8565Sagc 		}
127293bf6008Sagc 		break;
127393bf6008Sagc 
1274fc1f8641Sagc 	case PGP_PKA_ELGAMAL:
1275fc1f8641Sagc 	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
127641335e2dSagc 		if (!limread_mpi(&key->key.elgamal.p, region, stream) ||
127741335e2dSagc 		    !limread_mpi(&key->key.elgamal.g, region, stream) ||
127841335e2dSagc 		    !limread_mpi(&key->key.elgamal.y, region, stream)) {
127993bf6008Sagc 			return 0;
1280bcfd8565Sagc 		}
128193bf6008Sagc 		break;
128293bf6008Sagc 
128393bf6008Sagc 	default:
1284fc1f8641Sagc 		PGP_ERROR_1(&stream->errors,
1285fc1f8641Sagc 			PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
1286bcfd8565Sagc 			"Unsupported Public Key algorithm (%s)",
1287fc1f8641Sagc 			pgp_show_pka(key->alg));
128893bf6008Sagc 		return 0;
128993bf6008Sagc 	}
129093bf6008Sagc 
129193bf6008Sagc 	return 1;
129293bf6008Sagc }
129393bf6008Sagc 
129493bf6008Sagc 
129593bf6008Sagc /**
129693bf6008Sagc  * \ingroup Core_ReadPackets
129793bf6008Sagc  * \brief Parse a public key packet.
129893bf6008Sagc  *
129993bf6008Sagc  * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys.
130093bf6008Sagc  *
130193bf6008Sagc  * Once the key has been parsed successfully, it is passed to the callback.
130293bf6008Sagc  *
130393bf6008Sagc  * \param *ptag		Pointer to the current Packet Tag.  This function should consume the entire packet.
130493bf6008Sagc  * \param *reader	Our reader
130593bf6008Sagc  * \param *cb		The callback
130693bf6008Sagc  * \return		1 on success, 0 on error
130793bf6008Sagc  *
130893bf6008Sagc  * \see RFC4880 5.5.2
130993bf6008Sagc  */
131093bf6008Sagc static int
parse_pubkey(pgp_content_enum tag,pgp_region_t * region,pgp_stream_t * stream)1311fc1f8641Sagc parse_pubkey(pgp_content_enum tag, pgp_region_t *region,
1312fc1f8641Sagc 		 pgp_stream_t *stream)
131393bf6008Sagc {
1314fc1f8641Sagc 	pgp_packet_t pkt;
131593bf6008Sagc 
13169b987001Sagc 	if (!parse_pubkey_data(&pkt.u.pubkey, region, stream)) {
13179b987001Sagc 		(void) fprintf(stderr, "parse_pubkey: parse_pubkey_data failed\n");
131893bf6008Sagc 		return 0;
13199b987001Sagc 	}
132093bf6008Sagc 
132193bf6008Sagc 	/* XXX: this test should be done for all packets, surely? */
132257324b9fSagc 	if (region->readc != region->length) {
1323fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
132457324b9fSagc 			    "Unconsumed data (%d)", region->length - region->readc);
132593bf6008Sagc 		return 0;
132693bf6008Sagc 	}
132741335e2dSagc 	CALLBACK(tag, &stream->cbinfo, &pkt);
132893bf6008Sagc 
132993bf6008Sagc 	return 1;
133093bf6008Sagc }
133193bf6008Sagc 
133293bf6008Sagc /**
133393bf6008Sagc  * \ingroup Core_ReadPackets
133493bf6008Sagc  * \brief Parse one user attribute packet.
133593bf6008Sagc  *
133693bf6008Sagc  * User attribute packets contain one or more attribute subpackets.
133793bf6008Sagc  * For now, handle the whole packet as raw data.
133893bf6008Sagc  */
133993bf6008Sagc 
134093bf6008Sagc static int
parse_userattr(pgp_region_t * region,pgp_stream_t * stream)1341fc1f8641Sagc parse_userattr(pgp_region_t *region, pgp_stream_t *stream)
134293bf6008Sagc {
134393bf6008Sagc 
1344fc1f8641Sagc 	pgp_packet_t pkt;
134593bf6008Sagc 
134693bf6008Sagc 	/*
134793bf6008Sagc 	 * xxx- treat as raw data for now. Could break down further into
134893bf6008Sagc 	 * attribute sub-packets later - rachel
134993bf6008Sagc 	 */
135057324b9fSagc 	if (region->readc != 0) {
1351ed0df671Sagc 		/* We should not have read anything so far */
135257324b9fSagc 		(void) fprintf(stderr, "parse_userattr: bad length\n");
1353ed0df671Sagc 		return 0;
1354ed0df671Sagc 	}
1355d427c17dSagc 	if (!read_data(&pkt.u.userattr, region, stream)) {
135693bf6008Sagc 		return 0;
1357d427c17dSagc 	}
1358fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_USER_ATTR, &stream->cbinfo, &pkt);
135993bf6008Sagc 	return 1;
136093bf6008Sagc }
136193bf6008Sagc 
136293bf6008Sagc /**
136393bf6008Sagc \ingroup Core_Create
136493bf6008Sagc \brief Free allocated memory
136593bf6008Sagc */
136693bf6008Sagc /* ! Free the memory used when parsing this packet type */
136793bf6008Sagc void
pgp_userid_free(uint8_t ** id)1368fc1f8641Sagc pgp_userid_free(uint8_t **id)
136993bf6008Sagc {
1370d427c17dSagc 	free(*id);
1371d427c17dSagc 	*id = NULL;
137293bf6008Sagc }
137393bf6008Sagc 
137493bf6008Sagc /**
137593bf6008Sagc  * \ingroup Core_ReadPackets
137693bf6008Sagc  * \brief Parse a user id.
137793bf6008Sagc  *
137893bf6008Sagc  * This function parses an user id packet, which is basically just a char array the size of the packet.
137993bf6008Sagc  *
138093bf6008Sagc  * The char array is to be treated as an UTF-8 string.
138193bf6008Sagc  *
138293bf6008Sagc  * The userid gets null terminated by this function.  Freeing it is the responsibility of the caller.
138393bf6008Sagc  *
138493bf6008Sagc  * Once the userid has been parsed successfully, it is passed to the callback.
138593bf6008Sagc  *
138693bf6008Sagc  * \param *ptag		Pointer to the Packet Tag.  This function should consume the entire packet.
138793bf6008Sagc  * \param *reader	Our reader
138893bf6008Sagc  * \param *cb		The callback
138993bf6008Sagc  * \return		1 on success, 0 on error
139093bf6008Sagc  *
139193bf6008Sagc  * \see RFC4880 5.11
139293bf6008Sagc  */
139393bf6008Sagc static int
parse_userid(pgp_region_t * region,pgp_stream_t * stream)1394fc1f8641Sagc parse_userid(pgp_region_t *region, pgp_stream_t *stream)
139593bf6008Sagc {
1396fc1f8641Sagc 	pgp_packet_t pkt;
139793bf6008Sagc 
139857324b9fSagc 	 if (region->readc != 0) {
1399ed0df671Sagc 		/* We should not have read anything so far */
140057324b9fSagc 		(void) fprintf(stderr, "parse_userid: bad length\n");
1401ed0df671Sagc 		return 0;
1402ed0df671Sagc 	}
140393bf6008Sagc 
1404d427c17dSagc 	if ((pkt.u.userid = calloc(1, region->length + 1)) == NULL) {
140557036e70Sagc 		(void) fprintf(stderr, "parse_userid: bad alloc\n");
140657036e70Sagc 		return 0;
140757036e70Sagc 	}
140893bf6008Sagc 
14092232f800Sagc 	if (region->length &&
1410d427c17dSagc 	    !limread(pkt.u.userid, region->length, region,
141141335e2dSagc 			stream)) {
141293bf6008Sagc 		return 0;
14132232f800Sagc 	}
1414d427c17dSagc 	pkt.u.userid[region->length] = 0x0;
1415fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_USER_ID, &stream->cbinfo, &pkt);
141693bf6008Sagc 	return 1;
141793bf6008Sagc }
141893bf6008Sagc 
1419fc1f8641Sagc static pgp_hash_t     *
parse_hash_find(pgp_stream_t * stream,const uint8_t * keyid)1420fc1f8641Sagc parse_hash_find(pgp_stream_t *stream, const uint8_t *keyid)
142193bf6008Sagc {
1422fc1f8641Sagc 	pgp_hashtype_t	*hp;
142393bf6008Sagc 	size_t			 n;
142493bf6008Sagc 
142541335e2dSagc 	for (n = 0, hp = stream->hashes; n < stream->hashc; n++, hp++) {
1426fc1f8641Sagc 		if (memcmp(hp->keyid, keyid, PGP_KEY_ID_SIZE) == 0) {
142741335e2dSagc 			return &hp->hash;
142893bf6008Sagc 		}
142993bf6008Sagc 	}
143093bf6008Sagc 	return NULL;
143193bf6008Sagc }
143293bf6008Sagc 
143393bf6008Sagc /**
143493bf6008Sagc  * \ingroup Core_Parse
143593bf6008Sagc  * \brief Parse a version 3 signature.
143693bf6008Sagc  *
143793bf6008Sagc  * This function parses an version 3 signature packet, handling RSA and DSA signatures.
143893bf6008Sagc  *
143993bf6008Sagc  * Once the signature has been parsed successfully, it is passed to the callback.
144093bf6008Sagc  *
144193bf6008Sagc  * \param *ptag		Pointer to the Packet Tag.  This function should consume the entire packet.
144293bf6008Sagc  * \param *reader	Our reader
144393bf6008Sagc  * \param *cb		The callback
144493bf6008Sagc  * \return		1 on success, 0 on error
144593bf6008Sagc  *
144693bf6008Sagc  * \see RFC4880 5.2.2
144793bf6008Sagc  */
144893bf6008Sagc static int
parse_v3_sig(pgp_region_t * region,pgp_stream_t * stream)1449fc1f8641Sagc parse_v3_sig(pgp_region_t *region,
1450fc1f8641Sagc 		   pgp_stream_t *stream)
145193bf6008Sagc {
1452fc1f8641Sagc 	pgp_packet_t	pkt;
1453b15ec256Sagc 	uint8_t		c = 0x0;
145493bf6008Sagc 
145593bf6008Sagc 	/* clear signature */
14563326c4c5Sagc 	(void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
145793bf6008Sagc 
1458fc1f8641Sagc 	pkt.u.sig.info.version = PGP_V3;
145993bf6008Sagc 
146093bf6008Sagc 	/* hash info length */
146141335e2dSagc 	if (!limread(&c, 1, region, stream)) {
146293bf6008Sagc 		return 0;
1463bcfd8565Sagc 	}
146457324b9fSagc 	if (c != 5) {
146541335e2dSagc 		ERRP(&stream->cbinfo, pkt, "bad hash info length");
1466efdd9dbaSagc 	}
146793bf6008Sagc 
146841335e2dSagc 	if (!limread(&c, 1, region, stream)) {
146993bf6008Sagc 		return 0;
1470bcfd8565Sagc 	}
1471fc1f8641Sagc 	pkt.u.sig.info.type = (pgp_sig_type_t)c;
147293bf6008Sagc 	/* XXX: check signature type */
147393bf6008Sagc 
147441335e2dSagc 	if (!limited_read_time(&pkt.u.sig.info.birthtime, region, stream)) {
147593bf6008Sagc 		return 0;
1476bcfd8565Sagc 	}
14774b3a3e18Sagc 	pkt.u.sig.info.birthtime_set = 1;
147893bf6008Sagc 
1479fc1f8641Sagc 	if (!limread(pkt.u.sig.info.signer_id, PGP_KEY_ID_SIZE, region,
148041335e2dSagc 			stream)) {
148193bf6008Sagc 		return 0;
1482bcfd8565Sagc 	}
14834b3a3e18Sagc 	pkt.u.sig.info.signer_id_set = 1;
148493bf6008Sagc 
148541335e2dSagc 	if (!limread(&c, 1, region, stream)) {
148693bf6008Sagc 		return 0;
1487bcfd8565Sagc 	}
1488fc1f8641Sagc 	pkt.u.sig.info.key_alg = (pgp_pubkey_alg_t)c;
148993bf6008Sagc 	/* XXX: check algorithm */
149093bf6008Sagc 
149141335e2dSagc 	if (!limread(&c, 1, region, stream)) {
149293bf6008Sagc 		return 0;
1493bcfd8565Sagc 	}
1494fc1f8641Sagc 	pkt.u.sig.info.hash_alg = (pgp_hash_alg_t)c;
149593bf6008Sagc 	/* XXX: check algorithm */
149693bf6008Sagc 
149741335e2dSagc 	if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
149893bf6008Sagc 		return 0;
1499bcfd8565Sagc 	}
150093bf6008Sagc 
15012232f800Sagc 	switch (pkt.u.sig.info.key_alg) {
1502fc1f8641Sagc 	case PGP_PKA_RSA:
1503fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
150441335e2dSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
150593bf6008Sagc 			return 0;
1506bcfd8565Sagc 		}
150793bf6008Sagc 		break;
150893bf6008Sagc 
1509fc1f8641Sagc 	case PGP_PKA_DSA:
151041335e2dSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream) ||
151141335e2dSagc 		    !limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
151293bf6008Sagc 			return 0;
1513bcfd8565Sagc 		}
151493bf6008Sagc 		break;
151593bf6008Sagc 
1516*0294a66bSjhigh 	case PGP_PKA_ECDSA:
1517*0294a66bSjhigh 		if (!limread_mpi(&pkt.u.sig.info.sig.ecdsa.r, region, stream) ||
1518*0294a66bSjhigh 		    !limread_mpi(&pkt.u.sig.info.sig.ecdsa.s, region, stream)) {
1519*0294a66bSjhigh 			return 0;
1520*0294a66bSjhigh 		}
1521*0294a66bSjhigh 		break;
1522*0294a66bSjhigh 
1523fc1f8641Sagc 	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
15246715e11aSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
152541335e2dSagc 				stream) ||
15266715e11aSagc 		    !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
152741335e2dSagc 		    		stream)) {
152893bf6008Sagc 			return 0;
1529bcfd8565Sagc 		}
153093bf6008Sagc 		break;
153193bf6008Sagc 
153293bf6008Sagc 	default:
1533fc1f8641Sagc 		PGP_ERROR_1(&stream->errors,
1534fc1f8641Sagc 			PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
153593bf6008Sagc 			"Unsupported signature key algorithm (%s)",
1536fc1f8641Sagc 			pgp_show_pka(pkt.u.sig.info.key_alg));
153793bf6008Sagc 		return 0;
153893bf6008Sagc 	}
153993bf6008Sagc 
154057324b9fSagc 	if (region->readc != region->length) {
1541fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
15422232f800Sagc 			"Unconsumed data (%d)",
154357324b9fSagc 			region->length - region->readc);
154493bf6008Sagc 		return 0;
154593bf6008Sagc 	}
15463326c4c5Sagc 	if (pkt.u.sig.info.signer_id_set) {
154741335e2dSagc 		pkt.u.sig.hash = parse_hash_find(stream,
15483326c4c5Sagc 				pkt.u.sig.info.signer_id);
1549bcfd8565Sagc 	}
1550fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_SIGNATURE, &stream->cbinfo, &pkt);
155193bf6008Sagc 	return 1;
155293bf6008Sagc }
155393bf6008Sagc 
155493bf6008Sagc /**
155593bf6008Sagc  * \ingroup Core_ReadPackets
155693bf6008Sagc  * \brief Parse one signature sub-packet.
155793bf6008Sagc  *
1558600b302bSagc  * Version 4 signatures can have an arbitrary amount of (hashed and
1559600b302bSagc  * unhashed) subpackets.  Subpackets are used to hold optional
1560600b302bSagc  * attributes of subpackets.
156193bf6008Sagc  *
156293bf6008Sagc  * This function parses one such signature subpacket.
156393bf6008Sagc  *
156493bf6008Sagc  * Once the subpacket has been parsed successfully, it is passed to the callback.
156593bf6008Sagc  *
156693bf6008Sagc  * \param *ptag		Pointer to the Packet Tag.  This function should consume the entire subpacket.
156793bf6008Sagc  * \param *reader	Our reader
156893bf6008Sagc  * \param *cb		The callback
156993bf6008Sagc  * \return		1 on success, 0 on error
157093bf6008Sagc  *
157193bf6008Sagc  * \see RFC4880 5.2.3
157293bf6008Sagc  */
157393bf6008Sagc static int
parse_one_sig_subpacket(pgp_sig_t * sig,pgp_region_t * region,pgp_stream_t * stream)1574fc1f8641Sagc parse_one_sig_subpacket(pgp_sig_t *sig,
1575fc1f8641Sagc 			      pgp_region_t *region,
1576fc1f8641Sagc 			      pgp_stream_t *stream)
157793bf6008Sagc {
1578fc1f8641Sagc 	pgp_region_t	subregion;
1579fc1f8641Sagc 	pgp_packet_t	pkt;
1580b15ec256Sagc 	uint8_t		bools = 0x0;
1581b15ec256Sagc 	uint8_t		c = 0x0;
1582ce6d35b1Sjhigh 	uint8_t		temp = 0x0;
15834b3a3e18Sagc 	unsigned	doread = 1;
158457324b9fSagc 	unsigned        t8;
158557324b9fSagc 	unsigned        t7;
158693bf6008Sagc 
1587fc1f8641Sagc 	pgp_init_subregion(&subregion, region);
158841335e2dSagc 	if (!limited_read_new_length(&subregion.length, region, stream)) {
158993bf6008Sagc 		return 0;
15902232f800Sagc 	}
159193bf6008Sagc 
15922232f800Sagc 	if (subregion.length > region->length) {
159341335e2dSagc 		ERRP(&stream->cbinfo, pkt, "Subpacket too long");
15942232f800Sagc 	}
159593bf6008Sagc 
159641335e2dSagc 	if (!limread(&c, 1, &subregion, stream)) {
159793bf6008Sagc 		return 0;
15982232f800Sagc 	}
159993bf6008Sagc 
160057324b9fSagc 	t8 = (c & 0x7f) / 8;
160157324b9fSagc 	t7 = 1 << (c & 7);
160293bf6008Sagc 
160357324b9fSagc 	pkt.critical = (unsigned)c >> 7;
1604fc1f8641Sagc 	pkt.tag = (pgp_content_enum)(PGP_PTAG_SIG_SUBPKT_BASE + (c & 0x7f));
160593bf6008Sagc 
160693bf6008Sagc 	/* Application wants it delivered raw */
160741335e2dSagc 	if (stream->ss_raw[t8] & t7) {
1608bcfd8565Sagc 		pkt.u.ss_raw.tag = pkt.tag;
1609bcfd8565Sagc 		pkt.u.ss_raw.length = subregion.length - 1;
1610bcfd8565Sagc 		pkt.u.ss_raw.raw = calloc(1, pkt.u.ss_raw.length);
16110aa9bccaSagc 		if (pkt.u.ss_raw.raw == NULL) {
16120aa9bccaSagc 			(void) fprintf(stderr, "parse_one_sig_subpacket: bad alloc\n");
16130aa9bccaSagc 			return 0;
16140aa9bccaSagc 		}
16153f685a78Sagc 		if (!limread(pkt.u.ss_raw.raw, (unsigned)pkt.u.ss_raw.length,
161641335e2dSagc 				&subregion, stream)) {
161793bf6008Sagc 			return 0;
16182232f800Sagc 		}
1619fc1f8641Sagc 		CALLBACK(PGP_PTAG_RAW_SS, &stream->cbinfo, &pkt);
162093bf6008Sagc 		return 1;
162193bf6008Sagc 	}
1622bcfd8565Sagc 	switch (pkt.tag) {
1623fc1f8641Sagc 	case PGP_PTAG_SS_CREATION_TIME:
1624fc1f8641Sagc 	case PGP_PTAG_SS_EXPIRATION_TIME:
1625fc1f8641Sagc 	case PGP_PTAG_SS_KEY_EXPIRY:
1626d427c17dSagc 		if (!limited_read_time(&pkt.u.ss_time, &subregion, stream))
162793bf6008Sagc 			return 0;
1628fc1f8641Sagc 		if (pkt.tag == PGP_PTAG_SS_CREATION_TIME) {
1629d427c17dSagc 			sig->info.birthtime = pkt.u.ss_time;
16304b3a3e18Sagc 			sig->info.birthtime_set = 1;
163193bf6008Sagc 		}
1632fc1f8641Sagc 		if (pkt.tag == PGP_PTAG_SS_EXPIRATION_TIME) {
1633d427c17dSagc 			sig->info.duration = pkt.u.ss_time;
1634600b302bSagc 			sig->info.duration_set = 1;
1635600b302bSagc 		}
163693bf6008Sagc 		break;
163793bf6008Sagc 
1638fc1f8641Sagc 	case PGP_PTAG_SS_TRUST:
163941335e2dSagc 		if (!limread(&pkt.u.ss_trust.level, 1, &subregion, stream) ||
164041335e2dSagc 		    !limread(&pkt.u.ss_trust.amount, 1, &subregion, stream)) {
164193bf6008Sagc 			return 0;
16426715e11aSagc 		}
164393bf6008Sagc 		break;
164493bf6008Sagc 
1645fc1f8641Sagc 	case PGP_PTAG_SS_REVOCABLE:
164641335e2dSagc 		if (!limread(&bools, 1, &subregion, stream)) {
164793bf6008Sagc 			return 0;
16482232f800Sagc 		}
1649d427c17dSagc 		pkt.u.ss_revocable = !!bools;
165093bf6008Sagc 		break;
165193bf6008Sagc 
1652fc1f8641Sagc 	case PGP_PTAG_SS_ISSUER_KEY_ID:
1653fc1f8641Sagc 		if (!limread(pkt.u.ss_issuer, PGP_KEY_ID_SIZE, &subregion, stream)) {
165493bf6008Sagc 			return 0;
16552232f800Sagc 		}
1656fc1f8641Sagc 		(void) memcpy(sig->info.signer_id, pkt.u.ss_issuer, PGP_KEY_ID_SIZE);
16574b3a3e18Sagc 		sig->info.signer_id_set = 1;
165893bf6008Sagc 		break;
165993bf6008Sagc 
1660fc1f8641Sagc 	case PGP_PTAG_SS_PREFERRED_SKA:
1661d427c17dSagc 		if (!read_data(&pkt.u.ss_skapref, &subregion, stream)) {
166293bf6008Sagc 			return 0;
16632232f800Sagc 		}
166493bf6008Sagc 		break;
166593bf6008Sagc 
1666fc1f8641Sagc 	case PGP_PTAG_SS_PREFERRED_HASH:
1667d427c17dSagc 		if (!read_data(&pkt.u.ss_hashpref, &subregion, stream)) {
166893bf6008Sagc 			return 0;
16692232f800Sagc 		}
167093bf6008Sagc 		break;
167193bf6008Sagc 
1672fc1f8641Sagc 	case PGP_PTAG_SS_PREF_COMPRESS:
1673d427c17dSagc 		if (!read_data(&pkt.u.ss_zpref, &subregion, stream)) {
167493bf6008Sagc 			return 0;
16752232f800Sagc 		}
167693bf6008Sagc 		break;
167793bf6008Sagc 
1678fc1f8641Sagc 	case PGP_PTAG_SS_PRIMARY_USER_ID:
167941335e2dSagc 		if (!limread(&bools, 1, &subregion, stream)) {
168093bf6008Sagc 			return 0;
16812232f800Sagc 		}
1682d427c17dSagc 		pkt.u.ss_primary_userid = !!bools;
168393bf6008Sagc 		break;
168493bf6008Sagc 
1685fc1f8641Sagc 	case PGP_PTAG_SS_KEY_FLAGS:
1686d427c17dSagc 		if (!read_data(&pkt.u.ss_key_flags, &subregion, stream)) {
168793bf6008Sagc 			return 0;
16882232f800Sagc 		}
168993bf6008Sagc 		break;
169093bf6008Sagc 
1691fc1f8641Sagc 	case PGP_PTAG_SS_KEYSERV_PREFS:
1692d427c17dSagc 		if (!read_data(&pkt.u.ss_key_server_prefs, &subregion, stream)) {
169393bf6008Sagc 			return 0;
16942232f800Sagc 		}
169593bf6008Sagc 		break;
169693bf6008Sagc 
1697fc1f8641Sagc 	case PGP_PTAG_SS_FEATURES:
1698d427c17dSagc 		if (!read_data(&pkt.u.ss_features, &subregion, stream)) {
169993bf6008Sagc 			return 0;
17002232f800Sagc 		}
170193bf6008Sagc 		break;
170293bf6008Sagc 
1703fc1f8641Sagc 	case PGP_PTAG_SS_SIGNERS_USER_ID:
1704d427c17dSagc 		if (!read_unsig_str(&pkt.u.ss_signer, &subregion, stream)) {
170593bf6008Sagc 			return 0;
17062232f800Sagc 		}
170793bf6008Sagc 		break;
170893bf6008Sagc 
1709fc1f8641Sagc 	case PGP_PTAG_SS_EMBEDDED_SIGNATURE:
171093bf6008Sagc 		/* \todo should do something with this sig? */
1711d427c17dSagc 		if (!read_data(&pkt.u.ss_embedded_sig, &subregion, stream)) {
171293bf6008Sagc 			return 0;
17132232f800Sagc 		}
171493bf6008Sagc 		break;
171593bf6008Sagc 
1716fc1f8641Sagc 	case PGP_PTAG_SS_NOTATION_DATA:
17176715e11aSagc 		if (!limread_data(&pkt.u.ss_notation.flags, 4,
171841335e2dSagc 				&subregion, stream)) {
171993bf6008Sagc 			return 0;
172057324b9fSagc 		}
17216715e11aSagc 		if (!limread_size_t(&pkt.u.ss_notation.name.len, 2,
172241335e2dSagc 				&subregion, stream)) {
17232232f800Sagc 			return 0;
172457324b9fSagc 		}
17256715e11aSagc 		if (!limread_size_t(&pkt.u.ss_notation.value.len, 2,
172641335e2dSagc 				&subregion, stream)) {
172793bf6008Sagc 			return 0;
172857324b9fSagc 		}
17296715e11aSagc 		if (!limread_data(&pkt.u.ss_notation.name,
17303f685a78Sagc 				(unsigned)pkt.u.ss_notation.name.len,
173141335e2dSagc 				&subregion, stream)) {
173293bf6008Sagc 			return 0;
173357324b9fSagc 		}
17346715e11aSagc 		if (!limread_data(&pkt.u.ss_notation.value,
17353f685a78Sagc 			   (unsigned)pkt.u.ss_notation.value.len,
173641335e2dSagc 			   &subregion, stream)) {
173793bf6008Sagc 			return 0;
173857324b9fSagc 		}
173993bf6008Sagc 		break;
174093bf6008Sagc 
1741fc1f8641Sagc 	case PGP_PTAG_SS_POLICY_URI:
1742d427c17dSagc 		if (!read_string(&pkt.u.ss_policy, &subregion, stream)) {
174393bf6008Sagc 			return 0;
17442232f800Sagc 		}
174593bf6008Sagc 		break;
174693bf6008Sagc 
1747fc1f8641Sagc 	case PGP_PTAG_SS_REGEXP:
1748d427c17dSagc 		if (!read_string(&pkt.u.ss_regexp, &subregion, stream)) {
174993bf6008Sagc 			return 0;
17502232f800Sagc 		}
175193bf6008Sagc 		break;
175293bf6008Sagc 
1753fc1f8641Sagc 	case PGP_PTAG_SS_PREF_KEYSERV:
1754d427c17dSagc 		if (!read_string(&pkt.u.ss_keyserv, &subregion, stream)) {
175593bf6008Sagc 			return 0;
175657324b9fSagc 		}
175793bf6008Sagc 		break;
175893bf6008Sagc 
1759fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED00:
1760fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED01:
1761fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED02:
1762fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED03:
1763fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED04:
1764fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED05:
1765fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED06:
1766fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED07:
1767fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED08:
1768fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED09:
1769fc1f8641Sagc 	case PGP_PTAG_SS_USERDEFINED10:
1770d427c17dSagc 		if (!read_data(&pkt.u.ss_userdef, &subregion, stream)) {
177193bf6008Sagc 			return 0;
177257324b9fSagc 		}
177393bf6008Sagc 		break;
177493bf6008Sagc 
1775fc1f8641Sagc 	case PGP_PTAG_SS_RESERVED:
1776d427c17dSagc 		if (!read_data(&pkt.u.ss_unknown, &subregion, stream)) {
177793bf6008Sagc 			return 0;
177857324b9fSagc 		}
177993bf6008Sagc 		break;
178093bf6008Sagc 
1781fc1f8641Sagc 	case PGP_PTAG_SS_REVOCATION_REASON:
178293bf6008Sagc 		/* first byte is the machine-readable code */
178341335e2dSagc 		if (!limread(&pkt.u.ss_revocation.code, 1, &subregion, stream)) {
178493bf6008Sagc 			return 0;
17852232f800Sagc 		}
178693bf6008Sagc 		/* the rest is a human-readable UTF-8 string */
17872232f800Sagc 		if (!read_string(&pkt.u.ss_revocation.reason, &subregion,
178841335e2dSagc 				stream)) {
178993bf6008Sagc 			return 0;
17902232f800Sagc 		}
179193bf6008Sagc 		break;
179293bf6008Sagc 
1793ce6d35b1Sjhigh 	case PGP_PTAG_SS_ISSUER_FINGERPRINT:
1794ce6d35b1Sjhigh 		/* octet 0: version */
1795ce6d35b1Sjhigh 		/* 	0x04:20 bytes, 0x05:32 bytes */
1796ce6d35b1Sjhigh 		if (!limread(&temp, 1, &subregion, stream)) {
1797ce6d35b1Sjhigh 			return 0;
1798ce6d35b1Sjhigh 		}
1799ce6d35b1Sjhigh 
1800ce6d35b1Sjhigh 		switch (temp) {
1801ce6d35b1Sjhigh 			case 0x04: pkt.u.ss_issuer_fingerprint.len = 20; break;
1802ce6d35b1Sjhigh 			case 0x05: pkt.u.ss_issuer_fingerprint.len = 32; break;
1803ce6d35b1Sjhigh 			default:
1804ce6d35b1Sjhigh 				return 0;
1805ce6d35b1Sjhigh 		}
1806ce6d35b1Sjhigh 
1807ce6d35b1Sjhigh 		if (!limread(pkt.u.ss_issuer_fingerprint.fingerprint,
1808ce6d35b1Sjhigh 			pkt.u.ss_issuer_fingerprint.len, &subregion, stream)) {
1809ce6d35b1Sjhigh 			return 0;
1810ce6d35b1Sjhigh 		}
1811ce6d35b1Sjhigh 		break;
1812ce6d35b1Sjhigh 
1813fc1f8641Sagc 	case PGP_PTAG_SS_REVOCATION_KEY:
181493bf6008Sagc 		/* octet 0 = class. Bit 0x80 must be set */
18156715e11aSagc 		if (!limread(&pkt.u.ss_revocation_key.class, 1,
181641335e2dSagc 				&subregion, stream)) {
181793bf6008Sagc 			return 0;
18182232f800Sagc 		}
1819bcfd8565Sagc 		if (!(pkt.u.ss_revocation_key.class & 0x80)) {
1820fc1f8641Sagc 			printf("Warning: PGP_PTAG_SS_REVOCATION_KEY class: "
182193bf6008Sagc 			       "Bit 0x80 should be set\n");
182293bf6008Sagc 			return 0;
182393bf6008Sagc 		}
182493bf6008Sagc 		/* octet 1 = algid */
18256715e11aSagc 		if (!limread(&pkt.u.ss_revocation_key.algid, 1,
182641335e2dSagc 				&subregion, stream)) {
182793bf6008Sagc 			return 0;
18282232f800Sagc 		}
182993bf6008Sagc 		/* octets 2-21 = fingerprint */
18306715e11aSagc 		if (!limread(&pkt.u.ss_revocation_key.fingerprint[0],
1831fc1f8641Sagc 				PGP_FINGERPRINT_SIZE, &subregion, stream)) {
183293bf6008Sagc 			return 0;
18332232f800Sagc 		}
183493bf6008Sagc 		break;
183593bf6008Sagc 
183693bf6008Sagc 	default:
183741335e2dSagc 		if (stream->ss_parsed[t8] & t7) {
1838fc1f8641Sagc 			PGP_ERROR_1(&stream->errors, PGP_E_PROTO_UNKNOWN_SS,
18392232f800Sagc 				    "Unknown signature subpacket type (%d)",
184057324b9fSagc 				    c & 0x7f);
18412232f800Sagc 		}
18424b3a3e18Sagc 		doread = 0;
184393bf6008Sagc 		break;
184493bf6008Sagc 	}
184593bf6008Sagc 
184693bf6008Sagc 	/* Application doesn't want it delivered parsed */
184741335e2dSagc 	if (!(stream->ss_parsed[t8] & t7)) {
18482232f800Sagc 		if (pkt.critical) {
1849fc1f8641Sagc 			PGP_ERROR_1(&stream->errors,
1850fc1f8641Sagc 				PGP_E_PROTO_CRITICAL_SS_IGNORED,
185193bf6008Sagc 				"Critical signature subpacket ignored (%d)",
185257324b9fSagc 				c & 0x7f);
18532232f800Sagc 		}
18542232f800Sagc 		if (!doread &&
185541335e2dSagc 		    !limskip(subregion.length - 1, &subregion, stream)) {
185693bf6008Sagc 			return 0;
18572232f800Sagc 		}
18582232f800Sagc 		if (doread) {
1859fc1f8641Sagc 			pgp_parser_content_free(&pkt);
18602232f800Sagc 		}
186193bf6008Sagc 		return 1;
186293bf6008Sagc 	}
186357324b9fSagc 	if (doread && subregion.readc != subregion.length) {
1864fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
186593bf6008Sagc 			    "Unconsumed data (%d)",
186657324b9fSagc 			    subregion.length - subregion.readc);
186793bf6008Sagc 		return 0;
186893bf6008Sagc 	}
186941335e2dSagc 	CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
187093bf6008Sagc 	return 1;
187193bf6008Sagc }
187293bf6008Sagc 
187393bf6008Sagc /**
187493bf6008Sagc  * \ingroup Core_ReadPackets
187593bf6008Sagc  * \brief Parse several signature subpackets.
187693bf6008Sagc  *
187793bf6008Sagc  * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set.
18783326c4c5Sagc  * This function parses this length and then calls parse_one_sig_subpacket() for each subpacket until the
187993bf6008Sagc  * entire set is consumed.
188093bf6008Sagc  *
18813326c4c5Sagc  * This function does not call the callback directly, parse_one_sig_subpacket() does for each subpacket.
188293bf6008Sagc  *
188393bf6008Sagc  * \param *ptag		Pointer to the Packet Tag.
188493bf6008Sagc  * \param *reader	Our reader
188593bf6008Sagc  * \param *cb		The callback
188693bf6008Sagc  * \return		1 on success, 0 on error
188793bf6008Sagc  *
188893bf6008Sagc  * \see RFC4880 5.2.3
188993bf6008Sagc  */
189093bf6008Sagc static int
parse_sig_subpkts(pgp_sig_t * sig,pgp_region_t * region,pgp_stream_t * stream)1891fc1f8641Sagc parse_sig_subpkts(pgp_sig_t *sig,
1892fc1f8641Sagc 			   pgp_region_t *region,
1893fc1f8641Sagc 			   pgp_stream_t *stream)
189493bf6008Sagc {
1895fc1f8641Sagc 	pgp_region_t	subregion;
1896fc1f8641Sagc 	pgp_packet_t	pkt;
189793bf6008Sagc 
1898fc1f8641Sagc 	pgp_init_subregion(&subregion, region);
189941335e2dSagc 	if (!limread_scalar(&subregion.length, 2, region, stream)) {
190093bf6008Sagc 		return 0;
1901bcfd8565Sagc 	}
190293bf6008Sagc 
1903bcfd8565Sagc 	if (subregion.length > region->length) {
190441335e2dSagc 		ERRP(&stream->cbinfo, pkt, "Subpacket set too long");
1905bcfd8565Sagc 	}
190693bf6008Sagc 
190757324b9fSagc 	while (subregion.readc < subregion.length) {
190841335e2dSagc 		if (!parse_one_sig_subpacket(sig, &subregion, stream)) {
190993bf6008Sagc 			return 0;
1910bcfd8565Sagc 		}
1911bcfd8565Sagc 	}
191293bf6008Sagc 
191357324b9fSagc 	if (subregion.readc != subregion.length) {
19146715e11aSagc 		if (!limskip(subregion.length - subregion.readc,
191541335e2dSagc 				&subregion, stream)) {
191641335e2dSagc 			ERRP(&stream->cbinfo, pkt,
191757324b9fSagc "parse_sig_subpkts: subpacket length read mismatch");
1918bcfd8565Sagc 		}
191941335e2dSagc 		ERRP(&stream->cbinfo, pkt, "Subpacket length mismatch");
192093bf6008Sagc 	}
192193bf6008Sagc 	return 1;
192293bf6008Sagc }
192393bf6008Sagc 
192493bf6008Sagc /**
192593bf6008Sagc  * \ingroup Core_ReadPackets
192693bf6008Sagc  * \brief Parse a version 4 signature.
192793bf6008Sagc  *
192893bf6008Sagc  * This function parses a version 4 signature including all its hashed and unhashed subpackets.
192993bf6008Sagc  *
193093bf6008Sagc  * Once the signature packet has been parsed successfully, it is passed to the callback.
193193bf6008Sagc  *
193293bf6008Sagc  * \param *ptag		Pointer to the Packet Tag.
193393bf6008Sagc  * \param *reader	Our reader
193493bf6008Sagc  * \param *cb		The callback
193593bf6008Sagc  * \return		1 on success, 0 on error
193693bf6008Sagc  *
193793bf6008Sagc  * \see RFC4880 5.2.3
193893bf6008Sagc  */
193993bf6008Sagc static int
parse_v4_sig(pgp_region_t * region,pgp_stream_t * stream)1940fc1f8641Sagc parse_v4_sig(pgp_region_t *region, pgp_stream_t *stream)
194193bf6008Sagc {
1942fc1f8641Sagc 	pgp_packet_t	pkt;
1943b15ec256Sagc 	uint8_t		c = 0x0;
194493bf6008Sagc 
1945fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
19463326c4c5Sagc 		fprintf(stderr, "\nparse_v4_sig\n");
194793bf6008Sagc 	}
194893bf6008Sagc 	/* clear signature */
19493326c4c5Sagc 	(void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
195093bf6008Sagc 
195193bf6008Sagc 	/*
195293bf6008Sagc 	 * We need to hash the packet data from version through the hashed
195393bf6008Sagc 	 * subpacket data
195493bf6008Sagc 	 */
195593bf6008Sagc 
195641335e2dSagc 	pkt.u.sig.v4_hashstart = stream->readinfo.alength - 1;
195793bf6008Sagc 
195893bf6008Sagc 	/* Set version,type,algorithms */
195993bf6008Sagc 
1960fc1f8641Sagc 	pkt.u.sig.info.version = PGP_V4;
196193bf6008Sagc 
196241335e2dSagc 	if (!limread(&c, 1, region, stream)) {
196393bf6008Sagc 		return 0;
19646715e11aSagc 	}
1965fc1f8641Sagc 	pkt.u.sig.info.type = (pgp_sig_type_t)c;
1966fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
196793bf6008Sagc 		fprintf(stderr, "signature type=%d (%s)\n",
19683326c4c5Sagc 			pkt.u.sig.info.type,
1969fc1f8641Sagc 			pgp_show_sig_type(pkt.u.sig.info.type));
197093bf6008Sagc 	}
197193bf6008Sagc 	/* XXX: check signature type */
197293bf6008Sagc 
197341335e2dSagc 	if (!limread(&c, 1, region, stream)) {
197493bf6008Sagc 		return 0;
197593bf6008Sagc 	}
1976fc1f8641Sagc 	pkt.u.sig.info.key_alg = (pgp_pubkey_alg_t)c;
1977600b302bSagc 	/* XXX: check key algorithm */
1978fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
19792232f800Sagc 		(void) fprintf(stderr, "key_alg=%d (%s)\n",
19802232f800Sagc 			pkt.u.sig.info.key_alg,
1981fc1f8641Sagc 			pgp_show_pka(pkt.u.sig.info.key_alg));
19822232f800Sagc 	}
198341335e2dSagc 	if (!limread(&c, 1, region, stream)) {
19842232f800Sagc 		return 0;
19852232f800Sagc 	}
1986fc1f8641Sagc 	pkt.u.sig.info.hash_alg = (pgp_hash_alg_t)c;
1987600b302bSagc 	/* XXX: check hash algorithm */
1988fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
19892232f800Sagc 		fprintf(stderr, "hash_alg=%d %s\n",
19902232f800Sagc 			pkt.u.sig.info.hash_alg,
1991fc1f8641Sagc 		  pgp_show_hash_alg(pkt.u.sig.info.hash_alg));
199293bf6008Sagc 	}
1993fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_SIGNATURE_HEADER, &stream->cbinfo, &pkt);
199493bf6008Sagc 
199541335e2dSagc 	if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
199693bf6008Sagc 		return 0;
19972232f800Sagc 	}
199893bf6008Sagc 
199941335e2dSagc 	pkt.u.sig.info.v4_hashlen = stream->readinfo.alength
20006715e11aSagc 					- pkt.u.sig.v4_hashstart;
2001fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
2002024dc5b6Sdsl 		fprintf(stderr, "v4_hashlen=%zd\n", pkt.u.sig.info.v4_hashlen);
2003600b302bSagc 	}
200493bf6008Sagc 
200593bf6008Sagc 	/* copy hashed subpackets */
20066715e11aSagc 	if (pkt.u.sig.info.v4_hashed) {
200757036e70Sagc 		free(pkt.u.sig.info.v4_hashed);
20082232f800Sagc 	}
20096715e11aSagc 	pkt.u.sig.info.v4_hashed = calloc(1, pkt.u.sig.info.v4_hashlen);
20100aa9bccaSagc 	if (pkt.u.sig.info.v4_hashed == NULL) {
20110aa9bccaSagc 		(void) fprintf(stderr, "parse_v4_sig: bad alloc\n");
20120aa9bccaSagc 		return 0;
20130aa9bccaSagc 	}
201493bf6008Sagc 
201541335e2dSagc 	if (!stream->readinfo.accumulate) {
201693bf6008Sagc 		/* We must accumulate, else we can't check the signature */
20174b3a3e18Sagc 		fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
2018ed0df671Sagc 		return 0;
201993bf6008Sagc 	}
20206715e11aSagc 	(void) memcpy(pkt.u.sig.info.v4_hashed,
202141335e2dSagc 	       stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
20226715e11aSagc 	       pkt.u.sig.info.v4_hashlen);
202393bf6008Sagc 
202441335e2dSagc 	if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
202593bf6008Sagc 		return 0;
20262232f800Sagc 	}
202793bf6008Sagc 
202841335e2dSagc 	if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
202993bf6008Sagc 		return 0;
20302232f800Sagc 	}
203193bf6008Sagc 
20322232f800Sagc 	switch (pkt.u.sig.info.key_alg) {
2033fc1f8641Sagc 	case PGP_PKA_RSA:
203441335e2dSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
203593bf6008Sagc 			return 0;
20362232f800Sagc 		}
2037fc1f8641Sagc 		if (pgp_get_debug_level(__FILE__)) {
2038600b302bSagc 			(void) fprintf(stderr, "parse_v4_sig: RSA: sig is\n");
2039600b302bSagc 			BN_print_fp(stderr, pkt.u.sig.info.sig.rsa.sig);
2040c973dd49Sagc 			(void) fprintf(stderr, "\n");
2041600b302bSagc 		}
204293bf6008Sagc 		break;
204393bf6008Sagc 
2044fc1f8641Sagc 	case PGP_PKA_DSA:
204541335e2dSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream)) {
204693bf6008Sagc 			/*
204793bf6008Sagc 			 * usually if this fails, it just means we've reached
204893bf6008Sagc 			 * the end of the keyring
204993bf6008Sagc 			 */
2050fc1f8641Sagc 			if (pgp_get_debug_level(__FILE__)) {
20512232f800Sagc 				(void) fprintf(stderr,
20522232f800Sagc 				"Error reading DSA r field in signature");
205393bf6008Sagc 			}
205493bf6008Sagc 			return 0;
205593bf6008Sagc 		}
205641335e2dSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
205741335e2dSagc 			ERRP(&stream->cbinfo, pkt,
20582232f800Sagc 			"Error reading DSA s field in signature");
20592232f800Sagc 		}
206093bf6008Sagc 		break;
206193bf6008Sagc 
2062*0294a66bSjhigh 	case PGP_PKA_ECDSA:
2063*0294a66bSjhigh 		if (!limread_mpi(&pkt.u.sig.info.sig.ecdsa.r, region, stream) ||
2064*0294a66bSjhigh 		    !limread_mpi(&pkt.u.sig.info.sig.ecdsa.s, region, stream)) {
2065*0294a66bSjhigh 			return 0;
2066*0294a66bSjhigh 		}
2067*0294a66bSjhigh 		break;
2068*0294a66bSjhigh 
2069fc1f8641Sagc 	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
20706715e11aSagc 		if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
207141335e2dSagc 				stream) ||
20726715e11aSagc 		    !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
207341335e2dSagc 		    		stream)) {
207493bf6008Sagc 			return 0;
20752232f800Sagc 		}
207693bf6008Sagc 		break;
207793bf6008Sagc 
2078fc1f8641Sagc 	case PGP_PKA_PRIVATE00:
2079fc1f8641Sagc 	case PGP_PKA_PRIVATE01:
2080fc1f8641Sagc 	case PGP_PKA_PRIVATE02:
2081fc1f8641Sagc 	case PGP_PKA_PRIVATE03:
2082fc1f8641Sagc 	case PGP_PKA_PRIVATE04:
2083fc1f8641Sagc 	case PGP_PKA_PRIVATE05:
2084fc1f8641Sagc 	case PGP_PKA_PRIVATE06:
2085fc1f8641Sagc 	case PGP_PKA_PRIVATE07:
2086fc1f8641Sagc 	case PGP_PKA_PRIVATE08:
2087fc1f8641Sagc 	case PGP_PKA_PRIVATE09:
2088fc1f8641Sagc 	case PGP_PKA_PRIVATE10:
2089d427c17dSagc 		if (!read_data(&pkt.u.sig.info.sig.unknown, region, stream)) {
209093bf6008Sagc 			return 0;
20912232f800Sagc 		}
209293bf6008Sagc 		break;
209393bf6008Sagc 
209493bf6008Sagc 	default:
2095fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
209693bf6008Sagc 			    "Bad v4 signature key algorithm (%s)",
2097fc1f8641Sagc 			    pgp_show_pka(pkt.u.sig.info.key_alg));
209893bf6008Sagc 		return 0;
209993bf6008Sagc 	}
210057324b9fSagc 	if (region->readc != region->length) {
2101fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_R_UNCONSUMED_DATA,
210293bf6008Sagc 			    "Unconsumed data (%d)",
210357324b9fSagc 			    region->length - region->readc);
210493bf6008Sagc 		return 0;
210593bf6008Sagc 	}
2106fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
210793bf6008Sagc 	return 1;
210893bf6008Sagc }
210993bf6008Sagc 
211093bf6008Sagc /**
211193bf6008Sagc  * \ingroup Core_ReadPackets
211293bf6008Sagc  * \brief Parse a signature subpacket.
211393bf6008Sagc  *
211493bf6008Sagc  * This function calls the appropriate function to handle v3 or v4 signatures.
211593bf6008Sagc  *
211693bf6008Sagc  * Once the signature packet has been parsed successfully, it is passed to the callback.
211793bf6008Sagc  *
211893bf6008Sagc  * \param *ptag		Pointer to the Packet Tag.
211993bf6008Sagc  * \param *reader	Our reader
212093bf6008Sagc  * \param *cb		The callback
212193bf6008Sagc  * \return		1 on success, 0 on error
212293bf6008Sagc  */
212393bf6008Sagc static int
parse_sig(pgp_region_t * region,pgp_stream_t * stream)2124fc1f8641Sagc parse_sig(pgp_region_t *region, pgp_stream_t *stream)
212593bf6008Sagc {
2126fc1f8641Sagc 	pgp_packet_t	pkt;
2127b15ec256Sagc 	uint8_t		c = 0x0;
212893bf6008Sagc 
212957324b9fSagc 	if (region->readc != 0) {
2130ed0df671Sagc 		/* We should not have read anything so far */
21313326c4c5Sagc 		(void) fprintf(stderr, "parse_sig: bad length\n");
2132ed0df671Sagc 		return 0;
2133ed0df671Sagc 	}
213493bf6008Sagc 
2135bcfd8565Sagc 	(void) memset(&pkt, 0x0, sizeof(pkt));
213641335e2dSagc 	if (!limread(&c, 1, region, stream)) {
213793bf6008Sagc 		return 0;
21386715e11aSagc 	}
21396715e11aSagc 	if (c == 2 || c == 3) {
214041335e2dSagc 		return parse_v3_sig(region, stream);
21416715e11aSagc 	}
21426715e11aSagc 	if (c == 4) {
214341335e2dSagc 		return parse_v4_sig(region, stream);
21446715e11aSagc 	}
2145fc1f8641Sagc 	PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_SIGNATURE_VRSN,
214657324b9fSagc 		    "Bad signature version (%d)", c);
214793bf6008Sagc 	return 0;
214893bf6008Sagc }
214993bf6008Sagc 
215093bf6008Sagc /**
215193bf6008Sagc  \ingroup Core_ReadPackets
215293bf6008Sagc  \brief Parse Compressed packet
215393bf6008Sagc */
215493bf6008Sagc static int
parse_compressed(pgp_region_t * region,pgp_stream_t * stream)2155fc1f8641Sagc parse_compressed(pgp_region_t *region, pgp_stream_t *stream)
215693bf6008Sagc {
2157fc1f8641Sagc 	pgp_packet_t	pkt;
2158b15ec256Sagc 	uint8_t		c = 0x0;
215993bf6008Sagc 
216041335e2dSagc 	if (!limread(&c, 1, region, stream)) {
216193bf6008Sagc 		return 0;
2162bcfd8565Sagc 	}
216393bf6008Sagc 
2164fc1f8641Sagc 	pkt.u.compressed = (pgp_compression_type_t)c;
216593bf6008Sagc 
2166fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_COMPRESSED, &stream->cbinfo, &pkt);
216793bf6008Sagc 
216893bf6008Sagc 	/*
216993bf6008Sagc 	 * The content of a compressed data packet is more OpenPGP packets
217093bf6008Sagc 	 * once decompressed, so recursively handle them
217193bf6008Sagc 	 */
217293bf6008Sagc 
2173fc1f8641Sagc 	return pgp_decompress(region, stream, pkt.u.compressed);
217493bf6008Sagc }
217593bf6008Sagc 
217693bf6008Sagc /* XXX: this could be improved by sharing all hashes that are the */
217793bf6008Sagc /* same, then duping them just before checking the signature. */
217893bf6008Sagc static void
parse_hash_init(pgp_stream_t * stream,pgp_hash_alg_t type,const uint8_t * keyid)2179fc1f8641Sagc parse_hash_init(pgp_stream_t *stream, pgp_hash_alg_t type,
2180b15ec256Sagc 		    const uint8_t *keyid)
218193bf6008Sagc {
2182fc1f8641Sagc 	pgp_hashtype_t *hash;
218393bf6008Sagc 
21840aa9bccaSagc 	hash = realloc(stream->hashes,
218541335e2dSagc 			      (stream->hashc + 1) * sizeof(*stream->hashes));
21860aa9bccaSagc 	if (hash == NULL) {
21870aa9bccaSagc 		(void) fprintf(stderr, "parse_hash_init: bad alloc 0\n");
21880aa9bccaSagc 		/* just continue and die here */
21890aa9bccaSagc 		/* XXX - agc - no way to return failure */
21900aa9bccaSagc 	} else {
21910aa9bccaSagc 		stream->hashes = hash;
21920aa9bccaSagc 	}
219341335e2dSagc 	hash = &stream->hashes[stream->hashc++];
219493bf6008Sagc 
2195fc1f8641Sagc 	pgp_hash_any(&hash->hash, type);
21967affbacaSagc 	if (!hash->hash.init(&hash->hash)) {
21977affbacaSagc 		(void) fprintf(stderr, "parse_hash_init: bad alloc\n");
21987affbacaSagc 		/* just continue and die here */
21997affbacaSagc 		/* XXX - agc - no way to return failure */
22007affbacaSagc 	}
220193bf6008Sagc 	(void) memcpy(hash->keyid, keyid, sizeof(hash->keyid));
220293bf6008Sagc }
220393bf6008Sagc 
220493bf6008Sagc /**
220593bf6008Sagc    \ingroup Core_ReadPackets
220693bf6008Sagc    \brief Parse a One Pass Signature packet
220793bf6008Sagc */
220893bf6008Sagc static int
parse_one_pass(pgp_region_t * region,pgp_stream_t * stream)2209fc1f8641Sagc parse_one_pass(pgp_region_t * region, pgp_stream_t * stream)
221093bf6008Sagc {
2211fc1f8641Sagc 	pgp_packet_t	pkt;
2212b15ec256Sagc 	uint8_t		c = 0x0;
221393bf6008Sagc 
221441335e2dSagc 	if (!limread(&pkt.u.one_pass_sig.version, 1, region, stream)) {
221593bf6008Sagc 		return 0;
22162232f800Sagc 	}
22173326c4c5Sagc 	if (pkt.u.one_pass_sig.version != 3) {
2218fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_ONE_PASS_SIG_VRSN,
221993bf6008Sagc 			    "Bad one-pass signature version (%d)",
22203326c4c5Sagc 			    pkt.u.one_pass_sig.version);
222193bf6008Sagc 		return 0;
222293bf6008Sagc 	}
222341335e2dSagc 	if (!limread(&c, 1, region, stream)) {
222493bf6008Sagc 		return 0;
22252232f800Sagc 	}
2226fc1f8641Sagc 	pkt.u.one_pass_sig.sig_type = (pgp_sig_type_t)c;
222793bf6008Sagc 
222841335e2dSagc 	if (!limread(&c, 1, region, stream)) {
222993bf6008Sagc 		return 0;
22302232f800Sagc 	}
2231fc1f8641Sagc 	pkt.u.one_pass_sig.hash_alg = (pgp_hash_alg_t)c;
223293bf6008Sagc 
223341335e2dSagc 	if (!limread(&c, 1, region, stream)) {
223493bf6008Sagc 		return 0;
22352232f800Sagc 	}
2236fc1f8641Sagc 	pkt.u.one_pass_sig.key_alg = (pgp_pubkey_alg_t)c;
223793bf6008Sagc 
22386715e11aSagc 	if (!limread(pkt.u.one_pass_sig.keyid,
22393f685a78Sagc 			  (unsigned)sizeof(pkt.u.one_pass_sig.keyid),
22403f685a78Sagc 			  region, stream)) {
224193bf6008Sagc 		return 0;
22422232f800Sagc 	}
224393bf6008Sagc 
224441335e2dSagc 	if (!limread(&c, 1, region, stream)) {
224593bf6008Sagc 		return 0;
22462232f800Sagc 	}
224757324b9fSagc 	pkt.u.one_pass_sig.nested = !!c;
2248fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_1_PASS_SIG, &stream->cbinfo, &pkt);
224993bf6008Sagc 	/* XXX: we should, perhaps, let the app choose whether to hash or not */
225041335e2dSagc 	parse_hash_init(stream, pkt.u.one_pass_sig.hash_alg,
22513326c4c5Sagc 			    pkt.u.one_pass_sig.keyid);
225293bf6008Sagc 	return 1;
225393bf6008Sagc }
225493bf6008Sagc 
225593bf6008Sagc /**
225693bf6008Sagc  \ingroup Core_ReadPackets
225793bf6008Sagc  \brief Parse a Trust packet
225893bf6008Sagc */
225993bf6008Sagc static int
parse_trust(pgp_region_t * region,pgp_stream_t * stream)2260fc1f8641Sagc parse_trust(pgp_region_t *region, pgp_stream_t *stream)
226193bf6008Sagc {
2262fc1f8641Sagc 	pgp_packet_t pkt;
226393bf6008Sagc 
2264d427c17dSagc 	if (!read_data(&pkt.u.trust, region, stream)) {
226593bf6008Sagc 		return 0;
22662232f800Sagc 	}
2267fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_TRUST, &stream->cbinfo, &pkt);
226893bf6008Sagc 	return 1;
226993bf6008Sagc }
227093bf6008Sagc 
227193bf6008Sagc static void
parse_hash_data(pgp_stream_t * stream,const void * data,size_t length)2272fc1f8641Sagc parse_hash_data(pgp_stream_t *stream, const void *data,
227393bf6008Sagc 		    size_t length)
227493bf6008Sagc {
227593bf6008Sagc 	size_t          n;
227693bf6008Sagc 
227741335e2dSagc 	for (n = 0; n < stream->hashc; ++n) {
22783f685a78Sagc 		stream->hashes[n].hash.add(&stream->hashes[n].hash, data, (unsigned)length);
227993bf6008Sagc 	}
228093bf6008Sagc }
228193bf6008Sagc 
228293bf6008Sagc /**
228393bf6008Sagc    \ingroup Core_ReadPackets
228493bf6008Sagc    \brief Parse a Literal Data packet
228593bf6008Sagc */
228693bf6008Sagc static int
parse_litdata(pgp_region_t * region,pgp_stream_t * stream)2287fc1f8641Sagc parse_litdata(pgp_region_t *region, pgp_stream_t *stream)
228893bf6008Sagc {
2289fc1f8641Sagc 	pgp_memory_t	*mem;
2290fc1f8641Sagc 	pgp_packet_t	 pkt;
2291b15ec256Sagc 	uint8_t		 c = 0x0;
229293bf6008Sagc 
229341335e2dSagc 	if (!limread(&c, 1, region, stream)) {
229493bf6008Sagc 		return 0;
2295bcfd8565Sagc 	}
2296fc1f8641Sagc 	pkt.u.litdata_header.format = (pgp_litdata_enum)c;
229741335e2dSagc 	if (!limread(&c, 1, region, stream)) {
229893bf6008Sagc 		return 0;
2299bcfd8565Sagc 	}
2300b15ec256Sagc 	if (!limread((uint8_t *)pkt.u.litdata_header.filename,
230141335e2dSagc 			(unsigned)c, region, stream)) {
230293bf6008Sagc 		return 0;
2303bcfd8565Sagc 	}
230457324b9fSagc 	pkt.u.litdata_header.filename[c] = '\0';
230541335e2dSagc 	if (!limited_read_time(&pkt.u.litdata_header.mtime, region, stream)) {
230693bf6008Sagc 		return 0;
2307bcfd8565Sagc 	}
2308fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_LITDATA_HEADER, &stream->cbinfo, &pkt);
2309fc1f8641Sagc 	mem = pkt.u.litdata_body.mem = pgp_memory_new();
2310fc1f8641Sagc 	pgp_memory_init(pkt.u.litdata_body.mem,
231157036e70Sagc 			(unsigned)((region->length * 101) / 100) + 12);
23123326c4c5Sagc 	pkt.u.litdata_body.data = mem->buf;
231393bf6008Sagc 
231457324b9fSagc 	while (region->readc < region->length) {
231557324b9fSagc 		unsigned        readc = region->length - region->readc;
231693bf6008Sagc 
231741335e2dSagc 		if (!limread(mem->buf, readc, region, stream)) {
231893bf6008Sagc 			return 0;
231993bf6008Sagc 		}
23203326c4c5Sagc 		pkt.u.litdata_body.length = readc;
232141335e2dSagc 		parse_hash_data(stream, pkt.u.litdata_body.data, region->length);
2322fc1f8641Sagc 		CALLBACK(PGP_PTAG_CT_LITDATA_BODY, &stream->cbinfo, &pkt);
232393bf6008Sagc 	}
232493bf6008Sagc 
232593bf6008Sagc 	/* XXX - get rid of mem here? */
232693bf6008Sagc 
232793bf6008Sagc 	return 1;
232893bf6008Sagc }
232993bf6008Sagc 
233093bf6008Sagc /**
233193bf6008Sagc  * \ingroup Core_Create
233293bf6008Sagc  *
2333fc1f8641Sagc  * pgp_seckey_free() frees the memory associated with "key". Note that
233493bf6008Sagc  * the key itself is not freed.
233593bf6008Sagc  *
233693bf6008Sagc  * \param key
233793bf6008Sagc  */
233893bf6008Sagc 
233993bf6008Sagc void
pgp_seckey_free(pgp_seckey_t * key)2340fc1f8641Sagc pgp_seckey_free(pgp_seckey_t *key)
234193bf6008Sagc {
23422232f800Sagc 	switch (key->pubkey.alg) {
2343fc1f8641Sagc 	case PGP_PKA_RSA:
2344fc1f8641Sagc 	case PGP_PKA_RSA_ENCRYPT_ONLY:
2345fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
234693bf6008Sagc 		free_BN(&key->key.rsa.d);
234793bf6008Sagc 		free_BN(&key->key.rsa.p);
234893bf6008Sagc 		free_BN(&key->key.rsa.q);
234993bf6008Sagc 		free_BN(&key->key.rsa.u);
235093bf6008Sagc 		break;
235193bf6008Sagc 
2352fc1f8641Sagc 	case PGP_PKA_DSA:
235393bf6008Sagc 		free_BN(&key->key.dsa.x);
235493bf6008Sagc 		break;
235593bf6008Sagc 
2356*0294a66bSjhigh 	case PGP_PKA_ECDSA:
2357*0294a66bSjhigh 		free_BN(&key->key.ecdsa.x);
2358*0294a66bSjhigh 		break;
2359*0294a66bSjhigh 
236093bf6008Sagc 	default:
2361bcfd8565Sagc 		(void) fprintf(stderr,
2362fc1f8641Sagc 			"pgp_seckey_free: Unknown algorithm: %d (%s)\n",
23632232f800Sagc 			key->pubkey.alg,
2364fc1f8641Sagc 			pgp_show_pka(key->pubkey.alg));
236593bf6008Sagc 	}
236657036e70Sagc 	free(key->checkhash);
236793bf6008Sagc }
236893bf6008Sagc 
236993bf6008Sagc static int
consume_packet(pgp_region_t * region,pgp_stream_t * stream,unsigned warn)2370fc1f8641Sagc consume_packet(pgp_region_t *region, pgp_stream_t *stream, unsigned warn)
237193bf6008Sagc {
2372fc1f8641Sagc 	pgp_packet_t	pkt;
2373fc1f8641Sagc 	pgp_data_t	remainder;
237493bf6008Sagc 
2375bcfd8565Sagc 	if (region->indeterminate) {
237641335e2dSagc 		ERRP(&stream->cbinfo, pkt,
23772232f800Sagc 			"Can't consume indeterminate packets");
2378bcfd8565Sagc 	}
237993bf6008Sagc 
238041335e2dSagc 	if (read_data(&remainder, region, stream)) {
2381bcfd8565Sagc 		/* now throw it away */
2382fc1f8641Sagc 		pgp_data_free(&remainder);
2383bcfd8565Sagc 		if (warn) {
238494fcde8eSchristos 			PGP_ERROR_1(&stream->errors, PGP_E_P_PACKET_CONSUMED,
238594fcde8eSchristos 			    "%s", "Warning: packet consumer");
2386bcfd8565Sagc 		}
2387bcfd8565Sagc 		return 1;
2388bcfd8565Sagc 	}
238994fcde8eSchristos 	PGP_ERROR_1(&stream->errors, PGP_E_P_PACKET_NOT_CONSUMED,
239094fcde8eSchristos 	    "%s", (warn) ? "Warning: Packet was not consumed" :
2391bcfd8565Sagc 	    "Packet was not consumed");
2392bcfd8565Sagc 	return warn;
239393bf6008Sagc }
239493bf6008Sagc 
239593bf6008Sagc /**
239693bf6008Sagc  * \ingroup Core_ReadPackets
239793bf6008Sagc  * \brief Parse a secret key
239893bf6008Sagc  */
239993bf6008Sagc static int
parse_seckey(pgp_region_t * region,pgp_stream_t * stream)2400fc1f8641Sagc parse_seckey(pgp_region_t *region, pgp_stream_t *stream)
240193bf6008Sagc {
2402fc1f8641Sagc 	pgp_packet_t		pkt;
2403fc1f8641Sagc 	pgp_region_t		encregion;
2404fc1f8641Sagc 	pgp_region_t	       *saved_region = NULL;
2405fc1f8641Sagc 	pgp_crypt_t		decrypt;
2406fc1f8641Sagc 	pgp_hash_t		checkhash;
2407efdd9dbaSagc 	unsigned		blocksize;
24084b3a3e18Sagc 	unsigned		crypted;
2409b15ec256Sagc 	uint8_t			c = 0x0;
2410efdd9dbaSagc 	int			ret = 1;
241193bf6008Sagc 
2412fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
24133326c4c5Sagc 		fprintf(stderr, "\n---------\nparse_seckey:\n");
24142232f800Sagc 		fprintf(stderr,
241557036e70Sagc 			"region length=%u, readc=%u, remainder=%u\n",
241657324b9fSagc 			region->length, region->readc,
241757324b9fSagc 			region->length - region->readc);
241893bf6008Sagc 	}
2419bcfd8565Sagc 	(void) memset(&pkt, 0x0, sizeof(pkt));
242041335e2dSagc 	if (!parse_pubkey_data(&pkt.u.seckey.pubkey, region, stream)) {
242193bf6008Sagc 		return 0;
24226715e11aSagc 	}
2423fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
24243326c4c5Sagc 		fprintf(stderr, "parse_seckey: public key parsed\n");
2425fc1f8641Sagc 		pgp_print_pubkey(&pkt.u.seckey.pubkey);
242693bf6008Sagc 	}
2427fc1f8641Sagc 	stream->reading_v3_secret = (pkt.u.seckey.pubkey.version != PGP_V4);
242893bf6008Sagc 
242941335e2dSagc 	if (!limread(&c, 1, region, stream)) {
243093bf6008Sagc 		return 0;
24312232f800Sagc 	}
2432fc1f8641Sagc 	pkt.u.seckey.s2k_usage = (pgp_s2k_usage_t)c;
243393bf6008Sagc 
2434fc1f8641Sagc 	if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED ||
2435fc1f8641Sagc 	    pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
243641335e2dSagc 		if (!limread(&c, 1, region, stream)) {
243793bf6008Sagc 			return 0;
243893bf6008Sagc 		}
2439fc1f8641Sagc 		pkt.u.seckey.alg = (pgp_symm_alg_t)c;
244041335e2dSagc 		if (!limread(&c, 1, region, stream)) {
244193bf6008Sagc 			return 0;
244293bf6008Sagc 		}
2443fc1f8641Sagc 		pkt.u.seckey.s2k_specifier = (pgp_s2k_specifier_t)c;
24443326c4c5Sagc 		switch (pkt.u.seckey.s2k_specifier) {
2445fc1f8641Sagc 		case PGP_S2KS_SIMPLE:
2446fc1f8641Sagc 		case PGP_S2KS_SALTED:
2447fc1f8641Sagc 		case PGP_S2KS_ITERATED_AND_SALTED:
2448ed0df671Sagc 			break;
2449ed0df671Sagc 		default:
2450ed0df671Sagc 			(void) fprintf(stderr,
24513326c4c5Sagc 				"parse_seckey: bad seckey\n");
2452ed0df671Sagc 			return 0;
2453ed0df671Sagc 		}
245441335e2dSagc 		if (!limread(&c, 1, region, stream)) {
2455bcfd8565Sagc 			return 0;
2456bcfd8565Sagc 		}
2457fc1f8641Sagc 		pkt.u.seckey.hash_alg = (pgp_hash_alg_t)c;
2458fc1f8641Sagc 		if (pkt.u.seckey.s2k_specifier != PGP_S2KS_SIMPLE &&
245941335e2dSagc 		    !limread(pkt.u.seckey.salt, 8, region, stream)) {
2460bcfd8565Sagc 			return 0;
2461bcfd8565Sagc 		}
24623326c4c5Sagc 		if (pkt.u.seckey.s2k_specifier ==
2463fc1f8641Sagc 					PGP_S2KS_ITERATED_AND_SALTED) {
246441335e2dSagc 			if (!limread(&c, 1, region, stream)) {
2465bcfd8565Sagc 				return 0;
2466bcfd8565Sagc 			}
24672232f800Sagc 			pkt.u.seckey.octetc =
246857324b9fSagc 				(16 + ((unsigned)c & 15)) <<
246957324b9fSagc 						(((unsigned)c >> 4) + 6);
2470bcfd8565Sagc 		}
2471fc1f8641Sagc 	} else if (pkt.u.seckey.s2k_usage != PGP_S2KU_NONE) {
247293bf6008Sagc 		/* this is V3 style, looks just like a V4 simple hash */
2473fc1f8641Sagc 		pkt.u.seckey.alg = (pgp_symm_alg_t)c;
2474fc1f8641Sagc 		pkt.u.seckey.s2k_usage = PGP_S2KU_ENCRYPTED;
2475fc1f8641Sagc 		pkt.u.seckey.s2k_specifier = PGP_S2KS_SIMPLE;
2476fc1f8641Sagc 		pkt.u.seckey.hash_alg = PGP_HASH_MD5;
247793bf6008Sagc 	}
2478fc1f8641Sagc 	crypted = pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED ||
2479fc1f8641Sagc 		pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED;
248093bf6008Sagc 
248193bf6008Sagc 	if (crypted) {
2482fc1f8641Sagc 		pgp_packet_t	seckey;
2483fc1f8641Sagc 		pgp_hash_t	hashes[(PGP_MAX_KEY_SIZE + PGP_MIN_HASH_SIZE - 1) / PGP_MIN_HASH_SIZE];
24843f685a78Sagc 		unsigned	passlen;
2485fc1f8641Sagc 		uint8_t   	key[PGP_MAX_KEY_SIZE + PGP_MAX_HASH_SIZE];
24866715e11aSagc 		char           *passphrase;
248793bf6008Sagc 		int             hashsize;
24886715e11aSagc 		int             keysize;
24896715e11aSagc 		int             n;
249093bf6008Sagc 
2491fc1f8641Sagc 		if (pgp_get_debug_level(__FILE__)) {
2492520c968fSagc 			(void) fprintf(stderr, "crypted seckey\n");
2493520c968fSagc 		}
2494fc1f8641Sagc 		blocksize = pgp_block_size(pkt.u.seckey.alg);
2495fc1f8641Sagc 		if (blocksize == 0 || blocksize > PGP_MAX_BLOCK_SIZE) {
2496ed0df671Sagc 			(void) fprintf(stderr,
24973326c4c5Sagc 				"parse_seckey: bad blocksize\n");
2498ed0df671Sagc 			return 0;
2499ed0df671Sagc 		}
250093bf6008Sagc 
250141335e2dSagc 		if (!limread(pkt.u.seckey.iv, blocksize, region, stream)) {
250293bf6008Sagc 			return 0;
2503bcfd8565Sagc 		}
250493bf6008Sagc 		(void) memset(&seckey, 0x0, sizeof(seckey));
250593bf6008Sagc 		passphrase = NULL;
2506bcfd8565Sagc 		seckey.u.skey_passphrase.passphrase = &passphrase;
25076715e11aSagc 		seckey.u.skey_passphrase.seckey = &pkt.u.seckey;
2508fc1f8641Sagc 		CALLBACK(PGP_GET_PASSPHRASE, &stream->cbinfo, &seckey);
250993bf6008Sagc 		if (!passphrase) {
2510fc1f8641Sagc 			if (pgp_get_debug_level(__FILE__)) {
251193bf6008Sagc 				/* \todo make into proper error */
2512bcfd8565Sagc 				(void) fprintf(stderr,
25133326c4c5Sagc 				"parse_seckey: can't get passphrase\n");
251493bf6008Sagc 			}
251541335e2dSagc 			if (!consume_packet(region, stream, 0)) {
251693bf6008Sagc 				return 0;
2517bcfd8565Sagc 			}
251893bf6008Sagc 
2519fc1f8641Sagc 			CALLBACK(PGP_PTAG_CT_ENCRYPTED_SECRET_KEY,
252041335e2dSagc 				&stream->cbinfo, &pkt);
252193bf6008Sagc 
252293bf6008Sagc 			return 1;
252393bf6008Sagc 		}
2524fc1f8641Sagc 		keysize = pgp_key_size(pkt.u.seckey.alg);
2525fc1f8641Sagc 		if (keysize == 0 || keysize > PGP_MAX_KEY_SIZE) {
2526ed0df671Sagc 			(void) fprintf(stderr,
25273326c4c5Sagc 				"parse_seckey: bad keysize\n");
2528ed0df671Sagc 			return 0;
2529ed0df671Sagc 		}
253093bf6008Sagc 
253105e6b0bbSagc 		/* Hardcoded SHA1 for just now */
253205e6b0bbSagc 		pkt.u.seckey.hash_alg = PGP_HASH_SHA1;
2533fc1f8641Sagc 		hashsize = pgp_hash_size(pkt.u.seckey.hash_alg);
2534fc1f8641Sagc 		if (hashsize == 0 || hashsize > PGP_MAX_HASH_SIZE) {
2535ed0df671Sagc 			(void) fprintf(stderr,
25363326c4c5Sagc 				"parse_seckey: bad hashsize\n");
2537ed0df671Sagc 			return 0;
2538ed0df671Sagc 		}
253993bf6008Sagc 
254093bf6008Sagc 		for (n = 0; n * hashsize < keysize; ++n) {
254193bf6008Sagc 			int             i;
254293bf6008Sagc 
2543fc1f8641Sagc 			pgp_hash_any(&hashes[n],
25442232f800Sagc 				pkt.u.seckey.hash_alg);
25457affbacaSagc 			if (!hashes[n].init(&hashes[n])) {
25467affbacaSagc 				(void) fprintf(stderr,
25477affbacaSagc 					"parse_seckey: bad alloc\n");
25487affbacaSagc 				return 0;
25497affbacaSagc 			}
255093bf6008Sagc 			/* preload hashes with zeroes... */
2551bcfd8565Sagc 			for (i = 0; i < n; ++i) {
2552bcfd8565Sagc 				hashes[n].add(&hashes[n],
2553b15ec256Sagc 					(const uint8_t *) "", 1);
2554bcfd8565Sagc 			}
255593bf6008Sagc 		}
2556593d671cSagc 		passlen = (unsigned)strlen(passphrase);
255793bf6008Sagc 		for (n = 0; n * hashsize < keysize; ++n) {
255893bf6008Sagc 			unsigned        i;
255993bf6008Sagc 
25603326c4c5Sagc 			switch (pkt.u.seckey.s2k_specifier) {
2561fc1f8641Sagc 			case PGP_S2KS_SALTED:
2562bcfd8565Sagc 				hashes[n].add(&hashes[n],
25633326c4c5Sagc 					pkt.u.seckey.salt,
2564fc1f8641Sagc 					PGP_SALT_SIZE);
256593bf6008Sagc 				/* FALLTHROUGH */
2566fc1f8641Sagc 			case PGP_S2KS_SIMPLE:
2567bcfd8565Sagc 				hashes[n].add(&hashes[n],
25683f685a78Sagc 					(uint8_t *)passphrase, (unsigned)passlen);
256993bf6008Sagc 				break;
257093bf6008Sagc 
2571fc1f8641Sagc 			case PGP_S2KS_ITERATED_AND_SALTED:
25722232f800Sagc 				for (i = 0; i < pkt.u.seckey.octetc;
2573fc1f8641Sagc 						i += passlen + PGP_SALT_SIZE) {
25742232f800Sagc 					unsigned	j;
257593bf6008Sagc 
2576fc1f8641Sagc 					j = passlen + PGP_SALT_SIZE;
25772232f800Sagc 					if (i + j > pkt.u.seckey.octetc && i != 0) {
25782232f800Sagc 						j = pkt.u.seckey.octetc - i;
2579bcfd8565Sagc 					}
2580efdd9dbaSagc 					hashes[n].add(&hashes[n],
25813326c4c5Sagc 						pkt.u.seckey.salt,
2582fc1f8641Sagc 						(unsigned)(j > PGP_SALT_SIZE) ?
2583fc1f8641Sagc 							PGP_SALT_SIZE : j);
2584fc1f8641Sagc 					if (j > PGP_SALT_SIZE) {
2585bcfd8565Sagc 						hashes[n].add(&hashes[n],
2586b15ec256Sagc 						(uint8_t *) passphrase,
2587fc1f8641Sagc 						j - PGP_SALT_SIZE);
2588bcfd8565Sagc 					}
258993bf6008Sagc 				}
2590632dc3acSagc 				break;
259157036e70Sagc 			default:
259257036e70Sagc 				break;
259393bf6008Sagc 			}
259493bf6008Sagc 		}
259593bf6008Sagc 
259693bf6008Sagc 		for (n = 0; n * hashsize < keysize; ++n) {
2597bcfd8565Sagc 			int	r;
2598bcfd8565Sagc 
2599bcfd8565Sagc 			r = hashes[n].finish(&hashes[n], key + n * hashsize);
2600ed0df671Sagc 			if (r != hashsize) {
2601ed0df671Sagc 				(void) fprintf(stderr,
26023326c4c5Sagc 					"parse_seckey: bad r\n");
2603ed0df671Sagc 				return 0;
2604ed0df671Sagc 			}
260593bf6008Sagc 		}
260693bf6008Sagc 
2607fc1f8641Sagc 		pgp_forget(passphrase, passlen);
260893bf6008Sagc 
2609fc1f8641Sagc 		pgp_crypt_any(&decrypt, pkt.u.seckey.alg);
2610fc1f8641Sagc 		if (pgp_get_debug_level(__FILE__)) {
2611fc1f8641Sagc 			hexdump(stderr, "input iv", pkt.u.seckey.iv, pgp_block_size(pkt.u.seckey.alg));
261247561e26Sagc 			hexdump(stderr, "key", key, CAST_KEY_LENGTH);
261393bf6008Sagc 		}
26143326c4c5Sagc 		decrypt.set_iv(&decrypt, pkt.u.seckey.iv);
2615f72138f8Sagc 		decrypt.set_crypt_key(&decrypt, key);
261693bf6008Sagc 
261793bf6008Sagc 		/* now read encrypted data */
261893bf6008Sagc 
2619fc1f8641Sagc 		pgp_reader_push_decrypt(stream, &decrypt, region);
262093bf6008Sagc 
262193bf6008Sagc 		/*
262293bf6008Sagc 		 * Since all known encryption for PGP doesn't compress, we
262393bf6008Sagc 		 * can limit to the same length as the current region (for
262493bf6008Sagc 		 * now).
262593bf6008Sagc 		 */
2626fc1f8641Sagc 		pgp_init_subregion(&encregion, NULL);
262757324b9fSagc 		encregion.length = region->length - region->readc;
2628fc1f8641Sagc 		if (pkt.u.seckey.pubkey.version != PGP_V4) {
262993bf6008Sagc 			encregion.length -= 2;
263093bf6008Sagc 		}
263193bf6008Sagc 		saved_region = region;
263293bf6008Sagc 		region = &encregion;
263393bf6008Sagc 	}
2634fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
2635520c968fSagc 		fprintf(stderr, "parse_seckey: end of crypted passphrase\n");
2636520c968fSagc 	}
2637fc1f8641Sagc 	if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
263805e6b0bbSagc 		/* XXX - Hard-coded SHA1 here ?? Check */
263905e6b0bbSagc 		pkt.u.seckey.checkhash = calloc(1, PGP_SHA1_HASH_SIZE);
26400aa9bccaSagc 		if (pkt.u.seckey.checkhash == NULL) {
26410aa9bccaSagc 			(void) fprintf(stderr, "parse_seckey: bad alloc\n");
26420aa9bccaSagc 			return 0;
26430aa9bccaSagc 		}
2644fc1f8641Sagc 		pgp_hash_sha1(&checkhash);
2645fc1f8641Sagc 		pgp_reader_push_hash(stream, &checkhash);
264693bf6008Sagc 	} else {
2647fc1f8641Sagc 		pgp_reader_push_sum16(stream);
264893bf6008Sagc 	}
2649fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
2650520c968fSagc 		fprintf(stderr, "parse_seckey: checkhash, reading MPIs\n");
2651520c968fSagc 	}
26522232f800Sagc 	switch (pkt.u.seckey.pubkey.alg) {
2653fc1f8641Sagc 	case PGP_PKA_RSA:
2654fc1f8641Sagc 	case PGP_PKA_RSA_ENCRYPT_ONLY:
2655fc1f8641Sagc 	case PGP_PKA_RSA_SIGN_ONLY:
265641335e2dSagc 		if (!limread_mpi(&pkt.u.seckey.key.rsa.d, region, stream) ||
265741335e2dSagc 		    !limread_mpi(&pkt.u.seckey.key.rsa.p, region, stream) ||
265841335e2dSagc 		    !limread_mpi(&pkt.u.seckey.key.rsa.q, region, stream) ||
265941335e2dSagc 		    !limread_mpi(&pkt.u.seckey.key.rsa.u, region, stream)) {
266093bf6008Sagc 			ret = 0;
2661bcfd8565Sagc 		}
266293bf6008Sagc 		break;
266393bf6008Sagc 
2664fc1f8641Sagc 	case PGP_PKA_DSA:
266541335e2dSagc 		if (!limread_mpi(&pkt.u.seckey.key.dsa.x, region, stream)) {
266693bf6008Sagc 			ret = 0;
2667bcfd8565Sagc 		}
266893bf6008Sagc 		break;
266993bf6008Sagc 
2670*0294a66bSjhigh 	case PGP_PKA_ECDSA:
2671*0294a66bSjhigh 		if (!limread_mpi(&pkt.u.seckey.key.ecdsa.x, region, stream)) {
2672*0294a66bSjhigh 			ret = 0;
2673*0294a66bSjhigh 		}
2674*0294a66bSjhigh 		break;
2675*0294a66bSjhigh 
2676fc1f8641Sagc 	case PGP_PKA_ELGAMAL:
2677520c968fSagc 		if (!limread_mpi(&pkt.u.seckey.key.elgamal.x, region, stream)) {
2678520c968fSagc 			ret = 0;
2679520c968fSagc 		}
2680520c968fSagc 		break;
2681520c968fSagc 
268293bf6008Sagc 	default:
2683fc1f8641Sagc 		PGP_ERROR_2(&stream->errors,
2684fc1f8641Sagc 			PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2685bcfd8565Sagc 			"Unsupported Public Key algorithm %d (%s)",
26862232f800Sagc 			pkt.u.seckey.pubkey.alg,
2687fc1f8641Sagc 			pgp_show_pka(pkt.u.seckey.pubkey.alg));
268893bf6008Sagc 		ret = 0;
268993bf6008Sagc 	}
269093bf6008Sagc 
2691fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
2692bcfd8565Sagc 		(void) fprintf(stderr, "4 MPIs read\n");
269393bf6008Sagc 	}
269441335e2dSagc 	stream->reading_v3_secret = 0;
269593bf6008Sagc 
2696fc1f8641Sagc 	if (pkt.u.seckey.s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
2697fc1f8641Sagc 		uint8_t   hash[PGP_CHECKHASH_SIZE];
269893bf6008Sagc 
2699fc1f8641Sagc 		pgp_reader_pop_hash(stream);
270093bf6008Sagc 		checkhash.finish(&checkhash, hash);
270193bf6008Sagc 
2702bcfd8565Sagc 		if (crypted &&
2703fc1f8641Sagc 		    pkt.u.seckey.pubkey.version != PGP_V4) {
2704fc1f8641Sagc 			pgp_reader_pop_decrypt(stream);
270593bf6008Sagc 			region = saved_region;
270693bf6008Sagc 		}
270793bf6008Sagc 		if (ret) {
27086715e11aSagc 			if (!limread(pkt.u.seckey.checkhash,
2709fc1f8641Sagc 				PGP_CHECKHASH_SIZE, region, stream)) {
271093bf6008Sagc 				return 0;
2711bcfd8565Sagc 			}
271293bf6008Sagc 
27136715e11aSagc 			if (memcmp(hash, pkt.u.seckey.checkhash,
2714fc1f8641Sagc 					PGP_CHECKHASH_SIZE) != 0) {
271541335e2dSagc 				ERRP(&stream->cbinfo, pkt,
2716bcfd8565Sagc 					"Hash mismatch in secret key");
2717bcfd8565Sagc 			}
271893bf6008Sagc 		}
271993bf6008Sagc 	} else {
2720b15ec256Sagc 		uint16_t  sum;
272193bf6008Sagc 
2722fc1f8641Sagc 		sum = pgp_reader_pop_sum16(stream);
2723bcfd8565Sagc 		if (crypted &&
2724fc1f8641Sagc 		    pkt.u.seckey.pubkey.version != PGP_V4) {
2725fc1f8641Sagc 			pgp_reader_pop_decrypt(stream);
272693bf6008Sagc 			region = saved_region;
272793bf6008Sagc 		}
272893bf6008Sagc 		if (ret) {
27296715e11aSagc 			if (!limread_scalar(&pkt.u.seckey.checksum, 2,
273041335e2dSagc 					region, stream))
273193bf6008Sagc 				return 0;
273293bf6008Sagc 
27332232f800Sagc 			if (sum != pkt.u.seckey.checksum) {
273441335e2dSagc 				ERRP(&stream->cbinfo, pkt,
27352232f800Sagc 					"Checksum mismatch in secret key");
27362232f800Sagc 			}
273793bf6008Sagc 		}
273893bf6008Sagc 	}
273993bf6008Sagc 
2740fc1f8641Sagc 	if (crypted && pkt.u.seckey.pubkey.version == PGP_V4) {
2741fc1f8641Sagc 		pgp_reader_pop_decrypt(stream);
274293bf6008Sagc 	}
274357036e70Sagc 	if (region == NULL) {
274457036e70Sagc 		(void) fprintf(stderr, "parse_seckey: NULL region\n");
274557036e70Sagc 		return 0;
274657036e70Sagc 	}
274757324b9fSagc 	if (ret && region->readc != region->length) {
27483326c4c5Sagc 		(void) fprintf(stderr, "parse_seckey: bad length\n");
2749ed0df671Sagc 		return 0;
2750ed0df671Sagc 	}
27512232f800Sagc 	if (!ret) {
275293bf6008Sagc 		return 0;
27532232f800Sagc 	}
2754fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
2755fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
27562232f800Sagc 		(void) fprintf(stderr, "--- end of parse_seckey\n\n");
275793bf6008Sagc 	}
275893bf6008Sagc 	return 1;
275993bf6008Sagc }
276093bf6008Sagc 
276193bf6008Sagc /**
276293bf6008Sagc    \ingroup Core_ReadPackets
276393bf6008Sagc    \brief Parse a Public Key Session Key packet
276493bf6008Sagc */
276593bf6008Sagc static int
parse_pk_sesskey(pgp_region_t * region,pgp_stream_t * stream)2766fc1f8641Sagc parse_pk_sesskey(pgp_region_t *region,
2767fc1f8641Sagc 		     pgp_stream_t *stream)
276893bf6008Sagc {
2769fc1f8641Sagc 	const pgp_seckey_t	*secret;
2770fc1f8641Sagc 	pgp_packet_t		 sesskey;
2771fc1f8641Sagc 	pgp_packet_t		 pkt;
2772b15ec256Sagc 	uint8_t			*iv;
2773b15ec256Sagc 	uint8_t		   	 c = 0x0;
2774b15ec256Sagc 	uint8_t			 cs[2];
2775bcfd8565Sagc 	unsigned		 k;
2776c2430ca2Sagc 	BIGNUM			*g_to_k;
2777bcfd8565Sagc 	BIGNUM			*enc_m;
2778bcfd8565Sagc 	int			 n;
2779b15ec256Sagc 	uint8_t		 	 unencoded_m_buf[1024];
278093bf6008Sagc 
278141335e2dSagc 	if (!limread(&c, 1, region, stream)) {
2782b0df0a22Sagc 		(void) fprintf(stderr, "parse_pk_sesskey - can't read char in region\n");
278393bf6008Sagc 		return 0;
278493bf6008Sagc 	}
2785d427c17dSagc 	pkt.u.pk_sesskey.version = c;
2786d427c17dSagc 	if (pkt.u.pk_sesskey.version != 3) {
2787fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_PROTO_BAD_PKSK_VRSN,
27882232f800Sagc 			"Bad public-key encrypted session key version (%d)",
27892232f800Sagc 			    pkt.u.pk_sesskey.version);
27902232f800Sagc 		return 0;
27912232f800Sagc 	}
27926715e11aSagc 	if (!limread(pkt.u.pk_sesskey.key_id,
27933f685a78Sagc 			  (unsigned)sizeof(pkt.u.pk_sesskey.key_id), region, stream)) {
279493bf6008Sagc 		return 0;
279593bf6008Sagc 	}
2796fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
279747561e26Sagc 		hexdump(stderr, "sesskey: pubkey id", pkt.u.pk_sesskey.key_id, sizeof(pkt.u.pk_sesskey.key_id));
279893bf6008Sagc 	}
279941335e2dSagc 	if (!limread(&c, 1, region, stream)) {
280093bf6008Sagc 		return 0;
28012232f800Sagc 	}
2802fc1f8641Sagc 	pkt.u.pk_sesskey.alg = (pgp_pubkey_alg_t)c;
28032232f800Sagc 	switch (pkt.u.pk_sesskey.alg) {
2804fc1f8641Sagc 	case PGP_PKA_RSA:
280541335e2dSagc 		if (!limread_mpi(&pkt.u.pk_sesskey.params.rsa.encrypted_m,
280641335e2dSagc 				      region, stream)) {
280793bf6008Sagc 			return 0;
280893bf6008Sagc 		}
280941335e2dSagc 		enc_m = pkt.u.pk_sesskey.params.rsa.encrypted_m;
2810c2430ca2Sagc 		g_to_k = NULL;
281193bf6008Sagc 		break;
281293bf6008Sagc 
2813fc1f8641Sagc 	case PGP_PKA_DSA:
2814fc1f8641Sagc 	case PGP_PKA_ELGAMAL:
281541335e2dSagc 		if (!limread_mpi(&pkt.u.pk_sesskey.params.elgamal.g_to_k,
281641335e2dSagc 				      region, stream) ||
28176715e11aSagc 		    !limread_mpi(
281841335e2dSagc 			&pkt.u.pk_sesskey.params.elgamal.encrypted_m,
281941335e2dSagc 					 region, stream)) {
282093bf6008Sagc 			return 0;
282193bf6008Sagc 		}
2822c2430ca2Sagc 		g_to_k = pkt.u.pk_sesskey.params.elgamal.g_to_k;
282341335e2dSagc 		enc_m = pkt.u.pk_sesskey.params.elgamal.encrypted_m;
282493bf6008Sagc 		break;
282593bf6008Sagc 
282693bf6008Sagc 	default:
2827fc1f8641Sagc 		PGP_ERROR_1(&stream->errors,
2828fc1f8641Sagc 			PGP_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
282993bf6008Sagc 			"Unknown public key algorithm in session key (%s)",
2830fc1f8641Sagc 			pgp_show_pka(pkt.u.pk_sesskey.alg));
283193bf6008Sagc 		return 0;
283293bf6008Sagc 	}
283393bf6008Sagc 
283493bf6008Sagc 	(void) memset(&sesskey, 0x0, sizeof(sesskey));
283593bf6008Sagc 	secret = NULL;
28363326c4c5Sagc 	sesskey.u.get_seckey.seckey = &secret;
28372232f800Sagc 	sesskey.u.get_seckey.pk_sesskey = &pkt.u.pk_sesskey;
283893bf6008Sagc 
2839b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
2840b0df0a22Sagc 		(void) fprintf(stderr, "getting secret key via callback\n");
2841b0df0a22Sagc 	}
2842b0df0a22Sagc 
2843fc1f8641Sagc 	CALLBACK(PGP_GET_SECKEY, &stream->cbinfo, &sesskey);
284493bf6008Sagc 
2845b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
2846b0df0a22Sagc 		(void) fprintf(stderr, "got secret key via callback\n");
2847b0df0a22Sagc 	}
284893bf6008Sagc 	if (!secret) {
2849fc1f8641Sagc 		CALLBACK(PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbinfo,
28502232f800Sagc 			&pkt);
285193bf6008Sagc 		return 1;
285293bf6008Sagc 	}
2853fc1f8641Sagc 	n = pgp_decrypt_decode_mpi(unencoded_m_buf,
2854c2430ca2Sagc 		(unsigned)sizeof(unencoded_m_buf), g_to_k, enc_m, secret);
2855c2430ca2Sagc 
285693bf6008Sagc 	if (n < 1) {
285741335e2dSagc 		ERRP(&stream->cbinfo, pkt, "decrypted message too short");
285893bf6008Sagc 		return 0;
285993bf6008Sagc 	}
28606715e11aSagc 
286193bf6008Sagc 	/* PKA */
2862fc1f8641Sagc 	pkt.u.pk_sesskey.symm_alg = (pgp_symm_alg_t)unencoded_m_buf[0];
2863b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
2864b0df0a22Sagc 		(void) fprintf(stderr, "symm alg %d\n", pkt.u.pk_sesskey.symm_alg);
2865b0df0a22Sagc 	}
286693bf6008Sagc 
2867fc1f8641Sagc 	if (!pgp_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) {
286893bf6008Sagc 		/* ERR1P */
2869fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_ALG_UNSUPPORTED_SYMMETRIC_ALG,
287093bf6008Sagc 			    "Symmetric algorithm %s not supported",
2871fc1f8641Sagc 			    pgp_show_symm_alg(
28722232f800Sagc 				pkt.u.pk_sesskey.symm_alg));
287393bf6008Sagc 		return 0;
287493bf6008Sagc 	}
2875fc1f8641Sagc 	k = pgp_key_size(pkt.u.pk_sesskey.symm_alg);
2876b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
2877b0df0a22Sagc 		(void) fprintf(stderr, "key size %d\n", k);
2878b0df0a22Sagc 	}
287993bf6008Sagc 
288093bf6008Sagc 	if ((unsigned) n != k + 3) {
2881fc1f8641Sagc 		PGP_ERROR_2(&stream->errors, PGP_E_PROTO_DECRYPTED_MSG_WRONG_LEN,
288293bf6008Sagc 		      "decrypted message wrong length (got %d expected %d)",
288393bf6008Sagc 			    n, k + 3);
288493bf6008Sagc 		return 0;
288593bf6008Sagc 	}
28862232f800Sagc 	if (k > sizeof(pkt.u.pk_sesskey.key)) {
28872232f800Sagc 		(void) fprintf(stderr, "parse_pk_sesskey: bad keylength\n");
2888ed0df671Sagc 		return 0;
2889ed0df671Sagc 	}
289093bf6008Sagc 
28912232f800Sagc 	(void) memcpy(pkt.u.pk_sesskey.key, unencoded_m_buf + 1, k);
289293bf6008Sagc 
2893fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
289447561e26Sagc 		hexdump(stderr, "recovered sesskey", pkt.u.pk_sesskey.key, k);
289593bf6008Sagc 	}
28962232f800Sagc 	pkt.u.pk_sesskey.checksum = unencoded_m_buf[k + 1] +
28972232f800Sagc 			(unencoded_m_buf[k + 2] << 8);
2898fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
2899b0df0a22Sagc 		(void) fprintf(stderr, "session key checksum: %2x %2x\n",
29002232f800Sagc 			unencoded_m_buf[k + 1], unencoded_m_buf[k + 2]);
290193bf6008Sagc 	}
290293bf6008Sagc 
290357324b9fSagc 	/* Check checksum */
2904fc1f8641Sagc 	pgp_calc_sesskey_checksum(&pkt.u.pk_sesskey, &cs[0]);
29052232f800Sagc 	if (unencoded_m_buf[k + 1] != cs[0] ||
29062232f800Sagc 	    unencoded_m_buf[k + 2] != cs[1]) {
2907fc1f8641Sagc 		PGP_ERROR_4(&stream->errors, PGP_E_PROTO_BAD_SK_CHECKSUM,
290893bf6008Sagc 		"Session key checksum wrong: expected %2x %2x, got %2x %2x",
29092232f800Sagc 		cs[0], cs[1], unencoded_m_buf[k + 1],
29102232f800Sagc 		unencoded_m_buf[k + 2]);
291193bf6008Sagc 		return 0;
291293bf6008Sagc 	}
2913b0df0a22Sagc 
2914b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
2915b0df0a22Sagc 		(void) fprintf(stderr, "getting pk session key via callback\n");
2916b0df0a22Sagc 	}
291793bf6008Sagc 	/* all is well */
2918fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_PK_SESSION_KEY, &stream->cbinfo, &pkt);
2919b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
2920b0df0a22Sagc 		(void) fprintf(stderr, "got pk session key via callback\n");
2921b0df0a22Sagc 	}
292293bf6008Sagc 
2923fc1f8641Sagc 	pgp_crypt_any(&stream->decrypt, pkt.u.pk_sesskey.symm_alg);
292441335e2dSagc 	iv = calloc(1, stream->decrypt.blocksize);
29250aa9bccaSagc 	if (iv == NULL) {
29260aa9bccaSagc 		(void) fprintf(stderr, "parse_pk_sesskey: bad alloc\n");
29270aa9bccaSagc 		return 0;
29280aa9bccaSagc 	}
292941335e2dSagc 	stream->decrypt.set_iv(&stream->decrypt, iv);
2930f72138f8Sagc 	stream->decrypt.set_crypt_key(&stream->decrypt, pkt.u.pk_sesskey.key);
2931fc1f8641Sagc 	pgp_encrypt_init(&stream->decrypt);
293257036e70Sagc 	free(iv);
293393bf6008Sagc 	return 1;
293493bf6008Sagc }
293593bf6008Sagc 
293693bf6008Sagc static int
decrypt_se_data(pgp_content_enum tag,pgp_region_t * region,pgp_stream_t * stream)2937e2c60ad1Sagc decrypt_se_data(pgp_content_enum tag, pgp_region_t *region,
2938fc1f8641Sagc 		    pgp_stream_t *stream)
293993bf6008Sagc {
2940fc1f8641Sagc 	pgp_crypt_t	*decrypt;
2941393ecd92Sagc 	const int	 printerrors = 1;
294257324b9fSagc 	int		 r = 1;
294393bf6008Sagc 
2944fc1f8641Sagc 	decrypt = pgp_get_decrypt(stream);
294593bf6008Sagc 	if (decrypt) {
2946fc1f8641Sagc 		pgp_region_t	encregion;
2947593d671cSagc 		unsigned	b = (unsigned)decrypt->blocksize;
2948fc1f8641Sagc 		uint8_t		buf[PGP_MAX_BLOCK_SIZE + 2] = "";
294993bf6008Sagc 
2950fc1f8641Sagc 		pgp_reader_push_decrypt(stream, decrypt, region);
295193bf6008Sagc 
2952fc1f8641Sagc 		pgp_init_subregion(&encregion, NULL);
295393bf6008Sagc 		encregion.length = b + 2;
295493bf6008Sagc 
295541335e2dSagc 		if (!exact_limread(buf, b + 2, &encregion, stream)) {
295693bf6008Sagc 			return 0;
29576715e11aSagc 		}
295893bf6008Sagc 		if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) {
2959fc1f8641Sagc 			pgp_reader_pop_decrypt(stream);
2960fc1f8641Sagc 			PGP_ERROR_4(&stream->errors,
2961fc1f8641Sagc 				PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT,
296293bf6008Sagc 				"Bad symmetric decrypt (%02x%02x vs %02x%02x)",
296393bf6008Sagc 				buf[b - 2], buf[b - 1], buf[b], buf[b + 1]);
296493bf6008Sagc 			return 0;
296593bf6008Sagc 		}
2966fc1f8641Sagc 		if (tag == PGP_PTAG_CT_SE_DATA_BODY) {
296793bf6008Sagc 			decrypt->decrypt_resync(decrypt);
29682232f800Sagc 			decrypt->block_encrypt(decrypt, decrypt->civ,
29692232f800Sagc 					decrypt->civ);
297093bf6008Sagc 		}
2971fc1f8641Sagc 		r = pgp_parse(stream, !printerrors);
297293bf6008Sagc 
2973fc1f8641Sagc 		pgp_reader_pop_decrypt(stream);
297493bf6008Sagc 	} else {
2975fc1f8641Sagc 		pgp_packet_t pkt;
297693bf6008Sagc 
297757324b9fSagc 		while (region->readc < region->length) {
29782232f800Sagc 			unsigned        len;
297993bf6008Sagc 
298057324b9fSagc 			len = region->length - region->readc;
2981bcfd8565Sagc 			if (len > sizeof(pkt.u.se_data_body.data))
2982bcfd8565Sagc 				len = sizeof(pkt.u.se_data_body.data);
298393bf6008Sagc 
29846715e11aSagc 			if (!limread(pkt.u.se_data_body.data, len,
298541335e2dSagc 					region, stream)) {
298693bf6008Sagc 				return 0;
29872232f800Sagc 			}
2988bcfd8565Sagc 			pkt.u.se_data_body.length = len;
298941335e2dSagc 			CALLBACK(tag, &stream->cbinfo, &pkt);
299093bf6008Sagc 		}
299193bf6008Sagc 	}
299293bf6008Sagc 
299393bf6008Sagc 	return r;
299493bf6008Sagc }
299593bf6008Sagc 
299693bf6008Sagc static int
decrypt_se_ip_data(pgp_content_enum tag,pgp_region_t * region,pgp_stream_t * stream)2997e2c60ad1Sagc decrypt_se_ip_data(pgp_content_enum tag, pgp_region_t *region,
2998fc1f8641Sagc 		       pgp_stream_t *stream)
299993bf6008Sagc {
3000fc1f8641Sagc 	pgp_crypt_t	*decrypt;
3001393ecd92Sagc 	const int	 printerrors = 1;
300257324b9fSagc 	int		 r = 1;
300393bf6008Sagc 
3004fc1f8641Sagc 	decrypt = pgp_get_decrypt(stream);
300593bf6008Sagc 	if (decrypt) {
3006b0df0a22Sagc 		if (pgp_get_debug_level(__FILE__)) {
3007e2c60ad1Sagc 			(void) fprintf(stderr, "decrypt_se_ip_data: decrypt\n");
3008b0df0a22Sagc 		}
3009fc1f8641Sagc 		pgp_reader_push_decrypt(stream, decrypt, region);
3010fc1f8641Sagc 		pgp_reader_push_se_ip_data(stream, decrypt, region);
301193bf6008Sagc 
3012fc1f8641Sagc 		r = pgp_parse(stream, !printerrors);
301393bf6008Sagc 
3014fc1f8641Sagc 		pgp_reader_pop_se_ip_data(stream);
3015fc1f8641Sagc 		pgp_reader_pop_decrypt(stream);
301693bf6008Sagc 	} else {
3017fc1f8641Sagc 		pgp_packet_t pkt;
301893bf6008Sagc 
3019b0df0a22Sagc 		if (pgp_get_debug_level(__FILE__)) {
3020e2c60ad1Sagc 			(void) fprintf(stderr, "decrypt_se_ip_data: no decrypt\n");
3021b0df0a22Sagc 		}
302257324b9fSagc 		while (region->readc < region->length) {
30232232f800Sagc 			unsigned        len;
302493bf6008Sagc 
302557324b9fSagc 			len = region->length - region->readc;
3026bcfd8565Sagc 			if (len > sizeof(pkt.u.se_data_body.data)) {
3027bcfd8565Sagc 				len = sizeof(pkt.u.se_data_body.data);
3028bcfd8565Sagc 			}
302993bf6008Sagc 
30306715e11aSagc 			if (!limread(pkt.u.se_data_body.data,
303141335e2dSagc 					len, region, stream)) {
303293bf6008Sagc 				return 0;
3033bcfd8565Sagc 			}
303493bf6008Sagc 
3035bcfd8565Sagc 			pkt.u.se_data_body.length = len;
303693bf6008Sagc 
303741335e2dSagc 			CALLBACK(tag, &stream->cbinfo, &pkt);
303893bf6008Sagc 		}
303993bf6008Sagc 	}
304093bf6008Sagc 
304193bf6008Sagc 	return r;
304293bf6008Sagc }
304393bf6008Sagc 
304457324b9fSagc /**
304557324b9fSagc    \ingroup Core_ReadPackets
304657324b9fSagc    \brief Read a Symmetrically Encrypted packet
304757324b9fSagc */
304857324b9fSagc static int
parse_se_data(pgp_region_t * region,pgp_stream_t * stream)3049fc1f8641Sagc parse_se_data(pgp_region_t *region, pgp_stream_t *stream)
305057324b9fSagc {
3051fc1f8641Sagc 	pgp_packet_t pkt;
305257324b9fSagc 
305357324b9fSagc 	/* there's no info to go with this, so just announce it */
3054fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_SE_DATA_HEADER, &stream->cbinfo, &pkt);
305557324b9fSagc 
305657324b9fSagc 	/*
305757324b9fSagc 	 * The content of an encrypted data packet is more OpenPGP packets
305857324b9fSagc 	 * once decrypted, so recursively handle them
305957324b9fSagc 	 */
3060e2c60ad1Sagc 	return decrypt_se_data(PGP_PTAG_CT_SE_DATA_BODY, region, stream);
306157324b9fSagc }
306257324b9fSagc 
306357324b9fSagc /**
306457324b9fSagc    \ingroup Core_ReadPackets
306557324b9fSagc    \brief Read a Symmetrically Encrypted Integrity Protected packet
306657324b9fSagc */
306757324b9fSagc static int
parse_se_ip_data(pgp_region_t * region,pgp_stream_t * stream)3068fc1f8641Sagc parse_se_ip_data(pgp_region_t *region, pgp_stream_t *stream)
306957324b9fSagc {
3070fc1f8641Sagc 	pgp_packet_t	pkt;
3071b15ec256Sagc 	uint8_t		c = 0x0;
307257324b9fSagc 
307341335e2dSagc 	if (!limread(&c, 1, region, stream)) {
307457324b9fSagc 		return 0;
307557324b9fSagc 	}
3076d427c17dSagc 	pkt.u.se_ip_data_header = c;
3077b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
3078b0df0a22Sagc 		(void) fprintf(stderr, "parse_se_ip_data: data header %d\n", c);
3079b0df0a22Sagc 	}
3080fc1f8641Sagc 	if (pkt.u.se_ip_data_header != PGP_SE_IP_DATA_VERSION) {
308157324b9fSagc 		(void) fprintf(stderr, "parse_se_ip_data: bad version\n");
308257324b9fSagc 		return 0;
308357324b9fSagc 	}
308457324b9fSagc 
3085b0df0a22Sagc 	if (pgp_get_debug_level(__FILE__)) {
3086b0df0a22Sagc 		(void) fprintf(stderr, "parse_se_ip_data: region %d,%d\n",
3087b0df0a22Sagc 			region->readc, region->length);
3088b0df0a22Sagc 		hexdump(stderr, "compressed region", stream->virtualpkt, stream->virtualc);
3089b0df0a22Sagc 	}
309057324b9fSagc 	/*
309157324b9fSagc 	 * The content of an encrypted data packet is more OpenPGP packets
309257324b9fSagc 	 * once decrypted, so recursively handle them
309357324b9fSagc 	 */
3094e2c60ad1Sagc 	return decrypt_se_ip_data(PGP_PTAG_CT_SE_IP_DATA_BODY, region, stream);
309557324b9fSagc }
309657324b9fSagc 
309757324b9fSagc /**
309857324b9fSagc    \ingroup Core_ReadPackets
309957324b9fSagc    \brief Read a MDC packet
310057324b9fSagc */
310157324b9fSagc static int
parse_mdc(pgp_region_t * region,pgp_stream_t * stream)3102fc1f8641Sagc parse_mdc(pgp_region_t *region, pgp_stream_t *stream)
310357324b9fSagc {
3104fc1f8641Sagc 	pgp_packet_t pkt;
310557324b9fSagc 
3106fc1f8641Sagc 	pkt.u.mdc.length = PGP_SHA1_HASH_SIZE;
3107fc1f8641Sagc 	if ((pkt.u.mdc.data = calloc(1, PGP_SHA1_HASH_SIZE)) == NULL) {
310857036e70Sagc 		(void) fprintf(stderr, "parse_mdc: bad alloc\n");
310957036e70Sagc 		return 0;
311057036e70Sagc 	}
3111fc1f8641Sagc 	if (!limread(pkt.u.mdc.data, PGP_SHA1_HASH_SIZE, region, stream)) {
311257324b9fSagc 		return 0;
311357324b9fSagc 	}
3114fc1f8641Sagc 	CALLBACK(PGP_PTAG_CT_MDC, &stream->cbinfo, &pkt);
311557036e70Sagc 	free(pkt.u.mdc.data);
311657324b9fSagc 	return 1;
311757324b9fSagc }
311857324b9fSagc 
311957324b9fSagc /**
312057324b9fSagc  * \ingroup Core_ReadPackets
312157324b9fSagc  * \brief Parse one packet.
312257324b9fSagc  *
312357324b9fSagc  * This function parses the packet tag.  It computes the value of the
312457324b9fSagc  * content tag and then calls the appropriate function to handle the
312557324b9fSagc  * content.
312657324b9fSagc  *
312741335e2dSagc  * \param *stream	How to parse
312857324b9fSagc  * \param *pktlen	On return, will contain number of bytes in packet
312957324b9fSagc  * \return 1 on success, 0 on error, -1 on EOF */
313057324b9fSagc static int
parse_packet(pgp_stream_t * stream,uint32_t * pktlen)3131e2c60ad1Sagc parse_packet(pgp_stream_t *stream, uint32_t *pktlen)
313257324b9fSagc {
3133fc1f8641Sagc 	pgp_packet_t		pkt;
3134fc1f8641Sagc 	pgp_region_t		region;
31353118701fSmlelstv 	pgp_content_enum	tag;
3136b15ec256Sagc 	uint8_t			ptag;
313757324b9fSagc 	unsigned		indeterminate = 0;
313857324b9fSagc 	int			ret;
313957324b9fSagc 
314041335e2dSagc 	pkt.u.ptag.position = stream->readinfo.position;
314157324b9fSagc 
314241335e2dSagc 	ret = base_read(&ptag, 1, stream);
314357324b9fSagc 
3144fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
314557324b9fSagc 		(void) fprintf(stderr,
3146e2c60ad1Sagc 			"parse_packet: base_read returned %d, ptag %d\n",
3147b0df0a22Sagc 			ret, ptag);
314857324b9fSagc 	}
314957324b9fSagc 
315057324b9fSagc 	/* errors in the base read are effectively EOF. */
315157324b9fSagc 	if (ret <= 0) {
315257324b9fSagc 		return -1;
315357324b9fSagc 	}
315457324b9fSagc 
315557324b9fSagc 	*pktlen = 0;
315657324b9fSagc 
3157fc1f8641Sagc 	if (!(ptag & PGP_PTAG_ALWAYS_SET)) {
3158d427c17dSagc 		pkt.u.error = "Format error (ptag bit not set)";
3159fc1f8641Sagc 		CALLBACK(PGP_PARSER_ERROR, &stream->cbinfo, &pkt);
316057324b9fSagc 		return 0;
316157324b9fSagc 	}
3162fc1f8641Sagc 	pkt.u.ptag.new_format = !!(ptag & PGP_PTAG_NEW_FORMAT);
316357324b9fSagc 	if (pkt.u.ptag.new_format) {
3164fc1f8641Sagc 		pkt.u.ptag.type = (ptag & PGP_PTAG_NF_CONTENT_TAG_MASK);
316557324b9fSagc 		pkt.u.ptag.length_type = 0;
316641335e2dSagc 		if (!read_new_length(&pkt.u.ptag.length, stream)) {
316757324b9fSagc 			return 0;
316857324b9fSagc 		}
316957324b9fSagc 	} else {
317057324b9fSagc 		unsigned   rb;
317157324b9fSagc 
317257324b9fSagc 		rb = 0;
317357324b9fSagc 		pkt.u.ptag.type = ((unsigned)ptag &
3174fc1f8641Sagc 				PGP_PTAG_OF_CONTENT_TAG_MASK)
3175fc1f8641Sagc 			>> PGP_PTAG_OF_CONTENT_TAG_SHIFT;
3176fc1f8641Sagc 		pkt.u.ptag.length_type = ptag & PGP_PTAG_OF_LENGTH_TYPE_MASK;
317757324b9fSagc 		switch (pkt.u.ptag.length_type) {
3178fc1f8641Sagc 		case PGP_PTAG_OLD_LEN_1:
317941335e2dSagc 			rb = _read_scalar(&pkt.u.ptag.length, 1, stream);
318057324b9fSagc 			break;
318157324b9fSagc 
3182fc1f8641Sagc 		case PGP_PTAG_OLD_LEN_2:
318341335e2dSagc 			rb = _read_scalar(&pkt.u.ptag.length, 2, stream);
318457324b9fSagc 			break;
318557324b9fSagc 
3186fc1f8641Sagc 		case PGP_PTAG_OLD_LEN_4:
318741335e2dSagc 			rb = _read_scalar(&pkt.u.ptag.length, 4, stream);
318857324b9fSagc 			break;
318957324b9fSagc 
3190fc1f8641Sagc 		case PGP_PTAG_OLD_LEN_INDETERMINATE:
319157324b9fSagc 			pkt.u.ptag.length = 0;
319257324b9fSagc 			indeterminate = 1;
319357324b9fSagc 			rb = 1;
319457324b9fSagc 			break;
319557324b9fSagc 		}
319657324b9fSagc 		if (!rb) {
319757324b9fSagc 			return 0;
319857324b9fSagc 		}
319957324b9fSagc 	}
320057324b9fSagc 
3201fc1f8641Sagc 	CALLBACK(PGP_PARSER_PTAG, &stream->cbinfo, &pkt);
320257324b9fSagc 
3203fc1f8641Sagc 	pgp_init_subregion(&region, NULL);
320457324b9fSagc 	region.length = pkt.u.ptag.length;
320557324b9fSagc 	region.indeterminate = indeterminate;
3206fc1f8641Sagc 	if (pgp_get_debug_level(__FILE__)) {
3207e2c60ad1Sagc 		(void) fprintf(stderr, "parse_packet: type %u\n",
320857324b9fSagc 			       pkt.u.ptag.type);
320957324b9fSagc 	}
32103118701fSmlelstv 
32113118701fSmlelstv 	/* save tag for accumulator */
32123118701fSmlelstv 	tag = pkt.u.ptag.type;
321357324b9fSagc 	switch (pkt.u.ptag.type) {
3214fc1f8641Sagc 	case PGP_PTAG_CT_SIGNATURE:
321541335e2dSagc 		ret = parse_sig(&region, stream);
321657324b9fSagc 		break;
321757324b9fSagc 
3218fc1f8641Sagc 	case PGP_PTAG_CT_PUBLIC_KEY:
3219fc1f8641Sagc 	case PGP_PTAG_CT_PUBLIC_SUBKEY:
3220fc1f8641Sagc 		ret = parse_pubkey((pgp_content_enum)pkt.u.ptag.type, &region, stream);
322157324b9fSagc 		break;
322257324b9fSagc 
3223fc1f8641Sagc 	case PGP_PTAG_CT_TRUST:
322441335e2dSagc 		ret = parse_trust(&region, stream);
322557324b9fSagc 		break;
322657324b9fSagc 
3227fc1f8641Sagc 	case PGP_PTAG_CT_USER_ID:
322841335e2dSagc 		ret = parse_userid(&region, stream);
322957324b9fSagc 		break;
323057324b9fSagc 
3231fc1f8641Sagc 	case PGP_PTAG_CT_COMPRESSED:
323241335e2dSagc 		ret = parse_compressed(&region, stream);
323357324b9fSagc 		break;
323457324b9fSagc 
3235fc1f8641Sagc 	case PGP_PTAG_CT_1_PASS_SIG:
323641335e2dSagc 		ret = parse_one_pass(&region, stream);
323757324b9fSagc 		break;
323857324b9fSagc 
3239fc1f8641Sagc 	case PGP_PTAG_CT_LITDATA:
324041335e2dSagc 		ret = parse_litdata(&region, stream);
324157324b9fSagc 		break;
324257324b9fSagc 
3243fc1f8641Sagc 	case PGP_PTAG_CT_USER_ATTR:
324441335e2dSagc 		ret = parse_userattr(&region, stream);
324557324b9fSagc 		break;
324657324b9fSagc 
3247fc1f8641Sagc 	case PGP_PTAG_CT_SECRET_KEY:
324841335e2dSagc 		ret = parse_seckey(&region, stream);
324957324b9fSagc 		break;
325057324b9fSagc 
3251fc1f8641Sagc 	case PGP_PTAG_CT_SECRET_SUBKEY:
325241335e2dSagc 		ret = parse_seckey(&region, stream);
325357324b9fSagc 		break;
325457324b9fSagc 
3255fc1f8641Sagc 	case PGP_PTAG_CT_PK_SESSION_KEY:
325641335e2dSagc 		ret = parse_pk_sesskey(&region, stream);
325757324b9fSagc 		break;
325857324b9fSagc 
3259fc1f8641Sagc 	case PGP_PTAG_CT_SE_DATA:
326041335e2dSagc 		ret = parse_se_data(&region, stream);
326157324b9fSagc 		break;
326257324b9fSagc 
3263fc1f8641Sagc 	case PGP_PTAG_CT_SE_IP_DATA:
326441335e2dSagc 		ret = parse_se_ip_data(&region, stream);
326557324b9fSagc 		break;
326657324b9fSagc 
3267fc1f8641Sagc 	case PGP_PTAG_CT_MDC:
326841335e2dSagc 		ret = parse_mdc(&region, stream);
326957324b9fSagc 		break;
327057324b9fSagc 
327157324b9fSagc 	default:
3272fc1f8641Sagc 		PGP_ERROR_1(&stream->errors, PGP_E_P_UNKNOWN_TAG,
327357324b9fSagc 			    "Unknown content tag 0x%x",
327457324b9fSagc 			    pkt.u.ptag.type);
327557324b9fSagc 		ret = 0;
327657324b9fSagc 	}
327757324b9fSagc 
327857324b9fSagc 	/* Ensure that the entire packet has been consumed */
327957324b9fSagc 
328057324b9fSagc 	if (region.length != region.readc && !region.indeterminate) {
328141335e2dSagc 		if (!consume_packet(&region, stream, 0)) {
328293bf6008Sagc 			ret = -1;
3283bcfd8565Sagc 		}
3284bcfd8565Sagc 	}
328593bf6008Sagc 
328693bf6008Sagc 	/* also consume it if there's been an error? */
328793bf6008Sagc 	/* \todo decide what to do about an error on an */
328893bf6008Sagc 	/* indeterminate packet */
328993bf6008Sagc 	if (ret == 0) {
329041335e2dSagc 		if (!consume_packet(&region, stream, 0)) {
329193bf6008Sagc 			ret = -1;
329293bf6008Sagc 		}
3293bcfd8565Sagc 	}
329493bf6008Sagc 	/* set pktlen */
329593bf6008Sagc 
329641335e2dSagc 	*pktlen = stream->readinfo.alength;
329793bf6008Sagc 
329893bf6008Sagc 	/* do callback on entire packet, if desired and there was no error */
329993bf6008Sagc 
330041335e2dSagc 	if (ret > 0 && stream->readinfo.accumulate) {
330141335e2dSagc 		pkt.u.packet.length = stream->readinfo.alength;
330241335e2dSagc 		pkt.u.packet.raw = stream->readinfo.accumulated;
33033118701fSmlelstv 		pkt.u.packet.tag = tag;
330441335e2dSagc 		stream->readinfo.accumulated = NULL;
330541335e2dSagc 		stream->readinfo.asize = 0;
3306fc1f8641Sagc 		CALLBACK(PGP_PARSER_PACKET_END, &stream->cbinfo, &pkt);
330793bf6008Sagc 	}
330841335e2dSagc 	stream->readinfo.alength = 0;
330993bf6008Sagc 
3310bcfd8565Sagc 	return (ret < 0) ? -1 : (ret) ? 1 : 0;
331193bf6008Sagc }
331293bf6008Sagc 
331393bf6008Sagc /**
331493bf6008Sagc  * \ingroup Core_ReadPackets
331593bf6008Sagc  *
331693bf6008Sagc  * \brief Parse packets from an input stream until EOF or error.
331793bf6008Sagc  *
331841335e2dSagc  * \details Setup the necessary parsing configuration in "stream"
3319fc1f8641Sagc  * before calling pgp_parse().
332093bf6008Sagc  *
332193bf6008Sagc  * That information includes :
332293bf6008Sagc  *
332393bf6008Sagc  * - a "reader" function to be used to get the data to be parsed
332493bf6008Sagc  *
332593bf6008Sagc  * - a "callback" function to be called when this library has identified
332693bf6008Sagc  * a parseable object within the data
332793bf6008Sagc  *
3328bcfd8565Sagc  * - whether the calling function wants the signature subpackets
3329bcfd8565Sagc  * returned raw, parsed or not at all.
333093bf6008Sagc  *
333141335e2dSagc  * After returning, stream->errors holds any errors encountered while parsing.
333293bf6008Sagc  *
333341335e2dSagc  * \param stream	Parsing configuration
333493bf6008Sagc  * \return		1 on success in all packets, 0 on error in any packet
333593bf6008Sagc  *
333693bf6008Sagc  * \sa CoreAPI Overview
333793bf6008Sagc  *
3338fc1f8641Sagc  * \sa pgp_print_errors()
333993bf6008Sagc  *
334093bf6008Sagc  */
334193bf6008Sagc 
334293bf6008Sagc int
pgp_parse(pgp_stream_t * stream,const int perrors)3343fc1f8641Sagc pgp_parse(pgp_stream_t *stream, const int perrors)
334493bf6008Sagc {
3345b15ec256Sagc 	uint32_t   pktlen;
3346bcfd8565Sagc 	int             r;
334793bf6008Sagc 
334893bf6008Sagc 	do {
3349e2c60ad1Sagc 		r = parse_packet(stream, &pktlen);
335093bf6008Sagc 	} while (r != -1);
3351bcfd8565Sagc 	if (perrors) {
3352fc1f8641Sagc 		pgp_print_errors(stream->errors);
3353bcfd8565Sagc 	}
335441335e2dSagc 	return (stream->errors == NULL);
335593bf6008Sagc }
335693bf6008Sagc 
335793bf6008Sagc /**
335893bf6008Sagc  * \ingroup Core_ReadPackets
335993bf6008Sagc  *
336093bf6008Sagc  * \brief Specifies whether one or more signature
336193bf6008Sagc  * subpacket types should be returned parsed; or raw; or ignored.
336293bf6008Sagc  *
336341335e2dSagc  * \param	stream	Pointer to previously allocated structure
3364fc1f8641Sagc  * \param	tag	Packet tag. PGP_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag
336593bf6008Sagc  * \param	type	Parse type
336693bf6008Sagc  * \todo Make all packet types optional, not just subpackets */
336793bf6008Sagc void
pgp_parse_options(pgp_stream_t * stream,pgp_content_enum tag,pgp_parse_type_t type)3368fc1f8641Sagc pgp_parse_options(pgp_stream_t *stream,
3369fc1f8641Sagc 		  pgp_content_enum tag,
3370fc1f8641Sagc 		  pgp_parse_type_t type)
337193bf6008Sagc {
337257036e70Sagc 	unsigned	t7;
337357036e70Sagc 	unsigned	t8;
337493bf6008Sagc 
3375fc1f8641Sagc 	if (tag == PGP_PTAG_SS_ALL) {
337693bf6008Sagc 		int             n;
337793bf6008Sagc 
33782232f800Sagc 		for (n = 0; n < 256; ++n) {
3379fc1f8641Sagc 			pgp_parse_options(stream,
3380fc1f8641Sagc 				PGP_PTAG_SIG_SUBPKT_BASE + n,
338193bf6008Sagc 				type);
33822232f800Sagc 		}
338393bf6008Sagc 		return;
338493bf6008Sagc 	}
3385fc1f8641Sagc 	if (tag < PGP_PTAG_SIG_SUBPKT_BASE ||
3386fc1f8641Sagc 	    tag > PGP_PTAG_SIG_SUBPKT_BASE + NTAGS - 1) {
3387fc1f8641Sagc 		(void) fprintf(stderr, "pgp_parse_options: bad tag\n");
3388ed0df671Sagc 		return;
3389ed0df671Sagc 	}
3390fc1f8641Sagc 	t8 = (tag - PGP_PTAG_SIG_SUBPKT_BASE) / 8;
3391fc1f8641Sagc 	t7 = 1 << ((tag - PGP_PTAG_SIG_SUBPKT_BASE) & 7);
339293bf6008Sagc 	switch (type) {
3393fc1f8641Sagc 	case PGP_PARSE_RAW:
339441335e2dSagc 		stream->ss_raw[t8] |= t7;
339541335e2dSagc 		stream->ss_parsed[t8] &= ~t7;
339693bf6008Sagc 		break;
339793bf6008Sagc 
3398fc1f8641Sagc 	case PGP_PARSE_PARSED:
339941335e2dSagc 		stream->ss_raw[t8] &= ~t7;
340041335e2dSagc 		stream->ss_parsed[t8] |= t7;
340193bf6008Sagc 		break;
340293bf6008Sagc 
3403fc1f8641Sagc 	case PGP_PARSE_IGNORE:
340441335e2dSagc 		stream->ss_raw[t8] &= ~t7;
340541335e2dSagc 		stream->ss_parsed[t8] &= ~t7;
340693bf6008Sagc 		break;
340793bf6008Sagc 	}
340893bf6008Sagc }
340993bf6008Sagc 
341093bf6008Sagc /**
341193bf6008Sagc \ingroup Core_ReadPackets
3412fc1f8641Sagc \brief Free pgp_stream_t struct and its contents
341393bf6008Sagc */
341493bf6008Sagc void
pgp_stream_delete(pgp_stream_t * stream)3415fc1f8641Sagc pgp_stream_delete(pgp_stream_t *stream)
341693bf6008Sagc {
3417fc1f8641Sagc 	pgp_cbdata_t	*cbinfo;
3418fc1f8641Sagc 	pgp_cbdata_t	*next;
341993bf6008Sagc 
342041335e2dSagc 	for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
342193bf6008Sagc 		next = cbinfo->next;
342257036e70Sagc 		free(cbinfo);
342393bf6008Sagc 	}
342441335e2dSagc 	if (stream->readinfo.destroyer) {
342541335e2dSagc 		stream->readinfo.destroyer(&stream->readinfo);
34262232f800Sagc 	}
3427fc1f8641Sagc 	pgp_free_errors(stream->errors);
342841335e2dSagc 	if (stream->readinfo.accumulated) {
342957036e70Sagc 		free(stream->readinfo.accumulated);
34302232f800Sagc 	}
343157036e70Sagc 	free(stream);
343293bf6008Sagc }
343393bf6008Sagc 
343493bf6008Sagc /**
343593bf6008Sagc \ingroup Core_ReadPackets
343693bf6008Sagc \brief Returns the parse_info's reader_info
343793bf6008Sagc \return Pointer to the reader_info inside the parse_info
343893bf6008Sagc */
3439fc1f8641Sagc pgp_reader_t *
pgp_readinfo(pgp_stream_t * stream)3440fc1f8641Sagc pgp_readinfo(pgp_stream_t *stream)
344193bf6008Sagc {
344241335e2dSagc 	return &stream->readinfo;
344393bf6008Sagc }
344493bf6008Sagc 
344593bf6008Sagc /**
344693bf6008Sagc \ingroup Core_ReadPackets
344793bf6008Sagc \brief Sets the parse_info's callback
344893bf6008Sagc This is used when adding the first callback in a stack of callbacks.
3449fc1f8641Sagc \sa pgp_callback_push()
345093bf6008Sagc */
345193bf6008Sagc 
345293bf6008Sagc void
pgp_set_callback(pgp_stream_t * stream,pgp_cbfunc_t * cb,void * arg)3453fc1f8641Sagc pgp_set_callback(pgp_stream_t *stream, pgp_cbfunc_t *cb, void *arg)
345493bf6008Sagc {
345541335e2dSagc 	stream->cbinfo.cbfunc = cb;
345641335e2dSagc 	stream->cbinfo.arg = arg;
345741335e2dSagc 	stream->cbinfo.errors = &stream->errors;
345893bf6008Sagc }
345993bf6008Sagc 
346093bf6008Sagc /**
346193bf6008Sagc \ingroup Core_ReadPackets
346293bf6008Sagc \brief Adds a further callback to a stack of callbacks
3463fc1f8641Sagc \sa pgp_set_callback()
346493bf6008Sagc */
346593bf6008Sagc void
pgp_callback_push(pgp_stream_t * stream,pgp_cbfunc_t * cb,void * arg)3466fc1f8641Sagc pgp_callback_push(pgp_stream_t *stream, pgp_cbfunc_t *cb, void *arg)
346793bf6008Sagc {
3468fc1f8641Sagc 	pgp_cbdata_t	*cbinfo;
346993bf6008Sagc 
34700aa9bccaSagc 	if ((cbinfo = calloc(1, sizeof(*cbinfo))) == NULL) {
3471fc1f8641Sagc 		(void) fprintf(stderr, "pgp_callback_push: bad alloc\n");
34720aa9bccaSagc 		return;
34730aa9bccaSagc 	}
347441335e2dSagc 	(void) memcpy(cbinfo, &stream->cbinfo, sizeof(*cbinfo));
347541335e2dSagc 	cbinfo->io = stream->io;
347641335e2dSagc 	stream->cbinfo.next = cbinfo;
3477fc1f8641Sagc 	pgp_set_callback(stream, cb, arg);
347893bf6008Sagc }
347993bf6008Sagc 
348093bf6008Sagc /**
348193bf6008Sagc \ingroup Core_ReadPackets
348293bf6008Sagc \brief Returns callback's arg
348393bf6008Sagc */
348493bf6008Sagc void *
pgp_callback_arg(pgp_cbdata_t * cbinfo)3485fc1f8641Sagc pgp_callback_arg(pgp_cbdata_t *cbinfo)
348693bf6008Sagc {
348793bf6008Sagc 	return cbinfo->arg;
348893bf6008Sagc }
348993bf6008Sagc 
349093bf6008Sagc /**
349193bf6008Sagc \ingroup Core_ReadPackets
349293bf6008Sagc \brief Returns callback's errors
349393bf6008Sagc */
349493bf6008Sagc void *
pgp_callback_errors(pgp_cbdata_t * cbinfo)3495fc1f8641Sagc pgp_callback_errors(pgp_cbdata_t *cbinfo)
349693bf6008Sagc {
349793bf6008Sagc 	return cbinfo->errors;
349893bf6008Sagc }
349993bf6008Sagc 
350093bf6008Sagc /**
350193bf6008Sagc \ingroup Core_ReadPackets
350293bf6008Sagc \brief Calls the parse_cb_info's callback if present
3503fc1f8641Sagc \return Return value from callback, if present; else PGP_FINISHED
350493bf6008Sagc */
3505fc1f8641Sagc pgp_cb_ret_t
pgp_callback(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)3506fc1f8641Sagc pgp_callback(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
350793bf6008Sagc {
3508fc1f8641Sagc 	return (cbinfo->cbfunc) ? cbinfo->cbfunc(pkt, cbinfo) : PGP_FINISHED;
350993bf6008Sagc }
351093bf6008Sagc 
351193bf6008Sagc /**
351293bf6008Sagc \ingroup Core_ReadPackets
351393bf6008Sagc \brief Calls the next callback  in the stack
351493bf6008Sagc \return Return value from callback
351593bf6008Sagc */
3516fc1f8641Sagc pgp_cb_ret_t
pgp_stacked_callback(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)3517fc1f8641Sagc pgp_stacked_callback(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
351893bf6008Sagc {
3519fc1f8641Sagc 	return pgp_callback(pkt, cbinfo->next);
352093bf6008Sagc }
352193bf6008Sagc 
352293bf6008Sagc /**
352393bf6008Sagc \ingroup Core_ReadPackets
352493bf6008Sagc \brief Returns the parse_info's errors
352593bf6008Sagc \return parse_info's errors
352693bf6008Sagc */
3527fc1f8641Sagc pgp_error_t    *
pgp_stream_get_errors(pgp_stream_t * stream)3528fc1f8641Sagc pgp_stream_get_errors(pgp_stream_t *stream)
352993bf6008Sagc {
353041335e2dSagc 	return stream->errors;
353193bf6008Sagc }
353293bf6008Sagc 
3533fc1f8641Sagc pgp_crypt_t    *
pgp_get_decrypt(pgp_stream_t * stream)3534fc1f8641Sagc pgp_get_decrypt(pgp_stream_t *stream)
353593bf6008Sagc {
353641335e2dSagc 	return (stream->decrypt.alg) ? &stream->decrypt : NULL;
353793bf6008Sagc }
3538