/*
 * Various files from /sys/src/cmd/auth/secstore, just enough
 * to download a file at boot time.
 */

#include "std.h"
#include "dat.h"
#include <ip.h>

enum{ CHK = 16};
enum{ MAXFILESIZE = 10*1024*1024 };

enum{/* PW status bits */
	Enabled 	= (1<<0),
	STA 		= (1<<1)	/* extra SecurID step */
};

static char testmess[] = "__secstore\tPAK\nC=%s\nm=0\n";
char *secstore;

int
secdial(void)
{
	char *p;

	p = secstore;
	if(p == nil)	  /* else use the authserver */
		p = getenv("secstore");
	if(p == nil)
		p = getenv("auth");
	if(p == nil)
		p = "secstore";

	return dial(netmkaddr(p, "net", "secstore"), 0, 0, 0);
}


int
havesecstore(void)
{
	int m, n, fd;
	uchar buf[500];

	n = snprint((char*)buf, sizeof buf, testmess, owner);
	hnputs(buf, 0x8000+n-2);

	fd = secdial();
	if(fd < 0){
		if(debug)
			fprint(2, "secdial: %r\n");
		flog("secdial: %r");
		return 0;
	}
	if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){
		flog("secstore: no count");
		close(fd);
		return 0;
	}
	n = ((buf[0]&0x7f)<<8) + buf[1];
	if(n+1 > sizeof buf){
		flog("secstore: bad count");
		werrstr("implausibly large count %d", n);
		close(fd);
		return 0;
	}
	m = readn(fd, buf, n);
	close(fd);
	if(m != n){
		flog("secstore: unexpected eof");
		if(m >= 0)
			werrstr("short read from secstore");
		return 0;
	}
	buf[n] = 0;
	if(strcmp((char*)buf, "!account expired") == 0){
		flog("secstore: account expired");
		werrstr("account expired");
		return 0;
	}
	if(strcmp((char*)buf, "!account exists") == 0){
		flog("secstore: account exists");
		return 1;
	}
	flog("secstore: %s", buf);
	return 0;
}

/* delimited, authenticated, encrypted connection */
enum{ Maxmsg=4096 };	/* messages > Maxmsg bytes are truncated */
typedef struct SConn SConn;

extern SConn* newSConn(int);	/* arg is open file descriptor */
struct SConn{
	void *chan;
	int secretlen;
	int (*secret)(SConn*, uchar*, int);/*  */
	int (*read)(SConn*, uchar*, int); /* <0 if error;  errmess in buffer */
	int (*write)(SConn*, uchar*, int);
	void (*free)(SConn*);		/* also closes file descriptor */
};
/* secret(s,b,dir) sets secret for digest, encrypt, using the secretlen */
/*		bytes in b to form keys 	for the two directions; */
/*	  set dir=0 in client, dir=1 in server */

/* error convention: write !message in-band */
#define readstr secstore_readstr
static void writerr(SConn*, char*);
static int readstr(SConn*, char*);  /* call with buf of size Maxmsg+1 */
	/* returns -1 upon error, with error message in buf */

typedef struct ConnState {
	uchar secret[SHA1dlen];
	ulong seqno;
	RC4state rc4;
} ConnState;

#undef SS
typedef struct SS {
	int fd;		/* file descriptor for read/write of encrypted data */
	int alg;	/* if nonzero, "alg sha rc4_128" */
	ConnState in, out;
} SS;

static int
SC_secret(SConn *conn, uchar *sigma, int direction)
{
	SS *ss = (SS*)(conn->chan);
	int nsigma = conn->secretlen;

	if(direction != 0){
		hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->out.secret, nil);
		hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->in.secret, nil);
	}else{
		hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->out.secret, nil);
		hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->in.secret, nil);
	}
	setupRC4state(&ss->in.rc4, ss->in.secret, 16); /* restrict to 128 bits */
	setupRC4state(&ss->out.rc4, ss->out.secret, 16);
	ss->alg = 1;
	return 0;
}

