xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/packet-parse.c (revision da9817918ec7e88db2912a2882967c7570a83f47)
1 /*-
2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Alistair Crooks (agc@NetBSD.org)
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*
30  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31  * All rights reserved.
32  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33  * their moral rights under the UK Copyright Design and Patents Act 1988 to
34  * be recorded as the authors of this copyright work.
35  *
36  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37  * use this file except in compliance with the License.
38  *
39  * You may obtain a copy of the License at
40  *     http://www.apache.org/licenses/LICENSE-2.0
41  *
42  * Unless required by applicable law or agreed to in writing, software
43  * distributed under the License is distributed on an "AS IS" BASIS,
44  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45  *
46  * See the License for the specific language governing permissions and
47  * limitations under the License.
48  */
49 
50 /** \file
51  * \brief Parser for OpenPGP packets
52  */
53 #include "config.h"
54 
55 #ifdef HAVE_SYS_CDEFS_H
56 #include <sys/cdefs.h>
57 #endif
58 
59 #if defined(__NetBSD__)
60 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
61 __RCSID("$NetBSD: packet-parse.c,v 1.22 2009/06/13 05:25:08 agc Exp $");
62 #endif
63 
64 #ifdef HAVE_OPENSSL_CAST_H
65 #include <openssl/cast.h>
66 #endif
67 
68 #include <stdarg.h>
69 #include <stdlib.h>
70 #include <string.h>
71 
72 #ifdef HAVE_UNISTD_H
73 #include <unistd.h>
74 #endif
75 
76 #include <errno.h>
77 
78 #ifdef HAVE_LIMITS_H
79 #include <limits.h>
80 #endif
81 
82 #include "packet.h"
83 #include "packet-parse.h"
84 #include "keyring.h"
85 #include "errors.h"
86 #include "packet-show.h"
87 #include "create.h"
88 #include "readerwriter.h"
89 #include "netpgpdefs.h"
90 #include "crypto.h"
91 #include "netpgpdigest.h"
92 
93 #define ERRP(cbinfo, cont, err)	do {					\
94 	cont.u.error.error = err;					\
95 	CALLBACK(OPS_PARSER_ERROR, cbinfo, &cont);			\
96 	return 0;							\
97 	/*NOTREACHED*/							\
98 } while(/*CONSTCOND*/0)
99 
100 /**
101  * limread_data reads the specified amount of the subregion's data
102  * into a data_t structure
103  *
104  * \param data	Empty structure which will be filled with data
105  * \param len	Number of octets to read
106  * \param subregion
107  * \param stream	How to parse
108  *
109  * \return 1 on success, 0 on failure
110  */
111 static int
112 limread_data(__ops_data_t *data, unsigned int len,
113 		  __ops_region_t *subregion, __ops_stream_t *stream)
114 {
115 	data->len = len;
116 
117 	if (subregion->length - subregion->readc < len) {
118 		(void) fprintf(stderr, "limread_data: bad length\n");
119 		return 0;
120 	}
121 
122 	data->contents = calloc(1, data->len);
123 	if (!data->contents) {
124 		return 0;
125 	}
126 
127 	return __ops_limited_read(data->contents, data->len, subregion,
128 			&stream->errors, &stream->readinfo, &stream->cbinfo);
129 }
130 
131 /**
132  * read_data reads the remainder of the subregion's data
133  * into a data_t structure
134  *
135  * \param data
136  * \param subregion
137  * \param stream
138  *
139  * \return 1 on success, 0 on failure
140  */
141 static int
142 read_data(__ops_data_t *data, __ops_region_t *region, __ops_stream_t *stream)
143 {
144 	int	cc;
145 
146 	cc = region->length - region->readc;
147 	return (cc >= 0) ? limread_data(data, (unsigned)cc, region, stream) : 0;
148 }
149 
150 /**
151  * Reads the remainder of the subregion as a string.
152  * It is the user's responsibility to free the memory allocated here.
153  */
154 
155 static int
156 read_unsig_str(unsigned char **str, __ops_region_t *subregion,
157 		     __ops_stream_t *stream)
158 {
159 	size_t	len = 0;
160 
161 	len = subregion->length - subregion->readc;
162 	if ((*str = calloc(1, len + 1)) == NULL) {
163 		return 0;
164 	}
165 	if (len &&
166 	    !__ops_limited_read(*str, len, subregion, &stream->errors,
167 				     &stream->readinfo, &stream->cbinfo)) {
168 		return 0;
169 	}
170 	(*str)[len] = '\0';
171 	return 1;
172 }
173 
174 static int
175 read_string(char **str, __ops_region_t *subregion, __ops_stream_t *stream)
176 {
177 	return read_unsig_str((unsigned char **) str, subregion, stream);
178 }
179 
180 void
181 __ops_init_subregion(__ops_region_t *subregion, __ops_region_t *region)
182 {
183 	(void) memset(subregion, 0x0, sizeof(*subregion));
184 	subregion->parent = region;
185 }
186 
187 /*
188  * XXX: replace __ops_ptag_t with something more appropriate for limiting reads
189  */
190 
191 /**
192  * low-level function to read data from reader function
193  *
194  * Use this function, rather than calling the reader directly.
195  *
196  * If the accumulate flag is set in *stream, the function
197  * adds the read data to the accumulated data, and updates
198  * the accumulated length. This is useful if, for example,
199  * the application wants access to the raw data as well as the
200  * parsed data.
201  *
202  * This function will also try to read the entire amount asked for, but not
203  * if it is over INT_MAX. Obviously many callers will know that they
204  * never ask for that much and so can avoid the extra complexity of
205  * dealing with return codes and filled-in lengths.
206  *
207  * \param *dest
208  * \param *plength
209  * \param flags
210  * \param *stream
211  *
212  * \return OPS_R_OK
213  * \return OPS_R_PARTIAL_READ
214  * \return OPS_R_EOF
215  * \return OPS_R_EARLY_EOF
216  *
217  * \sa #__ops_reader_ret_t for details of return codes
218  */
219 
220 static int
221 sub_base_read(void *dest, size_t length, __ops_error_t **errors,
222 	      __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo)
223 {
224 	size_t          n;
225 
226 	/* reading more than this would look like an error */
227 	if (length > INT_MAX)
228 		length = INT_MAX;
229 
230 	for (n = 0; n < length;) {
231 		int	r;
232 
233 		r = readinfo->reader((char *) dest + n, length - n, errors,
234 				readinfo, cbinfo);
235 		if (r > (int)(length - n)) {
236 			(void) fprintf(stderr, "sub_base_read: bad read\n");
237 			return 0;
238 		}
239 		if (r < 0) {
240 			return r;
241 		}
242 		if (r == 0) {
243 			break;
244 		}
245 		n += r;
246 	}
247 
248 	if (n == 0) {
249 		return 0;
250 	}
251 	if (readinfo->accumulate) {
252 		if (readinfo->asize < readinfo->alength) {
253 			(void) fprintf(stderr, "sub_base_read: bad size\n");
254 			return 0;
255 		}
256 		if (readinfo->alength + n > readinfo->asize) {
257 			readinfo->asize = readinfo->asize * 2 + n;
258 			readinfo->accumulated = realloc(readinfo->accumulated,
259 							readinfo->asize);
260 		}
261 		if (readinfo->asize < readinfo->alength + n) {
262 			(void) fprintf(stderr, "sub_base_read: bad realloc\n");
263 			return 0;
264 		}
265 		(void) memcpy(readinfo->accumulated + readinfo->alength, dest,
266 				n);
267 	}
268 	/* we track length anyway, because it is used for packet offsets */
269 	readinfo->alength += n;
270 	/* and also the position */
271 	readinfo->position += n;
272 
273 	return n;
274 }
275 
276 int
277 __ops_stacked_read(void *dest, size_t length, __ops_error_t **errors,
278 		 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo)
279 {
280 	return sub_base_read(dest, length, errors, readinfo->next, cbinfo);
281 }
282 
283 /* This will do a full read so long as length < MAX_INT */
284 static int
285 base_read(unsigned char *dest, size_t length,
286 	  __ops_stream_t *stream)
287 {
288 	return sub_base_read(dest, length, &stream->errors, &stream->readinfo,
289 			     &stream->cbinfo);
290 }
291 
292 /*
293  * Read a full size_t's worth. If the return is < than length, then
294  * *last_read tells you why - < 0 for an error, == 0 for EOF
295  */
296 
297 static size_t
298 full_read(unsigned char *dest,
299 		size_t length,
300 		int *last_read,
301 		__ops_error_t **errors,
302 		__ops_reader_t *readinfo,
303 		__ops_cbdata_t *cbinfo)
304 {
305 	size_t          t;
306 	int             r = 0;	/* preset in case some loon calls with length
307 				 * == 0 */
308 
309 	for (t = 0; t < length;) {
310 		r = sub_base_read(dest + t, length - t, errors, readinfo,
311 				cbinfo);
312 		if (r <= 0) {
313 			*last_read = r;
314 			return t;
315 		}
316 		t += r;
317 	}
318 
319 	*last_read = r;
320 
321 	return t;
322 }
323 
324 
325 
326 /** Read a scalar value of selected length from reader.
327  *
328  * Read an unsigned scalar value from reader in Big Endian representation.
329  *
330  * This function does not know or care about packet boundaries. It
331  * also assumes that an EOF is an error.
332  *
333  * \param *result	The scalar value is stored here
334  * \param *reader	Our reader
335  * \param length	How many bytes to read
336  * \return		1 on success, 0 on failure
337  */
338 static unsigned
339 _read_scalar(unsigned *result, unsigned length,
340 	     __ops_stream_t *stream)
341 {
342 	unsigned        t = 0;
343 
344 	if (length > sizeof(*result)) {
345 		(void) fprintf(stderr, "_read_scalar: bad length\n");
346 		return 0;
347 	}
348 
349 	while (length--) {
350 		unsigned char   c;
351 		int             r;
352 
353 		r = base_read(&c, 1, stream);
354 		if (r != 1)
355 			return 0;
356 		t = (t << 8) + c;
357 	}
358 
359 	*result = t;
360 	return 1;
361 }
362 
363 /**
364  * \ingroup Core_ReadPackets
365  * \brief Read bytes from a region within the packet.
366  *
367  * Read length bytes into the buffer pointed to by *dest.
368  * Make sure we do not read over the packet boundary.
369  * Updates the Packet Tag's __ops_ptag_t::readc.
370  *
371  * If length would make us read over the packet boundary, or if
372  * reading fails, we call the callback with an error.
373  *
374  * Note that if the region is indeterminate, this can return a short
375  * read - check region->last_read for the length. EOF is indicated by
376  * a success return and region->last_read == 0 in this case (for a
377  * region of known length, EOF is an error).
378  *
379  * This function makes sure to respect packet boundaries.
380  *
381  * \param dest		The destination buffer
382  * \param length	How many bytes to read
383  * \param region	Pointer to packet region
384  * \param errors    Error stack
385  * \param readinfo		Reader info
386  * \param cbinfo	Callback info
387  * \return		1 on success, 0 on error
388  */
389 unsigned
390 __ops_limited_read(unsigned char *dest,
391 			size_t length,
392 			__ops_region_t *region,
393 			__ops_error_t **errors,
394 			__ops_reader_t *readinfo,
395 			__ops_cbdata_t *cbinfo)
396 {
397 	size_t	r;
398 	int	lr;
399 
400 	if (!region->indeterminate &&
401 	    region->readc + length > region->length) {
402 		OPS_ERROR(errors, OPS_E_P_NOT_ENOUGH_DATA, "Not enough data");
403 		return 0;
404 	}
405 	r = full_read(dest, length, &lr, errors, readinfo, cbinfo);
406 	if (lr < 0) {
407 		OPS_ERROR(errors, OPS_E_R_READ_FAILED, "Read failed");
408 		return 0;
409 	}
410 	if (!region->indeterminate && r != length) {
411 		OPS_ERROR(errors, OPS_E_R_READ_FAILED, "Read failed");
412 		return 0;
413 	}
414 	region->last_read = r;
415 	do {
416 		region->readc += r;
417 		if (region->parent && region->length > region->parent->length) {
418 			(void) fprintf(stderr,
419 				"ops_limited_read: bad length\n");
420 			return 0;
421 		}
422 	} while ((region = region->parent) != NULL);
423 	return 1;
424 }
425 
426 /**
427    \ingroup Core_ReadPackets
428    \brief Call __ops_limited_read on next in stack
429 */
430 unsigned
431 __ops_stacked_limited_read(unsigned char *dest, unsigned length,
432 			 __ops_region_t *region,
433 			 __ops_error_t **errors,
434 			 __ops_reader_t *readinfo,
435 			 __ops_cbdata_t *cbinfo)
436 {
437 	return __ops_limited_read(dest, length, region, errors,
438 				readinfo->next, cbinfo);
439 }
440 
441 static unsigned
442 limread(unsigned char *dest, unsigned length,
443 	     __ops_region_t *region, __ops_stream_t *info)
444 {
445 	return __ops_limited_read(dest, length, region, &info->errors,
446 				&info->readinfo, &info->cbinfo);
447 }
448 
449 static unsigned
450 exact_limread(unsigned char *dest, unsigned len,
451 		   __ops_region_t *region,
452 		   __ops_stream_t *stream)
453 {
454 	unsigned   ret;
455 
456 	stream->exact_read = 1;
457 	ret = limread(dest, len, region, stream);
458 	stream->exact_read = 0;
459 	return ret;
460 }
461 
462 /** Skip over length bytes of this packet.
463  *
464  * Calls limread() to skip over some data.
465  *
466  * This function makes sure to respect packet boundaries.
467  *
468  * \param length	How many bytes to skip
469  * \param *region	Pointer to packet region
470  * \param *stream	How to parse
471  * \return		1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
472  */
473 static int
474 limskip(unsigned length, __ops_region_t *region, __ops_stream_t *stream)
475 {
476 	unsigned char   buf[NETPGP_BUFSIZ];
477 
478 	while (length > 0) {
479 		unsigned	n = length % NETPGP_BUFSIZ;
480 
481 		if (!limread(buf, n, region, stream)) {
482 			return 0;
483 		}
484 		length -= n;
485 	}
486 	return 1;
487 }
488 
489 /** Read a scalar.
490  *
491  * Read a big-endian scalar of length bytes, respecting packet
492  * boundaries (by calling limread() to read the raw data).
493  *
494  * This function makes sure to respect packet boundaries.
495  *
496  * \param *dest		The scalar value is stored here
497  * \param length	How many bytes make up this scalar (at most 4)
498  * \param *region	Pointer to current packet region
499  * \param *stream	How to parse
500  * \param *cb		The callback
501  * \return		1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
502  *
503  * \see RFC4880 3.1
504  */
505 static int
506 limread_scalar(unsigned *dest,
507 			unsigned len,
508 			__ops_region_t *region,
509 			__ops_stream_t *stream)
510 {
511 	unsigned char   c[4] = "";
512 	unsigned        t;
513 	unsigned        n;
514 
515 	if (len > 4) {
516 		(void) fprintf(stderr, "limread_scalar: bad length\n");
517 		return 0;
518 	}
519 	/*LINTED*/
520 	if (/*CONSTCOND*/sizeof(*dest) < 4) {
521 		(void) fprintf(stderr, "limread_scalar: bad dest\n");
522 		return 0;
523 	}
524 	if (!limread(c, len, region, stream)) {
525 		return 0;
526 	}
527 	for (t = 0, n = 0; n < len; ++n) {
528 		t = (t << 8) + c[n];
529 	}
530 	*dest = t;
531 	return 1;
532 }
533 
534 /** Read a scalar.
535  *
536  * Read a big-endian scalar of length bytes, respecting packet
537  * boundaries (by calling limread() to read the raw data).
538  *
539  * The value read is stored in a size_t, which is a different size
540  * from an unsigned on some platforms.
541  *
542  * This function makes sure to respect packet boundaries.
543  *
544  * \param *dest		The scalar value is stored here
545  * \param length	How many bytes make up this scalar (at most 4)
546  * \param *region	Pointer to current packet region
547  * \param *stream	How to parse
548  * \param *cb		The callback
549  * \return		1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
550  *
551  * \see RFC4880 3.1
552  */
553 static int
554 limread_size_t(size_t *dest,
555 				unsigned length,
556 				__ops_region_t *region,
557 				__ops_stream_t *stream)
558 {
559 	unsigned        tmp;
560 
561 	/*
562 	 * Note that because the scalar is at most 4 bytes, we don't care if
563 	 * size_t is bigger than usigned
564 	 */
565 	if (!limread_scalar(&tmp, length, region, stream))
566 		return 0;
567 
568 	*dest = tmp;
569 	return 1;
570 }
571 
572 /** Read a timestamp.
573  *
574  * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch (1.1.1970).  They are stored in an unsigned scalar
575  * of 4 bytes.
576  *
577  * This function reads the timestamp using limread_scalar().
578  *
579  * This function makes sure to respect packet boundaries.
580  *
581  * \param *dest		The timestamp is stored here
582  * \param *ptag		Pointer to current packet's Packet Tag.
583  * \param *reader	Our reader
584  * \param *cb		The callback
585  * \return		see limread_scalar()
586  *
587  * \see RFC4880 3.5
588  */
589 static int
590 limited_read_time(time_t *dest, __ops_region_t *region,
591 		  __ops_stream_t *stream)
592 {
593 	unsigned char   c;
594 	time_t          mytime = 0;
595 	int             i = 0;
596 
597 	/*
598          * Cannot assume that time_t is 4 octets long -
599 	 * SunOS 5.10 and NetBSD both have 64-bit time_ts.
600          */
601 	if (/* CONSTCOND */sizeof(time_t) == 4) {
602 		return limread_scalar((unsigned *)(void *)dest, 4, region, stream);
603 	}
604 	for (i = 0; i < 4; i++) {
605 		if (!limread(&c, 1, region, stream)) {
606 			return 0;
607 		}
608 		mytime = (mytime << 8) + c;
609 	}
610 	*dest = mytime;
611 	return 1;
612 }
613 
614 /**
615  * \ingroup Core_MPI
616  * Read a multiprecision integer.
617  *
618  * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts.  First there is a 2 byte scalar
619  * indicating the length of the following MPI in Bits.  Then follow the bits that make up the actual number, most
620  * significant bits first (Big Endian).  The most significant bit in the MPI is supposed to be 1 (unless the MPI is
621  * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted).
622  *
623  * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are
624  * supposed to be cleared - I guess. XXX - does anything actually say so?
625  *
626  * This function makes sure to respect packet boundaries.
627  *
628  * \param **pgn		return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed
629  * 				by the caller XXX right ben?
630  * \param *ptag		Pointer to current packet's Packet Tag.
631  * \param *reader	Our reader
632  * \param *cb		The callback
633  * \return		1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
634  * 				 see comment below - the callback is called with a OPS_PARSER_ERROR in case of an error)
635  *
636  * \see RFC4880 3.2
637  */
638 static int
639 limread_mpi(BIGNUM **pbn, __ops_region_t *region, __ops_stream_t *stream)
640 {
641 	unsigned char   buf[NETPGP_BUFSIZ] = "";
642 					/* an MPI has a 2 byte length part.
643 					 * Length is given in bits, so the
644 					 * largest we should ever need for
645 					 * the buffer is NETPGP_BUFSIZ bytes. */
646 	unsigned        length;
647 	unsigned        nonzero;
648 	unsigned   		ret;
649 
650 	stream->reading_mpi_len = 1;
651 	ret = limread_scalar(&length, 2, region, stream);
652 
653 	stream->reading_mpi_len = 0;
654 	if (!ret)
655 		return 0;
656 
657 	nonzero = length & 7;	/* there should be this many zero bits in the
658 				 * MS byte */
659 	if (!nonzero)
660 		nonzero = 8;
661 	length = (length + 7) / 8;
662 
663 	if (length == 0) {
664 		/* if we try to read a length of 0, then fail */
665 		if (__ops_get_debug_level(__FILE__)) {
666 			(void) fprintf(stderr, "limread_mpi: 0 length\n");
667 		}
668 		return 0;
669 	}
670 	if (length > NETPGP_BUFSIZ) {
671 		(void) fprintf(stderr, "limread_mpi: bad length\n");
672 		return 0;
673 	}
674 	if (!limread(buf, length, region, stream)) {
675 		return 0;
676 	}
677 	if (((unsigned)buf[0] >> nonzero) != 0 ||
678 	    !((unsigned)buf[0] & (1U << (nonzero - 1U)))) {
679 		OPS_ERROR(&stream->errors, OPS_E_P_MPI_FORMAT_ERROR, "MPI Format error");
680 		/* XXX: Ben, one part of
681 		 * this constraint does
682 		 * not apply to
683 		 * encrypted MPIs the
684 		 * draft says. -- peter */
685 		return 0;
686 	}
687 	*pbn = BN_bin2bn(buf, (int)length, NULL);
688 	return 1;
689 }
690 
691 /** Read some data with a New-Format length from reader.
692  *
693  * \sa Internet-Draft RFC4880.txt Section 4.2.2
694  *
695  * \param *length	Where the decoded length will be put
696  * \param *stream	How to parse
697  * \return		1 if OK, else 0
698  *
699  */
700 
701 static unsigned
702 read_new_length(unsigned *length, __ops_stream_t *stream)
703 {
704 	unsigned char   c;
705 
706 	if (base_read(&c, 1, stream) != 1)
707 		return 0;
708 	if (c < 192) {
709 		/* 1. One-octet packet */
710 		*length = c;
711 		return 1;
712 	} else if (c >= 192 && c <= 223) {
713 		/* 2. Two-octet packet */
714 		unsigned        t = (c - 192) << 8;
715 
716 		if (base_read(&c, 1, stream) != 1)
717 			return 0;
718 		*length = t + c + 192;
719 		return 1;
720 	} else if (c == 255) {
721 		/* 3. Five-Octet packet */
722 		return _read_scalar(length, 4, stream);
723 	} else if (c >= 224 && c < 255) {
724 		/* 4. Partial Body Length */
725 		/* XXX - agc - gpg multi-recipient encryption uses this */
726 		OPS_ERROR(&stream->errors, OPS_E_UNIMPLEMENTED,
727 		"New format Partial Body Length fields not yet implemented");
728 		return 0;
729 	}
730 	return 0;
731 }
732 
733 /** Read the length information for a new format Packet Tag.
734  *
735  * New style Packet Tags encode the length in one to five octets.  This function reads the right amount of bytes and
736  * decodes it to the proper length information.
737  *
738  * This function makes sure to respect packet boundaries.
739  *
740  * \param *length	return the length here
741  * \param *ptag		Pointer to current packet's Packet Tag.
742  * \param *reader	Our reader
743  * \param *cb		The callback
744  * \return		1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
745  * 				 see comment below)
746  *
747  * \see RFC4880 4.2.2
748  * \see __ops_ptag_t
749  */
750 static int
751 limited_read_new_length(unsigned *length, __ops_region_t *region,
752 			__ops_stream_t *stream)
753 {
754 	unsigned char   c = 0x0;
755 
756 	if (!limread(&c, 1, region, stream)) {
757 		return 0;
758 	}
759 	if (c < 192) {
760 		*length = c;
761 		return 1;
762 	}
763 	if (c < 255) {
764 		unsigned        t = (c - 192) << 8;
765 
766 		if (!limread(&c, 1, region, stream)) {
767 			return 0;
768 		}
769 		*length = t + c + 192;
770 		return 1;
771 	}
772 	return limread_scalar(length, 4, region, stream);
773 }
774 
775 /**
776 \ingroup Core_Create
777 \brief Free allocated memory
778 */
779 static void
780 data_free(__ops_data_t *data)
781 {
782 	(void) free(data->contents);
783 	data->contents = NULL;
784 	data->len = 0;
785 }
786 
787 /**
788 \ingroup Core_Create
789 \brief Free allocated memory
790 */
791 static void
792 string_free(char **str)
793 {
794 	(void) free(*str);
795 	*str = NULL;
796 }
797 
798 /**
799 \ingroup Core_Create
800 \brief Free allocated memory
801 */
802 /* ! Free packet memory, set pointer to NULL */
803 void
804 __ops_subpacket_free(__ops_subpacket_t *packet)
805 {
806 	(void) free(packet->raw);
807 	packet->raw = NULL;
808 }
809 
810 /**
811 \ingroup Core_Create
812 \brief Free allocated memory
813 */
814 static void
815 __ops_headers_free(__ops_headers_t *headers)
816 {
817 	unsigned        n;
818 
819 	for (n = 0; n < headers->headerc; ++n) {
820 		(void) free(headers->headers[n].key);
821 		(void) free(headers->headers[n].value);
822 	}
823 	(void) free(headers->headers);
824 	headers->headers = NULL;
825 }
826 
827 /**
828 \ingroup Core_Create
829 \brief Free allocated memory
830 */
831 static void
832 cleartext_trailer_free(__ops_cleartext_trailer_t *trailer)
833 {
834 	(void) free(trailer->hash);
835 	trailer->hash = NULL;
836 }
837 
838 /**
839 \ingroup Core_Create
840 \brief Free allocated memory
841 */
842 static void
843 __ops_cmd_get_passphrase_free(__ops_seckey_passphrase_t *skp)
844 {
845 	if (skp->passphrase && *skp->passphrase) {
846 		(void) free(*skp->passphrase);
847 		*skp->passphrase = NULL;
848 	}
849 }
850 
851 /**
852    \ingroup Core_Create
853    \brief Free the memory used when parsing this signature sub-packet type
854 */
855 static void
856 ss_userdef_free(__ops_ss_userdef_t *ss_userdef)
857 {
858 	data_free(&ss_userdef->data);
859 }
860 
861 /**
862    \ingroup Core_Create
863    \brief Free the memory used when parsing this signature sub-packet type
864 */
865 static void
866 ss_reserved_free(__ops_ss_unknown_t *ss_unknown)
867 {
868 	data_free(&ss_unknown->data);
869 }
870 
871 /**
872    \ingroup Core_Create
873    \brief Free the memory used when parsing this packet type
874 */
875 static void
876 trust_free(__ops_trust_t *trust)
877 {
878 	data_free(&trust->data);
879 }
880 
881 /**
882  * \ingroup Core_Create
883  * \brief Free the memory used when parsing a private/experimental PKA signature
884  * \param unknown_sig
885  */
886 static void
887 free_unknown_sig_pka(__ops_unknown_sig_t *unknown_sig)
888 {
889 	data_free(&unknown_sig->data);
890 }
891 
892 /**
893 \ingroup Core_Create
894 \brief Free allocated memory
895 */
896 static void
897 free_BN(BIGNUM **pp)
898 {
899 	BN_free(*pp);
900 	*pp = NULL;
901 }
902 
903 /**
904  * \ingroup Core_Create
905  * \brief Free the memory used when parsing a signature
906  * \param sig
907  */
908 static void
909 sig_free(__ops_sig_t *sig)
910 {
911 	switch (sig->info.key_alg) {
912 	case OPS_PKA_RSA:
913 	case OPS_PKA_RSA_SIGN_ONLY:
914 		free_BN(&sig->info.sig.rsa.sig);
915 		break;
916 
917 	case OPS_PKA_DSA:
918 		free_BN(&sig->info.sig.dsa.r);
919 		free_BN(&sig->info.sig.dsa.s);
920 		break;
921 
922 	case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
923 		free_BN(&sig->info.sig.elgamal.r);
924 		free_BN(&sig->info.sig.elgamal.s);
925 		break;
926 
927 	case OPS_PKA_PRIVATE00:
928 	case OPS_PKA_PRIVATE01:
929 	case OPS_PKA_PRIVATE02:
930 	case OPS_PKA_PRIVATE03:
931 	case OPS_PKA_PRIVATE04:
932 	case OPS_PKA_PRIVATE05:
933 	case OPS_PKA_PRIVATE06:
934 	case OPS_PKA_PRIVATE07:
935 	case OPS_PKA_PRIVATE08:
936 	case OPS_PKA_PRIVATE09:
937 	case OPS_PKA_PRIVATE10:
938 		free_unknown_sig_pka(&sig->info.sig.unknown);
939 		break;
940 
941 	default:
942 		(void) fprintf(stderr, "sig_free: bad sig type\n");
943 	}
944 }
945 
946 /**
947  \ingroup Core_Create
948  \brief Free the memory used when parsing this signature sub-packet type
949  \param ss_skapref
950 */
951 static void
952 ss_skapref_free(__ops_ss_skapref_t *ss_skapref)
953 {
954 	data_free(&ss_skapref->data);
955 }
956 
957 /**
958    \ingroup Core_Create
959    \brief Free the memory used when parsing this signature sub-packet type
960    \param ss_hashpref
961 */
962 static void
963 ss_hashpref_free(__ops_ss_hashpref_t *ss_hashpref)
964 {
965 	data_free(&ss_hashpref->data);
966 }
967 
968 /**
969    \ingroup Core_Create
970    \brief Free the memory used when parsing this signature sub-packet type
971 */
972 static void
973 ss_zpref_free(__ops_ss_zpref_t *ss_zpref)
974 {
975 	data_free(&ss_zpref->data);
976 }
977 
978 /**
979    \ingroup Core_Create
980    \brief Free the memory used when parsing this signature sub-packet type
981 */
982 static void
983 ss_key_flags_free(__ops_ss_key_flags_t *ss_key_flags)
984 {
985 	data_free(&ss_key_flags->data);
986 }
987 
988 /**
989    \ingroup Core_Create
990    \brief Free the memory used when parsing this signature sub-packet type
991 */
992 static void
993 ss_key_server_prefs_free(__ops_ss_key_server_prefs_t *ss_key_server_prefs)
994 {
995 	data_free(&ss_key_server_prefs->data);
996 }
997 
998 /**
999    \ingroup Core_Create
1000    \brief Free the memory used when parsing this signature sub-packet type
1001 */
1002 static void
1003 ss_features_free(__ops_ss_features_t *ss_features)
1004 {
1005 	data_free(&ss_features->data);
1006 }
1007 
1008 /**
1009    \ingroup Core_Create
1010    \brief Free the memory used when parsing this signature sub-packet type
1011 */
1012 static void
1013 ss_notation_free(__ops_ss_notation_t *ss_notation)
1014 {
1015 	data_free(&ss_notation->name);
1016 	data_free(&ss_notation->value);
1017 }
1018 
1019 /**
1020 \ingroup Core_Create
1021 \brief Free allocated memory
1022 */
1023 /* ! Free the memory used when parsing this signature sub-packet type */
1024 static void
1025 ss_regexp_free(__ops_ss_regexp_t *regexp)
1026 {
1027 	string_free(&regexp->regexp);
1028 }
1029 
1030 /**
1031 \ingroup Core_Create
1032 \brief Free allocated memory
1033 */
1034 /* ! Free the memory used when parsing this signature sub-packet type */
1035 static void
1036 ss_policy_free(__ops_ss_policy_t *policy)
1037 {
1038 	string_free(&policy->url);
1039 }
1040 
1041 /**
1042 \ingroup Core_Create
1043 \brief Free allocated memory
1044 */
1045 /* ! Free the memory used when parsing this signature sub-packet type */
1046 static void
1047 ss_keyserv_free(__ops_ss_keyserv_t *preferred_key_server)
1048 {
1049 	string_free(&preferred_key_server->name);
1050 }
1051 
1052 /**
1053    \ingroup Core_Create
1054    \brief Free the memory used when parsing this signature sub-packet type
1055 */
1056 static void
1057 ss_revocation_free(__ops_ss_revocation_t *ss_revocation)
1058 {
1059 	string_free(&ss_revocation->reason);
1060 }
1061 
1062 static void
1063 ss_embedded_sig_free(__ops_ss_embedded_sig_t *ss_embedded_sig)
1064 {
1065 	data_free(&ss_embedded_sig->sig);
1066 }
1067 
1068 /**
1069 \ingroup Core_Create
1070 \brief Free allocated memory
1071 */
1072 /* ! Free any memory allocated when parsing the packet content */
1073 void
1074 __ops_parser_content_free(__ops_packet_t *c)
1075 {
1076 	switch (c->tag) {
1077 	case OPS_PARSER_PTAG:
1078 	case OPS_PTAG_CT_COMPRESSED:
1079 	case OPS_PTAG_SS_CREATION_TIME:
1080 	case OPS_PTAG_SS_EXPIRATION_TIME:
1081 	case OPS_PTAG_SS_KEY_EXPIRY:
1082 	case OPS_PTAG_SS_TRUST:
1083 	case OPS_PTAG_SS_ISSUER_KEY_ID:
1084 	case OPS_PTAG_CT_1_PASS_SIG:
1085 	case OPS_PTAG_SS_PRIMARY_USER_ID:
1086 	case OPS_PTAG_SS_REVOCABLE:
1087 	case OPS_PTAG_SS_REVOCATION_KEY:
1088 	case OPS_PTAG_CT_LITDATA_HEADER:
1089 	case OPS_PTAG_CT_LITDATA_BODY:
1090 	case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
1091 	case OPS_PTAG_CT_UNARMOURED_TEXT:
1092 	case OPS_PTAG_CT_ARMOUR_TRAILER:
1093 	case OPS_PTAG_CT_SIGNATURE_HEADER:
1094 	case OPS_PTAG_CT_SE_DATA_HEADER:
1095 	case OPS_PTAG_CT_SE_IP_DATA_HEADER:
1096 	case OPS_PTAG_CT_SE_IP_DATA_BODY:
1097 	case OPS_PTAG_CT_MDC:
1098 	case OPS_GET_SECKEY:
1099 		break;
1100 
1101 	case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1102 		__ops_headers_free(&c->u.cleartext_head.headers);
1103 		break;
1104 
1105 	case OPS_PTAG_CT_ARMOUR_HEADER:
1106 		__ops_headers_free(&c->u.armour_header.headers);
1107 		break;
1108 
1109 	case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
1110 		cleartext_trailer_free(&c->u.cleartext_trailer);
1111 		break;
1112 
1113 	case OPS_PTAG_CT_TRUST:
1114 		trust_free(&c->u.trust);
1115 		break;
1116 
1117 	case OPS_PTAG_CT_SIGNATURE:
1118 	case OPS_PTAG_CT_SIGNATURE_FOOTER:
1119 		sig_free(&c->u.sig);
1120 		break;
1121 
1122 	case OPS_PTAG_CT_PUBLIC_KEY:
1123 	case OPS_PTAG_CT_PUBLIC_SUBKEY:
1124 		__ops_pubkey_free(&c->u.pubkey);
1125 		break;
1126 
1127 	case OPS_PTAG_CT_USER_ID:
1128 		__ops_userid_free(&c->u.userid);
1129 		break;
1130 
1131 	case OPS_PTAG_SS_SIGNERS_USER_ID:
1132 		__ops_userid_free(&c->u.ss_signer);
1133 		break;
1134 
1135 	case OPS_PTAG_CT_USER_ATTR:
1136 		__ops_userattr_free(&c->u.userattr);
1137 		break;
1138 
1139 	case OPS_PTAG_SS_PREFERRED_SKA:
1140 		ss_skapref_free(&c->u.ss_skapref);
1141 		break;
1142 
1143 	case OPS_PTAG_SS_PREFERRED_HASH:
1144 		ss_hashpref_free(&c->u.ss_hashpref);
1145 		break;
1146 
1147 	case OPS_PTAG_SS_PREF_COMPRESS:
1148 		ss_zpref_free(&c->u.ss_zpref);
1149 		break;
1150 
1151 	case OPS_PTAG_SS_KEY_FLAGS:
1152 		ss_key_flags_free(&c->u.ss_key_flags);
1153 		break;
1154 
1155 	case OPS_PTAG_SS_KEYSERV_PREFS:
1156 		ss_key_server_prefs_free(&c->u.ss_key_server_prefs);
1157 		break;
1158 
1159 	case OPS_PTAG_SS_FEATURES:
1160 		ss_features_free(&c->u.ss_features);
1161 		break;
1162 
1163 	case OPS_PTAG_SS_NOTATION_DATA:
1164 		ss_notation_free(&c->u.ss_notation);
1165 		break;
1166 
1167 	case OPS_PTAG_SS_REGEXP:
1168 		ss_regexp_free(&c->u.ss_regexp);
1169 		break;
1170 
1171 	case OPS_PTAG_SS_POLICY_URI:
1172 		ss_policy_free(&c->u.ss_policy);
1173 		break;
1174 
1175 	case OPS_PTAG_SS_PREF_KEYSERV:
1176 		ss_keyserv_free(&c->u.ss_keyserv);
1177 		break;
1178 
1179 	case OPS_PTAG_SS_USERDEFINED00:
1180 	case OPS_PTAG_SS_USERDEFINED01:
1181 	case OPS_PTAG_SS_USERDEFINED02:
1182 	case OPS_PTAG_SS_USERDEFINED03:
1183 	case OPS_PTAG_SS_USERDEFINED04:
1184 	case OPS_PTAG_SS_USERDEFINED05:
1185 	case OPS_PTAG_SS_USERDEFINED06:
1186 	case OPS_PTAG_SS_USERDEFINED07:
1187 	case OPS_PTAG_SS_USERDEFINED08:
1188 	case OPS_PTAG_SS_USERDEFINED09:
1189 	case OPS_PTAG_SS_USERDEFINED10:
1190 		ss_userdef_free(&c->u.ss_userdef);
1191 		break;
1192 
1193 	case OPS_PTAG_SS_RESERVED:
1194 		ss_reserved_free(&c->u.ss_unknown);
1195 		break;
1196 
1197 	case OPS_PTAG_SS_REVOCATION_REASON:
1198 		ss_revocation_free(&c->u.ss_revocation);
1199 		break;
1200 
1201 	case OPS_PTAG_SS_EMBEDDED_SIGNATURE:
1202 		ss_embedded_sig_free(&c->u.ss_embedded_sig);
1203 		break;
1204 
1205 	case OPS_PARSER_PACKET_END:
1206 		__ops_subpacket_free(&c->u.packet);
1207 		break;
1208 
1209 	case OPS_PARSER_ERROR:
1210 	case OPS_PARSER_ERRCODE:
1211 		break;
1212 
1213 	case OPS_PTAG_CT_SECRET_KEY:
1214 	case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY:
1215 		__ops_seckey_free(&c->u.seckey);
1216 		break;
1217 
1218 	case OPS_PTAG_CT_PK_SESSION_KEY:
1219 	case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1220 		__ops_pk_sesskey_free(&c->u.pk_sesskey);
1221 		break;
1222 
1223 	case OPS_GET_PASSPHRASE:
1224 		__ops_cmd_get_passphrase_free(&c->u.skey_passphrase);
1225 		break;
1226 
1227 	default:
1228 		fprintf(stderr, "Can't free %d (0x%x)\n", c->tag, c->tag);
1229 	}
1230 }
1231 
1232 /**
1233 \ingroup Core_Create
1234 \brief Free allocated memory
1235 */
1236 void
1237 __ops_pk_sesskey_free(__ops_pk_sesskey_t *sk)
1238 {
1239 	switch (sk->alg) {
1240 	case OPS_PKA_RSA:
1241 		free_BN(&sk->params.rsa.encrypted_m);
1242 		break;
1243 
1244 	case OPS_PKA_ELGAMAL:
1245 		free_BN(&sk->params.elgamal.g_to_k);
1246 		free_BN(&sk->params.elgamal.encrypted_m);
1247 		break;
1248 
1249 	default:
1250 		(void) fprintf(stderr, "__ops_pk_sesskey_free: bad alg\n");
1251 		break;
1252 	}
1253 }
1254 
1255 /**
1256 \ingroup Core_Create
1257 \brief Free allocated memory
1258 */
1259 /* ! Free the memory used when parsing a public key */
1260 void
1261 __ops_pubkey_free(__ops_pubkey_t *p)
1262 {
1263 	switch (p->alg) {
1264 	case OPS_PKA_RSA:
1265 	case OPS_PKA_RSA_ENCRYPT_ONLY:
1266 	case OPS_PKA_RSA_SIGN_ONLY:
1267 		free_BN(&p->key.rsa.n);
1268 		free_BN(&p->key.rsa.e);
1269 		break;
1270 
1271 	case OPS_PKA_DSA:
1272 		free_BN(&p->key.dsa.p);
1273 		free_BN(&p->key.dsa.q);
1274 		free_BN(&p->key.dsa.g);
1275 		free_BN(&p->key.dsa.y);
1276 		break;
1277 
1278 	case OPS_PKA_ELGAMAL:
1279 	case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1280 		free_BN(&p->key.elgamal.p);
1281 		free_BN(&p->key.elgamal.g);
1282 		free_BN(&p->key.elgamal.y);
1283 		break;
1284 
1285 	case 0:
1286 		/* nothing to free */
1287 		break;
1288 
1289 	default:
1290 		(void) fprintf(stderr, "__ops_pubkey_free: bad alg\n");
1291 	}
1292 }
1293 
1294 /**
1295    \ingroup Core_ReadPackets
1296 */
1297 static int
1298 parse_pubkey_data(__ops_pubkey_t *key, __ops_region_t *region,
1299 		      __ops_stream_t *stream)
1300 {
1301 	unsigned char   c = 0x0;
1302 
1303 	if (region->readc != 0) {
1304 		/* We should not have read anything so far */
1305 		(void) fprintf(stderr, "parse_pubkey_data: bad length\n");
1306 		return 0;
1307 	}
1308 
1309 	if (!limread(&c, 1, region, stream)) {
1310 		return 0;
1311 	}
1312 	key->version = c;
1313 	if (key->version < 2 || key->version > 4) {
1314 		OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN,
1315 			    "Bad public key version (0x%02x)", key->version);
1316 		return 0;
1317 	}
1318 	if (!limited_read_time(&key->birthtime, region, stream)) {
1319 		return 0;
1320 	}
1321 
1322 	key->days_valid = 0;
1323 	if ((key->version == 2 || key->version == 3) &&
1324 	    !limread_scalar(&key->days_valid, 2, region, stream)) {
1325 		return 0;
1326 	}
1327 
1328 	if (!limread(&c, 1, region, stream)) {
1329 		return 0;
1330 	}
1331 	key->alg = c;
1332 
1333 	switch (key->alg) {
1334 	case OPS_PKA_DSA:
1335 		if (!limread_mpi(&key->key.dsa.p, region, stream) ||
1336 		    !limread_mpi(&key->key.dsa.q, region, stream) ||
1337 		    !limread_mpi(&key->key.dsa.g, region, stream) ||
1338 		    !limread_mpi(&key->key.dsa.y, region, stream)) {
1339 			return 0;
1340 		}
1341 		break;
1342 
1343 	case OPS_PKA_RSA:
1344 	case OPS_PKA_RSA_ENCRYPT_ONLY:
1345 	case OPS_PKA_RSA_SIGN_ONLY:
1346 		if (!limread_mpi(&key->key.rsa.n, region, stream) ||
1347 		    !limread_mpi(&key->key.rsa.e, region, stream)) {
1348 			return 0;
1349 		}
1350 		break;
1351 
1352 	case OPS_PKA_ELGAMAL:
1353 	case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1354 		if (!limread_mpi(&key->key.elgamal.p, region, stream) ||
1355 		    !limread_mpi(&key->key.elgamal.g, region, stream) ||
1356 		    !limread_mpi(&key->key.elgamal.y, region, stream)) {
1357 			return 0;
1358 		}
1359 		break;
1360 
1361 	default:
1362 		OPS_ERROR_1(&stream->errors,
1363 			OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
1364 			"Unsupported Public Key algorithm (%s)",
1365 			__ops_show_pka(key->alg));
1366 		return 0;
1367 	}
1368 
1369 	return 1;
1370 }
1371 
1372 
1373 /**
1374  * \ingroup Core_ReadPackets
1375  * \brief Parse a public key packet.
1376  *
1377  * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys.
1378  *
1379  * Once the key has been parsed successfully, it is passed to the callback.
1380  *
1381  * \param *ptag		Pointer to the current Packet Tag.  This function should consume the entire packet.
1382  * \param *reader	Our reader
1383  * \param *cb		The callback
1384  * \return		1 on success, 0 on error
1385  *
1386  * \see RFC4880 5.5.2
1387  */
1388 static int
1389 parse_pubkey(__ops_content_tag_t tag, __ops_region_t *region,
1390 		 __ops_stream_t *stream)
1391 {
1392 	__ops_packet_t pkt;
1393 
1394 	if (!parse_pubkey_data(&pkt.u.pubkey, region, stream))
1395 		return 0;
1396 
1397 	/* XXX: this test should be done for all packets, surely? */
1398 	if (region->readc != region->length) {
1399 		OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
1400 			    "Unconsumed data (%d)", region->length - region->readc);
1401 		return 0;
1402 	}
1403 	CALLBACK(tag, &stream->cbinfo, &pkt);
1404 
1405 	return 1;
1406 }
1407 
1408 
1409 /**
1410 \ingroup Core_Create
1411 \brief Free allocated memory
1412 */
1413 /* ! Free the memory used when parsing this packet type */
1414 void
1415 __ops_userattr_free(__ops_userattr_t *user_att)
1416 {
1417 	data_free(&user_att->data);
1418 }
1419 
1420 /**
1421  * \ingroup Core_ReadPackets
1422  * \brief Parse one user attribute packet.
1423  *
1424  * User attribute packets contain one or more attribute subpackets.
1425  * For now, handle the whole packet as raw data.
1426  */
1427 
1428 static int
1429 parse_userattr(__ops_region_t *region, __ops_stream_t *stream)
1430 {
1431 
1432 	__ops_packet_t pkt;
1433 
1434 	/*
1435 	 * xxx- treat as raw data for now. Could break down further into
1436 	 * attribute sub-packets later - rachel
1437 	 */
1438 
1439 	if (region->readc != 0) {
1440 		/* We should not have read anything so far */
1441 		(void) fprintf(stderr, "parse_userattr: bad length\n");
1442 		return 0;
1443 	}
1444 
1445 	if (!read_data(&pkt.u.userattr.data, region, stream))
1446 		return 0;
1447 
1448 	CALLBACK(OPS_PTAG_CT_USER_ATTR, &stream->cbinfo, &pkt);
1449 
1450 	return 1;
1451 }
1452 
1453 /**
1454 \ingroup Core_Create
1455 \brief Free allocated memory
1456 */
1457 /* ! Free the memory used when parsing this packet type */
1458 void
1459 __ops_userid_free(__ops_userid_t *id)
1460 {
1461 	(void) free(id->userid);
1462 	id->userid = NULL;
1463 }
1464 
1465 /**
1466  * \ingroup Core_ReadPackets
1467  * \brief Parse a user id.
1468  *
1469  * This function parses an user id packet, which is basically just a char array the size of the packet.
1470  *
1471  * The char array is to be treated as an UTF-8 string.
1472  *
1473  * The userid gets null terminated by this function.  Freeing it is the responsibility of the caller.
1474  *
1475  * Once the userid has been parsed successfully, it is passed to the callback.
1476  *
1477  * \param *ptag		Pointer to the Packet Tag.  This function should consume the entire packet.
1478  * \param *reader	Our reader
1479  * \param *cb		The callback
1480  * \return		1 on success, 0 on error
1481  *
1482  * \see RFC4880 5.11
1483  */
1484 static int
1485 parse_userid(__ops_region_t *region, __ops_stream_t *stream)
1486 {
1487 	__ops_packet_t pkt;
1488 
1489 	 if (region->readc != 0) {
1490 		/* We should not have read anything so far */
1491 		(void) fprintf(stderr, "parse_userid: bad length\n");
1492 		return 0;
1493 	}
1494 
1495 	/* XXX should we not like check malloc's return value? */
1496 	pkt.u.userid.userid = calloc(1, region->length + 1);
1497 
1498 	if (region->length &&
1499 	    !limread(pkt.u.userid.userid, region->length, region,
1500 			stream)) {
1501 		return 0;
1502 	}
1503 	pkt.u.userid.userid[region->length] = '\0';
1504 	CALLBACK(OPS_PTAG_CT_USER_ID, &stream->cbinfo, &pkt);
1505 	return 1;
1506 }
1507 
1508 static __ops_hash_t     *
1509 parse_hash_find(__ops_stream_t *stream, const unsigned char *keyid)
1510 {
1511 	__ops_hashtype_t	*hp;
1512 	size_t			 n;
1513 
1514 	for (n = 0, hp = stream->hashes; n < stream->hashc; n++, hp++) {
1515 		if (memcmp(hp->keyid, keyid, OPS_KEY_ID_SIZE) == 0) {
1516 			return &hp->hash;
1517 		}
1518 	}
1519 	return NULL;
1520 }
1521 
1522 /**
1523  * \ingroup Core_Parse
1524  * \brief Parse a version 3 signature.
1525  *
1526  * This function parses an version 3 signature packet, handling RSA and DSA signatures.
1527  *
1528  * Once the signature has been parsed successfully, it is passed to the callback.
1529  *
1530  * \param *ptag		Pointer to the Packet Tag.  This function should consume the entire packet.
1531  * \param *reader	Our reader
1532  * \param *cb		The callback
1533  * \return		1 on success, 0 on error
1534  *
1535  * \see RFC4880 5.2.2
1536  */
1537 static int
1538 parse_v3_sig(__ops_region_t *region,
1539 		   __ops_stream_t *stream)
1540 {
1541 	__ops_packet_t	pkt;
1542 	unsigned char		c = 0x0;
1543 
1544 	/* clear signature */
1545 	(void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
1546 
1547 	pkt.u.sig.info.version = OPS_V3;
1548 
1549 	/* hash info length */
1550 	if (!limread(&c, 1, region, stream)) {
1551 		return 0;
1552 	}
1553 	if (c != 5) {
1554 		ERRP(&stream->cbinfo, pkt, "bad hash info length");
1555 	}
1556 
1557 	if (!limread(&c, 1, region, stream)) {
1558 		return 0;
1559 	}
1560 	pkt.u.sig.info.type = c;
1561 	/* XXX: check signature type */
1562 
1563 	if (!limited_read_time(&pkt.u.sig.info.birthtime, region, stream)) {
1564 		return 0;
1565 	}
1566 	pkt.u.sig.info.birthtime_set = 1;
1567 
1568 	if (!limread(pkt.u.sig.info.signer_id, OPS_KEY_ID_SIZE, region,
1569 			stream)) {
1570 		return 0;
1571 	}
1572 	pkt.u.sig.info.signer_id_set = 1;
1573 
1574 	if (!limread(&c, 1, region, stream)) {
1575 		return 0;
1576 	}
1577 	pkt.u.sig.info.key_alg = c;
1578 	/* XXX: check algorithm */
1579 
1580 	if (!limread(&c, 1, region, stream)) {
1581 		return 0;
1582 	}
1583 	pkt.u.sig.info.hash_alg = c;
1584 	/* XXX: check algorithm */
1585 
1586 	if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
1587 		return 0;
1588 	}
1589 
1590 	switch (pkt.u.sig.info.key_alg) {
1591 	case OPS_PKA_RSA:
1592 	case OPS_PKA_RSA_SIGN_ONLY:
1593 		if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
1594 			return 0;
1595 		}
1596 		break;
1597 
1598 	case OPS_PKA_DSA:
1599 		if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream) ||
1600 		    !limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
1601 			return 0;
1602 		}
1603 		break;
1604 
1605 	case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1606 		if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
1607 				stream) ||
1608 		    !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
1609 		    		stream)) {
1610 			return 0;
1611 		}
1612 		break;
1613 
1614 	default:
1615 		OPS_ERROR_1(&stream->errors,
1616 			OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
1617 			"Unsupported signature key algorithm (%s)",
1618 			__ops_show_pka(pkt.u.sig.info.key_alg));
1619 		return 0;
1620 	}
1621 
1622 	if (region->readc != region->length) {
1623 		OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
1624 			"Unconsumed data (%d)",
1625 			region->length - region->readc);
1626 		return 0;
1627 	}
1628 	if (pkt.u.sig.info.signer_id_set) {
1629 		pkt.u.sig.hash = parse_hash_find(stream,
1630 				pkt.u.sig.info.signer_id);
1631 	}
1632 	CALLBACK(OPS_PTAG_CT_SIGNATURE, &stream->cbinfo, &pkt);
1633 	return 1;
1634 }
1635 
1636 /**
1637  * \ingroup Core_ReadPackets
1638  * \brief Parse one signature sub-packet.
1639  *
1640  * Version 4 signatures can have an arbitrary amount of (hashed and unhashed) subpackets.  Subpackets are used to hold
1641  * optional attributes of subpackets.
1642  *
1643  * This function parses one such signature subpacket.
1644  *
1645  * Once the subpacket has been parsed successfully, it is passed to the callback.
1646  *
1647  * \param *ptag		Pointer to the Packet Tag.  This function should consume the entire subpacket.
1648  * \param *reader	Our reader
1649  * \param *cb		The callback
1650  * \return		1 on success, 0 on error
1651  *
1652  * \see RFC4880 5.2.3
1653  */
1654 static int
1655 parse_one_sig_subpacket(__ops_sig_t *sig,
1656 			      __ops_region_t *region,
1657 			      __ops_stream_t *stream)
1658 {
1659 	__ops_region_t	subregion;
1660 	__ops_packet_t	pkt;
1661 	unsigned char   bools = 0x0;
1662 	unsigned char	c = 0x0;
1663 	unsigned	doread = 1;
1664 	unsigned        t8;
1665 	unsigned        t7;
1666 
1667 	__ops_init_subregion(&subregion, region);
1668 	if (!limited_read_new_length(&subregion.length, region, stream)) {
1669 		return 0;
1670 	}
1671 
1672 	if (subregion.length > region->length) {
1673 		ERRP(&stream->cbinfo, pkt, "Subpacket too long");
1674 	}
1675 
1676 	if (!limread(&c, 1, &subregion, stream)) {
1677 		return 0;
1678 	}
1679 
1680 	t8 = (c & 0x7f) / 8;
1681 	t7 = 1 << (c & 7);
1682 
1683 	pkt.critical = (unsigned)c >> 7;
1684 	pkt.tag = OPS_PTAG_SIG_SUBPKT_BASE + (c & 0x7f);
1685 
1686 	/* Application wants it delivered raw */
1687 	if (stream->ss_raw[t8] & t7) {
1688 		pkt.u.ss_raw.tag = pkt.tag;
1689 		pkt.u.ss_raw.length = subregion.length - 1;
1690 		pkt.u.ss_raw.raw = calloc(1, pkt.u.ss_raw.length);
1691 		if (!limread(pkt.u.ss_raw.raw, pkt.u.ss_raw.length,
1692 				&subregion, stream)) {
1693 			return 0;
1694 		}
1695 		CALLBACK(OPS_PTAG_RAW_SS, &stream->cbinfo, &pkt);
1696 		return 1;
1697 	}
1698 	switch (pkt.tag) {
1699 	case OPS_PTAG_SS_CREATION_TIME:
1700 	case OPS_PTAG_SS_EXPIRATION_TIME:
1701 	case OPS_PTAG_SS_KEY_EXPIRY:
1702 		if (!limited_read_time(&pkt.u.ss_time.time, &subregion, stream))
1703 			return 0;
1704 		if (pkt.tag == OPS_PTAG_SS_CREATION_TIME) {
1705 			sig->info.birthtime = pkt.u.ss_time.time;
1706 			sig->info.birthtime_set = 1;
1707 		}
1708 		break;
1709 
1710 	case OPS_PTAG_SS_TRUST:
1711 		if (!limread(&pkt.u.ss_trust.level, 1, &subregion, stream) ||
1712 		    !limread(&pkt.u.ss_trust.amount, 1, &subregion, stream)) {
1713 			return 0;
1714 		}
1715 		break;
1716 
1717 	case OPS_PTAG_SS_REVOCABLE:
1718 		if (!limread(&bools, 1, &subregion, stream)) {
1719 			return 0;
1720 		}
1721 		pkt.u.ss_revocable.revocable = !!bools;
1722 		break;
1723 
1724 	case OPS_PTAG_SS_ISSUER_KEY_ID:
1725 		if (!limread(pkt.u.ss_issuer.key_id, OPS_KEY_ID_SIZE,
1726 				&subregion, stream)) {
1727 			return 0;
1728 		}
1729 		(void) memcpy(sig->info.signer_id,
1730 			pkt.u.ss_issuer.key_id, OPS_KEY_ID_SIZE);
1731 		sig->info.signer_id_set = 1;
1732 		break;
1733 
1734 	case OPS_PTAG_SS_PREFERRED_SKA:
1735 		if (!read_data(&pkt.u.ss_skapref.data, &subregion, stream)) {
1736 			return 0;
1737 		}
1738 		break;
1739 
1740 	case OPS_PTAG_SS_PREFERRED_HASH:
1741 		if (!read_data(&pkt.u.ss_hashpref.data, &subregion, stream)) {
1742 			return 0;
1743 		}
1744 		break;
1745 
1746 	case OPS_PTAG_SS_PREF_COMPRESS:
1747 		if (!read_data(&pkt.u.ss_zpref.data,
1748 				&subregion, stream)) {
1749 			return 0;
1750 		}
1751 		break;
1752 
1753 	case OPS_PTAG_SS_PRIMARY_USER_ID:
1754 		if (!limread(&bools, 1, &subregion, stream)) {
1755 			return 0;
1756 		}
1757 		pkt.u.ss_primary_userid.primary_userid = !!bools;
1758 		break;
1759 
1760 	case OPS_PTAG_SS_KEY_FLAGS:
1761 		if (!read_data(&pkt.u.ss_key_flags.data, &subregion, stream)) {
1762 			return 0;
1763 		}
1764 		break;
1765 
1766 	case OPS_PTAG_SS_KEYSERV_PREFS:
1767 		if (!read_data(&pkt.u.ss_key_server_prefs.data, &subregion,
1768 				stream)) {
1769 			return 0;
1770 		}
1771 		break;
1772 
1773 	case OPS_PTAG_SS_FEATURES:
1774 		if (!read_data(&pkt.u.ss_features.data, &subregion, stream)) {
1775 			return 0;
1776 		}
1777 		break;
1778 
1779 	case OPS_PTAG_SS_SIGNERS_USER_ID:
1780 		if (!read_unsig_str(&pkt.u.ss_signer.userid, &subregion,
1781 				stream)) {
1782 			return 0;
1783 		}
1784 		break;
1785 
1786 	case OPS_PTAG_SS_EMBEDDED_SIGNATURE:
1787 		/* \todo should do something with this sig? */
1788 		if (!read_data(&pkt.u.ss_embedded_sig.sig, &subregion, stream)) {
1789 			return 0;
1790 		}
1791 		break;
1792 
1793 	case OPS_PTAG_SS_NOTATION_DATA:
1794 		if (!limread_data(&pkt.u.ss_notation.flags, 4,
1795 				&subregion, stream)) {
1796 			return 0;
1797 		}
1798 		if (!limread_size_t(&pkt.u.ss_notation.name.len, 2,
1799 				&subregion, stream)) {
1800 			return 0;
1801 		}
1802 		if (!limread_size_t(&pkt.u.ss_notation.value.len, 2,
1803 				&subregion, stream)) {
1804 			return 0;
1805 		}
1806 		if (!limread_data(&pkt.u.ss_notation.name,
1807 				pkt.u.ss_notation.name.len,
1808 				&subregion, stream)) {
1809 			return 0;
1810 		}
1811 		if (!limread_data(&pkt.u.ss_notation.value,
1812 			   pkt.u.ss_notation.value.len,
1813 			   &subregion, stream)) {
1814 			return 0;
1815 		}
1816 		break;
1817 
1818 	case OPS_PTAG_SS_POLICY_URI:
1819 		if (!read_string(&pkt.u.ss_policy.url, &subregion, stream)) {
1820 			return 0;
1821 		}
1822 		break;
1823 
1824 	case OPS_PTAG_SS_REGEXP:
1825 		if (!read_string(&pkt.u.ss_regexp.regexp, &subregion, stream)) {
1826 			return 0;
1827 		}
1828 		break;
1829 
1830 	case OPS_PTAG_SS_PREF_KEYSERV:
1831 		if (!read_string(&pkt.u.ss_keyserv.name, &subregion, stream)) {
1832 			return 0;
1833 		}
1834 		break;
1835 
1836 	case OPS_PTAG_SS_USERDEFINED00:
1837 	case OPS_PTAG_SS_USERDEFINED01:
1838 	case OPS_PTAG_SS_USERDEFINED02:
1839 	case OPS_PTAG_SS_USERDEFINED03:
1840 	case OPS_PTAG_SS_USERDEFINED04:
1841 	case OPS_PTAG_SS_USERDEFINED05:
1842 	case OPS_PTAG_SS_USERDEFINED06:
1843 	case OPS_PTAG_SS_USERDEFINED07:
1844 	case OPS_PTAG_SS_USERDEFINED08:
1845 	case OPS_PTAG_SS_USERDEFINED09:
1846 	case OPS_PTAG_SS_USERDEFINED10:
1847 		if (!read_data(&pkt.u.ss_userdef.data, &subregion, stream)) {
1848 			return 0;
1849 		}
1850 		break;
1851 
1852 	case OPS_PTAG_SS_RESERVED:
1853 		if (!read_data(&pkt.u.ss_unknown.data, &subregion, stream)) {
1854 			return 0;
1855 		}
1856 		break;
1857 
1858 	case OPS_PTAG_SS_REVOCATION_REASON:
1859 		/* first byte is the machine-readable code */
1860 		if (!limread(&pkt.u.ss_revocation.code, 1, &subregion, stream)) {
1861 			return 0;
1862 		}
1863 		/* the rest is a human-readable UTF-8 string */
1864 		if (!read_string(&pkt.u.ss_revocation.reason, &subregion,
1865 				stream)) {
1866 			return 0;
1867 		}
1868 		break;
1869 
1870 	case OPS_PTAG_SS_REVOCATION_KEY:
1871 		/* octet 0 = class. Bit 0x80 must be set */
1872 		if (!limread(&pkt.u.ss_revocation_key.class, 1,
1873 				&subregion, stream)) {
1874 			return 0;
1875 		}
1876 		if (!(pkt.u.ss_revocation_key.class & 0x80)) {
1877 			printf("Warning: OPS_PTAG_SS_REVOCATION_KEY class: "
1878 			       "Bit 0x80 should be set\n");
1879 			return 0;
1880 		}
1881 		/* octet 1 = algid */
1882 		if (!limread(&pkt.u.ss_revocation_key.algid, 1,
1883 				&subregion, stream)) {
1884 			return 0;
1885 		}
1886 		/* octets 2-21 = fingerprint */
1887 		if (!limread(&pkt.u.ss_revocation_key.fingerprint[0],
1888 				OPS_FINGERPRINT_SIZE, &subregion, stream)) {
1889 			return 0;
1890 		}
1891 		break;
1892 
1893 	default:
1894 		if (stream->ss_parsed[t8] & t7) {
1895 			OPS_ERROR_1(&stream->errors, OPS_E_PROTO_UNKNOWN_SS,
1896 				    "Unknown signature subpacket type (%d)",
1897 				    c & 0x7f);
1898 		}
1899 		doread = 0;
1900 		break;
1901 	}
1902 
1903 	/* Application doesn't want it delivered parsed */
1904 	if (!(stream->ss_parsed[t8] & t7)) {
1905 		if (pkt.critical) {
1906 			OPS_ERROR_1(&stream->errors,
1907 				OPS_E_PROTO_CRITICAL_SS_IGNORED,
1908 				"Critical signature subpacket ignored (%d)",
1909 				c & 0x7f);
1910 		}
1911 		if (!doread &&
1912 		    !limskip(subregion.length - 1, &subregion, stream)) {
1913 			return 0;
1914 		}
1915 		if (doread) {
1916 			__ops_parser_content_free(&pkt);
1917 		}
1918 		return 1;
1919 	}
1920 	if (doread && subregion.readc != subregion.length) {
1921 		OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
1922 			    "Unconsumed data (%d)",
1923 			    subregion.length - subregion.readc);
1924 		return 0;
1925 	}
1926 	CALLBACK(pkt.tag, &stream->cbinfo, &pkt);
1927 	return 1;
1928 }
1929 
1930 /**
1931  * \ingroup Core_ReadPackets
1932  * \brief Parse several signature subpackets.
1933  *
1934  * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set.
1935  * This function parses this length and then calls parse_one_sig_subpacket() for each subpacket until the
1936  * entire set is consumed.
1937  *
1938  * This function does not call the callback directly, parse_one_sig_subpacket() does for each subpacket.
1939  *
1940  * \param *ptag		Pointer to the Packet Tag.
1941  * \param *reader	Our reader
1942  * \param *cb		The callback
1943  * \return		1 on success, 0 on error
1944  *
1945  * \see RFC4880 5.2.3
1946  */
1947 static int
1948 parse_sig_subpkts(__ops_sig_t *sig,
1949 			   __ops_region_t *region,
1950 			   __ops_stream_t *stream)
1951 {
1952 	__ops_region_t	subregion;
1953 	__ops_packet_t	pkt;
1954 
1955 	__ops_init_subregion(&subregion, region);
1956 	if (!limread_scalar(&subregion.length, 2, region, stream)) {
1957 		return 0;
1958 	}
1959 
1960 	if (subregion.length > region->length) {
1961 		ERRP(&stream->cbinfo, pkt, "Subpacket set too long");
1962 	}
1963 
1964 	while (subregion.readc < subregion.length) {
1965 		if (!parse_one_sig_subpacket(sig, &subregion, stream)) {
1966 			return 0;
1967 		}
1968 	}
1969 
1970 	if (subregion.readc != subregion.length) {
1971 		if (!limskip(subregion.length - subregion.readc,
1972 				&subregion, stream)) {
1973 			ERRP(&stream->cbinfo, pkt,
1974 "parse_sig_subpkts: subpacket length read mismatch");
1975 		}
1976 		ERRP(&stream->cbinfo, pkt, "Subpacket length mismatch");
1977 	}
1978 	return 1;
1979 }
1980 
1981 /**
1982  * \ingroup Core_ReadPackets
1983  * \brief Parse a version 4 signature.
1984  *
1985  * This function parses a version 4 signature including all its hashed and unhashed subpackets.
1986  *
1987  * Once the signature packet has been parsed successfully, it is passed to the callback.
1988  *
1989  * \param *ptag		Pointer to the Packet Tag.
1990  * \param *reader	Our reader
1991  * \param *cb		The callback
1992  * \return		1 on success, 0 on error
1993  *
1994  * \see RFC4880 5.2.3
1995  */
1996 static int
1997 parse_v4_sig(__ops_region_t *region, __ops_stream_t *stream)
1998 {
1999 	unsigned char   c = 0x0;
2000 	__ops_packet_t pkt;
2001 
2002 	/* debug=1; */
2003 	if (__ops_get_debug_level(__FILE__)) {
2004 		fprintf(stderr, "\nparse_v4_sig\n");
2005 	}
2006 	/* clear signature */
2007 	(void) memset(&pkt.u.sig, 0x0, sizeof(pkt.u.sig));
2008 
2009 	/*
2010 	 * We need to hash the packet data from version through the hashed
2011 	 * subpacket data
2012 	 */
2013 
2014 	pkt.u.sig.v4_hashstart = stream->readinfo.alength - 1;
2015 
2016 	/* Set version,type,algorithms */
2017 
2018 	pkt.u.sig.info.version = OPS_V4;
2019 
2020 	if (!limread(&c, 1, region, stream)) {
2021 		return 0;
2022 	}
2023 	pkt.u.sig.info.type = c;
2024 	if (__ops_get_debug_level(__FILE__)) {
2025 		fprintf(stderr, "signature type=%d (%s)\n",
2026 			pkt.u.sig.info.type,
2027 			__ops_show_sig_type(pkt.u.sig.info.type));
2028 	}
2029 	/* XXX: check signature type */
2030 
2031 	if (!limread(&c, 1, region, stream)) {
2032 		return 0;
2033 	}
2034 	pkt.u.sig.info.key_alg = c;
2035 	/* XXX: check algorithm */
2036 	if (__ops_get_debug_level(__FILE__)) {
2037 		(void) fprintf(stderr, "key_alg=%d (%s)\n",
2038 			pkt.u.sig.info.key_alg,
2039 			__ops_show_pka(pkt.u.sig.info.key_alg));
2040 	}
2041 	if (!limread(&c, 1, region, stream)) {
2042 		return 0;
2043 	}
2044 	pkt.u.sig.info.hash_alg = c;
2045 	/* XXX: check algorithm */
2046 	if (__ops_get_debug_level(__FILE__)) {
2047 		fprintf(stderr, "hash_alg=%d %s\n",
2048 			pkt.u.sig.info.hash_alg,
2049 		  __ops_show_hash_alg(pkt.u.sig.info.hash_alg));
2050 	}
2051 	CALLBACK(OPS_PTAG_CT_SIGNATURE_HEADER, &stream->cbinfo, &pkt);
2052 
2053 	if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
2054 		return 0;
2055 	}
2056 
2057 	pkt.u.sig.info.v4_hashlen = stream->readinfo.alength
2058 					- pkt.u.sig.v4_hashstart;
2059 
2060 	/* copy hashed subpackets */
2061 	if (pkt.u.sig.info.v4_hashed) {
2062 		(void) free(pkt.u.sig.info.v4_hashed);
2063 	}
2064 	pkt.u.sig.info.v4_hashed = calloc(1, pkt.u.sig.info.v4_hashlen);
2065 
2066 	if (!stream->readinfo.accumulate) {
2067 		/* We must accumulate, else we can't check the signature */
2068 		fprintf(stderr, "*** ERROR: must set accumulate to 1\n");
2069 		return 0;
2070 	}
2071 	(void) memcpy(pkt.u.sig.info.v4_hashed,
2072 	       stream->readinfo.accumulated + pkt.u.sig.v4_hashstart,
2073 	       pkt.u.sig.info.v4_hashlen);
2074 
2075 	if (!parse_sig_subpkts(&pkt.u.sig, region, stream)) {
2076 		return 0;
2077 	}
2078 
2079 	if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
2080 		return 0;
2081 	}
2082 
2083 	switch (pkt.u.sig.info.key_alg) {
2084 	case OPS_PKA_RSA:
2085 		if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
2086 			return 0;
2087 		}
2088 		break;
2089 
2090 	case OPS_PKA_DSA:
2091 		if (!limread_mpi(&pkt.u.sig.info.sig.dsa.r, region, stream)) {
2092 			/*
2093 			 * usually if this fails, it just means we've reached
2094 			 * the end of the keyring
2095 			 */
2096 			if (__ops_get_debug_level(__FILE__)) {
2097 				(void) fprintf(stderr,
2098 				"Error reading DSA r field in signature");
2099 			}
2100 			return 0;
2101 		}
2102 		if (!limread_mpi(&pkt.u.sig.info.sig.dsa.s, region, stream)) {
2103 			ERRP(&stream->cbinfo, pkt,
2104 			"Error reading DSA s field in signature");
2105 		}
2106 		break;
2107 
2108 	case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
2109 		if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
2110 				stream) ||
2111 		    !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
2112 		    		stream)) {
2113 			return 0;
2114 		}
2115 		break;
2116 
2117 	case OPS_PKA_PRIVATE00:
2118 	case OPS_PKA_PRIVATE01:
2119 	case OPS_PKA_PRIVATE02:
2120 	case OPS_PKA_PRIVATE03:
2121 	case OPS_PKA_PRIVATE04:
2122 	case OPS_PKA_PRIVATE05:
2123 	case OPS_PKA_PRIVATE06:
2124 	case OPS_PKA_PRIVATE07:
2125 	case OPS_PKA_PRIVATE08:
2126 	case OPS_PKA_PRIVATE09:
2127 	case OPS_PKA_PRIVATE10:
2128 		if (!read_data(&pkt.u.sig.info.sig.unknown.data, region,
2129 				stream)) {
2130 			return 0;
2131 		}
2132 		break;
2133 
2134 	default:
2135 		OPS_ERROR_1(&stream->errors, OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG,
2136 			    "Bad v4 signature key algorithm (%s)",
2137 			    __ops_show_pka(pkt.u.sig.info.key_alg));
2138 		return 0;
2139 	}
2140 	if (region->readc != region->length) {
2141 		OPS_ERROR_1(&stream->errors, OPS_E_R_UNCONSUMED_DATA,
2142 			    "Unconsumed data (%d)",
2143 			    region->length - region->readc);
2144 		return 0;
2145 	}
2146 	CALLBACK(OPS_PTAG_CT_SIGNATURE_FOOTER, &stream->cbinfo, &pkt);
2147 	return 1;
2148 }
2149 
2150 /**
2151  * \ingroup Core_ReadPackets
2152  * \brief Parse a signature subpacket.
2153  *
2154  * This function calls the appropriate function to handle v3 or v4 signatures.
2155  *
2156  * Once the signature packet has been parsed successfully, it is passed to the callback.
2157  *
2158  * \param *ptag		Pointer to the Packet Tag.
2159  * \param *reader	Our reader
2160  * \param *cb		The callback
2161  * \return		1 on success, 0 on error
2162  */
2163 static int
2164 parse_sig(__ops_region_t *region, __ops_stream_t *stream)
2165 {
2166 	unsigned char   c = 0x0;
2167 	__ops_packet_t pkt;
2168 
2169 	if (region->readc != 0) {
2170 		/* We should not have read anything so far */
2171 		(void) fprintf(stderr, "parse_sig: bad length\n");
2172 		return 0;
2173 	}
2174 
2175 	(void) memset(&pkt, 0x0, sizeof(pkt));
2176 	if (!limread(&c, 1, region, stream)) {
2177 		return 0;
2178 	}
2179 	if (c == 2 || c == 3) {
2180 		return parse_v3_sig(region, stream);
2181 	}
2182 	if (c == 4) {
2183 		return parse_v4_sig(region, stream);
2184 	}
2185 	OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_SIGNATURE_VRSN,
2186 		    "Bad signature version (%d)", c);
2187 	return 0;
2188 }
2189 
2190 /**
2191  \ingroup Core_ReadPackets
2192  \brief Parse Compressed packet
2193 */
2194 static int
2195 parse_compressed(__ops_region_t *region, __ops_stream_t *stream)
2196 {
2197 	__ops_packet_t	pkt;
2198 	unsigned char		c = 0x0;
2199 
2200 	if (!limread(&c, 1, region, stream)) {
2201 		return 0;
2202 	}
2203 
2204 	pkt.u.compressed.type = c;
2205 
2206 	CALLBACK(OPS_PTAG_CT_COMPRESSED, &stream->cbinfo, &pkt);
2207 
2208 	/*
2209 	 * The content of a compressed data packet is more OpenPGP packets
2210 	 * once decompressed, so recursively handle them
2211 	 */
2212 
2213 	return __ops_decompress(region, stream, pkt.u.compressed.type);
2214 }
2215 
2216 /* XXX: this could be improved by sharing all hashes that are the */
2217 /* same, then duping them just before checking the signature. */
2218 static void
2219 parse_hash_init(__ops_stream_t *stream, __ops_hash_alg_t type,
2220 		    const unsigned char *keyid)
2221 {
2222 	__ops_hashtype_t *hash;
2223 
2224 	stream->hashes = realloc(stream->hashes,
2225 			      (stream->hashc + 1) * sizeof(*stream->hashes));
2226 	hash = &stream->hashes[stream->hashc++];
2227 
2228 	__ops_hash_any(&hash->hash, type);
2229 	hash->hash.init(&hash->hash);
2230 	(void) memcpy(hash->keyid, keyid, sizeof(hash->keyid));
2231 }
2232 
2233 /**
2234    \ingroup Core_ReadPackets
2235    \brief Parse a One Pass Signature packet
2236 */
2237 static int
2238 parse_one_pass(__ops_region_t * region, __ops_stream_t * stream)
2239 {
2240 	unsigned char   c = 0x0;
2241 	__ops_packet_t pkt;
2242 
2243 	if (!limread(&pkt.u.one_pass_sig.version, 1, region, stream)) {
2244 		return 0;
2245 	}
2246 	if (pkt.u.one_pass_sig.version != 3) {
2247 		OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN,
2248 			    "Bad one-pass signature version (%d)",
2249 			    pkt.u.one_pass_sig.version);
2250 		return 0;
2251 	}
2252 	if (!limread(&c, 1, region, stream)) {
2253 		return 0;
2254 	}
2255 	pkt.u.one_pass_sig.sig_type = c;
2256 
2257 	if (!limread(&c, 1, region, stream)) {
2258 		return 0;
2259 	}
2260 	pkt.u.one_pass_sig.hash_alg = c;
2261 
2262 	if (!limread(&c, 1, region, stream)) {
2263 		return 0;
2264 	}
2265 	pkt.u.one_pass_sig.key_alg = c;
2266 
2267 	if (!limread(pkt.u.one_pass_sig.keyid,
2268 			  sizeof(pkt.u.one_pass_sig.keyid), region, stream)) {
2269 		return 0;
2270 	}
2271 
2272 	if (!limread(&c, 1, region, stream)) {
2273 		return 0;
2274 	}
2275 	pkt.u.one_pass_sig.nested = !!c;
2276 	CALLBACK(OPS_PTAG_CT_1_PASS_SIG, &stream->cbinfo, &pkt);
2277 	/* XXX: we should, perhaps, let the app choose whether to hash or not */
2278 	parse_hash_init(stream, pkt.u.one_pass_sig.hash_alg,
2279 			    pkt.u.one_pass_sig.keyid);
2280 	return 1;
2281 }
2282 
2283 /**
2284  \ingroup Core_ReadPackets
2285  \brief Parse a Trust packet
2286 */
2287 static int
2288 parse_trust(__ops_region_t *region, __ops_stream_t *stream)
2289 {
2290 	__ops_packet_t pkt;
2291 
2292 	if (!read_data(&pkt.u.trust.data, region, stream)) {
2293 		return 0;
2294 	}
2295 	CALLBACK(OPS_PTAG_CT_TRUST, &stream->cbinfo, &pkt);
2296 	return 1;
2297 }
2298 
2299 static void
2300 parse_hash_data(__ops_stream_t *stream, const void *data,
2301 		    size_t length)
2302 {
2303 	size_t          n;
2304 
2305 	for (n = 0; n < stream->hashc; ++n) {
2306 		stream->hashes[n].hash.add(&stream->hashes[n].hash, data, length);
2307 	}
2308 }
2309 
2310 /**
2311    \ingroup Core_ReadPackets
2312    \brief Parse a Literal Data packet
2313 */
2314 static int
2315 parse_litdata(__ops_region_t *region, __ops_stream_t *stream)
2316 {
2317 	__ops_memory_t	*mem;
2318 	__ops_packet_t	 pkt;
2319 	unsigned char	 c = 0x0;
2320 
2321 	if (!limread(&c, 1, region, stream)) {
2322 		return 0;
2323 	}
2324 	pkt.u.litdata_header.format = c;
2325 	if (!limread(&c, 1, region, stream)) {
2326 		return 0;
2327 	}
2328 	if (!limread((unsigned char *)pkt.u.litdata_header.filename,
2329 			(unsigned)c, region, stream)) {
2330 		return 0;
2331 	}
2332 	pkt.u.litdata_header.filename[c] = '\0';
2333 	if (!limited_read_time(&pkt.u.litdata_header.mtime, region, stream)) {
2334 		return 0;
2335 	}
2336 	CALLBACK(OPS_PTAG_CT_LITDATA_HEADER, &stream->cbinfo, &pkt);
2337 	mem = pkt.u.litdata_body.mem = __ops_memory_new();
2338 	__ops_memory_init(pkt.u.litdata_body.mem,
2339 			(unsigned)(region->length * 1.01) + 12);
2340 	pkt.u.litdata_body.data = mem->buf;
2341 
2342 	while (region->readc < region->length) {
2343 		unsigned        readc = region->length - region->readc;
2344 
2345 		if (!limread(mem->buf, readc, region, stream)) {
2346 			return 0;
2347 		}
2348 		pkt.u.litdata_body.length = readc;
2349 		parse_hash_data(stream, pkt.u.litdata_body.data, region->length);
2350 		CALLBACK(OPS_PTAG_CT_LITDATA_BODY, &stream->cbinfo, &pkt);
2351 	}
2352 
2353 	/* XXX - get rid of mem here? */
2354 
2355 	return 1;
2356 }
2357 
2358 /**
2359  * \ingroup Core_Create
2360  *
2361  * __ops_seckey_free() frees the memory associated with "key". Note that
2362  * the key itself is not freed.
2363  *
2364  * \param key
2365  */
2366 
2367 void
2368 __ops_seckey_free(__ops_seckey_t *key)
2369 {
2370 	switch (key->pubkey.alg) {
2371 	case OPS_PKA_RSA:
2372 	case OPS_PKA_RSA_ENCRYPT_ONLY:
2373 	case OPS_PKA_RSA_SIGN_ONLY:
2374 		free_BN(&key->key.rsa.d);
2375 		free_BN(&key->key.rsa.p);
2376 		free_BN(&key->key.rsa.q);
2377 		free_BN(&key->key.rsa.u);
2378 		break;
2379 
2380 	case OPS_PKA_DSA:
2381 		free_BN(&key->key.dsa.x);
2382 		break;
2383 
2384 	default:
2385 		(void) fprintf(stderr,
2386 			"__ops_seckey_free: Unknown algorithm: %d (%s)\n",
2387 			key->pubkey.alg,
2388 			__ops_show_pka(key->pubkey.alg));
2389 	}
2390 	(void) free(key->checkhash);
2391 	__ops_pubkey_free(&key->pubkey);
2392 }
2393 
2394 static int
2395 consume_packet(__ops_region_t *region, __ops_stream_t *stream, unsigned warn)
2396 {
2397 	__ops_packet_t	pkt;
2398 	__ops_data_t	remainder;
2399 
2400 	if (region->indeterminate) {
2401 		ERRP(&stream->cbinfo, pkt,
2402 			"Can't consume indeterminate packets");
2403 	}
2404 
2405 	if (read_data(&remainder, region, stream)) {
2406 		/* now throw it away */
2407 		data_free(&remainder);
2408 		if (warn) {
2409 			OPS_ERROR(&stream->errors, OPS_E_P_PACKET_CONSUMED,
2410 				"Warning: packet consumer");
2411 		}
2412 		return 1;
2413 	}
2414 	OPS_ERROR(&stream->errors, OPS_E_P_PACKET_NOT_CONSUMED,
2415 			(warn) ? "Warning: Packet was not consumed" :
2416 				"Packet was not consumed");
2417 	return warn;
2418 }
2419 
2420 /**
2421  * \ingroup Core_ReadPackets
2422  * \brief Parse a secret key
2423  */
2424 static int
2425 parse_seckey(__ops_region_t *region, __ops_stream_t *stream)
2426 {
2427 	__ops_packet_t		pkt;
2428 	__ops_region_t		encregion;
2429 	__ops_region_t	       *saved_region = NULL;
2430 	unsigned char		c = 0x0;
2431 	__ops_crypt_t		decrypt;
2432 	__ops_hash_t		checkhash;
2433 	unsigned		blocksize;
2434 	unsigned		crypted;
2435 	int			ret = 1;
2436 
2437 	if (__ops_get_debug_level(__FILE__)) {
2438 		fprintf(stderr, "\n---------\nparse_seckey:\n");
2439 		fprintf(stderr,
2440 			"region length=%d, readc=%d, remainder=%d\n",
2441 			region->length, region->readc,
2442 			region->length - region->readc);
2443 	}
2444 	(void) memset(&pkt, 0x0, sizeof(pkt));
2445 	if (!parse_pubkey_data(&pkt.u.seckey.pubkey, region, stream)) {
2446 		return 0;
2447 	}
2448 	if (__ops_get_debug_level(__FILE__)) {
2449 		fprintf(stderr, "parse_seckey: public key parsed\n");
2450 		__ops_print_pubkey(&pkt.u.seckey.pubkey);
2451 	}
2452 	stream->reading_v3_secret = pkt.u.seckey.pubkey.version != OPS_V4;
2453 
2454 	if (!limread(&c, 1, region, stream)) {
2455 		return 0;
2456 	}
2457 	pkt.u.seckey.s2k_usage = c;
2458 
2459 	if (pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED ||
2460 	    pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) {
2461 		if (!limread(&c, 1, region, stream)) {
2462 			return 0;
2463 		}
2464 		pkt.u.seckey.alg = c;
2465 		if (!limread(&c, 1, region, stream)) {
2466 			return 0;
2467 		}
2468 		pkt.u.seckey.s2k_specifier = c;
2469 		switch (pkt.u.seckey.s2k_specifier) {
2470 		case OPS_S2KS_SIMPLE:
2471 		case OPS_S2KS_SALTED:
2472 		case OPS_S2KS_ITERATED_AND_SALTED:
2473 			break;
2474 		default:
2475 			(void) fprintf(stderr,
2476 				"parse_seckey: bad seckey\n");
2477 			return 0;
2478 		}
2479 		if (!limread(&c, 1, region, stream)) {
2480 			return 0;
2481 		}
2482 		pkt.u.seckey.hash_alg = c;
2483 		if (pkt.u.seckey.s2k_specifier != OPS_S2KS_SIMPLE &&
2484 		    !limread(pkt.u.seckey.salt, 8, region, stream)) {
2485 			return 0;
2486 		}
2487 		if (pkt.u.seckey.s2k_specifier ==
2488 					OPS_S2KS_ITERATED_AND_SALTED) {
2489 			if (!limread(&c, 1, region, stream)) {
2490 				return 0;
2491 			}
2492 			pkt.u.seckey.octetc =
2493 				(16 + ((unsigned)c & 15)) <<
2494 						(((unsigned)c >> 4) + 6);
2495 		}
2496 	} else if (pkt.u.seckey.s2k_usage != OPS_S2KU_NONE) {
2497 		/* this is V3 style, looks just like a V4 simple hash */
2498 		pkt.u.seckey.alg = c;
2499 		pkt.u.seckey.s2k_usage = OPS_S2KU_ENCRYPTED;
2500 		pkt.u.seckey.s2k_specifier = OPS_S2KS_SIMPLE;
2501 		pkt.u.seckey.hash_alg = OPS_HASH_MD5;
2502 	}
2503 	crypted = pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED ||
2504 		pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED;
2505 
2506 	if (crypted) {
2507 		__ops_packet_t	seckey;
2508 		unsigned char   key[OPS_MAX_KEY_SIZE + OPS_MAX_HASH_SIZE];
2509 		__ops_hash_t	hashes[(OPS_MAX_KEY_SIZE + OPS_MIN_HASH_SIZE - 1) / OPS_MIN_HASH_SIZE];
2510 		size_t          passlen;
2511 		char           *passphrase;
2512 		int             hashsize;
2513 		int             keysize;
2514 		int             n;
2515 
2516 		blocksize = __ops_block_size(pkt.u.seckey.alg);
2517 		if (blocksize == 0 || blocksize > OPS_MAX_BLOCK_SIZE) {
2518 			(void) fprintf(stderr,
2519 				"parse_seckey: bad blocksize\n");
2520 			return 0;
2521 		}
2522 
2523 		if (!limread(pkt.u.seckey.iv, blocksize, region, stream)) {
2524 			return 0;
2525 		}
2526 		(void) memset(&seckey, 0x0, sizeof(seckey));
2527 		passphrase = NULL;
2528 		seckey.u.skey_passphrase.passphrase = &passphrase;
2529 		seckey.u.skey_passphrase.seckey = &pkt.u.seckey;
2530 		CALLBACK(OPS_GET_PASSPHRASE, &stream->cbinfo, &seckey);
2531 		if (!passphrase) {
2532 			if (__ops_get_debug_level(__FILE__)) {
2533 				/* \todo make into proper error */
2534 				(void) fprintf(stderr,
2535 				"parse_seckey: can't get passphrase\n");
2536 			}
2537 			if (!consume_packet(region, stream, 0)) {
2538 				return 0;
2539 			}
2540 
2541 			CALLBACK(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY,
2542 				&stream->cbinfo, &pkt);
2543 
2544 			return 1;
2545 		}
2546 		keysize = __ops_key_size(pkt.u.seckey.alg);
2547 		if (keysize == 0 || keysize > OPS_MAX_KEY_SIZE) {
2548 			(void) fprintf(stderr,
2549 				"parse_seckey: bad keysize\n");
2550 			return 0;
2551 		}
2552 
2553 		hashsize = __ops_hash_size(pkt.u.seckey.hash_alg);
2554 		if (hashsize == 0 || hashsize > OPS_MAX_HASH_SIZE) {
2555 			(void) fprintf(stderr,
2556 				"parse_seckey: bad hashsize\n");
2557 			return 0;
2558 		}
2559 
2560 		for (n = 0; n * hashsize < keysize; ++n) {
2561 			int             i;
2562 
2563 			__ops_hash_any(&hashes[n],
2564 				pkt.u.seckey.hash_alg);
2565 			hashes[n].init(&hashes[n]);
2566 			/* preload hashes with zeroes... */
2567 			for (i = 0; i < n; ++i) {
2568 				hashes[n].add(&hashes[n],
2569 					(const unsigned char *) "", 1);
2570 			}
2571 		}
2572 		passlen = strlen(passphrase);
2573 		for (n = 0; n * hashsize < keysize; ++n) {
2574 			unsigned        i;
2575 
2576 			switch (pkt.u.seckey.s2k_specifier) {
2577 			case OPS_S2KS_SALTED:
2578 				hashes[n].add(&hashes[n],
2579 					pkt.u.seckey.salt,
2580 					OPS_SALT_SIZE);
2581 				/* FALLTHROUGH */
2582 			case OPS_S2KS_SIMPLE:
2583 				hashes[n].add(&hashes[n],
2584 					(unsigned char *) passphrase, passlen);
2585 				break;
2586 
2587 			case OPS_S2KS_ITERATED_AND_SALTED:
2588 				for (i = 0; i < pkt.u.seckey.octetc;
2589 						i += passlen + OPS_SALT_SIZE) {
2590 					unsigned	j;
2591 
2592 					j = passlen + OPS_SALT_SIZE;
2593 					if (i + j > pkt.u.seckey.octetc && i != 0) {
2594 						j = pkt.u.seckey.octetc - i;
2595 					}
2596 					hashes[n].add(&hashes[n],
2597 						pkt.u.seckey.salt,
2598 						(unsigned)(j > OPS_SALT_SIZE) ?
2599 							OPS_SALT_SIZE : j);
2600 					if (j > OPS_SALT_SIZE) {
2601 						hashes[n].add(&hashes[n],
2602 						(unsigned char *) passphrase,
2603 						j - OPS_SALT_SIZE);
2604 					}
2605 				}
2606 
2607 			}
2608 		}
2609 
2610 		for (n = 0; n * hashsize < keysize; ++n) {
2611 			int	r;
2612 
2613 			r = hashes[n].finish(&hashes[n], key + n * hashsize);
2614 			if (r != hashsize) {
2615 				(void) fprintf(stderr,
2616 					"parse_seckey: bad r\n");
2617 				return 0;
2618 			}
2619 		}
2620 
2621 		__ops_forget(passphrase, passlen);
2622 
2623 		__ops_crypt_any(&decrypt, pkt.u.seckey.alg);
2624 		if (__ops_get_debug_level(__FILE__)) {
2625 			unsigned int    i = 0;
2626 			fprintf(stderr, "\nREADING:\niv=");
2627 			for (i = 0;
2628 			     i < __ops_block_size(pkt.u.seckey.alg);
2629 			     i++) {
2630 				fprintf(stderr, "%02x ", pkt.u.seckey.iv[i]);
2631 			}
2632 			fprintf(stderr, "\n");
2633 			fprintf(stderr, "key=");
2634 			for (i = 0; i < CAST_KEY_LENGTH; i++) {
2635 				fprintf(stderr, "%02x ", key[i]);
2636 			}
2637 			fprintf(stderr, "\n");
2638 		}
2639 		decrypt.set_iv(&decrypt, pkt.u.seckey.iv);
2640 		decrypt.set_crypt_key(&decrypt, key);
2641 
2642 		/* now read encrypted data */
2643 
2644 		__ops_reader_push_decrypt(stream, &decrypt, region);
2645 
2646 		/*
2647 		 * Since all known encryption for PGP doesn't compress, we
2648 		 * can limit to the same length as the current region (for
2649 		 * now).
2650 		 */
2651 		__ops_init_subregion(&encregion, NULL);
2652 		encregion.length = region->length - region->readc;
2653 		if (pkt.u.seckey.pubkey.version != OPS_V4) {
2654 			encregion.length -= 2;
2655 		}
2656 		saved_region = region;
2657 		region = &encregion;
2658 	}
2659 	if (pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) {
2660 		pkt.u.seckey.checkhash = calloc(1, OPS_CHECKHASH_SIZE);
2661 		__ops_hash_sha1(&checkhash);
2662 		__ops_reader_push_hash(stream, &checkhash);
2663 	} else {
2664 		__ops_reader_push_sum16(stream);
2665 	}
2666 
2667 	switch (pkt.u.seckey.pubkey.alg) {
2668 	case OPS_PKA_RSA:
2669 	case OPS_PKA_RSA_ENCRYPT_ONLY:
2670 	case OPS_PKA_RSA_SIGN_ONLY:
2671 		if (!limread_mpi(&pkt.u.seckey.key.rsa.d, region, stream) ||
2672 		    !limread_mpi(&pkt.u.seckey.key.rsa.p, region, stream) ||
2673 		    !limread_mpi(&pkt.u.seckey.key.rsa.q, region, stream) ||
2674 		    !limread_mpi(&pkt.u.seckey.key.rsa.u, region, stream)) {
2675 			ret = 0;
2676 		}
2677 		break;
2678 
2679 	case OPS_PKA_DSA:
2680 		if (!limread_mpi(&pkt.u.seckey.key.dsa.x, region, stream)) {
2681 			ret = 0;
2682 		}
2683 		break;
2684 
2685 	default:
2686 		OPS_ERROR_2(&stream->errors,
2687 			OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2688 			"Unsupported Public Key algorithm %d (%s)",
2689 			pkt.u.seckey.pubkey.alg,
2690 			__ops_show_pka(pkt.u.seckey.pubkey.alg));
2691 		ret = 0;
2692 	}
2693 
2694 	if (__ops_get_debug_level(__FILE__)) {
2695 		(void) fprintf(stderr, "4 MPIs read\n");
2696 	}
2697 	stream->reading_v3_secret = 0;
2698 
2699 	if (pkt.u.seckey.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) {
2700 		unsigned char   hash[OPS_CHECKHASH_SIZE];
2701 
2702 		__ops_reader_pop_hash(stream);
2703 		checkhash.finish(&checkhash, hash);
2704 
2705 		if (crypted &&
2706 		    pkt.u.seckey.pubkey.version != OPS_V4) {
2707 			__ops_reader_pop_decrypt(stream);
2708 			region = saved_region;
2709 		}
2710 		if (ret) {
2711 			if (!limread(pkt.u.seckey.checkhash,
2712 				OPS_CHECKHASH_SIZE, region, stream)) {
2713 				return 0;
2714 			}
2715 
2716 			if (memcmp(hash, pkt.u.seckey.checkhash,
2717 					OPS_CHECKHASH_SIZE) != 0) {
2718 				ERRP(&stream->cbinfo, pkt,
2719 					"Hash mismatch in secret key");
2720 			}
2721 		}
2722 	} else {
2723 		unsigned short  sum;
2724 
2725 		sum = __ops_reader_pop_sum16(stream);
2726 		if (crypted &&
2727 		    pkt.u.seckey.pubkey.version != OPS_V4) {
2728 			__ops_reader_pop_decrypt(stream);
2729 			region = saved_region;
2730 		}
2731 		if (ret) {
2732 			if (!limread_scalar(&pkt.u.seckey.checksum, 2,
2733 					region, stream))
2734 				return 0;
2735 
2736 			if (sum != pkt.u.seckey.checksum) {
2737 				ERRP(&stream->cbinfo, pkt,
2738 					"Checksum mismatch in secret key");
2739 			}
2740 		}
2741 	}
2742 
2743 	if (crypted && pkt.u.seckey.pubkey.version == OPS_V4) {
2744 		__ops_reader_pop_decrypt(stream);
2745 	}
2746 	if (ret && region->readc != region->length) {
2747 		(void) fprintf(stderr, "parse_seckey: bad length\n");
2748 		return 0;
2749 	}
2750 	if (!ret) {
2751 		return 0;
2752 	}
2753 	CALLBACK(OPS_PTAG_CT_SECRET_KEY, &stream->cbinfo, &pkt);
2754 	if (__ops_get_debug_level(__FILE__)) {
2755 		(void) fprintf(stderr, "--- end of parse_seckey\n\n");
2756 	}
2757 	return 1;
2758 }
2759 
2760 /**
2761    \ingroup Core_ReadPackets
2762    \brief Parse a Public Key Session Key packet
2763 */
2764 static int
2765 parse_pk_sesskey(__ops_region_t *region,
2766 		     __ops_stream_t *stream)
2767 {
2768 	const __ops_seckey_t	*secret;
2769 	__ops_packet_t		 sesskey;
2770 	__ops_packet_t		 pkt;
2771 	unsigned char		*iv;
2772 	unsigned char	   	 c = 0x0;
2773 	unsigned char		 cs[2];
2774 	unsigned		 k;
2775 	BIGNUM			*enc_m;
2776 	int			 n;
2777 
2778 	/* Can't rely on it being CAST5 */
2779 	/* \todo FIXME RW */
2780 	/* const size_t sz_unencoded_m_buf=CAST_KEY_LENGTH+1+2; */
2781 	unsigned char		 unencoded_m_buf[1024];
2782 
2783 	if (!limread(&c, 1, region, stream)) {
2784 		return 0;
2785 	}
2786 	pkt.u.pk_sesskey.version = c;
2787 	if (pkt.u.pk_sesskey.version != OPS_PKSK_V3) {
2788 		OPS_ERROR_1(&stream->errors, OPS_E_PROTO_BAD_PKSK_VRSN,
2789 			"Bad public-key encrypted session key version (%d)",
2790 			    pkt.u.pk_sesskey.version);
2791 		return 0;
2792 	}
2793 	if (!limread(pkt.u.pk_sesskey.key_id,
2794 			  sizeof(pkt.u.pk_sesskey.key_id), region, stream)) {
2795 		return 0;
2796 	}
2797 	if (__ops_get_debug_level(__FILE__)) {
2798 		int             i;
2799 		int             x = sizeof(pkt.u.pk_sesskey.key_id);
2800 
2801 		printf("session key: public key id: x=%d\n", x);
2802 		for (i = 0; i < x; i++) {
2803 			printf("%2x ", pkt.u.pk_sesskey.key_id[i]);
2804 		}
2805 		printf("\n");
2806 	}
2807 	if (!limread(&c, 1, region, stream)) {
2808 		return 0;
2809 	}
2810 	pkt.u.pk_sesskey.alg = c;
2811 	switch (pkt.u.pk_sesskey.alg) {
2812 	case OPS_PKA_RSA:
2813 		if (!limread_mpi(&pkt.u.pk_sesskey.params.rsa.encrypted_m,
2814 				      region, stream)) {
2815 			return 0;
2816 		}
2817 		enc_m = pkt.u.pk_sesskey.params.rsa.encrypted_m;
2818 		break;
2819 
2820 	case OPS_PKA_ELGAMAL:
2821 		if (!limread_mpi(&pkt.u.pk_sesskey.params.elgamal.g_to_k,
2822 				      region, stream) ||
2823 		    !limread_mpi(
2824 			&pkt.u.pk_sesskey.params.elgamal.encrypted_m,
2825 					 region, stream)) {
2826 			return 0;
2827 		}
2828 		enc_m = pkt.u.pk_sesskey.params.elgamal.encrypted_m;
2829 		break;
2830 
2831 	default:
2832 		OPS_ERROR_1(&stream->errors,
2833 			OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,
2834 			"Unknown public key algorithm in session key (%s)",
2835 			__ops_show_pka(pkt.u.pk_sesskey.alg));
2836 		return 0;
2837 	}
2838 
2839 	(void) memset(&sesskey, 0x0, sizeof(sesskey));
2840 	secret = NULL;
2841 	sesskey.u.get_seckey.seckey = &secret;
2842 	sesskey.u.get_seckey.pk_sesskey = &pkt.u.pk_sesskey;
2843 
2844 	CALLBACK(OPS_GET_SECKEY, &stream->cbinfo, &sesskey);
2845 
2846 	if (!secret) {
2847 		CALLBACK(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbinfo,
2848 			&pkt);
2849 		return 1;
2850 	}
2851 	n = __ops_decrypt_decode_mpi(unencoded_m_buf, sizeof(unencoded_m_buf),
2852 			enc_m, secret);
2853 	if (n < 1) {
2854 		ERRP(&stream->cbinfo, pkt, "decrypted message too short");
2855 		return 0;
2856 	}
2857 
2858 	/* PKA */
2859 	pkt.u.pk_sesskey.symm_alg = unencoded_m_buf[0];
2860 
2861 	if (!__ops_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) {
2862 		/* ERR1P */
2863 		OPS_ERROR_1(&stream->errors, OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG,
2864 			    "Symmetric algorithm %s not supported",
2865 			    __ops_show_symm_alg(
2866 				pkt.u.pk_sesskey.symm_alg));
2867 		return 0;
2868 	}
2869 	k = __ops_key_size(pkt.u.pk_sesskey.symm_alg);
2870 
2871 	if ((unsigned) n != k + 3) {
2872 		OPS_ERROR_2(&stream->errors, OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN,
2873 		      "decrypted message wrong length (got %d expected %d)",
2874 			    n, k + 3);
2875 		return 0;
2876 	}
2877 	if (k > sizeof(pkt.u.pk_sesskey.key)) {
2878 		(void) fprintf(stderr, "parse_pk_sesskey: bad keylength\n");
2879 		return 0;
2880 	}
2881 
2882 	(void) memcpy(pkt.u.pk_sesskey.key, unencoded_m_buf + 1, k);
2883 
2884 	if (__ops_get_debug_level(__FILE__)) {
2885 		unsigned int    j;
2886 		printf("session key recovered (len=%d):\n", k);
2887 		for (j = 0; j < k; j++)
2888 			printf("%2x ", pkt.u.pk_sesskey.key[j]);
2889 		printf("\n");
2890 	}
2891 	pkt.u.pk_sesskey.checksum = unencoded_m_buf[k + 1] +
2892 			(unencoded_m_buf[k + 2] << 8);
2893 	if (__ops_get_debug_level(__FILE__)) {
2894 		printf("session key checksum: %2x %2x\n",
2895 			unencoded_m_buf[k + 1], unencoded_m_buf[k + 2]);
2896 	}
2897 
2898 	/* Check checksum */
2899 	__ops_calc_sesskey_checksum(&pkt.u.pk_sesskey, &cs[0]);
2900 	if (unencoded_m_buf[k + 1] != cs[0] ||
2901 	    unencoded_m_buf[k + 2] != cs[1]) {
2902 		OPS_ERROR_4(&stream->errors, OPS_E_PROTO_BAD_SK_CHECKSUM,
2903 		"Session key checksum wrong: expected %2x %2x, got %2x %2x",
2904 		cs[0], cs[1], unencoded_m_buf[k + 1],
2905 		unencoded_m_buf[k + 2]);
2906 		return 0;
2907 	}
2908 	/* all is well */
2909 	CALLBACK(OPS_PTAG_CT_PK_SESSION_KEY, &stream->cbinfo, &pkt);
2910 
2911 	__ops_crypt_any(&stream->decrypt, pkt.u.pk_sesskey.symm_alg);
2912 	iv = calloc(1, stream->decrypt.blocksize);
2913 	stream->decrypt.set_iv(&stream->decrypt, iv);
2914 	stream->decrypt.set_crypt_key(&stream->decrypt, pkt.u.pk_sesskey.key);
2915 	__ops_encrypt_init(&stream->decrypt);
2916 	(void) free(iv);
2917 	return 1;
2918 }
2919 
2920 static int
2921 __ops_decrypt_se_data(__ops_content_tag_t tag, __ops_region_t *region,
2922 		    __ops_stream_t *stream)
2923 {
2924 	__ops_crypt_t	*decrypt;
2925 	const int	 printerrors = 1;
2926 	int		 r = 1;
2927 
2928 	decrypt = __ops_get_decrypt(stream);
2929 	if (decrypt) {
2930 		unsigned char   buf[OPS_MAX_BLOCK_SIZE + 2] = "";
2931 		size_t          b = decrypt->blocksize;
2932 		/* __ops_packet_t pkt; */
2933 		__ops_region_t    encregion;
2934 
2935 
2936 		__ops_reader_push_decrypt(stream, decrypt, region);
2937 
2938 		__ops_init_subregion(&encregion, NULL);
2939 		encregion.length = b + 2;
2940 
2941 		if (!exact_limread(buf, b + 2, &encregion, stream)) {
2942 			return 0;
2943 		}
2944 		if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) {
2945 			__ops_reader_pop_decrypt(stream);
2946 			OPS_ERROR_4(&stream->errors,
2947 				OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT,
2948 				"Bad symmetric decrypt (%02x%02x vs %02x%02x)",
2949 				buf[b - 2], buf[b - 1], buf[b], buf[b + 1]);
2950 			return 0;
2951 		}
2952 		if (tag == OPS_PTAG_CT_SE_DATA_BODY) {
2953 			decrypt->decrypt_resync(decrypt);
2954 			decrypt->block_encrypt(decrypt, decrypt->civ,
2955 					decrypt->civ);
2956 		}
2957 		r = __ops_parse(stream, !printerrors);
2958 
2959 		__ops_reader_pop_decrypt(stream);
2960 	} else {
2961 		__ops_packet_t pkt;
2962 
2963 		while (region->readc < region->length) {
2964 			unsigned        len;
2965 
2966 			len = region->length - region->readc;
2967 			if (len > sizeof(pkt.u.se_data_body.data))
2968 				len = sizeof(pkt.u.se_data_body.data);
2969 
2970 			if (!limread(pkt.u.se_data_body.data, len,
2971 					region, stream)) {
2972 				return 0;
2973 			}
2974 			pkt.u.se_data_body.length = len;
2975 			CALLBACK(tag, &stream->cbinfo, &pkt);
2976 		}
2977 	}
2978 
2979 	return r;
2980 }
2981 
2982 static int
2983 __ops_decrypt_se_ip_data(__ops_content_tag_t tag, __ops_region_t *region,
2984 		       __ops_stream_t *stream)
2985 {
2986 	__ops_crypt_t	*decrypt;
2987 	const int	 printerrors = 1;
2988 	int		 r = 1;
2989 
2990 	decrypt = __ops_get_decrypt(stream);
2991 	if (decrypt) {
2992 		__ops_reader_push_decrypt(stream, decrypt, region);
2993 		__ops_reader_push_se_ip_data(stream, decrypt, region);
2994 
2995 		r = __ops_parse(stream, !printerrors);
2996 
2997 		__ops_reader_pop_se_ip_data(stream);
2998 		__ops_reader_pop_decrypt(stream);
2999 	} else {
3000 		__ops_packet_t pkt;
3001 
3002 		while (region->readc < region->length) {
3003 			unsigned        len;
3004 
3005 			len = region->length - region->readc;
3006 			if (len > sizeof(pkt.u.se_data_body.data)) {
3007 				len = sizeof(pkt.u.se_data_body.data);
3008 			}
3009 
3010 			if (!limread(pkt.u.se_data_body.data,
3011 					len, region, stream)) {
3012 				return 0;
3013 			}
3014 
3015 			pkt.u.se_data_body.length = len;
3016 
3017 			CALLBACK(tag, &stream->cbinfo, &pkt);
3018 		}
3019 	}
3020 
3021 	return r;
3022 }
3023 
3024 /**
3025    \ingroup Core_ReadPackets
3026    \brief Read a Symmetrically Encrypted packet
3027 */
3028 static int
3029 parse_se_data(__ops_region_t *region, __ops_stream_t *stream)
3030 {
3031 	__ops_packet_t pkt;
3032 
3033 	/* there's no info to go with this, so just announce it */
3034 	CALLBACK(OPS_PTAG_CT_SE_DATA_HEADER, &stream->cbinfo, &pkt);
3035 
3036 	/*
3037 	 * The content of an encrypted data packet is more OpenPGP packets
3038 	 * once decrypted, so recursively handle them
3039 	 */
3040 	return __ops_decrypt_se_data(OPS_PTAG_CT_SE_DATA_BODY, region, stream);
3041 }
3042 
3043 /**
3044    \ingroup Core_ReadPackets
3045    \brief Read a Symmetrically Encrypted Integrity Protected packet
3046 */
3047 static int
3048 parse_se_ip_data(__ops_region_t *region, __ops_stream_t *stream)
3049 {
3050 	__ops_packet_t	pkt;
3051 	unsigned char   c = 0x0;
3052 
3053 	if (!limread(&c, 1, region, stream)) {
3054 		return 0;
3055 	}
3056 	pkt.u.se_ip_data_header.version = c;
3057 
3058 	if (pkt.u.se_ip_data_header.version != OPS_SE_IP_V1) {
3059 		(void) fprintf(stderr, "parse_se_ip_data: bad version\n");
3060 		return 0;
3061 	}
3062 
3063 	/*
3064 	 * The content of an encrypted data packet is more OpenPGP packets
3065 	 * once decrypted, so recursively handle them
3066 	 */
3067 	return __ops_decrypt_se_ip_data(OPS_PTAG_CT_SE_IP_DATA_BODY, region,
3068 			stream);
3069 }
3070 
3071 /**
3072    \ingroup Core_ReadPackets
3073    \brief Read a MDC packet
3074 */
3075 static int
3076 parse_mdc(__ops_region_t *region, __ops_stream_t *stream)
3077 {
3078 	__ops_packet_t pkt;
3079 
3080 	pkt.u.mdc.length = OPS_SHA1_HASH_SIZE;
3081 	pkt.u.mdc.data = calloc(1, OPS_SHA1_HASH_SIZE);
3082 	if (!limread(pkt.u.mdc.data, OPS_SHA1_HASH_SIZE, region, stream)) {
3083 		return 0;
3084 	}
3085 	CALLBACK(OPS_PTAG_CT_MDC, &stream->cbinfo, &pkt);
3086 	(void) free(pkt.u.mdc.data);
3087 	return 1;
3088 }
3089 
3090 /**
3091  * \ingroup Core_ReadPackets
3092  * \brief Parse one packet.
3093  *
3094  * This function parses the packet tag.  It computes the value of the
3095  * content tag and then calls the appropriate function to handle the
3096  * content.
3097  *
3098  * \param *stream	How to parse
3099  * \param *pktlen	On return, will contain number of bytes in packet
3100  * \return 1 on success, 0 on error, -1 on EOF */
3101 static int
3102 __ops_parse_packet(__ops_stream_t *stream, unsigned long *pktlen)
3103 {
3104 	__ops_packet_t	pkt;
3105 	__ops_region_t	region;
3106 	unsigned char	ptag;
3107 	unsigned	indeterminate = 0;
3108 	int		ret;
3109 
3110 	pkt.u.ptag.position = stream->readinfo.position;
3111 
3112 	ret = base_read(&ptag, 1, stream);
3113 
3114 	if (__ops_get_debug_level(__FILE__)) {
3115 		(void) fprintf(stderr,
3116 			"__ops_parse_packet: base_read returned %d\n",
3117 			ret);
3118 	}
3119 
3120 	/* errors in the base read are effectively EOF. */
3121 	if (ret <= 0) {
3122 		return -1;
3123 	}
3124 
3125 	*pktlen = 0;
3126 
3127 	if (!(ptag & OPS_PTAG_ALWAYS_SET)) {
3128 		pkt.u.error.error = "Format error (ptag bit not set)";
3129 		CALLBACK(OPS_PARSER_ERROR, &stream->cbinfo, &pkt);
3130 		return 0;
3131 	}
3132 	pkt.u.ptag.new_format = !!(ptag & OPS_PTAG_NEW_FORMAT);
3133 	if (pkt.u.ptag.new_format) {
3134 		pkt.u.ptag.type = ptag & OPS_PTAG_NF_CONTENT_TAG_MASK;
3135 		pkt.u.ptag.length_type = 0;
3136 		if (!read_new_length(&pkt.u.ptag.length, stream)) {
3137 			return 0;
3138 		}
3139 	} else {
3140 		unsigned   rb;
3141 
3142 		rb = 0;
3143 		pkt.u.ptag.type = ((unsigned)ptag &
3144 				OPS_PTAG_OF_CONTENT_TAG_MASK)
3145 			>> OPS_PTAG_OF_CONTENT_TAG_SHIFT;
3146 		pkt.u.ptag.length_type = ptag & OPS_PTAG_OF_LENGTH_TYPE_MASK;
3147 		switch (pkt.u.ptag.length_type) {
3148 		case OPS_PTAG_OLD_LEN_1:
3149 			rb = _read_scalar(&pkt.u.ptag.length, 1, stream);
3150 			break;
3151 
3152 		case OPS_PTAG_OLD_LEN_2:
3153 			rb = _read_scalar(&pkt.u.ptag.length, 2, stream);
3154 			break;
3155 
3156 		case OPS_PTAG_OLD_LEN_4:
3157 			rb = _read_scalar(&pkt.u.ptag.length, 4, stream);
3158 			break;
3159 
3160 		case OPS_PTAG_OLD_LEN_INDETERMINATE:
3161 			pkt.u.ptag.length = 0;
3162 			indeterminate = 1;
3163 			rb = 1;
3164 			break;
3165 		}
3166 		if (!rb) {
3167 			return 0;
3168 		}
3169 	}
3170 
3171 	CALLBACK(OPS_PARSER_PTAG, &stream->cbinfo, &pkt);
3172 
3173 	__ops_init_subregion(&region, NULL);
3174 	region.length = pkt.u.ptag.length;
3175 	region.indeterminate = indeterminate;
3176 	if (__ops_get_debug_level(__FILE__)) {
3177 		(void) fprintf(stderr, "__ops_parse_packet: type %d\n",
3178 			       pkt.u.ptag.type);
3179 	}
3180 	switch (pkt.u.ptag.type) {
3181 	case OPS_PTAG_CT_SIGNATURE:
3182 		ret = parse_sig(&region, stream);
3183 		break;
3184 
3185 	case OPS_PTAG_CT_PUBLIC_KEY:
3186 	case OPS_PTAG_CT_PUBLIC_SUBKEY:
3187 		ret = parse_pubkey(pkt.u.ptag.type, &region, stream);
3188 		break;
3189 
3190 	case OPS_PTAG_CT_TRUST:
3191 		ret = parse_trust(&region, stream);
3192 		break;
3193 
3194 	case OPS_PTAG_CT_USER_ID:
3195 		ret = parse_userid(&region, stream);
3196 		break;
3197 
3198 	case OPS_PTAG_CT_COMPRESSED:
3199 		ret = parse_compressed(&region, stream);
3200 		break;
3201 
3202 	case OPS_PTAG_CT_1_PASS_SIG:
3203 		ret = parse_one_pass(&region, stream);
3204 		break;
3205 
3206 	case OPS_PTAG_CT_LITDATA:
3207 		ret = parse_litdata(&region, stream);
3208 		break;
3209 
3210 	case OPS_PTAG_CT_USER_ATTR:
3211 		ret = parse_userattr(&region, stream);
3212 		break;
3213 
3214 	case OPS_PTAG_CT_SECRET_KEY:
3215 		ret = parse_seckey(&region, stream);
3216 		break;
3217 
3218 	case OPS_PTAG_CT_SECRET_SUBKEY:
3219 		ret = parse_seckey(&region, stream);
3220 		break;
3221 
3222 	case OPS_PTAG_CT_PK_SESSION_KEY:
3223 		ret = parse_pk_sesskey(&region, stream);
3224 		break;
3225 
3226 	case OPS_PTAG_CT_SE_DATA:
3227 		ret = parse_se_data(&region, stream);
3228 		break;
3229 
3230 	case OPS_PTAG_CT_SE_IP_DATA:
3231 		ret = parse_se_ip_data(&region, stream);
3232 		break;
3233 
3234 	case OPS_PTAG_CT_MDC:
3235 		ret = parse_mdc(&region, stream);
3236 		break;
3237 
3238 	default:
3239 		OPS_ERROR_1(&stream->errors, OPS_E_P_UNKNOWN_TAG,
3240 			    "Unknown content tag 0x%x",
3241 			    pkt.u.ptag.type);
3242 		ret = 0;
3243 	}
3244 
3245 	/* Ensure that the entire packet has been consumed */
3246 
3247 	if (region.length != region.readc && !region.indeterminate) {
3248 		if (!consume_packet(&region, stream, 0)) {
3249 			ret = -1;
3250 		}
3251 	}
3252 
3253 	/* also consume it if there's been an error? */
3254 	/* \todo decide what to do about an error on an */
3255 	/* indeterminate packet */
3256 	if (ret == 0) {
3257 		if (!consume_packet(&region, stream, 0)) {
3258 			ret = -1;
3259 		}
3260 	}
3261 	/* set pktlen */
3262 
3263 	*pktlen = stream->readinfo.alength;
3264 
3265 	/* do callback on entire packet, if desired and there was no error */
3266 
3267 	if (ret > 0 && stream->readinfo.accumulate) {
3268 		pkt.u.packet.length = stream->readinfo.alength;
3269 		pkt.u.packet.raw = stream->readinfo.accumulated;
3270 		stream->readinfo.accumulated = NULL;
3271 		stream->readinfo.asize = 0;
3272 		CALLBACK(OPS_PARSER_PACKET_END, &stream->cbinfo, &pkt);
3273 	}
3274 	stream->readinfo.alength = 0;
3275 
3276 	return (ret < 0) ? -1 : (ret) ? 1 : 0;
3277 }
3278 
3279 /**
3280  * \ingroup Core_ReadPackets
3281  *
3282  * \brief Parse packets from an input stream until EOF or error.
3283  *
3284  * \details Setup the necessary parsing configuration in "stream"
3285  * before calling __ops_parse().
3286  *
3287  * That information includes :
3288  *
3289  * - a "reader" function to be used to get the data to be parsed
3290  *
3291  * - a "callback" function to be called when this library has identified
3292  * a parseable object within the data
3293  *
3294  * - whether the calling function wants the signature subpackets
3295  * returned raw, parsed or not at all.
3296  *
3297  * After returning, stream->errors holds any errors encountered while parsing.
3298  *
3299  * \param stream	Parsing configuration
3300  * \return		1 on success in all packets, 0 on error in any packet
3301  *
3302  * \sa CoreAPI Overview
3303  *
3304  * \sa __ops_print_errors()
3305  *
3306  */
3307 
3308 int
3309 __ops_parse(__ops_stream_t *stream, int perrors)
3310 {
3311 	unsigned long   pktlen;
3312 	int             r;
3313 
3314 	do {
3315 		r = __ops_parse_packet(stream, &pktlen);
3316 	} while (r != -1);
3317 	if (perrors) {
3318 		__ops_print_errors(stream->errors);
3319 	}
3320 	return (stream->errors == NULL);
3321 }
3322 
3323 /**
3324  * \ingroup Core_ReadPackets
3325  *
3326  * \brief Specifies whether one or more signature
3327  * subpacket types should be returned parsed; or raw; or ignored.
3328  *
3329  * \param	stream	Pointer to previously allocated structure
3330  * \param	tag	Packet tag. OPS_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag
3331  * \param	type	Parse type
3332  * \todo Make all packet types optional, not just subpackets */
3333 void
3334 __ops_parse_options(__ops_stream_t *stream,
3335 		  __ops_content_tag_t tag,
3336 		  __ops_parse_type_t type)
3337 {
3338 	int             t8, t7;
3339 
3340 	if (tag == OPS_PTAG_SS_ALL) {
3341 		int             n;
3342 
3343 		for (n = 0; n < 256; ++n) {
3344 			__ops_parse_options(stream,
3345 				OPS_PTAG_SIG_SUBPKT_BASE + n,
3346 				type);
3347 		}
3348 		return;
3349 	}
3350 	if (tag < OPS_PTAG_SIG_SUBPKT_BASE ||
3351 	    tag > OPS_PTAG_SIG_SUBPKT_BASE + NTAGS - 1) {
3352 		(void) fprintf(stderr, "__ops_parse_options: bad tag\n");
3353 		return;
3354 	}
3355 	t8 = (tag - OPS_PTAG_SIG_SUBPKT_BASE) / 8;
3356 	t7 = 1 << ((tag - OPS_PTAG_SIG_SUBPKT_BASE) & 7);
3357 	switch (type) {
3358 	case OPS_PARSE_RAW:
3359 		stream->ss_raw[t8] |= t7;
3360 		stream->ss_parsed[t8] &= ~t7;
3361 		break;
3362 
3363 	case OPS_PARSE_PARSED:
3364 		stream->ss_raw[t8] &= ~t7;
3365 		stream->ss_parsed[t8] |= t7;
3366 		break;
3367 
3368 	case OPS_PARSE_IGNORE:
3369 		stream->ss_raw[t8] &= ~t7;
3370 		stream->ss_parsed[t8] &= ~t7;
3371 		break;
3372 	}
3373 }
3374 
3375 /**
3376 \ingroup Core_ReadPackets
3377 \brief Free __ops_stream_t struct and its contents
3378 */
3379 void
3380 __ops_stream_delete(__ops_stream_t *stream)
3381 {
3382 	__ops_cbdata_t	*cbinfo;
3383 	__ops_cbdata_t	*next;
3384 
3385 	for (cbinfo = stream->cbinfo.next; cbinfo; cbinfo = next) {
3386 		next = cbinfo->next;
3387 		(void) free(cbinfo);
3388 	}
3389 	if (stream->readinfo.destroyer) {
3390 		stream->readinfo.destroyer(&stream->readinfo);
3391 	}
3392 	__ops_free_errors(stream->errors);
3393 	if (stream->readinfo.accumulated) {
3394 		(void) free(stream->readinfo.accumulated);
3395 	}
3396 	(void) free(stream);
3397 }
3398 
3399 /**
3400 \ingroup Core_ReadPackets
3401 \brief Returns the parse_info's reader_info
3402 \return Pointer to the reader_info inside the parse_info
3403 */
3404 __ops_reader_t *
3405 __ops_readinfo(__ops_stream_t *stream)
3406 {
3407 	return &stream->readinfo;
3408 }
3409 
3410 /**
3411 \ingroup Core_ReadPackets
3412 \brief Sets the parse_info's callback
3413 This is used when adding the first callback in a stack of callbacks.
3414 \sa __ops_callback_push()
3415 */
3416 
3417 void
3418 __ops_set_callback(__ops_stream_t *stream, __ops_cbfunc_t *cb, void *arg)
3419 {
3420 	stream->cbinfo.cbfunc = cb;
3421 	stream->cbinfo.arg = arg;
3422 	stream->cbinfo.errors = &stream->errors;
3423 }
3424 
3425 /**
3426 \ingroup Core_ReadPackets
3427 \brief Adds a further callback to a stack of callbacks
3428 \sa __ops_set_callback()
3429 */
3430 void
3431 __ops_callback_push(__ops_stream_t *stream, __ops_cbfunc_t *cb, void *arg)
3432 {
3433 	__ops_cbdata_t *cbinfo = calloc(1, sizeof(*cbinfo));
3434 
3435 	(void) memcpy(cbinfo, &stream->cbinfo, sizeof(*cbinfo));
3436 	cbinfo->io = stream->io;
3437 	stream->cbinfo.next = cbinfo;
3438 	__ops_set_callback(stream, cb, arg);
3439 }
3440 
3441 /**
3442 \ingroup Core_ReadPackets
3443 \brief Returns callback's arg
3444 */
3445 void *
3446 __ops_callback_arg(__ops_cbdata_t *cbinfo)
3447 {
3448 	return cbinfo->arg;
3449 }
3450 
3451 /**
3452 \ingroup Core_ReadPackets
3453 \brief Returns callback's errors
3454 */
3455 void *
3456 __ops_callback_errors(__ops_cbdata_t *cbinfo)
3457 {
3458 	return cbinfo->errors;
3459 }
3460 
3461 /**
3462 \ingroup Core_ReadPackets
3463 \brief Calls the parse_cb_info's callback if present
3464 \return Return value from callback, if present; else OPS_FINISHED
3465 */
3466 __ops_cb_ret_t
3467 __ops_callback(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo)
3468 {
3469 	return (cbinfo->cbfunc) ? cbinfo->cbfunc(pkt, cbinfo) : OPS_FINISHED;
3470 }
3471 
3472 /**
3473 \ingroup Core_ReadPackets
3474 \brief Calls the next callback  in the stack
3475 \return Return value from callback
3476 */
3477 __ops_cb_ret_t
3478 __ops_stacked_callback(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo)
3479 {
3480 	return __ops_callback(pkt, cbinfo->next);
3481 }
3482 
3483 /**
3484 \ingroup Core_ReadPackets
3485 \brief Returns the parse_info's errors
3486 \return parse_info's errors
3487 */
3488 __ops_error_t    *
3489 __ops_stream_get_errors(__ops_stream_t *stream)
3490 {
3491 	return stream->errors;
3492 }
3493 
3494 __ops_crypt_t    *
3495 __ops_get_decrypt(__ops_stream_t *stream)
3496 {
3497 	return (stream->decrypt.alg) ? &stream->decrypt : NULL;
3498 }
3499