plan 9 kernel history: overview | file list | diff list

1995/1215/port/devssl.c (diff list | history)

1995/1213/sys/src/9/port/devssl.c:159,1821995/1215/sys/src/9/port/devssl.c:159,164 (short | long | prev | next)
1995/1213    
	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) 
{ 
1995/1213/sys/src/9/port/devssl.c:335,3961995/1215/sys/src/9/port/devssl.c:317,491
1995/1213    
	return n; 
} 
 
void 
digestb(Dstate *s, Block *b, OneWay *w) 
1995/1215    
/* 
 *  use SSL record format, add in count and digest or encrypt 
 */ 
long 
sslbwrite(Chan *c, Block *b, ulong offset) 
1995/1213    
{ 
1995/1215    
	Dstate *s; 
1995/1213    
	Block *nb; 
	uchar *p; 
	DigestState ss; 
	uchar msgid[4]; 
	ulong n, h; 
1995/1215    
	int h, n, m, pad, rv; 
 
	s = c->aux; 
	if(s == 0 || s->state != Established) 
		error(Ebadusefd); 
 
	if(waserror()){ 
		qunlock(&s->out); 
		if(b) 
			freeb(b); 
		dighangup(s); 
		nexterror(); 
	} 
	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, 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; 
1995/1213    
 
	memset(&ss, 0, sizeof(ss)); 
	h = s->diglen + 2; 
	n = BLEN(b) - h; 
1995/1215    
		if(encryptalg) 
			encryptb(s, nb); 
		else 
			digestb(s, nb); 
1995/1213    
 
	/* hash secret + message */ 
	(*s->hf)(w->secret, w->slen, 0, &ss); 
	(*s->hf)(nb->rp + h, n, 0, &ss); 
1995/1215    
		(*devtab[s->c->type].bwrite)(s->c, nb, offset); 
1995/1213    
 
	/* 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); 
1995/1215    
	} 
	qunlock(&s->out); 
	poperror(); 
 
	return rv; 
1995/1213    
} 
 
long 
encryptb(Dstate *s, Block *b) 
1995/1215    
Block* 
sslbread(Chan *c, long n, ulong offset) 
1995/1213    
{ 
	ulong n, h; 
	int j; 
	uchar *p, *ep, *ip; 
	DESstate *ds; 
1995/1215    
	Block *bp, **l; 
	uchar count[2]; 
	int len; 
	int pad; 
1995/1213    
 
	h = s->diglen + 2; 
1995/1215    
	USED(offset); 
1995/1213    
 
	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; 
1995/1215    
	s = c->aux; 
	if(s == 0 || s->state != Established) 
		error(Ebadusefd); 
 
	if(waserror()){ 
		qunlock(&s->in); 
		dighangup(s); 
		nexterror(); 
1995/1213    
	} 
1995/1215    
	qlock(&s->in); 
 
	if(s->processed == 0){ 
1995/1213    
	 
1995/1215    
		/* 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; 
1995/1213    
} 
 
long 
decryptb(Dstate *s, Block *b) 
1995/1215    
Block* 
decryptb(Dstate *s, Block *b, int len) 
1995/1213    
{ 
	ulong n, h; 
	uchar *p, *ep; 
1995/1213/sys/src/9/port/devssl.c:549,6031995/1215/sys/src/9/port/devssl.c:644,707
1995/1213    
	return b; 
} 
 
static Block* 
sslbread(Chan *c, long n, ulong offset) 
1995/1215    
void 
digestb(Dstate *s, Block *b) 
1995/1213    
{ 
	Block *bp; 
	uchar count[2]; 
	int len; 
	int pad; 
1995/1215    
	Block *nb; 
	uchar *p; 
	DigestState ss; 
	uchar msgid[4]; 
	ulong n, h; 
	OneWay *w; 
1995/1213    
 
	USED(offset); 
1995/1215    
	w = &s->out; 
1995/1213    
 
	s = c->aux; 
	if(s == 0 || s->state != Established) 
		error(Ebadusefd); 
1995/1215    
	memset(&ss, 0, sizeof(ss)); 
	h = s->diglen + 2; 
	n = BLEN(b) - h; 
1995/1213    
 
	if(waserror()){ 
		qunlock(&s->in); 
		dighangup(s); 
		nexterror(); 
	} 
1995/1215    
	/* hash secret + message */ 
	(*s->hf)(w->secret, w->slen, 0, &ss); 
	(*s->hf)(nb->rp + h, n, 0, &ss); 
1995/1213    
 
	qlock(&s->in); 
1995/1215    
	/* 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); 
} 
1995/1213    
 
	/* 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); 
1995/1215    
long 
encryptb(Dstate *s, Block *b) 
{ 
	ulong n, h; 
	int j; 
	uchar *p, *ep, *ip; 
	DESstate *ds; 
1995/1213    
 
	if(pad) 
1995/1215    
	h = s->diglen + 2; 
1995/1213    
 
	qunlock(&s->in); 
	poperror(); 
                 
	return b; 
1995/1215    
	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; 
	} 
	 
1995/1213    
} 
 
1995/1215    
/* get channel associated with an fd */ 
1995/1213    
static Chan* 
buftochan(char *a, long n) 
{ 
1995/1213/sys/src/9/port/devssl.c:615,7021995/1215/sys/src/9/port/devssl.c:719,741
1995/1213    
	return c; 
} 
 
/* 
 *  use SSL record format, add in count and digest or encrypt 
 */ 
long 
sslbwrite(Chan *c, Block *b, ulong offset) 
1995/1215    
/* hand up a digest connection */ 
static void 
dighangup(Dstate *s) 
1995/1213    
{ 
	Dstate *s; 
	Block *nb; 
	int h, n, m, pad, rv; 
1995/1215    
	Block *b; 
1995/1213    
 
	s = c->aux; 
	if(s == 0 || s->state != Established) 
		error(Ebadusefd); 
                 
	if(waserror()){ 
		qunlock(&s->out); 
		if(b) 
			freeb(b); 
		dighangup(s); 
		nexterror(); 
1995/1215    
	qlock(&s->in); 
	for(b = s->processed; b; b = s->processed){ 
		s->processed = b->next; 
		freeb(b); 
1995/1213    
	} 
	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); 
                 
1995/1215    
	if(s->unprocessed){ 
		freeb(s->unprocessed); 
		s->unprocessed = 0; 
1995/1213    
	} 
	qunlock(&s->out); 
	poperror(); 
                 
	return rv; 
1995/1215    
	s->state = Closed; 
	qunlock(&s->in); 
1995/1213    
} 
 
/* 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)