Charles.Forsyth20080116-012525a614318 years agoHistory
3029 lines · 50.4 KB · C
RawDownload
#include "lib9.h"#include "kernel.h"#include <isa.h>#include "interp.h"#include "runt.h"#include "keyring.h"#include <mp.h>#include <libsec.h>#include "pool.h"#include "raise.h"#include "../libkeyring/keys.h"  enum {	PSEUDO=0,	REALLY,};void getRandBetween(BigInt p, BigInt q, BigInt result, int type); Type	*TSigAlg;Type	*TCertificate;Type	*TSK;Type	*TPK;Type	*TDigestState;Type	*TAuthinfo;Type *TAESstate;Type	*TDESstate;Type *TIDEAstate;Type *TBFstate;Type	*TRC4state;Type	*TIPint;Type *TDSAsk;Type *TDSApk;Type *TDSAsig;Type *TEGsk;Type *TEGpk;Type *TEGsig;Type *TRSAsk;Type *TRSApk;Type *TRSAsig; enum {	Maxmsg=	4096}; uchar IPintmap[] = Keyring_IPint_map;uchar SigAlgmap[] = Keyring_SigAlg_map;uchar SKmap[] = Keyring_SK_map;uchar PKmap[] = Keyring_PK_map;uchar Certificatemap[] = Keyring_Certificate_map;uchar DigestStatemap[] = Keyring_DigestState_map;uchar Authinfomap[] = Keyring_Authinfo_map;uchar AESstatemap[] = Keyring_AESstate_map;uchar DESstatemap[] = Keyring_DESstate_map;uchar IDEAstatemap[] = Keyring_IDEAstate_map;uchar BFstatemap[] = Keyring_BFstate_map;uchar RC4statemap[] = Keyring_RC4state_map;uchar DSAskmap[] = Keyring_DSAsk_map;uchar DSApkmap[] = Keyring_DSApk_map;uchar DSAsigmap[] = Keyring_DSAsig_map;uchar EGskmap[] = Keyring_EGsk_map;uchar EGpkmap[] = Keyring_EGpk_map;uchar EGsigmap[] = Keyring_EGsig_map;uchar RSAskmap[] = Keyring_RSAsk_map;uchar RSApkmap[] = Keyring_RSApk_map;uchar RSAsigmap[] = Keyring_RSAsig_map; PK*	checkPK(Keyring_PK *k); extern void		setid(char*, int);extern vlong		osusectime(void);extern Keyring_IPint*	newIPint(BigInt);extern void		freeIPint(Heap*, int); static char exBadSA[]	= "bad signature algorithm";static char exBadSK[]	= "bad secret key";static char exBadPK[]	= "bad public key";static char exBadCert[]	= "bad certificate"; typedef struct XBFstate XBFstate; /* BF state */struct XBFstate{	Keyring_BFstate	x;	BFstate	state;}; /* *  Infinite (actually kind of big) precision integers */ /* convert a Big to base64 ascii */intbigtobase64(BigInt b, char *buf, int len){	uchar *p;	int n, rv, o; 	n = (b->top+1)*Dbytes;	p = malloc(n+1);	if(p == nil)		goto Err;	n = mptobe(b, p+1, n, nil);	if(n < 0)		goto Err;	p[0] = 0;	if(n != 0 && (p[1]&0x80)){		/* force leading 0 byte for compatibility with older representation */		/* TO DO: if b->sign < 0, complement bits and add one */		o = 0;		n++;	}else		o = 1;	rv = enc64(buf, len, p+o, n);	free(p);	return rv; Err:	free(p);	if(len > 0){		*buf = '*';		return 1;	}	return 0;} /* convert a Big to base64 ascii for %U */intbig64conv(Fmt *f){	BigInt b;	char *buf;	int n; 	b = va_arg(f->args, BigInt);	n = (b->top+1)*Dbytes + 1;	n = ((n+3)/3)*4 + 1;	buf = malloc(n);	bigtobase64(b, buf, n);	n = fmtstrcpy(f, buf);	free(buf);	return  n;} static BigIntcheckIPint(Keyring_IPint *v){	IPint *ip; 	ip = (IPint*)v;	if(ip == H || ip == nil)		error(exNilref);	if(D2H(ip)->t != TIPint)		error(exType);	return ip->b;} static void*newthing(Type *t, int add){	Heap *h; 	h = heap(t);	if(add)		ptradd(h);	return H2D(void*, h);} static Keyring_IPint*ipcopymp(BigInt b){	if(b == nil)		return H;	return newIPint(mpcopy(b));} /* convert a base64 string to a big */BigIntbase64tobig(char *str, char **strp){	int n;	char *p;	BigInt b;	uchar hex[(MaxBigBytes*6 + 7)/8]; 	for(p = str; *p && *p != '\n'; p++)		;	n = dec64(hex, sizeof(hex), str, p - str);	b = betomp(hex, n, nil);	if(strp){		if(*p)			p++;		*strp = p;	}	return b;} /* *  signature algorithms */enum{	Maxalg = 8};static SigAlgVec	*algs[Maxalg];static int		nalg; static SigAlg*newSigAlg(SigAlgVec *vec){	Heap *h;	SigAlg *sa; 	h = heap(TSigAlg);	sa = H2D(SigAlg*, h);	retstr(vec->name, &sa->x.name);	sa->vec = vec;	return sa;} static voidfreeSigAlg(Heap *h, int swept){	if(!swept)		freeheap(h, 0);} SigAlgVec*findsigalg(char *name){	SigAlgVec **sap; 	for(sap = algs; sap < &algs[nalg]; sap++)		if(strcmp(name, (*sap)->name) == 0)			return *sap;	return nil;} SigAlg*strtoalg(char *str, char **strp){	int n;	char *p, name[20];	SigAlgVec *sa;  	p = strchr(str, '\n');	if(p == 0){		p = str + strlen(str);		if(strp)			*strp = p;	} else {		if(strp)			*strp = p+1;	} 	n = p - str;	if(n < sizeof(name)){		strncpy(name, str, n);		name[n] = 0;		sa = findsigalg(name);		if(sa != nil)			return newSigAlg(sa);	}	return nil;} static SigAlg*checkSigAlg(Keyring_SigAlg *ksa){	SigAlgVec **sap;	SigAlg *sa; 	sa = (SigAlg*)ksa; 	for(sap = algs; sap < &algs[Maxalg]; sap++)		if(sa->vec == *sap)			return sa;	errorf("%s: %s", exType, exBadSA);	return nil;} /* *  parse next new line terminated string into a String */String*strtostring(char *str, char **strp){	char *p;	String *s; 	p = strchr(str, '\n');	if(p == 0)		p = str + strlen(str);	s = H;	retnstr(str, p - str, &s); 	if(strp){		if(*p)			p++;		*strp = p;	} 	return s;} /* *  private part of a key */static SK*newSK(SigAlg *sa, String *owner, int increfsa){	Heap *h;	SK *k; 	h = heap(TSK);	k = H2D(SK*, h);	k->x.sa = (Keyring_SigAlg*)sa;	if(increfsa) {		h = D2H(sa);		h->ref++;		Setmark(h);	}	k->x.owner = owner;	k->key = 0;	return k;} static voidfreeSK(Heap *h, int swept){	SK *k;	SigAlg *sa; 	k = H2D(SK*, h);	sa = checkSigAlg(k->x.sa);	if(k->key)		(*sa->vec->skfree)(k->key);	freeheap(h, swept);} static SK*checkSK(Keyring_SK *k){	SK *sk; 	sk = (SK*)k;	if(sk == H || sk == nil || sk->key == 0 || D2H(sk)->t != TSK){		errorf("%s: %s", exType, exBadSK);		return nil;	}	return sk;} voidKeyring_genSK(void *fp){	F_Keyring_genSK *f;	SK *sk;	SigAlg *sa;	void *v; 	f = fp;	v = *f->ret;	*f->ret = H;	destroy(v); 	sa = strtoalg(string2c(f->algname), 0);	if(sa == nil)		return; 	sk = newSK(sa, stringdup(f->owner), 0);	*f->ret = (Keyring_SK*)sk;	release();	sk->key = (*sa->vec->gensk)(f->length);	acquire();} voidKeyring_genSKfromPK(void *fp){	F_Keyring_genSKfromPK *f;	SigAlg *sa;	PK *pk;	SK *sk;	void *v; 	f = fp;	v = *f->ret;	*f->ret = H;	destroy(v); 	pk = checkPK(f->pk);	sa = checkSigAlg(pk->x.sa);	sk = newSK(sa, stringdup(f->owner), 1);	*f->ret = (Keyring_SK*)sk;	release();	sk->key = (*sa->vec->genskfrompk)(pk->key);	acquire();} /* converts a sequence of newline-separated base64-encoded BigInts to attr=hexval ... in f */static char*bigs2attr(Fmt *f, char *bigs, char **names){	int i, n, nd;	char *b16, *vals[20];	uchar data[(MaxBigBytes*6 + 7)/8]; 	b16 = malloc(2*MaxBigBytes+1);	if(b16 == nil)		return nil;	n = getfields(bigs, vals, nelem(vals), 0, "\n");	for(i = 0; i < n-1; i++){		if(names == nil || names[i] == nil)			break;	/* shouldn't happen */		nd = dec64(data, sizeof(data), vals[i], strlen(vals[i]));		if(nd < 0)			break;		enc16(b16, 2*MaxBigBytes+1, data, nd);		fmtprint(f, " %s=%s", names[i], b16);	}	free(b16);	return fmtstrflush(f);} voidKeyring_sktoattr(void *fp){	F_Keyring_sktoattr *f;	char *val, *buf, *owner;	SigAlg *sa;	Fmt o;	SK *sk; 	f = fp;	sk = checkSK(f->sk);	sa = checkSigAlg(sk->x.sa);	buf = malloc(Maxbuf);	if(buf == nil){		retstr(nil, f->ret);		return;	}	(*sa->vec->sk2str)(sk->key, buf, Maxbuf);	fmtstrinit(&o);	fmtprint(&o, "alg=%q", string2c(sa->x.name));	owner = string2c(sk->x.owner);	if(*owner)		fmtprint(&o, " owner=%q", owner);	val = bigs2attr(&o, buf, sa->vec->skattr);	free(buf);	retstr(val, f->ret);	free(val);} static intsktostr(SK *sk, char *buf, int len){	int n;	SigAlg *sa; 	sa = checkSigAlg(sk->x.sa);	n = snprint(buf, len, "%s\n%s\n", string2c(sa->x.name),			string2c(sk->x.owner));	return n + (*sa->vec->sk2str)(sk->key, buf+n, len - n);} voidKeyring_sktostr(void *fp){	F_Keyring_sktostr *f;	char *buf; 	f = fp;	buf = malloc(Maxbuf); 	if(buf)		sktostr(checkSK(f->sk), buf, Maxbuf);	retstr(buf, f->ret); 	free(buf);} static SK*strtosk(char *buf){	SK *sk;	char *p;	SigAlg *sa;	String *owner;	void *key; 	sa = strtoalg(buf, &p);	if(sa == nil)		return H;	owner = strtostring(p, &p);	if(owner == H){		destroy(sa);		return H;

Lines 1–500 of 3029.