/*
 * 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");
		return 0;
	}
	if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){
		close(fd);
		return 0;
	}
	n = ((buf[0]&0x7f)<<8) + buf[1];
	if(n+1 > sizeof buf){
		werrstr("implausibly large count %d", n);
		close(fd);
		return 0;
	}
	m = readn(fd, buf, n);
	close(fd);
	if(m != n){
		if(m >= 0)
			werrstr("short read from secstore");
		return 0;
	}
	buf[n] = 0;
	if(strcmp((char*)buf, "!account expired") == 0){
		werrstr("account expired");
		return 0;
	}
	return strcmp((char*)buf, "!account exists") == 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;

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)
			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(conn)
		conn->free(conn);
	if(pass)
		free(pass);
	if(sta)
		free(sta);
	return rv;
}

