|
|
1.1 root 1: /*
2: *
3: * Adobe's encryption/decryption algorithm for eexec and show. Runs in
4: * eexec mode unless told otherwise. Use,
5: *
6: * pscrypt file.cypher > file.clear
7: *
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).
10: * Use
11: *
12: * pscrypt -e12ab34ef file.clear >file.cypher
13: *
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,
17: *
18: * pscrypt -sshow file.cypher > file.clear
19: *
20: * Use -b or -x to read binary or hex input, and -B or -X to output binary
21: * or hex.
22: *
23: */
24:
25: #include <stdio.h>
26: #include <ctype.h>
27:
28: #define ENCRYPT 0
29: #define DECRYPT 1
30:
31: #define NOTSET -1
32: #define BINARY 0
33: #define HEX 1
34: #define LINELENGTH 40
35:
36: #define CHARSTRING 4330
37: #define EEXEC 55665
38: #define MAGIC1 52845
39: #define MAGIC2 22719
40:
41: int argc;
42: char **argv;
43:
44: int mode = DECRYPT;
45: int input = NOTSET;
46: int output = NOTSET;
47: int outoffset = NOTSET;
48: int inoffset = NOTSET;
49:
50: int cryptkey = 0; /* encryption key set with -e */
51: int linelength = LINELENGTH; /* only for hex output */
52: int lastchar = 0;
53:
54: unsigned long seed = EEXEC;
55: unsigned long key;
56:
57: FILE *fp_in = stdin;
58:
59: /*****************************************************************************/
60:
61: main(agc, agv)
62:
63: int agc;
64: char *agv[];
65:
66: {
67:
68: /*
69: *
70: * Implementation of the encryption/decryption used by eexec and show.
71: *
72: */
73:
74: argc = agc;
75: argv = agv;
76:
77: options();
78: initialize();
79: arguments();
80:
81: exit(0);
82:
83: } /* End of main */
84:
85: /*****************************************************************************/
86:
87: options()
88:
89: {
90:
91: int ch;
92: char *names = "bde:l:os:xBSX";
93:
94: extern char *optarg;
95: extern int optind;
96:
97: /*
98: *
99: * Command line options.
100: *
101: */
102:
103: while ( (ch = getopt(argc, argv, names)) != EOF )
104: switch ( ch ) {
105: case 'b': /* binary input */
106: input = BINARY;
107: break;
108:
109: case 'd': /* decrypt */
110: mode = DECRYPT;
111: break;
112:
113: case 'e': /* encrypt */
114: mode = ENCRYPT;
115: if ( *optarg == '0' && *optarg == 'x' )
116: optarg += 2;
117: sscanf(optarg, "%8x", &cryptkey);
118: break;
119:
120: case 'l': /* line length hex output */
121: linelength = atoi(optarg);
122: break;
123:
124: case 'o': /* output all bytes - debugging */
125: outoffset = 0;
126: break;
127:
128: case 's': /* seed */
129: if ( *optarg == 'e' )
130: seed = EEXEC;
131: else if ( *optarg == 's' )
132: seed = CHARSTRING;
133: else if ( *optarg == '0' && *(optarg+1) == 'x' )
134: sscanf(optarg+2, "%x", &seed);
135: else if ( *optarg == '0' )
136: sscanf(optarg, "%o", &seed);
137: else sscanf(optarg, "%d", &seed);
138: break;
139:
140: case 'x': /* hex input */
141: input = HEX;
142: break;
143:
144: case 'B': /* binary output */
145: output = BINARY;
146: break;
147:
148: case 'X': /* hex output */
149: output = HEX;
150: break;
151:
152: case '?': /* don't understand the option */
153: fprintf(stderr, "bad option -%c\n", ch);
154: exit(1);
155: break;
156:
157: default: /* don't know what to do for ch */
158: fprintf(stderr, "missing case for option -%c\n", ch);
159: exit(1);
160: break;
161: } /* End switch */
162:
163: argc -= optind; /* get ready for non-option args */
164: argv += optind;
165:
166: } /* End of options */
167:
168: /*****************************************************************************/
169:
170: initialize()
171:
172: {
173:
174: /*
175: *
176: * Initialization that has to be done after the options.
177: *
178: */
179:
180: key = seed;
181:
182: if ( mode == DECRYPT ) {
183: input = (input == NOTSET) ? HEX : input;
184: output = (output == NOTSET) ? BINARY : output;
185: inoffset = (inoffset == NOTSET) ? 0 : inoffset;
186: outoffset = (outoffset == NOTSET) ? -4 : outoffset;
187: } else {
188: input = (input == NOTSET) ? BINARY : input;
189: output = (output == NOTSET) ? HEX : output;
190: inoffset = (inoffset == NOTSET) ? 4 : inoffset;
191: outoffset = (outoffset == NOTSET) ? 0 : outoffset;
192: } /* End else */
193:
194: if ( linelength <= 0 )
195: linelength = LINELENGTH;
196:
197: } /* End of initialize */
198:
199: /*****************************************************************************/
200:
201: arguments()
202:
203: {
204:
205: /*
206: *
207: * Everything left is an input file. No arguments or '-' means stdin.
208: *
209: */
210:
211: if ( argc < 1 )
212: crypt();
213: else
214: while ( argc > 0 ) {
215: if ( strcmp(*argv, "-") == 0 )
216: fp_in = stdin;
217: else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
218: fprintf(stderr, "can't open %s\n", *argv);
219: exit(1);
220: } /* End if */
221: crypt();
222: if ( fp_in != stdin )
223: fclose(fp_in);
224: argc--;
225: argv++;
226: } /* End while */
227:
228: } /* End of arguments */
229:
230: /*****************************************************************************/
231:
232: crypt()
233:
234: {
235:
236: unsigned int cypher;
237: unsigned int clear;
238:
239: /*
240: *
241: * Runs the encryption/decryption algorithm.
242: *
243: */
244:
245: while ( lastchar != EOF ) {
246: cypher = nextbyte();
247: clear = ((key >> 8) ^ cypher) & 0xFF;
248: key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
249: if ( ++outoffset > 0 && lastchar != EOF ) {
250: if ( output == HEX ) {
251: printf("%.2X", clear);
252: if ( linelength > 0 && (outoffset % linelength) == 0 )
253: putchar('\n');
254: } else putchar(clear);
255: } /* End if */
256: } /* End while */
257:
258: } /* End of crypt */
259:
260: /*****************************************************************************/
261:
262: nextbyte()
263:
264: {
265:
266: int val = EOF;
267:
268: /*
269: *
270: * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
271: * positive, otherwise reads (hex or binary) from fp_in.
272: *
273: */
274:
275: if ( inoffset-- > 0 )
276: val = (cryptkey >> (inoffset*8)) & 0xFF;
277: else if ( input == HEX ) {
278: if ( (val = nexthexchar()) != EOF )
279: val = (val << 4) | nexthexchar();
280: } else if ( input == BINARY )
281: val = Getc(fp_in);
282:
283: return(val);
284:
285: } /* End of nextbyte */
286:
287: /*****************************************************************************/
288:
289: nexthexchar()
290:
291: {
292:
293: int ch;
294:
295: /*
296: *
297: * Reads the next hex character.
298: *
299: */
300:
301: while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;
302:
303: if ( isdigit(ch) )
304: ch -= '0';
305: else if ( isupper(ch) )
306: ch -= 'A' - 10;
307: else if ( islower(ch) )
308: ch -= 'a' - 10;
309:
310: return(ch);
311:
312: } /* End of nexthexchar */
313:
314: /*****************************************************************************/
315:
316: Getc(fp)
317:
318: FILE *fp;
319:
320: {
321:
322: /*
323: *
324: * Reads the next byte from *fp, sets lastchar, and returns the character.
325: *
326: */
327:
328: return(lastchar = getc(fp));
329:
330: } /* End of Getc */
331:
332: /*****************************************************************************/
333:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.