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