⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devssl.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
📖 第 1 页 / 共 2 页
字号:
			offset = 3;		} else {			p = nb->rp;			p[0] = (m>>8) | 0x80;			p[1] = m;			offset = 2;		}		switch(s.s->state){		case Sencrypting:			nb = encryptb(s.s, nb, offset);			break;		case Sdigesting:			nb = digestb(s.s, nb, offset);			break;		case Sdigenc:			nb = digestb(s.s, nb, offset);			nb = encryptb(s.s, nb, offset);			break;		}		s.s->out.mid++;		m = BLEN(nb);		devtab[s.s->c->type]->bwrite(s.s->c, nb, s.s->c->offset);		s.s->c->offset += m;	}	qunlock(&s.s->out.q);	poperror();	return rv;}static voidsetsecret(OneWay *w, uchar *secret, int n){	if(w->secret)		free(w->secret);	w->secret = smalloc(n);	memmove(w->secret, secret, n);	w->slen = n;}static voidinitDESkey(OneWay *w){	if(w->state){		free(w->state);		w->state = 0;	}	w->state = smalloc(sizeof(DESstate));	if(w->slen >= 16)		setupDESstate(w->state, w->secret, w->secret+8);	else if(w->slen >= 8)		setupDESstate(w->state, w->secret, 0);	else		error("secret too short");}/* *  40 bit DES is the same as 56 bit DES.  However, *  16 bits of the key are masked to zero. */static voidinitDESkey_40(OneWay *w){	uchar key[8];	if(w->state){		free(w->state);		w->state = 0;	}	if(w->slen >= 8){		memmove(key, w->secret, 8);		key[0] &= 0x0f;		key[2] &= 0x0f;		key[4] &= 0x0f;		key[6] &= 0x0f;	}	w->state = malloc(sizeof(DESstate));	if(w->slen >= 16)		setupDESstate(w->state, key, w->secret+8);	else if(w->slen >= 8)		setupDESstate(w->state, key, 0);	else		error("secret too short");}static voidinitRC4key(OneWay *w){	if(w->state){		free(w->state);		w->state = 0;	}	w->state = smalloc(sizeof(RC4state));	setupRC4state(w->state, w->secret, w->slen);}/* *  40 bit RC4 is the same as n-bit RC4.  However, *  we ignore all but the first 40 bits of the key. */static voidinitRC4key_40(OneWay *w){	if(w->state){		free(w->state);		w->state = 0;	}	if(w->slen > 5)		w->slen = 5;	w->state = malloc(sizeof(RC4state));	setupRC4state(w->state, w->secret, w->slen);}/* *  128 bit RC4 is the same as n-bit RC4.  However, *  we ignore all but the first 128 bits of the key. */static voidinitRC4key_128(OneWay *w){	if(w->state){		free(w->state);		w->state = 0;	}	if(w->slen > 16)		w->slen = 16;	w->state = malloc(sizeof(RC4state));	setupRC4state(w->state, w->secret, w->slen);}typedef struct Hashalg Hashalg;struct Hashalg{	char	*name;	int	diglen;	DigestState *(*hf)(uchar*, ulong, uchar*, DigestState*);};Hashalg hashtab[] ={	{ "md4", MD4dlen, md4, },	{ "md5", MD5dlen, md5, },	{ "sha1", SHA1dlen, sha1, },	{ "sha", SHA1dlen, sha1, },	{ 0 }};static intparsehashalg(char *p, Dstate *s){	Hashalg *ha;	for(ha = hashtab; ha->name; ha++){		if(strcmp(p, ha->name) == 0){			s->hf = ha->hf;			s->diglen = ha->diglen;			s->state &= ~Sclear;			s->state |= Sdigesting;			return 0;		}	}	return -1;}typedef struct Encalg Encalg;struct Encalg{	char	*name;	int	blocklen;	int	alg;	void	(*keyinit)(OneWay*);};#ifdef NOSPOOKSEncalg encrypttab[] ={	{ "descbc", 8, DESCBC, initDESkey, },           /* DEPRECATED -- use des_56_cbc */	{ "desecb", 8, DESECB, initDESkey, },           /* DEPRECATED -- use des_56_ecb */	{ "des_56_cbc", 8, DESCBC, initDESkey, },	{ "des_56_ecb", 8, DESECB, initDESkey, },	{ "des_40_cbc", 8, DESCBC, initDESkey_40, },	{ "des_40_ecb", 8, DESECB, initDESkey_40, },	{ "rc4", 1, RC4, initRC4key_40, },              /* DEPRECATED -- use rc4_X      */	{ "rc4_256", 1, RC4, initRC4key, },	{ "rc4_128", 1, RC4, initRC4key_128, },	{ "rc4_40", 1, RC4, initRC4key_40, },	{ 0 }};#elseEncalg encrypttab[] ={	{ "des_40_cbc", 8, DESCBC, initDESkey_40, },	{ "des_40_ecb", 8, DESECB, initDESkey_40, },	{ "rc4", 1, RC4, initRC4key_40, },              /* DEPRECATED -- use rc4_X      */	{ "rc4_40", 1, RC4, initRC4key_40, },	{ 0 }};#endif NOSPOOKSstatic intparseencryptalg(char *p, Dstate *s){	Encalg *ea;	for(ea = encrypttab; ea->name; ea++){		if(strcmp(p, ea->name) == 0){			s->encryptalg = ea->alg;			s->blocklen = ea->blocklen;			(*ea->keyinit)(&s->in);			(*ea->keyinit)(&s->out);			s->state &= ~Sclear;			s->state |= Sencrypting;			return 0;		}	}	return -1;}static longsslwrite(Chan *c, void *a, long n, vlong off){	volatile struct { Dstate *s; } s;	volatile struct { Block *b; } b;	int m, t;	char *p, *np, *e, buf[128];	uchar *x;	ulong offset = off;	s.s = dstate[CONV(c->qid)];	if(s.s == 0)		panic("sslwrite");	t = TYPE(c->qid);	if(t == Qdata){		if(s.s->state == Sincomplete)			error(Ebadusefd);		p = a;		e = p + n;		do {			m = e - p;			if(m > s.s->max)				m = s.s->max;			b.b = allocb(m);			if(waserror()){				freeb(b.b);				nexterror();			}			memmove(b.b->wp, p, m);			poperror();			b.b->wp += m;			sslbwrite(c, b.b, offset);			p += m;		} while(p < e);		return n;	}	/* mutex with operations using what we're about to change */	if(waserror()){		qunlock(&s.s->in.ctlq);		qunlock(&s.s->out.q);		nexterror();	}	qlock(&s.s->in.ctlq);	qlock(&s.s->out.q);	switch(t){	default:		panic("sslwrite");	case Qsecretin:		setsecret(&s.s->in, a, n);		goto out;	case Qsecretout:		setsecret(&s.s->out, a, n);		goto out;	case Qctl:		break;	}	if(n >= sizeof(buf))		error("arg too long");	strncpy(buf, a, n);	buf[n] = 0;	p = strchr(buf, '\n');	if(p)		*p = 0;	p = strchr(buf, ' ');	if(p)		*p++ = 0;	if(strcmp(buf, "fd") == 0){		s.s->c = buftochan(p);		/* default is clear (msg delimiters only) */		s.s->state = Sclear;		s.s->blocklen = 1;		s.s->diglen = 0;		s.s->maxpad = s.s->max = (1<<15) - s.s->diglen - 1;		s.s->in.mid = 0;		s.s->out.mid = 0;	} else if(strcmp(buf, "alg") == 0 && p != 0){		s.s->blocklen = 1;		s.s->diglen = 0;		if(s.s->c == 0)			error("must set fd before algorithm");		s.s->state = Sclear;		s.s->maxpad = s.s->max = (1<<15) - s.s->diglen - 1;		if(strcmp(p, "clear") == 0){			goto out;		}		if(s.s->in.secret && s.s->out.secret == 0)			setsecret(&s.s->out, s.s->in.secret, s.s->in.slen);		if(s.s->out.secret && s.s->in.secret == 0)			setsecret(&s.s->in, s.s->out.secret, s.s->out.slen);		if(s.s->in.secret == 0 || s.s->out.secret == 0)			error("algorithm but no secret");		s.s->hf = 0;		s.s->encryptalg = Noencryption;		s.s->blocklen = 1;		for(;;){			np = strchr(p, ' ');			if(np)				*np++ = 0;			if(parsehashalg(p, s.s) < 0)			if(parseencryptalg(p, s.s) < 0)				error("bad algorithm");			if(np == 0)				break;			p = np;		}		if(s.s->hf == 0 && s.s->encryptalg == Noencryption)			error("bad algorithm");		if(s.s->blocklen != 1){			s.s->max = (1<<15) - s.s->diglen - 1;			s.s->max -= s.s->max % s.s->blocklen;			s.s->maxpad = (1<<14) - s.s->diglen - 1;			s.s->maxpad -= s.s->maxpad % s.s->blocklen;		} else			s.s->maxpad = s.s->max = (1<<15) - s.s->diglen - 1;	} else if(strcmp(buf, "secretin") == 0 && p != 0) {		m = (strlen(p)*3)/2;		x = smalloc(m);		n = dec64(x, m, p, strlen(p));		setsecret(&s.s->in, x, n);		free(x);	} else if(strcmp(buf, "secretout") == 0 && p != 0) {		m = (strlen(p)*3)/2 + 1;		x = smalloc(m);		n = dec64(x, m, p, strlen(p));		setsecret(&s.s->out, x, n);		free(x);	} else		error(Ebadarg);out:	qunlock(&s.s->in.ctlq);	qunlock(&s.s->out.q);	poperror();	return n;}static voidsslinit(void){	struct Encalg *e;	struct Hashalg *h;	int n;	char *cp;	if((dstate = smalloc(sizeof(Dstate*) * maxdstate)) == 0)		panic("sslinit");	n = 1;	for(e = encrypttab; e->name != nil; e++)		n += strlen(e->name) + 1;	cp = encalgs = smalloc(n);	for(e = encrypttab;;){		strcpy(cp, e->name);		cp += strlen(e->name);		e++;		if(e->name == nil)			break;		*cp++ = ' ';	}	*cp = 0;	n = 1;	for(h = hashtab; h->name != nil; h++)		n += strlen(h->name) + 1;	cp = hashalgs = smalloc(n);	for(h = hashtab;;){		strcpy(cp, h->name);		cp += strlen(h->name);		h++;		if(h->name == nil)			break;		*cp++ = ' ';	}	*cp = 0;}Dev ssldevtab = {	'D',	"ssl",	devreset,	sslinit,	sslattach,	devclone,	sslwalk,	sslstat,	sslopen,	devcreate,	sslclose,	sslread,	sslbread,	sslwrite,	sslbwrite,	devremove,	sslwstat,};static Block*encryptb(Dstate *s, Block *b, int offset){	uchar *p, *ep, *p2, *ip, *eip;	DESstate *ds;	switch(s->encryptalg){	case DESECB:		ds = s->out.state;		ep = b->rp + BLEN(b);		for(p = b->rp + offset; p < ep; p += 8)			block_cipher(ds->expanded, p, 0);		break;	case DESCBC:		ds = s->out.state;		ep = b->rp + BLEN(b);		for(p = b->rp + offset; p < ep; p += 8){			p2 = p;			ip = ds->ivec;			for(eip = ip+8; ip < eip; )				*p2++ ^= *ip++;			block_cipher(ds->expanded, p, 0);			memmove(ds->ivec, p, 8);		}		break;	case RC4:		rc4(s->out.state, b->rp + offset, BLEN(b) - offset);		break;	}	return b;}static Block*decryptb(Dstate *s, Block *bin){	Block *b, **l;	uchar *p, *ep, *tp, *ip, *eip;	DESstate *ds;	uchar tmp[8];	int i;	l = &bin;	for(b = bin; b; b = b->next){		/* make sure we have a multiple of s->blocklen */		if(s->blocklen > 1){			i = BLEN(b);			if(i % s->blocklen){				*l = b = pullupblock(b, i + s->blocklen - (i%s->blocklen));				if(b == 0)					error("ssl encrypted message too short");			}		}		l = &b->next;		/* decrypt */		switch(s->encryptalg){		case DESECB:			ds = s->in.state;			ep = b->rp + BLEN(b);			for(p = b->rp; p < ep; p += 8)				block_cipher(ds->expanded, p, 1);			break;		case DESCBC:			ds = s->in.state;			ep = b->rp + BLEN(b);			for(p = b->rp; p < ep;){				memmove(tmp, p, 8);				block_cipher(ds->expanded, p, 1);				tp = tmp;				ip = ds->ivec;				for(eip = ip+8; ip < eip; ){					*p++ ^= *ip;					*ip++ = *tp++;				}			}			break;		case RC4:			rc4(s->in.state, b->rp, BLEN(b));			break;		}	}	return bin;}static Block*digestb(Dstate *s, Block *b, int offset){	uchar *p;	DigestState ss;	uchar msgid[4];	ulong n, h;	OneWay *w;	w = &s->out;	memset(&ss, 0, sizeof(ss));	h = s->diglen + offset;	n = BLEN(b) - h;	/* hash secret + message */	(*s->hf)(w->secret, w->slen, 0, &ss);	(*s->hf)(b->rp + h, n, 0, &ss);	/* hash message id */	p = msgid;	n = w->mid;	*p++ = n>>24;	*p++ = n>>16;	*p++ = n>>8;	*p = n;	(*s->hf)(msgid, 4, b->rp + offset, &ss);	return b;}static voidcheckdigestb(Dstate *s, Block *bin){	uchar *p;	DigestState ss;	uchar msgid[4];	int n, h;	OneWay *w;	uchar digest[128];	Block *b;	w = &s->in;	memset(&ss, 0, sizeof(ss));	/* hash secret */	(*s->hf)(w->secret, w->slen, 0, &ss);	/* hash message */	h = s->diglen;	for(b = bin; b; b = b->next){		n = BLEN(b) - h;		if(n < 0)			panic("checkdigestb");		(*s->hf)(b->rp + h, n, 0, &ss);		h = 0;	}	/* hash message id */	p = msgid;	n = w->mid;	*p++ = n>>24;	*p++ = n>>16;	*p++ = n>>8;	*p = n;	(*s->hf)(msgid, 4, digest, &ss);	if(memcmp(digest, bin->rp, s->diglen) != 0)		error("bad digest");}/* get channel associated with an fd */static Chan*buftochan(char *p){	Chan *c;	int fd;	if(p == 0)		error(Ebadarg);	fd = strtoul(p, 0, 0);	if(fd < 0)		error(Ebadarg);	c = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */	return c;}/* hand up a digest connection */static voidsslhangup(Dstate *s){	Block *b;	qlock(&s->in.q);	for(b = s->processed; b; b = s->processed){		s->processed = b->next;		freeb(b);	}	if(s->unprocessed){		freeb(s->unprocessed);		s->unprocessed = 0;	}	s->state = Sincomplete;	qunlock(&s->in.q);}static Dstate*dsclone(Chan *ch){	Dstate **pp, **ep, **np;	int newmax;	if(waserror()) {		unlock(&dslock);		nexterror();	}	lock(&dslock);	ep = &dstate[maxdstate];	for(pp = dstate; pp < ep; pp++) {		if(*pp == 0) {			dsnew(ch, pp);			break;		}	}	if(pp >= ep) {		if(maxdstate >= Maxdstate) {			unlock(&dslock);			poperror();			return 0;		}		newmax = 2 * maxdstate;		if(newmax > Maxdstate)			newmax = Maxdstate;		np = smalloc(sizeof(Dstate*) * newmax);		if(np == 0)			error(Enomem);		memmove(np, dstate, sizeof(Dstate*) * maxdstate);		dstate = np;		pp = &dstate[maxdstate];		memset(pp, 0, sizeof(Dstate*)*(newmax - maxdstate));		maxdstate = newmax;		dsnew(ch, pp);	}	unlock(&dslock);	poperror();	return *pp;}static voiddsnew(Chan *ch, Dstate **pp){	Dstate *s;	int t;	*pp = s = malloc(sizeof(*s));	if(!s)		error(Enomem);	if(pp - dstate >= dshiwat)		dshiwat++;	memset(s, 0, sizeof(*s));	s->state = Sincomplete;	s->ref = 1;	strncpy(s->user, up->user, sizeof(s->user));	s->perm = 0660;	t = TYPE(ch->qid);	if(t == Qclonus)		t = Qctl;	ch->qid.path = QID(pp - dstate, t);	ch->qid.vers = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -