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