//
//p-crypt.c
//
//Cryptographic pipe
//
//
//
//-UserX 2001/11/13

#include <stdlib.h>

#include "base/dblock.h"
#include "base/mem.h"
#include "pipe/crypt.h"
#include "pipe/c-stream.h"
#include "pipe/cs-iip1.h"
#include "base/str.h"

#include "net/sock.h"

PipeCrypt blankpipecrypt = BLANKPIPECRYPT;


Pipe *pipecryptMake(char *pipename, char *options) {
	PipeCrypt *pc = memCopy(&blankpipecrypt, sizeof(PipeCrypt), "PipeCrypt", NULL);//xiclone(&blankpipecrypt, sizeof(PipeCrypt));
	pipeInitFunctions((Pipe *) pc, 
			(PipeFuncIn) pipecryptRead, (PipeFuncOut) pipecryptWrite, 
			(PipeFuncAttach) pipecryptAttach, (PipeFuncDetach) pipecryptDetach, 
			(PipeFuncClose) pipecryptClose, (PipeFuncStatus) pipecryptStatus);
	pipeInit((Pipe *) pc);
	pc->cryptstream = csMake(pipename, options);
	return (Pipe *)pc;
}

void pipecryptFree(PipeCrypt *pc) {
	pipeFree(&pc->IOPipe);
	csFree(pc->cryptstream);
	memFree(pc);
}

void pipecryptRead(PipeCrypt *thispipe, Pipe **errPipe) {
	*errPipe = pipeGenericRead(thispipe->IOPipe.backPipe);
	if(*errPipe == NULL) {
		csRead(thispipe->cryptstream);
	}
}

void pipecryptWrite(PipeCrypt *thispipe, Pipe **errPipe) {
	csWrite(thispipe->cryptstream);
	*errPipe = pipeGenericWrite(thispipe->IOPipe.backPipe);
}


void pipecryptAttach(PipeCrypt *thispipe) {
	SockHandle *sh;
	NodeRef *nr;
	//technicly should have been done on the attaching the backpipe
	//thispipe->cryptstream->backPipe = thispipe->IOPipe.backPipe;
	thispipe->cryptstream->ParentPipe = &(thispipe->IOPipe);
	sh = (SockHandle *)pipeGetEnd((Pipe *)thispipe);
	if(sh->direction == SOCK_DIR_IN) {
		nr = sh->localnoderef;
	} else {
		nr = sh->noderef;
	}
	if(nr != NULL) {
		thispipe->cryptstream->noderef = noderefCopy(nr);
		/*
		if(!isStringBlank(nr->PrivateKey)) {
			thispipe->cryptstream->privkey = bignumFromHex(nr->PrivateKey);
		}
		if(!isStringBlank(nr->PublicKey)) {
			thispipe->cryptstream->setremotekey = bignumFromHex(nr->PublicKey);
		}
		*/
	}
}

void pipecryptDetach(PipeCrypt *thispipe) {
	pipecryptFree(thispipe);
}

void pipecryptClose(PipeCrypt *thispipe) {
}

//this can block data from further down the chain so clear the READ bit
void pipecryptStatus(PipeCrypt *thispipe, int *status) {
	*status &= ~PSTATUS_READ;
}
