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