1 /*
2 * Copyright (c) 2018-2020, [Ribose Inc](https://www.ribose.com).
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28 #include <sys/stat.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #else
34 #include "uniwin.h"
35 #endif
36 #include <string.h>
37 #include "time-utils.h"
38 #include "stream-def.h"
39 #include "stream-dump.h"
40 #include "stream-armor.h"
41 #include "stream-packet.h"
42 #include "stream-parse.h"
43 #include "types.h"
44 #include "ctype.h"
45 #include "crypto/symmetric.h"
46 #include "crypto/s2k.h"
47 #include "fingerprint.h"
48 #include "pgp-key.h"
49 #include "crypto.h"
50 #include "json-utils.h"
51 #include <algorithm>
52
53 static const id_str_pair packet_tag_map[] = {
54 {PGP_PKT_RESERVED, "Reserved"},
55 {PGP_PKT_PK_SESSION_KEY, "Public-Key Encrypted Session Key"},
56 {PGP_PKT_SIGNATURE, "Signature"},
57 {PGP_PKT_SK_SESSION_KEY, "Symmetric-Key Encrypted Session Key"},
58 {PGP_PKT_ONE_PASS_SIG, "One-Pass Signature"},
59 {PGP_PKT_SECRET_KEY, "Secret Key"},
60 {PGP_PKT_PUBLIC_KEY, "Public Key"},
61 {PGP_PKT_SECRET_SUBKEY, "Secret Subkey"},
62 {PGP_PKT_COMPRESSED, "Compressed Data"},
63 {PGP_PKT_SE_DATA, "Symmetrically Encrypted Data"},
64 {PGP_PKT_MARKER, "Marker"},
65 {PGP_PKT_LITDATA, "Literal Data"},
66 {PGP_PKT_TRUST, "Trust"},
67 {PGP_PKT_USER_ID, "User ID"},
68 {PGP_PKT_PUBLIC_SUBKEY, "Public Subkey"},
69 {PGP_PKT_RESERVED2, "reserved2"},
70 {PGP_PKT_RESERVED3, "reserved3"},
71 {PGP_PKT_USER_ATTR, "User Attribute"},
72 {PGP_PKT_SE_IP_DATA, "Symmetric Encrypted and Integrity Protected Data"},
73 {PGP_PKT_MDC, "Modification Detection Code"},
74 {PGP_PKT_AEAD_ENCRYPTED, "AEAD Encrypted Data Packet"},
75 {0x00, NULL},
76 };
77
78 static const id_str_pair sig_type_map[] = {
79 {PGP_SIG_BINARY, "Signature of a binary document"},
80 {PGP_SIG_TEXT, "Signature of a canonical text document"},
81 {PGP_SIG_STANDALONE, "Standalone signature"},
82 {PGP_CERT_GENERIC, "Generic User ID certification"},
83 {PGP_CERT_PERSONA, "Personal User ID certification"},
84 {PGP_CERT_CASUAL, "Casual User ID certification"},
85 {PGP_CERT_POSITIVE, "Positive User ID certification"},
86 {PGP_SIG_SUBKEY, "Subkey Binding Signature"},
87 {PGP_SIG_PRIMARY, "Primary Key Binding Signature"},
88 {PGP_SIG_DIRECT, "Direct-key signature"},
89 {PGP_SIG_REV_KEY, "Key revocation signature"},
90 {PGP_SIG_REV_SUBKEY, "Subkey revocation signature"},
91 {PGP_SIG_REV_CERT, "Certification revocation signature"},
92 {PGP_SIG_TIMESTAMP, "Timestamp signature"},
93 {PGP_SIG_3RD_PARTY, "Third-Party Confirmation signature"},
94 {0x00, NULL},
95 };
96
97 static const id_str_pair sig_subpkt_type_map[] = {
98 {PGP_SIG_SUBPKT_CREATION_TIME, "signature creation time"},
99 {PGP_SIG_SUBPKT_EXPIRATION_TIME, "signature expiration time"},
100 {PGP_SIG_SUBPKT_EXPORT_CERT, "exportable certification"},
101 {PGP_SIG_SUBPKT_TRUST, "trust signature"},
102 {PGP_SIG_SUBPKT_REGEXP, "regular expression"},
103 {PGP_SIG_SUBPKT_REVOCABLE, "revocable"},
104 {PGP_SIG_SUBPKT_KEY_EXPIRY, "key expiration time"},
105 {PGP_SIG_SUBPKT_PREFERRED_SKA, "preferred symmetric algorithms"},
106 {PGP_SIG_SUBPKT_REVOCATION_KEY, "revocation key"},
107 {PGP_SIG_SUBPKT_ISSUER_KEY_ID, "issuer key ID"},
108 {PGP_SIG_SUBPKT_NOTATION_DATA, "notation data"},
109 {PGP_SIG_SUBPKT_PREFERRED_HASH, "preferred hash algorithms"},
110 {PGP_SIG_SUBPKT_PREF_COMPRESS, "preferred compression algorithms"},
111 {PGP_SIG_SUBPKT_KEYSERV_PREFS, "key server preferences"},
112 {PGP_SIG_SUBPKT_PREF_KEYSERV, "preferred key server"},
113 {PGP_SIG_SUBPKT_PRIMARY_USER_ID, "primary user ID"},
114 {PGP_SIG_SUBPKT_POLICY_URI, "policy URI"},
115 {PGP_SIG_SUBPKT_KEY_FLAGS, "key flags"},
116 {PGP_SIG_SUBPKT_SIGNERS_USER_ID, "signer's user ID"},
117 {PGP_SIG_SUBPKT_REVOCATION_REASON, "reason for revocation"},
118 {PGP_SIG_SUBPKT_FEATURES, "features"},
119 {PGP_SIG_SUBPKT_SIGNATURE_TARGET, "signature target"},
120 {PGP_SIG_SUBPKT_EMBEDDED_SIGNATURE, "embedded signature"},
121 {PGP_SIG_SUBPKT_ISSUER_FPR, "issuer fingerprint"},
122 {PGP_SIG_SUBPKT_PREFERRED_AEAD, "preferred AEAD algorithms"},
123 {0x00, NULL},
124 };
125
126 static const id_str_pair key_type_map[] = {
127 {PGP_PKT_SECRET_KEY, "Secret key"},
128 {PGP_PKT_PUBLIC_KEY, "Public key"},
129 {PGP_PKT_SECRET_SUBKEY, "Secret subkey"},
130 {PGP_PKT_PUBLIC_SUBKEY, "Public subkey"},
131 {0x00, NULL},
132 };
133
134 static const id_str_pair pubkey_alg_map[] = {
135 {PGP_PKA_RSA, "RSA (Encrypt or Sign)"},
136 {PGP_PKA_RSA_ENCRYPT_ONLY, "RSA (Encrypt-Only)"},
137 {PGP_PKA_RSA_SIGN_ONLY, "RSA (Sign-Only)"},
138 {PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"},
139 {PGP_PKA_DSA, "DSA"},
140 {PGP_PKA_ECDH, "ECDH"},
141 {PGP_PKA_ECDSA, "ECDSA"},
142 {PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Elgamal"},
143 {PGP_PKA_RESERVED_DH, "Reserved for DH (X9.42)"},
144 {PGP_PKA_EDDSA, "EdDSA"},
145 {PGP_PKA_SM2, "SM2"},
146 {0x00, NULL},
147 };
148
149 static const id_str_pair symm_alg_map[] = {
150 {PGP_SA_PLAINTEXT, "Plaintext"},
151 {PGP_SA_IDEA, "IDEA"},
152 {PGP_SA_TRIPLEDES, "TripleDES"},
153 {PGP_SA_CAST5, "CAST5"},
154 {PGP_SA_BLOWFISH, "Blowfish"},
155 {PGP_SA_AES_128, "AES-128"},
156 {PGP_SA_AES_192, "AES-192"},
157 {PGP_SA_AES_256, "AES-256"},
158 {PGP_SA_TWOFISH, "Twofish"},
159 {PGP_SA_CAMELLIA_128, "Camellia-128"},
160 {PGP_SA_CAMELLIA_192, "Camellia-192"},
161 {PGP_SA_CAMELLIA_256, "Camellia-256"},
162 {PGP_SA_SM4, "SM4"},
163 {0x00, NULL},
164 };
165
166 static const id_str_pair hash_alg_map[] = {
167 {PGP_HASH_MD5, "MD5"},
168 {PGP_HASH_SHA1, "SHA1"},
169 {PGP_HASH_RIPEMD, "RIPEMD160"},
170 {PGP_HASH_SHA256, "SHA256"},
171 {PGP_HASH_SHA384, "SHA384"},
172 {PGP_HASH_SHA512, "SHA512"},
173 {PGP_HASH_SHA224, "SHA224"},
174 {PGP_HASH_SM3, "SM3"},
175 {PGP_HASH_SHA3_256, "SHA3-256"},
176 {PGP_HASH_SHA3_512, "SHA3-512"},
177 {0x00, NULL},
178 };
179
180 static const id_str_pair z_alg_map[] = {
181 {PGP_C_NONE, "Uncompressed"},
182 {PGP_C_ZIP, "ZIP"},
183 {PGP_C_ZLIB, "ZLib"},
184 {PGP_C_BZIP2, "BZip2"},
185 {0x00, NULL},
186 };
187
188 static const id_str_pair aead_alg_map[] = {
189 {PGP_AEAD_NONE, "None"},
190 {PGP_AEAD_EAX, "EAX"},
191 {PGP_AEAD_OCB, "OCB"},
192 {0x00, NULL},
193 };
194
195 static const id_str_pair revoc_reason_map[] = {
196 {PGP_REVOCATION_NO_REASON, "No reason"},
197 {PGP_REVOCATION_SUPERSEDED, "Superseded"},
198 {PGP_REVOCATION_COMPROMISED, "Compromised"},
199 {PGP_REVOCATION_RETIRED, "Retired"},
200 {PGP_REVOCATION_NO_LONGER_VALID, "No longer valid"},
201 {0x00, NULL},
202 };
203
204 typedef struct pgp_dest_indent_param_t {
205 int level;
206 bool lstart;
207 pgp_dest_t *writedst;
208 } pgp_dest_indent_param_t;
209
210 static rnp_result_t
indent_dst_write(pgp_dest_t * dst,const void * buf,size_t len)211 indent_dst_write(pgp_dest_t *dst, const void *buf, size_t len)
212 {
213 pgp_dest_indent_param_t *param = (pgp_dest_indent_param_t *) dst->param;
214 const char * line = (const char *) buf;
215 char indent[4] = {' ', ' ', ' ', ' '};
216
217 if (!len) {
218 return RNP_SUCCESS;
219 }
220
221 do {
222 if (param->lstart) {
223 for (int i = 0; i < param->level; i++) {
224 dst_write(param->writedst, indent, sizeof(indent));
225 }
226 param->lstart = false;
227 }
228
229 for (size_t i = 0; i < len; i++) {
230 if ((line[i] == '\n') || (i == len - 1)) {
231 dst_write(param->writedst, line, i + 1);
232 param->lstart = line[i] == '\n';
233 line += i + 1;
234 len -= i + 1;
235 break;
236 }
237 }
238 } while (len > 0);
239
240 return RNP_SUCCESS;
241 }
242
243 static void
indent_dst_close(pgp_dest_t * dst,bool discard)244 indent_dst_close(pgp_dest_t *dst, bool discard)
245 {
246 pgp_dest_indent_param_t *param = (pgp_dest_indent_param_t *) dst->param;
247 if (!param) {
248 return;
249 }
250
251 free(param);
252 }
253
254 static rnp_result_t
init_indent_dest(pgp_dest_t * dst,pgp_dest_t * origdst)255 init_indent_dest(pgp_dest_t *dst, pgp_dest_t *origdst)
256 {
257 pgp_dest_indent_param_t *param;
258
259 if (!init_dst_common(dst, sizeof(*param))) {
260 return RNP_ERROR_OUT_OF_MEMORY;
261 }
262
263 dst->write = indent_dst_write;
264 dst->close = indent_dst_close;
265 dst->finish = NULL;
266 dst->no_cache = true;
267 param = (pgp_dest_indent_param_t *) dst->param;
268 param->writedst = origdst;
269 param->lstart = true;
270
271 return RNP_SUCCESS;
272 }
273
274 static void
indent_dest_increase(pgp_dest_t * dst)275 indent_dest_increase(pgp_dest_t *dst)
276 {
277 pgp_dest_indent_param_t *param = (pgp_dest_indent_param_t *) dst->param;
278 param->level++;
279 }
280
281 static void
indent_dest_decrease(pgp_dest_t * dst)282 indent_dest_decrease(pgp_dest_t *dst)
283 {
284 pgp_dest_indent_param_t *param = (pgp_dest_indent_param_t *) dst->param;
285 if (param->level > 0) {
286 param->level--;
287 }
288 }
289
290 static void
indent_dest_set(pgp_dest_t * dst,int level)291 indent_dest_set(pgp_dest_t *dst, int level)
292 {
293 pgp_dest_indent_param_t *param = (pgp_dest_indent_param_t *) dst->param;
294 param->level = level;
295 }
296
297 static size_t
vsnprinthex(char * str,size_t slen,const uint8_t * buf,size_t buflen)298 vsnprinthex(char *str, size_t slen, const uint8_t *buf, size_t buflen)
299 {
300 static const char *hexes = "0123456789abcdef";
301 size_t idx = 0;
302
303 for (size_t i = 0; (i < buflen) && (i < (slen - 1) / 2); i++) {
304 str[idx++] = hexes[buf[i] >> 4];
305 str[idx++] = hexes[buf[i] & 0xf];
306 }
307 str[idx] = '\0';
308 return buflen * 2;
309 }
310
311 static void
dst_print_mpi(pgp_dest_t * dst,const char * name,pgp_mpi_t * mpi,bool dumpbin)312 dst_print_mpi(pgp_dest_t *dst, const char *name, pgp_mpi_t *mpi, bool dumpbin)
313 {
314 char hex[5000];
315 if (!dumpbin) {
316 dst_printf(dst, "%s: %d bits\n", name, (int) mpi_bits(mpi));
317 } else {
318 vsnprinthex(hex, sizeof(hex), mpi->mpi, mpi->len);
319 dst_printf(dst, "%s: %d bits, %s\n", name, (int) mpi_bits(mpi), hex);
320 }
321 }
322
323 static void
dst_print_palg(pgp_dest_t * dst,const char * name,pgp_pubkey_alg_t palg)324 dst_print_palg(pgp_dest_t *dst, const char *name, pgp_pubkey_alg_t palg)
325 {
326 const char *palg_name = id_str_pair::lookup(pubkey_alg_map, palg, "Unknown");
327 if (!name) {
328 name = "public key algorithm";
329 }
330
331 dst_printf(dst, "%s: %d (%s)\n", name, (int) palg, palg_name);
332 }
333
334 static void
dst_print_halg(pgp_dest_t * dst,const char * name,pgp_hash_alg_t halg)335 dst_print_halg(pgp_dest_t *dst, const char *name, pgp_hash_alg_t halg)
336 {
337 const char *halg_name = id_str_pair::lookup(hash_alg_map, halg, "Unknown");
338 if (!name) {
339 name = "hash algorithm";
340 }
341
342 dst_printf(dst, "%s: %d (%s)\n", name, (int) halg, halg_name);
343 }
344
345 static void
dst_print_salg(pgp_dest_t * dst,const char * name,pgp_symm_alg_t salg)346 dst_print_salg(pgp_dest_t *dst, const char *name, pgp_symm_alg_t salg)
347 {
348 const char *salg_name = id_str_pair::lookup(symm_alg_map, salg, "Unknown");
349 if (!name) {
350 name = "symmetric algorithm";
351 }
352
353 dst_printf(dst, "%s: %d (%s)\n", name, (int) salg, salg_name);
354 }
355
356 static void
dst_print_aalg(pgp_dest_t * dst,const char * name,pgp_aead_alg_t aalg)357 dst_print_aalg(pgp_dest_t *dst, const char *name, pgp_aead_alg_t aalg)
358 {
359 const char *aalg_name = id_str_pair::lookup(aead_alg_map, aalg, "Unknown");
360 if (!name) {
361 name = "aead algorithm";
362 }
363
364 dst_printf(dst, "%s: %d (%s)\n", name, (int) aalg, aalg_name);
365 }
366
367 static void
dst_print_zalg(pgp_dest_t * dst,const char * name,pgp_compression_type_t zalg)368 dst_print_zalg(pgp_dest_t *dst, const char *name, pgp_compression_type_t zalg)
369 {
370 const char *zalg_name = id_str_pair::lookup(z_alg_map, zalg, "Unknown");
371 if (!name) {
372 name = "compression algorithm";
373 }
374
375 dst_printf(dst, "%s: %d (%s)\n", name, (int) zalg, zalg_name);
376 }
377
378 static void
dst_print_raw(pgp_dest_t * dst,const char * name,const void * data,size_t len)379 dst_print_raw(pgp_dest_t *dst, const char *name, const void *data, size_t len)
380 {
381 dst_printf(dst, "%s: ", name);
382 dst_write(dst, data, len);
383 dst_printf(dst, "\n");
384 }
385
386 static void
dst_print_algs(pgp_dest_t * dst,const char * name,uint8_t * algs,size_t algc,const id_str_pair map[])387 dst_print_algs(
388 pgp_dest_t *dst, const char *name, uint8_t *algs, size_t algc, const id_str_pair map[])
389 {
390 if (!name) {
391 name = "algorithms";
392 }
393
394 dst_printf(dst, "%s: ", name);
395 for (size_t i = 0; i < algc; i++) {
396 dst_printf(
397 dst, "%s%s", id_str_pair::lookup(map, algs[i], "Unknown"), i + 1 < algc ? ", " : "");
398 }
399 dst_printf(dst, " (");
400 for (size_t i = 0; i < algc; i++) {
401 dst_printf(dst, "%d%s", (int) algs[i], i + 1 < algc ? ", " : "");
402 }
403 dst_printf(dst, ")\n");
404 }
405
406 static void
dst_print_sig_type(pgp_dest_t * dst,const char * name,pgp_sig_type_t sigtype)407 dst_print_sig_type(pgp_dest_t *dst, const char *name, pgp_sig_type_t sigtype)
408 {
409 const char *sig_name = id_str_pair::lookup(sig_type_map, sigtype, "Unknown");
410 if (!name) {
411 name = "signature type";
412 }
413 dst_printf(dst, "%s: %d (%s)\n", name, (int) sigtype, sig_name);
414 }
415
416 static void
dst_print_hex(pgp_dest_t * dst,const char * name,const uint8_t * data,size_t len,bool bytes)417 dst_print_hex(pgp_dest_t *dst, const char *name, const uint8_t *data, size_t len, bool bytes)
418 {
419 char hex[512];
420 vsnprinthex(hex, sizeof(hex), data, len);
421 if (bytes) {
422 dst_printf(dst, "%s: 0x%s (%d bytes)\n", name, hex, (int) len);
423 } else {
424 dst_printf(dst, "%s: 0x%s\n", name, hex);
425 }
426 }
427
428 static void
dst_print_keyid(pgp_dest_t * dst,const char * name,const pgp_key_id_t & keyid)429 dst_print_keyid(pgp_dest_t *dst, const char *name, const pgp_key_id_t &keyid)
430 {
431 if (!name) {
432 name = "key id";
433 }
434 dst_print_hex(dst, name, keyid.data(), keyid.size(), false);
435 }
436
437 static void
dst_print_s2k(pgp_dest_t * dst,pgp_s2k_t * s2k)438 dst_print_s2k(pgp_dest_t *dst, pgp_s2k_t *s2k)
439 {
440 dst_printf(dst, "s2k specifier: %d\n", (int) s2k->specifier);
441 if ((s2k->specifier == PGP_S2KS_EXPERIMENTAL) && s2k->gpg_ext_num) {
442 dst_printf(dst, "GPG extension num: %d\n", (int) s2k->gpg_ext_num);
443 if (s2k->gpg_ext_num == PGP_S2K_GPG_SMARTCARD) {
444 static_assert(sizeof(s2k->gpg_serial) == 16, "invalid s2k->gpg_serial size");
445 size_t slen = s2k->gpg_serial_len > 16 ? 16 : s2k->gpg_serial_len;
446 dst_print_hex(dst, "card serial number", s2k->gpg_serial, slen, true);
447 }
448 return;
449 }
450 if (s2k->specifier == PGP_S2KS_EXPERIMENTAL) {
451 dst_print_hex(dst,
452 "Unknown experimental s2k",
453 s2k->experimental.data(),
454 s2k->experimental.size(),
455 true);
456 return;
457 }
458 dst_print_halg(dst, "s2k hash algorithm", s2k->hash_alg);
459 if ((s2k->specifier == PGP_S2KS_SALTED) ||
460 (s2k->specifier == PGP_S2KS_ITERATED_AND_SALTED)) {
461 dst_print_hex(dst, "s2k salt", s2k->salt, PGP_SALT_SIZE, false);
462 }
463 if (s2k->specifier == PGP_S2KS_ITERATED_AND_SALTED) {
464 size_t real_iter = pgp_s2k_decode_iterations(s2k->iterations);
465 dst_printf(dst, "s2k iterations: %zu (encoded as %u)\n", real_iter, s2k->iterations);
466 }
467 }
468
469 static void
dst_print_time(pgp_dest_t * dst,const char * name,uint32_t time)470 dst_print_time(pgp_dest_t *dst, const char *name, uint32_t time)
471 {
472 char buf[26] = {0};
473 if (!name) {
474 name = "time";
475 }
476 strncpy(buf, rnp_ctime(time), sizeof(buf));
477 buf[24] = '\0';
478 dst_printf(
479 dst, "%s: %zu (%s%s)\n", name, (size_t) time, rnp_y2k38_warning(time) ? ">=" : "", buf);
480 }
481
482 static void
dst_print_expiration(pgp_dest_t * dst,const char * name,uint32_t seconds)483 dst_print_expiration(pgp_dest_t *dst, const char *name, uint32_t seconds)
484 {
485 if (!name) {
486 name = "expiration";
487 }
488 if (seconds) {
489 int days = seconds / (24 * 60 * 60);
490 dst_printf(dst, "%s: %zu seconds (%d days)\n", name, (size_t) seconds, days);
491 } else {
492 dst_printf(dst, "%s: 0 (never)\n", name);
493 }
494 }
495
496 #define LINELEN 16
497
498 static void
dst_hexdump(pgp_dest_t * dst,const uint8_t * src,size_t length)499 dst_hexdump(pgp_dest_t *dst, const uint8_t *src, size_t length)
500 {
501 size_t i;
502 char line[LINELEN + 1];
503
504 for (i = 0; i < length; i++) {
505 if (i % LINELEN == 0) {
506 dst_printf(dst, "%.5zu | ", i);
507 }
508 dst_printf(dst, "%.02x ", (uint8_t) src[i]);
509 line[i % LINELEN] = (isprint(src[i])) ? src[i] : '.';
510 if (i % LINELEN == LINELEN - 1) {
511 line[LINELEN] = 0x0;
512 dst_printf(dst, " | %s\n", line);
513 }
514 }
515 if (i % LINELEN != 0) {
516 for (; i % LINELEN != 0; i++) {
517 dst_printf(dst, " ");
518 line[i % LINELEN] = ' ';
519 }
520 line[LINELEN] = 0x0;
521 dst_printf(dst, " | %s\n", line);
522 }
523 }
524
525 static rnp_result_t stream_dump_packets_raw(rnp_dump_ctx_t *ctx,
526 pgp_source_t * src,
527 pgp_dest_t * dst);
528 static void stream_dump_signature_pkt(rnp_dump_ctx_t * ctx,
529 pgp_signature_t *sig,
530 pgp_dest_t * dst);
531
532 static void
signature_dump_subpacket(rnp_dump_ctx_t * ctx,pgp_dest_t * dst,const pgp_sig_subpkt_t & subpkt)533 signature_dump_subpacket(rnp_dump_ctx_t *ctx, pgp_dest_t *dst, const pgp_sig_subpkt_t &subpkt)
534 {
535 const char *sname = id_str_pair::lookup(sig_subpkt_type_map, subpkt.type, "Unknown");
536
537 switch (subpkt.type) {
538 case PGP_SIG_SUBPKT_CREATION_TIME:
539 dst_print_time(dst, sname, subpkt.fields.create);
540 break;
541 case PGP_SIG_SUBPKT_EXPIRATION_TIME:
542 dst_print_expiration(dst, sname, subpkt.fields.expiry);
543 break;
544 case PGP_SIG_SUBPKT_EXPORT_CERT:
545 dst_printf(dst, "%s: %d\n", sname, (int) subpkt.fields.exportable);
546 break;
547 case PGP_SIG_SUBPKT_TRUST:
548 dst_printf(dst,
549 "%s: amount %d, level %d\n",
550 sname,
551 (int) subpkt.fields.trust.amount,
552 (int) subpkt.fields.trust.level);
553 break;
554 case PGP_SIG_SUBPKT_REGEXP:
555 dst_print_raw(dst, sname, subpkt.fields.regexp.str, subpkt.fields.regexp.len);
556 break;
557 case PGP_SIG_SUBPKT_REVOCABLE:
558 dst_printf(dst, "%s: %d\n", sname, (int) subpkt.fields.revocable);
559 break;
560 case PGP_SIG_SUBPKT_KEY_EXPIRY:
561 dst_print_expiration(dst, sname, subpkt.fields.expiry);
562 break;
563 case PGP_SIG_SUBPKT_PREFERRED_SKA:
564 dst_print_algs(dst,
565 "preferred symmetric algorithms",
566 subpkt.fields.preferred.arr,
567 subpkt.fields.preferred.len,
568 symm_alg_map);
569 break;
570 case PGP_SIG_SUBPKT_REVOCATION_KEY:
571 dst_printf(dst, "%s\n", sname);
572 dst_printf(dst, "class: %d\n", (int) subpkt.fields.revocation_key.klass);
573 dst_print_palg(dst, NULL, subpkt.fields.revocation_key.pkalg);
574 dst_print_hex(
575 dst, "fingerprint", subpkt.fields.revocation_key.fp, PGP_FINGERPRINT_SIZE, true);
576 break;
577 case PGP_SIG_SUBPKT_ISSUER_KEY_ID:
578 dst_print_hex(dst, sname, subpkt.fields.issuer, PGP_KEY_ID_SIZE, false);
579 break;
580 case PGP_SIG_SUBPKT_NOTATION_DATA: {
581 std::string name(subpkt.fields.notation.name,
582 subpkt.fields.notation.name + subpkt.fields.notation.nlen);
583 std::vector<uint8_t> value(subpkt.fields.notation.value,
584 subpkt.fields.notation.value + subpkt.fields.notation.vlen);
585 if (subpkt.fields.notation.human) {
586 dst_printf(dst, "%s: %s = ", sname, name.c_str());
587 dst_printf(dst, "%.*s\n", (int) value.size(), (char *) value.data());
588 } else {
589 char hex[64];
590 vsnprinthex(hex, sizeof(hex), value.data(), value.size());
591 dst_printf(dst, "%s: %s = ", sname, name.c_str());
592 dst_printf(dst, "0x%s (%zu bytes)\n", hex, value.size());
593 }
594 break;
595 }
596 case PGP_SIG_SUBPKT_PREFERRED_HASH:
597 dst_print_algs(dst,
598 "preferred hash algorithms",
599 subpkt.fields.preferred.arr,
600 subpkt.fields.preferred.len,
601 hash_alg_map);
602 break;
603 case PGP_SIG_SUBPKT_PREF_COMPRESS:
604 dst_print_algs(dst,
605 "preferred compression algorithms",
606 subpkt.fields.preferred.arr,
607 subpkt.fields.preferred.len,
608 z_alg_map);
609 break;
610 case PGP_SIG_SUBPKT_KEYSERV_PREFS:
611 dst_printf(dst, "%s\n", sname);
612 dst_printf(dst, "no-modify: %d\n", (int) subpkt.fields.ks_prefs.no_modify);
613 break;
614 case PGP_SIG_SUBPKT_PREF_KEYSERV:
615 dst_print_raw(
616 dst, sname, subpkt.fields.preferred_ks.uri, subpkt.fields.preferred_ks.len);
617 break;
618 case PGP_SIG_SUBPKT_PRIMARY_USER_ID:
619 dst_printf(dst, "%s: %d\n", sname, (int) subpkt.fields.primary_uid);
620 break;
621 case PGP_SIG_SUBPKT_POLICY_URI:
622 dst_print_raw(dst, sname, subpkt.fields.policy.uri, subpkt.fields.policy.len);
623 break;
624 case PGP_SIG_SUBPKT_KEY_FLAGS: {
625 uint8_t flg = subpkt.fields.key_flags;
626 dst_printf(dst, "%s: 0x%02x ( ", sname, flg);
627 dst_printf(dst, "%s", flg ? "" : "none");
628 dst_printf(dst, "%s", flg & PGP_KF_CERTIFY ? "certify " : "");
629 dst_printf(dst, "%s", flg & PGP_KF_SIGN ? "sign " : "");
630 dst_printf(dst, "%s", flg & PGP_KF_ENCRYPT_COMMS ? "encrypt_comm " : "");
631 dst_printf(dst, "%s", flg & PGP_KF_ENCRYPT_STORAGE ? "encrypt_storage " : "");
632 dst_printf(dst, "%s", flg & PGP_KF_SPLIT ? "split " : "");
633 dst_printf(dst, "%s", flg & PGP_KF_AUTH ? "auth " : "");
634 dst_printf(dst, "%s", flg & PGP_KF_SHARED ? "shared " : "");
635 dst_printf(dst, ")\n");
636 break;
637 }
638 case PGP_SIG_SUBPKT_SIGNERS_USER_ID:
639 dst_print_raw(dst, sname, subpkt.fields.signer.uid, subpkt.fields.signer.len);
640 break;
641 case PGP_SIG_SUBPKT_REVOCATION_REASON: {
642 int code = subpkt.fields.revocation_reason.code;
643 const char *reason = id_str_pair::lookup(revoc_reason_map, code, "Unknown");
644 dst_printf(dst, "%s: %d (%s)\n", sname, code, reason);
645 dst_print_raw(dst,
646 "message",
647 subpkt.fields.revocation_reason.str,
648 subpkt.fields.revocation_reason.len);
649 break;
650 }
651 case PGP_SIG_SUBPKT_FEATURES:
652 dst_printf(dst, "%s: 0x%02x ( ", sname, subpkt.data[0]);
653 dst_printf(dst, "%s", subpkt.fields.features & PGP_KEY_FEATURE_MDC ? "mdc " : "");
654 dst_printf(dst, "%s", subpkt.fields.features & PGP_KEY_FEATURE_AEAD ? "aead " : "");
655 dst_printf(dst, "%s", subpkt.fields.features & PGP_KEY_FEATURE_V5 ? "v5 keys " : "");
656 dst_printf(dst, ")\n");
657 break;
658 case PGP_SIG_SUBPKT_EMBEDDED_SIGNATURE:
659 dst_printf(dst, "%s:\n", sname);
660 stream_dump_signature_pkt(ctx, subpkt.fields.sig, dst);
661 break;
662 case PGP_SIG_SUBPKT_ISSUER_FPR:
663 dst_print_hex(
664 dst, sname, subpkt.fields.issuer_fp.fp, subpkt.fields.issuer_fp.len, true);
665 break;
666 case PGP_SIG_SUBPKT_PREFERRED_AEAD:
667 dst_print_algs(dst,
668 "preferred aead algorithms",
669 subpkt.fields.preferred.arr,
670 subpkt.fields.preferred.len,
671 aead_alg_map);
672 break;
673 default:
674 if (!ctx->dump_packets) {
675 indent_dest_increase(dst);
676 dst_hexdump(dst, subpkt.data, subpkt.len);
677 indent_dest_decrease(dst);
678 }
679 }
680 }
681
682 static void
signature_dump_subpackets(rnp_dump_ctx_t * ctx,pgp_dest_t * dst,pgp_signature_t * sig,bool hashed)683 signature_dump_subpackets(rnp_dump_ctx_t * ctx,
684 pgp_dest_t * dst,
685 pgp_signature_t *sig,
686 bool hashed)
687 {
688 bool empty = true;
689
690 for (auto &subpkt : sig->subpkts) {
691 if (subpkt.hashed != hashed) {
692 continue;
693 }
694 empty = false;
695 dst_printf(dst, ":type %d, len %d", (int) subpkt.type, (int) subpkt.len);
696 dst_printf(dst, "%s\n", subpkt.critical ? ", critical" : "");
697 if (ctx->dump_packets) {
698 dst_printf(dst, ":subpacket contents:\n");
699 indent_dest_increase(dst);
700 dst_hexdump(dst, subpkt.data, subpkt.len);
701 indent_dest_decrease(dst);
702 }
703 signature_dump_subpacket(ctx, dst, subpkt);
704 }
705
706 if (empty) {
707 dst_printf(dst, "none\n");
708 }
709 }
710
711 static void
stream_dump_signature_pkt(rnp_dump_ctx_t * ctx,pgp_signature_t * sig,pgp_dest_t * dst)712 stream_dump_signature_pkt(rnp_dump_ctx_t *ctx, pgp_signature_t *sig, pgp_dest_t *dst)
713 {
714 indent_dest_increase(dst);
715
716 dst_printf(dst, "version: %d\n", (int) sig->version);
717 dst_print_sig_type(dst, "type", sig->type());
718 if (sig->version < PGP_V4) {
719 dst_print_time(dst, "creation time", sig->creation_time);
720 dst_print_keyid(dst, "signing key id", sig->signer);
721 }
722 dst_print_palg(dst, NULL, sig->palg);
723 dst_print_halg(dst, NULL, sig->halg);
724
725 if (sig->version >= PGP_V4) {
726 dst_printf(dst, "hashed subpackets:\n");
727 indent_dest_increase(dst);
728 signature_dump_subpackets(ctx, dst, sig, true);
729 indent_dest_decrease(dst);
730
731 dst_printf(dst, "unhashed subpackets:\n");
732 indent_dest_increase(dst);
733 signature_dump_subpackets(ctx, dst, sig, false);
734 indent_dest_decrease(dst);
735 }
736
737 dst_print_hex(dst, "lbits", sig->lbits, sizeof(sig->lbits), false);
738 dst_printf(dst, "signature material:\n");
739 indent_dest_increase(dst);
740
741 pgp_signature_material_t material = {};
742 try {
743 sig->parse_material(material);
744 } catch (const std::exception &e) {
745 RNP_LOG("%s", e.what());
746 return;
747 }
748 switch (sig->palg) {
749 case PGP_PKA_RSA:
750 case PGP_PKA_RSA_ENCRYPT_ONLY:
751 case PGP_PKA_RSA_SIGN_ONLY:
752 dst_print_mpi(dst, "rsa s", &material.rsa.s, ctx->dump_mpi);
753 break;
754 case PGP_PKA_DSA:
755 dst_print_mpi(dst, "dsa r", &material.dsa.r, ctx->dump_mpi);
756 dst_print_mpi(dst, "dsa s", &material.dsa.s, ctx->dump_mpi);
757 break;
758 case PGP_PKA_EDDSA:
759 case PGP_PKA_ECDSA:
760 case PGP_PKA_SM2:
761 case PGP_PKA_ECDH:
762 dst_print_mpi(dst, "ecc r", &material.ecc.r, ctx->dump_mpi);
763 dst_print_mpi(dst, "ecc s", &material.ecc.s, ctx->dump_mpi);
764 break;
765 case PGP_PKA_ELGAMAL:
766 case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
767 dst_print_mpi(dst, "eg r", &material.eg.r, ctx->dump_mpi);
768 dst_print_mpi(dst, "eg s", &material.eg.s, ctx->dump_mpi);
769 break;
770 default:
771 dst_printf(dst, "unknown algorithm\n");
772 }
773 indent_dest_decrease(dst);
774 indent_dest_decrease(dst);
775 }
776
777 static void
stream_dump_signature(rnp_dump_ctx_t * ctx,pgp_source_t * src,pgp_dest_t * dst)778 stream_dump_signature(rnp_dump_ctx_t *ctx, pgp_source_t *src, pgp_dest_t *dst)
779 {
780 pgp_signature_t sig;
781 rnp_result_t ret;
782
783 dst_printf(dst, "Signature packet\n");
784 try {
785 ret = sig.parse(*src);
786 } catch (const std::exception &e) {
787 RNP_LOG("%s", e.what());
788 ret = RNP_ERROR_GENERIC;
789 }
790 if (ret) {
791 indent_dest_increase(dst);
792 dst_printf(dst, "failed to parse\n");
793 indent_dest_decrease(dst);
794 return;
795 }
796 stream_dump_signature_pkt(ctx, &sig, dst);
797 }
798
799 static rnp_result_t
stream_dump_key(rnp_dump_ctx_t * ctx,pgp_source_t * src,pgp_dest_t * dst)800 stream_dump_key(rnp_dump_ctx_t *ctx, pgp_source_t *src, pgp_dest_t *dst)
801 {
802 pgp_key_pkt_t key;
803 rnp_result_t ret;
804 pgp_fingerprint_t keyfp = {};
805
806 try {
807 ret = key.parse(*src);
808 } catch (const std::exception &e) {
809 RNP_LOG("%s", e.what());
810 ret = RNP_ERROR_GENERIC;
811 }
812 if (ret) {
813 return ret;
814 }
815
816 dst_printf(dst, "%s packet\n", id_str_pair::lookup(key_type_map, key.tag, "Unknown"));
817 indent_dest_increase(dst);
818
819 dst_printf(dst, "version: %d\n", (int) key.version);
820 dst_print_time(dst, "creation time", key.creation_time);
821 if (key.version < PGP_V4) {
822 dst_printf(dst, "v3 validity days: %d\n", (int) key.v3_days);
823 }
824 dst_print_palg(dst, NULL, key.alg);
825 dst_printf(dst, "public key material:\n");
826 indent_dest_increase(dst);
827
828 switch (key.alg) {
829 case PGP_PKA_RSA:
830 case PGP_PKA_RSA_ENCRYPT_ONLY:
831 case PGP_PKA_RSA_SIGN_ONLY:
832 dst_print_mpi(dst, "rsa n", &key.material.rsa.n, ctx->dump_mpi);
833 dst_print_mpi(dst, "rsa e", &key.material.rsa.e, ctx->dump_mpi);
834 break;
835 case PGP_PKA_DSA:
836 dst_print_mpi(dst, "dsa p", &key.material.dsa.p, ctx->dump_mpi);
837 dst_print_mpi(dst, "dsa q", &key.material.dsa.q, ctx->dump_mpi);
838 dst_print_mpi(dst, "dsa g", &key.material.dsa.g, ctx->dump_mpi);
839 dst_print_mpi(dst, "dsa y", &key.material.dsa.y, ctx->dump_mpi);
840 break;
841 case PGP_PKA_ELGAMAL:
842 case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
843 dst_print_mpi(dst, "eg p", &key.material.eg.p, ctx->dump_mpi);
844 dst_print_mpi(dst, "eg g", &key.material.eg.g, ctx->dump_mpi);
845 dst_print_mpi(dst, "eg y", &key.material.eg.y, ctx->dump_mpi);
846 break;
847 case PGP_PKA_ECDSA:
848 case PGP_PKA_EDDSA:
849 case PGP_PKA_SM2: {
850 const ec_curve_desc_t *cdesc = get_curve_desc(key.material.ec.curve);
851 dst_print_mpi(dst, "ecc p", &key.material.ec.p, ctx->dump_mpi);
852 dst_printf(dst, "ecc curve: %s\n", cdesc ? cdesc->pgp_name : "unknown");
853 break;
854 }
855 case PGP_PKA_ECDH: {
856 const ec_curve_desc_t *cdesc = get_curve_desc(key.material.ec.curve);
857 dst_print_mpi(dst, "ecdh p", &key.material.ec.p, ctx->dump_mpi);
858 dst_printf(dst, "ecdh curve: %s\n", cdesc ? cdesc->pgp_name : "unknown");
859 dst_print_halg(dst, "ecdh hash algorithm", key.material.ec.kdf_hash_alg);
860 dst_printf(dst, "ecdh key wrap algorithm: %d\n", (int) key.material.ec.key_wrap_alg);
861 break;
862 }
863 default:
864 dst_printf(dst, "unknown public key algorithm\n");
865 }
866 indent_dest_decrease(dst);
867
868 if (is_secret_key_pkt(key.tag)) {
869 dst_printf(dst, "secret key material:\n");
870 indent_dest_increase(dst);
871
872 dst_printf(dst, "s2k usage: %d\n", (int) key.sec_protection.s2k.usage);
873 if ((key.sec_protection.s2k.usage == PGP_S2KU_ENCRYPTED) ||
874 (key.sec_protection.s2k.usage == PGP_S2KU_ENCRYPTED_AND_HASHED)) {
875 dst_print_salg(dst, NULL, key.sec_protection.symm_alg);
876 dst_print_s2k(dst, &key.sec_protection.s2k);
877 if (key.sec_protection.s2k.specifier != PGP_S2KS_EXPERIMENTAL) {
878 size_t bl_size = pgp_block_size(key.sec_protection.symm_alg);
879 if (bl_size) {
880 dst_print_hex(dst, "cipher iv", key.sec_protection.iv, bl_size, true);
881 } else {
882 dst_printf(dst, "cipher iv: unknown algorithm\n");
883 }
884 }
885 dst_printf(dst, "encrypted secret key data: %d bytes\n", (int) key.sec_len);
886 }
887
888 if (!key.sec_protection.s2k.usage) {
889 dst_printf(dst, "cleartext secret key data: %d bytes\n", (int) key.sec_len);
890 }
891 indent_dest_decrease(dst);
892 }
893
894 pgp_key_id_t keyid = {};
895 if (!pgp_keyid(keyid, key)) {
896 dst_print_hex(dst, "keyid", keyid.data(), keyid.size(), false);
897 } else {
898 dst_printf(dst, "keyid: failed to calculate");
899 }
900
901 if ((key.version > PGP_V3) && (ctx->dump_grips)) {
902 if (!pgp_fingerprint(keyfp, key)) {
903 dst_print_hex(dst, "fingerprint", keyfp.fingerprint, keyfp.length, false);
904 } else {
905 dst_printf(dst, "fingerprint: failed to calculate");
906 }
907 }
908
909 if (ctx->dump_grips) {
910 pgp_key_grip_t grip;
911 if (rnp_key_store_get_key_grip(&key.material, grip)) {
912 dst_print_hex(dst, "grip", grip.data(), grip.size(), false);
913 } else {
914 dst_printf(dst, "grip: failed to calculate");
915 }
916 }
917
918 indent_dest_decrease(dst);
919 return RNP_SUCCESS;
920 }
921
922 static rnp_result_t
stream_dump_userid(pgp_source_t * src,pgp_dest_t * dst)923 stream_dump_userid(pgp_source_t *src, pgp_dest_t *dst)
924 {
925 pgp_userid_pkt_t uid;
926 rnp_result_t ret;
927 const char * utype;
928
929 try {
930 ret = uid.parse(*src);
931 } catch (const std::exception &e) {
932 ret = RNP_ERROR_GENERIC;
933 }
934 if (ret) {
935 return ret;
936 }
937
938 switch (uid.tag) {
939 case PGP_PKT_USER_ID:
940 utype = "UserID";
941 break;
942 case PGP_PKT_USER_ATTR:
943 utype = "UserAttr";
944 break;
945 default:
946 utype = "Unknown user id";
947 }
948
949 dst_printf(dst, "%s packet\n", utype);
950 indent_dest_increase(dst);
951
952 switch (uid.tag) {
953 case PGP_PKT_USER_ID:
954 dst_printf(dst, "id: ");
955 dst_write(dst, uid.uid, uid.uid_len);
956 dst_printf(dst, "\n");
957 break;
958 case PGP_PKT_USER_ATTR:
959 dst_printf(dst, "id: (%d bytes of data)\n", (int) uid.uid_len);
960 break;
961 default:;
962 }
963
964 indent_dest_decrease(dst);
965 return RNP_SUCCESS;
966 }
967
968 static rnp_result_t
stream_dump_pk_session_key(rnp_dump_ctx_t * ctx,pgp_source_t * src,pgp_dest_t * dst)969 stream_dump_pk_session_key(rnp_dump_ctx_t *ctx, pgp_source_t *src, pgp_dest_t *dst)
970 {
971 pgp_pk_sesskey_t pkey;
972 pgp_encrypted_material_t material;
973 rnp_result_t ret;
974
975 try {
976 ret = pkey.parse(*src);
977 if (!pkey.parse_material(material)) {
978 ret = RNP_ERROR_BAD_FORMAT;
979 }
980 } catch (const std::exception &e) {
981 ret = RNP_ERROR_GENERIC;
982 }
983 if (ret) {
984 return ret;
985 }
986
987 dst_printf(dst, "Public-key encrypted session key packet\n");
988 indent_dest_increase(dst);
989
990 dst_printf(dst, "version: %d\n", (int) pkey.version);
991 dst_print_keyid(dst, NULL, pkey.key_id);
992 dst_print_palg(dst, NULL, pkey.alg);
993 dst_printf(dst, "encrypted material:\n");
994 indent_dest_increase(dst);
995
996 switch (pkey.alg) {
997 case PGP_PKA_RSA:
998 case PGP_PKA_RSA_ENCRYPT_ONLY:
999 case PGP_PKA_RSA_SIGN_ONLY:
1000 dst_print_mpi(dst, "rsa m", &material.rsa.m, ctx->dump_mpi);
1001 break;
1002 case PGP_PKA_ELGAMAL:
1003 case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1004 dst_print_mpi(dst, "eg g", &material.eg.g, ctx->dump_mpi);
1005 dst_print_mpi(dst, "eg m", &material.eg.m, ctx->dump_mpi);
1006 break;
1007 case PGP_PKA_SM2:
1008 dst_print_mpi(dst, "sm2 m", &material.sm2.m, ctx->dump_mpi);
1009 break;
1010 case PGP_PKA_ECDH:
1011 dst_print_mpi(dst, "ecdh p", &material.ecdh.p, ctx->dump_mpi);
1012 if (ctx->dump_mpi) {
1013 dst_print_hex(dst, "ecdh m", material.ecdh.m, material.ecdh.mlen, true);
1014 } else {
1015 dst_printf(dst, "ecdh m: %d bytes\n", (int) material.ecdh.mlen);
1016 }
1017 break;
1018 default:
1019 dst_printf(dst, "unknown public key algorithm\n");
1020 }
1021
1022 indent_dest_decrease(dst);
1023 indent_dest_decrease(dst);
1024 return RNP_SUCCESS;
1025 }
1026
1027 static rnp_result_t
stream_dump_sk_session_key(pgp_source_t * src,pgp_dest_t * dst)1028 stream_dump_sk_session_key(pgp_source_t *src, pgp_dest_t *dst)
1029 {
1030 pgp_sk_sesskey_t skey;
1031 rnp_result_t ret;
1032
1033 try {
1034 ret = skey.parse(*src);
1035 } catch (const std::exception &e) {
1036 ret = RNP_ERROR_GENERIC;
1037 }
1038 if (ret) {
1039 return ret;
1040 }
1041
1042 dst_printf(dst, "Symmetric-key encrypted session key packet\n");
1043 indent_dest_increase(dst);
1044 dst_printf(dst, "version: %d\n", (int) skey.version);
1045 dst_print_salg(dst, NULL, skey.alg);
1046 if (skey.version == PGP_SKSK_V5) {
1047 dst_print_aalg(dst, NULL, skey.aalg);
1048 }
1049 dst_print_s2k(dst, &skey.s2k);
1050 if (skey.version == PGP_SKSK_V5) {
1051 dst_print_hex(dst, "aead iv", skey.iv, skey.ivlen, true);
1052 }
1053 dst_print_hex(dst, "encrypted key", skey.enckey, skey.enckeylen, true);
1054 indent_dest_decrease(dst);
1055
1056 return RNP_SUCCESS;
1057 }
1058
1059 static bool
stream_dump_get_aead_hdr(pgp_source_t * src,pgp_aead_hdr_t * hdr)1060 stream_dump_get_aead_hdr(pgp_source_t *src, pgp_aead_hdr_t *hdr)
1061 {
1062 pgp_dest_t encdst = {};
1063 uint8_t encpkt[64] = {};
1064
1065 if (init_mem_dest(&encdst, &encpkt, sizeof(encpkt))) {
1066 return false;
1067 }
1068 mem_dest_discard_overflow(&encdst, true);
1069
1070 if (stream_read_packet(src, &encdst)) {
1071 dst_close(&encdst, false);
1072 return false;
1073 }
1074 size_t len = std::min(encdst.writeb, sizeof(encpkt));
1075 dst_close(&encdst, false);
1076
1077 pgp_source_t memsrc = {};
1078 if (init_mem_src(&memsrc, encpkt, len, false)) {
1079 return false;
1080 }
1081 bool res = get_aead_src_hdr(&memsrc, hdr);
1082 src_close(&memsrc);
1083 return res;
1084 }
1085
1086 static rnp_result_t
stream_dump_aead_encrypted(pgp_source_t * src,pgp_dest_t * dst)1087 stream_dump_aead_encrypted(pgp_source_t *src, pgp_dest_t *dst)
1088 {
1089 dst_printf(dst, "AEAD-encrypted data packet\n");
1090
1091 pgp_aead_hdr_t aead = {};
1092 if (!stream_dump_get_aead_hdr(src, &aead)) {
1093 dst_printf(dst, "ERROR: failed to read AEAD header\n");
1094 return RNP_ERROR_READ;
1095 }
1096
1097 indent_dest_increase(dst);
1098
1099 dst_printf(dst, "version: %d\n", (int) aead.version);
1100 dst_print_salg(dst, NULL, aead.ealg);
1101 dst_print_aalg(dst, NULL, aead.aalg);
1102 dst_printf(dst, "chunk size: %d\n", (int) aead.csize);
1103 dst_print_hex(dst, "initialization vector", aead.iv, aead.ivlen, true);
1104
1105 indent_dest_decrease(dst);
1106 return RNP_SUCCESS;
1107 }
1108
1109 static rnp_result_t
stream_dump_encrypted(pgp_source_t * src,pgp_dest_t * dst,int tag)1110 stream_dump_encrypted(pgp_source_t *src, pgp_dest_t *dst, int tag)
1111 {
1112 switch (tag) {
1113 case PGP_PKT_SE_DATA:
1114 dst_printf(dst, "Symmetrically-encrypted data packet\n\n");
1115 break;
1116 case PGP_PKT_SE_IP_DATA:
1117 dst_printf(dst, "Symmetrically-encrypted integrity protected data packet\n\n");
1118 break;
1119 case PGP_PKT_AEAD_ENCRYPTED:
1120 return stream_dump_aead_encrypted(src, dst);
1121 default:
1122 dst_printf(dst, "Unknown encrypted data packet\n\n");
1123 break;
1124 }
1125
1126 return stream_skip_packet(src);
1127 }
1128
1129 static rnp_result_t
stream_dump_one_pass(pgp_source_t * src,pgp_dest_t * dst)1130 stream_dump_one_pass(pgp_source_t *src, pgp_dest_t *dst)
1131 {
1132 pgp_one_pass_sig_t onepass;
1133 rnp_result_t ret;
1134
1135 try {
1136 ret = onepass.parse(*src);
1137 } catch (const std::exception &e) {
1138 ret = RNP_ERROR_GENERIC;
1139 }
1140 if (ret) {
1141 return ret;
1142 }
1143
1144 dst_printf(dst, "One-pass signature packet\n");
1145 indent_dest_increase(dst);
1146
1147 dst_printf(dst, "version: %d\n", (int) onepass.version);
1148 dst_print_sig_type(dst, NULL, onepass.type);
1149 dst_print_halg(dst, NULL, onepass.halg);
1150 dst_print_palg(dst, NULL, onepass.palg);
1151 dst_print_keyid(dst, "signing key id", onepass.keyid);
1152 dst_printf(dst, "nested: %d\n", (int) onepass.nested);
1153
1154 indent_dest_decrease(dst);
1155 return RNP_SUCCESS;
1156 }
1157
1158 static rnp_result_t
stream_dump_compressed(rnp_dump_ctx_t * ctx,pgp_source_t * src,pgp_dest_t * dst)1159 stream_dump_compressed(rnp_dump_ctx_t *ctx, pgp_source_t *src, pgp_dest_t *dst)
1160 {
1161 pgp_source_t zsrc = {0};
1162 uint8_t zalg;
1163 rnp_result_t ret;
1164
1165 if ((ret = init_compressed_src(&zsrc, src))) {
1166 return ret;
1167 }
1168
1169 dst_printf(dst, "Compressed data packet\n");
1170 indent_dest_increase(dst);
1171
1172 get_compressed_src_alg(&zsrc, &zalg);
1173 dst_print_zalg(dst, NULL, (pgp_compression_type_t) zalg);
1174 dst_printf(dst, "Decompressed contents:\n");
1175 ret = stream_dump_packets_raw(ctx, &zsrc, dst);
1176
1177 src_close(&zsrc);
1178 indent_dest_decrease(dst);
1179 return ret;
1180 }
1181
1182 static rnp_result_t
stream_dump_literal(pgp_source_t * src,pgp_dest_t * dst)1183 stream_dump_literal(pgp_source_t *src, pgp_dest_t *dst)
1184 {
1185 pgp_source_t lsrc = {0};
1186 pgp_literal_hdr_t lhdr = {0};
1187 rnp_result_t ret;
1188 uint8_t readbuf[16384];
1189
1190 if ((ret = init_literal_src(&lsrc, src))) {
1191 return ret;
1192 }
1193
1194 dst_printf(dst, "Literal data packet\n");
1195 indent_dest_increase(dst);
1196
1197 get_literal_src_hdr(&lsrc, &lhdr);
1198 dst_printf(dst, "data format: '%c'\n", lhdr.format);
1199 dst_printf(dst, "filename: %s (len %d)\n", lhdr.fname, (int) lhdr.fname_len);
1200 dst_print_time(dst, "timestamp", lhdr.timestamp);
1201
1202 ret = RNP_SUCCESS;
1203 while (!src_eof(&lsrc)) {
1204 size_t read = 0;
1205 if (!src_read(&lsrc, readbuf, sizeof(readbuf), &read)) {
1206 ret = RNP_ERROR_READ;
1207 break;
1208 }
1209 }
1210
1211 dst_printf(dst, "data bytes: %lu\n", (unsigned long) lsrc.readb);
1212 src_close(&lsrc);
1213 indent_dest_decrease(dst);
1214 return ret;
1215 }
1216
1217 static rnp_result_t
stream_dump_marker(pgp_source_t & src,pgp_dest_t & dst)1218 stream_dump_marker(pgp_source_t &src, pgp_dest_t &dst)
1219 {
1220 dst_printf(&dst, "Marker packet\n");
1221 indent_dest_increase(&dst);
1222 dst_printf(
1223 &dst, "contents: %s\n", stream_parse_marker(src) ? "invalid" : PGP_MARKER_CONTENTS);
1224 indent_dest_decrease(&dst);
1225 return RNP_SUCCESS;
1226 }
1227
1228 static rnp_result_t
stream_dump_packets_raw(rnp_dump_ctx_t * ctx,pgp_source_t * src,pgp_dest_t * dst)1229 stream_dump_packets_raw(rnp_dump_ctx_t *ctx, pgp_source_t *src, pgp_dest_t *dst)
1230 {
1231 char msg[1024 + PGP_MAX_HEADER_SIZE] = {0};
1232 char smsg[128] = {0};
1233 rnp_result_t ret = RNP_ERROR_GENERIC;
1234
1235 if (src_eof(src)) {
1236 return RNP_SUCCESS;
1237 }
1238
1239 /* do not allow endless recursion */
1240 if (++ctx->layers > MAXIMUM_NESTING_LEVEL) {
1241 RNP_LOG("Too many OpenPGP nested layers during the dump.");
1242 dst_printf(dst, ":too many OpenPGP packet layers, stopping.\n");
1243 ret = RNP_SUCCESS;
1244 goto finish;
1245 }
1246
1247 while (!src_eof(src)) {
1248 pgp_packet_hdr_t hdr = {};
1249 size_t off = src->readb;
1250 rnp_result_t hdrret = stream_peek_packet_hdr(src, &hdr);
1251 if (hdrret) {
1252 ret = hdrret;
1253 goto finish;
1254 }
1255
1256 if (hdr.partial) {
1257 snprintf(msg, sizeof(msg), "partial len");
1258 } else if (hdr.indeterminate) {
1259 snprintf(msg, sizeof(msg), "indeterminate len");
1260 } else {
1261 snprintf(msg, sizeof(msg), "len %zu", hdr.pkt_len);
1262 }
1263 vsnprinthex(smsg, sizeof(smsg), hdr.hdr, hdr.hdr_len);
1264 dst_printf(
1265 dst, ":off %zu: packet header 0x%s (tag %d, %s)\n", off, smsg, hdr.tag, msg);
1266
1267 if (ctx->dump_packets) {
1268 size_t rlen = hdr.pkt_len + hdr.hdr_len;
1269 bool part = false;
1270
1271 if (!hdr.pkt_len || (rlen > 1024 + hdr.hdr_len)) {
1272 rlen = 1024 + hdr.hdr_len;
1273 part = true;
1274 }
1275
1276 dst_printf(dst, ":off %zu: packet contents ", off + hdr.hdr_len);
1277 if (!src_peek(src, msg, rlen, &rlen)) {
1278 dst_printf(dst, "- failed to read\n");
1279 } else {
1280 rlen -= hdr.hdr_len;
1281 if (part || (rlen < hdr.pkt_len)) {
1282 dst_printf(dst, "(first %d bytes)\n", (int) rlen);
1283 } else {
1284 dst_printf(dst, "(%d bytes)\n", (int) rlen);
1285 }
1286 indent_dest_increase(dst);
1287 dst_hexdump(dst, (uint8_t *) msg + hdr.hdr_len, rlen);
1288 indent_dest_decrease(dst);
1289 }
1290 dst_printf(dst, "\n");
1291 }
1292
1293 switch (hdr.tag) {
1294 case PGP_PKT_SIGNATURE:
1295 stream_dump_signature(ctx, src, dst);
1296 ret = RNP_SUCCESS;
1297 break;
1298 case PGP_PKT_SECRET_KEY:
1299 case PGP_PKT_PUBLIC_KEY:
1300 case PGP_PKT_SECRET_SUBKEY:
1301 case PGP_PKT_PUBLIC_SUBKEY:
1302 ret = stream_dump_key(ctx, src, dst);
1303 break;
1304 case PGP_PKT_USER_ID:
1305 case PGP_PKT_USER_ATTR:
1306 ret = stream_dump_userid(src, dst);
1307 break;
1308 case PGP_PKT_PK_SESSION_KEY:
1309 ret = stream_dump_pk_session_key(ctx, src, dst);
1310 break;
1311 case PGP_PKT_SK_SESSION_KEY:
1312 ret = stream_dump_sk_session_key(src, dst);
1313 break;
1314 case PGP_PKT_SE_DATA:
1315 case PGP_PKT_SE_IP_DATA:
1316 case PGP_PKT_AEAD_ENCRYPTED:
1317 ctx->stream_pkts++;
1318 ret = stream_dump_encrypted(src, dst, hdr.tag);
1319 break;
1320 case PGP_PKT_ONE_PASS_SIG:
1321 ret = stream_dump_one_pass(src, dst);
1322 break;
1323 case PGP_PKT_COMPRESSED:
1324 ctx->stream_pkts++;
1325 ret = stream_dump_compressed(ctx, src, dst);
1326 break;
1327 case PGP_PKT_LITDATA:
1328 ctx->stream_pkts++;
1329 ret = stream_dump_literal(src, dst);
1330 break;
1331 case PGP_PKT_MARKER:
1332 ret = stream_dump_marker(*src, *dst);
1333 break;
1334 case PGP_PKT_TRUST:
1335 case PGP_PKT_MDC:
1336 dst_printf(dst, "Skipping unhandled pkt: %d\n\n", (int) hdr.tag);
1337 ret = stream_skip_packet(src);
1338 break;
1339 default:
1340 dst_printf(dst, "Skipping Unknown pkt: %d\n\n", (int) hdr.tag);
1341 ret = stream_skip_packet(src);
1342 }
1343
1344 if (ret) {
1345 RNP_LOG("failed to process packet");
1346 goto finish;
1347 }
1348
1349 if (ctx->stream_pkts > MAXIMUM_STREAM_PKTS) {
1350 RNP_LOG("Too many OpenPGP stream packets during the dump.");
1351 dst_printf(dst, ":too many OpenPGP stream packets, stopping.\n");
1352 ret = RNP_SUCCESS;
1353 goto finish;
1354 }
1355 }
1356
1357 ret = RNP_SUCCESS;
1358 finish:
1359 return ret;
1360 }
1361
1362 static bool
stream_skip_cleartext(pgp_source_t * src)1363 stream_skip_cleartext(pgp_source_t *src)
1364 {
1365 char buf[4096];
1366 size_t read = 0;
1367 size_t siglen = strlen(ST_SIG_BEGIN);
1368 char * hdrpos;
1369
1370 while (!src_eof(src)) {
1371 if (!src_peek(src, buf, sizeof(buf) - 1, &read) || (read <= siglen)) {
1372 return false;
1373 }
1374 buf[read] = '\0';
1375
1376 if ((hdrpos = strstr(buf, ST_SIG_BEGIN))) {
1377 /* +1 here is to skip \n on the beginning of ST_SIG_BEGIN */
1378 src_skip(src, hdrpos - buf + 1);
1379 return true;
1380 }
1381 src_skip(src, read - siglen + 1);
1382 }
1383 return false;
1384 }
1385
1386 rnp_result_t
stream_dump_packets(rnp_dump_ctx_t * ctx,pgp_source_t * src,pgp_dest_t * dst)1387 stream_dump_packets(rnp_dump_ctx_t *ctx, pgp_source_t *src, pgp_dest_t *dst)
1388 {
1389 pgp_source_t armorsrc = {0};
1390 pgp_dest_t wrdst = {0};
1391 bool armored = false;
1392 bool indent = false;
1393 rnp_result_t ret = RNP_ERROR_GENERIC;
1394
1395 ctx->layers = 0;
1396 ctx->stream_pkts = 0;
1397 /* check whether source is cleartext - then skip till the signature */
1398 if (is_cleartext_source(src)) {
1399 dst_printf(dst, ":cleartext signed data\n");
1400 if (!stream_skip_cleartext(src)) {
1401 RNP_LOG("malformed cleartext signed data");
1402 ret = RNP_ERROR_BAD_FORMAT;
1403 goto finish;
1404 }
1405 }
1406 /* check whether source is armored */
1407 if (is_armored_source(src)) {
1408 if ((ret = init_armored_src(&armorsrc, src))) {
1409 RNP_LOG("failed to parse armored data");
1410 goto finish;
1411 }
1412 armored = true;
1413 src = &armorsrc;
1414 dst_printf(dst, ":armored input\n");
1415 }
1416
1417 if (src_eof(src)) {
1418 dst_printf(dst, ":empty input\n");
1419 ret = RNP_SUCCESS;
1420 goto finish;
1421 }
1422
1423 if ((ret = init_indent_dest(&wrdst, dst))) {
1424 RNP_LOG("failed to init indent dest");
1425 goto finish;
1426 }
1427 indent = true;
1428 indent_dest_set(&wrdst, 0);
1429
1430 ret = stream_dump_packets_raw(ctx, src, &wrdst);
1431 finish:
1432 if (armored) {
1433 src_close(&armorsrc);
1434 }
1435 if (indent) {
1436 dst_close(&wrdst, false);
1437 }
1438 return ret;
1439 }
1440
1441 static bool
obj_add_intstr_json(json_object * obj,const char * name,int val,const id_str_pair map[])1442 obj_add_intstr_json(json_object *obj, const char *name, int val, const id_str_pair map[])
1443 {
1444 if (!obj_add_field_json(obj, name, json_object_new_int(val))) {
1445 return false;
1446 }
1447 if (!map) {
1448 return true;
1449 }
1450 char namestr[64] = {0};
1451 const char *str = id_str_pair::lookup(map, val, "Unknown");
1452 snprintf(namestr, sizeof(namestr), "%s.str", name);
1453 return obj_add_field_json(obj, namestr, json_object_new_string(str));
1454 }
1455
1456 static bool
obj_add_mpi_json(json_object * obj,const char * name,const pgp_mpi_t * mpi,bool contents)1457 obj_add_mpi_json(json_object *obj, const char *name, const pgp_mpi_t *mpi, bool contents)
1458 {
1459 char strname[64] = {0};
1460 snprintf(strname, sizeof(strname), "%s.bits", name);
1461 if (!obj_add_field_json(obj, strname, json_object_new_int(mpi_bits(mpi)))) {
1462 return false;
1463 }
1464 if (!contents) {
1465 return true;
1466 }
1467 snprintf(strname, sizeof(strname), "%s.raw", name);
1468 return obj_add_hex_json(obj, strname, mpi->mpi, mpi->len);
1469 }
1470
1471 static bool
subpacket_obj_add_algs(json_object * obj,const char * name,uint8_t * algs,size_t len,const id_str_pair map[])1472 subpacket_obj_add_algs(
1473 json_object *obj, const char *name, uint8_t *algs, size_t len, const id_str_pair map[])
1474 {
1475 json_object *jso_algs = json_object_new_array();
1476 if (!jso_algs || !obj_add_field_json(obj, name, jso_algs)) {
1477 return false;
1478 }
1479 for (size_t i = 0; i < len; i++) {
1480 if (!array_add_element_json(jso_algs, json_object_new_int(algs[i]))) {
1481 return false;
1482 }
1483 }
1484 if (!map) {
1485 return true;
1486 }
1487
1488 char strname[64] = {0};
1489 snprintf(strname, sizeof(strname), "%s.str", name);
1490
1491 jso_algs = json_object_new_array();
1492 if (!jso_algs || !obj_add_field_json(obj, strname, jso_algs)) {
1493 return false;
1494 }
1495 for (size_t i = 0; i < len; i++) {
1496 if (!array_add_element_json(
1497 jso_algs,
1498 json_object_new_string(id_str_pair::lookup(map, algs[i], "Unknown")))) {
1499 return false;
1500 }
1501 }
1502 return true;
1503 }
1504
1505 static bool
obj_add_s2k_json(json_object * obj,pgp_s2k_t * s2k)1506 obj_add_s2k_json(json_object *obj, pgp_s2k_t *s2k)
1507 {
1508 json_object *s2k_obj = json_object_new_object();
1509 if (!obj_add_field_json(obj, "s2k", s2k_obj)) {
1510 return false;
1511 }
1512 if (!obj_add_field_json(s2k_obj, "specifier", json_object_new_int(s2k->specifier))) {
1513 return false;
1514 }
1515 if ((s2k->specifier == PGP_S2KS_EXPERIMENTAL) && s2k->gpg_ext_num) {
1516 if (!obj_add_field_json(
1517 s2k_obj, "gpg extension", json_object_new_int(s2k->gpg_ext_num))) {
1518 return false;
1519 }
1520 if (s2k->gpg_ext_num == PGP_S2K_GPG_SMARTCARD) {
1521 size_t slen = s2k->gpg_serial_len > 16 ? 16 : s2k->gpg_serial_len;
1522 if (!obj_add_hex_json(s2k_obj, "card serial number", s2k->gpg_serial, slen)) {
1523 return false;
1524 }
1525 }
1526 }
1527 if (s2k->specifier == PGP_S2KS_EXPERIMENTAL) {
1528 return obj_add_hex_json(
1529 s2k_obj, "unknown experimental", s2k->experimental.data(), s2k->experimental.size());
1530 }
1531 if (!obj_add_intstr_json(s2k_obj, "hash algorithm", s2k->hash_alg, hash_alg_map)) {
1532 return false;
1533 }
1534 if (((s2k->specifier == PGP_S2KS_SALTED) ||
1535 (s2k->specifier == PGP_S2KS_ITERATED_AND_SALTED)) &&
1536 !obj_add_hex_json(s2k_obj, "salt", s2k->salt, PGP_SALT_SIZE)) {
1537 return false;
1538 }
1539 if (s2k->specifier == PGP_S2KS_ITERATED_AND_SALTED) {
1540 size_t real_iter = pgp_s2k_decode_iterations(s2k->iterations);
1541 if (!obj_add_field_json(s2k_obj, "iterations", json_object_new_int(real_iter))) {
1542 return false;
1543 }
1544 }
1545 return true;
1546 }
1547
1548 static rnp_result_t stream_dump_signature_pkt_json(rnp_dump_ctx_t * ctx,
1549 const pgp_signature_t *sig,
1550 json_object * pkt);
1551
1552 static bool
signature_dump_subpacket_json(rnp_dump_ctx_t * ctx,const pgp_sig_subpkt_t & subpkt,json_object * obj)1553 signature_dump_subpacket_json(rnp_dump_ctx_t * ctx,
1554 const pgp_sig_subpkt_t &subpkt,
1555 json_object * obj)
1556 {
1557 switch (subpkt.type) {
1558 case PGP_SIG_SUBPKT_CREATION_TIME:
1559 return obj_add_field_json(
1560 obj, "creation time", json_object_new_int64(subpkt.fields.create));
1561 case PGP_SIG_SUBPKT_EXPIRATION_TIME:
1562 return obj_add_field_json(
1563 obj, "expiration time", json_object_new_int64(subpkt.fields.expiry));
1564 case PGP_SIG_SUBPKT_EXPORT_CERT:
1565 return obj_add_field_json(
1566 obj, "exportable", json_object_new_boolean(subpkt.fields.exportable));
1567 case PGP_SIG_SUBPKT_TRUST:
1568 return obj_add_field_json(
1569 obj, "amount", json_object_new_int(subpkt.fields.trust.amount)) &&
1570 obj_add_field_json(
1571 obj, "level", json_object_new_int(subpkt.fields.trust.level));
1572 case PGP_SIG_SUBPKT_REGEXP:
1573 return obj_add_field_json(
1574 obj,
1575 "regexp",
1576 json_object_new_string_len(subpkt.fields.regexp.str, subpkt.fields.regexp.len));
1577 case PGP_SIG_SUBPKT_REVOCABLE:
1578 return obj_add_field_json(
1579 obj, "revocable", json_object_new_boolean(subpkt.fields.revocable));
1580 case PGP_SIG_SUBPKT_KEY_EXPIRY:
1581 return obj_add_field_json(
1582 obj, "key expiration", json_object_new_int64(subpkt.fields.expiry));
1583 case PGP_SIG_SUBPKT_PREFERRED_SKA:
1584 return subpacket_obj_add_algs(obj,
1585 "algorithms",
1586 subpkt.fields.preferred.arr,
1587 subpkt.fields.preferred.len,
1588 symm_alg_map);
1589 case PGP_SIG_SUBPKT_PREFERRED_HASH:
1590 return subpacket_obj_add_algs(obj,
1591 "algorithms",
1592 subpkt.fields.preferred.arr,
1593 subpkt.fields.preferred.len,
1594 hash_alg_map);
1595 case PGP_SIG_SUBPKT_PREF_COMPRESS:
1596 return subpacket_obj_add_algs(obj,
1597 "algorithms",
1598 subpkt.fields.preferred.arr,
1599 subpkt.fields.preferred.len,
1600 z_alg_map);
1601 case PGP_SIG_SUBPKT_PREFERRED_AEAD:
1602 return subpacket_obj_add_algs(obj,
1603 "algorithms",
1604 subpkt.fields.preferred.arr,
1605 subpkt.fields.preferred.len,
1606 aead_alg_map);
1607 case PGP_SIG_SUBPKT_REVOCATION_KEY:
1608 return obj_add_field_json(
1609 obj, "class", json_object_new_int(subpkt.fields.revocation_key.klass)) &&
1610 obj_add_field_json(
1611 obj, "algorithm", json_object_new_int(subpkt.fields.revocation_key.pkalg)) &&
1612 obj_add_hex_json(
1613 obj, "fingerprint", subpkt.fields.revocation_key.fp, PGP_FINGERPRINT_SIZE);
1614 case PGP_SIG_SUBPKT_ISSUER_KEY_ID:
1615 return obj_add_hex_json(obj, "issuer keyid", subpkt.fields.issuer, PGP_KEY_ID_SIZE);
1616 case PGP_SIG_SUBPKT_KEYSERV_PREFS:
1617 return obj_add_field_json(
1618 obj, "no-modify", json_object_new_boolean(subpkt.fields.ks_prefs.no_modify));
1619 case PGP_SIG_SUBPKT_PREF_KEYSERV:
1620 return obj_add_field_json(obj,
1621 "uri",
1622 json_object_new_string_len(subpkt.fields.preferred_ks.uri,
1623 subpkt.fields.preferred_ks.len));
1624 case PGP_SIG_SUBPKT_PRIMARY_USER_ID:
1625 return obj_add_field_json(
1626 obj, "primary", json_object_new_boolean(subpkt.fields.primary_uid));
1627 case PGP_SIG_SUBPKT_POLICY_URI:
1628 return obj_add_field_json(
1629 obj,
1630 "uri",
1631 json_object_new_string_len(subpkt.fields.policy.uri, subpkt.fields.policy.len));
1632 case PGP_SIG_SUBPKT_KEY_FLAGS: {
1633 uint8_t flg = subpkt.fields.key_flags;
1634 if (!obj_add_field_json(obj, "flags", json_object_new_int(flg))) {
1635 return false;
1636 }
1637 json_object *jso_flg = json_object_new_array();
1638 if (!jso_flg || !obj_add_field_json(obj, "flags.str", jso_flg)) {
1639 return false;
1640 }
1641 if ((flg & PGP_KF_CERTIFY) &&
1642 !array_add_element_json(jso_flg, json_object_new_string("certify"))) {
1643 return false;
1644 }
1645 if ((flg & PGP_KF_SIGN) &&
1646 !array_add_element_json(jso_flg, json_object_new_string("sign"))) {
1647 return false;
1648 }
1649 if ((flg & PGP_KF_ENCRYPT_COMMS) &&
1650 !array_add_element_json(jso_flg, json_object_new_string("encrypt_comm"))) {
1651 return false;
1652 }
1653 if ((flg & PGP_KF_ENCRYPT_STORAGE) &&
1654 !array_add_element_json(jso_flg, json_object_new_string("encrypt_storage"))) {
1655 return false;
1656 }
1657 if ((flg & PGP_KF_SPLIT) &&
1658 !array_add_element_json(jso_flg, json_object_new_string("split"))) {
1659 return false;
1660 }
1661 if ((flg & PGP_KF_AUTH) &&
1662 !array_add_element_json(jso_flg, json_object_new_string("auth"))) {
1663 return false;
1664 }
1665 if ((flg & PGP_KF_SHARED) &&
1666 !array_add_element_json(jso_flg, json_object_new_string("shared"))) {
1667 return false;
1668 }
1669 return true;
1670 }
1671 case PGP_SIG_SUBPKT_SIGNERS_USER_ID:
1672 return obj_add_field_json(
1673 obj,
1674 "uid",
1675 json_object_new_string_len(subpkt.fields.signer.uid, subpkt.fields.signer.len));
1676 case PGP_SIG_SUBPKT_REVOCATION_REASON: {
1677 if (!obj_add_intstr_json(
1678 obj, "code", subpkt.fields.revocation_reason.code, revoc_reason_map)) {
1679 return false;
1680 }
1681 return obj_add_field_json(
1682 obj,
1683 "message",
1684 json_object_new_string_len(subpkt.fields.revocation_reason.str,
1685 subpkt.fields.revocation_reason.len));
1686 }
1687 case PGP_SIG_SUBPKT_FEATURES:
1688 return obj_add_field_json(
1689 obj,
1690 "mdc",
1691 json_object_new_boolean(subpkt.fields.features & PGP_KEY_FEATURE_MDC)) &&
1692 obj_add_field_json(
1693 obj,
1694 "aead",
1695 json_object_new_boolean(subpkt.fields.features & PGP_KEY_FEATURE_AEAD)) &&
1696 obj_add_field_json(
1697 obj,
1698 "v5 keys",
1699 json_object_new_boolean(subpkt.fields.features & PGP_KEY_FEATURE_V5));
1700 case PGP_SIG_SUBPKT_EMBEDDED_SIGNATURE: {
1701 json_object *sig = json_object_new_object();
1702 if (!sig || !obj_add_field_json(obj, "signature", sig)) {
1703 return false;
1704 }
1705 return !stream_dump_signature_pkt_json(ctx, subpkt.fields.sig, sig);
1706 }
1707 case PGP_SIG_SUBPKT_ISSUER_FPR:
1708 return obj_add_hex_json(
1709 obj, "fingerprint", subpkt.fields.issuer_fp.fp, subpkt.fields.issuer_fp.len);
1710 case PGP_SIG_SUBPKT_NOTATION_DATA: {
1711 bool human = subpkt.fields.notation.human;
1712 if (!json_add(obj, "human", human) || !json_add(obj,
1713 "name",
1714 (char *) subpkt.fields.notation.name,
1715 subpkt.fields.notation.nlen)) {
1716 return false;
1717 }
1718 if (human) {
1719 return json_add(obj,
1720 "value",
1721 (char *) subpkt.fields.notation.value,
1722 subpkt.fields.notation.vlen);
1723 }
1724 return obj_add_hex_json(
1725 obj, "value", subpkt.fields.notation.value, subpkt.fields.notation.vlen);
1726 }
1727 default:
1728 if (!ctx->dump_packets) {
1729 return obj_add_hex_json(obj, "raw", subpkt.data, subpkt.len);
1730 }
1731 return true;
1732 }
1733 return true;
1734 }
1735
1736 static json_object *
signature_dump_subpackets_json(rnp_dump_ctx_t * ctx,const pgp_signature_t * sig)1737 signature_dump_subpackets_json(rnp_dump_ctx_t *ctx, const pgp_signature_t *sig)
1738 {
1739 json_object *res = json_object_new_array();
1740
1741 for (auto &subpkt : sig->subpkts) {
1742 json_object *jso_subpkt = json_object_new_object();
1743 if (json_object_array_add(res, jso_subpkt)) {
1744 json_object_put(jso_subpkt);
1745 goto error;
1746 }
1747
1748 if (!obj_add_intstr_json(jso_subpkt, "type", subpkt.type, sig_subpkt_type_map)) {
1749 goto error;
1750 }
1751 if (!obj_add_field_json(jso_subpkt, "length", json_object_new_int(subpkt.len))) {
1752 goto error;
1753 }
1754 if (!obj_add_field_json(
1755 jso_subpkt, "hashed", json_object_new_boolean(subpkt.hashed))) {
1756 goto error;
1757 }
1758 if (!obj_add_field_json(
1759 jso_subpkt, "critical", json_object_new_boolean(subpkt.critical))) {
1760 goto error;
1761 }
1762
1763 if (ctx->dump_packets &&
1764 !obj_add_hex_json(jso_subpkt, "raw", subpkt.data, subpkt.len)) {
1765 goto error;
1766 }
1767
1768 if (!signature_dump_subpacket_json(ctx, subpkt, jso_subpkt)) {
1769 goto error;
1770 }
1771 }
1772
1773 return res;
1774 error:
1775 json_object_put(res);
1776 return NULL;
1777 }
1778
1779 static rnp_result_t
stream_dump_signature_pkt_json(rnp_dump_ctx_t * ctx,const pgp_signature_t * sig,json_object * pkt)1780 stream_dump_signature_pkt_json(rnp_dump_ctx_t * ctx,
1781 const pgp_signature_t *sig,
1782 json_object * pkt)
1783 {
1784 json_object * material = NULL;
1785 pgp_signature_material_t sigmaterial = {};
1786 rnp_result_t ret = RNP_ERROR_OUT_OF_MEMORY;
1787
1788 if (!obj_add_field_json(pkt, "version", json_object_new_int(sig->version))) {
1789 goto done;
1790 }
1791 if (!obj_add_intstr_json(pkt, "type", sig->type(), sig_type_map)) {
1792 goto done;
1793 }
1794
1795 if (sig->version < PGP_V4) {
1796 if (!obj_add_field_json(
1797 pkt, "creation time", json_object_new_int(sig->creation_time))) {
1798 goto done;
1799 }
1800 if (!obj_add_hex_json(pkt, "signer", sig->signer.data(), sig->signer.size())) {
1801 goto done;
1802 }
1803 }
1804 if (!obj_add_intstr_json(pkt, "algorithm", sig->palg, pubkey_alg_map)) {
1805 goto done;
1806 }
1807 if (!obj_add_intstr_json(pkt, "hash algorithm", sig->halg, hash_alg_map)) {
1808 goto done;
1809 }
1810
1811 if (sig->version >= PGP_V4) {
1812 json_object *subpkts = signature_dump_subpackets_json(ctx, sig);
1813 if (!subpkts) {
1814 goto done;
1815 }
1816 if (!obj_add_field_json(pkt, "subpackets", subpkts)) {
1817 goto done;
1818 }
1819 }
1820
1821 if (!obj_add_hex_json(pkt, "lbits", sig->lbits, sizeof(sig->lbits))) {
1822 goto done;
1823 }
1824
1825 material = json_object_new_object();
1826 if (!material || !obj_add_field_json(pkt, "material", material)) {
1827 goto done;
1828 }
1829
1830 try {
1831 sig->parse_material(sigmaterial);
1832 } catch (const std::exception &e) {
1833 RNP_LOG("%s", e.what());
1834 return RNP_ERROR_OUT_OF_MEMORY;
1835 }
1836 switch (sig->palg) {
1837 case PGP_PKA_RSA:
1838 case PGP_PKA_RSA_ENCRYPT_ONLY:
1839 case PGP_PKA_RSA_SIGN_ONLY:
1840 if (!obj_add_mpi_json(material, "s", &sigmaterial.rsa.s, ctx->dump_mpi)) {
1841 goto done;
1842 }
1843 break;
1844 case PGP_PKA_DSA:
1845 if (!obj_add_mpi_json(material, "r", &sigmaterial.dsa.r, ctx->dump_mpi) ||
1846 !obj_add_mpi_json(material, "s", &sigmaterial.dsa.s, ctx->dump_mpi)) {
1847 goto done;
1848 }
1849 break;
1850 case PGP_PKA_EDDSA:
1851 case PGP_PKA_ECDSA:
1852 case PGP_PKA_SM2:
1853 case PGP_PKA_ECDH:
1854 if (!obj_add_mpi_json(material, "r", &sigmaterial.ecc.r, ctx->dump_mpi) ||
1855 !obj_add_mpi_json(material, "s", &sigmaterial.ecc.s, ctx->dump_mpi)) {
1856 goto done;
1857 }
1858 break;
1859 case PGP_PKA_ELGAMAL:
1860 case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1861 if (!obj_add_mpi_json(material, "r", &sigmaterial.eg.r, ctx->dump_mpi) ||
1862 !obj_add_mpi_json(material, "s", &sigmaterial.eg.s, ctx->dump_mpi)) {
1863 goto done;
1864 }
1865 break;
1866 default:
1867 break;
1868 }
1869 ret = RNP_SUCCESS;
1870 done:
1871 return ret;
1872 }
1873
1874 static rnp_result_t
stream_dump_signature_json(rnp_dump_ctx_t * ctx,pgp_source_t * src,json_object * pkt)1875 stream_dump_signature_json(rnp_dump_ctx_t *ctx, pgp_source_t *src, json_object *pkt)
1876 {
1877 pgp_signature_t sig;
1878 rnp_result_t ret;
1879 try {
1880 ret = sig.parse(*src);
1881 } catch (const std::exception &e) {
1882 RNP_LOG("%s", e.what());
1883 ret = RNP_ERROR_GENERIC;
1884 }
1885 if (ret) {
1886 return RNP_SUCCESS;
1887 }
1888 return stream_dump_signature_pkt_json(ctx, &sig, pkt);
1889 }
1890
1891 static rnp_result_t
stream_dump_key_json(rnp_dump_ctx_t * ctx,pgp_source_t * src,json_object * pkt)1892 stream_dump_key_json(rnp_dump_ctx_t *ctx, pgp_source_t *src, json_object *pkt)
1893 {
1894 pgp_key_pkt_t key;
1895 rnp_result_t ret;
1896 pgp_key_id_t keyid = {};
1897 pgp_fingerprint_t keyfp = {};
1898 json_object * material = NULL;
1899
1900 try {
1901 ret = key.parse(*src);
1902 } catch (const std::exception &e) {
1903 RNP_LOG("%s", e.what());
1904 ret = RNP_ERROR_GENERIC;
1905 }
1906 if (ret) {
1907 return ret;
1908 }
1909
1910 ret = RNP_ERROR_OUT_OF_MEMORY;
1911
1912 if (!obj_add_field_json(pkt, "version", json_object_new_int(key.version))) {
1913 goto done;
1914 }
1915 if (!obj_add_field_json(pkt, "creation time", json_object_new_int64(key.creation_time))) {
1916 goto done;
1917 }
1918 if ((key.version < PGP_V4) &&
1919 !obj_add_field_json(pkt, "v3 days", json_object_new_int(key.v3_days))) {
1920 goto done;
1921 }
1922 if (!obj_add_intstr_json(pkt, "algorithm", key.alg, pubkey_alg_map)) {
1923 goto done;
1924 }
1925
1926 material = json_object_new_object();
1927 if (!material || !obj_add_field_json(pkt, "material", material)) {
1928 goto done;
1929 }
1930
1931 switch (key.alg) {
1932 case PGP_PKA_RSA:
1933 case PGP_PKA_RSA_ENCRYPT_ONLY:
1934 case PGP_PKA_RSA_SIGN_ONLY:
1935 if (!obj_add_mpi_json(material, "n", &key.material.rsa.n, ctx->dump_mpi) ||
1936 !obj_add_mpi_json(material, "e", &key.material.rsa.e, ctx->dump_mpi)) {
1937 goto done;
1938 }
1939 break;
1940 case PGP_PKA_DSA:
1941 if (!obj_add_mpi_json(material, "p", &key.material.dsa.p, ctx->dump_mpi) ||
1942 !obj_add_mpi_json(material, "q", &key.material.dsa.q, ctx->dump_mpi) ||
1943 !obj_add_mpi_json(material, "g", &key.material.dsa.g, ctx->dump_mpi) ||
1944 !obj_add_mpi_json(material, "y", &key.material.dsa.y, ctx->dump_mpi)) {
1945 goto done;
1946 }
1947 break;
1948 case PGP_PKA_ELGAMAL:
1949 case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1950 if (!obj_add_mpi_json(material, "p", &key.material.eg.p, ctx->dump_mpi) ||
1951 !obj_add_mpi_json(material, "g", &key.material.eg.g, ctx->dump_mpi) ||
1952 !obj_add_mpi_json(material, "y", &key.material.eg.y, ctx->dump_mpi)) {
1953 goto done;
1954 }
1955 break;
1956 case PGP_PKA_ECDSA:
1957 case PGP_PKA_EDDSA:
1958 case PGP_PKA_SM2: {
1959 const ec_curve_desc_t *cdesc = get_curve_desc(key.material.ec.curve);
1960 if (!obj_add_mpi_json(material, "p", &key.material.ec.p, ctx->dump_mpi)) {
1961 goto done;
1962 }
1963 if (!obj_add_field_json(material,
1964 "curve",
1965 json_object_new_string(cdesc ? cdesc->pgp_name : "unknown"))) {
1966 goto done;
1967 }
1968 break;
1969 }
1970 case PGP_PKA_ECDH: {
1971 const ec_curve_desc_t *cdesc = get_curve_desc(key.material.ec.curve);
1972 if (!obj_add_mpi_json(material, "p", &key.material.ec.p, ctx->dump_mpi)) {
1973 goto done;
1974 }
1975 if (!obj_add_field_json(material,
1976 "curve",
1977 json_object_new_string(cdesc ? cdesc->pgp_name : "unknown"))) {
1978 goto done;
1979 }
1980 if (!obj_add_intstr_json(
1981 material, "hash algorithm", key.material.ec.kdf_hash_alg, hash_alg_map)) {
1982 goto done;
1983 }
1984 if (!obj_add_intstr_json(
1985 material, "key wrap algorithm", key.material.ec.key_wrap_alg, symm_alg_map)) {
1986 goto done;
1987 }
1988 break;
1989 }
1990 default:
1991 break;
1992 }
1993
1994 if (is_secret_key_pkt(key.tag)) {
1995 if (!obj_add_field_json(
1996 material, "s2k usage", json_object_new_int(key.sec_protection.s2k.usage))) {
1997 goto done;
1998 }
1999 if (!obj_add_s2k_json(material, &key.sec_protection.s2k)) {
2000 goto done;
2001 }
2002 if (key.sec_protection.s2k.usage &&
2003 !obj_add_intstr_json(
2004 material, "symmetric algorithm", key.sec_protection.symm_alg, symm_alg_map)) {
2005 goto done;
2006 }
2007 }
2008
2009 if (pgp_keyid(keyid, key) || !obj_add_hex_json(pkt, "keyid", keyid.data(), keyid.size())) {
2010 goto done;
2011 }
2012
2013 if (ctx->dump_grips) {
2014 if (pgp_fingerprint(keyfp, key) ||
2015 !obj_add_hex_json(pkt, "fingerprint", keyfp.fingerprint, keyfp.length)) {
2016 goto done;
2017 }
2018
2019 pgp_key_grip_t grip;
2020 if (!rnp_key_store_get_key_grip(&key.material, grip) ||
2021 !obj_add_hex_json(pkt, "grip", grip.data(), grip.size())) {
2022 goto done;
2023 }
2024 }
2025 ret = RNP_SUCCESS;
2026 done:
2027 return ret;
2028 }
2029
2030 static rnp_result_t
stream_dump_userid_json(pgp_source_t * src,json_object * pkt)2031 stream_dump_userid_json(pgp_source_t *src, json_object *pkt)
2032 {
2033 pgp_userid_pkt_t uid;
2034 rnp_result_t ret;
2035
2036 try {
2037 ret = uid.parse(*src);
2038 } catch (const std::exception &e) {
2039 ret = RNP_ERROR_GENERIC;
2040 }
2041 if (ret) {
2042 return ret;
2043 }
2044
2045 switch (uid.tag) {
2046 case PGP_PKT_USER_ID:
2047 if (!obj_add_field_json(
2048 pkt, "userid", json_object_new_string_len((char *) uid.uid, uid.uid_len))) {
2049 return RNP_ERROR_OUT_OF_MEMORY;
2050 }
2051 break;
2052 case PGP_PKT_USER_ATTR:
2053 if (!obj_add_hex_json(pkt, "userattr", uid.uid, uid.uid_len)) {
2054 return RNP_ERROR_OUT_OF_MEMORY;
2055 }
2056 break;
2057 default:;
2058 }
2059 return RNP_SUCCESS;
2060 }
2061
2062 static rnp_result_t
stream_dump_pk_session_key_json(rnp_dump_ctx_t * ctx,pgp_source_t * src,json_object * pkt)2063 stream_dump_pk_session_key_json(rnp_dump_ctx_t *ctx, pgp_source_t *src, json_object *pkt)
2064 {
2065 pgp_pk_sesskey_t pkey;
2066 pgp_encrypted_material_t pkmaterial;
2067 rnp_result_t ret;
2068
2069 try {
2070 ret = pkey.parse(*src);
2071 if (!pkey.parse_material(pkmaterial)) {
2072 ret = RNP_ERROR_BAD_FORMAT;
2073 }
2074 } catch (const std::exception &e) {
2075 ret = RNP_ERROR_GENERIC;
2076 }
2077 if (ret) {
2078 return ret;
2079 }
2080
2081 if (!obj_add_field_json(pkt, "version", json_object_new_int(pkey.version)) ||
2082 !obj_add_hex_json(pkt, "keyid", pkey.key_id.data(), pkey.key_id.size()) ||
2083 !obj_add_intstr_json(pkt, "algorithm", pkey.alg, pubkey_alg_map)) {
2084 return RNP_ERROR_OUT_OF_MEMORY;
2085 }
2086
2087 json_object *material = json_object_new_object();
2088 if (!obj_add_field_json(pkt, "material", material)) {
2089 return RNP_ERROR_OUT_OF_MEMORY;
2090 }
2091
2092 switch (pkey.alg) {
2093 case PGP_PKA_RSA:
2094 case PGP_PKA_RSA_ENCRYPT_ONLY:
2095 case PGP_PKA_RSA_SIGN_ONLY:
2096 if (!obj_add_mpi_json(material, "m", &pkmaterial.rsa.m, ctx->dump_mpi)) {
2097 return RNP_ERROR_OUT_OF_MEMORY;
2098 }
2099 break;
2100 case PGP_PKA_ELGAMAL:
2101 case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
2102 if (!obj_add_mpi_json(material, "g", &pkmaterial.eg.g, ctx->dump_mpi) ||
2103 !obj_add_mpi_json(material, "m", &pkmaterial.eg.m, ctx->dump_mpi)) {
2104 return RNP_ERROR_OUT_OF_MEMORY;
2105 }
2106 break;
2107 case PGP_PKA_SM2:
2108 if (!obj_add_mpi_json(material, "m", &pkmaterial.sm2.m, ctx->dump_mpi)) {
2109 return RNP_ERROR_OUT_OF_MEMORY;
2110 }
2111 break;
2112 case PGP_PKA_ECDH:
2113 if (!obj_add_mpi_json(material, "p", &pkmaterial.ecdh.p, ctx->dump_mpi) ||
2114 !obj_add_field_json(
2115 material, "m.bytes", json_object_new_int(pkmaterial.ecdh.mlen))) {
2116 return RNP_ERROR_OUT_OF_MEMORY;
2117 }
2118 if (ctx->dump_mpi &&
2119 !obj_add_hex_json(material, "m", pkmaterial.ecdh.m, pkmaterial.ecdh.mlen)) {
2120 return RNP_ERROR_OUT_OF_MEMORY;
2121 }
2122 break;
2123 default:;
2124 }
2125
2126 return RNP_SUCCESS;
2127 }
2128
2129 static rnp_result_t
stream_dump_sk_session_key_json(pgp_source_t * src,json_object * pkt)2130 stream_dump_sk_session_key_json(pgp_source_t *src, json_object *pkt)
2131 {
2132 pgp_sk_sesskey_t skey;
2133 rnp_result_t ret;
2134
2135 try {
2136 ret = skey.parse(*src);
2137 } catch (const std::exception &e) {
2138 ret = RNP_ERROR_GENERIC;
2139 }
2140 if (ret) {
2141 return ret;
2142 }
2143
2144 if (!obj_add_field_json(pkt, "version", json_object_new_int(skey.version)) ||
2145 !obj_add_intstr_json(pkt, "algorithm", skey.alg, symm_alg_map)) {
2146 return RNP_ERROR_OUT_OF_MEMORY;
2147 }
2148 if ((skey.version == PGP_SKSK_V5) &&
2149 !obj_add_intstr_json(pkt, "aead algorithm", skey.aalg, aead_alg_map)) {
2150 return RNP_ERROR_OUT_OF_MEMORY;
2151 }
2152 if (!obj_add_s2k_json(pkt, &skey.s2k)) {
2153 return RNP_ERROR_OUT_OF_MEMORY;
2154 }
2155 if ((skey.version == PGP_SKSK_V5) &&
2156 !obj_add_hex_json(pkt, "aead iv", skey.iv, skey.ivlen)) {
2157 return RNP_ERROR_OUT_OF_MEMORY;
2158 }
2159 if (!obj_add_hex_json(pkt, "encrypted key", skey.enckey, skey.enckeylen)) {
2160 return RNP_ERROR_OUT_OF_MEMORY;
2161 }
2162 return RNP_SUCCESS;
2163 }
2164
2165 static rnp_result_t
stream_dump_encrypted_json(pgp_source_t * src,json_object * pkt,pgp_pkt_type_t tag)2166 stream_dump_encrypted_json(pgp_source_t *src, json_object *pkt, pgp_pkt_type_t tag)
2167 {
2168 if (tag != PGP_PKT_AEAD_ENCRYPTED) {
2169 /* packet header with tag is already in pkt */
2170 return stream_skip_packet(src);
2171 }
2172
2173 /* dumping AEAD data */
2174 pgp_aead_hdr_t aead = {};
2175 if (!stream_dump_get_aead_hdr(src, &aead)) {
2176 return RNP_ERROR_READ;
2177 }
2178
2179 if (!obj_add_field_json(pkt, "version", json_object_new_int(aead.version)) ||
2180 !obj_add_intstr_json(pkt, "algorithm", aead.ealg, symm_alg_map) ||
2181 !obj_add_intstr_json(pkt, "aead algorithm", aead.aalg, aead_alg_map) ||
2182 !obj_add_field_json(pkt, "chunk size", json_object_new_int(aead.csize)) ||
2183 !obj_add_hex_json(pkt, "aead iv", aead.iv, aead.ivlen)) {
2184 return RNP_ERROR_OUT_OF_MEMORY;
2185 }
2186
2187 return RNP_SUCCESS;
2188 }
2189
2190 static rnp_result_t
stream_dump_one_pass_json(pgp_source_t * src,json_object * pkt)2191 stream_dump_one_pass_json(pgp_source_t *src, json_object *pkt)
2192 {
2193 pgp_one_pass_sig_t onepass;
2194 rnp_result_t ret;
2195
2196 try {
2197 ret = onepass.parse(*src);
2198 } catch (const std::exception &e) {
2199 ret = RNP_ERROR_GENERIC;
2200 }
2201 if (ret) {
2202 return ret;
2203 }
2204
2205 if (!obj_add_field_json(pkt, "version", json_object_new_int(onepass.version))) {
2206 return RNP_ERROR_OUT_OF_MEMORY;
2207 }
2208 if (!obj_add_intstr_json(pkt, "type", onepass.type, sig_type_map)) {
2209 return RNP_ERROR_OUT_OF_MEMORY;
2210 }
2211 if (!obj_add_intstr_json(pkt, "hash algorithm", onepass.halg, hash_alg_map)) {
2212 return RNP_ERROR_OUT_OF_MEMORY;
2213 }
2214 if (!obj_add_intstr_json(pkt, "public key algorithm", onepass.palg, pubkey_alg_map)) {
2215 return RNP_ERROR_OUT_OF_MEMORY;
2216 }
2217 if (!obj_add_hex_json(pkt, "signer", onepass.keyid.data(), onepass.keyid.size())) {
2218 return RNP_ERROR_OUT_OF_MEMORY;
2219 }
2220 if (!obj_add_field_json(pkt, "nested", json_object_new_boolean(onepass.nested))) {
2221 return RNP_ERROR_OUT_OF_MEMORY;
2222 }
2223 return RNP_SUCCESS;
2224 }
2225
2226 static rnp_result_t
stream_dump_marker_json(pgp_source_t & src,json_object * pkt)2227 stream_dump_marker_json(pgp_source_t &src, json_object *pkt)
2228 {
2229 rnp_result_t ret = stream_parse_marker(src);
2230
2231 if (!obj_add_field_json(
2232 pkt, "contents", json_object_new_string(ret ? "invalid" : PGP_MARKER_CONTENTS))) {
2233 return RNP_ERROR_OUT_OF_MEMORY;
2234 }
2235 return RNP_SUCCESS;
2236 }
2237
2238 static rnp_result_t stream_dump_raw_packets_json(rnp_dump_ctx_t *ctx,
2239 pgp_source_t * src,
2240 json_object ** jso);
2241
2242 static rnp_result_t
stream_dump_compressed_json(rnp_dump_ctx_t * ctx,pgp_source_t * src,json_object * pkt)2243 stream_dump_compressed_json(rnp_dump_ctx_t *ctx, pgp_source_t *src, json_object *pkt)
2244 {
2245 pgp_source_t zsrc = {0};
2246 uint8_t zalg;
2247 rnp_result_t ret;
2248 json_object *contents = NULL;
2249
2250 if ((ret = init_compressed_src(&zsrc, src))) {
2251 return ret;
2252 }
2253
2254 get_compressed_src_alg(&zsrc, &zalg);
2255 if (!obj_add_intstr_json(pkt, "algorithm", zalg, z_alg_map)) {
2256 ret = RNP_ERROR_OUT_OF_MEMORY;
2257 goto done;
2258 }
2259
2260 ret = stream_dump_raw_packets_json(ctx, &zsrc, &contents);
2261 if (!ret && !obj_add_field_json(pkt, "contents", contents)) {
2262 json_object_put(contents);
2263 ret = RNP_ERROR_OUT_OF_MEMORY;
2264 }
2265 done:
2266 src_close(&zsrc);
2267 return ret;
2268 }
2269
2270 static rnp_result_t
stream_dump_literal_json(pgp_source_t * src,json_object * pkt)2271 stream_dump_literal_json(pgp_source_t *src, json_object *pkt)
2272 {
2273 pgp_source_t lsrc = {0};
2274 pgp_literal_hdr_t lhdr = {0};
2275 rnp_result_t ret;
2276 uint8_t readbuf[16384];
2277
2278 if ((ret = init_literal_src(&lsrc, src))) {
2279 return ret;
2280 }
2281 ret = RNP_ERROR_OUT_OF_MEMORY;
2282 get_literal_src_hdr(&lsrc, &lhdr);
2283 if (!obj_add_field_json(
2284 pkt, "format", json_object_new_string_len((char *) &lhdr.format, 1))) {
2285 goto done;
2286 }
2287 if (!obj_add_field_json(
2288 pkt, "filename", json_object_new_string_len(lhdr.fname, lhdr.fname_len))) {
2289 goto done;
2290 }
2291 if (!obj_add_field_json(pkt, "timestamp", json_object_new_int64(lhdr.timestamp))) {
2292 goto done;
2293 }
2294
2295 while (!src_eof(&lsrc)) {
2296 size_t read = 0;
2297 if (!src_read(&lsrc, readbuf, sizeof(readbuf), &read)) {
2298 ret = RNP_ERROR_READ;
2299 goto done;
2300 }
2301 }
2302
2303 if (!obj_add_field_json(pkt, "datalen", json_object_new_int64(lsrc.readb))) {
2304 goto done;
2305 }
2306 ret = RNP_SUCCESS;
2307 done:
2308 src_close(&lsrc);
2309 return ret;
2310 }
2311
2312 static bool
stream_dump_hdr_json(pgp_source_t * src,pgp_packet_hdr_t * hdr,json_object * pkt)2313 stream_dump_hdr_json(pgp_source_t *src, pgp_packet_hdr_t *hdr, json_object *pkt)
2314 {
2315 rnp_result_t hdrret = stream_peek_packet_hdr(src, hdr);
2316 if (hdrret) {
2317 return false;
2318 }
2319
2320 json_object *jso_hdr = json_object_new_object();
2321 if (!jso_hdr) {
2322 return false;
2323 }
2324
2325 if (!obj_add_field_json(jso_hdr, "offset", json_object_new_int64(src->readb))) {
2326 goto error;
2327 }
2328 if (!obj_add_intstr_json(jso_hdr, "tag", hdr->tag, packet_tag_map)) {
2329 goto error;
2330 }
2331 if (!obj_add_hex_json(jso_hdr, "raw", hdr->hdr, hdr->hdr_len)) {
2332 goto error;
2333 }
2334 if (!hdr->partial && !hdr->indeterminate &&
2335 !obj_add_field_json(jso_hdr, "length", json_object_new_int64(hdr->pkt_len))) {
2336 goto error;
2337 }
2338 if (!obj_add_field_json(jso_hdr, "partial", json_object_new_boolean(hdr->partial))) {
2339 goto error;
2340 }
2341 if (!obj_add_field_json(
2342 jso_hdr, "indeterminate", json_object_new_boolean(hdr->indeterminate))) {
2343 goto error;
2344 }
2345 return obj_add_field_json(pkt, "header", jso_hdr);
2346 error:
2347 json_object_put(jso_hdr);
2348 return false;
2349 }
2350
2351 static rnp_result_t
stream_dump_raw_packets_json(rnp_dump_ctx_t * ctx,pgp_source_t * src,json_object ** jso)2352 stream_dump_raw_packets_json(rnp_dump_ctx_t *ctx, pgp_source_t *src, json_object **jso)
2353 {
2354 json_object *pkts = NULL;
2355 json_object *pkt = NULL;
2356 rnp_result_t ret = RNP_ERROR_GENERIC;
2357
2358 pkts = json_object_new_array();
2359 if (!pkts) {
2360 return RNP_ERROR_OUT_OF_MEMORY;
2361 }
2362
2363 if (src_eof(src)) {
2364 ret = RNP_SUCCESS;
2365 goto done;
2366 }
2367
2368 /* do not allow endless recursion */
2369 if (++ctx->layers > MAXIMUM_NESTING_LEVEL) {
2370 RNP_LOG("Too many OpenPGP nested layers during the dump.");
2371 ret = RNP_SUCCESS;
2372 goto done;
2373 }
2374
2375 while (!src_eof(src)) {
2376 pgp_packet_hdr_t hdr = {};
2377
2378 pkt = json_object_new_object();
2379 if (!pkt) {
2380 ret = RNP_ERROR_OUT_OF_MEMORY;
2381 goto done;
2382 }
2383
2384 if (!stream_dump_hdr_json(src, &hdr, pkt)) {
2385 ret = RNP_ERROR_OUT_OF_MEMORY;
2386 goto done;
2387 }
2388
2389 if (ctx->dump_packets) {
2390 size_t rlen = hdr.pkt_len + hdr.hdr_len;
2391 uint8_t buf[2048 + sizeof(hdr.hdr)] = {0};
2392
2393 if (!hdr.pkt_len || (rlen > 2048 + hdr.hdr_len)) {
2394 rlen = 2048 + hdr.hdr_len;
2395 }
2396 if (!src_peek(src, buf, rlen, &rlen) || (rlen < hdr.hdr_len)) {
2397 ret = RNP_ERROR_READ;
2398 goto done;
2399 }
2400 if (!obj_add_hex_json(pkt, "raw", buf + hdr.hdr_len, rlen - hdr.hdr_len)) {
2401 ret = RNP_ERROR_OUT_OF_MEMORY;
2402 goto done;
2403 }
2404 }
2405
2406 switch (hdr.tag) {
2407 case PGP_PKT_SIGNATURE:
2408 ret = stream_dump_signature_json(ctx, src, pkt);
2409 break;
2410 case PGP_PKT_SECRET_KEY:
2411 case PGP_PKT_PUBLIC_KEY:
2412 case PGP_PKT_SECRET_SUBKEY:
2413 case PGP_PKT_PUBLIC_SUBKEY:
2414 ret = stream_dump_key_json(ctx, src, pkt);
2415 break;
2416 case PGP_PKT_USER_ID:
2417 case PGP_PKT_USER_ATTR:
2418 ret = stream_dump_userid_json(src, pkt);
2419 break;
2420 case PGP_PKT_PK_SESSION_KEY:
2421 ret = stream_dump_pk_session_key_json(ctx, src, pkt);
2422 break;
2423 case PGP_PKT_SK_SESSION_KEY:
2424 ret = stream_dump_sk_session_key_json(src, pkt);
2425 break;
2426 case PGP_PKT_SE_DATA:
2427 case PGP_PKT_SE_IP_DATA:
2428 case PGP_PKT_AEAD_ENCRYPTED:
2429 ctx->stream_pkts++;
2430 ret = stream_dump_encrypted_json(src, pkt, hdr.tag);
2431 break;
2432 case PGP_PKT_ONE_PASS_SIG:
2433 ret = stream_dump_one_pass_json(src, pkt);
2434 break;
2435 case PGP_PKT_COMPRESSED:
2436 ctx->stream_pkts++;
2437 ret = stream_dump_compressed_json(ctx, src, pkt);
2438 break;
2439 case PGP_PKT_LITDATA:
2440 ctx->stream_pkts++;
2441 ret = stream_dump_literal_json(src, pkt);
2442 break;
2443 case PGP_PKT_MARKER:
2444 ret = stream_dump_marker_json(*src, pkt);
2445 break;
2446 case PGP_PKT_TRUST:
2447 case PGP_PKT_MDC:
2448 ret = stream_skip_packet(src);
2449 break;
2450 default:
2451 ret = stream_skip_packet(src);
2452 }
2453
2454 if (ret) {
2455 RNP_LOG("failed to process packet");
2456 goto done;
2457 }
2458
2459 if (json_object_array_add(pkts, pkt)) {
2460 ret = RNP_ERROR_OUT_OF_MEMORY;
2461 goto done;
2462 }
2463 if (ctx->stream_pkts > MAXIMUM_STREAM_PKTS) {
2464 RNP_LOG("Too many OpenPGP stream packets during the dump.");
2465 ret = RNP_SUCCESS;
2466 goto done;
2467 }
2468
2469 pkt = NULL;
2470 }
2471 done:
2472 if (ret) {
2473 json_object_put(pkts);
2474 json_object_put(pkt);
2475 pkts = NULL;
2476 }
2477 *jso = pkts;
2478 return ret;
2479 }
2480
2481 rnp_result_t
stream_dump_packets_json(rnp_dump_ctx_t * ctx,pgp_source_t * src,json_object ** jso)2482 stream_dump_packets_json(rnp_dump_ctx_t *ctx, pgp_source_t *src, json_object **jso)
2483 {
2484 pgp_source_t armorsrc = {0};
2485 bool armored = false;
2486 rnp_result_t ret = RNP_ERROR_GENERIC;
2487
2488 ctx->layers = 0;
2489 /* check whether source is cleartext - then skip till the signature */
2490 if (is_cleartext_source(src)) {
2491 if (!stream_skip_cleartext(src)) {
2492 RNP_LOG("malformed cleartext signed data");
2493 ret = RNP_ERROR_BAD_FORMAT;
2494 goto finish;
2495 }
2496 }
2497 /* check whether source is armored */
2498 if (is_armored_source(src)) {
2499 if ((ret = init_armored_src(&armorsrc, src))) {
2500 RNP_LOG("failed to parse armored data");
2501 goto finish;
2502 }
2503 armored = true;
2504 src = &armorsrc;
2505 }
2506
2507 if (src_eof(src)) {
2508 ret = RNP_ERROR_NOT_ENOUGH_DATA;
2509 goto finish;
2510 }
2511
2512 ret = stream_dump_raw_packets_json(ctx, src, jso);
2513 finish:
2514 if (armored) {
2515 src_close(&armorsrc);
2516 }
2517 return ret;
2518 }
2519