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 */
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
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 */
185void
186pgp_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 */
204void
205pgp_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 */
232void
233pgp_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 */
247void           *
248pgp_reader_get_arg(pgp_reader_t *readinfo)
249{
250	return readinfo->arg;
251}
252
253/**************************************************************************/
254
255#define CRC24_POLY 0x1864cfbL
256
257enum {
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 */
277typedef 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
317static void
318push_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 */
336typedef 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
342static 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 */
361static int
362findheaderline(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
374static int
375set_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
441static int
442read_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
467static int
468eat_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
483static int
484read_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
498static void
499flush(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
511static int
512unarmoured_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 */
539static const char *
540find_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 */
556static void
557dup_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 */
576static int
577process_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
710static int
711add_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 */
739static int
740parse_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
831end:
832	free(buf);
833
834	return ret;
835}
836
837static int
838read4(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
878unsigned
879pgp_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
892static int
893decode64(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
1033static void
1034base64(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
1046static int
1047armoured_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
1121got_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
1250got_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		}
1312reloop:
1313		continue;
1314	}
1315
1316	return saved;
1317}
1318
1319static void
1320armoured_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 */
1331void
1332pgp_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 */
1374void
1375pgp_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* */
1387typedef 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
1396static int
1397encrypted_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
1509static void
1510encrypted_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 */
1520void
1521pgp_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 */
1542void
1543pgp_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
1555typedef 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*/
1572static int
1573se_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
1693static void
1694se_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*/
1706void
1707pgp_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 */
1725void
1726pgp_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 */
1740typedef 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 */
1765static int
1766fd_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
1790static void
1791reader_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
1801void
1802pgp_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
1816typedef struct {
1817	const uint8_t *buffer;
1818	size_t          length;
1819	size_t          offset;
1820} reader_mem_t;
1821
1822static int
1823mem_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
1848static void
1849mem_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
1859void
1860pgp_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*/
1886void
1887pgp_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*/
1908void
1909pgp_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*/
1927void
1928pgp_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*/
1954void
1955pgp_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*/
1971int
1972pgp_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*/
2010void
2011pgp_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*/
2022int
2023pgp_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*/
2046void
2047pgp_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*/
2063int
2064pgp_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*/
2104void
2105pgp_teardown_file_read(pgp_stream_t *stream, int fd)
2106{
2107	close(fd);
2108	pgp_stream_delete(stream);
2109}
2110
2111pgp_cb_ret_t
2112pgp_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
2146pgp_cb_ret_t
2147pgp_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
2198pgp_cb_ret_t
2199pgp_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*/
2268pgp_cb_ret_t
2269get_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
2295unsigned
2296pgp_reader_set_accumulate(pgp_stream_t *stream, unsigned state)
2297{
2298	return stream->readinfo.accumulate = state;
2299}
2300
2301/**************************************************************************/
2302
2303static int
2304hash_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*/
2325void
2326pgp_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*/
2340void
2341pgp_reader_pop_hash(pgp_stream_t *stream)
2342{
2343	pgp_reader_pop(stream);
2344}
2345
2346/* read memory from the previously mmap-ed file */
2347static int
2348mmap_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 */
2370static void
2371mmap_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 */
2381void
2382pgp_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