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