home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / adobeenc.zoo / encrypt.shar / chars.c next >
C/C++ Source or Header  |  1990-10-27  |  5KB  |  246 lines

  1. /*
  2.  * chars.c -- decrypt an Adobe font file of encrypted CharStrings
  3.  *
  4.  * Chris B. Sears
  5.  */
  6. #include <stdio.h>
  7. #include <strings.h>
  8.  
  9. #define TRUE            1
  10. #define FALSE            0
  11.  
  12. int lenIV = 4;            /* CharString salt length */
  13.  
  14. typedef struct {
  15.     char *command;
  16.     int value;
  17. } Command;
  18.  
  19. Command commands[] = {
  20.     { "notdefined_c0",    0 },
  21.     { "hstem",            1 },
  22.     { "notdefined_c2",    2 },
  23.     { "vstem",            3 },
  24.     { "vmoveto",        4 },
  25.     { "chars_rlineto",    5 },
  26.     { "hlineto",        6 },
  27.     { "vlineto",        7 },
  28.     { "rrcurveto",        8 },
  29.     { "chars_closepath",9 },
  30.     { "callsubr",        10 },
  31.     { "return",            11 },
  32.     { "escape",            12 },
  33.     { "hsbw",            13 },
  34.     { "endchar",        14 },
  35.     { "notdefined_c15",    15 },
  36.     { "notdefined_c16",    16 },
  37.     { "notdefined_c17",    17 },
  38.     { "notdefined_c18",    18 },
  39.     { "notdefined_c19",    19 },
  40.     { "notdefined_c20",    20 },
  41.     { "chars_rmoveto",    21 },
  42.     { "hmoveto",        22 },
  43.     { "notdefined_c23",    23 },
  44.     { "notdefined_c24",    24 },
  45.     { "notdefined_c25",    25 },
  46.     { "notdefined_c26",    26 },
  47.     { "notdefined_c27",    27 },
  48.     { "notdefined_c28",    28 },
  49.     { "notdefined_c29",    29 },
  50.     { "vhcurveto",        30 },
  51.     { "hvcurveto",        31 }
  52. };
  53.  
  54. Command escapes[] = {
  55.     { "dotsection",        0 },
  56.     { "vstem3",            1 },
  57.     { "hstem3",            2 },
  58.     { "notdefined_e3",    3 },
  59.     { "notdefined_e4",    4 },
  60.     { "notdefined_e5",    5 },
  61.     { "seac",            6 },
  62.     { "sbw",            7 },
  63.     { "notdefined_e8",    8 },
  64.     { "notdefined_e9",    9 },
  65.     { "notdefined_e10",    10 },
  66.     { "notdefined_e11",    11 },
  67.     { "chars_div",        12 },
  68.     { "notdefined_e13",    13 },
  69.     { "notdefined_e14",    14 },
  70.     { "notdefined_e15",    15 },
  71.     { "callothersubr",    16 },
  72.     { "chars_pop",        17 },
  73.     { "notdefined_e18",    18 },
  74.     { "notdefined_e19",    19 },
  75.     { "notdefined_e20",    20 },
  76.     { "notdefined_e21",    21 },
  77.     { "notdefined_e22",    22 },
  78.     { "notdefined_e23",    23 },
  79.     { "notdefined_e24",    24 },
  80.     { "notdefined_e25",    25 },
  81.     { "notdefined_e26",    26 },
  82.     { "notdefined_e27",    27 },
  83.     { "notdefined_e28",    28 },
  84.     { "notdefined_e29",    29 },
  85.     { "notdefined_e30",    30 },
  86.     { "notdefined_e31",    31 },
  87.     { "notdefined_e32",    32 },
  88.     { "setcurrentpoint",33 }
  89. };
  90.  
  91. #define MAX_ESCAPE        33
  92.  
  93. #define CR                4330
  94. #define CC1                52845
  95. #define CC2                22719
  96.  
  97. unsigned short int cr, cc1, cc2;
  98.  
  99. unsigned char
  100. DeCrypt(cipher)
  101.     unsigned char cipher;
  102. {
  103.     unsigned char plain;
  104.  
  105.     plain = (cipher ^ (cr >> 8));
  106.     cr = (cipher + cr) * cc1 + cc2;
  107.  
  108.     return plain;
  109. }
  110.  
  111. void
  112. main(argc, argv)
  113.     int argc;
  114.     char **argv;
  115. {
  116.     FILE *in, *out;
  117.     unsigned char in_buff[BUFSIZ], byte, *rd_pos, *count_pos;
  118.     int in_size, line_pos, i, count;
  119.     long value;
  120.  
  121.     if (argc != 3) {
  122.         fprintf(stderr, "Usage: %s input output\n", argv[0]);
  123.         exit(0);
  124.     }
  125.  
  126.     if ((in = fopen(argv[1], "r")) == NULL) {
  127.         fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
  128.         exit(0);
  129.     }
  130.  
  131.     out = fopen(argv[2], "w");
  132.  
  133.     setbuf(out, NULL);
  134.  
  135.     /*
  136.      * TODO: rewrite this so as not to use a seek and to use stdin.
  137.      */
  138.     for (;;) {
  139.         line_pos = ftell(in);
  140.  
  141.         if (fgets(in_buff, BUFSIZ, in) == NULL)
  142.             break;
  143.         in_size = strlen(in_buff) - 1;
  144.  
  145.         if (strncmp("/lenIV", in_buff, 6) == 0)
  146.             lenIV = atoi(in_buff + 7);
  147.  
  148.         if ((rd_pos = (unsigned char *) strstr(in_buff, " RD ")) == NULL) {
  149.             fputs(in_buff, out);
  150.             continue;
  151.         }
  152.  
  153.         /*
  154.          * We found an encrypted CharString.
  155.          * Back up and determine the number of encrypted characters.
  156.          * These have the form: dup 105 9 RD 9bytesofdata noaccess put
  157.          */
  158.         for (count_pos = rd_pos - 1;
  159.             (count_pos >= in_buff) && (*count_pos != ' ');
  160.             count_pos--)
  161.                 ;
  162.  
  163.         if (*count_pos == ' ')    /* This can be at the beginning of a line */
  164.             count_pos++;
  165.  
  166.         /*
  167.          * Write out the beginning of the string without the RD stuff.
  168.          */
  169.         fwrite(in_buff, count_pos - in_buff, 1, out);
  170.         fprintf(out, "{");
  171.  
  172.         count = atoi(count_pos);
  173.  
  174.         /*
  175.          * Seek to and read the binary data.
  176.          */
  177.         fseek(in, line_pos + (rd_pos - in_buff) + 4, SEEK_SET);
  178.         fread(in_buff, BUFSIZ, 1, in);
  179.  
  180.         /*
  181.          * We must restart the decryption machinery for each CharString.
  182.          */
  183.         cr = CR;
  184.         cc1 = CC1;
  185.         cc2 = CC2;
  186.  
  187.         /*
  188.          * Skip over the salt.
  189.          */
  190.         for (i = 0; i < lenIV; i++)
  191.             byte = DeCrypt(in_buff[i]);
  192.  
  193.         /*
  194.          * Translate the buffer.
  195.          */
  196.         for (; i < count;) {
  197.             byte = DeCrypt(in_buff[i++]);
  198.             if (byte == 11) {            /* return */
  199.                 fprintf(out, " %s", commands[byte].command);
  200.                 break;
  201.             } else if (byte == 12) {    /* escape */
  202.                 byte = DeCrypt(in_buff[i++]);
  203.                 if (byte > MAX_ESCAPE)
  204.                     fprintf(out, " not_defined_e%d", byte);
  205.                 else
  206.                     fprintf(out, " %s", escapes[byte].command);
  207.                 continue;
  208.             } else if (byte < 32)
  209.                 fprintf(out, " %s", commands[byte].command);
  210.  
  211.             if (byte >= 32) {
  212.                 if (byte <= 246)
  213.                     fprintf(out, " %d", byte  - 139);
  214.                 else if ((byte >= 247) && (byte <= 250))
  215.                     fprintf(out, " %d",
  216.                         (byte  - 247) * 256 + DeCrypt(in_buff[i++]) + 108);
  217.                 else if ((byte >= 251) && (byte <= 254))
  218.                     fprintf(out, " %d",
  219.                         -(byte  - 251) * 256 - DeCrypt(in_buff[i++]) - 108);
  220.                 else if (byte == 255) {
  221.                     value = DeCrypt(in_buff[i++]);
  222.                     value <<= 8;
  223.                     value += DeCrypt(in_buff[i++]);
  224.                     value <<= 8;
  225.                     value += DeCrypt(in_buff[i++]);
  226.                     value <<= 8;
  227.                     value += DeCrypt(in_buff[i++]);
  228.                     fprintf(out, " %d", value);
  229.                 }
  230.             }
  231.         }
  232.  
  233.         fprintf(out, " }");
  234.  
  235.         /*
  236.          * Seek just past the CharString bytes and continue.
  237.          */
  238.         fseek(in, line_pos + (rd_pos - in_buff) + 4 + i, SEEK_SET);
  239.     }
  240.  
  241.     fclose(in);
  242.     fclose(out);
  243.  
  244.     exit(0);
  245. }
  246.