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