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