pscrypt.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. #include <stdio.h>
  25. #include <ctype.h>
  26. #define ENCRYPT 0
  27. #define DECRYPT 1
  28. #define NOTSET -1
  29. #define BINARY 0
  30. #define HEX 1
  31. #define LINELENGTH 40
  32. #define CHARSTRING 4330
  33. #define EEXEC 55665
  34. #define MAGIC1 52845
  35. #define MAGIC2 22719
  36. int argc;
  37. char **argv;
  38. int mode = DECRYPT;
  39. int input = NOTSET;
  40. int output = NOTSET;
  41. int outoffset = NOTSET;
  42. int inoffset = NOTSET;
  43. int cryptkey = 0; /* encryption key set with -e */
  44. int linelength = LINELENGTH; /* only for hex output */
  45. int lastchar = 0;
  46. unsigned long seed = EEXEC;
  47. unsigned long key;
  48. FILE *fp_in = stdin;
  49. /*****************************************************************************/
  50. main(agc, agv)
  51. int agc;
  52. char *agv[];
  53. {
  54. /*
  55. *
  56. * Implementation of the encryption/decryption used by eexec and show.
  57. *
  58. */
  59. argc = agc;
  60. argv = agv;
  61. options();
  62. initialize();
  63. arguments();
  64. exit(0);
  65. } /* End of main */
  66. /*****************************************************************************/
  67. options()
  68. {
  69. int ch;
  70. char *names = "bde:l:os:xBSX";
  71. extern char *optarg;
  72. extern int optind;
  73. /*
  74. *
  75. * Command line options.
  76. *
  77. */
  78. while ( (ch = getopt(argc, argv, names)) != EOF )
  79. switch ( ch ) {
  80. case 'b': /* binary input */
  81. input = BINARY;
  82. break;
  83. case 'd': /* decrypt */
  84. mode = DECRYPT;
  85. break;
  86. case 'e': /* encrypt */
  87. mode = ENCRYPT;
  88. if ( *optarg == '0' && *optarg == 'x' )
  89. optarg += 2;
  90. sscanf(optarg, "%8x", &cryptkey);
  91. break;
  92. case 'l': /* line length hex output */
  93. linelength = atoi(optarg);
  94. break;
  95. case 'o': /* output all bytes - debugging */
  96. outoffset = 0;
  97. break;
  98. case 's': /* seed */
  99. if ( *optarg == 'e' )
  100. seed = EEXEC;
  101. else if ( *optarg == 's' )
  102. seed = CHARSTRING;
  103. else if ( *optarg == '0' && *(optarg+1) == 'x' )
  104. sscanf(optarg+2, "%x", &seed);
  105. else if ( *optarg == '0' )
  106. sscanf(optarg, "%o", &seed);
  107. else sscanf(optarg, "%d", &seed);
  108. break;
  109. case 'x': /* hex input */
  110. input = HEX;
  111. break;
  112. case 'B': /* binary output */
  113. output = BINARY;
  114. break;
  115. case 'X': /* hex output */
  116. output = HEX;
  117. break;
  118. case '?': /* don't understand the option */
  119. fprintf(stderr, "bad option -%c\n", ch);
  120. exit(1);
  121. break;
  122. default: /* don't know what to do for ch */
  123. fprintf(stderr, "missing case for option -%c\n", ch);
  124. exit(1);
  125. break;
  126. } /* End switch */
  127. argc -= optind; /* get ready for non-option args */
  128. argv += optind;
  129. } /* End of options */
  130. /*****************************************************************************/
  131. initialize()
  132. {
  133. /*
  134. *
  135. * Initialization that has to be done after the options.
  136. *
  137. */
  138. key = seed;
  139. if ( mode == DECRYPT ) {
  140. input = (input == NOTSET) ? HEX : input;
  141. output = (output == NOTSET) ? BINARY : output;
  142. inoffset = (inoffset == NOTSET) ? 0 : inoffset;
  143. outoffset = (outoffset == NOTSET) ? -4 : outoffset;
  144. } else {
  145. input = (input == NOTSET) ? BINARY : input;
  146. output = (output == NOTSET) ? HEX : output;
  147. inoffset = (inoffset == NOTSET) ? 4 : inoffset;
  148. outoffset = (outoffset == NOTSET) ? 0 : outoffset;
  149. } /* End else */
  150. if ( linelength <= 0 )
  151. linelength = LINELENGTH;
  152. } /* End of initialize */
  153. /*****************************************************************************/
  154. arguments()
  155. {
  156. /*
  157. *
  158. * Everything left is an input file. No arguments or '-' means stdin.
  159. *
  160. */
  161. if ( argc < 1 )
  162. crypt();
  163. else
  164. while ( argc > 0 ) {
  165. if ( strcmp(*argv, "-") == 0 )
  166. fp_in = stdin;
  167. else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
  168. fprintf(stderr, "can't open %s\n", *argv);
  169. exit(1);
  170. } /* End if */
  171. crypt();
  172. if ( fp_in != stdin )
  173. fclose(fp_in);
  174. argc--;
  175. argv++;
  176. } /* End while */
  177. } /* End of arguments */
  178. /*****************************************************************************/
  179. crypt()
  180. {
  181. unsigned int cypher;
  182. unsigned int clear;
  183. /*
  184. *
  185. * Runs the encryption/decryption algorithm.
  186. *
  187. */
  188. while ( lastchar != EOF ) {
  189. cypher = nextbyte();
  190. clear = ((key >> 8) ^ cypher) & 0xFF;
  191. key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
  192. if ( ++outoffset > 0 && lastchar != EOF ) {
  193. if ( output == HEX ) {
  194. printf("%.2X", clear);
  195. if ( linelength > 0 && (outoffset % linelength) == 0 )
  196. putchar('\n');
  197. } else putchar(clear);
  198. } /* End if */
  199. } /* End while */
  200. } /* End of crypt */
  201. /*****************************************************************************/
  202. nextbyte()
  203. {
  204. int val = EOF;
  205. /*
  206. *
  207. * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
  208. * positive, otherwise reads (hex or binary) from fp_in.
  209. *
  210. */
  211. if ( inoffset-- > 0 )
  212. val = (cryptkey >> (inoffset*8)) & 0xFF;
  213. else if ( input == HEX ) {
  214. if ( (val = nexthexchar()) != EOF )
  215. val = (val << 4) | nexthexchar();
  216. } else if ( input == BINARY )
  217. val = Getc(fp_in);
  218. return(val);
  219. } /* End of nextbyte */
  220. /*****************************************************************************/
  221. nexthexchar()
  222. {
  223. int ch;
  224. /*
  225. *
  226. * Reads the next hex character.
  227. *
  228. */
  229. while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;
  230. if ( isdigit(ch) )
  231. ch -= '0';
  232. else if ( isupper(ch) )
  233. ch -= 'A' - 10;
  234. else if ( islower(ch) )
  235. ch -= 'a' - 10;
  236. return(ch);
  237. } /* End of nexthexchar */
  238. /*****************************************************************************/
  239. Getc(fp)
  240. FILE *fp;
  241. {
  242. /*
  243. *
  244. * Reads the next byte from *fp, sets lastchar, and returns the character.
  245. *
  246. */
  247. return(lastchar = getc(fp));
  248. } /* End of Getc */
  249. /*****************************************************************************/