home *** CD-ROM | disk | FTP | other *** search
- /*
- * chars.c -- decrypt an Adobe font file of encrypted CharStrings
- *
- * Chris B. Sears
- */
- #include <stdio.h>
- #include <strings.h>
-
- #define TRUE 1
- #define FALSE 0
-
- int lenIV = 4; /* CharString salt length */
-
- typedef struct {
- char *command;
- int value;
- } Command;
-
- Command commands[] = {
- { "notdefined_c0", 0 },
- { "hstem", 1 },
- { "notdefined_c2", 2 },
- { "vstem", 3 },
- { "vmoveto", 4 },
- { "chars_rlineto", 5 },
- { "hlineto", 6 },
- { "vlineto", 7 },
- { "rrcurveto", 8 },
- { "chars_closepath",9 },
- { "callsubr", 10 },
- { "return", 11 },
- { "escape", 12 },
- { "hsbw", 13 },
- { "endchar", 14 },
- { "notdefined_c15", 15 },
- { "notdefined_c16", 16 },
- { "notdefined_c17", 17 },
- { "notdefined_c18", 18 },
- { "notdefined_c19", 19 },
- { "notdefined_c20", 20 },
- { "chars_rmoveto", 21 },
- { "hmoveto", 22 },
- { "notdefined_c23", 23 },
- { "notdefined_c24", 24 },
- { "notdefined_c25", 25 },
- { "notdefined_c26", 26 },
- { "notdefined_c27", 27 },
- { "notdefined_c28", 28 },
- { "notdefined_c29", 29 },
- { "vhcurveto", 30 },
- { "hvcurveto", 31 }
- };
-
- Command escapes[] = {
- { "dotsection", 0 },
- { "vstem3", 1 },
- { "hstem3", 2 },
- { "notdefined_e3", 3 },
- { "notdefined_e4", 4 },
- { "notdefined_e5", 5 },
- { "seac", 6 },
- { "sbw", 7 },
- { "notdefined_e8", 8 },
- { "notdefined_e9", 9 },
- { "notdefined_e10", 10 },
- { "notdefined_e11", 11 },
- { "chars_div", 12 },
- { "notdefined_e13", 13 },
- { "notdefined_e14", 14 },
- { "notdefined_e15", 15 },
- { "callothersubr", 16 },
- { "chars_pop", 17 },
- { "notdefined_e18", 18 },
- { "notdefined_e19", 19 },
- { "notdefined_e20", 20 },
- { "notdefined_e21", 21 },
- { "notdefined_e22", 22 },
- { "notdefined_e23", 23 },
- { "notdefined_e24", 24 },
- { "notdefined_e25", 25 },
- { "notdefined_e26", 26 },
- { "notdefined_e27", 27 },
- { "notdefined_e28", 28 },
- { "notdefined_e29", 29 },
- { "notdefined_e30", 30 },
- { "notdefined_e31", 31 },
- { "notdefined_e32", 32 },
- { "setcurrentpoint",33 }
- };
-
- #define MAX_ESCAPE 33
-
- #define CR 4330
- #define CC1 52845
- #define CC2 22719
-
- unsigned short int cr, cc1, cc2;
-
- unsigned char
- DeCrypt(cipher)
- unsigned char cipher;
- {
- unsigned char plain;
-
- plain = (cipher ^ (cr >> 8));
- cr = (cipher + cr) * cc1 + cc2;
-
- return plain;
- }
-
- void
- main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *in, *out;
- unsigned char in_buff[BUFSIZ], byte, *rd_pos, *count_pos;
- int in_size, line_pos, i, count;
- long value;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s input output\n", argv[0]);
- exit(0);
- }
-
- if ((in = fopen(argv[1], "r")) == NULL) {
- fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
- exit(0);
- }
-
- out = fopen(argv[2], "w");
-
- setbuf(out, NULL);
-
- /*
- * TODO: rewrite this so as not to use a seek and to use stdin.
- */
- for (;;) {
- line_pos = ftell(in);
-
- if (fgets(in_buff, BUFSIZ, in) == NULL)
- break;
- in_size = strlen(in_buff) - 1;
-
- if (strncmp("/lenIV", in_buff, 6) == 0)
- lenIV = atoi(in_buff + 7);
-
- if ((rd_pos = (unsigned char *) strstr(in_buff, " RD ")) == NULL) {
- fputs(in_buff, out);
- continue;
- }
-
- /*
- * We found an encrypted CharString.
- * Back up and determine the number of encrypted characters.
- * These have the form: dup 105 9 RD 9bytesofdata noaccess put
- */
- for (count_pos = rd_pos - 1;
- (count_pos >= in_buff) && (*count_pos != ' ');
- count_pos--)
- ;
-
- if (*count_pos == ' ') /* This can be at the beginning of a line */
- count_pos++;
-
- /*
- * Write out the beginning of the string without the RD stuff.
- */
- fwrite(in_buff, count_pos - in_buff, 1, out);
- fprintf(out, "{");
-
- count = atoi(count_pos);
-
- /*
- * Seek to and read the binary data.
- */
- fseek(in, line_pos + (rd_pos - in_buff) + 4, SEEK_SET);
- fread(in_buff, BUFSIZ, 1, in);
-
- /*
- * We must restart the decryption machinery for each CharString.
- */
- cr = CR;
- cc1 = CC1;
- cc2 = CC2;
-
- /*
- * Skip over the salt.
- */
- for (i = 0; i < lenIV; i++)
- byte = DeCrypt(in_buff[i]);
-
- /*
- * Translate the buffer.
- */
- for (; i < count;) {
- byte = DeCrypt(in_buff[i++]);
- if (byte == 11) { /* return */
- fprintf(out, " %s", commands[byte].command);
- break;
- } else if (byte == 12) { /* escape */
- byte = DeCrypt(in_buff[i++]);
- if (byte > MAX_ESCAPE)
- fprintf(out, " not_defined_e%d", byte);
- else
- fprintf(out, " %s", escapes[byte].command);
- continue;
- } else if (byte < 32)
- fprintf(out, " %s", commands[byte].command);
-
- if (byte >= 32) {
- if (byte <= 246)
- fprintf(out, " %d", byte - 139);
- else if ((byte >= 247) && (byte <= 250))
- fprintf(out, " %d",
- (byte - 247) * 256 + DeCrypt(in_buff[i++]) + 108);
- else if ((byte >= 251) && (byte <= 254))
- fprintf(out, " %d",
- -(byte - 251) * 256 - DeCrypt(in_buff[i++]) - 108);
- else if (byte == 255) {
- value = DeCrypt(in_buff[i++]);
- value <<= 8;
- value += DeCrypt(in_buff[i++]);
- value <<= 8;
- value += DeCrypt(in_buff[i++]);
- value <<= 8;
- value += DeCrypt(in_buff[i++]);
- fprintf(out, " %d", value);
- }
- }
- }
-
- fprintf(out, " }");
-
- /*
- * Seek just past the CharString bytes and continue.
- */
- fseek(in, line_pos + (rd_pos - in_buff) + 4 + i, SEEK_SET);
- }
-
- fclose(in);
- fclose(out);
-
- exit(0);
- }
-