~kris/9p

9hist

500be379339ec608b7109957ed85b216c2ec4d3e — David du Colombier 30 years ago f539ce2
Plan 9 from Bell Labs 1995-12-15
1 files changed, 216 insertions(+), 177 deletions(-)

M port/devssl.c
M port/devssl.c => port/devssl.c +216 -177
@@ 159,24 159,6 @@ sslwstat(Chan *c, char *dp)
	error(Eperm);
}

static void
dighangup(Dstate *s)
{
	Block *b;

	qlock(&s->in);
	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 = Closed;
	qunlock(&s->in);
}

void
sslclose(Chan *c)
{


@@ 335,62 317,175 @@ sslwrite(Chan *c, char *a, long n, ulong offset)
	return n;
}

void
digestb(Dstate *s, Block *b, OneWay *w)
/*
 *  use SSL record format, add in count and digest or encrypt
 */
long
sslbwrite(Chan *c, Block *b, ulong offset)
{
	Dstate *s;
	Block *nb;
	uchar *p;
	DigestState ss;
	uchar msgid[4];
	ulong n, h;
	int h, n, m, pad, rv;

	memset(&ss, 0, sizeof(ss));
	h = s->diglen + 2;
	n = BLEN(b) - h;
	s = c->aux;
	if(s == 0 || s->state != Established)
		error(Ebadusefd);

	/* hash secret + message */
	(*s->hf)(w->secret, w->slen, 0, &ss);
	(*s->hf)(nb->rp + h, n, 0, &ss);
	if(waserror()){
		qunlock(&s->out);
		if(b)
			freeb(b);
		dighangup(s);
		nexterror();
	}
	qlock(&s->out);

	/* hash message id */
	p = msgid;
	n = w->mid++;
	*p++ = n>>24;
	*p++ = n>>16;
	*p++ = n>>8;
	*p = n;
	(*s->func)(msgid, 4, nb->rp + 2, &ss);
	rv = 0;
	while(b){
		m = n = BLEN(b);
		h = s->diglen + 2;

		/* padded blocks are shorter than unpadded ones (strange) */
		pad = 0;
		if(m > s->max){
			m = s->max;
		} else if(s->blocklen != 1){
			pad = m%s->blocklen;
			if(pad){
				pad = s->blocklen - pad;
				if(m > s->maxpad){
					pad = 0;
					m = s->maxpad;
				}
			}
		}

		rv += m;
		if(m != n){
			nb = allocb(m + h + pad);
			memmove(nb->wp + h, m, b->rp);
			nb->wp += m + h;
			b->rp += m;
		} else {
			/* add header */
			nb = padblock(b, h);
			nb->rp -= h;

			/* add pad */
			if(pad)
				nb = padblock(nb, -pad);
			b = 0;
		}
		m += s->diglen;

		/* SSL style count */
		if(pad){
			memset(nb->wp, 0, pad);
			m += pad;
			nb->wp += pad;
		} else
			m |= 0x8000;
		np->rp[0] = (m>>8);
		np->rp[1] = m;

		if(encryptalg)
			encryptb(s, nb);
		else
			digestb(s, nb);

		(*devtab[s->c->type].bwrite)(s->c, nb, offset);

	}
	qunlock(&s->out);
	poperror();

	return rv;
}