static void
hash(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
{
	DigestState sha;
	uchar seq[4];

	seq[0] = seqno>>24;
	seq[1] = seqno>>16;
	seq[2] = seqno>>8;
	seq[3] = seqno;
	memset(&sha, 0, sizeof sha);
	sha1(secret, SHA1dlen, nil, &sha);
	sha1(data, len, nil, &sha);
	sha1(seq, 4, d, &sha);
}

static int
verify(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
{
	DigestState sha;
	uchar seq[4];
	uchar digest[SHA1dlen];

	seq[0] = seqno>>24;
	seq[1] = seqno>>16;
	seq[2] = seqno>>8;
	seq[3] = seqno;
	memset(&sha, 0, sizeof sha);
	sha1(secret, SHA1dlen, nil, &sha);
	sha1(data, len, nil, &sha);
	sha1(seq, 4, digest, &sha);
	return memcmp(d, digest, SHA1dlen);
}

static int
SC_read(SConn *conn, uchar *buf, int n)
{
	SS *ss = (SS*)(conn->chan);
	uchar count[2], digest[SHA1dlen];
	int len, nr;

	if(read(ss->fd, count, 2) != 2 || count[0]&0x80 == 0){
		werrstr("!SC_read invalid count");
		return -1;
	}
	len = (count[0]&0x7f)<<8 | count[1];	/* SSL-style count; no pad */
	if(ss->alg){
		len -= SHA1dlen;
		if(len <= 0 || readn(ss->fd, digest, SHA1dlen) != SHA1dlen){
			werrstr("!SC_read missing sha1");
			return -1;
		}
		if(len > n || readn(ss->fd, buf, len) != len){
			werrstr("!SC_read missing data");
			return -1;
		}
		rc4(&ss->in.rc4, digest, SHA1dlen);
		rc4(&ss->in.rc4, buf, len);
		if(verify(ss->in.secret, buf, len, ss->in.seqno, digest) != 0){
			werrstr("!SC_read integrity check failed");
			return -1;
		}
	}else{
		if(len <= 0 || len > n){
			werrstr("!SC_read implausible record length");
			return -1;
		}
		if( (nr = readn(ss->fd, buf, len)) != len){
			werrstr("!SC_read expected %d bytes, but got %d", len, nr);
			return -1;
		}
	}
	ss->in.seqno++;
	return len;
}

static int
SC_write(SConn *conn, uchar *buf, int n)
{
	SS *ss = (SS*)(conn->chan);
	uchar count[2], digest[SHA1dlen], enc[Maxmsg+1];
	int len;

	if(n <= 0 || n > Maxmsg+1){
		werrstr("!SC_write invalid n %d", n);
		return -1;
	}
	len = n;
	if(ss->alg)
		len += SHA1dlen;
	count[0] = 0x80 | len>>8;
	count[1] = len;
	if(write(ss->fd, count, 2) != 2){
		werrstr("!SC_write invalid count");
		return -1;
	}
	if(ss->alg){
		hash(ss->out.secret, buf, n, ss->out.seqno, digest);
		rc4(&ss->out.rc4, digest, SHA1dlen);
		memcpy(enc, buf, n);
		rc4(&ss->out.rc4, enc, n);
		if(write(ss->fd, digest, SHA1dlen) != SHA1dlen ||
				write(ss->fd, enc, n) != n){
			werrstr("!SC_write error on send");
			return -1;
		}
	}else{
		if(write(ss->fd, buf, n) != n){
			werrstr("!SC_write error on send");
			return -1;
		}
	}
	ss->out.seqno++;
	return n;
}

static void
SC_free(SConn *conn)
{
	SS *ss = (SS*)(conn->chan);

	close(ss->fd);
	free(ss);
	free(conn);
}

SConn*
newSConn(int fd)
{
	SS *ss;
	SConn *conn;

	if(fd < 0)
		return nil;
	ss = (SS*)emalloc(sizeof(*ss));
	conn = (SConn*)emalloc(sizeof(*conn));
	ss->fd  = fd;
	ss->alg = 0;
	conn->chan = (void*)ss;
	conn->secretlen = SHA1dlen;
	conn->free = SC_free;
	conn->secret = SC_secret;
	conn->read = SC_read;
	conn->write = SC_write;
	return conn;
}

static void
writerr(SConn *conn, char *s)
{
	char buf[Maxmsg];

	snprint(buf, Maxmsg, "!%s", s);
	conn->write(conn, (uchar*)buf, strlen(buf));
}

static int
readstr(SConn *conn, char *s)
{
	int n;

	n = conn->read(conn, (uchar*)s, Maxmsg);
	if(n >= 0){
		s[n] = 0;
		if(s[0] == '!'){
			memmove(s, s+1, n);
			n = -1;
		}
	}else{
		strcpy(s, "read error");
	}
	return n;
}

static int
getfile(SConn *conn, uchar *key, int nkey)
{
	char *buf;
	int nbuf, n, nr, len;
	char s[Maxmsg+1], *gf, *p, *q;
	uchar skey[SHA1dlen], ib[Maxmsg+CHK], *ibr, *ibw;
	AESstate aes;
	DigestState *sha;

	gf = "factotum";
	memset(&aes, 0, sizeof aes);

	snprint(s, Maxmsg, "GET %s\n", gf);
	conn->write(conn, (uchar*)s, strlen(s));

	/* get file size */
	s[0] = '\0';
	if(readstr(conn, s) < 0){
		werrstr("secstore: %r");
		return -1;
	}
	if((len = atoi(s)) < 0){
		werrstr("secstore: remote file %s does not exist", gf);
		return -1;
	}else if(len > MAXFILESIZE){/*assert */
		werrstr("secstore: implausible file size %d for %s", len, gf);
		return -1;
	}

	ibr = ibw = ib;
	buf = nil;
	nbuf = 0;
	for(nr=0; nr < len;){
		if((n = conn->read(conn, ibw, Maxmsg)) <= 0){
			werrstr("secstore: empty file chunk n=%d nr=%d len=%d: %r", n, nr, len);
			return -1;
		}
		nr += n;
		ibw += n;
		if(!aes.setup){ /* first time, read 16 byte IV */
			if(n < 16){
				werrstr("secstore: no IV in file");
				return -1;
			}
			sha = sha1((uchar*)"aescbc file", 11, nil, nil);
			sha1(key, nkey, skey, sha);
			setupAESstate(&aes, skey, AESbsize, ibr);
			memset(skey, 0, sizeof skey);
			ibr += AESbsize;
			n -= AESbsize;
		}
		aesCBCdecrypt(ibw-n, n, &aes);
		n = ibw-ibr-CHK;
		if(n > 0){
			buf = erealloc(buf, nbuf+n+1);
			memmove(buf+nbuf, ibr, n);
			nbuf += n;
			ibr += n;
		}
		memmove(ib, ibr, ibw-ibr);
		ibw = ib + (ibw-ibr);
		ibr = ib;
	}
	n = ibw-ibr;
	if((n != CHK) || (memcmp(ib, "XXXXXXXXXXXXXXXX", CHK) != 0)){
		werrstr("secstore: decrypted file failed to authenticate!");
		free(buf);
		return -1;
	}
	if(nbuf == 0){
		werrstr("secstore got empty file");
		return -1;
	}
	buf[nbuf] = '\0';
	p = buf;
	n = 0;
	while(p){
		if(q = strchr(p, '\n'))
			*q++ = '\0';
		n++;
		if(ctlwrite(p) < 0){
			flog("secstore %s:%d: %r", gf, n);
			fprint(2, "secstore(%s) line %d: %r\n", gf, n);
		}
		p = q;
	}
	free(buf);
	return 0;
}

static char VERSION[] = "secstore";

typedef struct PAKparams{
	mpint *q, *p, *r, *g;
} PAKparams;

static PAKparams *pak;

/* This group was generated by the seed EB7B6E35F7CD37B511D96C67D6688CC4DD440E1E. */
static void
initPAKparams(void)
{
	if(pak)
		return;
	pak = (PAKparams*)emalloc(sizeof(*pak));
	pak->q = strtomp("E0F0EF284E10796C5A2A511E94748BA03C795C13", nil, 16, nil);
	pak->p = strtomp("C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBBD"
		"B12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A86"
		"3A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D9"
		"3D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D", nil, 16, nil);
	pak->r = strtomp("DF310F4E54A5FEC5D86D3E14863921E834113E060F90052AD332B3241CEF"
		"2497EFA0303D6344F7C819691A0F9C4A773815AF8EAECFB7EC1D98F039F17A32A7E887"
		"D97251A927D093F44A55577F4D70444AEBD06B9B45695EC23962B175F266895C67D21"
		"C4656848614D888A4", nil, 16, nil);
	pak->g = strtomp("2F1C308DC46B9A44B52DF7DACCE1208CCEF72F69C743ADD4D2327173444"
		"ED6E65E074694246E07F9FD4AE26E0FDDD9F54F813C40CB9BCD4338EA6F242AB94CD41"
		"0E676C290368A16B1A3594877437E516C53A6EEE5493A038A017E955E218E7819734E3E"
		"2A6E0BAE08B14258F8C03CC1B30E0DDADFCF7CEDF0727684D3D255F1", nil, 16, nil);
}

/* H = (sha(ver,C,sha(passphrase)))^r mod p, */
/* a hash function expensive to attack by brute force. */
static void
longhash(char *ver, char *C, uchar *passwd, mpint *H)
{
	uchar *Cp;
	int i, n, nver, nC;
	uchar buf[140], key[1];

	nver = strlen(ver);
	nC = strlen(C);
	n = nver + nC + SHA1dlen;
	Cp = (uchar*)emalloc(n);
	memmove(Cp, ver, nver);
	memmove(Cp+nver, C, nC);
	memmove(Cp+nver+nC, passwd, SHA1dlen);
	for(i = 0; i < 7; i++){
		key[0] = 'A'+i;
		hmac_sha1(Cp, n, key, sizeof key, buf+i*SHA1dlen, nil);
	}
	memset(Cp, 0, n);
	free(Cp);
	betomp(buf, sizeof buf, H);
	mpmod(H, pak->p, H);
	mpexp(H, pak->r, pak->p, H);
}

/* Hi = H^-1 mod p */
static char *
PAK_Hi(char *C, char *passphrase, mpint *H, mpint *Hi)
{
	uchar passhash[SHA1dlen];

	sha1((uchar *)passphrase, strlen(passphrase), passhash, nil);
	initPAKparams();
	longhash(VERSION, C, passhash, H);
	mpinvert(H, pak->p, Hi);
	return mptoa(Hi, 64, nil, 0);
}

/* another, faster, hash function for each party to */
/* confirm that the other has the right secrets. */
static void
shorthash(char *mess, char *C, char *S, char *m, char *mu, char *sigma, char *Hi, uchar *digest)
{
	SHA1state *state;

	state = sha1((uchar*)mess, strlen(mess), 0, 0);
	state = sha1((uchar*)C, strlen(C), 0, state);
	state = sha1((uchar*)S, strlen(S), 0, state);
	state = sha1((uchar*)m, strlen(m), 0, state);
	state = sha1((uchar*)mu, strlen(mu), 0, state);
	state = sha1((uchar*)sigma, strlen(sigma), 0, state);
	state = sha1((uchar*)Hi, strlen(Hi), 0, state);
	state = sha1((uchar*)mess, strlen(mess), 0, state);
	state = sha1((uchar*)C, strlen(C), 0, state);
	state = sha1((uchar*)S, strlen(S), 0, state);
	state = sha1((uchar*)m, strlen(m), 0, state);
	state = sha1((uchar*)mu, strlen(mu), 0, state);
	state = sha1((uchar*)sigma, strlen(sigma), 0, state);
	sha1((uchar*)Hi, strlen(Hi), digest, state);
}

/* On input, conn provides an open channel to the server; */
/*	C is the name this client calls itself; */
/*	pass is the user's passphrase */
/* On output, session secret has been set in conn */
/*	(unless return code is negative, which means failure). */
/*    If pS is not nil, it is set to the (alloc'd) name the server calls itself. */
static int
PAKclient(SConn *conn, char *C, char *pass, char **pS)
{
	char *mess, *mess2, *eol, *S, *hexmu, *ks, *hexm, *hexsigma = nil, *hexHi;
	char kc[2*SHA1dlen+1];
	uchar digest[SHA1dlen];
	int rc = -1, n;
	mpint *x, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
	mpint *H = mpnew(0), *Hi = mpnew(0);

	hexHi = PAK_Hi(C, pass, H, Hi);

	/* random 1<=x<=q-1; send C, m=g**x H */
	x = mprand(164, genrandom, nil);
	mpmod(x, pak->q, x);
	if(mpcmp(x, mpzero) == 0)
		mpassign(mpone, x);
	mpexp(pak->g, x, pak->p, m);
	mpmul(m, H, m);
	mpmod(m, pak->p, m);
	hexm = mptoa(m, 64, nil, 0);
	mess = (char*)emalloc(2*Maxmsg+2);
	mess2 = mess+Maxmsg+1;
	snprint(mess, Maxmsg, "%s\tPAK\nC=%s\nm=%s\n", VERSION, C, hexm);
	conn->write(conn, (uchar*)mess, strlen(mess));

	/* recv g**y, S, check hash1(g**xy) */
	if(readstr(conn, mess) < 0){
		fprint(2, "error: %s\n", mess);
		writerr(conn, "couldn't read g**y");
		goto done;
	}
	eol = strchr(mess, '\n');
	if(strncmp("mu=", mess, 3) != 0 || !eol || strncmp("\nk=", eol, 3) != 0){
		writerr(conn, "verifier syntax error");
		goto done;
	}
	hexmu = mess+3;
	*eol = 0;
	ks = eol+3;
	eol = strchr(ks, '\n');
	if(!eol || strncmp("\nS=", eol, 3) != 0){
		writerr(conn, "verifier syntax error for secstore 1.0");
		goto done;
	}
	*eol = 0;
	S = eol+3;
	eol = strchr(S, '\n');
	if(!eol){
		writerr(conn, "verifier syntax error for secstore 1.0");
		goto done;
	}
	*eol = 0;
	if(pS)
		*pS = estrdup(S);
	strtomp(hexmu, nil, 64, mu);
	mpexp(mu, x, pak->p, sigma);
	hexsigma = mptoa(sigma, 64, nil, 0);
	shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
	enc64(kc, sizeof kc, digest, SHA1dlen);
	if(strcmp(ks, kc) != 0){
		writerr(conn, "verifier didn't match");
		goto done;
	}

	/* send hash2(g**xy) */
	shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
	enc64(kc, sizeof kc, digest, SHA1dlen);
	snprint(mess2, Maxmsg, "k'=%s\n", kc);
	conn->write(conn, (uchar*)mess2, strlen(mess2));

	/* set session key */
	shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
	memset(hexsigma, 0, strlen(hexsigma));
	n = conn->secret(conn, digest, 0);
	memset(digest, 0, SHA1dlen);
	if(n < 0){/*assert */
		writerr(conn, "can't set secret");
		goto done;
	}

	rc = 0;
done:
	mpfree(x);
	mpfree(sigma);
	mpfree(mu);
	mpfree(m);
	mpfree(Hi);
	mpfree(H);
	free(hexsigma);
	free(hexHi);
	free(hexm);
	free(mess);
	return rc;
}

int
secstorefetch(void)
{
	int rv = -1, fd;
	char s[Maxmsg+1];
	SConn *conn;
	char *pass, *sta;

	sta = nil;
	conn = nil;
	pass = readcons("secstore password", nil, 1);
	if(pass==nil || strlen(pass)==0){
		werrstr("cancel");
		goto Out;
	}
	if((fd = secdial()) < 0)
		goto Out;
	if((conn = newSConn(fd)) == nil)
		goto Out;
	if(PAKclient(conn, owner, pass, nil) < 0){
		werrstr("password mistyped?");
		goto Out;
	}
	if(readstr(conn, s) < 0)
		goto Out;
	if(strcmp(s, "STA") == 0){
		sta = readcons("STA PIN+SecureID", nil, 1);
		if(sta==nil || strlen(sta)==0){
			werrstr("cancel");
			goto Out;
		}
		if(strlen(sta) >= sizeof s - 3){
			werrstr("STA response too long");
			goto Out;
		}
		strcpy(s+3, sta);
		conn->write(conn, (uchar*)s, strlen(s));
		readstr(conn, s);
	}
	if(strcmp(s, "OK") !=0){
		werrstr("%s", s);
		goto Out;
	}
	if(getfile(conn, (uchar*)pass, strlen(pass)) < 0)
		goto Out;
	conn->write(conn, (uchar*)"BYE", 3);
	rv = 0;

Out:
	if(rv < 0)
		flog("secstorefetch: %r");
	if(conn)
		conn->free(conn);
	if(pass)
		free(pass);
	if(sta)
		free(sta);
	return rv;
}

