1/*-
2 * Copyright (c) 2012,2013,2014,2015,2016 Alistair Crooks <agc@NetBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25#include "config.h"
26
27#include <sys/types.h>
28#include <sys/stat.h>
29#include <sys/param.h>
30#include <sys/mman.h>
31
32#include <arpa/inet.h>
33
34#include <inttypes.h>
35#include <limits.h>
36#include <stdarg.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <time.h>
41#include <unistd.h>
42
43#include "netpgpv-bzlib.h"
44#include "zlib.h"
45
46#include "array.h"
47#include "b64.h"
48#include "bn.h"
49#include "bufgap.h"
50#include "digest.h"
51#include "misc.h"
52#include "pgpsum.h"
53#include "rsa.h"
54#include "verify.h"
55
56#ifndef PRIi64
57#define PRIi64	"lld"
58#endif
59
60/* 64bit key ids */
61#define PGPV_KEYID_LEN		8
62#define PGPV_STR_KEYID_LEN	(PGPV_KEYID_LEN + PGPV_KEYID_LEN + 1)
63
64/* bignum structure */
65typedef struct pgpv_bignum_t {
66	void			*bn;	/* hide the implementation details */
67	uint16_t		 bits;	/* cached number of bits */
68} pgpv_bignum_t;
69
70/* right now, our max binary digest length is 20 bytes */
71#define PGPV_MAX_HASH_LEN	64
72
73/* fingerprint */
74typedef struct pgpv_fingerprint_t {
75	uint8_t			hashalg;	/* algorithm for digest */
76	uint8_t			v[PGPV_MAX_HASH_LEN];	/* the digest */
77	uint32_t		len;		/* its length */
78} pgpv_fingerprint_t;
79
80/* specify size for array of bignums */
81#define PGPV_MAX_PUBKEY_BN	4
82
83/* public key */
84typedef struct pgpv_pubkey_t {
85	pgpv_fingerprint_t	 fingerprint;	/* key fingerprint i.e. digest */
86	uint8_t			 keyid[PGPV_KEYID_LEN];	/* last 8 bytes of v4 keys */
87	int64_t		 	 birth;		/* creation time */
88	int64_t			 expiry;	/* expiry time */
89	pgpv_bignum_t		 bn[PGPV_MAX_PUBKEY_BN]; /* bignums */
90	uint8_t			 keyalg;	/* key algorithm */
91	uint8_t			 hashalg;	/* hash algorithm */
92	uint8_t			 version;	/* key version */
93} pgpv_pubkey_t;
94
95#define PGPV_MAX_SESSKEY_BN	2
96
97/* a (size, byte array) string */
98typedef struct pgpv_string_t {
99	size_t			 size;
100	uint8_t			*data;
101	uint8_t			 allocated;
102} pgpv_string_t;
103
104typedef struct pgpv_ref_t {
105	void			*vp;
106	size_t			 offset;
107	unsigned		 mem;
108} pgpv_ref_t;
109
110#define PGPV_MAX_SECKEY_BN	4
111
112typedef struct pgpv_compress_t {
113	pgpv_string_t		 s;
114	uint8_t			 compalg;
115} pgpv_compress_t;
116
117/* a packet dealing with trust */
118typedef struct pgpv_trust_t {
119	uint8_t			level;
120	uint8_t			amount;
121} pgpv_trust_t;
122
123/* a signature sub packet */
124typedef struct pgpv_sigsubpkt_t {
125	pgpv_string_t		 s;
126	uint8_t			 tag;
127	uint8_t			 critical;
128} pgpv_sigsubpkt_t;
129
130#define PGPV_MAX_SIG_BN		2
131
132typedef struct pgpv_signature_t {
133	uint8_t			 signer[PGPV_KEYID_LEN]; /* key id of signer */
134	pgpv_ref_t		 hashstart;
135	uint8_t			*hash2;
136	uint8_t			*mpi;
137	int64_t			 birth;
138	int64_t			 keyexpiry;
139	int64_t			 expiry;
140	uint32_t		 hashlen;
141	uint8_t			 version;
142	uint8_t			 type;
143	uint8_t			 keyalg;
144	uint8_t			 hashalg;
145	uint8_t			 trustlevel;
146	uint8_t			 trustamount;
147	pgpv_bignum_t		 bn[PGPV_MAX_SIG_BN];
148	char			*regexp;
149	char			*pref_key_server;
150	char			*policy;
151	char			*features;
152	char			*why_revoked;
153	uint8_t			*revoke_fingerprint;
154	uint8_t			*issuer_fingerprint;
155	uint8_t			 ifver;
156	uint8_t			 revoke_alg;
157	uint8_t			 revoke_sensitive;
158	uint8_t			 trustsig;
159	uint8_t			 revocable;
160	uint8_t			 pref_symm_alg;
161	uint8_t			 pref_hash_alg;
162	uint8_t			 pref_compress_alg;
163	uint8_t			 key_server_modify;
164	uint8_t			 notation;
165	uint8_t			 type_key;
166	uint8_t			 primary_userid;
167	uint8_t			 revoked;	/* subtract 1 to get real reason, 0 == not revoked */
168} pgpv_signature_t;
169
170/* a signature packet */
171typedef struct pgpv_sigpkt_t {
172	pgpv_signature_t	 sig;
173	uint16_t		 subslen;
174	uint16_t		 unhashlen;
175	ARRAY(uint64_t,	 	 subpackets);
176} pgpv_sigpkt_t;
177
178/* a one-pass signature packet */
179typedef struct pgpv_onepass_t {
180	uint8_t			 keyid[PGPV_KEYID_LEN];
181	uint8_t			 version;
182	uint8_t			 type;
183	uint8_t			 hashalg;
184	uint8_t			 keyalg;
185	uint8_t			 nested;
186} pgpv_onepass_t;
187
188/* a literal data packet */
189typedef struct pgpv_litdata_t {
190	pgpv_string_t		 filename;
191	pgpv_string_t		 s;
192	uint32_t		 secs;
193	uint8_t			 namelen;
194	char			 format;
195	unsigned		 mem;
196	size_t			 offset;
197	size_t			 len;
198} pgpv_litdata_t;
199
200/* user attributes - images */
201typedef struct pgpv_userattr_t {
202	size_t 			 len;
203	ARRAY(pgpv_string_t, 	 subattrs);
204} pgpv_userattr_t;
205
206/* a general PGP packet */
207typedef struct pgpv_pkt_t {
208	uint8_t			 tag;
209	uint8_t			 newfmt;
210	uint8_t			 allocated;
211	uint8_t			 mement;
212	size_t			 offset;
213	pgpv_string_t		 s;
214	union {
215		pgpv_sigpkt_t	sigpkt;
216		pgpv_onepass_t	onepass;
217		pgpv_litdata_t	litdata;
218		pgpv_compress_t	compressed;
219		pgpv_trust_t	trust;
220		pgpv_pubkey_t	pubkey;
221		pgpv_string_t	userid;
222		pgpv_userattr_t	userattr;
223	} u;
224} pgpv_pkt_t;
225
226/* a memory structure */
227typedef struct pgpv_mem_t {
228	size_t			 size;
229	size_t			 cc;
230	uint8_t			*mem;
231	FILE			*fp;
232	uint8_t			 dealloc;
233	const char		*allowed;	/* the types of packet that are allowed */
234} pgpv_mem_t;
235
236/* packet parser */
237
238typedef struct pgpv_signed_userid_t {
239	pgpv_string_t	 	 userid;
240	ARRAY(uint64_t, 	 signatures);
241	uint8_t			 primary_userid;
242	uint8_t			 revoked;
243} pgpv_signed_userid_t;
244
245typedef struct pgpv_signed_userattr_t {
246	pgpv_userattr_t	 	 userattr;
247	ARRAY(uint64_t, 	 signatures);
248	uint8_t			 revoked;
249} pgpv_signed_userattr_t;
250
251typedef struct pgpv_signed_subkey_t {
252	pgpv_pubkey_t	 	 subkey;
253	pgpv_signature_t 	 revoc_self_sig;
254	ARRAY(uint64_t, 	 signatures);
255} pgpv_signed_subkey_t;
256
257typedef struct pgpv_primarykey_t {
258	pgpv_pubkey_t 		 primary;
259	pgpv_signature_t 	 revoc_self_sig;
260	ARRAY(uint64_t, 	 signatures);
261	ARRAY(uint64_t, 	 signed_userids);
262	ARRAY(uint64_t, 	 signed_userattrs);
263	ARRAY(uint64_t, 	 signed_subkeys);
264	size_t			 fmtsize;
265	uint8_t			 primary_userid;
266} pgpv_primarykey_t;
267
268/* everything stems from this structure */
269struct pgpv_t {
270	ARRAY(pgpv_pkt_t, 	 pkts);		/* packet array */
271	ARRAY(pgpv_primarykey_t, primaries);	/* array of primary keys */
272	ARRAY(pgpv_mem_t,	 areas);	/* areas we read packets from */
273	ARRAY(size_t,	 	 datastarts);	/* starts of data packets */
274	ARRAY(pgpv_signature_t,	 signatures);	/* all signatures */
275	ARRAY(pgpv_signed_userid_t, signed_userids); /* all signed userids */
276	ARRAY(pgpv_signed_userattr_t, signed_userattrs); /* all signed user attrs */
277	ARRAY(pgpv_signed_subkey_t, signed_subkeys); /* all signed subkeys */
278	ARRAY(pgpv_sigsubpkt_t,	 subpkts);	/* all sub packets */
279	size_t		 	 pkt;		/* when parsing, current pkt number */
280	const char		*op;		/* the operation we're doing */
281	unsigned		 ssh;		/* using ssh keys */
282};
283
284#define PGPV_REASON_LEN		128
285
286/* when searching, we define a cursor, and fill in an array of subscripts */
287struct pgpv_cursor_t {
288	pgpv_t			*pgp;			/* pointer to pgp tree */
289	char			*field;			/* field we're searching on */
290	char			*op;			/* operation we're doing */
291	char			*value;			/* value we're searching for */
292	void			*ptr;			/* for regexps etc */
293	ARRAY(uint32_t,	 	 found);		/* array of matched pimary key subscripts */
294	ARRAY(size_t,	 	 datacookies);		/* cookies to retrieve matched data */
295	int64_t			 sigtime;		/* time of signature */
296	char			 why[PGPV_REASON_LEN];	/* reason for bad signature */
297};
298
299#ifndef USE_ARG
300#define USE_ARG(x)	/*LINTED*/(void)&(x)
301#endif
302
303#ifndef __dead
304#define __dead				__attribute__((__noreturn__))
305#endif
306
307#ifndef __printflike
308#define __printflike(n, m)		__attribute__((format(printf,n,m)))
309#endif
310
311#ifndef MIN
312#define MIN(a,b)			(((a)<(b))?(a):(b))
313#endif
314
315#ifndef howmany
316#define howmany(x, y)   		(((x)+((y)-1))/(y))
317#endif
318
319#define BITS_TO_BYTES(b)		(((b) + (CHAR_BIT - 1)) / CHAR_BIT)
320
321/* packet types */
322#define SIGNATURE_PKT			2
323#define ONEPASS_SIGNATURE_PKT		4
324#define PUBKEY_PKT			6
325#define COMPRESSED_DATA_PKT		8
326#define MARKER_PKT			10
327#define LITDATA_PKT			11
328#define TRUST_PKT			12
329#define USERID_PKT			13
330#define PUB_SUBKEY_PKT			14
331#define USER_ATTRIBUTE_PKT		17
332
333/* only allow certain packets at certain times */
334#define PUBRING_ALLOWED			"\002\006\014\015\016\021"
335#define SIGNATURE_ALLOWED		"\002\004\010\013"
336
337/* actions to do on close */
338#define FREE_MEM			0x01
339#define UNMAP_MEM			0x02
340
341/* types of pubkey we encounter */
342#define PUBKEY_RSA_ENCRYPT_OR_SIGN	1
343#define PUBKEY_RSA_ENCRYPT		2
344#define PUBKEY_RSA_SIGN			3
345#define PUBKEY_ELGAMAL_ENCRYPT		16
346#define PUBKEY_DSA			17
347#define PUBKEY_ECDH			18
348#define PUBKEY_ECDSA			19
349#define PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN	20
350
351/* hash algorithm definitions */
352#define PGPV_HASH_MD5			1
353#define PGPV_HASH_SHA1			2
354#define PGPV_HASH_RIPEMD		3
355#define PGPV_HASH_SHA256		8
356#define PGPV_HASH_SHA384		9
357#define PGPV_HASH_SHA512		10
358
359/* pubkey defs for bignums */
360#define RSA_N				0
361#define RSA_E				1
362#define DSA_P				0
363#define DSA_Q				1
364#define DSA_G				2
365#define DSA_Y				3
366#define ELGAMAL_P			0
367#define ELGAMAL_G			1
368#define ELGAMAL_Y			2
369
370/* sesskey indices */
371#define RSA_SESSKEY_ENCRYPTED_M		0
372#define RSA_SESSKEY_M			1
373#define ELGAMAL_SESSKEY_G_TO_K		0
374#define ELGAMAL_SESSKEY_ENCRYPTED_M	1
375
376/* seckey indices */
377#define RSA_SECKEY_D			0
378#define RSA_SECKEY_P			1
379#define RSA_SECKEY_Q			2
380#define RSA_SECKEY_U			3
381#define DSA_SECKEY_X			0
382#define ELGAMAL_SECKEY_X		0
383
384/* signature mpi indices in bignumber array */
385#define RSA_SIG				0
386#define DSA_R				0
387#define DSA_S				1
388#define ELGAMAL_SIG_R			0
389#define ELGAMAL_SIG_S			1
390
391/* signature types */
392#define SIGTYPE_BINARY_DOC		0x00	/* Signature of a binary document */
393#define SIGTYPE_TEXT			0x01	/* Signature of a canonical text document */
394#define SIGTYPE_STANDALONE		0x02	/* Standalone signature */
395
396#define SIGTYPE_GENERIC_USERID		0x10	/* Generic certification of a User ID and Public Key packet */
397#define SIGTYPE_PERSONA_USERID		0x11	/* Persona certification of a User ID and Public Key packet */
398#define SIGTYPE_CASUAL_USERID		0x12	/* Casual certification of a User ID and Public Key packet */
399#define SIGTYPE_POSITIVE_USERID		0x13	/* Positive certification of a User ID and Public Key packet */
400
401#define SIGTYPE_SUBKEY_BINDING		0x18	/* Subkey Binding Signature */
402#define SIGTYPE_PRIMARY_KEY_BINDING	0x19	/* Primary Key Binding Signature */
403#define SIGTYPE_DIRECT_KEY		0x1f	/* Signature directly on a key */
404
405#define SIGTYPE_KEY_REVOCATION		0x20	/* Key revocation signature */
406#define SIGTYPE_SUBKEY_REVOCATION	0x28	/* Subkey revocation signature */
407#define SIGTYPE_CERT_REVOCATION		0x30	/* Certification revocation signature */
408
409#define SIGTYPE_TIMESTAMP_SIG		0x40	/* Timestamp signature */
410#define SIGTYPE_3RDPARTY		0x50	/* Third-Party Confirmation signature */
411
412/* Forward declarations */
413static int read_all_packets(pgpv_t */*pgp*/, pgpv_mem_t */*mem*/, const char */*op*/);
414static int read_binary_file(pgpv_t */*pgp*/, const char */*op*/, const char */*fmt*/, ...) __printflike(3, 4);
415static int read_binary_memory(pgpv_t */*pgp*/, const char */*op*/, const void */*memory*/, size_t /*size*/);
416
417/* output buffer structure */
418typedef struct obuf_t {
419	size_t	 alloc;		/* amount of memory allocated */
420	size_t	 c;		/* # of chars used so far */
421	uint8_t	*v;		/* array of bytes */
422	uint32_t endian;	/* byte order of output stream */
423} obuf_t;
424
425/* grow the buffer, if needed */
426static int
427growbuf(obuf_t *obuf, size_t cc)
428{
429	size_t	 newalloc;
430	uint8_t	*newv;
431
432	if (obuf->c + cc > obuf->alloc) {
433		newalloc = howmany(obuf->alloc + cc, 128) * 128;
434		newv = realloc(obuf->v, newalloc);
435		if (newv == NULL) {
436			return 0;
437		}
438		obuf->v = newv;
439		obuf->alloc = newalloc;
440	}
441	return 1;
442}
443
444/* add a fixed-length area of memory */
445static int
446obuf_add_mem(obuf_t *obuf, const void *s, size_t len)
447{
448	if (obuf && s && len > 0) {
449		if (!growbuf(obuf, len)) {
450			return 0;
451		}
452		memcpy(&obuf->v[obuf->c], s, len);
453		obuf->c += len;
454		return 1;
455	}
456	return 0;
457}
458
459/* read a file into the pgpv_mem_t struct */
460static int
461read_file(pgpv_t *pgp, const char *f)
462{
463	struct stat	 st;
464	pgpv_mem_t	*mem;
465
466	ARRAY_EXPAND(pgp->areas);
467	ARRAY_COUNT(pgp->areas) += 1;
468	mem = &ARRAY_LAST(pgp->areas);
469	memset(mem, 0x0, sizeof(*mem));
470	if ((mem->fp = fopen(f, "r")) == NULL) {
471		fprintf(stderr, "can't read '%s'", f);
472		return 0;
473	}
474	fstat(fileno(mem->fp), &st);
475	mem->size = (size_t)st.st_size;
476	mem->mem = mmap(NULL, mem->size, PROT_READ, MAP_SHARED, fileno(mem->fp), 0);
477	mem->dealloc = UNMAP_MEM;
478	return 1;
479}
480
481/* DTRT and free resources */
482static int
483closemem(pgpv_mem_t *mem)
484{
485	switch(mem->dealloc) {
486	case FREE_MEM:
487		free(mem->mem);
488		mem->size = 0;
489		break;
490	case UNMAP_MEM:
491		munmap(mem->mem, mem->size);
492		fclose(mem->fp);
493		break;
494	}
495	return 1;
496}
497
498/* make a reference to a memory area, and its offset */
499static void
500make_ref(pgpv_t *pgp, uint8_t mement, pgpv_ref_t *ref)
501{
502	ref->mem = mement;
503	ref->offset = ARRAY_ELEMENT(pgp->areas, ref->mem).cc;
504	ref->vp = pgp;
505}
506
507/* return the pointer we wanted originally */
508static uint8_t *
509get_ref(pgpv_ref_t *ref)
510{
511	pgpv_mem_t	*mem;
512	pgpv_t		*pgp = (pgpv_t *)ref->vp;
513
514	mem = &ARRAY_ELEMENT(pgp->areas, ref->mem);
515	return &mem->mem[ref->offset];
516}
517
518#define IS_PARTIAL(x)		((x) >= 224 && (x) < 255)
519#define DECODE_PARTIAL(x)	(1 << ((x) & 0x1f))
520
521#define PKT_LENGTH(m, off)						\
522	((m[off] < 192) ? (m[off]) : 					\
523	 (m[off] < 224) ? ((m[off] - 192) << 8) + (m[off + 1]) + 192 :	\
524	 (m[off + 1] << 24) | ((m[off + 2]) << 16) | ((m[off + 3]) << 8)  | (m[off + 4]))
525
526#define PKT_LENGTH_LENGTH(m, off)					\
527	((m[off] < 192) ? 1 : (m[off] < 224) ? 2 : 5)
528
529/* fix up partial body lengths, return new size */
530static size_t
531fixup_partials(pgpv_t *pgp, uint8_t *p, size_t totlen, size_t filesize, size_t *cc)
532{
533	pgpv_mem_t	*mem;
534	size_t		 partial;
535	size_t		 newcc;
536
537	if (totlen > filesize) {
538		printf("fixup_partial: filesize %zu is less than encoded size %zu\n", filesize, totlen);
539		return 0;
540	}
541	ARRAY_EXPAND(pgp->areas);
542	ARRAY_COUNT(pgp->areas) += 1;
543	mem = &ARRAY_LAST(pgp->areas);
544	mem->size = totlen;
545	if ((mem->mem = calloc(1, mem->size + 5)) == NULL) {
546		printf("fixup_partial: can't allocate %zu length\n", totlen);
547		return 0;
548	}
549	newcc = 0;
550	mem->dealloc = FREE_MEM;
551	for (*cc = 0 ; *cc < totlen ; newcc += partial, *cc += partial + 1) {
552		if (IS_PARTIAL(p[*cc])) {
553			partial = DECODE_PARTIAL(p[*cc]);
554			memcpy(&mem->mem[newcc], &p[*cc + 1], partial);
555		} else {
556			partial = PKT_LENGTH(p, *cc);
557			*cc += PKT_LENGTH_LENGTH(p, *cc);
558			memcpy(&mem->mem[newcc], &p[*cc], partial);
559			newcc += partial;
560			*cc += partial;
561			break;
562		}
563	}
564	return newcc;
565}
566
567/* get the weirdo packet length */
568static size_t
569get_pkt_len(uint8_t newfmt, uint8_t *p, size_t filesize, int isprimary)
570{
571	size_t	lenbytes;
572	size_t	len;
573
574	if (newfmt) {
575		if (IS_PARTIAL(*p)) {
576			if (!isprimary) {
577				/* for sub-packets, only 1, 2 or 4 byte sizes allowed */
578				return ((*p - 192) << 8) + *(p + 1) + 192;
579			}
580			lenbytes = 1;
581			for (len = DECODE_PARTIAL(*p) ; IS_PARTIAL(p[len + lenbytes]) ; lenbytes++) {
582				len += DECODE_PARTIAL(p[len + lenbytes]);
583			}
584			len += get_pkt_len(newfmt, &p[len + lenbytes], filesize, 1);
585			return len;
586		}
587		return PKT_LENGTH(p, 0);
588	} else {
589		switch(*--p & 0x3) {
590		case 0:
591			return *(p + 1);
592		case 1:
593			return (*(p + 1) << 8) | *(p + 2);
594		case 2:
595			return (*(p + 1) << 24) | (*(p + 2) << 16) | (*(p + 3) << 8)  | *(p + 4);
596		default:
597			return filesize;
598		}
599	}
600}
601
602static const uint8_t	base64s[] =
603/* 000 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
604/* 016 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
605/* 032 */       "\0\0\0\0\0\0\0\0\0\0\0?\0\0\0@"
606/* 048 */       "56789:;<=>\0\0\0\0\0\0"
607/* 064 */       "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17"
608/* 080 */       "\20\21\22\23\24\25\26\27\30\31\32\0\0\0\0\0"
609/* 096 */       "\0\33\34\35\36\37 !\"#$%&'()"
610/* 112 */       "*+,-./01234\0\0\0\0\0"
611/* 128 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
612/* 144 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
613/* 160 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
614/* 176 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
615/* 192 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
616/* 208 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
617/* 224 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
618/* 240 */       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
619
620
621/* short function to decode from base64 */
622/* inspired by an ancient copy of b64.c, then rewritten, the bugs are all mine */
623static int
624frombase64(char *dst, const char *src, size_t size, int flag)
625{
626	uint8_t	out[3];
627	uint8_t	in[4];
628	uint8_t	b;
629	size_t	srcc;
630	int	dstc;
631	int	gotc;
632	int	i;
633
634	USE_ARG(flag);
635	for (dstc = 0, srcc = 0 ; srcc < size; ) {
636		for (gotc = 0, i = 0; i < 4 && srcc < size; i++) {
637			for (b = 0x0; srcc < size && b == 0x0 ; ) {
638				b = base64s[(unsigned)src[srcc++]];
639			}
640			if (srcc < size) {
641				gotc += 1;
642				if (b) {
643					in[i] = (uint8_t)(b - 1);
644				}
645			} else {
646				in[i] = 0x0;
647			}
648		}
649		if (gotc) {
650			out[0] = (uint8_t)((unsigned)in[0] << 2 |
651						(unsigned)in[1] >> 4);
652			out[1] = (uint8_t)((unsigned)in[1] << 4 |
653						(unsigned)in[2] >> 2);
654			out[2] = (uint8_t)(((in[2] << 6) & 0xc0) | in[3]);
655			for (i = 0; i < gotc - 1; i++) {
656				*dst++ = out[i];
657			}
658			dstc += gotc - 1;
659		}
660	}
661	return dstc;
662}
663
664/* get the length of the packet length field */
665static unsigned
666get_pkt_len_len(uint8_t newfmt, uint8_t *p, int isprimary)
667{
668	if (newfmt) {
669		if (IS_PARTIAL(*p)) {
670			return (isprimary) ? 1 : 2;
671		}
672		return PKT_LENGTH_LENGTH(p, 0);
673	} else {
674		switch(*--p & 0x3) {
675		case 0:
676			return 1;
677		case 1:
678			return 2;
679		case 2:
680			return 4;
681		default:
682			return 0;
683		}
684	}
685}
686
687/* copy the 32bit integer in memory in network order */
688static unsigned
689fmt_32(uint8_t *p, uint32_t a)
690{
691	a = pgp_hton32(a);
692	memcpy(p, &a, sizeof(a));
693	return sizeof(a);
694}
695
696/* copy the 16bit integer in memory in network order */
697static unsigned
698fmt_16(uint8_t *p, uint16_t a)
699{
700	a = pgp_hton16(a);
701	memcpy(p, &a, sizeof(a));
702	return sizeof(a);
703}
704
705/* format a binary string in memory */
706static size_t
707fmt_binary(obuf_t *obuf, const uint8_t *bin, unsigned len)
708{
709	unsigned	i;
710	char		newbuf[3];
711
712	for (i = 0 ; i < len ; i++) {
713		snprintf(newbuf, sizeof(newbuf), "%02hhx", bin[i]);
714		if (!obuf_add_mem(obuf, newbuf, 2)) {
715			return 0;
716		}
717	}
718	return 1;
719}
720
721/* format an mpi into memory */
722static unsigned
723fmt_binary_mpi(pgpv_bignum_t *mpi, uint8_t *p, size_t size)
724{
725	unsigned	 bytes;
726	PGPV_BIGNUM		*bn;
727
728	bytes = BITS_TO_BYTES(mpi->bits);
729	if ((size_t)bytes + 2 + 1 > size) {
730		fprintf(stderr, "truncated mpi");
731		return 0;
732	}
733	bn = (PGPV_BIGNUM *)mpi->bn;
734	if (bn == NULL || PGPV_BN_is_zero(bn)) {
735		fmt_32(p, 0);
736		return 2 + 1;
737	}
738	fmt_16(p, mpi->bits);
739	PGPV_BN_bn2bin(bn, &p[2]);
740	return bytes + 2;
741}
742
743/* dump an mpi value onto stdout */
744static size_t
745fmt_mpi(char *s, size_t size, pgpv_bignum_t *bn, const char *name, int pbits)
746{
747	size_t	 cc;
748	char	*buf;
749
750	cc = snprintf(s, size, "%s=", name);
751	if (pbits) {
752		cc += snprintf(&s[cc], size - cc, "[%u bits] ", bn->bits);
753	}
754	buf = PGPV_BN_bn2hex(bn->bn);
755	cc += snprintf(&s[cc], size - cc, "%s\n", buf);
756	free(buf);
757	return cc;
758}
759
760#define ALG_IS_RSA(alg)	(((alg) == PUBKEY_RSA_ENCRYPT_OR_SIGN) ||	\
761			 ((alg) == PUBKEY_RSA_ENCRYPT) ||		\
762			 ((alg) == PUBKEY_RSA_SIGN))
763
764#define ALG_IS_DSA(alg)	((alg) == PUBKEY_DSA)
765
766/* format key mpis into memory */
767static unsigned
768fmt_key_mpis(pgpv_pubkey_t *pubkey, uint8_t *buf, size_t size)
769{
770	size_t	cc;
771
772	cc = 0;
773	buf[cc++] = pubkey->version;
774	cc += fmt_32(&buf[cc], (uint32_t)pubkey->birth); /* XXX - do this portably! */
775	buf[cc++] = pubkey->keyalg;	/* XXX - sign, or encrypt and sign? */
776	switch(pubkey->keyalg) {
777	case PUBKEY_RSA_ENCRYPT_OR_SIGN:
778	case PUBKEY_RSA_ENCRYPT:
779	case PUBKEY_RSA_SIGN:
780		cc += fmt_binary_mpi(&pubkey->bn[RSA_N], &buf[cc], size - cc);
781		cc += fmt_binary_mpi(&pubkey->bn[RSA_E], &buf[cc], size - cc);
782		break;
783	case PUBKEY_DSA:
784		cc += fmt_binary_mpi(&pubkey->bn[DSA_P], &buf[cc], size - cc);
785		cc += fmt_binary_mpi(&pubkey->bn[DSA_Q], &buf[cc], size - cc);
786		cc += fmt_binary_mpi(&pubkey->bn[DSA_G], &buf[cc], size - cc);
787		cc += fmt_binary_mpi(&pubkey->bn[DSA_Y], &buf[cc], size - cc);
788		break;
789	default:
790		cc += fmt_binary_mpi(&pubkey->bn[ELGAMAL_P], &buf[cc], size - cc);
791		cc += fmt_binary_mpi(&pubkey->bn[ELGAMAL_G], &buf[cc], size - cc);
792		cc += fmt_binary_mpi(&pubkey->bn[ELGAMAL_Y], &buf[cc], size - cc);
793		break;
794	}
795	return (unsigned)cc;
796}
797
798/* calculate the fingerprint, RFC 4880, section 12.2 */
799static int
800pgpv_calc_fingerprint(pgpv_fingerprint_t *fingerprint, pgpv_pubkey_t *pubkey, const char *hashtype)
801{
802	digest_t	 fphash;
803	uint16_t	 cc;
804	uint8_t		 ch = 0x99;
805	uint8_t		 buf[8192 + 2 + 1];
806	uint8_t		 len[2];
807
808	memset(&fphash, 0x0, sizeof(fphash));
809	if (pubkey->version == 4) {
810		/* v4 keys */
811		fingerprint->hashalg = digest_get_alg(hashtype);
812		digest_init(&fphash, (unsigned)fingerprint->hashalg);
813		cc = fmt_key_mpis(pubkey, buf, sizeof(buf));
814		digest_update(&fphash, &ch, 1);
815		fmt_16(len, cc);
816		digest_update(&fphash, len, 2);
817		digest_update(&fphash, buf, (unsigned)cc);
818		fingerprint->len = digest_final(fingerprint->v, &fphash);
819		return 1;
820	}
821	if (ALG_IS_RSA(pubkey->keyalg)) {
822		/* v3 keys are RSA */
823		fingerprint->hashalg = digest_get_alg("md5");
824		digest_init(&fphash, (unsigned)fingerprint->hashalg);
825		if (pubkey->bn[RSA_N].bn && pubkey->bn[RSA_E].bn) {
826			cc = fmt_binary_mpi(&pubkey->bn[RSA_N], buf, sizeof(buf));
827			digest_update(&fphash, &buf[2], (unsigned)(cc - 2));
828			cc = fmt_binary_mpi(&pubkey->bn[RSA_E], buf, sizeof(buf));
829			digest_update(&fphash, &buf[2], (unsigned)(cc - 2));
830			fingerprint->len = digest_final(fingerprint->v, &fphash);
831			return 1;
832		}
833	}
834	if (pubkey->bn[RSA_N].bn) {
835		if ((cc = fmt_binary_mpi(&pubkey->bn[RSA_N], buf, sizeof(buf))) >= PGPV_KEYID_LEN) {
836			memcpy(fingerprint->v, &buf[cc - PGPV_KEYID_LEN], PGPV_KEYID_LEN);
837			fingerprint->len = PGPV_KEYID_LEN;
838			return 1;
839		}
840	}
841	/* exhausted all avenues, really */
842	memset(fingerprint->v, 0xff, fingerprint->len = PGPV_KEYID_LEN);
843	return 1;
844}
845
846/* format a fingerprint into memory */
847static int
848fmt_fingerprint(obuf_t *obuf, pgpv_fingerprint_t *fingerprint, const char *name)
849{
850	unsigned	i;
851	char		newbuf[3];
852	int		cc;
853
854	if (!obuf_add_mem(obuf, name, strlen(name)) ||
855	    !obuf_add_mem(obuf, " ", 1)) {
856		return 0;
857	}
858	for (i = 0 ; i < fingerprint->len ; i++) {
859		cc = snprintf(newbuf, sizeof(newbuf), "%02hhx",
860			fingerprint->v[i]);
861		if (!obuf_add_mem(obuf, newbuf, cc)) {
862			return 0;
863		}
864		if (i % 2 == 1 && !obuf_add_mem(obuf, " ", 1)) {
865			return 0;
866		}
867	}
868	return obuf_add_mem(obuf, "\n", 1);
869}
870
871/* calculate keyid from a pubkey */
872static int
873calc_keyid(pgpv_pubkey_t *key, const char *hashtype)
874{
875	pgpv_calc_fingerprint(&key->fingerprint, key, hashtype);
876	memcpy(key->keyid, &key->fingerprint.v[key->fingerprint.len - PGPV_KEYID_LEN], PGPV_KEYID_LEN);
877	return 1;
878}
879
880/* convert a hex string to a 64bit key id (in big endian byte order */
881static void
882str_to_keyid(const char *s, uint8_t *keyid)
883{
884	uint64_t	u;
885
886	u = (uint64_t)strtoull(s, NULL, 16);
887	u =     ((u & 0x00000000000000FFULL) << 56) |
888		((u & 0x000000000000FF00ULL) << 40) |
889		((u & 0x0000000000FF0000ULL) << 24) |
890		((u & 0x00000000FF000000ULL) <<  8) |
891		((u & 0x000000FF00000000ULL) >>  8) |
892		((u & 0x0000FF0000000000ULL) >> 24) |
893		((u & 0x00FF000000000000ULL) >> 40) |
894		((u & 0xFF00000000000000ULL) >> 56);
895	memcpy(keyid, &u, PGPV_KEYID_LEN);
896}
897
898#define PKT_ALWAYS_ON			0x80
899#define PKT_NEWFMT_MASK			0x40
900#define PKT_NEWFMT_TAG_MASK		0x3f
901#define PKT_OLDFMT_TAG_MASK		0x3c
902
903#define SUBPKT_CRITICAL_MASK		0x80
904#define SUBPKT_TAG_MASK			0x7f
905
906#define SUBPKT_SIG_BIRTH		2
907#define SUBPKT_SIG_EXPIRY		3
908#define SUBPKT_EXPORT_CERT		4
909#define SUBPKT_TRUST_SIG		5
910#define SUBPKT_REGEXP			6
911#define SUBPKT_REVOCABLE		7
912#define SUBPKT_KEY_EXPIRY		9
913#define SUBPKT_BWD_COMPAT		10
914#define SUBPKT_PREF_SYMMETRIC_ALG	11
915#define SUBPKT_REVOCATION_KEY		12
916#define SUBPKT_ISSUER			16
917#define SUBPKT_NOTATION			20
918#define SUBPKT_PREF_HASH_ALG		21
919#define SUBPKT_PREF_COMPRESS_ALG	22
920#define SUBPKT_KEY_SERVER_PREFS		23
921#define SUBPKT_PREF_KEY_SERVER		24
922#define SUBPKT_PRIMARY_USER_ID		25
923#define SUBPKT_POLICY_URI		26
924#define SUBPKT_KEY_FLAGS		27
925#define SUBPKT_SIGNER_ID		28
926#define SUBPKT_REVOCATION_REASON	29
927#define SUBPKT_FEATURES			30
928#define SUBPKT_SIGNATURE_TARGET		31
929#define SUBPKT_EMBEDDED_SIGNATURE	32
930#define SUBPKT_ISSUER_FINGERPRINT	33
931
932#define UNCOMPRESSED			0
933#define ZIP_COMPRESSION			1
934#define ZLIB_COMPRESSION		2
935#define BZIP2_COMPRESSION		3
936
937/* get a 16 bit integer, in host order */
938static uint16_t
939get_16(uint8_t *p)
940{
941	uint16_t	u16;
942
943	memcpy(&u16, p, sizeof(u16));
944	return pgp_ntoh16(u16);
945}
946
947/* get a 32 bit integer, in host order */
948static uint32_t
949get_32(uint8_t *p)
950{
951	uint32_t	u32;
952
953	memcpy(&u32, p, sizeof(u32));
954	return pgp_ntoh32(u32);
955}
956
957#define HOURSECS	(int64_t)(60 * 60)
958#define DAYSECS		(int64_t)(24 * 60 * 60)
959#define MONSECS		(int64_t)(30 * DAYSECS)
960#define YEARSECS	(int64_t)(365 * DAYSECS)
961
962/* format (human readable) time into memory */
963static size_t
964fmt_time(obuf_t *obuf, const char *header, int64_t n, const char *trailer, int relative)
965{
966	struct tm	tm;
967	time_t		elapsed;
968	time_t		now;
969	time_t		t;
970	char		newbuf[128];
971	int		cc;
972
973	t = (time_t)n;
974	now = time(NULL);
975	elapsed = now - t;
976	gmtime_r(&t, &tm);
977	cc = snprintf(newbuf, sizeof(newbuf), "%04d-%02d-%02d",
978		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
979	if (!obuf_add_mem(obuf, header, strlen(header)) ||
980	    !obuf_add_mem(obuf, newbuf, cc)) {
981		return 0;
982	}
983	if (relative) {
984		cc = snprintf(newbuf, sizeof(newbuf),
985			" (%lldy %lldm %lldd %lldh %s)",
986			llabs((long long)elapsed / YEARSECS),
987			llabs(((long long)elapsed % YEARSECS) / MONSECS),
988			llabs(((long long)elapsed % MONSECS) / DAYSECS),
989			llabs(((long long)elapsed % DAYSECS) / HOURSECS),
990			(now > t) ? "ago" : "ahead");
991		if (!obuf_add_mem(obuf, newbuf, cc)) {
992			return 0;
993		}
994	}
995	return (*trailer) ? obuf_add_mem(obuf, trailer, strlen(trailer)) : 1;
996}
997
998/* dump key mpis to stdout */
999static void
1000print_key_mpis(pgpv_bignum_t *v, uint8_t keyalg)
1001{
1002	char	s[8192];
1003
1004	switch(keyalg) {
1005	case PUBKEY_RSA_ENCRYPT_OR_SIGN:
1006	case PUBKEY_RSA_ENCRYPT:
1007	case PUBKEY_RSA_SIGN:
1008		fmt_mpi(s, sizeof(s), &v[RSA_N], "rsa.n", 1);
1009		printf("%s", s);
1010		fmt_mpi(s, sizeof(s), &v[RSA_E], "rsa.e", 1);
1011		printf("%s", s);
1012		break;
1013	case PUBKEY_ELGAMAL_ENCRYPT:
1014		fmt_mpi(s, sizeof(s), &v[ELGAMAL_P], "elgamal.p", 1);
1015		printf("%s", s);
1016		fmt_mpi(s, sizeof(s), &v[ELGAMAL_Y], "elgamal.y", 1);
1017		printf("%s", s);
1018		break;
1019	case PUBKEY_DSA:
1020		fmt_mpi(s, sizeof(s), &v[DSA_P], "dsa.p", 1);
1021		printf("%s", s);
1022		fmt_mpi(s, sizeof(s), &v[DSA_Q], "dsa.q", 1);
1023		printf("%s", s);
1024		fmt_mpi(s, sizeof(s), &v[DSA_G], "dsa.g", 1);
1025		printf("%s", s);
1026		fmt_mpi(s, sizeof(s), &v[DSA_Y], "dsa.y", 1);
1027		printf("%s", s);
1028		break;
1029	default:
1030		printf("hi, unusual keyalg %u\n", keyalg);
1031		break;
1032	}
1033}
1034
1035/* get an mpi, including 2 byte length */
1036static int
1037get_mpi(pgpv_bignum_t *mpi, uint8_t *p, size_t pktlen, size_t *off)
1038{
1039	size_t	bytes;
1040
1041	mpi->bits = get_16(p);
1042	if ((bytes = (size_t)BITS_TO_BYTES(mpi->bits)) > pktlen) {
1043		return 0;
1044	}
1045	*off += sizeof(mpi->bits);
1046	mpi->bn = PGPV_BN_bin2bn(&p[sizeof(mpi->bits)], (int)bytes, NULL);
1047	*off += bytes;
1048	return 1;
1049}
1050
1051/* read mpis in signature */
1052static int
1053read_signature_mpis(pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen)
1054{
1055	size_t	off;
1056
1057	off = 0;
1058	switch(sigpkt->sig.keyalg) {
1059	case PUBKEY_RSA_ENCRYPT_OR_SIGN:
1060	case PUBKEY_RSA_SIGN:
1061	case PUBKEY_RSA_ENCRYPT:
1062		if (!get_mpi(&sigpkt->sig.bn[RSA_SIG], p, pktlen, &off)) {
1063			printf("sigpkt->version %d, rsa sig weird\n", sigpkt->sig.version);
1064			return 0;
1065		}
1066		break;
1067	case PUBKEY_DSA:
1068	case PUBKEY_ECDSA:
1069	case PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN: /* deprecated */
1070		if (!get_mpi(&sigpkt->sig.bn[DSA_R], p, pktlen, &off) ||
1071		    !get_mpi(&sigpkt->sig.bn[DSA_S], &p[off], pktlen, &off)) {
1072			printf("sigpkt->version %d, dsa/elgamal sig weird\n", sigpkt->sig.version);
1073			return 0;
1074		}
1075		break;
1076	default:
1077		printf("weird type of sig! %d\n", sigpkt->sig.keyalg);
1078		return 0;
1079	}
1080	return 1;
1081}
1082
1083/* add the signature sub packet to the signature packet */
1084static int
1085add_subpacket(pgpv_t *pgp, pgpv_sigpkt_t *sigpkt, uint8_t tag, uint8_t *p, uint16_t len)
1086{
1087	pgpv_sigsubpkt_t	subpkt;
1088
1089	memset(&subpkt, 0x0, sizeof(subpkt));
1090	subpkt.s.size = len;
1091	subpkt.critical = 0;
1092	subpkt.tag = tag;
1093	subpkt.s.data = p;
1094	ARRAY_APPEND(sigpkt->subpackets, ARRAY_COUNT(pgp->subpkts));
1095	ARRAY_APPEND(pgp->subpkts, subpkt);
1096	return 1;
1097}
1098
1099/* read the subpackets in the signature */
1100static int
1101read_sig_subpackets(pgpv_t *pgp, pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen)
1102{
1103	pgpv_sigsubpkt_t	 subpkt;
1104	const int		 is_subpkt = 0;
1105	unsigned		 lenlen;
1106	unsigned		 i;
1107	uint8_t			*start;
1108
1109	start = p;
1110	for (i = 0 ; (unsigned)(p - start) < sigpkt->subslen ; i++) {
1111		memset(&subpkt, 0x0, sizeof(subpkt));
1112		subpkt.s.size = get_pkt_len(1, p, 0, is_subpkt);
1113		lenlen = get_pkt_len_len(1, p, is_subpkt);
1114		if (lenlen > pktlen) {
1115			printf("weird lenlen %u\n", lenlen);
1116			return 0;
1117		}
1118		p += lenlen;
1119		subpkt.critical = (*p & SUBPKT_CRITICAL_MASK);
1120		subpkt.tag = (*p & SUBPKT_TAG_MASK);
1121		p += 1;
1122		switch(subpkt.tag) {
1123		case SUBPKT_SIG_BIRTH:
1124			sigpkt->sig.birth = (int64_t)get_32(p);
1125			break;
1126		case SUBPKT_SIG_EXPIRY:
1127			sigpkt->sig.expiry = (int64_t)get_32(p);
1128			break;
1129		case SUBPKT_KEY_EXPIRY:
1130			sigpkt->sig.keyexpiry = (int64_t)get_32(p);
1131			break;
1132		case SUBPKT_ISSUER:
1133			memcpy(sigpkt->sig.signer, p, sizeof(sigpkt->sig.signer));
1134			break;
1135		case SUBPKT_SIGNER_ID:
1136			memcpy(sigpkt->sig.signer, p, sizeof(sigpkt->sig.signer));
1137			break;
1138		case SUBPKT_TRUST_SIG:
1139			sigpkt->sig.trustsig = *p;
1140			break;
1141		case SUBPKT_REGEXP:
1142			sigpkt->sig.regexp = (char *)(void *)p;
1143			break;
1144		case SUBPKT_REVOCABLE:
1145			sigpkt->sig.revocable = *p;
1146			break;
1147		case SUBPKT_PREF_SYMMETRIC_ALG:
1148			sigpkt->sig.pref_symm_alg = *p;
1149			break;
1150		case SUBPKT_REVOCATION_KEY:
1151			sigpkt->sig.revoke_sensitive = (*p & 0x40);
1152			sigpkt->sig.revoke_alg = p[1];
1153			sigpkt->sig.revoke_fingerprint = &p[2];
1154			break;
1155		case SUBPKT_NOTATION:
1156			sigpkt->sig.notation = *p;
1157			break;
1158		case SUBPKT_PREF_HASH_ALG:
1159			sigpkt->sig.pref_hash_alg = *p;
1160			break;
1161		case SUBPKT_PREF_COMPRESS_ALG:
1162			sigpkt->sig.pref_compress_alg = *p;
1163			break;
1164		case SUBPKT_PREF_KEY_SERVER:
1165			sigpkt->sig.pref_key_server = (char *)(void *)p;
1166			break;
1167		case SUBPKT_KEY_SERVER_PREFS:
1168			sigpkt->sig.key_server_modify = *p;
1169			break;
1170		case SUBPKT_KEY_FLAGS:
1171			sigpkt->sig.type_key = *p;
1172			break;
1173		case SUBPKT_PRIMARY_USER_ID:
1174			sigpkt->sig.primary_userid = *p;
1175			break;
1176		case SUBPKT_POLICY_URI:
1177			sigpkt->sig.policy = (char *)(void *)p;
1178			break;
1179		case SUBPKT_FEATURES:
1180			sigpkt->sig.features = (char *)(void *)p;
1181			break;
1182		case SUBPKT_REVOCATION_REASON:
1183			sigpkt->sig.revoked = *p++ + 1;
1184			sigpkt->sig.why_revoked = (char *)(void *)p;
1185			break;
1186		case SUBPKT_ISSUER_FINGERPRINT:
1187			sigpkt->sig.ifver = *p;
1188			sigpkt->sig.issuer_fingerprint = &p[1];
1189			break;
1190		default:
1191			printf("Ignoring unusual/reserved signature subpacket %d\n", subpkt.tag);
1192			break;
1193		}
1194		subpkt.s.data = p;
1195		p += subpkt.s.size - 1;
1196		ARRAY_APPEND(sigpkt->subpackets, ARRAY_COUNT(pgp->subpkts));
1197		ARRAY_APPEND(pgp->subpkts, subpkt);
1198	}
1199	return 1;
1200}
1201
1202/* parse signature packet */
1203static int
1204read_sigpkt(pgpv_t *pgp, uint8_t mement, pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen)
1205{
1206	unsigned	 lenlen;
1207	uint8_t		*base;
1208
1209	make_ref(pgp, mement, &sigpkt->sig.hashstart);
1210	base = p;
1211	switch(sigpkt->sig.version = *p++) {
1212	case 2:
1213	case 3:
1214		if ((lenlen = *p++) != 5) {
1215			printf("read_sigpkt: hashed length not 5\n");
1216			return 0;
1217		}
1218		sigpkt->sig.hashlen = lenlen;
1219		/* put birthtime into a subpacket */
1220		sigpkt->sig.type = *p++;
1221		add_subpacket(pgp, sigpkt, SUBPKT_SIG_BIRTH, p, sizeof(uint32_t));
1222		sigpkt->sig.birth = (int64_t)get_32(p);
1223		p += sizeof(uint32_t);
1224		memcpy(sigpkt->sig.signer, p, sizeof(sigpkt->sig.signer));
1225		add_subpacket(pgp, sigpkt, SUBPKT_SIGNER_ID, p, PGPV_KEYID_LEN);
1226		p += PGPV_KEYID_LEN;
1227		sigpkt->sig.keyalg = *p++;
1228		sigpkt->sig.hashalg = *p++;
1229		sigpkt->sig.hash2 = p;
1230		if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) {
1231			printf("read_sigpkt: can't read sigs v3\n");
1232			return 0;
1233		}
1234		break;
1235	case 4:
1236		sigpkt->sig.type = *p++;
1237		sigpkt->sig.keyalg = *p++;
1238		sigpkt->sig.hashalg = *p++;
1239		sigpkt->subslen = get_16(p);
1240		p += sizeof(sigpkt->subslen);
1241		if (!read_sig_subpackets(pgp, sigpkt, p, pktlen)) {
1242			printf("read_sigpkt: can't read sig subpackets, v4\n");
1243			return 0;
1244		}
1245		if (sigpkt->sig.signer[0] == 0x0) {
1246			memcpy(sigpkt->sig.signer,
1247				get_ref(&sigpkt->sig.hashstart) + 16,
1248				sizeof(sigpkt->sig.signer));
1249		}
1250		p += sigpkt->subslen;
1251		sigpkt->sig.hashlen = (unsigned)(p - base);
1252		sigpkt->unhashlen = get_16(p);
1253		p += sizeof(sigpkt->unhashlen) + sigpkt->unhashlen;
1254		sigpkt->sig.hash2 = p;
1255		if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) {
1256			printf("read_sigpkt: can't read sigs, v4\n");
1257			return 0;
1258		}
1259		break;
1260	default:
1261		printf("read_sigpkt: unusual signature version (%u)\n", sigpkt->sig.version);
1262		break;
1263	}
1264	return 1;
1265}
1266
1267
1268/* this parses compressed data, decompresses it, and calls the parser again */
1269static int
1270read_compressed(pgpv_t *pgp, pgpv_compress_t *compressed, uint8_t *p, size_t len)
1271{
1272	pgpv_mem_t	*unzmem;
1273	bz_stream	 bz;
1274	z_stream	 z;
1275	int		 ok = 0;
1276
1277	compressed->compalg = *p;
1278	compressed->s.size = len;
1279	if ((compressed->s.data = calloc(1, len)) == NULL) {
1280		printf("read_compressed: can't allocate %zu length\n", len);
1281		return 0;
1282	}
1283	switch(compressed->compalg) {
1284	case UNCOMPRESSED:
1285		printf("not implemented %d compression yet\n", compressed->compalg);
1286		return 0;
1287	default:
1288		break;
1289	}
1290	ARRAY_EXPAND(pgp->areas);
1291	ARRAY_COUNT(pgp->areas) += 1;
1292	unzmem = &ARRAY_LAST(pgp->areas);
1293	unzmem->size = len * 10;
1294	unzmem->dealloc = FREE_MEM;
1295	if ((unzmem->mem = calloc(1, unzmem->size)) == NULL) {
1296		printf("read_compressed: calloc failed!\n");
1297		return 0;
1298	}
1299	switch(compressed->compalg) {
1300	case ZIP_COMPRESSION:
1301	case ZLIB_COMPRESSION:
1302		memset(&z, 0x0, sizeof(z));
1303		z.next_in = p + 1;
1304		z.avail_in = (unsigned)(len - 1);
1305		z.total_in = (unsigned)(len - 1);
1306		z.next_out = unzmem->mem;
1307		z.avail_out = (unsigned)unzmem->size;
1308		z.total_out = (unsigned)unzmem->size;
1309		break;
1310	case BZIP2_COMPRESSION:
1311		memset(&bz, 0x0, sizeof(bz));
1312		bz.avail_in = (unsigned)(len - 1);
1313		bz.next_in = (char *)(void *)p + 1;
1314		bz.next_out = (char *)(void *)unzmem->mem;
1315		bz.avail_out = (unsigned)unzmem->size;
1316		break;
1317	}
1318	switch(compressed->compalg) {
1319	case ZIP_COMPRESSION:
1320		ok = (inflateInit2(&z, -15) == Z_OK);
1321		break;
1322	case ZLIB_COMPRESSION:
1323		ok = (inflateInit(&z) == Z_OK);
1324		break;
1325	case BZIP2_COMPRESSION:
1326		ok = (netpgpv_BZ2_bzDecompressInit(&bz, 1, 0) == BZ_OK);
1327		break;
1328	}
1329	if (!ok) {
1330		printf("read_compressed: initialisation failed!\n");
1331		return 0;
1332	}
1333	switch(compressed->compalg) {
1334	case ZIP_COMPRESSION:
1335	case ZLIB_COMPRESSION:
1336		ok = (inflate(&z, Z_FINISH) == Z_STREAM_END);
1337		unzmem->size = z.total_out;
1338		break;
1339	case BZIP2_COMPRESSION:
1340		ok = (netpgpv_BZ2_bzDecompress(&bz) == BZ_STREAM_END);
1341		unzmem->size = ((uint64_t)bz.total_out_hi32 << 32) | bz.total_out_lo32;
1342		break;
1343	}
1344	if (!ok) {
1345		printf("read_compressed: inflate failed!\n");
1346		return 0;
1347	}
1348	return 1;
1349}
1350
1351/* parse one pass signature packet */
1352static int
1353read_onepass_sig(pgpv_onepass_t *onepasspkt, uint8_t *mem)
1354{
1355	onepasspkt->version = mem[0];
1356	onepasspkt->type = mem[1];
1357	onepasspkt->hashalg = mem[2];
1358	onepasspkt->keyalg = mem[3];
1359	memcpy(onepasspkt->keyid, &mem[4], sizeof(onepasspkt->keyid));
1360	onepasspkt->nested = mem[12];
1361	return 1;
1362}
1363
1364/* parse public key packet */
1365static int
1366read_pubkey(pgpv_pubkey_t *pubkey, uint8_t *mem, size_t pktlen, int pbn)
1367{
1368	size_t		 off;
1369
1370	off = 0;
1371	pubkey->version = mem[off++];
1372	pubkey->birth = get_32(&mem[off]);
1373	off += 4;
1374	if (pubkey->version == 2 || pubkey->version == 3) {
1375		pubkey->expiry = get_16(&mem[off]) * DAYSECS;
1376		off += 2;
1377	}
1378	if ((pubkey->keyalg = mem[off++]) == 0) {
1379		pubkey->keyalg = PUBKEY_RSA_ENCRYPT_OR_SIGN;
1380		printf("got unusual pubkey keyalg %u\n", mem[off - 1]);
1381	}
1382	switch(pubkey->keyalg) {
1383	case PUBKEY_RSA_ENCRYPT_OR_SIGN:
1384	case PUBKEY_RSA_ENCRYPT:
1385	case PUBKEY_RSA_SIGN:
1386		if (!get_mpi(&pubkey->bn[RSA_N], &mem[off], pktlen, &off) ||
1387		    !get_mpi(&pubkey->bn[RSA_E], &mem[off], pktlen, &off)) {
1388			return 0;
1389		}
1390		break;
1391	case PUBKEY_ELGAMAL_ENCRYPT:
1392	case PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN:
1393		if (!get_mpi(&pubkey->bn[ELGAMAL_P], &mem[off], pktlen, &off) ||
1394		    !get_mpi(&pubkey->bn[ELGAMAL_Y], &mem[off], pktlen, &off)) {
1395			return 0;
1396		}
1397		break;
1398	case PUBKEY_DSA:
1399		if (!get_mpi(&pubkey->bn[DSA_P], &mem[off], pktlen, &off) ||
1400		    !get_mpi(&pubkey->bn[DSA_Q], &mem[off], pktlen, &off) ||
1401		    !get_mpi(&pubkey->bn[DSA_G], &mem[off], pktlen, &off) ||
1402		    !get_mpi(&pubkey->bn[DSA_Y], &mem[off], pktlen, &off)) {
1403			return 0;
1404		}
1405		break;
1406	default:
1407		printf("hi, different type of pubkey here %u\n", pubkey->keyalg);
1408		break;
1409	}
1410	if (pbn) {
1411		print_key_mpis(pubkey->bn, pubkey->keyalg);
1412	}
1413	return 1;
1414}
1415
1416/* parse a user attribute */
1417static int
1418read_userattr(pgpv_userattr_t *userattr, uint8_t *p, size_t pktlen)
1419{
1420	pgpv_string_t	subattr;
1421	const int 	is_subpkt = 0;
1422	const int	indian = 1;
1423	unsigned	lenlen;
1424	uint16_t	imagelen;
1425	size_t		cc;
1426
1427	userattr->len = pktlen;
1428	for (cc = 0 ; cc < pktlen ; cc += subattr.size + lenlen + 1) {
1429		subattr.size = get_pkt_len(1, p, 0, is_subpkt);
1430		lenlen = get_pkt_len_len(1, p, is_subpkt);
1431		if (lenlen > pktlen) {
1432			printf("weird lenlen %u\n", lenlen);
1433			return 0;
1434		}
1435		p += lenlen;
1436		if (*p++ != 1) {
1437			printf("image type (%u) != 1. weird packet\n", *(p - 1));
1438		}
1439		memcpy(&imagelen, p, sizeof(imagelen));
1440		if (!*(const char *)(const void *)&indian) {
1441			/* big endian - byteswap length */
1442			imagelen = (((unsigned)imagelen & 0xff) << 8) | (((unsigned)imagelen >> 8) & 0xff);
1443		}
1444		subattr.data = p + 3;
1445		p += subattr.size;
1446		ARRAY_APPEND(userattr->subattrs, subattr);
1447	}
1448	return 1;
1449}
1450
1451#define LITDATA_BINARY	'b'
1452#define LITDATA_TEXT	't'
1453#define LITDATA_UTF8	'u'
1454
1455/* parse literal packet */
1456static int
1457read_litdata(pgpv_t *pgp, pgpv_litdata_t *litdata, uint8_t *p, size_t size)
1458{
1459	size_t	cc;
1460
1461	cc = 0;
1462	switch(litdata->format = p[cc++]) {
1463	case LITDATA_BINARY:
1464	case LITDATA_TEXT:
1465	case LITDATA_UTF8:
1466		litdata->namelen = 0;
1467		break;
1468	default:
1469		printf("weird litdata format %u\n", litdata->format);
1470		break;
1471	}
1472	litdata->filename.size = litdata->namelen = p[cc++];
1473	litdata->filename.data = &p[cc];
1474	litdata->filename.allocated = 0;
1475	cc += litdata->namelen;
1476	litdata->secs = get_32(&p[cc]);
1477	cc += 4;
1478	litdata->s.data = &p[cc];
1479	litdata->len = litdata->s.size = size - cc;
1480	litdata->mem = ARRAY_COUNT(pgp->areas) - 1;
1481	litdata->offset = cc;
1482	return 1;
1483}
1484
1485/* parse a single packet */
1486static int
1487read_pkt(pgpv_t *pgp, pgpv_mem_t *mem)
1488{
1489	const int	 isprimary = 1;
1490	pgpv_pkt_t	 pkt;
1491	pgpv_mem_t	*newmem;
1492	unsigned	 lenlen;
1493	uint8_t		 ispartial;
1494	size_t		 size;
1495
1496	memset(&pkt, 0x0, sizeof(pkt));
1497	pkt.tag = mem->mem[mem->cc++];
1498	if (!(pkt.tag & PKT_ALWAYS_ON)) {
1499		printf("BAD PACKET - bit 7 not 1, offset %zu!\n", mem->cc - 1);
1500	}
1501	pkt.newfmt = (pkt.tag & PKT_NEWFMT_MASK);
1502	pkt.tag = (pkt.newfmt) ?
1503		(pkt.tag & PKT_NEWFMT_TAG_MASK) :
1504		(((unsigned)pkt.tag & PKT_OLDFMT_TAG_MASK) >> 2);
1505	ispartial = (pkt.newfmt && IS_PARTIAL(mem->mem[mem->cc]));
1506	pkt.s.size = get_pkt_len(pkt.newfmt, &mem->mem[mem->cc], mem->size - mem->cc, isprimary);
1507	lenlen = get_pkt_len_len(pkt.newfmt, &mem->mem[mem->cc], isprimary);
1508	pkt.offset = mem->cc;
1509	mem->cc += lenlen;
1510	pkt.mement = (uint8_t)(mem - ARRAY_ARRAY(pgp->areas));
1511	pkt.s.data = &mem->mem[mem->cc];
1512	if (strchr(mem->allowed, pkt.tag) == NULL) {
1513		printf("packet %d not allowed for operation %s\n", pkt.tag, pgp->op);
1514		return 0;
1515	}
1516	size = pkt.s.size;
1517	if (ispartial) {
1518		pkt.s.size = fixup_partials(pgp, &mem->mem[mem->cc - lenlen], pkt.s.size, mem->size, &size);
1519		newmem = &ARRAY_LAST(pgp->areas);
1520		pkt.mement = (uint8_t)(newmem - ARRAY_ARRAY(pgp->areas));
1521		pkt.s.data = newmem->mem;
1522		size -= 1;
1523	}
1524	switch(pkt.tag) {
1525	case SIGNATURE_PKT:
1526		if (!read_sigpkt(pgp, pkt.mement, &pkt.u.sigpkt, pkt.s.data, pkt.s.size)) {
1527			return 0;
1528		}
1529		break;
1530	case ONEPASS_SIGNATURE_PKT:
1531		read_onepass_sig(&pkt.u.onepass, pkt.s.data);
1532		break;
1533	case PUBKEY_PKT:
1534	case PUB_SUBKEY_PKT:
1535		break;
1536	case LITDATA_PKT:
1537		read_litdata(pgp, &pkt.u.litdata, pkt.s.data, pkt.s.size);
1538		break;
1539	case TRUST_PKT:
1540		pkt.u.trust.level = pkt.s.data[0];
1541		pkt.u.trust.amount = pkt.s.data[1];
1542		break;
1543	case USERID_PKT:
1544		pkt.u.userid.size = pkt.s.size;
1545		pkt.u.userid.data = pkt.s.data;
1546		pkt.u.userid.allocated = 0;
1547		break;
1548	case COMPRESSED_DATA_PKT:
1549		read_compressed(pgp, &pkt.u.compressed, pkt.s.data, pkt.s.size);
1550		ARRAY_APPEND(pgp->pkts, pkt);
1551		read_all_packets(pgp, &ARRAY_LAST(pgp->areas), pgp->op);
1552		break;
1553	case USER_ATTRIBUTE_PKT:
1554		read_userattr(&pkt.u.userattr, pkt.s.data, pkt.s.size);
1555		break;
1556	default:
1557		printf("hi, need to implement %d, offset %zu\n", pkt.tag, mem->cc);
1558		break;
1559	}
1560	mem->cc += size;
1561	if (pkt.tag != COMPRESSED_DATA_PKT) {
1562		/* compressed was added earlier to preserve pkt ordering */
1563		ARRAY_APPEND(pgp->pkts, pkt);
1564	}
1565	return 1;
1566}
1567
1568/* checks the tag type of a packet */
1569static int
1570pkt_is(pgpv_t *pgp, int wanted)
1571{
1572	return (ARRAY_ELEMENT(pgp->pkts, pgp->pkt).tag == wanted);
1573}
1574
1575/* checks the packet is a signature packet, and the signature type is the expected one */
1576static int
1577pkt_sigtype_is(pgpv_t *pgp, int wanted)
1578{
1579	if (!pkt_is(pgp, SIGNATURE_PKT)) {
1580		return 0;
1581	}
1582	return (ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.sigpkt.sig.type == wanted);
1583}
1584
1585/* check for expected type of packet, and move to the next */
1586static int
1587pkt_accept(pgpv_t *pgp, int expected)
1588{
1589	int	got;
1590
1591	if ((got = ARRAY_ELEMENT(pgp->pkts, pgp->pkt).tag) == expected) {
1592		pgp->pkt += 1;
1593		return 1;
1594	}
1595	printf("problem at token %zu, expcted %d, got %d\n", pgp->pkt, expected, got);
1596	return 0;
1597}
1598
1599/* recognise signature (and trust) packet */
1600static int
1601recog_signature(pgpv_t *pgp, pgpv_signature_t *signature)
1602{
1603	if (!pkt_is(pgp, SIGNATURE_PKT)) {
1604		printf("recog_signature: not a signature packet\n");
1605		return 0;
1606	}
1607	memcpy(signature, &ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.sigpkt.sig, sizeof(*signature));
1608	pgp->pkt += 1;
1609	if (pkt_is(pgp, TRUST_PKT)) {
1610		pkt_accept(pgp, TRUST_PKT);
1611	}
1612	return 1;
1613}
1614
1615/* recognise user id packet */
1616static int
1617recog_userid(pgpv_t *pgp, pgpv_signed_userid_t *userid)
1618{
1619	pgpv_signature_t	 signature;
1620	pgpv_pkt_t		*pkt;
1621
1622	memset(userid, 0x0, sizeof(*userid));
1623	if (!pkt_is(pgp, USERID_PKT)) {
1624		printf("recog_userid: not %d\n", USERID_PKT);
1625		return 0;
1626	}
1627	pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt);
1628	userid->userid.size = pkt->s.size;
1629	userid->userid.data = pkt->s.data;
1630	userid->userid.allocated = 0;
1631	pgp->pkt += 1;
1632	while (pkt_is(pgp, SIGNATURE_PKT)) {
1633		if (!recog_signature(pgp, &signature)) {
1634			printf("recog_userid: can't recognise signature/trust\n");
1635			return 0;
1636		}
1637		ARRAY_APPEND(userid->signatures, ARRAY_COUNT(pgp->signatures));
1638		ARRAY_APPEND(pgp->signatures, signature);
1639		if (signature.primary_userid) {
1640			userid->primary_userid = signature.primary_userid;
1641		}
1642		if (signature.revoked) {
1643			userid->revoked = signature.revoked;
1644		}
1645	}
1646	return 1;
1647}
1648
1649/* recognise user attributes packet */
1650static int
1651recog_userattr(pgpv_t *pgp, pgpv_signed_userattr_t *userattr)
1652{
1653	pgpv_signature_t	 signature;
1654
1655	memset(userattr, 0x0, sizeof(*userattr));
1656	if (!pkt_is(pgp, USER_ATTRIBUTE_PKT)) {
1657		printf("recog_userattr: not %d\n", USER_ATTRIBUTE_PKT);
1658		return 0;
1659	}
1660	userattr->userattr = ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.userattr;
1661	pgp->pkt += 1;
1662	while (pkt_is(pgp, SIGNATURE_PKT)) {
1663		if (!recog_signature(pgp, &signature)) {
1664			printf("recog_userattr: can't recognise signature/trust\n");
1665			return 0;
1666		}
1667		ARRAY_APPEND(userattr->signatures, ARRAY_COUNT(pgp->signatures));
1668		ARRAY_APPEND(pgp->signatures, signature);
1669		if (signature.revoked) {
1670			userattr->revoked = signature.revoked;
1671		}
1672	}
1673	return 1;
1674}
1675
1676/* recognise a sub key */
1677static int
1678recog_subkey(pgpv_t *pgp, pgpv_signed_subkey_t *subkey)
1679{
1680	pgpv_signature_t	 signature;
1681	pgpv_pkt_t		*pkt;
1682
1683	pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt);
1684	memset(subkey, 0x0, sizeof(*subkey));
1685	read_pubkey(&subkey->subkey, pkt->s.data, pkt->s.size, 0);
1686	pgp->pkt += 1;
1687	if (pkt_sigtype_is(pgp, SIGTYPE_KEY_REVOCATION) ||
1688	    pkt_sigtype_is(pgp, SIGTYPE_SUBKEY_REVOCATION) ||
1689	    pkt_sigtype_is(pgp, SIGTYPE_CERT_REVOCATION)) {
1690		recog_signature(pgp, &signature);
1691		subkey->revoc_self_sig = signature;
1692	}
1693	do {
1694		if (!pkt_is(pgp, SIGNATURE_PKT)) {
1695			printf("recog_subkey: not signature packet at %zu\n", pgp->pkt);
1696			return 0;
1697		}
1698		if (!recog_signature(pgp, &signature)) {
1699			printf("recog_subkey: bad signature/trust at %zu\n", pgp->pkt);
1700			return 0;
1701		}
1702		ARRAY_APPEND(subkey->signatures, ARRAY_COUNT(pgp->signatures));
1703		ARRAY_APPEND(pgp->signatures, signature);
1704		if (signature.keyexpiry) {
1705			/* XXX - check it's a good key expiry */
1706			subkey->subkey.expiry = signature.keyexpiry;
1707		}
1708	} while (pkt_is(pgp, SIGNATURE_PKT));
1709	return 1;
1710}
1711
1712/* use a sparse map for the text strings here to save space */
1713static const char	*keyalgs[] = {
1714	"[Unknown]",
1715	"RSA (Encrypt or Sign)",
1716	"RSA (Encrypt Only)",
1717	"RSA (Sign Only)",
1718	"Elgamal (Encrypt Only)",
1719	"DSA",
1720	"Elliptic Curve",
1721	"ECDSA",
1722	"Elgamal (Encrypt or Sign)"
1723};
1724
1725#define MAX_KEYALG	21
1726
1727static const char *keyalgmap = "\0\01\02\03\0\0\0\0\0\0\0\0\0\0\0\0\04\05\06\07\010\011";
1728
1729/* return human readable name for key algorithm */
1730static const char *
1731fmtkeyalg(uint8_t keyalg)
1732{
1733	return keyalgs[(uint8_t)keyalgmap[(keyalg >= MAX_KEYALG) ? 0 : keyalg]];
1734}
1735
1736/* return the number of bits in the public key */
1737static unsigned
1738numkeybits(const pgpv_pubkey_t *pubkey)
1739{
1740	switch(pubkey->keyalg) {
1741	case PUBKEY_RSA_ENCRYPT_OR_SIGN:
1742	case PUBKEY_RSA_ENCRYPT:
1743	case PUBKEY_RSA_SIGN:
1744		return pubkey->bn[RSA_N].bits;
1745	case PUBKEY_DSA:
1746	case PUBKEY_ECDSA:
1747		return pubkey->bn[DSA_P].bits;
1748		//return BITS_TO_BYTES(pubkey->bn[DSA_Q].bits) * 64;
1749	case PUBKEY_ELGAMAL_ENCRYPT:
1750	case PUBKEY_ELGAMAL_ENCRYPT_OR_SIGN:
1751		return pubkey->bn[ELGAMAL_P].bits;
1752	default:
1753		return 0;
1754	}
1755}
1756
1757/* print a public key */
1758static int
1759fmt_pubkey(obuf_t *obuf, pgpv_pubkey_t *pubkey, const char *leader)
1760{
1761	char	newbuf[128];
1762	int	cc;
1763
1764	cc = snprintf(newbuf, sizeof(newbuf), " %u/%s ",
1765		numkeybits(pubkey), fmtkeyalg(pubkey->keyalg));
1766	if (!obuf_add_mem(obuf, leader, strlen(leader)) ||
1767	    !obuf_add_mem(obuf, newbuf, cc)) {
1768		return 0;
1769	}
1770	if (!fmt_binary(obuf, pubkey->keyid, PGPV_KEYID_LEN)) {
1771		return 0;
1772	}
1773	if (!fmt_time(obuf, " ", pubkey->birth, "", 0)) {
1774		return 0;
1775	}
1776	if (pubkey->expiry) {
1777		if (!fmt_time(obuf, " [Expiry ", pubkey->birth + pubkey->expiry, "]", 0)) {
1778			return 0;
1779		}
1780	}
1781	if (!obuf_add_mem(obuf, "\n", 1)) {
1782		return 0;
1783	}
1784	return fmt_fingerprint(obuf, &pubkey->fingerprint, "fingerprint  ");
1785}
1786
1787/* we add 1 to revocation value to denote compromised */
1788#define COMPROMISED	(0x02 + 1)
1789
1790/* format a userid - used to order the userids when formatting */
1791static int
1792fmt_userid(obuf_t *obuf, pgpv_t *pgp, pgpv_primarykey_t *primary, uint8_t u)
1793{
1794	pgpv_signed_userid_t	*userid;
1795	const char		*s;
1796	uint64_t		 id;
1797
1798	id = ARRAY_ELEMENT(primary->signed_userids, u);
1799	userid = &ARRAY_ELEMENT(pgp->signed_userids, id);
1800	s = (userid->revoked == COMPROMISED) ? " [COMPROMISED AND REVOKED]\n" :
1801		(userid->revoked) ? " [REVOKED]\n" : "\n";
1802	return obuf_add_mem(obuf, "uid           ", 14) &&
1803		obuf_add_mem(obuf, userid->userid.data, userid->userid.size) &&
1804		obuf_add_mem(obuf, s, strlen(s));
1805}
1806
1807/* format a trust sig - used to order the userids when formatting */
1808static int
1809fmt_trust(obuf_t *obuf, pgpv_signature_t *sig)
1810{
1811	if (!obuf_add_mem(obuf, "trust          ", 15) ||
1812	    !fmt_binary(obuf, sig->signer, PGPV_KEYID_LEN)) {
1813		return 0;
1814	}
1815	return obuf_add_mem(obuf, "\n", 1);
1816}
1817
1818/* print a primary key, per RFC 4880 */
1819static int
1820fmt_primary(obuf_t *obuf, pgpv_t *pgp, pgpv_primarykey_t *primary, unsigned subkey, const char *modifiers)
1821{
1822	pgpv_signed_userid_t	*userid;
1823	pgpv_signed_subkey_t	*signed_subkey;
1824	pgpv_pubkey_t		*pubkey;
1825	unsigned		 i;
1826	unsigned		 j;
1827	uint64_t		 id;
1828
1829	if (subkey == 0) {
1830		pubkey = &primary->primary;
1831	} else {
1832		id = ARRAY_ELEMENT(primary->signed_subkeys, subkey);
1833		pubkey = &ARRAY_ELEMENT(pgp->signed_subkeys, id).subkey;
1834	}
1835	if (!fmt_pubkey(obuf, pubkey, "signature    ")) {
1836		return 0;
1837	}
1838	if (!fmt_userid(obuf, pgp, primary, primary->primary_userid)) {
1839		return 0;
1840	}
1841	for (i = 0 ; i < ARRAY_COUNT(primary->signed_userids) ; i++) {
1842		if (i != primary->primary_userid) {
1843			if (!fmt_userid(obuf, pgp, primary, i)) {
1844				return 0;
1845			}
1846			if (strcasecmp(modifiers, "trust") == 0) {
1847				id = ARRAY_ELEMENT(primary->signed_userids, i);
1848				userid = &ARRAY_ELEMENT(pgp->signed_userids, id);
1849				for (j = 0 ; j < ARRAY_COUNT(userid->signatures) ; j++) {
1850					if (!fmt_trust(obuf, &ARRAY_ELEMENT(pgp->signatures,
1851							ARRAY_ELEMENT(userid->signatures, j)))) {
1852						return 0;
1853					}
1854				}
1855			}
1856		}
1857	}
1858	if (strcasecmp(modifiers, "subkeys") == 0) {
1859		for (i = 0 ; i < ARRAY_COUNT(primary->signed_subkeys) ; i++) {
1860			id = ARRAY_ELEMENT(primary->signed_subkeys, i);
1861			signed_subkey = &ARRAY_ELEMENT(pgp->signed_subkeys, id);
1862			if (!fmt_pubkey(obuf, &signed_subkey->subkey, "encryption")) {
1863				return 0;
1864			}
1865		}
1866	}
1867	return obuf_add_mem(obuf, "\n", 1);
1868}
1869
1870
1871/* check the padding on the signature */
1872static int
1873rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num)
1874{
1875	USE_ARG(num);
1876	if (flen > tlen) {
1877		printf("from length larger than to length\n");
1878		return -1;
1879	}
1880	(void) memset(to, 0x0, (size_t)(tlen - flen));
1881	(void) memcpy(to + tlen - flen, from, (size_t)flen);
1882	return tlen;
1883}
1884
1885#define RSA_MAX_MODULUS_BITS	16384
1886#define RSA_SMALL_MODULUS_BITS	3072
1887#define RSA_MAX_PUBEXP_BITS	64 /* exponent limit enforced for "large" modulus only */
1888
1889/* check against the exponent/moudulo operation */
1890static int
1891lowlevel_rsa_public_check(const uint8_t *encbuf, int enclen, uint8_t *dec, const netpgpv_rsa_pubkey_t *rsa)
1892{
1893	uint8_t		*decbuf;
1894	PGPV_BIGNUM		*decbn;
1895	PGPV_BIGNUM		*encbn;
1896	int		 decbytes;
1897	int		 nbytes;
1898	int		 r;
1899
1900	nbytes = 0;
1901	r = -1;
1902	decbuf = NULL;
1903	decbn = encbn = NULL;
1904	if (PGPV_BN_num_bits(rsa->n) > RSA_MAX_MODULUS_BITS) {
1905		printf("rsa r modulus too large\n");
1906		goto err;
1907	}
1908	if (PGPV_BN_cmp(rsa->n, rsa->e) <= 0) {
1909		printf("rsa r bad n value\n");
1910		goto err;
1911	}
1912	if (PGPV_BN_num_bits(rsa->n) > RSA_SMALL_MODULUS_BITS &&
1913	    PGPV_BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) {
1914		printf("rsa r bad exponent limit\n");
1915		goto err;
1916	}
1917	nbytes = PGPV_BN_num_bytes(rsa->n);
1918	if ((encbn = PGPV_BN_new()) == NULL ||
1919	    (decbn = PGPV_BN_new()) == NULL ||
1920	    (decbuf = calloc(1, (size_t)nbytes)) == NULL) {
1921		printf("allocation failure\n");
1922		goto err;
1923	}
1924	if (enclen > nbytes) {
1925		printf("rsa r > mod len\n");
1926		goto err;
1927	}
1928	if (PGPV_BN_bin2bn(encbuf, enclen, encbn) == NULL) {
1929		printf("null encrypted BN\n");
1930		goto err;
1931	}
1932	if (PGPV_BN_cmp(encbn, rsa->n) >= 0) {
1933		printf("rsa r data too large for modulus\n");
1934		goto err;
1935	}
1936	if (PGPV_BN_mod_exp(decbn, encbn, rsa->e, rsa->n, NULL) < 0) {
1937		printf("PGPV_BN_mod_exp < 0\n");
1938		goto err;
1939	}
1940	decbytes = PGPV_BN_num_bytes(decbn);
1941	(void) PGPV_BN_bn2bin(decbn, decbuf);
1942	if ((r = rsa_padding_check_none(dec, nbytes, decbuf, decbytes, 0)) < 0) {
1943		printf("rsa r padding check failed\n");
1944	}
1945err:
1946	PGPV_BN_clear_free(encbn);
1947	PGPV_BN_clear_free(decbn);
1948	if (decbuf != NULL) {
1949		(void) memset(decbuf, 0x0, nbytes);
1950		free(decbuf);
1951	}
1952	return r;
1953}
1954
1955/* verify */
1956static int
1957rsa_public_decrypt(int enclen, const unsigned char *enc, unsigned char *dec, NETPGPV_RSA *rsa, int padding)
1958{
1959	netpgpv_rsa_pubkey_t	pub;
1960	int			ret;
1961
1962	if (enc == NULL || dec == NULL || rsa == NULL) {
1963		return 0;
1964	}
1965	USE_ARG(padding);
1966	(void) memset(&pub, 0x0, sizeof(pub));
1967	pub.n = PGPV_BN_dup(rsa->n);
1968	pub.e = PGPV_BN_dup(rsa->e);
1969	ret = lowlevel_rsa_public_check(enc, enclen, dec, &pub);
1970	PGPV_BN_clear_free(pub.n);
1971	PGPV_BN_clear_free(pub.e);
1972	return ret;
1973}
1974
1975#define SUBKEY_LEN(x)	(80 + 80)
1976#define SIG_LEN		80
1977#define UID_LEN		80
1978
1979/* return worst case number of bytes needed to format a primary key */
1980static size_t
1981estimate_primarykey_size(pgpv_primarykey_t *primary)
1982{
1983	size_t		cc;
1984
1985	cc = SUBKEY_LEN("signature") +
1986		(ARRAY_COUNT(primary->signed_userids) * UID_LEN) +
1987		(ARRAY_COUNT(primary->signed_subkeys) * SUBKEY_LEN("encrypt uids"));
1988	return cc;
1989}
1990
1991/* use public decrypt to verify a signature */
1992static int
1993pgpv_rsa_public_decrypt(uint8_t *out, const uint8_t *in, size_t length, const pgpv_pubkey_t *pubkey)
1994{
1995	NETPGPV_RSA    *orsa;
1996	int             n;
1997
1998	if ((orsa = calloc(1, sizeof(*orsa))) == NULL) {
1999		return 0;
2000	}
2001	orsa->n = pubkey->bn[RSA_N].bn;
2002	orsa->e = pubkey->bn[RSA_E].bn;
2003	n = rsa_public_decrypt((int)length, in, out, orsa, NETPGPV_RSA_NO_PADDING);
2004	orsa->n = orsa->e = NULL;
2005	free(orsa);
2006	return n;
2007}
2008
2009/* verify rsa signature */
2010static int
2011rsa_verify(uint8_t *calculated, unsigned calclen, uint8_t hashalg, pgpv_bignum_t *bn, pgpv_pubkey_t *pubkey)
2012{
2013	unsigned	 prefixlen;
2014	unsigned	 decryptc;
2015	unsigned	 i;
2016	uint8_t		 decrypted[8192];
2017	uint8_t		 sigbn[8192];
2018	uint8_t		 prefix[64];
2019	size_t		 keysize;
2020
2021	keysize = BITS_TO_BYTES(pubkey->bn[RSA_N].bits);
2022	PGPV_BN_bn2bin(bn[RSA_SIG].bn, sigbn);
2023	decryptc = pgpv_rsa_public_decrypt(decrypted, sigbn, BITS_TO_BYTES(bn[RSA_SIG].bits), pubkey);
2024	if (decryptc != keysize || (decrypted[0] != 0 || decrypted[1] != 1)) {
2025		return 0;
2026	}
2027	if ((prefixlen = digest_get_prefix((unsigned)hashalg, prefix, sizeof(prefix))) == 0) {
2028		printf("rsa_verify: unknown hash algorithm: %d\n", hashalg);
2029		return 0;
2030	}
2031	for (i = 2 ; i < keysize - prefixlen - calclen - 1 ; i++) {
2032		if (decrypted[i] != 0xff) {
2033			return 0;
2034		}
2035	}
2036	if (decrypted[i++] != 0x0) {
2037		return 0;
2038	}
2039	if (memcmp(&decrypted[i], prefix, prefixlen) != 0) {
2040		printf("rsa_verify: wrong hash algorithm\n");
2041		return 0;
2042	}
2043	return memcmp(&decrypted[i + prefixlen], calculated, calclen) == 0;
2044}
2045
2046/* return 1 if bn <= 0 */
2047static int
2048bignum_is_bad(PGPV_BIGNUM *bn)
2049{
2050	return PGPV_BN_is_zero(bn) || PGPV_BN_is_negative(bn);
2051}
2052
2053#define BAD_BIGNUM(s, k)	\
2054	(bignum_is_bad((s)->bn) || PGPV_BN_cmp((s)->bn, (k)->bn) >= 0)
2055
2056#ifndef DSA_MAX_MODULUS_BITS
2057#define DSA_MAX_MODULUS_BITS      10000
2058#endif
2059
2060/* verify DSA signature */
2061static int
2062verify_dsa_sig(uint8_t *calculated, unsigned calclen, pgpv_bignum_t *sig, pgpv_pubkey_t *pubkey)
2063{
2064	PGPV_BIGNUM	 *M;
2065	PGPV_BIGNUM	 *W;
2066	PGPV_BIGNUM	 *t1;
2067	unsigned	  qbits;
2068	uint8_t		  calcnum[128];
2069	uint8_t		  signum[128];
2070	int		  ret;
2071
2072	if (pubkey->bn[DSA_P].bn == NULL ||
2073	    pubkey->bn[DSA_Q].bn == NULL ||
2074	    pubkey->bn[DSA_G].bn == NULL) {
2075		return 0;
2076	}
2077	M = W = t1 = NULL;
2078	qbits = pubkey->bn[DSA_Q].bits;
2079	switch(qbits) {
2080	case 160:
2081	case 224:
2082	case 256:
2083		break;
2084	default:
2085		printf("dsa: bad # of Q bits\n");
2086		return 0;
2087	}
2088	if (pubkey->bn[DSA_P].bits > DSA_MAX_MODULUS_BITS) {
2089		printf("dsa: p too large\n");
2090		return 0;
2091	}
2092	if (calclen > SHA256_DIGEST_LENGTH) {
2093		printf("dsa: digest too long\n");
2094		return 0;
2095	}
2096	ret = 0;
2097	if ((M = PGPV_BN_new()) == NULL || (W = PGPV_BN_new()) == NULL || (t1 = PGPV_BN_new()) == NULL ||
2098	    BAD_BIGNUM(&sig[DSA_R], &pubkey->bn[DSA_Q]) ||
2099	    BAD_BIGNUM(&sig[DSA_S], &pubkey->bn[DSA_Q]) ||
2100	    PGPV_BN_mod_inverse(W, sig[DSA_S].bn, pubkey->bn[DSA_Q].bn, NULL) == NULL) {
2101		goto done;
2102	}
2103	if (calclen > qbits / 8) {
2104		calclen = qbits / 8;
2105	}
2106	if (PGPV_BN_bin2bn(calculated, (int)calclen, M) == NULL ||
2107	    !PGPV_BN_mod_mul(M, M, W, pubkey->bn[DSA_Q].bn, NULL) ||
2108	    !PGPV_BN_mod_mul(W, sig[DSA_R].bn, W, pubkey->bn[DSA_Q].bn, NULL) ||
2109	    !PGPV_BN_mod_exp(t1, pubkey->bn[DSA_G].bn, M, pubkey->bn[DSA_P].bn, NULL) ||
2110	    !PGPV_BN_mod_exp(W, pubkey->bn[DSA_Y].bn, W, pubkey->bn[DSA_P].bn, NULL) ||
2111	    !PGPV_BN_mod_mul(t1, t1, W, pubkey->bn[DSA_P].bn, NULL) ||
2112	    !PGPV_BN_div(NULL, t1, t1, pubkey->bn[DSA_Q].bn, NULL)) {
2113		goto done;
2114	}
2115	/* only compare the first q bits */
2116	PGPV_BN_bn2bin(t1, calcnum);
2117	PGPV_BN_bn2bin(sig[DSA_R].bn, signum);
2118	ret = memcmp(calcnum, signum, BITS_TO_BYTES(qbits)) == 0;
2119done:
2120	if (M) {
2121		PGPV_BN_clear_free(M);
2122	}
2123	if (W) {
2124		PGPV_BN_clear_free(W);
2125	}
2126	if (t1) {
2127		PGPV_BN_clear_free(t1);
2128	}
2129	return ret;
2130}
2131
2132#define TIME_SNPRINTF(_cc, _buf, _size, _fmt, _val)	do {		\
2133	time_t	 _t;							\
2134	char	*_s;							\
2135									\
2136	_t = _val;							\
2137	_s = ctime(&_t);						\
2138	_cc += snprintf(_buf, _size, _fmt, _s);				\
2139} while(/*CONSTCOND*/0)
2140
2141/* check dates on signature and key are valid */
2142static size_t
2143valid_dates(pgpv_signature_t *signature, pgpv_pubkey_t *pubkey, char *buf, size_t size)
2144{
2145	time_t	 now;
2146	time_t	 t;
2147	size_t	 cc;
2148
2149	cc = 0;
2150	if (signature->birth < pubkey->birth) {
2151		TIME_SNPRINTF(cc, buf, size, "Signature time (%.24s) was before pubkey creation ", signature->birth);
2152		TIME_SNPRINTF(cc, &buf[cc], size - cc, "(%s)", pubkey->birth);
2153		return cc;
2154	}
2155	now = time(NULL);
2156	if (signature->expiry != 0) {
2157		if ((t = signature->birth + signature->expiry) < now) {
2158			TIME_SNPRINTF(cc, buf, size, "Signature expired on %.24s", t);
2159			return cc;
2160		}
2161	}
2162	if (now < signature->birth) {
2163		TIME_SNPRINTF(cc, buf, size, "Signature not valid before %.24s", signature->birth);
2164		return cc;
2165	}
2166	return 0;
2167}
2168
2169/* check if the signing key has expired */
2170static int
2171key_expired(pgpv_pubkey_t *pubkey, char *buf, size_t size)
2172{
2173	time_t	 now;
2174	time_t	 t;
2175	size_t	 cc;
2176
2177	now = time(NULL);
2178	cc = 0;
2179	if (pubkey->expiry != 0) {
2180		if ((t = pubkey->birth + pubkey->expiry) < now) {
2181			TIME_SNPRINTF(cc, buf, size, "Pubkey expired on %.24s", t);
2182			return (int)cc;
2183		}
2184	}
2185	if (now < pubkey->birth) {
2186		TIME_SNPRINTF(cc, buf, size, "Pubkey not valid before %.24s", pubkey->birth);
2187		return (int)cc;
2188	}
2189	return 0;
2190}
2191
2192/* find the leading onepass packet */
2193static size_t
2194find_onepass(pgpv_cursor_t *cursor, size_t datastart)
2195{
2196	size_t	pkt;
2197
2198	for (pkt = datastart ; pkt < ARRAY_COUNT(cursor->pgp->pkts) ; pkt++) {
2199		if (ARRAY_ELEMENT(cursor->pgp->pkts, pkt).tag == ONEPASS_SIGNATURE_PKT) {
2200			return pkt + 1;
2201		}
2202	}
2203	snprintf(cursor->why, sizeof(cursor->why), "No signature to verify");
2204	return 0;
2205}
2206
2207static const char	*armor_begins[] = {
2208	"-----BEGIN PGP SIGNED MESSAGE-----\n",
2209	"-----BEGIN PGP MESSAGE-----\n",
2210	NULL
2211};
2212
2213/* return non-zero if the buf introduces an armored message */
2214static int
2215is_armored(const char *buf, size_t size)
2216{
2217	const char	**arm;
2218	const char	 *nl;
2219	size_t		  n;
2220
2221	if ((nl = memchr(buf, '\n', size)) == NULL) {
2222		return 0;
2223	}
2224	n = (size_t)(nl - buf);
2225	for (arm = armor_begins ; *arm ; arm++) {
2226		if (strncmp(buf, *arm, n) == 0) {
2227			return 1;
2228		}
2229	}
2230	return 0;
2231}
2232
2233/* find first occurrence of pat binary string in block */
2234static void *
2235find_bin_string(const void *blockarg, size_t blen, const void *pat, size_t plen)
2236{
2237	const uint8_t	*block;
2238	const uint8_t	*bp;
2239
2240	if (plen == 0) {
2241		return __UNCONST(blockarg);
2242	}
2243	if (blen < plen) {
2244		return NULL;
2245	}
2246	for (bp = block = blockarg ; (size_t)(bp - block) < blen - plen + 1 ; bp++) {
2247		if (memcmp(bp, pat, plen) == 0) {
2248			return __UNCONST(bp);
2249		}
2250	}
2251	return NULL;
2252}
2253
2254/* store string in allocated memory */
2255static uint8_t *
2256pgpv_strdup(const char *s)
2257{
2258	uint8_t	*cp;
2259	size_t	 len;
2260
2261	len = strlen(s);
2262	if ((cp = calloc(len + 1, 1)) != NULL) {
2263		memcpy(cp, s, len);
2264	}
2265	return cp;
2266}
2267
2268#define SIGSTART	"-----BEGIN PGP SIGNATURE-----\n"
2269#define SIGEND		"-----END PGP SIGNATURE-----\n"
2270
2271/* for ascii armor, we don't get a onepass packet - make one */
2272static const char 	*cons_onepass = "\304\015\003\0\0\0\0\377\377\377\377\377\377\377\377\1";
2273
2274/* read ascii armor */
2275static int
2276read_ascii_armor(pgpv_cursor_t *cursor, pgpv_mem_t *mem, const char *filename)
2277{
2278	pgpv_onepass_t	*onepass;
2279	pgpv_sigpkt_t	*sigpkt;
2280	pgpv_pkt_t	 litdata;
2281	uint8_t		 binsig[8192];
2282	uint8_t		*datastart;
2283	uint8_t		*sigend;
2284	uint8_t		*p;
2285	size_t		 binsigsize;
2286
2287	/* cons up litdata pkt */
2288	memset(&litdata, 0x0, sizeof(litdata));
2289	litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1;
2290	p = mem->mem;
2291	/* jump over signed message line */
2292	if ((p = find_bin_string(mem->mem, mem->size, "\n\n",  2)) == NULL) {
2293		snprintf(cursor->why, sizeof(cursor->why), "malformed armor at offset 0");
2294		return 0;
2295	}
2296	p += 2;
2297	litdata.tag = LITDATA_PKT;
2298	litdata.s.data = p;
2299	litdata.u.litdata.offset = (size_t)(p - mem->mem);
2300	litdata.u.litdata.filename.data = pgpv_strdup(filename);
2301	litdata.u.litdata.filename.allocated = 1;
2302	if ((p = find_bin_string(datastart = p, mem->size - litdata.offset, SIGSTART, sizeof(SIGSTART) - 1)) == NULL) {
2303		snprintf(cursor->why, sizeof(cursor->why),
2304			"malformed armor - no sig - at %zu", (size_t)(p - mem->mem));
2305		return 0;
2306	}
2307	litdata.u.litdata.len = litdata.s.size = (size_t)(p - datastart);
2308	/* this puts p at the newline character, so it will find \n\n if no version */
2309	p += strlen(SIGSTART) - 1;
2310	if ((p = find_bin_string(p, mem->size, "\n\n",  2)) == NULL) {
2311		snprintf(cursor->why, sizeof(cursor->why),
2312			"malformed armed signature at %zu", (size_t)(p - mem->mem));
2313		return 0;
2314	}
2315	p += 2;
2316	sigend = find_bin_string(p, mem->size, SIGEND, sizeof(SIGEND) - 1);
2317	if (sigend == NULL) {
2318		snprintf(cursor->why, sizeof(cursor->why),
2319			"malformed armor - no end sig - at %zu",
2320			(size_t)(p - mem->mem));
2321		return 0;
2322	}
2323	binsigsize = netpgpv_b64decode((char *)p, (size_t)(sigend - p), binsig, sizeof(binsig));
2324
2325	read_binary_memory(cursor->pgp, "signature", cons_onepass, 15);
2326	ARRAY_APPEND(cursor->pgp->pkts, litdata);
2327	read_binary_memory(cursor->pgp, "signature", binsig, binsigsize - 3);
2328	/* XXX - hardwired - 3 is format and length */
2329
2330	/* fix up packets in the packet array now we have them there */
2331	onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, ARRAY_COUNT(cursor->pgp->pkts) - 1 - 2).u.onepass;
2332	sigpkt = &ARRAY_LAST(cursor->pgp->pkts).u.sigpkt;
2333	memcpy(onepass->keyid, sigpkt->sig.signer, sizeof(onepass->keyid));
2334	onepass->hashalg = sigpkt->sig.hashalg;
2335	onepass->keyalg = sigpkt->sig.keyalg;
2336	return 1;
2337}
2338
2339/* read ascii armor from a file */
2340static int
2341read_ascii_armor_file(pgpv_cursor_t *cursor, const char *filename)
2342{
2343	/* cons up litdata pkt */
2344	read_file(cursor->pgp, filename);
2345	return read_ascii_armor(cursor, &ARRAY_LAST(cursor->pgp->areas), filename);
2346}
2347
2348/* read ascii armor from memory */
2349static int
2350read_ascii_armor_memory(pgpv_cursor_t *cursor, const void *p, size_t size)
2351{
2352	pgpv_mem_t	*mem;
2353
2354	/* cons up litdata pkt */
2355	ARRAY_EXPAND(cursor->pgp->areas);
2356	ARRAY_COUNT(cursor->pgp->areas) += 1;
2357	mem = &ARRAY_LAST(cursor->pgp->areas);
2358	memset(mem, 0x0, sizeof(*mem));
2359	mem->size = size;
2360	mem->mem = __UNCONST(p);
2361	mem->dealloc = 0;
2362	return read_ascii_armor(cursor, mem, "[stdin]");
2363}
2364
2365/* set up the data to verify */
2366static int
2367setup_data(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size)
2368{
2369	FILE		*fp;
2370	char		 buf[BUFSIZ];
2371
2372	if (cursor == NULL || pgp == NULL || p == NULL) {
2373		return 0;
2374	}
2375	memset(cursor, 0x0, sizeof(*cursor));
2376	ARRAY_APPEND(pgp->datastarts, pgp->pkt);
2377	cursor->pgp = pgp;
2378	if (size < 0) {
2379		/* we have a file name in p */
2380		if ((fp = fopen(p, "r")) == NULL) {
2381			snprintf(cursor->why, sizeof(cursor->why), "No such file '%s'", (const char *)p);
2382			return 0;
2383		}
2384		if (fgets(buf, (int)sizeof(buf), fp) == NULL) {
2385			fclose(fp);
2386			snprintf(cursor->why, sizeof(cursor->why), "can't read file '%s'", (const char *)p);
2387			return 0;
2388		}
2389		if (is_armored(buf, sizeof(buf))) {
2390			read_ascii_armor_file(cursor, p);
2391		} else {
2392			read_binary_file(pgp, "signature", "%s", (const char *)p);
2393		}
2394		fclose(fp);
2395	} else {
2396		if (is_armored(p, (size_t)size)) {
2397			read_ascii_armor_memory(cursor, p, (size_t)size);
2398		} else {
2399			read_binary_memory(pgp, "signature", p, (size_t)size);
2400		}
2401	}
2402	return 1;
2403}
2404
2405/* get the data and size from litdata packet */
2406static uint8_t *
2407get_literal_data(pgpv_cursor_t *cursor, pgpv_litdata_t *litdata, size_t *size)
2408{
2409	pgpv_mem_t	*mem;
2410
2411	if (litdata->s.data == NULL && litdata->s.size == 0) {
2412		mem = &ARRAY_ELEMENT(cursor->pgp->areas, litdata->mem);
2413		*size = litdata->len;
2414		return &mem->mem[litdata->offset];
2415	}
2416	*size = litdata->s.size;
2417	return litdata->s.data;
2418}
2419
2420/*
2421RFC 4880 describes the structure of v4 keys as:
2422
2423           Primary-Key
2424              [Revocation Self Signature]
2425              [Direct Key Signature...]
2426               User ID [Signature ...]
2427              [User ID [Signature ...] ...]
2428              [User Attribute [Signature ...] ...]
2429              [[Subkey [Binding-Signature-Revocation]
2430                      Primary-Key-Binding-Signature] ...]
2431
2432and that's implemented below as a recursive descent parser.
2433It has had to be modified, though: see the comment
2434
2435	some keys out there have user ids where they shouldn't
2436
2437to look like:
2438
2439           Primary-Key
2440              [Revocation Self Signature]
2441              [Direct Key Signature...]
2442              [User ID [Signature ...]
2443                 [User ID [Signature ...] ...]
2444                 [User Attribute [Signature ...] ...]
2445                 [Subkey [Binding-Signature-Revocation]
2446                        Primary-Key-Binding-Signature] ...]
2447
2448to accommodate keyrings set up by gpg
2449*/
2450
2451/* recognise a primary key */
2452static int
2453recog_primary_key(pgpv_t *pgp, pgpv_primarykey_t *primary)
2454{
2455	pgpv_signed_userattr_t	 userattr;
2456	pgpv_signed_userid_t	 userid;
2457	pgpv_signed_subkey_t	 subkey;
2458	pgpv_signature_t	 signature;
2459	pgpv_pkt_t		*pkt;
2460
2461	pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt);
2462	memset(primary, 0x0, sizeof(*primary));
2463	read_pubkey(&primary->primary, pkt->s.data, pkt->s.size, 0);
2464	pgp->pkt += 1;
2465	if (pkt_sigtype_is(pgp, SIGTYPE_KEY_REVOCATION)) {
2466		if (!recog_signature(pgp, &primary->revoc_self_sig)) {
2467			printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_KEY_REVOCATION\n");
2468			return 0;
2469		}
2470	}
2471	while (pkt_sigtype_is(pgp, SIGTYPE_DIRECT_KEY)) {
2472		if (!recog_signature(pgp, &signature)) {
2473			printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_DIRECT_KEY\n");
2474			return 0;
2475		}
2476		if (signature.keyexpiry) {
2477			/* XXX - check it's a good key expiry */
2478			primary->primary.expiry = signature.keyexpiry;
2479		}
2480		ARRAY_APPEND(primary->signatures, ARRAY_COUNT(pgp->signatures));
2481		ARRAY_APPEND(pgp->signatures, signature);
2482	}
2483	/* some keys out there have user ids where they shouldn't */
2484	do {
2485		if (!recog_userid(pgp, &userid)) {
2486			printf("recog_primary_key: not userid\n");
2487			return 0;
2488		}
2489		ARRAY_APPEND(primary->signed_userids, ARRAY_COUNT(pgp->signed_userids));
2490		ARRAY_APPEND(pgp->signed_userids, userid);
2491		if (userid.primary_userid) {
2492			primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1;
2493		}
2494		while (pkt_is(pgp, USERID_PKT)) {
2495			if (!recog_userid(pgp, &userid)) {
2496				printf("recog_primary_key: not signed secondary userid\n");
2497				return 0;
2498			}
2499			ARRAY_APPEND(primary->signed_userids, ARRAY_COUNT(pgp->signed_userids));
2500			ARRAY_APPEND(pgp->signed_userids, userid);
2501			if (userid.primary_userid) {
2502				primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1;
2503			}
2504		}
2505		while (pkt_is(pgp, USER_ATTRIBUTE_PKT)) {
2506			if (!recog_userattr(pgp, &userattr)) {
2507				printf("recog_primary_key: not signed user attribute\n");
2508				return 0;
2509			}
2510			ARRAY_APPEND(primary->signed_userattrs, ARRAY_COUNT(pgp->signed_userattrs));
2511			ARRAY_APPEND(pgp->signed_userattrs, userattr);
2512		}
2513		while (pkt_is(pgp, PUB_SUBKEY_PKT)) {
2514			if (!recog_subkey(pgp, &subkey)) {
2515				printf("recog_primary_key: not signed public subkey\n");
2516				return 0;
2517			}
2518			calc_keyid(&subkey.subkey, "sha1");
2519			ARRAY_APPEND(primary->signed_subkeys, ARRAY_COUNT(pgp->signed_subkeys));
2520			ARRAY_APPEND(pgp->signed_subkeys, subkey);
2521		}
2522	} while (pgp->pkt < ARRAY_COUNT(pgp->pkts) && pkt_is(pgp, USERID_PKT));
2523	primary->fmtsize = estimate_primarykey_size(primary);
2524	return 1;
2525}
2526
2527/* parse all of the packets for a given operation */
2528static int
2529read_all_packets(pgpv_t *pgp, pgpv_mem_t *mem, const char *op)
2530{
2531	pgpv_primarykey_t	 primary;
2532
2533	if (op == NULL) {
2534		return 0;
2535	}
2536	if (strcmp(pgp->op = op, "pubring") == 0) {
2537		mem->allowed = PUBRING_ALLOWED;
2538		/* pubrings have thousands of small packets */
2539		ARRAY_EXPAND_SIZED(pgp->pkts, 0, 5000);
2540	} else if (strcmp(op, "signature") == 0) {
2541		mem->allowed = SIGNATURE_ALLOWED;
2542	} else {
2543		mem->allowed = "";
2544	}
2545	for (mem->cc = 0; mem->cc < mem->size ; ) {
2546		if (!read_pkt(pgp, mem)) {
2547			return 0;
2548		}
2549	}
2550	if (strcmp(op, "pubring") == 0) {
2551		for (pgp->pkt = 0; pgp->pkt < ARRAY_COUNT(pgp->pkts) && recog_primary_key(pgp, &primary) ; ) {
2552			calc_keyid(&primary.primary, "sha1");
2553			ARRAY_APPEND(pgp->primaries, primary);
2554		}
2555		if (pgp->pkt < ARRAY_COUNT(pgp->pkts)) {
2556			printf("short pubring recognition???\n");
2557		}
2558	}
2559	pgp->pkt = ARRAY_COUNT(pgp->pkts);
2560	return 1;
2561}
2562
2563/* create a filename, read it, and then parse according to "op" */
2564static int
2565read_binary_file(pgpv_t *pgp, const char *op, const char *fmt, ...)
2566{
2567	va_list	args;
2568	char	buf[1024];
2569
2570	va_start(args, fmt);
2571	vsnprintf(buf, sizeof(buf), fmt, args);
2572	va_end(args);
2573	if (!read_file(pgp, buf)) {
2574		return 0;
2575	}
2576	return read_all_packets(pgp, &ARRAY_LAST(pgp->areas), op);
2577}
2578
2579/* get a bignum from the buffer gap */
2580static int
2581getbignum(pgpv_bignum_t *bignum, bufgap_t *bg, char *buf, const char *header)
2582{
2583	uint32_t	 len;
2584
2585	USE_ARG(header);
2586	(void) bufgap_getbin(bg, &len, sizeof(len));
2587	len = pgp_ntoh32(len);
2588	(void) bufgap_seek(bg, sizeof(len), BGFromHere, BGByte);
2589	(void) bufgap_getbin(bg, buf, len);
2590	bignum->bn = PGPV_BN_bin2bn((const uint8_t *)buf, (int)len, NULL);
2591	bignum->bits = PGPV_BN_num_bits(bignum->bn);
2592	(void) bufgap_seek(bg, len, BGFromHere, BGByte);
2593	return 1;
2594}
2595
2596/* structure for searching for constant strings */
2597typedef struct str_t {
2598	const char	*s;		/* string */
2599	size_t		 len;		/* its length */
2600	int		 type;		/* return type */
2601} str_t;
2602
2603static str_t	pkatypes[] = {
2604	{	"ssh-rsa",	7,	PUBKEY_RSA_SIGN	},
2605	{	"ssh-dss",	7,	PUBKEY_DSA	},
2606	{	"ssh-dsa",	7,	PUBKEY_DSA	},
2607	{	NULL,		0,	0		}
2608};
2609
2610/* look for a string in the given array */
2611static int
2612findstr(str_t *array, const char *name)
2613{
2614	str_t	*sp;
2615
2616	for (sp = array ; sp->s ; sp++) {
2617		if (strncmp(name, sp->s, sp->len) == 0) {
2618			return sp->type;
2619		}
2620	}
2621	return -1;
2622}
2623
2624/* read public key from the ssh pubkey file */
2625static __printflike(3, 4) int
2626read_ssh_file(pgpv_t *pgp, pgpv_primarykey_t *primary, const char *fmt, ...)
2627{
2628	pgpv_signed_userid_t	 userid;
2629	pgpv_pubkey_t		*pubkey;
2630	struct stat		 st;
2631	bufgap_t		 bg;
2632	uint32_t		 len;
2633	int64_t			 off;
2634	va_list			 args;
2635	char			 hostname[256];
2636	char			 owner[256];
2637	char			*space;
2638	char		 	*buf;
2639	char		 	*bin;
2640	char			 newbuf[2048];
2641	char			 f[1024];
2642	int			 ok;
2643	int			 cc;
2644
2645	USE_ARG(pgp);
2646	memset(primary, 0x0, sizeof(*primary));
2647	(void) memset(&bg, 0x0, sizeof(bg));
2648	va_start(args, fmt);
2649	vsnprintf(f, sizeof(f), fmt, args);
2650	va_end(args);
2651	if (!bufgap_open(&bg, f)) {
2652		(void) fprintf(stderr, "pgp_ssh2pubkey: can't open '%s'\n", f);
2653		return 0;
2654	}
2655	(void)stat(f, &st);
2656	if ((buf = calloc(1, (size_t)st.st_size)) == NULL) {
2657		(void) fprintf(stderr, "can't calloc %zu bytes for '%s'\n", (size_t)st.st_size, f);
2658		bufgap_close(&bg);
2659		return 0;
2660	}
2661	if ((bin = calloc(1, (size_t)st.st_size)) == NULL) {
2662		(void) fprintf(stderr, "can't calloc %zu bytes for '%s'\n", (size_t)st.st_size, f);
2663		(void) free(buf);
2664		bufgap_close(&bg);
2665		return 0;
2666	}
2667
2668	/* move past ascii type of key */
2669	while (bufgap_peek(&bg, 0) != ' ') {
2670		if (!bufgap_seek(&bg, 1, BGFromHere, BGByte)) {
2671			(void) fprintf(stderr, "bad key file '%s'\n", f);
2672			(void) free(buf);
2673			bufgap_close(&bg);
2674			return 0;
2675		}
2676	}
2677	if (!bufgap_seek(&bg, 1, BGFromHere, BGByte)) {
2678		(void) fprintf(stderr, "bad key file '%s'\n", f);
2679		(void) free(buf);
2680		bufgap_close(&bg);
2681		return 0;
2682	}
2683	off = bufgap_tell(&bg, BGFromBOF, BGByte);
2684
2685	if (bufgap_size(&bg, BGByte) - off < 10) {
2686		(void) fprintf(stderr, "bad key file '%s'\n", f);
2687		(void) free(buf);
2688		bufgap_close(&bg);
2689		return 0;
2690	}
2691
2692	/* convert from base64 to binary */
2693	cc = bufgap_getbin(&bg, buf, (size_t)bg.bcc);
2694	if ((space = strchr(buf, ' ')) != NULL) {
2695		cc = (int)(space - buf);
2696	}
2697	cc = frombase64(bin, buf, (size_t)cc, 0);
2698	bufgap_delete(&bg, (uint64_t)bufgap_tell(&bg, BGFromEOF, BGByte));
2699	bufgap_insert(&bg, bin, cc);
2700	bufgap_seek(&bg, off, BGFromBOF, BGByte);
2701
2702	/* get the type of key */
2703	(void) bufgap_getbin(&bg, &len, sizeof(len));
2704	len = pgp_ntoh32(len);
2705	if (len >= st.st_size) {
2706		(void) fprintf(stderr, "bad public key file '%s'\n", f);
2707		return 0;
2708	}
2709	(void) bufgap_seek(&bg, sizeof(len), BGFromHere, BGByte);
2710	(void) bufgap_getbin(&bg, buf, len);
2711	(void) bufgap_seek(&bg, len, BGFromHere, BGByte);
2712
2713	pubkey = &primary->primary;
2714	pubkey->hashalg = digest_get_alg("sha256"); /* gets fixed up later */
2715	pubkey->version = 4;
2716	pubkey->birth = 0; /* gets fixed up later */
2717	/* get key type */
2718	ok = 1;
2719	switch (pubkey->keyalg = findstr(pkatypes, buf)) {
2720	case PUBKEY_RSA_ENCRYPT_OR_SIGN:
2721	case PUBKEY_RSA_SIGN:
2722		getbignum(&pubkey->bn[RSA_E], &bg, buf, "RSA E");
2723		getbignum(&pubkey->bn[RSA_N], &bg, buf, "RSA N");
2724		break;
2725	case PUBKEY_DSA:
2726		getbignum(&pubkey->bn[DSA_P], &bg, buf, "DSA P");
2727		getbignum(&pubkey->bn[DSA_Q], &bg, buf, "DSA Q");
2728		getbignum(&pubkey->bn[DSA_G], &bg, buf, "DSA G");
2729		getbignum(&pubkey->bn[DSA_Y], &bg, buf, "DSA Y");
2730		break;
2731	default:
2732		(void) fprintf(stderr, "Unrecognised pubkey type %d for '%s'\n",
2733				pubkey->keyalg, f);
2734		ok = 0;
2735		break;
2736	}
2737
2738	/* check for stragglers */
2739	if (ok && bufgap_tell(&bg, BGFromEOF, BGByte) > 0) {
2740		printf("%"PRIi64" bytes left\n", bufgap_tell(&bg, BGFromEOF, BGByte));
2741		printf("[%s]\n", bufgap_getstr(&bg));
2742		ok = 0;
2743	}
2744	if (ok) {
2745		memset(&userid, 0x0, sizeof(userid));
2746		(void) gethostname(hostname, sizeof(hostname));
2747		if (strlen(space + 1) - 1 == 0) {
2748			(void) snprintf(owner, sizeof(owner), "<root@%.*s>",
2749					240, hostname);
2750		} else {
2751			(void) snprintf(owner, sizeof(owner), "<%.*s>",
2752				(int)strlen(space + 1) - 1,
2753				space + 1);
2754		}
2755		calc_keyid(pubkey, "sha1");
2756		cc = snprintf(newbuf, sizeof(newbuf), "%s (%s) %s",
2757			hostname, f, owner);
2758		userid.userid.size = cc;
2759		userid.userid.allocated = 1;
2760		if ((userid.userid.data = calloc(1, cc + 1)) == NULL) {
2761			ok = 0;
2762		} else {
2763			memcpy(userid.userid.data, newbuf, cc);
2764			ARRAY_APPEND(primary->signed_userids, ARRAY_COUNT(pgp->signed_userids));
2765			ARRAY_APPEND(pgp->signed_userids, userid);
2766			primary->fmtsize = estimate_primarykey_size(primary) + 1024;
2767		}
2768	}
2769	(void) free(bin);
2770	(void) free(buf);
2771	bufgap_close(&bg);
2772	return ok;
2773}
2774
2775/* parse memory according to "op" */
2776static int
2777read_binary_memory(pgpv_t *pgp, const char *op, const void *memory, size_t size)
2778{
2779	pgpv_mem_t	*mem;
2780
2781	ARRAY_EXPAND(pgp->areas);
2782	ARRAY_COUNT(pgp->areas) += 1;
2783	mem = &ARRAY_LAST(pgp->areas);
2784	memset(mem, 0x0, sizeof(*mem));
2785	mem->size = size;
2786	mem->mem = __UNCONST(memory);
2787	mem->dealloc = 0;
2788	return read_all_packets(pgp, mem, op);
2789}
2790
2791/* fixup the detached signature packets */
2792static int
2793fixup_detached(pgpv_cursor_t *cursor, const char *f)
2794{
2795	pgpv_onepass_t	*onepass;
2796	const char	*dot;
2797	pgpv_pkt_t	 sigpkt;
2798	pgpv_pkt_t	 litdata;
2799	pgpv_mem_t	*mem;
2800	size_t		 el;
2801	char		 original[MAXPATHLEN];
2802
2803	/* cons up litdata pkt */
2804	if ((dot = strrchr(f, '.')) == NULL || strcasecmp(dot, ".sig") != 0) {
2805		printf("weird filename '%s'\n", f);
2806		return 0;
2807	}
2808	/* hold sigpkt in a temp var while we insert onepass and litdata */
2809	el = ARRAY_COUNT(cursor->pgp->pkts) - 1;
2810	sigpkt = ARRAY_ELEMENT(cursor->pgp->pkts, el);
2811	ARRAY_DELETE(cursor->pgp->pkts, el);
2812	ARRAY_EXPAND(cursor->pgp->pkts);
2813	/* get onepass packet, append to packets */
2814	read_binary_memory(cursor->pgp, "signature", cons_onepass, 15);
2815	onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, el).u.onepass;
2816	/* read the original file into litdata */
2817	snprintf(original, sizeof(original), "%.*s", (int)(dot - f), f);
2818	if (!read_file(cursor->pgp, original)) {
2819		printf("can't read file '%s'\n", original);
2820		return 0;
2821	}
2822	memset(&litdata, 0x0, sizeof(litdata));
2823	mem = &ARRAY_LAST(cursor->pgp->areas);
2824	litdata.tag = LITDATA_PKT;
2825	litdata.s.data = mem->mem;
2826	litdata.u.litdata.format = LITDATA_BINARY;
2827	litdata.u.litdata.offset = 0;
2828	litdata.u.litdata.filename.data = pgpv_strdup(original);
2829	litdata.u.litdata.filename.allocated = 1;
2830	litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1;
2831	litdata.u.litdata.len = litdata.s.size = mem->size;
2832	ARRAY_APPEND(cursor->pgp->pkts, litdata);
2833	ARRAY_APPEND(cursor->pgp->pkts, sigpkt);
2834	memcpy(onepass->keyid, sigpkt.u.sigpkt.sig.signer, sizeof(onepass->keyid));
2835	onepass->hashalg = sigpkt.u.sigpkt.sig.hashalg;
2836	onepass->keyalg = sigpkt.u.sigpkt.sig.keyalg;
2837	return 1;
2838}
2839
2840/* match the calculated signature against the one in the signature packet */
2841static int
2842match_sig(pgpv_cursor_t *cursor, pgpv_signature_t *signature, pgpv_pubkey_t *pubkey, uint8_t *data, size_t size)
2843{
2844	unsigned	calclen;
2845	uint8_t		calculated[64];
2846	int		match;
2847
2848	calclen = pgpv_digest_memory(calculated, sizeof(calculated),
2849		data, size,
2850		get_ref(&signature->hashstart), signature->hashlen,
2851		(signature->type == SIGTYPE_TEXT) ? 't' : 'b');
2852	if (ALG_IS_RSA(signature->keyalg)) {
2853		match = rsa_verify(calculated, calclen, signature->hashalg, signature->bn, pubkey);
2854	} else if (ALG_IS_DSA(signature->keyalg)) {
2855		match = verify_dsa_sig(calculated, calclen, signature->bn, pubkey);
2856	} else {
2857		snprintf(cursor->why, sizeof(cursor->why), "Signature type %u not recognised", signature->keyalg);
2858		return 0;
2859	}
2860	if (!match && signature->type == SIGTYPE_TEXT) {
2861		/* second try for cleartext data, ignoring trailing whitespace */
2862		calclen = pgpv_digest_memory(calculated, sizeof(calculated),
2863			data, size,
2864			get_ref(&signature->hashstart), signature->hashlen, 'w');
2865		if (ALG_IS_RSA(signature->keyalg)) {
2866			match = rsa_verify(calculated, calclen, signature->hashalg, signature->bn, pubkey);
2867		} else if (ALG_IS_DSA(signature->keyalg)) {
2868			match = verify_dsa_sig(calculated, calclen, signature->bn, pubkey);
2869		}
2870	}
2871	if (!match) {
2872		snprintf(cursor->why, sizeof(cursor->why), "Signature on data did not match");
2873		return 0;
2874	}
2875	if (valid_dates(signature, pubkey, cursor->why, sizeof(cursor->why)) > 0) {
2876		return 0;
2877	}
2878	if (key_expired(pubkey, cursor->why, sizeof(cursor->why))) {
2879		return 0;
2880	}
2881	if (signature->revoked) {
2882		snprintf(cursor->why, sizeof(cursor->why), "Signature was revoked");
2883		return 0;
2884	}
2885	return 1;
2886}
2887
2888/* fixup key id, with birth, keyalg and hashalg value from signature */
2889static int
2890fixup_ssh_keyid(pgpv_t *pgp, pgpv_signature_t *signature, const char *hashtype)
2891{
2892	pgpv_pubkey_t	*pubkey;
2893	unsigned	 i;
2894
2895	for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) {
2896		pubkey = &ARRAY_ELEMENT(pgp->primaries, i).primary;
2897		pubkey->keyalg = signature->keyalg;
2898		calc_keyid(pubkey, hashtype);
2899	}
2900	return 1;
2901}
2902
2903/* find key id */
2904static int
2905find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid, unsigned *sub)
2906{
2907	pgpv_signed_subkey_t	*subkey;
2908	pgpv_primarykey_t	*prim;
2909	unsigned		 i;
2910	unsigned		 j;
2911	uint64_t		 n;
2912	uint8_t			 binkeyid[PGPV_KEYID_LEN];
2913	size_t			 off;
2914	size_t			 cmp;
2915
2916	if (strkeyid == NULL && keyid == NULL) {
2917		return 0;
2918	}
2919	if (strkeyid) {
2920		str_to_keyid(strkeyid, binkeyid);
2921		cmp = strlen(strkeyid) / 2;
2922	} else {
2923		memcpy(binkeyid, keyid, sizeof(binkeyid));
2924		cmp = PGPV_KEYID_LEN;
2925	}
2926	*sub = 0;
2927	off = PGPV_KEYID_LEN - cmp;
2928	for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) {
2929		prim = &ARRAY_ELEMENT(pgp->primaries, i);
2930		if (memcmp(&prim->primary.keyid[off], &binkeyid[off], cmp) == 0) {
2931			return i;
2932		}
2933		for (j = 0 ; j < ARRAY_COUNT(prim->signed_subkeys) ; j++) {
2934			n = ARRAY_ELEMENT(prim->signed_subkeys, j);
2935			subkey = &ARRAY_ELEMENT(pgp->signed_subkeys, n);
2936			if (memcmp(&subkey->subkey.keyid[off], &binkeyid[off], cmp) == 0) {
2937				*sub = j + 1;
2938				return i;
2939			}
2940		}
2941
2942	}
2943	return -1;
2944}
2945
2946/* match the signature with the id indexed by 'primary' */
2947static int
2948match_sig_id(pgpv_cursor_t *cursor, pgpv_t *pgp, pgpv_signature_t *signature, pgpv_litdata_t *litdata, unsigned primary, unsigned sub)
2949{
2950	pgpv_primarykey_t	*prim;
2951	pgpv_pubkey_t		*pubkey;
2952	uint64_t		 n;
2953	uint8_t			*data;
2954	size_t			 insize;
2955
2956	cursor->sigtime = signature->birth;
2957	/* calc hash on data packet */
2958	data = get_literal_data(cursor, litdata, &insize);
2959	if (sub == 0) {
2960		pubkey = &ARRAY_ELEMENT(cursor->pgp->primaries, primary).primary;
2961		return match_sig(cursor, signature, pubkey, data, insize);
2962	}
2963	prim = &ARRAY_ELEMENT(cursor->pgp->primaries, primary);
2964	n = ARRAY_ELEMENT(prim->signed_subkeys, sub - 1);
2965	pubkey = &ARRAY_ELEMENT(pgp->signed_subkeys, n).subkey;
2966	return match_sig(cursor, signature, pubkey, data, insize);
2967}
2968
2969/* return the packet type */
2970static const char *
2971get_packet_type(uint8_t tag)
2972{
2973	switch(tag) {
2974	case SIGNATURE_PKT:
2975		return "signature packet";
2976	case ONEPASS_SIGNATURE_PKT:
2977		return "onepass signature packet";
2978	case PUBKEY_PKT:
2979		return "pubkey packet";
2980	case COMPRESSED_DATA_PKT:
2981		return "compressed data packet";
2982	case MARKER_PKT:
2983		return "marker packet";
2984	case LITDATA_PKT:
2985		return "litdata packet";
2986	case TRUST_PKT:
2987		return "trust packet";
2988	case USERID_PKT:
2989		return "userid packet";
2990	case PUB_SUBKEY_PKT:
2991		return "public subkey packet";
2992	case USER_ATTRIBUTE_PKT:
2993		return "user attribute packet";
2994	default:
2995		return "[UNKNOWN]";
2996	}
2997}
2998
2999/* check return value from getenv */
3000static const char *
3001nonnull_getenv(const char *key)
3002{
3003	char	*value;
3004
3005	return ((value = getenv(key)) == NULL) ? "" : value;
3006}
3007
3008/* free an array of bignums */
3009static void
3010free_bn_array(pgpv_bignum_t *v, unsigned n)
3011{
3012	unsigned	i;
3013
3014	for (i = 0 ; i < n ; i++) {
3015		PGPV_BN_clear_free(v[i].bn);
3016		v[i].bn = NULL;
3017	}
3018}
3019
3020/************************************************************************/
3021/* start of exported functions */
3022/************************************************************************/
3023
3024/* close all stuff */
3025int
3026pgpv_close(pgpv_t *pgp)
3027{
3028	pgpv_primarykey_t	*primary;
3029	pgpv_pkt_t		*pkt;
3030	uint64_t		 n;
3031	unsigned		 i;
3032	unsigned		 j;
3033
3034	if (pgp == NULL) {
3035		return 0;
3036	}
3037	for (i = 0 ; i < ARRAY_COUNT(pgp->areas) ; i++) {
3038		if (ARRAY_ELEMENT(pgp->areas, i).size > 0) {
3039			closemem(&ARRAY_ELEMENT(pgp->areas, i));
3040		}
3041	}
3042        ARRAY_FREE(pgp->areas);
3043        for (i = 0 ; i < ARRAY_COUNT(pgp->pkts) ; i++) {
3044                pkt = &ARRAY_ELEMENT(pgp->pkts, i);
3045                switch(pkt->tag) {
3046                case SIGNATURE_PKT:
3047                        ARRAY_FREE(pkt->u.sigpkt.subpackets);
3048                        break;
3049                case LITDATA_PKT:
3050			if (pkt->u.litdata.filename.allocated) {
3051				free(pkt->u.litdata.filename.data);
3052			}
3053                        break;
3054		case PUBKEY_PKT:
3055			free_bn_array(pkt->u.pubkey.bn, PGPV_MAX_PUBKEY_BN);
3056			break;
3057                case USERID_PKT:
3058			if (pkt->u.userid.allocated) {
3059				free(pkt->u.userid.data);
3060			}
3061                        break;
3062                case USER_ATTRIBUTE_PKT:
3063                        ARRAY_FREE(pkt->u.userattr.subattrs);
3064                        break;
3065                }
3066        }
3067        ARRAY_FREE(pgp->pkts);
3068	for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) {
3069		primary = &ARRAY_ELEMENT(pgp->primaries, i);
3070		free_bn_array(primary->primary.bn, PGPV_MAX_PUBKEY_BN);
3071		ARRAY_FREE(primary->signatures);
3072		for (j = 0 ; j < ARRAY_COUNT(primary->signed_userids) ; j++) {
3073			n = ARRAY_ELEMENT(primary->signed_userids, j);
3074			ARRAY_FREE(ARRAY_ELEMENT(pgp->signed_userids, n).signatures);
3075		}
3076		ARRAY_FREE(primary->signed_userids);
3077		ARRAY_FREE(primary->signed_userattrs);
3078		ARRAY_FREE(primary->signed_subkeys);
3079	}
3080	for (i = 0 ; i < ARRAY_COUNT(pgp->signatures) ; i++) {
3081		free_bn_array(ARRAY_ELEMENT(pgp->signatures, i).bn, PGPV_MAX_SIG_BN);
3082	}
3083	for (i = 0 ; i < ARRAY_COUNT(pgp->signed_subkeys) ; i++) {
3084		free_bn_array(ARRAY_ELEMENT(pgp->signed_subkeys, i).subkey.bn, PGPV_MAX_SIG_BN);
3085	}
3086	ARRAY_FREE(pgp->primaries);
3087	ARRAY_FREE(pgp->datastarts);
3088	ARRAY_FREE(pgp->signatures);
3089	ARRAY_FREE(pgp->signed_userids);
3090	ARRAY_FREE(pgp->signed_userattrs);
3091	ARRAY_FREE(pgp->signed_subkeys);
3092	ARRAY_FREE(pgp->subpkts);
3093	return 1;
3094}
3095
3096/* free resources attached to cursor */
3097int
3098pgpv_cursor_close(pgpv_cursor_t *cursor)
3099{
3100	if (cursor) {
3101		ARRAY_FREE(cursor->datacookies);
3102		ARRAY_FREE(cursor->found);
3103	}
3104	return 0;
3105}
3106
3107/* return the formatted entry for the primary key desired */
3108size_t
3109pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **s, const char *modifiers)
3110{
3111	unsigned	subkey;
3112	unsigned	prim;
3113	obuf_t		obuf;
3114
3115	prim = ((ent >> 8) & 0xffffff);
3116	subkey = (ent & 0xff);
3117	if (s == NULL || pgp == NULL || prim >= ARRAY_COUNT(pgp->primaries)) {
3118		return 0;
3119	}
3120	*s = NULL;
3121	if (modifiers == NULL || (strcasecmp(modifiers, "trust") != 0 && strcasecmp(modifiers, "subkeys") != 0)) {
3122		modifiers = "no-subkeys";
3123	}
3124	memset(&obuf, 0x0, sizeof(obuf));
3125	if (!fmt_primary(&obuf, pgp, &ARRAY_ELEMENT(pgp->primaries, prim), subkey, modifiers)) {
3126		return 0;
3127	}
3128	*s = (char *)obuf.v;
3129	return obuf.c;
3130}
3131
3132/* make a new pgpv struct */
3133pgpv_t *
3134pgpv_new(void)
3135{
3136	return calloc(1, sizeof(pgpv_t));
3137}
3138
3139/* make a new pgpv_cursor struct */
3140pgpv_cursor_t *
3141pgpv_new_cursor(void)
3142{
3143	return calloc(1, sizeof(pgpv_cursor_t));
3144}
3145
3146/* get an element from the found array */
3147int
3148pgpv_get_cursor_element(pgpv_cursor_t *cursor, size_t element)
3149{
3150	if (cursor && element < ARRAY_COUNT(cursor->found)) {
3151		return (int)ARRAY_ELEMENT(cursor->found, element);
3152	}
3153	return -1;
3154}
3155
3156/* verify the signed packets we have */
3157size_t
3158pgpv_verify(pgpv_cursor_t *cursor, pgpv_t *pgp, const void *p, ssize_t size)
3159{
3160	pgpv_signature_t	*signature;
3161	pgpv_onepass_t		*onepass;
3162	pgpv_litdata_t		*litdata;
3163	unsigned		 sub;
3164	size_t			 pkt;
3165	obuf_t			 obuf;
3166	int			 j;
3167
3168	if (cursor == NULL || pgp == NULL || p == NULL) {
3169		return 0;
3170	}
3171	if (!setup_data(cursor, pgp, p, size)) {
3172		snprintf(cursor->why, sizeof(cursor->why), "No input data");
3173		return 0;
3174	}
3175	if (ARRAY_COUNT(cursor->pgp->pkts) == ARRAY_LAST(cursor->pgp->datastarts) + 1) {
3176		/* got detached signature here */
3177		if (!fixup_detached(cursor, p)) {
3178			snprintf(cursor->why, sizeof(cursor->why), "Can't read signed file '%s'", (const char *)p);
3179			return 0;
3180		}
3181	}
3182	if ((pkt = find_onepass(cursor, ARRAY_LAST(cursor->pgp->datastarts))) == 0) {
3183		snprintf(cursor->why, sizeof(cursor->why), "No signature found");
3184		return 0;
3185	}
3186	pkt -= 1;
3187	onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt).u.onepass;
3188	litdata = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt + 1).u.litdata;
3189	signature = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt + 2).u.sigpkt.sig;
3190	/* sanity check values in signature and onepass agree */
3191	if (signature->birth == 0) {
3192		if (!fmt_time(&obuf, "Signature creation time [",
3193				signature->birth, "] out of range", 0)) {
3194		}
3195		snprintf(cursor->why, sizeof(cursor->why), "%.*s", (int)obuf.c, (char *)obuf.v);
3196		return 0;
3197	}
3198	memset(&obuf, 0x0, sizeof(obuf));
3199	if (memcmp(onepass->keyid, signature->signer, PGPV_KEYID_LEN) != 0) {
3200		if (!fmt_binary(&obuf, onepass->keyid, (unsigned)sizeof(onepass->keyid))) {
3201			snprintf(cursor->why, sizeof(cursor->why), "Memory allocation failure");
3202			return 0;
3203		}
3204		snprintf(cursor->why, sizeof(cursor->why),
3205			"Signature key id %.*s does not match onepass keyid",
3206			(int)obuf.c, (char *)obuf.v);
3207		return 0;
3208	}
3209	if (onepass->hashalg != signature->hashalg) {
3210		snprintf(cursor->why, sizeof(cursor->why),
3211			"Signature hashalg %u does not match onepass hashalg %u",
3212			signature->hashalg, onepass->hashalg);
3213		return 0;
3214	}
3215	if (onepass->keyalg != signature->keyalg) {
3216		snprintf(cursor->why, sizeof(cursor->why),
3217			"Signature keyalg %u does not match onepass keyalg %u",
3218			signature->keyalg, onepass->keyalg);
3219		return 0;
3220	}
3221	if (cursor->pgp->ssh) {
3222		fixup_ssh_keyid(cursor->pgp, signature, "sha1");
3223	}
3224	sub = 0;
3225	if ((j = find_keyid(cursor->pgp, NULL, onepass->keyid, &sub)) < 0) {
3226		if (!fmt_binary(&obuf, onepass->keyid, (unsigned)sizeof(onepass->keyid))) {
3227			snprintf(cursor->why, sizeof(cursor->why), "Memory allocation failure");
3228			return 0;
3229		}
3230		snprintf(cursor->why, sizeof(cursor->why),
3231			"Signature key id %.*s not found ",
3232			(int)obuf.c, (char *)obuf.v);
3233		return 0;
3234	}
3235	if (!match_sig_id(cursor, pgp, signature, litdata, (unsigned)j, sub)) {
3236		return 0;
3237	}
3238	ARRAY_APPEND(cursor->datacookies, pkt);
3239	j = ((j & 0xffffff) << 8) | (sub & 0xff);
3240	ARRAY_APPEND(cursor->found, j);
3241	return pkt + 1;
3242}
3243
3244/* set up the pubkey keyring */
3245int
3246pgpv_read_pubring(pgpv_t *pgp, const void *keyring, ssize_t size)
3247{
3248	if (pgp == NULL) {
3249		return 0;
3250	}
3251	if (keyring) {
3252		return (size > 0) ?
3253			read_binary_memory(pgp, "pubring", keyring, (size_t)size) :
3254			read_binary_file(pgp, "pubring", "%s", (const char *)keyring);
3255	}
3256	return read_binary_file(pgp, "pubring", "%s/%s", nonnull_getenv("HOME"), ".gnupg/pubring.gpg");
3257}
3258
3259/* set up the pubkey keyring from ssh pub key */
3260int
3261pgpv_read_ssh_pubkeys(pgpv_t *pgp, const void *keyring, ssize_t size)
3262{
3263	pgpv_primarykey_t	primary;
3264
3265	USE_ARG(size);
3266	if (pgp == NULL) {
3267		return 0;
3268	}
3269	if (keyring) {
3270		if (!read_ssh_file(pgp, &primary, "%s", (const char *)keyring)) {
3271			return 0;
3272		}
3273	} else if (!read_ssh_file(pgp, &primary, "%s/%s", nonnull_getenv("HOME"), ".ssh/id_rsa.pub")) {
3274		return 0;
3275	}
3276	ARRAY_APPEND(pgp->primaries, primary);
3277	pgp->ssh = 1;
3278	return 1;
3279}
3280
3281/* get verified data as a string, return its size */
3282size_t
3283pgpv_get_verified(pgpv_cursor_t *cursor, size_t cookie, char **ret)
3284{
3285	pgpv_litdata_t		*litdata;
3286	uint8_t			*data;
3287	size_t			 size;
3288	size_t			 pkt;
3289
3290	if (ret == NULL || cursor == NULL || cookie == 0) {
3291		return 0;
3292	}
3293	*ret = NULL;
3294	if ((pkt = find_onepass(cursor, cookie - 1)) == 0) {
3295		return 0;
3296	}
3297	litdata = &ARRAY_ELEMENT(cursor->pgp->pkts, pkt).u.litdata;
3298	data = get_literal_data(cursor, litdata, &size);
3299	if ((*ret = calloc(1, size)) == NULL) {
3300		return 0;
3301	}
3302	memcpy(*ret, data, size);
3303	return size;
3304}
3305
3306#define KB(x)	((x) * 1024)
3307
3308/* dump all packets */
3309size_t
3310pgpv_dump(pgpv_t *pgp, char **data)
3311{
3312	ssize_t	 dumpc;
3313	size_t	 alloc;
3314	size_t	 pkt;
3315	size_t	 cc;
3316	size_t	 n;
3317	char	 buf[800];
3318	char	*newdata;
3319
3320	cc = alloc = 0;
3321	*data = NULL;
3322	for (pkt = 0 ; pkt < ARRAY_COUNT(pgp->pkts) ; pkt++) {
3323		if (cc + KB(64) >= alloc) {
3324			if ((newdata = realloc(*data, alloc + KB(64))) == NULL) {
3325				return cc;
3326			}
3327			alloc += KB(64);
3328			*data = newdata;
3329		}
3330		memset(buf, 0x0, sizeof(buf));
3331		dumpc = netpgp_hexdump(ARRAY_ELEMENT(pgp->pkts, pkt).s.data,
3332				MIN((sizeof(buf) / 80) * 16,
3333				ARRAY_ELEMENT(pgp->pkts, pkt).s.size),
3334				buf, sizeof(buf));
3335		n = snprintf(&(*data)[cc], alloc - cc,
3336			"[%zu] off %zu, len %zu, tag %u, %s\n%.*s",
3337			pkt,
3338			ARRAY_ELEMENT(pgp->pkts, pkt).offset,
3339			ARRAY_ELEMENT(pgp->pkts, pkt).s.size,
3340			ARRAY_ELEMENT(pgp->pkts, pkt).tag,
3341			get_packet_type(ARRAY_ELEMENT(pgp->pkts, pkt).tag),
3342			(int)dumpc, buf);
3343		cc += n;
3344	}
3345	return cc;
3346}
3347
3348/* return cursor field as a number */
3349int64_t
3350pgpv_get_cursor_num(pgpv_cursor_t *cursor, const char *field)
3351{
3352	if (cursor && field) {
3353		if (strcmp(field, "sigtime") == 0) {
3354			return cursor->sigtime;
3355		}
3356	}
3357	return 0;
3358}
3359
3360/* return cursor field as a string */
3361char *
3362pgpv_get_cursor_str(pgpv_cursor_t *cursor, const char *field)
3363{
3364	if (cursor && field) {
3365		if (strcmp(field, "why") == 0) {
3366			return cursor->why;
3367		}
3368	}
3369	return 0;
3370}
3371