123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /*
- *
- * Adobe's encryption/decryption algorithm for eexec and show. Runs in
- * eexec mode unless told otherwise. Use,
- *
- * pscrypt file.cypher > file.clear
- *
- * to decrypt eexec input. Assumes file.cypher is hex with the key as the
- * first four bytes, and writes file.clear as binary (omitting the key).
- * Use
- *
- * pscrypt -e12ab34ef file.clear >file.cypher
- *
- * to encrypt file.clear (for eexec) using 12ab34ef as the key. Input is
- * binary and output is hex. The key must be given as a hex number. Use
- * -sshow to encrypt or decrypt a CharString or Subr,
- *
- * pscrypt -sshow file.cypher > file.clear
- *
- * Use -b or -x to read binary or hex input, and -B or -X to output binary
- * or hex.
- *
- */
- #include <stdio.h>
- #include <ctype.h>
- #define ENCRYPT 0
- #define DECRYPT 1
- #define NOTSET -1
- #define BINARY 0
- #define HEX 1
- #define LINELENGTH 40
- #define CHARSTRING 4330
- #define EEXEC 55665
- #define MAGIC1 52845
- #define MAGIC2 22719
- int argc;
- char **argv;
- int mode = DECRYPT;
- int input = NOTSET;
- int output = NOTSET;
- int outoffset = NOTSET;
- int inoffset = NOTSET;
- int cryptkey = 0; /* encryption key set with -e */
- int linelength = LINELENGTH; /* only for hex output */
- int lastchar = 0;
- unsigned long seed = EEXEC;
- unsigned long key;
- FILE *fp_in = stdin;
- /*****************************************************************************/
- main(agc, agv)
- int agc;
- char *agv[];
- {
- /*
- *
- * Implementation of the encryption/decryption used by eexec and show.
- *
- */
- argc = agc;
- argv = agv;
- options();
- initialize();
- arguments();
- exit(0);
- } /* End of main */
- /*****************************************************************************/
- options()
- {
- int ch;
- char *names = "bde:l:os:xBSX";
- extern char *optarg;
- extern int optind;
- /*
- *
- * Command line options.
- *
- */
- while ( (ch = getopt(argc, argv, names)) != EOF )
- switch ( ch ) {
- case 'b': /* binary input */
- input = BINARY;
- break;
- case 'd': /* decrypt */
- mode = DECRYPT;
- break;
- case 'e': /* encrypt */
- mode = ENCRYPT;
- if ( *optarg == '0' && *optarg == 'x' )
- optarg += 2;
- sscanf(optarg, "%8x", &cryptkey);
- break;
- case 'l': /* line length hex output */
- linelength = atoi(optarg);
- break;
- case 'o': /* output all bytes - debugging */
- outoffset = 0;
- break;
- case 's': /* seed */
- if ( *optarg == 'e' )
- seed = EEXEC;
- else if ( *optarg == 's' )
- seed = CHARSTRING;
- else if ( *optarg == '0' && *(optarg+1) == 'x' )
- sscanf(optarg+2, "%x", &seed);
- else if ( *optarg == '0' )
- sscanf(optarg, "%o", &seed);
- else sscanf(optarg, "%d", &seed);
- break;
- case 'x': /* hex input */
- input = HEX;
- break;
- case 'B': /* binary output */
- output = BINARY;
- break;
- case 'X': /* hex output */
- output = HEX;
- break;
- case '?': /* don't understand the option */
- fprintf(stderr, "bad option -%c\n", ch);
- exit(1);
- break;
- default: /* don't know what to do for ch */
- fprintf(stderr, "missing case for option -%c\n", ch);
- exit(1);
- break;
- } /* End switch */
- argc -= optind; /* get ready for non-option args */
- argv += optind;
- } /* End of options */
- /*****************************************************************************/
- initialize()
- {
- /*
- *
- * Initialization that has to be done after the options.
- *
- */
- key = seed;
- if ( mode == DECRYPT ) {
- input = (input == NOTSET) ? HEX : input;
- output = (output == NOTSET) ? BINARY : output;
- inoffset = (inoffset == NOTSET) ? 0 : inoffset;
- outoffset = (outoffset == NOTSET) ? -4 : outoffset;
- } else {
- input = (input == NOTSET) ? BINARY : input;
- output = (output == NOTSET) ? HEX : output;
- inoffset = (inoffset == NOTSET) ? 4 : inoffset;
- outoffset = (outoffset == NOTSET) ? 0 : outoffset;
- } /* End else */
- if ( linelength <= 0 )
- linelength = LINELENGTH;
- } /* End of initialize */
- /*****************************************************************************/
- arguments()
- {
- /*
- *
- * Everything left is an input file. No arguments or '-' means stdin.
- *
- */
- if ( argc < 1 )
- crypt();
- else
- while ( argc > 0 ) {
- if ( strcmp(*argv, "-") == 0 )
- fp_in = stdin;
- else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
- fprintf(stderr, "can't open %s\n", *argv);
- exit(1);
- } /* End if */
- crypt();
- if ( fp_in != stdin )
- fclose(fp_in);
- argc--;
- argv++;
- } /* End while */
- } /* End of arguments */
- /*****************************************************************************/
- crypt()
- {
- unsigned int cypher;
- unsigned int clear;
- /*
- *
- * Runs the encryption/decryption algorithm.
- *
- */
- while ( lastchar != EOF ) {
- cypher = nextbyte();
- clear = ((key >> 8) ^ cypher) & 0xFF;
- key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
- if ( ++outoffset > 0 && lastchar != EOF ) {
- if ( output == HEX ) {
- printf("%.2X", clear);
- if ( linelength > 0 && (outoffset % linelength) == 0 )
- putchar('\n');
- } else putchar(clear);
- } /* End if */
- } /* End while */
- } /* End of crypt */
- /*****************************************************************************/
- nextbyte()
- {
- int val = EOF;
- /*
- *
- * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
- * positive, otherwise reads (hex or binary) from fp_in.
- *
- */
- if ( inoffset-- > 0 )
- val = (cryptkey >> (inoffset*8)) & 0xFF;
- else if ( input == HEX ) {
- if ( (val = nexthexchar()) != EOF )
- val = (val << 4) | nexthexchar();
- } else if ( input == BINARY )
- val = Getc(fp_in);
- return(val);
- } /* End of nextbyte */
- /*****************************************************************************/
- nexthexchar()
- {
- int ch;
- /*
- *
- * Reads the next hex character.
- *
- */
- while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;
- if ( isdigit(ch) )
- ch -= '0';
- else if ( isupper(ch) )
- ch -= 'A' - 10;
- else if ( islower(ch) )
- ch -= 'a' - 10;
- return(ch);
- } /* End of nexthexchar */
- /*****************************************************************************/
- Getc(fp)
- FILE *fp;
- {
- /*
- *
- * Reads the next byte from *fp, sets lastchar, and returns the character.
- *
- */
- return(lastchar = getc(fp));
- } /* End of Getc */
- /*****************************************************************************/
|