xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/reader.c (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
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 #include "config.h"
50 
51 #ifdef HAVE_SYS_CDEFS_H
52 #include <sys/cdefs.h>
53 #endif
54 
55 #if defined(__NetBSD__)
56 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
57 __RCSID("$NetBSD: reader.c,v 1.48 2011/01/01 22:29:00 agc Exp $");
58 #endif
59 
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 
63 #ifdef HAVE_SYS_MMAN_H
64 #include <sys/mman.h>
65 #endif
66 
67 #ifdef HAVE_SYS_PARAM_H
68 #include <sys/param.h>
69 #endif
70 
71 #ifdef HAVE_FCNTL_H
72 #include <fcntl.h>
73 #endif
74 
75 #ifdef HAVE_UNISTD_H
76 #include <unistd.h>
77 #endif
78 
79 #ifdef HAVE_DIRECT_H
80 #include <direct.h>
81 #endif
82 
83 #ifdef HAVE_INTTYPES_H
84 #include <inttypes.h>
85 #endif
86 
87 #ifdef HAVE_OPENSSL_IDEA_H
88 #include <openssl/cast.h>
89 #endif
90 
91 #ifdef HAVE_OPENSSL_IDEA_H
92 #include <openssl/idea.h>
93 #endif
94 
95 #ifdef HAVE_OPENSSL_AES_H
96 #include <openssl/aes.h>
97 #endif
98 
99 #ifdef HAVE_OPENSSL_DES_H
100 #include <openssl/des.h>
101 #endif
102 
103 #include <string.h>
104 #include <stdlib.h>
105 #include <stdio.h>
106 
107 #ifdef HAVE_TERMIOS_H
108 #include <termios.h>
109 #endif
110 
111 #ifdef HAVE_ERRNO_H
112 #include <errno.h>
113 #endif
114 
115 #ifdef HAVE_UNISTD_H
116 #include <unistd.h>
117 #endif
118 
119 #ifdef HAVE_LIMITS_H
120 #include <limits.h>
121 #endif
122 
123 #include "errors.h"
124 #include "crypto.h"
125 #include "create.h"
126 #include "signature.h"
127 #include "packet.h"
128 #include "packet-parse.h"
129 #include "packet-show.h"
130 #include "packet.h"
131 #include "keyring.h"
132 #include "readerwriter.h"
133 #include "netpgpsdk.h"
134 #include "netpgpdefs.h"
135 #include "netpgpdigest.h"
136 
137 /* data from partial blocks is queued up in virtual block in stream */
138 static int
139 read_partial_data(pgp_stream_t *stream, void *dest, size_t length)
140 {
141 	unsigned	n;
142 
143 	if (pgp_get_debug_level(__FILE__)) {
144 		(void) fprintf(stderr, "fd_reader: coalesced data, off %d\n",
145 				stream->virtualoff);
146 	}
147 	n = MIN(stream->virtualc - stream->virtualoff, (unsigned)length);
148 	(void) memcpy(dest, &stream->virtualpkt[stream->virtualoff], n);
149 	stream->virtualoff += n;
150 	if (stream->virtualoff == stream->virtualc) {
151 		free(stream->virtualpkt);
152 		stream->virtualpkt = NULL;
153 		stream->virtualc = stream->virtualoff = 0;
154 	}
155 	return (int)n;
156 }
157 
158 /* get a pass phrase from the user */
159 int
160 pgp_getpassphrase(void *in, char *phrase, size_t size)
161 {
162 	char	*p;
163 
164 	if (in == NULL) {
165 		while ((p = getpass("netpgp passphrase: ")) == NULL) {
166 		}
167 		(void) snprintf(phrase, size, "%s", p);
168 	} else {
169 		if (fgets(phrase, (int)size, in) == NULL) {
170 			return 0;
171 		}
172 		phrase[strlen(phrase) - 1] = 0x0;
173 	}
174 	return 1;
175 }
176 
177 /**
178  * \ingroup Internal_Readers_Generic
179  * \brief Starts reader stack
180  * \param stream Parse settings
181  * \param reader Reader to use
182  * \param destroyer Destroyer to use
183  * \param vp Reader-specific arg
184  */
185 void
186 pgp_reader_set(pgp_stream_t *stream,
187 		pgp_reader_func_t *reader,
188 		pgp_reader_destroyer_t *destroyer,
189 		void *vp)
190 {
191 	stream->readinfo.reader = reader;
192 	stream->readinfo.destroyer = destroyer;
193 	stream->readinfo.arg = vp;
194 }
195 
196 /**
197  * \ingroup Internal_Readers_Generic
198  * \brief Adds to reader stack
199  * \param stream Parse settings
200  * \param reader Reader to use
201  * \param destroyer Reader's destroyer
202  * \param vp Reader-specific arg
203  */
204 void
205 pgp_reader_push(pgp_stream_t *stream,
206 		pgp_reader_func_t *reader,
207 		pgp_reader_destroyer_t *destroyer,
208 		void *vp)
209 {
210 	pgp_reader_t *readinfo;
211 
212 	if ((readinfo = calloc(1, sizeof(*readinfo))) == NULL) {
213 		(void) fprintf(stderr, "pgp_reader_push: bad alloc\n");
214 	} else {
215 		*readinfo = stream->readinfo;
216 		(void) memset(&stream->readinfo, 0x0, sizeof(stream->readinfo));
217 		stream->readinfo.next = readinfo;
218 		stream->readinfo.parent = stream;
219 
220 		/* should copy accumulate flags from other reader? RW */
221 		stream->readinfo.accumulate = readinfo->accumulate;
222 
223 		pgp_reader_set(stream, reader, destroyer, vp);
224 	}
225 }
226 
227 /**
228  * \ingroup Internal_Readers_Generic
229  * \brief Removes from reader stack
230  * \param stream Parse settings
231  */
232 void
233 pgp_reader_pop(pgp_stream_t *stream)
234 {
235 	pgp_reader_t *next = stream->readinfo.next;
236 
237 	stream->readinfo = *next;
238 	free(next);
239 }
240 
241 /**
242  * \ingroup Internal_Readers_Generic
243  * \brief Gets arg from reader
244  * \param readinfo Reader info
245  * \return Pointer to reader info's arg
246  */
247 void           *
248 pgp_reader_get_arg(pgp_reader_t *readinfo)
249 {
250 	return readinfo->arg;
251 }
252 
253 /**************************************************************************/
254 
255 #define CRC24_POLY 0x1864cfbL
256 
257 enum {
258 	NONE = 0,
259 	BEGIN_PGP_MESSAGE,
260 	BEGIN_PGP_PUBLIC_KEY_BLOCK,
261 	BEGIN_PGP_PRIVATE_KEY_BLOCK,
262 	BEGIN_PGP_MULTI,
263 	BEGIN_PGP_SIGNATURE,
264 
265 	END_PGP_MESSAGE,
266 	END_PGP_PUBLIC_KEY_BLOCK,
267 	END_PGP_PRIVATE_KEY_BLOCK,
268 	END_PGP_MULTI,
269 	END_PGP_SIGNATURE,
270 
271 	BEGIN_PGP_SIGNED_MESSAGE
272 };
273 
274 /**
275  * \struct dearmour_t
276  */
277 typedef struct {
278 	enum {
279 		OUTSIDE_BLOCK = 0,
280 		BASE64,
281 		AT_TRAILER_NAME
282 	} state;
283 	int		lastseen;
284 	pgp_stream_t *parse_info;
285 	unsigned	seen_nl:1;
286 	unsigned	prev_nl:1;
287 	unsigned	allow_headers_without_gap:1;
288 			/* !< allow headers in armoured data that are
289 			* not separated from the data by a blank line
290 			* */
291 	unsigned	allow_no_gap:1;
292 			/* !< allow no blank line at the start of
293 			* armoured data */
294 	unsigned	allow_trailing_whitespace:1;
295 			/* !< allow armoured stuff to have trailing
296 			* whitespace where we wouldn't strictly expect
297 			* it */
298 	/* it is an error to get a cleartext message without a sig */
299 	unsigned   	expect_sig:1;
300 	unsigned   	got_sig:1;
301 	/* base64 stuff */
302 	unsigned        buffered;
303 	uint8_t		buffer[3];
304 	unsigned	eof64;
305 	uint32_t   checksum;
306 	uint32_t   read_checksum;
307 	/* unarmoured text blocks */
308 	uint8_t   unarmoured[NETPGP_BUFSIZ];
309 	size_t          unarmoredc;
310 	/* pushed back data (stored backwards) */
311 	uint8_t  *pushback;
312 	unsigned        pushbackc;
313 	/* armoured block headers */
314 	pgp_headers_t	headers;
315 } dearmour_t;
316 
317 static void
318 push_back(dearmour_t *dearmour, const uint8_t *buf,
319 	  unsigned length)
320 {
321 	unsigned        n;
322 
323 	if (dearmour->pushback) {
324 		(void) fprintf(stderr, "push_back: already pushed back\n");
325 	} else if ((dearmour->pushback = calloc(1, length)) == NULL) {
326 		(void) fprintf(stderr, "push_back: bad alloc\n");
327 	} else {
328 		for (n = 0; n < length; ++n) {
329 			dearmour->pushback[n] = buf[(length - n) - 1];
330 		}
331 		dearmour->pushbackc = length;
332 	}
333 }
334 
335 /* this struct holds a textual header line */
336 typedef struct headerline_t {
337 	const char	*s;		/* the header line */
338 	size_t		 len;		/* its length */
339 	int		 type;		/* the defined type */
340 } headerline_t;
341 
342 static headerline_t	headerlines[] = {
343 	{ "BEGIN PGP MESSAGE",		17, BEGIN_PGP_MESSAGE },
344 	{ "BEGIN PGP PUBLIC KEY BLOCK",	26, BEGIN_PGP_PUBLIC_KEY_BLOCK },
345 	{ "BEGIN PGP PRIVATE KEY BLOCK",27, BEGIN_PGP_PRIVATE_KEY_BLOCK },
346 	{ "BEGIN PGP MESSAGE, PART ",	25, BEGIN_PGP_MULTI },
347 	{ "BEGIN PGP SIGNATURE",	19, BEGIN_PGP_SIGNATURE },
348 
349 	{ "END PGP MESSAGE",		15, END_PGP_MESSAGE },
350 	{ "END PGP PUBLIC KEY BLOCK",	24, END_PGP_PUBLIC_KEY_BLOCK },
351 	{ "END PGP PRIVATE KEY BLOCK",	25, END_PGP_PRIVATE_KEY_BLOCK },
352 	{ "END PGP MESSAGE, PART ",	22, END_PGP_MULTI },
353 	{ "END PGP SIGNATURE",		17, END_PGP_SIGNATURE },
354 
355 	{ "BEGIN PGP SIGNED MESSAGE",	24, BEGIN_PGP_SIGNED_MESSAGE },
356 
357 	{ NULL,				0, -1	}
358 };
359 
360 /* search through the table of header lines */
361 static int
362 findheaderline(char *headerline)
363 {
364 	headerline_t	*hp;
365 
366 	for (hp = headerlines ; hp->s ; hp++) {
367 		if (strncmp(headerline, hp->s, hp->len) == 0) {
368 			break;
369 		}
370 	}
371 	return hp->type;
372 }
373 
374 static int
375 set_lastseen_headerline(dearmour_t *dearmour, char *hdr, pgp_error_t **errors)
376 {
377 	int	lastseen;
378 	int	prev;
379 
380 	prev = dearmour->lastseen;
381 	if ((lastseen = findheaderline(hdr)) == -1) {
382 		PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT,
383 			"Unrecognised Header Line %s", hdr);
384 		return 0;
385 	}
386 	dearmour->lastseen = lastseen;
387 	if (pgp_get_debug_level(__FILE__)) {
388 		printf("set header: hdr=%s, dearmour->lastseen=%d, prev=%d\n",
389 			hdr, dearmour->lastseen, prev);
390 	}
391 	switch (dearmour->lastseen) {
392 	case NONE:
393 		PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT,
394 			"Unrecognised last seen Header Line %s", hdr);
395 		break;
396 
397 	case END_PGP_MESSAGE:
398 		if (prev != BEGIN_PGP_MESSAGE) {
399 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
400 				"Got END PGP MESSAGE, but not after BEGIN");
401 		}
402 		break;
403 
404 	case END_PGP_PUBLIC_KEY_BLOCK:
405 		if (prev != BEGIN_PGP_PUBLIC_KEY_BLOCK) {
406 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
407 			"Got END PGP PUBLIC KEY BLOCK, but not after BEGIN");
408 		}
409 		break;
410 
411 	case END_PGP_PRIVATE_KEY_BLOCK:
412 		if (prev != BEGIN_PGP_PRIVATE_KEY_BLOCK) {
413 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
414 			"Got END PGP PRIVATE KEY BLOCK, but not after BEGIN");
415 		}
416 		break;
417 
418 	case BEGIN_PGP_MULTI:
419 	case END_PGP_MULTI:
420 		PGP_ERROR(errors, PGP_E_R_UNSUPPORTED,
421 			"Multi-part messages are not yet supported");
422 		break;
423 
424 	case END_PGP_SIGNATURE:
425 		if (prev != BEGIN_PGP_SIGNATURE) {
426 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
427 			"Got END PGP SIGNATURE, but not after BEGIN");
428 		}
429 		break;
430 
431 	case BEGIN_PGP_MESSAGE:
432 	case BEGIN_PGP_PUBLIC_KEY_BLOCK:
433 	case BEGIN_PGP_PRIVATE_KEY_BLOCK:
434 	case BEGIN_PGP_SIGNATURE:
435 	case BEGIN_PGP_SIGNED_MESSAGE:
436 		break;
437 	}
438 	return 1;
439 }
440 
441 static int
442 read_char(pgp_stream_t *stream, dearmour_t *dearmour,
443 		pgp_error_t **errors,
444 		pgp_reader_t *readinfo,
445 		pgp_cbdata_t *cbinfo,
446 		unsigned skip)
447 {
448 	uint8_t   c;
449 
450 	do {
451 		if (dearmour->pushbackc) {
452 			c = dearmour->pushback[--dearmour->pushbackc];
453 			if (dearmour->pushbackc == 0) {
454 				free(dearmour->pushback);
455 				dearmour->pushback = NULL;
456 			}
457 		} else if (pgp_stacked_read(stream, &c, 1, errors, readinfo,
458 					cbinfo) != 1) {
459 			return -1;
460 		}
461 	} while (skip && c == '\r');
462 	dearmour->prev_nl = dearmour->seen_nl;
463 	dearmour->seen_nl = c == '\n';
464 	return c;
465 }
466 
467 static int
468 eat_whitespace(pgp_stream_t *stream, int first,
469 	       dearmour_t *dearmour,
470 	       pgp_error_t **errors,
471 	       pgp_reader_t *readinfo,
472 	       pgp_cbdata_t *cbinfo,
473 	       unsigned skip)
474 {
475 	int             c = first;
476 
477 	while (c == ' ' || c == '\t') {
478 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, skip);
479 	}
480 	return c;
481 }
482 
483 static int
484 read_and_eat_whitespace(pgp_stream_t *stream, dearmour_t *dearmour,
485 			pgp_error_t **errors,
486 			pgp_reader_t *readinfo,
487 			pgp_cbdata_t *cbinfo,
488 			unsigned skip)
489 {
490 	int             c;
491 
492 	do {
493 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, skip);
494 	} while (c == ' ' || c == '\t');
495 	return c;
496 }
497 
498 static void
499 flush(dearmour_t *dearmour, pgp_cbdata_t *cbinfo)
500 {
501 	pgp_packet_t	content;
502 
503 	if (dearmour->unarmoredc > 0) {
504 		content.u.unarmoured_text.data = dearmour->unarmoured;
505 		content.u.unarmoured_text.length = (unsigned)dearmour->unarmoredc;
506 		CALLBACK(PGP_PTAG_CT_UNARMOURED_TEXT, cbinfo, &content);
507 		dearmour->unarmoredc = 0;
508 	}
509 }
510 
511 static int
512 unarmoured_read_char(pgp_stream_t *stream, dearmour_t *dearmour,
513 			pgp_error_t **errors,
514 			pgp_reader_t *readinfo,
515 			pgp_cbdata_t *cbinfo,
516 			unsigned skip)
517 {
518 	int             c;
519 
520 	do {
521 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
522 		if (c < 0) {
523 			return c;
524 		}
525 		dearmour->unarmoured[dearmour->unarmoredc++] = c;
526 		if (dearmour->unarmoredc == sizeof(dearmour->unarmoured)) {
527 			flush(dearmour, cbinfo);
528 		}
529 	} while (skip && c == '\r');
530 	return c;
531 }
532 
533 /**
534  * \param headers
535  * \param key
536  *
537  * \return header value if found, otherwise NULL
538  */
539 static const char *
540 find_header(pgp_headers_t *headers, const char *key)
541 {
542 	unsigned        n;
543 
544 	for (n = 0; n < headers->headerc; ++n) {
545 		if (strcmp(headers->headers[n].key, key) == 0) {
546 			return headers->headers[n].value;
547 		}
548 	}
549 	return NULL;
550 }
551 
552 /**
553  * \param dest
554  * \param src
555  */
556 static void
557 dup_headers(pgp_headers_t *dest, const pgp_headers_t *src)
558 {
559 	unsigned        n;
560 
561 	if ((dest->headers = calloc(src->headerc, sizeof(*dest->headers))) == NULL) {
562 		(void) fprintf(stderr, "dup_headers: bad alloc\n");
563 	} else {
564 		dest->headerc = src->headerc;
565 		for (n = 0; n < src->headerc; ++n) {
566 			dest->headers[n].key = netpgp_strdup(src->headers[n].key);
567 			dest->headers[n].value = netpgp_strdup(src->headers[n].value);
568 		}
569 	}
570 }
571 
572 /*
573  * Note that this skips CRs so implementations always see just straight LFs
574  * as line terminators
575  */
576 static int
577 process_dash_escaped(pgp_stream_t *stream, dearmour_t *dearmour,
578 			pgp_error_t **errors,
579 			pgp_reader_t *readinfo,
580 			pgp_cbdata_t *cbinfo)
581 {
582 	pgp_fixed_body_t	*body;
583 	pgp_packet_t		 content2;
584 	pgp_packet_t		 content;
585 	const char		*hashstr;
586 	pgp_hash_t		*hash;
587 	int			 total;
588 
589 	body = &content.u.cleartext_body;
590 	if ((hash = calloc(1, sizeof(*hash))) == NULL) {
591 		PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
592 			"process_dash_escaped: bad alloc");
593 		return -1;
594 	}
595 	hashstr = find_header(&dearmour->headers, "Hash");
596 	if (hashstr) {
597 		pgp_hash_alg_t alg;
598 
599 		alg = pgp_str_to_hash_alg(hashstr);
600 		if (!pgp_is_hash_alg_supported(&alg)) {
601 			free(hash);
602 			PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT,
603 				"Unsupported hash algorithm '%s'", hashstr);
604 			return -1;
605 		}
606 		if (alg == PGP_HASH_UNKNOWN) {
607 			free(hash);
608 			PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT,
609 				"Unknown hash algorithm '%s'", hashstr);
610 			return -1;
611 		}
612 		pgp_hash_any(hash, alg);
613 	} else {
614 		pgp_hash_md5(hash);
615 	}
616 
617 	if (!hash->init(hash)) {
618 		PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
619 			"can't initialise hash");
620 		return -1;
621 	}
622 
623 	body->length = 0;
624 	total = 0;
625 	for (;;) {
626 		int             c;
627 		unsigned        count;
628 
629 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
630 		if (c < 0) {
631 			return -1;
632 		}
633 		if (dearmour->prev_nl && c == '-') {
634 			if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo,
635 						0)) < 0) {
636 				return -1;
637 			}
638 			if (c != ' ') {
639 				/* then this had better be a trailer! */
640 				if (c != '-') {
641 					PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
642 						"Bad dash-escaping");
643 				}
644 				for (count = 2; count < 5; ++count) {
645 					if ((c = read_char(stream, dearmour, errors,
646 						readinfo, cbinfo, 0)) < 0) {
647 						return -1;
648 					}
649 					if (c != '-') {
650 						PGP_ERROR(errors,
651 						PGP_E_R_BAD_FORMAT,
652 						"Bad dash-escaping (2)");
653 					}
654 				}
655 				dearmour->state = AT_TRAILER_NAME;
656 				break;
657 			}
658 			/* otherwise we read the next character */
659 			if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo,
660 						0)) < 0) {
661 				return -1;
662 			}
663 		}
664 		if (c == '\n' && body->length) {
665 			if (memchr(body->data + 1, '\n', body->length - 1)
666 						!= NULL) {
667 				(void) fprintf(stderr,
668 				"process_dash_escaped: newline found\n");
669 				return -1;
670 			}
671 			if (body->data[0] == '\n') {
672 				hash->add(hash, (const uint8_t *)"\r", 1);
673 			}
674 			hash->add(hash, body->data, body->length);
675 			if (pgp_get_debug_level(__FILE__)) {
676 				fprintf(stderr, "Got body:\n%s\n", body->data);
677 			}
678 			CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbinfo,
679 						&content);
680 			body->length = 0;
681 		}
682 		body->data[body->length++] = c;
683 		total += 1;
684 		if (body->length == sizeof(body->data)) {
685 			if (pgp_get_debug_level(__FILE__)) {
686 				(void) fprintf(stderr, "Got body (2):\n%s\n",
687 						body->data);
688 			}
689 			CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbinfo,
690 					&content);
691 			body->length = 0;
692 		}
693 	}
694 	if (body->data[0] != '\n') {
695 		(void) fprintf(stderr,
696 			"process_dash_escaped: no newline in body data\n");
697 		return -1;
698 	}
699 	if (body->length != 1) {
700 		(void) fprintf(stderr,
701 			"process_dash_escaped: bad body length\n");
702 		return -1;
703 	}
704 	/* don't send that one character, because it's part of the trailer */
705 	(void) memset(&content2, 0x0, sizeof(content2));
706 	CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, cbinfo, &content2);
707 	return total;
708 }
709 
710 static int
711 add_header(dearmour_t *dearmour, const char *key, const char *value)
712 {
713 	int	n;
714 
715 	/*
716          * Check that the header is valid
717          */
718 	if (strcmp(key, "Version") == 0 ||
719 	    strcmp(key, "Comment") == 0 ||
720 	    strcmp(key, "MessageID") == 0 ||
721 	    strcmp(key, "Hash") == 0 ||
722 	    strcmp(key, "Charset") == 0) {
723 		n = dearmour->headers.headerc;
724 		dearmour->headers.headers = realloc(dearmour->headers.headers,
725 				(n + 1) * sizeof(*dearmour->headers.headers));
726 		if (dearmour->headers.headers == NULL) {
727 			(void) fprintf(stderr, "add_header: bad alloc\n");
728 			return 0;
729 		}
730 		dearmour->headers.headers[n].key = netpgp_strdup(key);
731 		dearmour->headers.headers[n].value = netpgp_strdup(value);
732 		dearmour->headers.headerc = n + 1;
733 		return 1;
734 	}
735 	return 0;
736 }
737 
738 /* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */
739 static int
740 parse_headers(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
741 	      pgp_reader_t * readinfo, pgp_cbdata_t * cbinfo)
742 {
743 	unsigned        nbuf;
744 	unsigned        size;
745 	unsigned	first = 1;
746 	char           *buf;
747 	int             ret = 1;
748 
749 	nbuf = 0;
750 	size = 80;
751 	if ((buf = calloc(1, size)) == NULL) {
752 		(void) fprintf(stderr, "parse_headers: bad calloc\n");
753 		return -1;
754 	}
755 	for (;;) {
756 		int             c;
757 
758 		if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1)) < 0) {
759 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "Unexpected EOF");
760 			ret = -1;
761 			break;
762 		}
763 		if (c == '\n') {
764 			char           *s;
765 
766 			if (nbuf == 0) {
767 				break;
768 			}
769 
770 			if (nbuf >= size) {
771 				(void) fprintf(stderr,
772 					"parse_headers: bad size\n");
773 				return -1;
774 			}
775 			buf[nbuf] = '\0';
776 
777 			if ((s = strchr(buf, ':')) == NULL) {
778 				if (!first && !dearmour->allow_headers_without_gap) {
779 					/*
780 					 * then we have seriously malformed
781 					 * armour
782 					 */
783 					PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "No colon in armour header");
784 					ret = -1;
785 					break;
786 				} else {
787 					if (first &&
788 					    !(dearmour->allow_headers_without_gap || dearmour->allow_no_gap)) {
789 						PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "No colon in armour header (2)");
790 						/*
791 						 * then we have a nasty
792 						 * armoured block with no
793 						 * headers, not even a blank
794 						 * line.
795 						 */
796 						buf[nbuf] = '\n';
797 						push_back(dearmour, (uint8_t *) buf, nbuf + 1);
798 						ret = -1;
799 						break;
800 					}
801 				}
802 			} else {
803 				*s = '\0';
804 				if (s[1] != ' ') {
805 					PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "No space in armour header");
806 					ret = -1;
807 					goto end;
808 				}
809 				if (!add_header(dearmour, buf, s + 2)) {
810 					PGP_ERROR_1(errors, PGP_E_R_BAD_FORMAT, "Invalid header %s", buf);
811 					ret = -1;
812 					goto end;
813 				}
814 				nbuf = 0;
815 			}
816 			first = 0;
817 		} else {
818 			if (size <= nbuf + 1) {
819 				size += size + 80;
820 				buf = realloc(buf, size);
821 				if (buf == NULL) {
822 					(void) fprintf(stderr, "bad alloc\n");
823 					ret = -1;
824 					goto end;
825 				}
826 			}
827 			buf[nbuf++] = c;
828 		}
829 	}
830 
831 end:
832 	free(buf);
833 
834 	return ret;
835 }
836 
837 static int
838 read4(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
839       pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo,
840       int *pc, unsigned *pn, uint32_t *pl)
841 {
842 	int             n, c;
843 	uint32_t   l = 0;
844 
845 	for (n = 0; n < 4; ++n) {
846 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
847 		if (c < 0) {
848 			dearmour->eof64 = 1;
849 			return -1;
850 		}
851 		if (c == '-' || c == '=') {
852 			break;
853 		}
854 		l <<= 6;
855 		if (c >= 'A' && c <= 'Z') {
856 			l += (uint32_t)(c - 'A');
857 		} else if (c >= 'a' && c <= 'z') {
858 			l += (uint32_t)(c - 'a') + 26;
859 		} else if (c >= '0' && c <= '9') {
860 			l += (uint32_t)(c - '0') + 52;
861 		} else if (c == '+') {
862 			l += 62;
863 		} else if (c == '/') {
864 			l += 63;
865 		} else {
866 			--n;
867 			l >>= 6;
868 		}
869 	}
870 
871 	*pc = c;
872 	*pn = n;
873 	*pl = l;
874 
875 	return 4;
876 }
877 
878 unsigned
879 pgp_crc24(unsigned checksum, uint8_t c)
880 {
881 	unsigned        i;
882 
883 	checksum ^= c << 16;
884 	for (i = 0; i < 8; i++) {
885 		checksum <<= 1;
886 		if (checksum & 0x1000000)
887 			checksum ^= CRC24_POLY;
888 	}
889 	return (unsigned)(checksum & 0xffffffL);
890 }
891 
892 static int
893 decode64(pgp_stream_t *stream, dearmour_t *dearmour, pgp_error_t **errors,
894 	 pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
895 {
896 	unsigned        n;
897 	int             n2;
898 	uint32_t	l;
899 	int             c;
900 	int             ret;
901 
902 	if (dearmour->buffered) {
903 		(void) fprintf(stderr, "decode64: bad dearmour->buffered\n");
904 		return 0;
905 	}
906 
907 	ret = read4(stream, dearmour, errors, readinfo, cbinfo, &c, &n, &l);
908 	if (ret < 0) {
909 		PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "Badly formed base64");
910 		return 0;
911 	}
912 	if (n == 3) {
913 		if (c != '=') {
914 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
915 					"Badly terminated base64 (2)");
916 			return 0;
917 		}
918 		dearmour->buffered = 2;
919 		dearmour->eof64 = 1;
920 		l >>= 2;
921 	} else if (n == 2) {
922 		if (c != '=') {
923 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
924 					"Badly terminated base64 (3)");
925 			return 0;
926 		}
927 		dearmour->buffered = 1;
928 		dearmour->eof64 = 1;
929 		l >>= 4;
930 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
931 		if (c != '=') {
932 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
933 					"Badly terminated base64");
934 			return 0;
935 		}
936 	} else if (n == 0) {
937 		if (!dearmour->prev_nl || c != '=') {
938 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
939 					"Badly terminated base64 (4)");
940 			return 0;
941 		}
942 		dearmour->buffered = 0;
943 	} else {
944 		if (n != 4) {
945 			(void) fprintf(stderr,
946 				"decode64: bad n (!= 4)\n");
947 			return 0;
948 		}
949 		dearmour->buffered = 3;
950 		if (c == '-' || c == '=') {
951 			(void) fprintf(stderr, "decode64: bad c\n");
952 			return 0;
953 		}
954 	}
955 
956 	if (dearmour->buffered < 3 && dearmour->buffered > 0) {
957 		/* then we saw padding */
958 		if (c != '=') {
959 			(void) fprintf(stderr, "decode64: bad c (=)\n");
960 			return 0;
961 		}
962 		c = read_and_eat_whitespace(stream, dearmour, errors, readinfo, cbinfo,
963 				1);
964 		if (c != '\n') {
965 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
966 				"No newline at base64 end");
967 			return 0;
968 		}
969 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
970 		if (c != '=') {
971 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
972 				"No checksum at base64 end");
973 			return 0;
974 		}
975 	}
976 	if (c == '=') {
977 		/* now we are at the checksum */
978 		ret = read4(stream, dearmour, errors, readinfo, cbinfo, &c, &n,
979 				&dearmour->read_checksum);
980 		if (ret < 0 || n != 4) {
981 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
982 					"Error in checksum");
983 			return 0;
984 		}
985 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 1);
986 		if (dearmour->allow_trailing_whitespace)
987 			c = eat_whitespace(stream, c, dearmour, errors, readinfo, cbinfo,
988 					1);
989 		if (c != '\n') {
990 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
991 					"Badly terminated checksum");
992 			return 0;
993 		}
994 		c = read_char(stream, dearmour, errors, readinfo, cbinfo, 0);
995 		if (c != '-') {
996 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
997 					"Bad base64 trailer (2)");
998 			return 0;
999 		}
1000 	}
1001 	if (c == '-') {
1002 		for (n = 0; n < 4; ++n)
1003 			if (read_char(stream, dearmour, errors, readinfo, cbinfo,
1004 						0) != '-') {
1005 				PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
1006 						"Bad base64 trailer");
1007 				return 0;
1008 			}
1009 		dearmour->eof64 = 1;
1010 	} else {
1011 		if (!dearmour->buffered) {
1012 			(void) fprintf(stderr, "decode64: not buffered\n");
1013 			return 0;
1014 		}
1015 	}
1016 
1017 	for (n = 0; n < dearmour->buffered; ++n) {
1018 		dearmour->buffer[n] = (uint8_t)l;
1019 		l >>= 8;
1020 	}
1021 
1022 	for (n2 = dearmour->buffered - 1; n2 >= 0; --n2)
1023 		dearmour->checksum = pgp_crc24((unsigned)dearmour->checksum,
1024 					dearmour->buffer[n2]);
1025 
1026 	if (dearmour->eof64 && dearmour->read_checksum != dearmour->checksum) {
1027 		PGP_ERROR(errors, PGP_E_R_BAD_FORMAT, "Checksum mismatch");
1028 		return 0;
1029 	}
1030 	return 1;
1031 }
1032 
1033 static void
1034 base64(dearmour_t *dearmour)
1035 {
1036 	dearmour->state = BASE64;
1037 	dearmour->checksum = CRC24_INIT;
1038 	dearmour->eof64 = 0;
1039 	dearmour->buffered = 0;
1040 }
1041 
1042 /* This reader is rather strange in that it can generate callbacks for */
1043 /* content - this is because plaintext is not encapsulated in PGP */
1044 /* packets... it also calls back for the text between the blocks. */
1045 
1046 static int
1047 armoured_data_reader(pgp_stream_t *stream, void *dest_, size_t length, pgp_error_t **errors,
1048 		     pgp_reader_t *readinfo,
1049 		     pgp_cbdata_t *cbinfo)
1050 {
1051 	pgp_packet_t	 content;
1052 	dearmour_t	*dearmour;
1053 	unsigned	 first;
1054 	uint8_t		*dest = dest_;
1055 	char		 buf[1024];
1056 	int		 saved;
1057 	int              ret;
1058 
1059 	dearmour = pgp_reader_get_arg(readinfo);
1060 	saved = (int)length;
1061 	if (dearmour->eof64 && !dearmour->buffered) {
1062 		if (dearmour->state != OUTSIDE_BLOCK &&
1063 		    dearmour->state != AT_TRAILER_NAME) {
1064 			(void) fprintf(stderr,
1065 				"armoured_data_reader: bad dearmour state\n");
1066 			return 0;
1067 		}
1068 	}
1069 
1070 	while (length > 0) {
1071 		unsigned        count;
1072 		unsigned        n;
1073 		int             c;
1074 
1075 		flush(dearmour, cbinfo);
1076 		switch (dearmour->state) {
1077 		case OUTSIDE_BLOCK:
1078 			/*
1079 			 * This code returns EOF rather than EARLY_EOF
1080 			 * because if we don't see a header line at all, then
1081 			 * it is just an EOF (and not a BLOCK_END)
1082 			 */
1083 			while (!dearmour->seen_nl) {
1084 				if ((c = unarmoured_read_char(stream, dearmour, errors,
1085 						readinfo, cbinfo, 1)) < 0) {
1086 					return 0;
1087 				}
1088 			}
1089 
1090 			/*
1091 			 * flush at this point so we definitely have room for
1092 			 * the header, and so we can easily erase it from the
1093 			 * buffer
1094 			 */
1095 			flush(dearmour, cbinfo);
1096 			/* Find and consume the 5 leading '-' */
1097 			for (count = 0; count < 5; ++count) {
1098 				if ((c = unarmoured_read_char(stream, dearmour, errors,
1099 						readinfo, cbinfo, 0)) < 0) {
1100 					return 0;
1101 				}
1102 				if (c != '-') {
1103 					goto reloop;
1104 				}
1105 			}
1106 
1107 			/* Now find the block type */
1108 			for (n = 0; n < sizeof(buf) - 1;) {
1109 				if ((c = unarmoured_read_char(stream, dearmour, errors,
1110 						readinfo, cbinfo, 0)) < 0) {
1111 					return 0;
1112 				}
1113 				if (c == '-') {
1114 					goto got_minus;
1115 				}
1116 				buf[n++] = c;
1117 			}
1118 			/* then I guess this wasn't a proper header */
1119 			break;
1120 
1121 got_minus:
1122 			buf[n] = '\0';
1123 
1124 			/* Consume trailing '-' */
1125 			for (count = 1; count < 5; ++count) {
1126 				if ((c = unarmoured_read_char(stream, dearmour, errors,
1127 						readinfo, cbinfo, 0)) < 0) {
1128 					return 0;
1129 				}
1130 				if (c != '-') {
1131 					/* wasn't a header after all */
1132 					goto reloop;
1133 				}
1134 			}
1135 
1136 			/* Consume final NL */
1137 			if ((c = unarmoured_read_char(stream, dearmour, errors, readinfo,
1138 						cbinfo, 1)) < 0) {
1139 				return 0;
1140 			}
1141 			if (dearmour->allow_trailing_whitespace) {
1142 				if ((c = eat_whitespace(stream, c, dearmour, errors,
1143 						readinfo, cbinfo, 1)) < 0) {
1144 					return 0;
1145 				}
1146 			}
1147 			if (c != '\n') {
1148 				/* wasn't a header line after all */
1149 				break;
1150 			}
1151 
1152 			/*
1153 			 * Now we've seen the header, scrub it from the
1154 			 * buffer
1155 			 */
1156 			dearmour->unarmoredc = 0;
1157 
1158 			/*
1159 			 * But now we've seen a header line, then errors are
1160 			 * EARLY_EOF
1161 			 */
1162 			if ((ret = parse_headers(stream, dearmour, errors, readinfo,
1163 					cbinfo)) <= 0) {
1164 				return -1;
1165 			}
1166 
1167 			if (!set_lastseen_headerline(dearmour, buf, errors)) {
1168 				return -1;
1169 			}
1170 
1171 			if (strcmp(buf, "BEGIN PGP SIGNED MESSAGE") == 0) {
1172 				dup_headers(&content.u.cleartext_head,
1173 					&dearmour->headers);
1174 				CALLBACK(PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER,
1175 					cbinfo,
1176 					&content);
1177 				ret = process_dash_escaped(stream, dearmour, errors,
1178 						readinfo, cbinfo);
1179 				if (ret <= 0) {
1180 					return ret;
1181 				}
1182 			} else {
1183 				content.u.armour_header.type = buf;
1184 				content.u.armour_header.headers =
1185 						dearmour->headers;
1186 				(void) memset(&dearmour->headers, 0x0,
1187 						sizeof(dearmour->headers));
1188 				CALLBACK(PGP_PTAG_CT_ARMOUR_HEADER, cbinfo,
1189 						&content);
1190 				base64(dearmour);
1191 			}
1192 			break;
1193 
1194 		case BASE64:
1195 			first = 1;
1196 			while (length > 0) {
1197 				if (!dearmour->buffered) {
1198 					if (!dearmour->eof64) {
1199 						ret = decode64(stream, dearmour,
1200 							errors, readinfo, cbinfo);
1201 						if (ret <= 0) {
1202 							return ret;
1203 						}
1204 					}
1205 					if (!dearmour->buffered) {
1206 						if (!dearmour->eof64) {
1207 							(void) fprintf(stderr,
1208 "armoured_data_reader: bad dearmour eof64\n");
1209 							return 0;
1210 						}
1211 						if (first) {
1212 							dearmour->state =
1213 								AT_TRAILER_NAME;
1214 							goto reloop;
1215 						}
1216 						return -1;
1217 					}
1218 				}
1219 				if (!dearmour->buffered) {
1220 					(void) fprintf(stderr,
1221 			"armoured_data_reader: bad dearmour buffered\n");
1222 					return 0;
1223 				}
1224 				*dest = dearmour->buffer[--dearmour->buffered];
1225 				++dest;
1226 				--length;
1227 				first = 0;
1228 			}
1229 			if (dearmour->eof64 && !dearmour->buffered) {
1230 				dearmour->state = AT_TRAILER_NAME;
1231 			}
1232 			break;
1233 
1234 		case AT_TRAILER_NAME:
1235 			for (n = 0; n < sizeof(buf) - 1;) {
1236 				if ((c = read_char(stream, dearmour, errors, readinfo,
1237 						cbinfo, 0)) < 0) {
1238 					return -1;
1239 				}
1240 				if (c == '-') {
1241 					goto got_minus2;
1242 				}
1243 				buf[n++] = c;
1244 			}
1245 			/* then I guess this wasn't a proper trailer */
1246 			PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
1247 					"Bad ASCII armour trailer");
1248 			break;
1249 
1250 got_minus2:
1251 			buf[n] = '\0';
1252 
1253 			if (!set_lastseen_headerline(dearmour, buf, errors)) {
1254 				return -1;
1255 			}
1256 
1257 			/* Consume trailing '-' */
1258 			for (count = 1; count < 5; ++count) {
1259 				if ((c = read_char(stream, dearmour, errors, readinfo,
1260 						cbinfo, 0)) < 0) {
1261 					return -1;
1262 				}
1263 				if (c != '-') {
1264 					/* wasn't a trailer after all */
1265 					PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
1266 						"Bad ASCII armour trailer (2)");
1267 				}
1268 			}
1269 
1270 			/* Consume final NL */
1271 			if ((c = read_char(stream, dearmour, errors, readinfo, cbinfo,
1272 						1)) < 0) {
1273 				return -1;
1274 			}
1275 			if (dearmour->allow_trailing_whitespace) {
1276 				if ((c = eat_whitespace(stream, c, dearmour, errors,
1277 						readinfo, cbinfo, 1)) < 0) {
1278 					return 0;
1279 				}
1280 			}
1281 			if (c != '\n') {
1282 				/* wasn't a trailer line after all */
1283 				PGP_ERROR(errors, PGP_E_R_BAD_FORMAT,
1284 					"Bad ASCII armour trailer (3)");
1285 			}
1286 
1287 			if (strncmp(buf, "BEGIN ", 6) == 0) {
1288 				if (!set_lastseen_headerline(dearmour, buf,
1289 						errors)) {
1290 					return -1;
1291 				}
1292 				if ((ret = parse_headers(stream, dearmour, errors,
1293 						readinfo, cbinfo)) <= 0) {
1294 					return ret;
1295 				}
1296 				content.u.armour_header.type = buf;
1297 				content.u.armour_header.headers =
1298 						dearmour->headers;
1299 				(void) memset(&dearmour->headers, 0x0,
1300 						sizeof(dearmour->headers));
1301 				CALLBACK(PGP_PTAG_CT_ARMOUR_HEADER, cbinfo,
1302 						&content);
1303 				base64(dearmour);
1304 			} else {
1305 				content.u.armour_trailer = buf;
1306 				CALLBACK(PGP_PTAG_CT_ARMOUR_TRAILER, cbinfo,
1307 						&content);
1308 				dearmour->state = OUTSIDE_BLOCK;
1309 			}
1310 			break;
1311 		}
1312 reloop:
1313 		continue;
1314 	}
1315 
1316 	return saved;
1317 }
1318 
1319 static void
1320 armoured_data_destroyer(pgp_reader_t *readinfo)
1321 {
1322 	free(pgp_reader_get_arg(readinfo));
1323 }
1324 
1325 /**
1326  * \ingroup Core_Readers_Armour
1327  * \brief Pushes dearmouring reader onto stack
1328  * \param parse_info Usual structure containing information about to how to do the parse
1329  * \sa pgp_reader_pop_dearmour()
1330  */
1331 void
1332 pgp_reader_push_dearmour(pgp_stream_t *parse_info)
1333 /*
1334  * This function originally had these params to cater for packets which
1335  * didn't strictly match the RFC. The initial 0.5 release is only going to
1336  * support strict checking. If it becomes desirable to support loose checking
1337  * of armoured packets and these params are reinstated, parse_headers() must
1338  * be fixed so that these flags work correctly.
1339  *
1340  * // Allow headers in armoured data that are not separated from the data by a
1341  * blank line unsigned without_gap,
1342  *
1343  * // Allow no blank line at the start of armoured data unsigned no_gap,
1344  *
1345  * //Allow armoured data to have trailing whitespace where we strictly would not
1346  * expect it			      unsigned trailing_whitespace
1347  */
1348 {
1349 	dearmour_t *dearmour;
1350 
1351 	if ((dearmour = calloc(1, sizeof(*dearmour))) == NULL) {
1352 		(void) fprintf(stderr, "pgp_reader_push_dearmour: bad alloc\n");
1353 	} else {
1354 		dearmour->seen_nl = 1;
1355 		/*
1356 		    dearmour->allow_headers_without_gap=without_gap;
1357 		    dearmour->allow_no_gap=no_gap;
1358 		    dearmour->allow_trailing_whitespace=trailing_whitespace;
1359 		*/
1360 		dearmour->expect_sig = 0;
1361 		dearmour->got_sig = 0;
1362 
1363 		pgp_reader_push(parse_info, armoured_data_reader,
1364 			armoured_data_destroyer, dearmour);
1365 	}
1366 }
1367 
1368 /**
1369  * \ingroup Core_Readers_Armour
1370  * \brief Pops dearmour reader from stock
1371  * \param stream
1372  * \sa pgp_reader_push_dearmour()
1373  */
1374 void
1375 pgp_reader_pop_dearmour(pgp_stream_t *stream)
1376 {
1377 	dearmour_t *dearmour;
1378 
1379 	dearmour = pgp_reader_get_arg(pgp_readinfo(stream));
1380 	free(dearmour);
1381 	pgp_reader_pop(stream);
1382 }
1383 
1384 /**************************************************************************/
1385 
1386 /* this is actually used for *decrypting* */
1387 typedef struct {
1388 	uint8_t		 decrypted[1024 * 15];
1389 	size_t		 c;
1390 	size_t		 off;
1391 	pgp_crypt_t	*decrypt;
1392 	pgp_region_t	*region;
1393 	unsigned	 prevplain:1;
1394 } encrypted_t;
1395 
1396 static int
1397 encrypted_data_reader(pgp_stream_t *stream, void *dest,
1398 			size_t length,
1399 			pgp_error_t **errors,
1400 			pgp_reader_t *readinfo,
1401 			pgp_cbdata_t *cbinfo)
1402 {
1403 	encrypted_t	*encrypted;
1404 	char		*cdest;
1405 	int		 saved;
1406 
1407 	encrypted = pgp_reader_get_arg(readinfo);
1408 	saved = (int)length;
1409 	/*
1410 	 * V3 MPIs have the count plain and the cipher is reset after each
1411 	 * count
1412 	 */
1413 	if (encrypted->prevplain && !readinfo->parent->reading_mpi_len) {
1414 		if (!readinfo->parent->reading_v3_secret) {
1415 			(void) fprintf(stderr,
1416 				"encrypted_data_reader: bad v3 secret\n");
1417 			return -1;
1418 		}
1419 		encrypted->decrypt->decrypt_resync(encrypted->decrypt);
1420 		encrypted->prevplain = 0;
1421 	} else if (readinfo->parent->reading_v3_secret &&
1422 		   readinfo->parent->reading_mpi_len) {
1423 		encrypted->prevplain = 1;
1424 	}
1425 	while (length > 0) {
1426 		if (encrypted->c) {
1427 			unsigned        n;
1428 
1429 			/*
1430 			 * if we are reading v3 we should never read
1431 			 * more than we're asked for */
1432 			if (length < encrypted->c &&
1433 			     (readinfo->parent->reading_v3_secret ||
1434 			      readinfo->parent->exact_read)) {
1435 				(void) fprintf(stderr,
1436 					"encrypted_data_reader: bad v3 read\n");
1437 				return 0;
1438 			}
1439 			n = (int)MIN(length, encrypted->c);
1440 			(void) memcpy(dest,
1441 				encrypted->decrypted + encrypted->off, n);
1442 			encrypted->c -= n;
1443 			encrypted->off += n;
1444 			length -= n;
1445 			cdest = dest;
1446 			cdest += n;
1447 			dest = cdest;
1448 		} else {
1449 			unsigned	n = encrypted->region->length;
1450 			uint8_t		buffer[1024];
1451 
1452 			if (!n) {
1453 				return -1;
1454 			}
1455 			if (!encrypted->region->indeterminate) {
1456 				n -= encrypted->region->readc;
1457 				if (n == 0) {
1458 					return (int)(saved - length);
1459 				}
1460 				if (n > sizeof(buffer)) {
1461 					n = sizeof(buffer);
1462 				}
1463 			} else {
1464 				n = sizeof(buffer);
1465 			}
1466 
1467 			/*
1468 			 * we can only read as much as we're asked for
1469 			 * in v3 keys because they're partially
1470 			 * unencrypted!  */
1471 			if ((readinfo->parent->reading_v3_secret ||
1472 			     readinfo->parent->exact_read) && n > length) {
1473 				n = (unsigned)length;
1474 			}
1475 
1476 			if (!pgp_stacked_limited_read(stream, buffer, n,
1477 				encrypted->region, errors, readinfo, cbinfo)) {
1478 				return -1;
1479 			}
1480 			if (!readinfo->parent->reading_v3_secret ||
1481 			    !readinfo->parent->reading_mpi_len) {
1482 				encrypted->c =
1483 					pgp_decrypt_se_ip(encrypted->decrypt,
1484 					encrypted->decrypted, buffer, n);
1485 
1486 				if (pgp_get_debug_level(__FILE__)) {
1487 					hexdump(stderr, "encrypted", buffer, 16);
1488 					hexdump(stderr, "decrypted", encrypted->decrypted, 16);
1489 				}
1490 			} else {
1491 				(void) memcpy(
1492 	&encrypted->decrypted[encrypted->off], buffer, n);
1493 				encrypted->c = n;
1494 			}
1495 
1496 			if (encrypted->c == 0) {
1497 				(void) fprintf(stderr,
1498 				"encrypted_data_reader: 0 decrypted count\n");
1499 				return 0;
1500 			}
1501 
1502 			encrypted->off = 0;
1503 		}
1504 	}
1505 
1506 	return saved;
1507 }
1508 
1509 static void
1510 encrypted_data_destroyer(pgp_reader_t *readinfo)
1511 {
1512 	free(pgp_reader_get_arg(readinfo));
1513 }
1514 
1515 /**
1516  * \ingroup Core_Readers_SE
1517  * \brief Pushes decryption reader onto stack
1518  * \sa pgp_reader_pop_decrypt()
1519  */
1520 void
1521 pgp_reader_push_decrypt(pgp_stream_t *stream, pgp_crypt_t *decrypt,
1522 			pgp_region_t *region)
1523 {
1524 	encrypted_t	*encrypted;
1525 
1526 	if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
1527 		(void) fprintf(stderr, "pgp_reader_push_decrypted: bad alloc\n");
1528 	} else {
1529 		encrypted->decrypt = decrypt;
1530 		encrypted->region = region;
1531 		pgp_decrypt_init(encrypted->decrypt);
1532 		pgp_reader_push(stream, encrypted_data_reader,
1533 			encrypted_data_destroyer, encrypted);
1534 	}
1535 }
1536 
1537 /**
1538  * \ingroup Core_Readers_Encrypted
1539  * \brief Pops decryption reader from stack
1540  * \sa pgp_reader_push_decrypt()
1541  */
1542 void
1543 pgp_reader_pop_decrypt(pgp_stream_t *stream)
1544 {
1545 	encrypted_t	*encrypted;
1546 
1547 	encrypted = pgp_reader_get_arg(pgp_readinfo(stream));
1548 	encrypted->decrypt->decrypt_finish(encrypted->decrypt);
1549 	free(encrypted);
1550 	pgp_reader_pop(stream);
1551 }
1552 
1553 /**************************************************************************/
1554 
1555 typedef struct {
1556 	/* boolean: 0 once we've done the preamble/MDC checks */
1557 	/* and are reading from the plaintext */
1558 	int              passed_checks;
1559 	uint8_t		*plaintext;
1560 	size_t           plaintext_available;
1561 	size_t           plaintext_offset;
1562 	pgp_region_t	*region;
1563 	pgp_crypt_t	*decrypt;
1564 } decrypt_se_ip_t;
1565 
1566 /*
1567   Gets entire SE_IP data packet.
1568   Verifies leading preamble
1569   Verifies trailing MDC packet
1570   Then passes up plaintext as requested
1571 */
1572 static int
1573 se_ip_data_reader(pgp_stream_t *stream, void *dest_,
1574 			size_t len,
1575 			pgp_error_t **errors,
1576 			pgp_reader_t *readinfo,
1577 			pgp_cbdata_t *cbinfo)
1578 {
1579 	decrypt_se_ip_t	*se_ip;
1580 	pgp_region_t	 decrypted_region;
1581 	unsigned	 n = 0;
1582 
1583 	se_ip = pgp_reader_get_arg(readinfo);
1584 	if (!se_ip->passed_checks) {
1585 		uint8_t		*buf = NULL;
1586 		uint8_t		hashed[PGP_SHA1_HASH_SIZE];
1587 		uint8_t		*preamble;
1588 		uint8_t		*plaintext;
1589 		uint8_t		*mdc;
1590 		uint8_t		*mdc_hash;
1591 		pgp_hash_t	hash;
1592 		size_t		b;
1593 		size_t          sz_preamble;
1594 		size_t          sz_mdc_hash;
1595 		size_t          sz_mdc;
1596 		size_t          sz_plaintext;
1597 
1598 		pgp_hash_any(&hash, PGP_HASH_SHA1);
1599 		if (!hash.init(&hash)) {
1600 			(void) fprintf(stderr,
1601 				"se_ip_data_reader: can't init hash\n");
1602 			return -1;
1603 		}
1604 
1605 		pgp_init_subregion(&decrypted_region, NULL);
1606 		decrypted_region.length =
1607 			se_ip->region->length - se_ip->region->readc;
1608 		if ((buf = calloc(1, decrypted_region.length)) == NULL) {
1609 			(void) fprintf(stderr, "se_ip_data_reader: bad alloc\n");
1610 			return -1;
1611 		}
1612 
1613 		/* read entire SE IP packet */
1614 		if (!pgp_stacked_limited_read(stream, buf, decrypted_region.length,
1615 				&decrypted_region, errors, readinfo, cbinfo)) {
1616 			free(buf);
1617 			return -1;
1618 		}
1619 		if (pgp_get_debug_level(__FILE__)) {
1620 			hexdump(stderr, "SE IP packet", buf, decrypted_region.length);
1621 		}
1622 		/* verify leading preamble */
1623 		if (pgp_get_debug_level(__FILE__)) {
1624 			hexdump(stderr, "preamble", buf, se_ip->decrypt->blocksize);
1625 		}
1626 		b = se_ip->decrypt->blocksize;
1627 		if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) {
1628 			fprintf(stderr,
1629 			"Bad symmetric decrypt (%02x%02x vs %02x%02x)\n",
1630 				buf[b - 2], buf[b - 1], buf[b], buf[b + 1]);
1631 			PGP_ERROR(errors, PGP_E_PROTO_BAD_SYMMETRIC_DECRYPT,
1632 			"Bad symmetric decrypt when parsing SE IP packet");
1633 			free(buf);
1634 			return -1;
1635 		}
1636 		/* Verify trailing MDC hash */
1637 
1638 		sz_preamble = se_ip->decrypt->blocksize + 2;
1639 		sz_mdc_hash = PGP_SHA1_HASH_SIZE;
1640 		sz_mdc = 1 + 1 + sz_mdc_hash;
1641 		sz_plaintext = (decrypted_region.length - sz_preamble) - sz_mdc;
1642 
1643 		preamble = buf;
1644 		plaintext = buf + sz_preamble;
1645 		mdc = plaintext + sz_plaintext;
1646 		mdc_hash = mdc + 2;
1647 
1648 		if (pgp_get_debug_level(__FILE__)) {
1649 			hexdump(stderr, "plaintext", plaintext, sz_plaintext);
1650 			hexdump(stderr, "mdc", mdc, sz_mdc);
1651 		}
1652 		pgp_calc_mdc_hash(preamble, sz_preamble, plaintext,
1653 				(unsigned)sz_plaintext, hashed);
1654 
1655 		if (memcmp(mdc_hash, hashed, PGP_SHA1_HASH_SIZE) != 0) {
1656 			PGP_ERROR(errors, PGP_E_V_BAD_HASH,
1657 					"Bad hash in MDC packet");
1658 			free(buf);
1659 			return 0;
1660 		}
1661 		/* all done with the checks */
1662 		/* now can start reading from the plaintext */
1663 		if (se_ip->plaintext) {
1664 			(void) fprintf(stderr,
1665 				"se_ip_data_reader: bad plaintext\n");
1666 			return 0;
1667 		}
1668 		if ((se_ip->plaintext = calloc(1, sz_plaintext)) == NULL) {
1669 			(void) fprintf(stderr,
1670 				"se_ip_data_reader: bad alloc\n");
1671 			return 0;
1672 		}
1673 		memcpy(se_ip->plaintext, plaintext, sz_plaintext);
1674 		se_ip->plaintext_available = sz_plaintext;
1675 
1676 		se_ip->passed_checks = 1;
1677 
1678 		free(buf);
1679 	}
1680 	n = (unsigned)len;
1681 	if (n > se_ip->plaintext_available) {
1682 		n = (unsigned)se_ip->plaintext_available;
1683 	}
1684 
1685 	memcpy(dest_, se_ip->plaintext + se_ip->plaintext_offset, n);
1686 	se_ip->plaintext_available -= n;
1687 	se_ip->plaintext_offset += n;
1688 	/* len -= n; - not used at all, for info only */
1689 
1690 	return n;
1691 }
1692 
1693 static void
1694 se_ip_data_destroyer(pgp_reader_t *readinfo)
1695 {
1696 	decrypt_se_ip_t	*se_ip;
1697 
1698 	se_ip = pgp_reader_get_arg(readinfo);
1699 	free(se_ip->plaintext);
1700 	free(se_ip);
1701 }
1702 
1703 /**
1704    \ingroup Internal_Readers_SEIP
1705 */
1706 void
1707 pgp_reader_push_se_ip_data(pgp_stream_t *stream, pgp_crypt_t *decrypt,
1708 			   pgp_region_t * region)
1709 {
1710 	decrypt_se_ip_t *se_ip;
1711 
1712 	if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
1713 		(void) fprintf(stderr, "pgp_reader_push_se_ip_data: bad alloc\n");
1714 	} else {
1715 		se_ip->region = region;
1716 		se_ip->decrypt = decrypt;
1717 		pgp_reader_push(stream, se_ip_data_reader, se_ip_data_destroyer,
1718 				se_ip);
1719 	}
1720 }
1721 
1722 /**
1723    \ingroup Internal_Readers_SEIP
1724  */
1725 void
1726 pgp_reader_pop_se_ip_data(pgp_stream_t *stream)
1727 {
1728 	/*
1729 	 * decrypt_se_ip_t
1730 	 * *se_ip=pgp_reader_get_arg(pgp_readinfo(stream));
1731 	 */
1732 	/* free(se_ip); */
1733 	pgp_reader_pop(stream);
1734 }
1735 
1736 /**************************************************************************/
1737 
1738 /** Arguments for reader_fd
1739  */
1740 typedef struct mmap_reader_t {
1741 	void		*mem;		/* memory mapped file */
1742 	uint64_t	 size;		/* size of file */
1743 	uint64_t	 offset;	/* current offset in file */
1744 	int		 fd;		/* file descriptor */
1745 } mmap_reader_t;
1746 
1747 
1748 /**
1749  * \ingroup Core_Readers
1750  *
1751  * pgp_reader_fd() attempts to read up to "plength" bytes from the file
1752  * descriptor in "parse_info" into the buffer starting at "dest" using the
1753  * rules contained in "flags"
1754  *
1755  * \param	dest	Pointer to previously allocated buffer
1756  * \param	plength Number of bytes to try to read
1757  * \param	flags	Rules about reading to use
1758  * \param	readinfo	Reader info
1759  * \param	cbinfo	Callback info
1760  *
1761  * \return	n	Number of bytes read
1762  *
1763  * PGP_R_EARLY_EOF and PGP_R_ERROR push errors on the stack
1764  */
1765 static int
1766 fd_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
1767 	  pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
1768 {
1769 	mmap_reader_t	*reader;
1770 	int		 n;
1771 
1772 	__PGP_USED(cbinfo);
1773 	reader = pgp_reader_get_arg(readinfo);
1774 	if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
1775 		n = read_partial_data(stream, dest, length);
1776 	} else {
1777 		n = (int)read(reader->fd, dest, length);
1778 	}
1779 	if (n == 0) {
1780 		return 0;
1781 	}
1782 	if (n < 0) {
1783 		PGP_SYSTEM_ERROR_1(errors, PGP_E_R_READ_FAILED, "read",
1784 				   "file descriptor %d", reader->fd);
1785 		return -1;
1786 	}
1787 	return n;
1788 }
1789 
1790 static void
1791 reader_fd_destroyer(pgp_reader_t *readinfo)
1792 {
1793 	free(pgp_reader_get_arg(readinfo));
1794 }
1795 
1796 /**
1797    \ingroup Core_Readers_First
1798    \brief Starts stack with file reader
1799 */
1800 
1801 void
1802 pgp_reader_set_fd(pgp_stream_t *stream, int fd)
1803 {
1804 	mmap_reader_t *reader;
1805 
1806 	if ((reader = calloc(1, sizeof(*reader))) == NULL) {
1807 		(void) fprintf(stderr, "pgp_reader_set_fd: bad alloc\n");
1808 	} else {
1809 		reader->fd = fd;
1810 		pgp_reader_set(stream, fd_reader, reader_fd_destroyer, reader);
1811 	}
1812 }
1813 
1814 /**************************************************************************/
1815 
1816 typedef struct {
1817 	const uint8_t *buffer;
1818 	size_t          length;
1819 	size_t          offset;
1820 } reader_mem_t;
1821 
1822 static int
1823 mem_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
1824 	   pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
1825 {
1826 	reader_mem_t *reader = pgp_reader_get_arg(readinfo);
1827 	unsigned        n;
1828 
1829 	__PGP_USED(cbinfo);
1830 	__PGP_USED(errors);
1831 	if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
1832 		n = read_partial_data(stream, dest, length);
1833 	} else {
1834 		if (reader->offset + length > reader->length) {
1835 			n = (unsigned)(reader->length - reader->offset);
1836 		} else {
1837 			n = (unsigned)length;
1838 		}
1839 		if (n == (unsigned)0) {
1840 			return 0;
1841 		}
1842 		memcpy(dest, reader->buffer + reader->offset, n);
1843 		reader->offset += n;
1844 	}
1845 	return n;
1846 }
1847 
1848 static void
1849 mem_destroyer(pgp_reader_t *readinfo)
1850 {
1851 	free(pgp_reader_get_arg(readinfo));
1852 }
1853 
1854 /**
1855    \ingroup Core_Readers_First
1856    \brief Starts stack with memory reader
1857 */
1858 
1859 void
1860 pgp_reader_set_memory(pgp_stream_t *stream, const void *buffer,
1861 		      size_t length)
1862 {
1863 	reader_mem_t *mem;
1864 
1865 	if ((mem = calloc(1, sizeof(*mem))) == NULL) {
1866 		(void) fprintf(stderr, "pgp_reader_set_memory: bad alloc\n");
1867 	} else {
1868 		mem->buffer = buffer;
1869 		mem->length = length;
1870 		mem->offset = 0;
1871 		pgp_reader_set(stream, mem_reader, mem_destroyer, mem);
1872 	}
1873 }
1874 
1875 /**************************************************************************/
1876 
1877 /**
1878  \ingroup Core_Writers
1879  \brief Create and initialise output and mem; Set for writing to mem
1880  \param output Address where new output pointer will be set
1881  \param mem Address when new mem pointer will be set
1882  \param bufsz Initial buffer size (will automatically be increased when necessary)
1883  \note It is the caller's responsiblity to free output and mem.
1884  \sa pgp_teardown_memory_write()
1885 */
1886 void
1887 pgp_setup_memory_write(pgp_output_t **output, pgp_memory_t **mem, size_t bufsz)
1888 {
1889 	/*
1890          * initialise needed structures for writing to memory
1891          */
1892 
1893 	*output = pgp_output_new();
1894 	*mem = pgp_memory_new();
1895 
1896 	pgp_memory_init(*mem, bufsz);
1897 
1898 	pgp_writer_set_memory(*output, *mem);
1899 }
1900 
1901 /**
1902    \ingroup Core_Writers
1903    \brief Closes writer and frees output and mem
1904    \param output
1905    \param mem
1906    \sa pgp_setup_memory_write()
1907 */
1908 void
1909 pgp_teardown_memory_write(pgp_output_t *output, pgp_memory_t *mem)
1910 {
1911 	pgp_writer_close(output);/* new */
1912 	pgp_output_delete(output);
1913 	pgp_memory_free(mem);
1914 }
1915 
1916 /**
1917    \ingroup Core_Readers
1918    \brief Create parse_info and sets to read from memory
1919    \param stream Address where new parse_info will be set
1920    \param mem Memory to read from
1921    \param arg Reader-specific arg
1922    \param callback Callback to use with reader
1923    \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification)
1924    \note It is the caller's responsiblity to free parse_info
1925    \sa pgp_teardown_memory_read()
1926 */
1927 void
1928 pgp_setup_memory_read(pgp_io_t *io,
1929 			pgp_stream_t **stream,
1930 			pgp_memory_t *mem,
1931 			void *vp,
1932 			pgp_cb_ret_t callback(const pgp_packet_t *,
1933 						pgp_cbdata_t *),
1934 			unsigned accumulate)
1935 {
1936 	*stream = pgp_new(sizeof(**stream));
1937 	(*stream)->io = (*stream)->cbinfo.io = io;
1938 	pgp_set_callback(*stream, callback, vp);
1939 	pgp_reader_set_memory(*stream,
1940 			      pgp_mem_data(mem),
1941 			      pgp_mem_len(mem));
1942 	if (accumulate) {
1943 		(*stream)->readinfo.accumulate = 1;
1944 	}
1945 }
1946 
1947 /**
1948    \ingroup Core_Readers
1949    \brief Frees stream and mem
1950    \param stream
1951    \param mem
1952    \sa pgp_setup_memory_read()
1953 */
1954 void
1955 pgp_teardown_memory_read(pgp_stream_t *stream, pgp_memory_t *mem)
1956 {
1957 	pgp_stream_delete(stream);
1958 	pgp_memory_free(mem);
1959 }
1960 
1961 /**
1962  \ingroup Core_Writers
1963  \brief Create and initialise output and mem; Set for writing to file
1964  \param output Address where new output pointer will be set
1965  \param filename File to write to
1966  \param allow_overwrite Allows file to be overwritten, if set.
1967  \return Newly-opened file descriptor
1968  \note It is the caller's responsiblity to free output and to close fd.
1969  \sa pgp_teardown_file_write()
1970 */
1971 int
1972 pgp_setup_file_write(pgp_output_t **output, const char *filename,
1973 			unsigned allow_overwrite)
1974 {
1975 	int             fd = 0;
1976 	int             flags = 0;
1977 
1978 	/*
1979          * initialise needed structures for writing to file
1980          */
1981 	if (filename == NULL) {
1982 		/* write to stdout */
1983 		fd = STDOUT_FILENO;
1984 	} else {
1985 		flags = O_WRONLY | O_CREAT;
1986 		if (allow_overwrite)
1987 			flags |= O_TRUNC;
1988 		else
1989 			flags |= O_EXCL;
1990 #ifdef O_BINARY
1991 		flags |= O_BINARY;
1992 #endif
1993 		fd = open(filename, flags, 0600);
1994 		if (fd < 0) {
1995 			perror(filename);
1996 			return fd;
1997 		}
1998 	}
1999 	*output = pgp_output_new();
2000 	pgp_writer_set_fd(*output, fd);
2001 	return fd;
2002 }
2003 
2004 /**
2005    \ingroup Core_Writers
2006    \brief Closes writer, frees info, closes fd
2007    \param output
2008    \param fd
2009 */
2010 void
2011 pgp_teardown_file_write(pgp_output_t *output, int fd)
2012 {
2013 	pgp_writer_close(output);
2014 	close(fd);
2015 	pgp_output_delete(output);
2016 }
2017 
2018 /**
2019    \ingroup Core_Writers
2020    \brief As pgp_setup_file_write, but appends to file
2021 */
2022 int
2023 pgp_setup_file_append(pgp_output_t **output, const char *filename)
2024 {
2025 	int	fd;
2026 
2027 	/*
2028          * initialise needed structures for writing to file
2029          */
2030 #ifdef O_BINARY
2031 	fd = open(filename, O_WRONLY | O_APPEND | O_BINARY, 0600);
2032 #else
2033 	fd = open(filename, O_WRONLY | O_APPEND, 0600);
2034 #endif
2035 	if (fd >= 0) {
2036 		*output = pgp_output_new();
2037 		pgp_writer_set_fd(*output, fd);
2038 	}
2039 	return fd;
2040 }
2041 
2042 /**
2043    \ingroup Core_Writers
2044    \brief As pgp_teardown_file_write()
2045 */
2046 void
2047 pgp_teardown_file_append(pgp_output_t *output, int fd)
2048 {
2049 	pgp_teardown_file_write(output, fd);
2050 }
2051 
2052 /**
2053    \ingroup Core_Readers
2054    \brief Creates parse_info, opens file, and sets to read from file
2055    \param stream Address where new parse_info will be set
2056    \param filename Name of file to read
2057    \param vp Reader-specific arg
2058    \param callback Callback to use when reading
2059    \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification)
2060    \note It is the caller's responsiblity to free parse_info and to close fd
2061    \sa pgp_teardown_file_read()
2062 */
2063 int
2064 pgp_setup_file_read(pgp_io_t *io,
2065 			pgp_stream_t **stream,
2066 			const char *filename,
2067 			void *vp,
2068 			pgp_cb_ret_t callback(const pgp_packet_t *,
2069 						pgp_cbdata_t *),
2070 			unsigned accumulate)
2071 {
2072 	int	fd;
2073 
2074 #ifdef O_BINARY
2075 	fd = open(filename, O_RDONLY | O_BINARY);
2076 #else
2077 	fd = open(filename, O_RDONLY);
2078 #endif
2079 	if (fd < 0) {
2080 		(void) fprintf(io->errs, "can't open \"%s\"\n", filename);
2081 		return fd;
2082 	}
2083 	*stream = pgp_new(sizeof(**stream));
2084 	(*stream)->io = (*stream)->cbinfo.io = io;
2085 	pgp_set_callback(*stream, callback, vp);
2086 #ifdef USE_MMAP_FOR_FILES
2087 	pgp_reader_set_mmap(*stream, fd);
2088 #else
2089 	pgp_reader_set_fd(*stream, fd);
2090 #endif
2091 	if (accumulate) {
2092 		(*stream)->readinfo.accumulate = 1;
2093 	}
2094 	return fd;
2095 }
2096 
2097 /**
2098    \ingroup Core_Readers
2099    \brief Frees stream and closes fd
2100    \param stream
2101    \param fd
2102    \sa pgp_setup_file_read()
2103 */
2104 void
2105 pgp_teardown_file_read(pgp_stream_t *stream, int fd)
2106 {
2107 	close(fd);
2108 	pgp_stream_delete(stream);
2109 }
2110 
2111 pgp_cb_ret_t
2112 pgp_litdata_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
2113 {
2114 	const pgp_contents_t	*content = &pkt->u;
2115 
2116 	if (pgp_get_debug_level(__FILE__)) {
2117 		printf("pgp_litdata_cb: ");
2118 		pgp_print_packet(&cbinfo->printstate, pkt);
2119 	}
2120 	/* Read data from packet into static buffer */
2121 	switch (pkt->tag) {
2122 	case PGP_PTAG_CT_LITDATA_BODY:
2123 		/* if writer enabled, use it */
2124 		if (cbinfo->output) {
2125 			if (pgp_get_debug_level(__FILE__)) {
2126 				printf("pgp_litdata_cb: length is %u\n",
2127 					content->litdata_body.length);
2128 			}
2129 			pgp_write(cbinfo->output,
2130 					content->litdata_body.data,
2131 					content->litdata_body.length);
2132 		}
2133 		break;
2134 
2135 	case PGP_PTAG_CT_LITDATA_HEADER:
2136 		/* ignore */
2137 		break;
2138 
2139 	default:
2140 		break;
2141 	}
2142 
2143 	return PGP_RELEASE_MEMORY;
2144 }
2145 
2146 pgp_cb_ret_t
2147 pgp_pk_sesskey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
2148 {
2149 	const pgp_contents_t	*content = &pkt->u;
2150 	unsigned		 from;
2151 	pgp_io_t		*io;
2152 
2153 	io = cbinfo->io;
2154 	if (pgp_get_debug_level(__FILE__)) {
2155 		pgp_print_packet(&cbinfo->printstate, pkt);
2156 	}
2157 	/* Read data from packet into static buffer */
2158 	switch (pkt->tag) {
2159 	case PGP_PTAG_CT_PK_SESSION_KEY:
2160 		if (pgp_get_debug_level(__FILE__)) {
2161 			printf("PGP_PTAG_CT_PK_SESSION_KEY\n");
2162 		}
2163 		if (!cbinfo->cryptinfo.secring) {
2164 			(void) fprintf(io->errs,
2165 				"pgp_pk_sesskey_cb: bad keyring\n");
2166 			return (pgp_cb_ret_t)0;
2167 		}
2168 		from = 0;
2169 		cbinfo->cryptinfo.keydata =
2170 			pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
2171 				content->pk_sesskey.key_id, &from, NULL);
2172 		if (!cbinfo->cryptinfo.keydata) {
2173 			break;
2174 		}
2175 		break;
2176 
2177 	default:
2178 		break;
2179 	}
2180 
2181 	return PGP_RELEASE_MEMORY;
2182 }
2183 
2184 /**
2185  \ingroup Core_Callbacks
2186 
2187 \brief Callback to get secret key, decrypting if necessary.
2188 
2189 @verbatim
2190  This callback does the following:
2191  * finds the session key in the keyring
2192  * gets a passphrase if required
2193  * decrypts the secret key, if necessary
2194  * sets the seckey in the content struct
2195 @endverbatim
2196 */
2197 
2198 pgp_cb_ret_t
2199 pgp_get_seckey_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
2200 {
2201 	const pgp_contents_t	*content = &pkt->u;
2202 	const pgp_seckey_t	*secret;
2203 	const pgp_key_t		*pubkey;
2204 	const pgp_key_t		*keypair;
2205 	unsigned		 from;
2206 	pgp_io_t		*io;
2207 	int			 i;
2208 
2209 	io = cbinfo->io;
2210 	if (pgp_get_debug_level(__FILE__)) {
2211 		pgp_print_packet(&cbinfo->printstate, pkt);
2212 	}
2213 	switch (pkt->tag) {
2214 	case PGP_GET_SECKEY:
2215 		/* print key from pubring */
2216 		from = 0;
2217 		pubkey = pgp_getkeybyid(io, cbinfo->cryptinfo.pubring,
2218 				content->get_seckey.pk_sesskey->key_id,
2219 				&from, NULL);
2220 		/* validate key from secring */
2221 		from = 0;
2222 		cbinfo->cryptinfo.keydata =
2223 			pgp_getkeybyid(io, cbinfo->cryptinfo.secring,
2224 				content->get_seckey.pk_sesskey->key_id,
2225 				&from, NULL);
2226 		if (!cbinfo->cryptinfo.keydata ||
2227 		    !pgp_is_key_secret(cbinfo->cryptinfo.keydata)) {
2228 			return (pgp_cb_ret_t)0;
2229 		}
2230 		keypair = cbinfo->cryptinfo.keydata;
2231 		if (pubkey == NULL) {
2232 			pubkey = keypair;
2233 		}
2234 		secret = NULL;
2235 		cbinfo->gotpass = 0;
2236 		for (i = 0 ; cbinfo->numtries == -1 || i < cbinfo->numtries ; i++) {
2237 			/* print out the user id */
2238 			pgp_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey,
2239 				"signature ", &pubkey->key.pubkey, 0);
2240 			/* now decrypt key */
2241 			secret = pgp_decrypt_seckey(keypair, cbinfo->passfp);
2242 			if (secret != NULL) {
2243 				break;
2244 			}
2245 			(void) fprintf(io->errs, "Bad passphrase\n");
2246 		}
2247 		if (secret == NULL) {
2248 			(void) fprintf(io->errs, "Exhausted passphrase attempts\n");
2249 			return (pgp_cb_ret_t)PGP_RELEASE_MEMORY;
2250 		}
2251 		cbinfo->gotpass = 1;
2252 		*content->get_seckey.seckey = secret;
2253 		break;
2254 
2255 	default:
2256 		break;
2257 	}
2258 
2259 	return PGP_RELEASE_MEMORY;
2260 }
2261 
2262 /**
2263  \ingroup HighLevel_Callbacks
2264  \brief Callback to use when you need to prompt user for passphrase
2265  \param contents
2266  \param cbinfo
2267 */
2268 pgp_cb_ret_t
2269 get_passphrase_cb(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
2270 {
2271 	const pgp_contents_t	*content = &pkt->u;
2272 	pgp_io_t		*io;
2273 
2274 	io = cbinfo->io;
2275 	if (pgp_get_debug_level(__FILE__)) {
2276 		pgp_print_packet(&cbinfo->printstate, pkt);
2277 	}
2278 	if (cbinfo->cryptinfo.keydata == NULL) {
2279 		(void) fprintf(io->errs, "get_passphrase_cb: NULL keydata\n");
2280 	} else {
2281 		pgp_print_keydata(io, cbinfo->cryptinfo.pubring, cbinfo->cryptinfo.keydata, "signature ",
2282 			&cbinfo->cryptinfo.keydata->key.pubkey, 0);
2283 	}
2284 	switch (pkt->tag) {
2285 	case PGP_GET_PASSPHRASE:
2286 		*(content->skey_passphrase.passphrase) =
2287 				netpgp_strdup(getpass("netpgp passphrase: "));
2288 		return PGP_KEEP_MEMORY;
2289 	default:
2290 		break;
2291 	}
2292 	return PGP_RELEASE_MEMORY;
2293 }
2294 
2295 unsigned
2296 pgp_reader_set_accumulate(pgp_stream_t *stream, unsigned state)
2297 {
2298 	return stream->readinfo.accumulate = state;
2299 }
2300 
2301 /**************************************************************************/
2302 
2303 static int
2304 hash_reader(pgp_stream_t *stream, void *dest,
2305 		size_t length,
2306 		pgp_error_t **errors,
2307 		pgp_reader_t *readinfo,
2308 		pgp_cbdata_t *cbinfo)
2309 {
2310 	pgp_hash_t	*hash = pgp_reader_get_arg(readinfo);
2311 	int		 r;
2312 
2313 	r = pgp_stacked_read(stream, dest, length, errors, readinfo, cbinfo);
2314 	if (r <= 0) {
2315 		return r;
2316 	}
2317 	hash->add(hash, dest, (unsigned)r);
2318 	return r;
2319 }
2320 
2321 /**
2322    \ingroup Internal_Readers_Hash
2323    \brief Push hashed data reader on stack
2324 */
2325 void
2326 pgp_reader_push_hash(pgp_stream_t *stream, pgp_hash_t *hash)
2327 {
2328 	if (!hash->init(hash)) {
2329 		(void) fprintf(stderr, "pgp_reader_push_hash: can't init hash\n");
2330 		/* just continue and die */
2331 		/* XXX - agc - no way to return failure */
2332 	}
2333 	pgp_reader_push(stream, hash_reader, NULL, hash);
2334 }
2335 
2336 /**
2337    \ingroup Internal_Readers_Hash
2338    \brief Pop hashed data reader from stack
2339 */
2340 void
2341 pgp_reader_pop_hash(pgp_stream_t *stream)
2342 {
2343 	pgp_reader_pop(stream);
2344 }
2345 
2346 /* read memory from the previously mmap-ed file */
2347 static int
2348 mmap_reader(pgp_stream_t *stream, void *dest, size_t length, pgp_error_t **errors,
2349 	  pgp_reader_t *readinfo, pgp_cbdata_t *cbinfo)
2350 {
2351 	mmap_reader_t	*mem = pgp_reader_get_arg(readinfo);
2352 	unsigned	 n;
2353 	char		*cmem = mem->mem;
2354 
2355 	__PGP_USED(errors);
2356 	__PGP_USED(cbinfo);
2357 	if (!stream->coalescing && stream->virtualc && stream->virtualoff < stream->virtualc) {
2358 		n = read_partial_data(stream, dest, length);
2359 	} else {
2360 		n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset));
2361 		if (n > 0) {
2362 			(void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
2363 			mem->offset += n;
2364 		}
2365 	}
2366 	return (int)n;
2367 }
2368 
2369 /* tear down the mmap, close the fd */
2370 static void
2371 mmap_destroyer(pgp_reader_t *readinfo)
2372 {
2373 	mmap_reader_t *mem = pgp_reader_get_arg(readinfo);
2374 
2375 	(void) munmap(mem->mem, (unsigned)mem->size);
2376 	(void) close(mem->fd);
2377 	free(pgp_reader_get_arg(readinfo));
2378 }
2379 
2380 /* set up the file to use mmap-ed memory if available, file IO otherwise */
2381 void
2382 pgp_reader_set_mmap(pgp_stream_t *stream, int fd)
2383 {
2384 	mmap_reader_t	*mem;
2385 	struct stat	 st;
2386 
2387 	if (fstat(fd, &st) != 0) {
2388 		(void) fprintf(stderr, "pgp_reader_set_mmap: can't fstat\n");
2389 	} else if ((mem = calloc(1, sizeof(*mem))) == NULL) {
2390 		(void) fprintf(stderr, "pgp_reader_set_mmap: bad alloc\n");
2391 	} else {
2392 		mem->size = (uint64_t)st.st_size;
2393 		mem->offset = 0;
2394 		mem->fd = fd;
2395 		mem->mem = mmap(NULL, (size_t)st.st_size, PROT_READ,
2396 				MAP_PRIVATE | MAP_FILE, fd, 0);
2397 		if (mem->mem == MAP_FAILED) {
2398 			pgp_reader_set(stream, fd_reader, reader_fd_destroyer,
2399 					mem);
2400 		} else {
2401 			pgp_reader_set(stream, mmap_reader, mmap_destroyer,
2402 					mem);
2403 		}
2404 	}
2405 }
2406