3 * Adobe's encryption/decryption algorithm for eexec and show. Runs in
4 * eexec mode unless told otherwise. Use,
6 * pscrypt file.cypher > file.clear
8 * to decrypt eexec input. Assumes file.cypher is hex with the key as the
9 * first four bytes, and writes file.clear as binary (omitting the key).
12 * pscrypt -e12ab34ef file.clear >file.cypher
14 * to encrypt file.clear (for eexec) using 12ab34ef as the key. Input is
15 * binary and output is hex. The key must be given as a hex number. Use
16 * -sshow to encrypt or decrypt a CharString or Subr,
18 * pscrypt -sshow file.cypher > file.clear
20 * Use -b or -x to read binary or hex input, and -B or -X to output binary
36 #define CHARSTRING 4330
47 int outoffset = NOTSET;
48 int inoffset = NOTSET;
50 int cryptkey = 0; /* encryption key set with -e */
51 int linelength = LINELENGTH; /* only for hex output */
54 unsigned long seed = EEXEC;
59 /*****************************************************************************/
70 * Implementation of the encryption/decryption used by eexec and show.
87 /*****************************************************************************/
94 char *names = "bde:l:os:xBSX";
101 * Command line options.
105 while ( (ch = getopt(argc, argv, names)) != EOF )
107 case 'b': /* binary input */
111 case 'd': /* decrypt */
115 case 'e': /* encrypt */
117 if ( *optarg == '0' && *optarg == 'x' )
119 sscanf(optarg, "%8x", &cryptkey);
122 case 'l': /* line length hex output */
123 linelength = atoi(optarg);
126 case 'o': /* output all bytes - debugging */
131 if ( *optarg == 'e' )
133 else if ( *optarg == 's' )
135 else if ( *optarg == '0' && *(optarg+1) == 'x' )
136 sscanf(optarg+2, "%x", &seed);
137 else if ( *optarg == '0' )
138 sscanf(optarg, "%o", &seed);
139 else sscanf(optarg, "%d", &seed);
142 case 'x': /* hex input */
146 case 'B': /* binary output */
150 case 'X': /* hex output */
154 case '?': /* don't understand the option */
155 fprintf(stderr, "bad option -%c\n", ch);
159 default: /* don't know what to do for ch */
160 fprintf(stderr, "missing case for option -%c\n", ch);
165 argc -= optind; /* get ready for non-option args */
168 } /* End of options */
170 /*****************************************************************************/
178 * Initialization that has to be done after the options.
184 if ( mode == DECRYPT ) {
185 input = (input == NOTSET) ? HEX : input;
186 output = (output == NOTSET) ? BINARY : output;
187 inoffset = (inoffset == NOTSET) ? 0 : inoffset;
188 outoffset = (outoffset == NOTSET) ? -4 : outoffset;
190 input = (input == NOTSET) ? BINARY : input;
191 output = (output == NOTSET) ? HEX : output;
192 inoffset = (inoffset == NOTSET) ? 4 : inoffset;
193 outoffset = (outoffset == NOTSET) ? 0 : outoffset;
196 if ( linelength <= 0 )
197 linelength = LINELENGTH;
199 } /* End of initialize */
201 /*****************************************************************************/
209 * Everything left is an input file. No arguments or '-' means stdin.
217 if ( strcmp(*argv, "-") == 0 )
219 else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
220 fprintf(stderr, "can't open %s\n", *argv);
224 if ( fp_in != stdin )
230 } /* End of arguments */
232 /*****************************************************************************/
243 * Runs the encryption/decryption algorithm.
247 while ( lastchar != EOF ) {
249 clear = ((key >> 8) ^ cypher) & 0xFF;
250 key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
251 if ( ++outoffset > 0 && lastchar != EOF ) {
252 if ( output == HEX ) {
253 printf("%.2X", clear);
254 if ( linelength > 0 && (outoffset % linelength) == 0 )
256 } else putchar(clear);
262 /*****************************************************************************/
272 * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
273 * positive, otherwise reads (hex or binary) from fp_in.
277 if ( inoffset-- > 0 )
278 val = (cryptkey >> (inoffset*8)) & 0xFF;
279 else if ( input == HEX ) {
280 if ( (val = nexthexchar()) != EOF )
281 val = (val << 4) | nexthexchar();
282 } else if ( input == BINARY )
287 } /* End of nextbyte */
289 /*****************************************************************************/
299 * Reads the next hex character.
303 while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;
307 else if ( isupper(ch) )
309 else if ( islower(ch) )
314 } /* End of nexthexchar */
316 /*****************************************************************************/
326 * Reads the next byte from *fp, sets lastchar, and returns the character.
330 return(lastchar = getc(fp));
334 /*****************************************************************************/