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