#include "std.h"
#include "dat.h"

/*
 * RSA authentication.
 * 
 * Encrypt/Decrypt:
 *	start n=xxx ek=xxx
 *	write msg
 *	read encrypt/decrypt(msg)
 *
 * Sign (PKCS #1 using hash=sha1 or hash=md5)
 *	start n=xxx ek=xxx
 *	write hash(msg)
 *	read signature(hash(msg))
 * 
 * Verify:
 *	start n=xxx ek=xxx
 *	write hash(msg)
 *	write signature(hash(msg))
 *	read ok or fail
 *
 * all numbers are hexadecimal biginits parsable with strtomp.
 * must be lower case for attribute matching in start.
 */

static int
xrsadecrypt(Conv *c)
{
	char *txt, buf[4096], *role;
	int n, ret;
	mpint *m, *mm;
	Key *k;
	RSApriv *key;

	ret = -1;
	txt = nil;
	m = nil;
	mm = nil;

	/* fetch key */
	c->state = "keylookup";
	k = keylookup("%A", c->attr);
	if(k == nil)
		goto out;
	key = k->priv;
	
	/* make sure have private half if needed */
	role = strfindattr(c->attr, "role");
	if(strcmp(role, "decrypt") == 0 && !key->c2){
		werrstr("missing private half of key -- cannot decrypt");
		goto out;
	}
	
	/* read text */
	c->state = "read";
	if((n=convreadm(c, &txt)) < 0)
		goto out;
	if(n < 32){
		convprint(c, "data too short");
		goto out;
	}
	
	/* encrypt/decrypt */
	m = betomp(txt, n, nil);
	if(m == nil)
		goto out;
	if(strcmp(role, "decrypt") == 0)
		mm = rsadecrypt(key, m, nil);
	else
		mm = rsaencrypt(&key->pub, m, nil);
	if(mm == nil)
		goto out;
	n = mptobe(mm, buf, sizeof buf, nil);
	
	/* send response */
	c->state = "write";
	convwrite(c, buf, n);
	ret = 0;

out:
	mpfree(m);
	mpfree(mm);
	keyclose(k);
	free(txt);
	return ret;
}

static int
xrsasign(Conv *c)
{
	char *hash, *role;
	int dlen, n, ret;
	DigestAlg *hashfn;
	Key *k;
	RSApriv *key;
	uchar sig[1024], digest[64];
	char *sig2;

	ret = -1;
	
	/* fetch key */
	c->state = "keylookup";
	k = keylookup("%A", c->attr);
	if(k == nil)
		goto out;

	/* make sure have private half if needed */
	key = k->priv;
	role = strfindattr(c->attr, "role");
	if(strcmp(role, "sign") == 0 && !key->c2){
		werrstr("missing private half of key -- cannot sign");
		goto out;
	}
	
	/* get hash type from key */
	hash = strfindattr(k->attr, "hash");
	if(hash == nil)
		hash = "sha1";
	if(strcmp(hash, "sha1") == 0){
		hashfn = sha1;
		dlen = SHA1dlen;
	}else if(strcmp(hash, "md5") == 0){
		hashfn = md5;
		dlen = MD5dlen;
	}else{
		werrstr("unknown hash function %s", hash);
		goto out;
	}

	/* read hash */
	c->state = "read hash";
	if((n=convread(c, digest, dlen)) < 0)
		goto out;

	if(strcmp(role, "sign") == 0){
		/* sign */
		if((n=rsasign(key, hashfn, digest, dlen, sig, sizeof sig)) < 0)
			goto out;

		/* write */
		convwrite(c, sig, n);
	}else{
		/* read signature */
		if((n = convreadm(c, &sig2)) < 0)
			goto out;
			
		/* verify */
		if(rsaverify(&key->pub, hashfn, digest, dlen, (uchar*)sig2, n) == 0)
			convprint(c, "ok");
		else
			convprint(c, "signature does not verify");
		free(sig2);
	}
	ret = 0;

out:
	keyclose(k);
	return ret;
}

/*
 * convert to canonical form (lower case) 
 * for use in attribute matches.
 */
static void
strlwr(char *a)
{
	for(; *a; a++){
		if('A' <= *a && *a <= 'Z')
			*a += 'a' - 'A';
	}
}

static RSApriv*
readrsapriv(Key *k)
{
	char *a;
	RSApriv *priv;

	priv = rsaprivalloc();

	if((a=strfindattr(k->attr, "ek"))==nil 
	|| (priv->pub.ek=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if((a=strfindattr(k->attr, "n"))==nil 
	|| (priv->pub.n=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if(k->privattr == nil)	/* only public half */
		return priv;

	if((a=strfindattr(k->privattr, "!p"))==nil 
	|| (priv->p=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if((a=strfindattr(k->privattr, "!q"))==nil 
	|| (priv->q=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if((a=strfindattr(k->privattr, "!kp"))==nil 
	|| (priv->kp=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if((a=strfindattr(k->privattr, "!kq"))==nil 
	|| (priv->kq=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if((a=strfindattr(k->privattr, "!c2"))==nil 
	|| (priv->c2=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	if((a=strfindattr(k->privattr, "!dk"))==nil 
	|| (priv->dk=strtomp(a, nil, 16, nil))==nil)
		goto Error;
	strlwr(a);
	return priv;

Error:
	rsaprivfree(priv);
	return nil;
}

static int
rsacheck(Key *k)
{
	static int first = 1;
	
	if(first){
		fmtinstall('B', mpfmt);
		first = 0;
	}

	if((k->priv = readrsapriv(k)) == nil){
		werrstr("malformed key data");
		return -1;
	}
	return 0;
}

static void
rsaclose(Key *k)
{
	rsaprivfree(k->priv);
	k->priv = nil;
}

static Role
rsaroles[] = 
{
	"sign",	xrsasign,
	"verify",	xrsasign,	/* public operation */
	"decrypt",	xrsadecrypt,
	"encrypt",	xrsadecrypt,	/* public operation */
	0
};

Proto rsa = {
	"rsa",
	rsaroles,
	nil,
	rsacheck,
	rsaclose
};
