* gpgkeys_ldap.c (printquoted), curl-shim.c (curl_escape): Fix bad
[gnupg.git] / tools / gpgsplit.c
blob3cdae05bfb696cbb0ee5e9f5353aa98581f40926
1 /* gpgsplit.c - An OpenPGP packet splitting tool
2 * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 /*
23 * TODO: Add an option to uncompress packets. This should come quite handy.
26 #include <config.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <assert.h>
34 #ifdef HAVE_DOSISH_SYSTEM
35 # include <fcntl.h> /* for setmode() */
36 #endif
37 #include <zlib.h>
38 #ifdef HAVE_BZIP2
39 #include <bzlib.h>
40 #endif /* HAVE_BZIP2 */
41 #if defined(__riscos__) && defined(USE_ZLIBRISCOS)
42 # include "zlib-riscos.h"
43 #endif
45 #define INCLUDED_BY_MAIN_MODULE 1
46 #include "../g10/packet.h"
47 #include "util.h"
49 static int opt_verbose;
50 static const char *opt_prefix = "";
51 static int opt_uncompress;
52 static int opt_secret_to_public;
53 static int opt_no_split;
55 static void g10_exit( int rc );
56 static void split_packets (const char *fname);
59 enum cmd_and_opt_values {
60 aNull = 0,
61 oVerbose = 'v',
62 oPrefix = 'p',
63 oUncompress = 500,
64 oSecretToPublic,
65 oNoSplit,
67 aTest
71 static ARGPARSE_OPTS opts[] = {
73 { 301, NULL, 0, "@Options:\n " },
75 { oVerbose, "verbose", 0, "verbose" },
76 { oPrefix, "prefix", 2, "|STRING|Prepend filenames with STRING" },
77 { oUncompress, "uncompress", 0, "uncompress a packet"},
78 { oSecretToPublic, "secret-to-public", 0, "convert secret keys to public keys"},
79 { oNoSplit, "no-split", 0, "write to stdout and don't actually split"},
80 {0} };
83 const char *
84 strusage( int level )
86 const char *p;
87 switch (level)
89 case 11: p = "gpgsplit (GnuPG)";
90 break;
91 case 13: p = VERSION; break;
92 case 17: p = PRINTABLE_OS_NAME; break;
93 case 19: p =
94 "Please report bugs to <bug-gnupg@gnu.org>.\n";
95 break;
96 case 1:
97 case 40: p =
98 "Usage: gpgsplit [options] [files] (-h for help)";
99 break;
100 case 41: p =
101 "Syntax: gpgsplit [options] [files]\n"
102 "Split an OpenPGP message into packets\n";
103 break;
105 default: p = default_strusage(level);
107 return p;
113 main( int argc, char **argv )
115 ARGPARSE_ARGS pargs;
117 #ifdef HAVE_DOSISH_SYSTEM
118 setmode( fileno(stdin), O_BINARY );
119 setmode( fileno(stdout), O_BINARY );
120 #endif
121 log_set_name("gpgsplit");
123 pargs.argc = &argc;
124 pargs.argv = &argv;
125 pargs.flags= 1; /* do not remove the args */
126 while (optfile_parse( NULL, NULL, NULL, &pargs, opts))
128 switch (pargs.r_opt)
130 case oVerbose: opt_verbose = 1; break;
131 case oPrefix: opt_prefix = pargs.r.ret_str; break;
132 case oUncompress: opt_uncompress = 1; break;
133 case oSecretToPublic: opt_secret_to_public = 1; break;
134 case oNoSplit: opt_no_split = 1; break;
135 default : pargs.err = 2; break;
139 if (log_get_errorcount(0))
140 g10_exit (2);
142 if (!argc)
143 split_packets (NULL);
144 else
146 for ( ;argc; argc--, argv++)
147 split_packets (*argv);
150 g10_exit (0);
151 return 0;
155 static void
156 g10_exit (int rc)
158 rc = rc? rc : log_get_errorcount(0)? 2 : 0;
159 exit(rc );
162 static const char *
163 pkttype_to_string (int pkttype)
165 const char *s;
167 switch (pkttype)
169 case PKT_PUBKEY_ENC : s = "pk_enc"; break;
170 case PKT_SIGNATURE : s = "sig"; break;
171 case PKT_SYMKEY_ENC : s = "sym_enc"; break;
172 case PKT_ONEPASS_SIG : s = "onepass_sig"; break;
173 case PKT_SECRET_KEY : s = "secret_key"; break;
174 case PKT_PUBLIC_KEY : s = "public_key"; break;
175 case PKT_SECRET_SUBKEY : s = "secret_subkey"; break;
176 case PKT_COMPRESSED :
177 s = opt_uncompress? "uncompressed":"compressed";
178 break;
179 case PKT_ENCRYPTED : s = "encrypted"; break;
180 case PKT_MARKER : s = "marker"; break;
181 case PKT_PLAINTEXT : s = "plaintext"; break;
182 case PKT_RING_TRUST : s = "ring_trust"; break;
183 case PKT_USER_ID : s = "user_id"; break;
184 case PKT_PUBLIC_SUBKEY : s = "public_subkey"; break;
185 case PKT_OLD_COMMENT : s = "old_comment"; break;
186 case PKT_ATTRIBUTE : s = "attribute"; break;
187 case PKT_ENCRYPTED_MDC : s = "encrypted_mdc"; break;
188 case PKT_MDC : s = "mdc"; break;
189 case PKT_COMMENT : s = "comment"; break;
190 case PKT_GPG_CONTROL : s = "gpg_control"; break;
191 default: s = "unknown"; break;
193 return s;
198 * Create a new filename and a return a pointer to a statically
199 * allocated buffer
201 static char *
202 create_filename (int pkttype)
204 static unsigned int partno = 0;
205 static char *name;
207 if (!name)
208 name = xmalloc (strlen (opt_prefix) + 100 );
210 assert (pkttype < 1000 && pkttype >= 0 );
211 partno++;
212 sprintf (name, "%s%06u-%03d" EXTSEP_S "%.40s",
213 opt_prefix, partno, pkttype, pkttype_to_string (pkttype));
214 return name;
217 static int
218 read_u16 (FILE *fp, size_t *rn)
220 int c;
222 if ( (c = getc (fp)) == EOF )
223 return -1;
224 *rn = c << 8;
225 if ( (c = getc (fp)) == EOF )
226 return -1;
227 *rn |= c;
228 return 0;
231 static int
232 read_u32 (FILE *fp, unsigned long *rn)
234 size_t tmp;
236 if (read_u16 (fp, &tmp))
237 return -1;
238 *rn = tmp << 16;
239 if (read_u16 (fp, &tmp))
240 return -1;
241 *rn |= tmp;
242 return 0;
245 static int
246 write_old_header (FILE *fp, int pkttype, unsigned int len)
248 int ctb = (0x80 | ((pkttype & 15)<<2));
250 if (len < 256)
252 else if (len < 65536)
253 ctb |= 1;
254 else
255 ctb |= 2;
257 if ( putc ( ctb, fp) == EOF )
258 return -1;
260 if ( (ctb & 2) )
262 if (putc ((len>>24), fp) == EOF)
263 return -1;
264 if (putc ((len>>16), fp) == EOF)
265 return -1;
267 if ( (ctb & 3) )
269 if (putc ((len>>8), fp) == EOF)
270 return -1;
272 if (putc ((len&0xff), fp) == EOF)
273 return -1;
274 return 0;
277 static int
278 write_new_header (FILE *fp, int pkttype, unsigned int len)
280 if ( putc ((0xc0 | (pkttype & 0x3f)), fp) == EOF )
281 return -1;
283 if (len < 192)
285 if (putc (len, fp) == EOF)
286 return -1;
288 else if (len < 8384)
290 len -= 192;
291 if (putc ((len/256)+192, fp) == EOF)
292 return -1;
293 if (putc ((len%256), fp) == EOF)
294 return -1;
296 else
298 if (putc ( 0xff, fp) == EOF)
299 return -1;
300 if (putc ( (len >> 24), fp) == EOF)
301 return -1;
302 if (putc ( (len >> 16), fp) == EOF)
303 return -1;
304 if (putc ( (len >> 8), fp) == EOF)
305 return -1;
306 if (putc ( (len & 0xff), fp) == EOF)
307 return -1;
309 return 0;
312 /* Return the length of the public key given BUF of BUFLEN with a
313 secret key. */
314 static int
315 public_key_length (const unsigned char *buf, size_t buflen)
317 const unsigned char *s;
318 int nmpis;
320 /* byte version number (3 or 4)
321 u32 creation time
322 [u16 valid days (version 3 only)]
323 byte algorithm
324 n MPIs (n and e) */
325 if (!buflen)
326 return 0;
327 if (buf[0] < 2 || buf[0] > 4)
328 return 0; /* wrong version number */
329 if (buflen < (buf[0] == 4? 6:8))
330 return 0;
331 s = buf + (buf[0] == 4? 6:8);
332 buflen -= (buf[0] == 4? 6:8);
333 switch (s[-1])
335 case 1:
336 case 2:
337 case 3:
338 nmpis = 2;
339 break;
340 case 16:
341 case 20:
342 nmpis = 3;
343 break;
344 case 17:
345 nmpis = 4;
346 break;
347 default:
348 return 0;
351 for (; nmpis; nmpis--)
353 unsigned int nbits, nbytes;
355 if (buflen < 2)
356 return 0;
357 nbits = (s[0] << 8) | s[1];
358 s += 2; buflen -= 2;
359 nbytes = (nbits+7) / 8;
360 if (buflen < nbytes)
361 return 0;
362 s += nbytes; buflen -= nbytes;
365 return s - buf;
368 static int
369 handle_zlib(int algo,FILE *fpin,FILE *fpout)
371 z_stream zs;
372 byte *inbuf, *outbuf;
373 unsigned int inbufsize, outbufsize;
374 int c,zinit_done, zrc, nread, count;
375 size_t n;
377 memset (&zs, 0, sizeof zs);
378 inbufsize = 2048;
379 inbuf = xmalloc (inbufsize);
380 outbufsize = 8192;
381 outbuf = xmalloc (outbufsize);
382 zs.avail_in = 0;
383 zinit_done = 0;
387 if (zs.avail_in < inbufsize)
389 n = zs.avail_in;
390 if (!n)
391 zs.next_in = (Bytef *) inbuf;
392 count = inbufsize - n;
393 for (nread=0;
394 nread < count && (c=getc (fpin)) != EOF;
395 nread++)
396 inbuf[n+nread] = c;
398 n += nread;
399 if (nread < count && algo == 1)
401 inbuf[n] = 0xFF; /* chew dummy byte */
402 n++;
404 zs.avail_in = n;
406 zs.next_out = (Bytef *) outbuf;
407 zs.avail_out = outbufsize;
409 if (!zinit_done)
411 zrc = (algo == 1? inflateInit2 ( &zs, -13)
412 : inflateInit ( &zs ));
413 if (zrc != Z_OK)
415 log_fatal ("zlib problem: %s\n", zs.msg? zs.msg :
416 zrc == Z_MEM_ERROR ? "out of core" :
417 zrc == Z_VERSION_ERROR ?
418 "invalid lib version" :
419 "unknown error" );
421 zinit_done = 1;
423 else
425 #ifdef Z_SYNC_FLUSH
426 zrc = inflate (&zs, Z_SYNC_FLUSH);
427 #else
428 zrc = inflate (&zs, Z_PARTIAL_FLUSH);
429 #endif
430 if (zrc == Z_STREAM_END)
431 ; /* eof */
432 else if (zrc != Z_OK && zrc != Z_BUF_ERROR)
434 if (zs.msg)
435 log_fatal ("zlib inflate problem: %s\n", zs.msg );
436 else
437 log_fatal ("zlib inflate problem: rc=%d\n", zrc );
439 for (n=0; n < outbufsize - zs.avail_out; n++)
441 if (putc (outbuf[n], fpout) == EOF )
442 return 1;
446 while (zrc != Z_STREAM_END && zrc != Z_BUF_ERROR);
447 inflateEnd (&zs);
449 return 0;
452 #ifdef HAVE_BZIP2
453 static int
454 handle_bzip2(int algo,FILE *fpin,FILE *fpout)
456 bz_stream bzs;
457 byte *inbuf, *outbuf;
458 unsigned int inbufsize, outbufsize;
459 int c,zinit_done, zrc, nread, count;
460 size_t n;
462 memset (&bzs, 0, sizeof bzs);
463 inbufsize = 2048;
464 inbuf = xmalloc (inbufsize);
465 outbufsize = 8192;
466 outbuf = xmalloc (outbufsize);
467 bzs.avail_in = 0;
468 zinit_done = 0;
472 if (bzs.avail_in < inbufsize)
474 n = bzs.avail_in;
475 if (!n)
476 bzs.next_in = inbuf;
477 count = inbufsize - n;
478 for (nread=0;
479 nread < count && (c=getc (fpin)) != EOF;
480 nread++)
481 inbuf[n+nread] = c;
483 n += nread;
484 if (nread < count && algo == 1)
486 inbuf[n] = 0xFF; /* chew dummy byte */
487 n++;
489 bzs.avail_in = n;
491 bzs.next_out = outbuf;
492 bzs.avail_out = outbufsize;
494 if (!zinit_done)
496 zrc = BZ2_bzDecompressInit(&bzs,0,0);
497 if (zrc != BZ_OK)
498 log_fatal ("bz2lib problem: %d\n",zrc);
499 zinit_done = 1;
501 else
503 zrc = BZ2_bzDecompress(&bzs);
504 if (zrc == BZ_STREAM_END)
505 ; /* eof */
506 else if (zrc != BZ_OK && zrc != BZ_PARAM_ERROR)
507 log_fatal ("bz2lib inflate problem: %d\n", zrc );
508 for (n=0; n < outbufsize - bzs.avail_out; n++)
510 if (putc (outbuf[n], fpout) == EOF )
511 return 1;
515 while (zrc != BZ_STREAM_END && zrc != BZ_PARAM_ERROR);
516 BZ2_bzDecompressEnd(&bzs);
518 return 0;
520 #endif /* HAVE_BZIP2 */
522 /* hdr must point to a buffer large enough to hold all header bytes */
523 static int
524 write_part ( const char *fname, FILE *fpin, unsigned long pktlen,
525 int pkttype, int partial, unsigned char *hdr, size_t hdrlen)
527 FILE *fpout;
528 int c, first;
529 unsigned char *p;
530 const char *outname = create_filename (pkttype);
532 #if defined(__riscos__) && defined(USE_ZLIBRISCOS)
533 static int initialized = 0;
535 if (!initialized)
536 initialized = riscos_load_module("ZLib", zlib_path, 1);
537 #endif
538 if (opt_no_split)
539 fpout = stdout;
540 else
542 if (opt_verbose)
543 log_info ("writing `%s'\n", outname);
544 fpout = fopen (outname, "wb");
545 if (!fpout)
547 log_error ("error creating `%s': %s\n", outname, strerror(errno));
548 /* stop right now, otherwise we would mess up the sequence
549 of the part numbers */
550 g10_exit (1);
554 if (opt_secret_to_public
555 && (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY))
557 unsigned char *blob = xmalloc (pktlen);
558 int i, len;
560 pkttype = pkttype == PKT_SECRET_KEY? PKT_PUBLIC_KEY:PKT_PUBLIC_SUBKEY;
562 for (i=0; i < pktlen; i++)
564 c = getc (fpin);
565 if (c == EOF)
566 goto read_error;
567 blob[i] = c;
569 len = public_key_length (blob, pktlen);
570 if (!len)
572 log_error ("error calcualting public key length\n");
573 g10_exit (1);
575 if ( (hdr[0] & 0x40) )
577 if (write_new_header (fpout, pkttype, len))
578 goto write_error;
580 else
582 if (write_old_header (fpout, pkttype, len))
583 goto write_error;
586 for (i=0; i < len; i++)
588 if ( putc (blob[i], fpout) == EOF )
589 goto write_error;
592 goto ready;
596 if (!opt_uncompress)
598 for (p=hdr; hdrlen; p++, hdrlen--)
600 if ( putc (*p, fpout) == EOF )
601 goto write_error;
605 first = 1;
606 while (partial)
608 size_t partlen;
610 if (partial == 1)
611 { /* openpgp */
612 if (first )
614 c = pktlen;
615 assert( c >= 224 && c < 255 );
616 first = 0;
618 else if ((c = getc (fpin)) == EOF )
619 goto read_error;
620 else
621 hdr[hdrlen++] = c;
623 if (c < 192)
625 pktlen = c;
626 partial = 0; /* (last segment may follow) */
628 else if (c < 224 )
630 pktlen = (c - 192) * 256;
631 if ((c = getc (fpin)) == EOF)
632 goto read_error;
633 hdr[hdrlen++] = c;
634 pktlen += c + 192;
635 partial = 0;
637 else if (c == 255)
639 if (read_u32 (fpin, &pktlen))
640 goto read_error;
641 hdr[hdrlen++] = pktlen >> 24;
642 hdr[hdrlen++] = pktlen >> 16;
643 hdr[hdrlen++] = pktlen >> 8;
644 hdr[hdrlen++] = pktlen;
645 partial = 0;
647 else
648 { /* next partial body length */
649 for (p=hdr; hdrlen; p++, hdrlen--)
651 if ( putc (*p, fpout) == EOF )
652 goto write_error;
654 partlen = 1 << (c & 0x1f);
655 for (; partlen; partlen--)
657 if ((c = getc (fpin)) == EOF)
658 goto read_error;
659 if ( putc (c, fpout) == EOF )
660 goto write_error;
664 else if (partial == 2)
665 { /* old gnupg */
666 assert (!pktlen);
667 if ( read_u16 (fpin, &partlen) )
668 goto read_error;
669 hdr[hdrlen++] = partlen >> 8;
670 hdr[hdrlen++] = partlen;
671 for (p=hdr; hdrlen; p++, hdrlen--)
673 if ( putc (*p, fpout) == EOF )
674 goto write_error;
676 if (!partlen)
677 partial = 0; /* end of packet */
678 for (; partlen; partlen--)
680 c = getc (fpin);
681 if (c == EOF)
682 goto read_error;
683 if ( putc (c, fpout) == EOF )
684 goto write_error;
687 else
688 { /* compressed: read to end */
689 pktlen = 0;
690 partial = 0;
691 hdrlen = 0;
692 if (opt_uncompress)
694 if ((c = getc (fpin)) == EOF)
695 goto read_error;
697 if(c==1 || c==2)
699 if(handle_zlib(c,fpin,fpout))
700 goto write_error;
702 #ifdef HAVE_BZIP2
703 else if(c==3)
705 if(handle_bzip2(c,fpin,fpout))
706 goto write_error;
708 #endif /* HAVE_BZIP2 */
709 else
711 log_error("invalid compression algorithm (%d)\n",c);
712 goto read_error;
715 else
717 while ( (c=getc (fpin)) != EOF )
719 if ( putc (c, fpout) == EOF )
720 goto write_error;
723 if (!feof (fpin))
724 goto read_error;
728 for (p=hdr; hdrlen; p++, hdrlen--)
730 if ( putc (*p, fpout) == EOF )
731 goto write_error;
734 /* standard packet or last segment of partial length encoded packet */
735 for (; pktlen; pktlen--)
737 c = getc (fpin);
738 if (c == EOF)
739 goto read_error;
740 if ( putc (c, fpout) == EOF )
741 goto write_error;
744 ready:
745 if ( !opt_no_split && fclose (fpout) )
746 log_error ("error closing `%s': %s\n", outname, strerror (errno));
747 return 0;
749 write_error:
750 log_error ("error writing `%s': %s\n", outname, strerror (errno));
751 if (!opt_no_split)
752 fclose (fpout);
753 return 2;
755 read_error:
756 if (!opt_no_split)
758 int save = errno;
759 fclose (fpout);
760 errno = save;
762 return -1;
767 static int
768 do_split (const char *fname, FILE *fp)
770 int c, ctb, pkttype;
771 unsigned long pktlen = 0;
772 int partial = 0;
773 unsigned char header[20];
774 int header_idx = 0;
776 ctb = getc (fp);
777 if (ctb == EOF)
778 return 3; /* ready */
779 header[header_idx++] = ctb;
781 if (!(ctb & 0x80))
783 log_error("invalid CTB %02x\n", ctb );
784 return 1;
786 if ( (ctb & 0x40) )
787 { /* new CTB */
788 pkttype = (ctb & 0x3f);
789 if( (c = getc (fp)) == EOF )
790 return -1;
791 header[header_idx++] = c;
793 if ( c < 192 )
794 pktlen = c;
795 else if ( c < 224 )
797 pktlen = (c - 192) * 256;
798 if( (c = getc (fp)) == EOF )
799 return -1;
800 header[header_idx++] = c;
801 pktlen += c + 192;
803 else if ( c == 255 )
805 if (read_u32 (fp, &pktlen))
806 return -1;
807 header[header_idx++] = pktlen >> 24;
808 header[header_idx++] = pktlen >> 16;
809 header[header_idx++] = pktlen >> 8;
810 header[header_idx++] = pktlen;
812 else
813 { /* partial body length */
814 pktlen = c;
815 partial = 1;
818 else
820 int lenbytes;
822 pkttype = (ctb>>2)&0xf;
823 lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
824 if (!lenbytes )
826 pktlen = 0; /* don't know the value */
827 if( pkttype == PKT_COMPRESSED )
828 partial = 3;
829 else
830 partial = 2; /* the old GnuPG partial length encoding */
832 else
834 for ( ; lenbytes; lenbytes-- )
836 pktlen <<= 8;
837 if( (c = getc (fp)) == EOF )
838 return -1;
839 header[header_idx++] = c;
841 pktlen |= c;
846 return write_part (fname, fp, pktlen, pkttype, partial,
847 header, header_idx);
851 static void
852 split_packets (const char *fname)
854 FILE *fp;
855 int rc;
857 if (!fname || !strcmp (fname, "-"))
859 fp = stdin;
860 fname = "-";
862 else if ( !(fp = fopen (fname,"rb")) )
864 log_error ("can't open `%s': %s\n", fname, strerror (errno));
865 return;
868 while ( !(rc = do_split (fname, fp)) )
870 if ( rc > 0 )
871 ; /* error already handled */
872 else if ( ferror (fp) )
873 log_error ("error reading `%s': %s\n", fname, strerror (errno));
874 else
875 log_error ("premature EOF while reading `%s'\n", fname );
877 if ( fp != stdin )
878 fclose (fp);