/**************************************************************** * * * ENCRYPT/DECRYPT text file * * * * Uses the C encrypt function to encode a text file. The file * * may be decrypted using the companion DECRYPT program or read * * with the aid of the C decrypt function (if you know the key!) * * * * Program call syntax is: * * * * $ ENCRYPT[/KEY=] infile outfile * * or $ DECRYPT[/KEY=] infile outfile * * * * Any items not given will be prompted for. * * * * The encrypt and decrypt functions work on blocks of 8 bytes * * at a time. The encrypted file is a 512-byte-block "binary" * * file, of which the first two bytes are a key check value, * * consisting of the first two bytes of the encryption of the * * key itself (giving it all would make it possible to find out * * the key from the file). The remainder is 9-byte records, in * * each of which, bytes 1-8 are the encrypted data, and byte 9 * * is the number of encrypted bytes, which will always be 8, * * except for the last record, which may be shorter. * * * * V1.0 January 1986, Chris Doran, Sira Ltd., * * South Hill, Chislehurst, Kent, BR7 5EH, England. * * Tel: +44 1 467 2636, Telex: 896649, Fax: +44 1 467 6515 * * * * Modifications Record: * * ===================== * * * ****************************************************************/ #include TEXT *_pname {"d"}; /* Change to "d" for VAX DECRYPT */ int main(argc,argv) int argc; char **argv; { register FILE infile,outfile; register int i,n; register char *p; static TINY ks[16][8],data[40]; static TINY key[8] = {' ',' ',' ',' ',' ',' ',' ',' '}; static BOOL have_key = NO; static BOOL decrypting; /* Whether to encrypt or decrypt infile is determined by _pname. On some systems (e.g. RSX), _main sets this according to the name by which the task is installed/invoked. On others (e.g. RT-11 and VMS) the compiled value above is used, and one must have two separate programs, differing only in the _pname compile time value. This inconsistency has been SPR'd to Whitesmiths'. In any case, make sure it's spelt in full, in upper case, for error messages, and set "decrypting" flag. */ _pname = (decrypting = (*_pname == 'd')) ? &"DECRYPT" : &"ENCRYPT"; infile = outfile = 0; for (n = 1; (p=argv[n]) != NULL; n++) { if ((i=scnstr(p,'/')) != lenstr(p)) { p += i+1; if (*p != 'k') errexit("IVQUAL, Unrecognised qualifier",p); if (i != 0) { /* Non-null prefix is a filename */ n--; *(p-1) = '\0'; } while (*p != '\0' && *p != '=' && *p != ':') p++; if (*p != '\0') p++; /* Copy key, ignoring single quote ("), double ("") -> single */ for (i = 0; *p != '\0' && i < 8; ) if (*p != '"' || *p++ == *p) key[i++] = *p++; if (i <= 0) errexit("NULKEY,","Missing key specification"); have_key = YES; } else if (!infile) infile = n; else if (!outfile) outfile = n; } argv[0] = &data; if (!infile) { do putstr(STDERR,"\n_From: ",NULL); while ((n=getlin(data,40)) == 1); if(n==0) return(YES); /* ctrl/Z typed to cancel ENCRYPT */ data[n-1] = '\0'; /* Remove trailing LF */ } n = infile; if ((infile = open(argv[n],READ,decrypting)) < 0) errexit("OPNERR, Can't read",argv[n]); if (!have_key) { do putstr(STDERR,"\n_Key: ",NULL); while ((n=getlin(key,8)) == 1); if(n==0) return(YES); /* Ctrl/Z typed to cancel ENCRYPT */ if(key[n-1]=='\n') key[n-1] = ' '; /* Remove trailing LF */ } if (!outfile) { do putstr(STDERR,"\n_To: ",NULL); while ((n=getlin(data,40)) == 1); if(n==0) return(YES); /* ctrl/Z typed to cancel ENCRYPT */ data[n-1] = '\0'; /* Remove trailing LF */ } close(STDIN); close(STDOUT); /* Free LUNs */ n = outfile; if ((outfile = create(argv[n],WRITE,!decrypting)) < 0) errexit("OPNERR, Can't write",argv[n]); /* Only allow upper-case letters in key, because of command line restrictions. */ for (n = 0; n < 8; n++) key[n] = toupper(key[n]); bldks(ks,key); encrypt(key,ks); if (!decrypting) { /* ENCRYPT */ fwrite(outfile,key,2); while ((data[8]=fread(infile,data,8)) > 0) fwrite(outfile,encrypt(data,ks),9); data[8] = 0; fwrite(outfile,data,9); /* Null terminator */ } else { /* DECRYPT */ fread(infile,data,2); if (key[0] != data[0] || key[1] != data[1]) errexit("WRNGKEY,","Wrong key"); while (fread(infile,data,9) > 0 && data[8] != 0) fwrite(outfile,decrypt(data,ks),data[8]); } return(YES); } /* Print error message, in VMS format, and exit with error. */ VOID errexit(s1,s2) TEXT *s1,*s2; { errfmt("\n%%%p-F-%p %p\n",_pname,s1,s2); exit(NO); }