/* CryptTest.c 
    D. Swinehart September 7, 1982  5:31 PM
    L. Stewart October 20, 1982  9:31 PM
    L. Stewart December 27, 1982  2:58 PM
      flush nested declarations
    L. Stewart January 1, 1983  4:10 PM
      flush AllocZero
    L. Stewart January 3, 1983  1:14 PM
      flush CStringToString
    L. Stewart March 6, 1983  4:39 PM
      return of CStringToString
 */

#include <Alloc.h>
#include <Queue.h>
#include <Ec.h>
#include <Env.h>
#include <Signal.h>
#include <rpc.h>
#include <rpcinternal.h>
#include <rpclupine.h>
#include <RPCBind.h>
#include <encrypt.h>

extern AddToDispatcherSpecs();
extern AddType();
extern dBlock();
extern int *Allocate();
extern struct ShortSTRING *CStringToString();
extern Block();
extern CallContext();
extern int CallFormatted();
extern CallSwat();
extern int CONT();
extern Dismiss();
extern Free();
extern int ExportFailed;
extern ExportInterface();
extern InitOS();
extern int ImportFailed;
extern int ImportInterface();
extern struct VersionRange *matchAllVersions;
extern Move2();
extern MoveBlock();
extern int mySoc;
extern RPCInitialize();
extern RPCInitializeCtx();
extern int *StartDispatcherSpecs();
extern StartNProcess();
extern int StdDispatcher();
extern Zero();

extern ReadCalendar();
extern int largest, totAv, routSent, routRcvd, calSent, calRcvd;
extern struct ZN *sysZone;
extern struct EncryptionKey nullKeyB;

static struct Queue ctxQ;
static int/*BOOL*/ running;
static int/*BOOL*/ beUser;
static int/*BOOL*/ beServer;
static struct ShortSTRING *retRope;
static struct ShortSTRING *srvr, *usr;

static struct ShortSTRING *spNl, *spWd, *spSt, *spSt2, *spSq;
static int remote;
static struct Conversation *shhhh;

/* RPC Procedure indices */
#define NullCrypt 	4
#define EZCrypt 	5
#define CheckCrypt 	6

extern/*forward*/ Client();
int key[4];
int nullK[4];
int nullSeed[4];
int unenc[20];


Main() {
  srvr = usr = 0;
  shhhh = unencrypted;
  InitOS(); /* Sets up sysZone */
  Zero(&ctxQ, 2);
  RPCInitialize(&ctxQ);
  spNl = (struct ShortSTRING *) Allocate(sysZone, 2);
  spSq = CStringToString("K");
  Zero(nullK, 4); Zero(nullSeed, 4);
  CorrectParity(nullK);
  StuffBlock(key, CStringToString("8765DEF043219ABC"));
  CorrectParity(key);
  StartNProcess("client", &ctxQ, &Client, 350, 90); /* ?? */
  while (true) { CallContext(ctxQ.head); }; };

StuffBlock(key, string) char key[]; struct ShortSTRING *string; {
	int i;
	for (i=0; i<((string->length)/2); ++i)
		key[i] = (Hex(string->text[i*2])<<4)+Hex(string->text[i*2+1]); };

int Hex(c) int c; {
	if (c<'A') return (c-'0');
	return (10+(c-'A')); };

static int time[2];
static struct ImportInstance handle[1];
static struct Seal sl;
static struct InterfaceName *clientInterface;
static struct ShortSTRING *tibet;
static struct ShortSTRING *seqRope;
static int *res;
static int teddyMode; /* Silent, but fast. */
int args[10];

static Client() {
  	int c, go;
  while (true) {
  	go=false; remote=false; teddyMode=false;
	Wf("\r.");
	c = MyGetChar();
	putchar(c);
	switch (c) {
	  case 'i': remote = true; Initialize(); break;
	  case 'b': Bind(); break
	  case '1':
		res=CallFormatted(handle, NullCrypt, spNl, spSq, 0);
		DecryptBlock(nullK, &res[1], unenc);
		Wf2("res, unenc = %xH, %xH\n", res, unenc);
		res=res;
		break;
	  case '2':
  		res = CallFormatted(handle, EZCrypt, spNl, spSq, 0);
		DecryptBlock(key, &res[1], unenc);
		Wf2("res, unenc = %xH, %xH\n", &res[1], unenc);
		res=res;
		break;
	  case '3':
  		res = CallFormatted(handle, CheckCrypt, spNl, spSq, 0);
		CBCCheckDecrypt(key, 4, &res[1], unenc, nullSeed);
		Wf2("res, unenc = %xH, %xH\n", res, unenc);
		res=res;
		break;
	  default: Wf(" ?? "); break; }; }; };

static int MyGetChar() {
	while (!chav()) Block();
	return getchar(); };

static Initialize() {
  RPCInitializeCtx(true);
  AddType('Z', 0);
  AddType('K', dBlock(16, 1, 0, true, false)); /* Word Sequence, no byte swaps */
  Zero(handle, lenImportInstance);
  clientInterface = (struct InterfaceName *) Allocate(sysZone, lenInterfaceName);
  clientInterface->type = CStringToString("Authenticator.Lark");
  clientInterface->instance = usr;
  Move2(&clientInterface->version, matchAllVersions);
  tibet = CStringToString("This rope went to Everest");
  seqRope = CStringToString("This is really a sequence"); };

static Bind () {
  { /* Implicit loop until ENABLE succeeds */
  int serverMachine;
  serverMachine = 0;
  if (ENABLE(ImportFailed, &CONT, &sl))
	CallSwat(ecPup1+100);
  ImportInterface(serverMachine, clientInterface, handle); }; /* endloop */ };