long
encryptb(Dstate *s, Block *b)
Block*
sslbread(Chan *c, long n, ulong offset)
{
	ulong n, h;
	int j;
	uchar *p, *ep, *ip;
	DESstate *ds;
	Block *bp, **l;
	uchar count[2];
	int len;
	int pad;

	h = s->diglen + 2;
	USED(offset);

	switch(s->encryptalg){
	case DESEBC:
		ds = s->out.state;
		ep = b->rp + BLEN(b);
		for(p = b->rp + h; 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 + h; p < ep; p += 8)
			bCBCEncrypt(p, ds->ivec, ds->expanded, 8);
		break;
	s = c->aux;
	if(s == 0 || s->state != Established)
		error(Ebadusefd);

	if(waserror()){
		qunlock(&s->in);
		dighangup(s);
		nexterror();
	}
	qlock(&s->in);

	if(s->processed == 0){
	
		/* read in the whole message */
		s->processed = s->unprocessed;
		s->unprocessed =- 0;
		ensure(s, &s->processed, 2);
		consume(&s->processed, count, 2);
		if(count[0] & 0x80){
			len = ((count[0] & 0x7f)<<8) | count[1];
			pad = 0;
		} else {
			len = ((count[0] & 0x3f)<<8) | count[1];
			ensure(s, &s->processed, 1);
			consume(&s->processed, count, 1);
			pad = count[0];
		}
		ensure(s, &s->processed, len);

		/* put remainder on unprocessed */
		i = 0;
		for(b = s->processed; b; b = b->next){
			i = BLEN(b);
			if(i >= len)
				break;
			(*s->func)(b->rp, i, 0, &ss);
			len -= i;
		}
		if(b == 0)
			panic("digestbread");
		if(i > len){
			i -= len;
			s->unprocessed = allocb(i);
			memmove(s->unprocessed->wp, b->rp+len, i);
			s->unprocessed->wp += i;
			b->wp -= i;
		}
			
		if(s->encrypalg)
			decryptb(s, len);
		else
			checkdigestb(s, len);

		if(pad){
			for(b = s->processed; b; b = b->next){
	}

	b = s->processed;
	if(BLEN(b) > n){
		b = allocb(n);
		memmove(b->wp, s->processed->rp, n);
		b->wp += n;
		s->processed->rp += n;
	} else 
		s->processed = b->next;

	qunlock(&s->in);
	poperror();

	return b;
}

long
decryptb(Dstate *s, Block *b)
Block*
decryptb(Dstate *s, Block *b, int len)
{
	ulong n, h;
	uchar *p, *ep;


@@ 549,55 644,64 @@ digestbread(Dstate *s, long n)
	return b;
}

static Block*
sslbread(Chan *c, long n, ulong offset)
void
digestb(Dstate *s, Block *b)
{
	Block *bp;
	uchar count[2];
	int len;
	int pad;

	USED(offset);
	Block *nb;
	uchar *p;
	DigestState ss;
	uchar msgid[4];
	ulong n, h;
	OneWay *w;

	s = c->aux;
	if(s == 0 || s->state != Established)
		error(Ebadusefd);
	w = &s->out;

	if(waserror()){
		qunlock(&s->in);
		dighangup(s);
		nexterror();
	}
	memset(&ss, 0, sizeof(ss));
	h = s->diglen + 2;
	n = BLEN(b) - h;

	qlock(&s->in);
	/* hash secret + message */
	(*s->hf)(w->secret, w->slen, 0, &ss);
	(*s->hf)(nb->rp + h, n, 0, &ss);

	/* get the whole message */
	ensure(s, &s->unprocessed, 2);
	consume(&s->unprocessed, count, 2);
	if(count[0] & 0x80){
		len = ((count[0] & 0x7f)<<8) | count[1];
		pad = 0;
	} else {
		len = ((count[0] & 0x3f)<<8) | count[1];
		ensure(s, &s->unprocessed, 1);
		consume(&s->unprocessed, count, 1);
		pad = count[0];
	}
	ensure(s, &s->unprocessed, len);
		
	if(s->encrypalg)
		b = decryptb(s, len);
	else
		b = digestb(s, len);
	/* hash message id */
	p = msgid;
	n = w->mid++;
	*p++ = n>>24;
	*p++ = n>>16;
	*p++ = n>>8;
	*p = n;
	(*s->func)(msgid, 4, nb->rp + 2, &ss);
}

	if(pad)
long
encryptb(Dstate *s, Block *b)
{
	ulong n, h;
	int j;
	uchar *p, *ep, *ip;
	DESstate *ds;

	qunlock(&s->in);
	poperror();
	h = s->diglen + 2;

	return b;
	switch(s->encryptalg){
	case DESEBC:
		ds = s->out.state;
		ep = b->rp + BLEN(b);
		for(p = b->rp + h; 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 + h; p < ep; p += 8)
			bCBCEncrypt(p, ds->ivec, ds->expanded, 8);
		break;
	}
	
}

/* get channel associated with an fd */
static Chan*
buftochan(char *a, long n)
{


@@ 615,88 719,23 @@ buftochan(char *a, long n)
	return c;
}

/*
 *  use SSL record format, add in count and digest or encrypt
 */
long
sslbwrite(Chan *c, Block *b, ulong offset)
/* hand up a digest connection */
static void
dighangup(Dstate *s)
{
	Dstate *s;
	Block *nb;
	int h, n, m, pad, rv;

	s = c->aux;
	if(s == 0 || s->state != Established)
		error(Ebadusefd);
	Block *b;

	if(waserror()){
		qunlock(&s->out);
		if(b)
			freeb(b);
		dighangup(s);
		nexterror();
	qlock(&s->in);
	for(b = s->processed; b; b = s->processed){
		s->processed = b->next;
		freeb(b);
	}
	qlock(&s->out);

	rv = 0;
	while(b){
		m = n = BLEN(b);
		h = s->diglen + 2;

		/* padded blocks are shorter than unpadded ones (strange) */
		pad = 0;
		if(m > s->max){
			m = s->max;
		} else if(s->blocklen != 1){
			pad = m%s->blocklen;
			if(pad){
				pad = s->blocklen - pad;
				if(m > s->maxpad){
					pad = 0;
					m = s->maxpad;
				}
			}
		}

		rv += m;
		if(m != n){
			nb = allocb(m + h + pad);
			memmove(nb->wp + h, m, nb->rptr);
			nb->wp += m + h;
			b->rp += m;
		} else {
			/* add header */
			nb = padblock(b, h);
			nb->rp -= h;

			/* add pad */
			if(pad)
				nb = padblock(nb, -pad);
			b = 0;
		}

		/* SSL style count */
		if(pad){
			memset(nb->wp, 0, pad);
			m += pad;
			nb->wp += pad;
		} else
			m |= 0x8000;
		np->rp[0] = (m>>8);
		np->rp[1] = m;

		if(encryptalg)
			encryptb(s, nb);
		else
			digestb(s, nb);

		(*devtab[s->c->type].bwrite)(s->c, nb, offset);

	if(s->unprocessed){
		freeb(s->unprocessed);
		s->unprocessed = 0;
	}
	qunlock(&s->out);
	poperror();

	return rv;
	s->state = Closed;
	qunlock(&s->in);
}

/*