/*
 *
 * Adobe's encryption/decryption algorithm for eexec and show. Runs in
 * eexec mode unless told otherwise. Use,
 *
 *		pscrypt file.cypher > file.clear
 *
 * to decrypt eexec input. Assumes file.cypher is hex with the key as the
 * first four bytes, and writes file.clear as binary (omitting the key).
 * Use
 *
 *		pscrypt -e12ab34ef file.clear >file.cypher
 *
 * to encrypt file.clear (for eexec) using 12ab34ef as the key. Input is
 * binary and output is hex. The key must be given as a hex number. Use
 * -sshow to encrypt or decrypt a CharString or Subr,
 *
 *		pscrypt -sshow file.cypher > file.clear
 *
 * Use -b or -x to read binary or hex input, and -B or -X to output binary
 * or hex.
 *
 */

#include <stdio.h>
#include <ctype.h>

#define ENCRYPT		0
#define DECRYPT		1

#define NOTSET		-1
#define BINARY		0
#define HEX		1
#define LINELENGTH	40

#define CHARSTRING	4330
#define EEXEC		55665
#define MAGIC1		52845
#define MAGIC2		22719

int	argc;
char	**argv;

int	mode = DECRYPT;
int	input = NOTSET;
int	output = NOTSET;
int	outoffset = NOTSET;
int	inoffset = NOTSET;

int	cryptkey = 0;			/* encryption key set with -e */
int	linelength = LINELENGTH;	/* only for hex output */
int	lastchar = 0;

unsigned long	seed = EEXEC;
unsigned long	key;

FILE	*fp_in;

/*****************************************************************************/

main(agc, agv)

    int		agc;
    char	*agv[];

{

/*
 *
 * Implementation of the encryption/decryption used by eexec and show.
 *
 */

    argc = agc;
    argv = agv;

    fp_in = stdin;

    options();
    initialize();
    arguments();

    exit(0);

}   /* End of main */

/*****************************************************************************/

options()

{

    int		ch;
    char	*names = "bde:l:os:xBSX";

    extern char	*optarg;
    extern int	optind;

/*
 *
 * Command line options.
 *
 */

    while ( (ch = getopt(argc, argv, names)) != EOF )
	switch ( ch ) {
	    case 'b':			/* binary input */
		    input = BINARY;
		    break;

	    case 'd':			/* decrypt */
		    mode = DECRYPT;
		    break;

	    case 'e':			/* encrypt */
		    mode = ENCRYPT;
		    if ( *optarg == '0' && *optarg == 'x' )
			optarg += 2;
		    sscanf(optarg, "%8x", &cryptkey);
		    break;

	    case 'l':			/* line length hex output */
		    linelength = atoi(optarg);
		    break;

	    case 'o':			/* output all bytes - debugging */
		    outoffset = 0;
		    break;

	    case 's':			/* seed */
		    if ( *optarg == 'e' )
			seed = EEXEC;
		    else if ( *optarg == 's' )
			seed = CHARSTRING;
		    else if ( *optarg == '0' && *(optarg+1) == 'x' )
			sscanf(optarg+2, "%x", &seed);
		    else if ( *optarg == '0' )
			sscanf(optarg, "%o", &seed);
		    else sscanf(optarg, "%d", &seed);
		    break;

	    case 'x':			/* hex input */
		    input = HEX;
		    break;

	    case 'B':			/* binary output */
		    output = BINARY;
		    break;

	    case 'X':			/* hex output */
		    output = HEX;
		    break;

	    case '?':			/* don't understand the option */
		    fprintf(stderr, "bad option -%c\n", ch);
		    exit(1);
		    break;

	    default:			/* don't know what to do for ch */
		    fprintf(stderr, "missing case for option -%c\n", ch);
		    exit(1);
		    break;
	}   /* End switch */

    argc -= optind;			/* get ready for non-option args */
    argv += optind;

}   /* End of options */

/*****************************************************************************/

initialize()

{

/*
 *
 * Initialization that has to be done after the options.
 *
 */

    key = seed;

    if ( mode == DECRYPT ) {
	input = (input == NOTSET) ? HEX : input;
	output = (output == NOTSET) ? BINARY : output;
	inoffset = (inoffset == NOTSET) ? 0 : inoffset;
	outoffset = (outoffset == NOTSET) ? -4 : outoffset;
    } else {
	input = (input == NOTSET) ? BINARY : input;
	output = (output == NOTSET) ? HEX : output;
	inoffset = (inoffset == NOTSET) ? 4 : inoffset;
	outoffset = (outoffset == NOTSET) ? 0 : outoffset;
    }	/* End else */

    if ( linelength <= 0 )
	linelength = LINELENGTH;

}   /* End of initialize */

/*****************************************************************************/

arguments()

{

/*
 *
 * Everything left is an input file. No arguments or '-' means stdin.
 *
 */

    if ( argc < 1 )
	crypt();
    else
	while ( argc > 0 ) {
	    if ( strcmp(*argv, "-") == 0 )
		fp_in = stdin;
	    else if ( (fp_in = fopen(*argv, "r")) == NULL ) {
		fprintf(stderr, "can't open %s\n", *argv);
		exit(1);
	    }	/* End if */
	    crypt();
	    if ( fp_in != stdin )
		fclose(fp_in);
	    argc--;
	    argv++;
	}   /* End while */

}   /* End of arguments */

/*****************************************************************************/

crypt()

{

    unsigned int	cypher;
    unsigned int	clear;

/*
 *
 * Runs the encryption/decryption algorithm.
 *
 */

    while ( lastchar != EOF ) {
	cypher = nextbyte();
	clear = ((key >> 8) ^ cypher) & 0xFF;
	key = (key + (mode == DECRYPT ? cypher : clear)) * MAGIC1 + MAGIC2;
	if ( ++outoffset > 0 && lastchar != EOF ) {
	    if ( output == HEX ) {
		printf("%.2X", clear);
		if ( linelength > 0 && (outoffset % linelength) == 0 )
		    putchar('\n');
	    } else putchar(clear);
	}   /* End if */
    }	/* End while */

}   /* End of crypt */

/*****************************************************************************/

nextbyte()

{

    int		val = EOF;

/*
 *
 * Returns the next byte. Uses cryptkey (i.e. what followed -e) while inoffset is
 * positive, otherwise reads (hex or binary) from fp_in.
 *
 */

    if ( inoffset-- > 0 )
	val = (cryptkey >> (inoffset*8)) & 0xFF;
    else if ( input == HEX ) {
	if ( (val = nexthexchar()) != EOF )
	    val = (val << 4) | nexthexchar();
    } else if ( input == BINARY )
	val = Getc(fp_in);

    return(val);

}   /* End of nextbyte */

/*****************************************************************************/

nexthexchar()

{

    int		ch;

/*
 *
 * Reads the next hex character.
 *
 */

    while ( (ch = Getc(fp_in)) != EOF && ! isxdigit(ch) ) ;

    if ( isdigit(ch) )
	ch -= '0';
    else if ( isupper(ch) )
	ch -= 'A' - 10;
    else if ( islower(ch) )
	ch -= 'a' - 10;

    return(ch);

}   /* End of nexthexchar */

/*****************************************************************************/

Getc(fp)

    FILE	*fp;

{

/*
 *
 * Reads the next byte from *fp, sets lastchar, and returns the character.
 *
 */

    return(lastchar = getc(fp));

}   /* End of Getc */

/*****************************************************************************/

