pscrypt.c (6547B)
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; 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 fp_in = stdin; 78 79 options(); 80 initialize(); 81 arguments(); 82 83 exit(0); 84 85 } /* End of main */ 86 87 /*****************************************************************************/ 88 89 options() 90 91 { 92 93 int ch; 94 char *names = "bde:l:os:xBSX"; 95 96 extern char *optarg; 97 extern int optind; 98 99 /* 100 * 101 * Command line options. 102 * 103 */ 104 105 while ( (ch = getopt(argc, argv, names)) != EOF ) 106 switch ( ch ) { 107 case 'b': /* binary input */ 108 input = BINARY; 109 break; 110 111 case 'd': /* decrypt */ 112 mode = DECRYPT; 113 break; 114 115 case 'e': /* encrypt */ 116 mode = ENCRYPT; 117 if ( *optarg == '0' && *optarg == 'x' ) 118 optarg += 2; 119 sscanf(optarg, "%8x", &cryptkey); 120 break; 121 122 case 'l': /* line length hex output */ 123 linelength = atoi(optarg); 124 break; 125 126 case 'o': /* output all bytes - debugging */ 127 outoffset = 0; 128 break; 129 130 case 's': /* seed */ 131 if ( *optarg == 'e' ) 132 seed = EEXEC; 133 else if ( *optarg == 's' ) 134 seed = CHARSTRING; 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); 140 break; 141 142 case 'x': /* hex input */ 143 input = HEX; 144 break; 145 146 case 'B': /* binary output */ 147 output = BINARY; 148 break; 149 150 case 'X': /* hex output */ 151 output = HEX; 152 break; 153 154 case '?': /* don't understand the option */ 155 fprintf(stderr, "bad option -%c\n", ch); 156 exit(1); 157 break; 158 159 default: /* don't know what to do for ch */ 160 fprintf(stderr, "missing case for option -%c\n", ch); 161 exit(1); 162 break; 163 } /* End switch */ 164 165 argc -= optind; /* get ready for non-option args */ 166 argv += optind; 167 168 } /* End of options */ 169 170 /*****************************************************************************/ 171 172 initialize() 173 174 { 175 176 /* 177 * 178 * Initialization that has to be done after the options. 179 * 180 */ 181 182 key = seed; 183 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; 189 } else { 190 input = (input == NOTSET) ? BINARY : input; 191 output = (output == NOTSET) ? HEX : output; 192 inoffset = (inoffset == NOTSET) ? 4 : inoffset; 193 outoffset = (outoffset == NOTSET) ? 0 : outoffset; 194 } /* End else */ 195 196 if ( linelength <= 0 ) 197 linelength = LINELENGTH; 198 199 } /* End of initialize */ 200 201 /*****************************************************************************/ 202 203 arguments() 204 205 { 206 207 /* 208 * 209 * Everything left is an input file. No arguments or '-' means stdin. 210 * 211 */ 212 213 if ( argc < 1 ) 214 crypt(); 215 else 216 while ( argc > 0 ) { 217 if ( strcmp(*argv, "-") == 0 ) 218 fp_in = stdin; 219 else if ( (fp_in = fopen(*argv, "r")) == NULL ) { 220 fprintf(stderr, "can't open %s\n", *argv); 221 exit(1); 222 } /* End if */ 223 crypt(); 224 if ( fp_in != stdin ) 225 fclose(fp_in); 226 argc--; 227 argv++; 228 } /* End while */ 229 230 } /* End of arguments */ 231 232 /*****************************************************************************/ 233 234 crypt() 235 236 { 237 238 unsigned int cypher; 239 unsigned int clear; 240 241 /* 242 * 243 * Runs the encryption/decryption algorithm. 244 * 245 */ 246 247 while ( lastchar != EOF ) { 248 cypher = nextbyte(); 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 ) 255 putchar('\n'); 256 } else putchar(clear); 257 } /* End if */ 258 } /* End while */ 259 260 } /* End of crypt */ 261 262 /*****************************************************************************/ 263 264 nextbyte() 265 266 { 267 268 int val = EOF; 269 270 /* 271 * 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. 274 * 275 */ 276 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 ) 283 val = Getc(fp_in); 284 285 return(val); 286 287 } /* End of nextbyte */ 288 289 /*****************************************************************************/ 290 291 nexthexchar() 292 293 { 294 295 int ch; 296 297 /* 298 * 299 * Reads the next hex character. 300 * 301 */ 302 303 while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ; 304 305 if ( isdigit(ch) ) 306 ch -= '0'; 307 else if ( isupper(ch) ) 308 ch -= 'A' - 10; 309 else if ( islower(ch) ) 310 ch -= 'a' - 10; 311 312 return(ch); 313 314 } /* End of nexthexchar */ 315 316 /*****************************************************************************/ 317 318 Getc(fp) 319 320 FILE *fp; 321 322 { 323 324 /* 325 * 326 * Reads the next byte from *fp, sets lastchar, and returns the character. 327 * 328 */ 329 330 return(lastchar = getc(fp)); 331 332 } /* End of Getc */ 333 334 /*****************************************************************************/