xref: /plan9/sys/src/cmd/unix/drawterm/kern/devtls.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
1 /*
2  *  devtls - record layer for transport layer security 1.0 and secure sockets layer 3.0
3  */
4 #include	"u.h"
5 #include	"lib.h"
6 #include	"dat.h"
7 #include	"fns.h"
8 #include	"error.h"
9 
10 #include	"libsec.h"
11 
12 typedef struct OneWay	OneWay;
13 typedef struct Secret		Secret;
14 typedef struct TlsRec	TlsRec;
15 typedef struct TlsErrs	TlsErrs;
16 
17 enum {
18 	Statlen=	1024,		/* max. length of status or stats message */
19 	/* buffer limits */
20 	MaxRecLen		= 1<<14,	/* max payload length of a record layer message */
21 	MaxCipherRecLen	= MaxRecLen + 2048,
22 	RecHdrLen		= 5,
23 	MaxMacLen		= SHA1dlen,
24 
25 	/* protocol versions we can accept */
26 	TLSVersion		= 0x0301,
27 	SSL3Version		= 0x0300,
28 	ProtocolVersion	= 0x0301,	/* maximum version we speak */
29 	MinProtoVersion	= 0x0300,	/* limits on version we accept */
30 	MaxProtoVersion	= 0x03ff,
31 
32 	/* connection states */
33 	SHandshake	= 1 << 0,	/* doing handshake */
34 	SOpen		= 1 << 1,	/* application data can be sent */
35 	SRClose		= 1 << 2,	/* remote side has closed down */
36 	SLClose		= 1 << 3,	/* sent a close notify alert */
37 	SAlert		= 1 << 5,	/* sending or sent a fatal alert */
38 	SError		= 1 << 6,	/* some sort of error has occured */
39 	SClosed		= 1 << 7,	/* it is all over */
40 
41 	/* record types */
42 	RChangeCipherSpec = 20,
43 	RAlert,
44 	RHandshake,
45 	RApplication,
46 
47 	SSL2ClientHello = 1,
48 	HSSL2ClientHello = 9,  /* local convention;  see tlshand.c */
49 
50 	/* alerts */
51 	ECloseNotify 			= 0,
52 	EUnexpectedMessage 	= 10,
53 	EBadRecordMac 		= 20,
54 	EDecryptionFailed 		= 21,
55 	ERecordOverflow 		= 22,
56 	EDecompressionFailure 	= 30,
57 	EHandshakeFailure 		= 40,
58 	ENoCertificate 			= 41,
59 	EBadCertificate 		= 42,
60 	EUnsupportedCertificate 	= 43,
61 	ECertificateRevoked 		= 44,
62 	ECertificateExpired 		= 45,
63 	ECertificateUnknown 	= 46,
64 	EIllegalParameter 		= 47,
65 	EUnknownCa 			= 48,
66 	EAccessDenied 		= 49,
67 	EDecodeError 			= 50,
68 	EDecryptError 			= 51,
69 	EExportRestriction 		= 60,
70 	EProtocolVersion 		= 70,
71 	EInsufficientSecurity 	= 71,
72 	EInternalError 			= 80,
73 	EUserCanceled 			= 90,
74 	ENoRenegotiation 		= 100,
75 
76 	EMAX = 256
77 };
78 
79 struct Secret
80 {
81 	char		*encalg;	/* name of encryption alg */
82 	char		*hashalg;	/* name of hash alg */
83 	int		(*enc)(Secret*, uchar*, int);
84 	int		(*dec)(Secret*, uchar*, int);
85 	int		(*unpad)(uchar*, int, int);
86 	DigestState	*(*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*);
87 	int		block;		/* encryption block len, 0 if none */
88 	int		maclen;
89 	void		*enckey;
90 	uchar	mackey[MaxMacLen];
91 };
92 
93 struct OneWay
94 {
95 	QLock		io;		/* locks io access */
96 	QLock		seclock;	/* locks secret paramaters */
97 	ulong		seq;
98 	Secret		*sec;		/* cipher in use */
99 	Secret		*new;		/* cipher waiting for enable */
100 };
101 
102 struct TlsRec
103 {
104 	Chan	*c;				/* io channel */
105 	int		ref;				/* serialized by tdlock for atomic destroy */
106 	int		version;			/* version of the protocol we are speaking */
107 	char		verset;			/* version has been set */
108 	char		opened;			/* opened command every issued? */
109 	char		err[ERRMAX];		/* error message to return to handshake requests */
110 	vlong	handin;			/* bytes communicated by the record layer */
111 	vlong	handout;
112 	vlong	datain;
113 	vlong	dataout;
114 
115 	Lock		statelk;
116 	int		state;
117 	int		debug;
118 
119 	/* record layer mac functions for different protocol versions */
120 	void		(*packMac)(Secret*, uchar*, uchar*, uchar*, uchar*, int, uchar*);
121 
122 	/* input side -- protected by in.io */
123 	OneWay		in;
124 	Block		*processed;	/* next bunch of application data */
125 	Block		*unprocessed;	/* data read from c but not parsed into records */
126 
127 	/* handshake queue */
128 	Lock		hqlock;			/* protects hqref, alloc & free of handq, hprocessed */
129 	int		hqref;
130 	Queue		*handq;		/* queue of handshake messages */
131 	Block		*hprocessed;	/* remainder of last block read from handq */
132 	QLock		hqread;		/* protects reads for hprocessed, handq */
133 
134 	/* output side */
135 	OneWay		out;
136 
137 	/* protections */
138 	char		*user;
139 	int		perm;
140 };
141 
142 struct TlsErrs{
143 	int	err;
144 	int	sslerr;
145 	int	tlserr;
146 	int	fatal;
147 	char	*msg;
148 };
149 
150 static TlsErrs tlserrs[] = {
151 	{ECloseNotify,			ECloseNotify,			ECloseNotify,			0, 	"close notify"},
152 	{EUnexpectedMessage,	EUnexpectedMessage,	EUnexpectedMessage, 	1, "unexpected message"},
153 	{EBadRecordMac,		EBadRecordMac,		EBadRecordMac, 		1, "bad record mac"},
154 	{EDecryptionFailed,		EIllegalParameter,		EDecryptionFailed,		1, "decryption failed"},
155 	{ERecordOverflow,		EIllegalParameter,		ERecordOverflow,		1, "record too long"},
156 	{EDecompressionFailure,	EDecompressionFailure,	EDecompressionFailure,	1, "decompression failed"},
157 	{EHandshakeFailure,		EHandshakeFailure,		EHandshakeFailure,		1, "could not negotiate acceptable security parameters"},
158 	{ENoCertificate,		ENoCertificate,			ECertificateUnknown,	1, "no appropriate certificate available"},
159 	{EBadCertificate,		EBadCertificate,		EBadCertificate,		1, "corrupted or invalid certificate"},
160 	{EUnsupportedCertificate,	EUnsupportedCertificate,	EUnsupportedCertificate,	1, "unsupported certificate type"},
161 	{ECertificateRevoked,	ECertificateRevoked,		ECertificateRevoked,		1, "revoked certificate"},
162 	{ECertificateExpired,		ECertificateExpired,		ECertificateExpired,		1, "expired certificate"},
163 	{ECertificateUnknown,	ECertificateUnknown,	ECertificateUnknown,	1, "unacceptable certificate"},
164 	{EIllegalParameter,		EIllegalParameter,		EIllegalParameter,		1, "illegal parameter"},
165 	{EUnknownCa,			EHandshakeFailure,		EUnknownCa,			1, "unknown certificate authority"},
166 	{EAccessDenied,		EHandshakeFailure,		EAccessDenied,		1, "access denied"},
167 	{EDecodeError,			EIllegalParameter,		EDecodeError,			1, "error decoding message"},
168 	{EDecryptError,			EIllegalParameter,		EDecryptError,			1, "error decrypting message"},
169 	{EExportRestriction,		EHandshakeFailure,		EExportRestriction,		1, "export restriction violated"},
170 	{EProtocolVersion,		EIllegalParameter,		EProtocolVersion,		1, "protocol version not supported"},
171 	{EInsufficientSecurity,	EHandshakeFailure,		EInsufficientSecurity,	1, "stronger security routines required"},
172 	{EInternalError,			EHandshakeFailure,		EInternalError,			1, "internal error"},
173 	{EUserCanceled,		ECloseNotify,			EUserCanceled,			0, "handshake canceled by user"},
174 	{ENoRenegotiation,		EUnexpectedMessage,	ENoRenegotiation,		0, "no renegotiation"},
175 };
176 
177 enum
178 {
179 	/* max. open tls connections */
180 	MaxTlsDevs	= 1024
181 };
182 
183 static	Lock	tdlock;
184 static	int	tdhiwat;
185 static	int	maxtlsdevs = 128;
186 static	TlsRec	**tlsdevs;
187 static	char	**trnames;
188 static	char	*encalgs;
189 static	char	*hashalgs;
190 
191 enum{
192 	Qtopdir		= 1,	/* top level directory */
193 	Qprotodir,
194 	Qclonus,
195 	Qencalgs,
196 	Qhashalgs,
197 	Qconvdir,		/* directory for a conversation */
198 	Qdata,
199 	Qctl,
200 	Qhand,
201 	Qstatus,
202 	Qstats,
203 };
204 
205 #define TYPE(x) 	((x).path & 0xf)
206 #define CONV(x) 	(((x).path >> 5)&(MaxTlsDevs-1))
207 #define QID(c, y) 	(((c)<<5) | (y))
208 
209 static void	checkstate(TlsRec *, int, int);
210 static void	ensure(TlsRec*, Block**, int);
211 static void	consume(Block**, uchar*, int);
212 static Chan*	buftochan(char*);
213 static void	tlshangup(TlsRec*);
214 static void	tlsError(TlsRec*, char *);
215 static void	alertHand(TlsRec*, char *);
216 static TlsRec	*newtls(Chan *c);
217 static TlsRec	*mktlsrec(void);
218 static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
219 static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
220 static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s);
221 static void	sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac);
222 static void	tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac);
223 static void	put64(uchar *p, vlong x);
224 static void	put32(uchar *p, u32int);
225 static void	put24(uchar *p, int);
226 static void	put16(uchar *p, int);
227 /* static u32int	get32(uchar *p); */
228 static int	get16(uchar *p);
229 static void	tlsSetState(TlsRec *tr, int new, int old);
230 static void	rcvAlert(TlsRec *tr, int err);
231 static void	sendAlert(TlsRec *tr, int err);
232 static void	rcvError(TlsRec *tr, int err, char *msg, ...);
233 static int	rc4enc(Secret *sec, uchar *buf, int n);
234 static int	des3enc(Secret *sec, uchar *buf, int n);
235 static int	des3dec(Secret *sec, uchar *buf, int n);
236 static int	noenc(Secret *sec, uchar *buf, int n);
237 static int	sslunpad(uchar *buf, int n, int block);
238 static int	tlsunpad(uchar *buf, int n, int block);
239 static void	freeSec(Secret *sec);
240 static char	*tlsstate(int s);
241 static void	pdump(int, void*, char*);
242 
243 static char *tlsnames[] = {
244 	/* unused */ 0,
245 	/* topdir */ 0,
246 	/* protodir */ 0,
247 	"clone",
248 	"encalgs",
249 	"hashalgs",
250 	/* convdir */ 0,
251 	"data",
252 	"ctl",
253 	"hand",
254 	"status",
255 	"stats",
256 };
257 
258 static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats };
259 
260 static int
tlsgen(Chan * c,char * unused1,Dirtab * unused2,int unused3,int s,Dir * dp)261 tlsgen(Chan *c, char*unused1, Dirtab *unused2, int unused3, int s, Dir *dp)
262 {
263 	Qid q;
264 	TlsRec *tr;
265 	char *name, *nm;
266 	int perm, t;
267 
268 	q.vers = 0;
269 	q.type = QTFILE;
270 
271 	t = TYPE(c->qid);
272 	switch(t) {
273 	case Qtopdir:
274 		if(s == DEVDOTDOT){
275 			q.path = QID(0, Qtopdir);
276 			q.type = QTDIR;
277 			devdir(c, q, "#a", 0, eve, 0555, dp);
278 			return 1;
279 		}
280 		if(s > 0)
281 			return -1;
282 		q.path = QID(0, Qprotodir);
283 		q.type = QTDIR;
284 		devdir(c, q, "tls", 0, eve, 0555, dp);
285 		return 1;
286 	case Qprotodir:
287 		if(s == DEVDOTDOT){
288 			q.path = QID(0, Qtopdir);
289 			q.type = QTDIR;
290 			devdir(c, q, ".", 0, eve, 0555, dp);
291 			return 1;
292 		}
293 		if(s < 3){
294 			switch(s) {
295 			default:
296 				return -1;
297 			case 0:
298 				q.path = QID(0, Qclonus);
299 				break;
300 			case 1:
301 				q.path = QID(0, Qencalgs);
302 				break;
303 			case 2:
304 				q.path = QID(0, Qhashalgs);
305 				break;
306 			}
307 			perm = 0444;
308 			if(TYPE(q) == Qclonus)
309 				perm = 0555;
310 			devdir(c, q, tlsnames[TYPE(q)], 0, eve, perm, dp);
311 			return 1;
312 		}
313 		s -= 3;
314 		if(s >= tdhiwat)
315 			return -1;
316 		q.path = QID(s, Qconvdir);
317 		q.type = QTDIR;
318 		lock(&tdlock);
319 		tr = tlsdevs[s];
320 		if(tr != nil)
321 			nm = tr->user;
322 		else
323 			nm = eve;
324 		if((name = trnames[s]) == nil){
325 			name = trnames[s] = smalloc(16);
326 			sprint(name, "%d", s);
327 		}
328 		devdir(c, q, name, 0, nm, 0555, dp);
329 		unlock(&tdlock);
330 		return 1;
331 	case Qconvdir:
332 		if(s == DEVDOTDOT){
333 			q.path = QID(0, Qprotodir);
334 			q.type = QTDIR;
335 			devdir(c, q, "tls", 0, eve, 0555, dp);
336 			return 1;
337 		}
338 		if(s < 0 || s >= nelem(convdir))
339 			return -1;
340 		lock(&tdlock);
341 		tr = tlsdevs[CONV(c->qid)];
342 		if(tr != nil){
343 			nm = tr->user;
344 			perm = tr->perm;
345 		}else{
346 			perm = 0;
347 			nm = eve;
348 		}
349 		t = convdir[s];
350 		if(t == Qstatus || t == Qstats)
351 			perm &= 0444;
352 		q.path = QID(CONV(c->qid), t);
353 		devdir(c, q, tlsnames[t], 0, nm, perm, dp);
354 		unlock(&tdlock);
355 		return 1;
356 	case Qclonus:
357 	case Qencalgs:
358 	case Qhashalgs:
359 		perm = 0444;
360 		if(t == Qclonus)
361 			perm = 0555;
362 		devdir(c, c->qid, tlsnames[t], 0, eve, perm, dp);
363 		return 1;
364 	default:
365 		lock(&tdlock);
366 		tr = tlsdevs[CONV(c->qid)];
367 		if(tr != nil){
368 			nm = tr->user;
369 			perm = tr->perm;
370 		}else{
371 			perm = 0;
372 			nm = eve;
373 		}
374 		if(t == Qstatus || t == Qstats)
375 			perm &= 0444;
376 		devdir(c, c->qid, tlsnames[t], 0, nm, perm, dp);
377 		unlock(&tdlock);
378 		return 1;
379 	}
380 	return -1;
381 }
382 
383 static Chan*
tlsattach(char * spec)384 tlsattach(char *spec)
385 {
386 	Chan *c;
387 
388 	c = devattach('a', spec);
389 	c->qid.path = QID(0, Qtopdir);
390 	c->qid.type = QTDIR;
391 	c->qid.vers = 0;
392 	return c;
393 }
394 
395 static Walkqid*
tlswalk(Chan * c,Chan * nc,char ** name,int nname)396 tlswalk(Chan *c, Chan *nc, char **name, int nname)
397 {
398 	return devwalk(c, nc, name, nname, nil, 0, tlsgen);
399 }
400 
401 static int
tlsstat(Chan * c,uchar * db,int n)402 tlsstat(Chan *c, uchar *db, int n)
403 {
404 	return devstat(c, db, n, nil, 0, tlsgen);
405 }
406 
407 static Chan*
tlsopen(Chan * c,int omode)408 tlsopen(Chan *c, int omode)
409 {
410 	TlsRec *tr, **pp;
411 	int t, perm;
412 
413 	perm = 0;
414 	omode &= 3;
415 	switch(omode) {
416 	case OREAD:
417 		perm = 4;
418 		break;
419 	case OWRITE:
420 		perm = 2;
421 		break;
422 	case ORDWR:
423 		perm = 6;
424 		break;
425 	}
426 
427 	t = TYPE(c->qid);
428 	switch(t) {
429 	default:
430 		panic("tlsopen");
431 	case Qtopdir:
432 	case Qprotodir:
433 	case Qconvdir:
434 		if(omode != OREAD)
435 			error(Eperm);
436 		break;
437 	case Qclonus:
438 		tr = newtls(c);
439 		if(tr == nil)
440 			error(Enodev);
441 		break;
442 	case Qctl:
443 	case Qdata:
444 	case Qhand:
445 	case Qstatus:
446 	case Qstats:
447 		if((t == Qstatus || t == Qstats) && omode != OREAD)
448 			error(Eperm);
449 		if(waserror()) {
450 			unlock(&tdlock);
451 			nexterror();
452 		}
453 		lock(&tdlock);
454 		pp = &tlsdevs[CONV(c->qid)];
455 		tr = *pp;
456 		if(tr == nil)
457 			error("must open connection using clone");
458 		if((perm & (tr->perm>>6)) != perm
459 		&& (strcmp(up->user, tr->user) != 0
460 		    || (perm & tr->perm) != perm))
461 			error(Eperm);
462 		if(t == Qhand){
463 			if(waserror()){
464 				unlock(&tr->hqlock);
465 				nexterror();
466 			}
467 			lock(&tr->hqlock);
468 			if(tr->handq != nil)
469 				error(Einuse);
470 			tr->handq = qopen(2 * MaxCipherRecLen, 0, 0, nil);
471 			if(tr->handq == nil)
472 				error("cannot allocate handshake queue");
473 			tr->hqref = 1;
474 			unlock(&tr->hqlock);
475 			poperror();
476 		}
477 		tr->ref++;
478 		unlock(&tdlock);
479 		poperror();
480 		break;
481 	case Qencalgs:
482 	case Qhashalgs:
483 		if(omode != OREAD)
484 			error(Eperm);
485 		break;
486 	}
487 	c->mode = openmode(omode);
488 	c->flag |= COPEN;
489 	c->offset = 0;
490 	c->iounit = qiomaxatomic;
491 	return c;
492 }
493 
494 static int
tlswstat(Chan * c,uchar * dp,int n)495 tlswstat(Chan *c, uchar *dp, int n)
496 {
497 	Dir *d;
498 	TlsRec *tr;
499 	int rv;
500 
501 	d = nil;
502 	if(waserror()){
503 		free(d);
504 		unlock(&tdlock);
505 		nexterror();
506 	}
507 
508 	lock(&tdlock);
509 	tr = tlsdevs[CONV(c->qid)];
510 	if(tr == nil)
511 		error(Ebadusefd);
512 	if(strcmp(tr->user, up->user) != 0)
513 		error(Eperm);
514 
515 	d = smalloc(n + sizeof *d);
516 	rv = convM2D(dp, n, &d[0], (char*) &d[1]);
517 	if(rv == 0)
518 		error(Eshortstat);
519 	if(!emptystr(d->uid))
520 		kstrdup(&tr->user, d->uid);
521 	if(d->mode != ~0UL)
522 		tr->perm = d->mode;
523 
524 	free(d);
525 	poperror();
526 	unlock(&tdlock);
527 
528 	return rv;
529 }
530 
531 static void
dechandq(TlsRec * tr)532 dechandq(TlsRec *tr)
533 {
534 	lock(&tr->hqlock);
535 	if(--tr->hqref == 0){
536 		if(tr->handq != nil){
537 			qfree(tr->handq);
538 			tr->handq = nil;
539 		}
540 		if(tr->hprocessed != nil){
541 			freeb(tr->hprocessed);
542 			tr->hprocessed = nil;
543 		}
544 	}
545 	unlock(&tr->hqlock);
546 }
547 
548 static void
tlsclose(Chan * c)549 tlsclose(Chan *c)
550 {
551 	TlsRec *tr;
552 	int t;
553 
554 	t = TYPE(c->qid);
555 	switch(t) {
556 	case Qctl:
557 	case Qdata:
558 	case Qhand:
559 	case Qstatus:
560 	case Qstats:
561 		if((c->flag & COPEN) == 0)
562 			break;
563 
564 		tr = tlsdevs[CONV(c->qid)];
565 		if(tr == nil)
566 			break;
567 
568 		if(t == Qhand)
569 			dechandq(tr);
570 
571 		lock(&tdlock);
572 		if(--tr->ref > 0) {
573 			unlock(&tdlock);
574 			return;
575 		}
576 		tlsdevs[CONV(c->qid)] = nil;
577 		unlock(&tdlock);
578 
579 		if(tr->c != nil && !waserror()){
580 			checkstate(tr, 0, SOpen|SHandshake|SRClose);
581 			sendAlert(tr, ECloseNotify);
582 			poperror();
583 		}
584 		tlshangup(tr);
585 		if(tr->c != nil)
586 			cclose(tr->c);
587 		freeSec(tr->in.sec);
588 		freeSec(tr->in.new);
589 		freeSec(tr->out.sec);
590 		freeSec(tr->out.new);
591 		free(tr->user);
592 		free(tr);
593 		break;
594 	}
595 }
596 
597 /*
598  *  make sure we have at least 'n' bytes in list 'l'
599  */
600 static void
ensure(TlsRec * s,Block ** l,int n)601 ensure(TlsRec *s, Block **l, int n)
602 {
603 	int sofar, i;
604 	Block *b, *bl;
605 
606 	sofar = 0;
607 	for(b = *l; b; b = b->next){
608 		sofar += BLEN(b);
609 		if(sofar >= n)
610 			return;
611 		l = &b->next;
612 	}
613 
614 	while(sofar < n){
615 		bl = devtab[s->c->type]->bread(s->c, MaxCipherRecLen + RecHdrLen, 0);
616 		if(bl == 0)
617 			error(Ehungup);
618 		*l = bl;
619 		i = 0;
620 		for(b = bl; b; b = b->next){
621 			i += BLEN(b);
622 			l = &b->next;
623 		}
624 		if(i == 0)
625 			error(Ehungup);
626 		sofar += i;
627 	}
628 if(s->debug) pprint("ensure read %d\n", sofar);
629 }
630 
631 /*
632  *  copy 'n' bytes from 'l' into 'p' and free
633  *  the bytes in 'l'
634  */
635 static void
consume(Block ** l,uchar * p,int n)636 consume(Block **l, uchar *p, int n)
637 {
638 	Block *b;
639 	int i;
640 
641 	for(; *l && n > 0; n -= i){
642 		b = *l;
643 		i = BLEN(b);
644 		if(i > n)
645 			i = n;
646 		memmove(p, b->rp, i);
647 		b->rp += i;
648 		p += i;
649 		if(BLEN(b) < 0)
650 			panic("consume");
651 		if(BLEN(b))
652 			break;
653 		*l = b->next;
654 		freeb(b);
655 	}
656 }
657 
658 /*
659  *  give back n bytes
660  */
661 static void
regurgitate(TlsRec * s,uchar * p,int n)662 regurgitate(TlsRec *s, uchar *p, int n)
663 {
664 	Block *b;
665 
666 	if(n <= 0)
667 		return;
668 	b = s->unprocessed;
669 	if(s->unprocessed == nil || b->rp - b->base < n) {
670 		b = allocb(n);
671 		memmove(b->wp, p, n);
672 		b->wp += n;
673 		b->next = s->unprocessed;
674 		s->unprocessed = b;
675 	} else {
676 		b->rp -= n;
677 		memmove(b->rp, p, n);
678 	}
679 }
680 
681 /*
682  *  remove at most n bytes from the queue
683  */
684 static Block*
qgrab(Block ** l,int n)685 qgrab(Block **l, int n)
686 {
687 	Block *bb, *b;
688 	int i;
689 
690 	b = *l;
691 	if(BLEN(b) == n){
692 		*l = b->next;
693 		b->next = nil;
694 		return b;
695 	}
696 
697 	i = 0;
698 	for(bb = b; bb != nil && i < n; bb = bb->next)
699 		i += BLEN(bb);
700 	if(i > n)
701 		i = n;
702 
703 	bb = allocb(i);
704 	consume(l, bb->wp, i);
705 	bb->wp += i;
706 	return bb;
707 }
708 
709 static void
tlsclosed(TlsRec * tr,int new)710 tlsclosed(TlsRec *tr, int new)
711 {
712 	lock(&tr->statelk);
713 	if(tr->state == SOpen || tr->state == SHandshake)
714 		tr->state = new;
715 	else if((new | tr->state) == (SRClose|SLClose))
716 		tr->state = SClosed;
717 	unlock(&tr->statelk);
718 	alertHand(tr, "close notify");
719 }
720 
721 /*
722  *  read and process one tls record layer message
723  *  must be called with tr->in.io held
724  *  We can't let Eintrs lose data, since doing so will get
725  *  us out of sync with the sender and break the reliablity
726  *  of the channel.  Eintr only happens during the reads in
727  *  consume.  Therefore we put back any bytes consumed before
728  *  the last call to ensure.
729  */
730 static void
tlsrecread(TlsRec * tr)731 tlsrecread(TlsRec *tr)
732 {
733 	OneWay *volatile in;
734 	Block *volatile b;
735 	uchar *p, seq[8], header[RecHdrLen], hmac[MD5dlen];
736 	int volatile nconsumed;
737 	int len, type, ver, unpad_len;
738 
739 	nconsumed = 0;
740 	if(waserror()){
741 		if(strcmp(up->errstr, Eintr) == 0 && !waserror()){
742 			regurgitate(tr, header, nconsumed);
743 			poperror();
744 		}else
745 			tlsError(tr, "channel error");
746 		nexterror();
747 	}
748 	ensure(tr, &tr->unprocessed, RecHdrLen);
749 	consume(&tr->unprocessed, header, RecHdrLen);
750 if(tr->debug)pprint("consumed %d header\n", RecHdrLen);
751 	nconsumed = RecHdrLen;
752 
753 	if((tr->handin == 0) && (header[0] & 0x80)){
754 		/* Cope with an SSL3 ClientHello expressed in SSL2 record format.
755 			This is sent by some clients that we must interoperate
756 			with, such as Java's JSSE and Microsoft's Internet Explorer. */
757 		len = (get16(header) & ~0x8000) - 3;
758 		type = header[2];
759 		ver = get16(header + 3);
760 		if(type != SSL2ClientHello || len < 22)
761 			rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message");
762 	}else{  /* normal SSL3 record format */
763 		type = header[0];
764 		ver = get16(header+1);
765 		len = get16(header+3);
766 	}
767 	if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion))
768 		rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'",
769 			tr->version, tr->verset?"/set":"", len, type, ver, (char*)header);
770 	if(len > MaxCipherRecLen || len < 0)
771 		rcvError(tr, ERecordOverflow, "record message too long %d", len);
772 	ensure(tr, &tr->unprocessed, len);
773 	nconsumed = 0;
774 	poperror();
775 
776 	/*
777 	 * If an Eintr happens after this, we'll get out of sync.
778 	 * Make sure nothing we call can sleep.
779 	 * Errors are ok, as they kill the connection.
780 	 * Luckily, allocb won't sleep, it'll just error out.
781 	 */
782 	b = nil;
783 	if(waserror()){
784 		if(b != nil)
785 			freeb(b);
786 		tlsError(tr, "channel error");
787 		nexterror();
788 	}
789 	b = qgrab(&tr->unprocessed, len);
790 if(tr->debug) pprint("consumed unprocessed %d\n", len);
791 
792 	in = &tr->in;
793 	if(waserror()){
794 		qunlock(&in->seclock);
795 		nexterror();
796 	}
797 	qlock(&in->seclock);
798 	p = b->rp;
799 	if(in->sec != nil) {
800 		/* to avoid Canvel-Hiltgen-Vaudenay-Vuagnoux attack, all errors here
801 		        should look alike, including timing of the response. */
802 		unpad_len = (*in->sec->dec)(in->sec, p, len);
803 		if(unpad_len >= in->sec->maclen)
804 			len = unpad_len - in->sec->maclen;
805 if(tr->debug) pprint("decrypted %d\n", unpad_len);
806 if(tr->debug) pdump(unpad_len, p, "decrypted:");
807 
808 		/* update length */
809 		put16(header+3, len);
810 		put64(seq, in->seq);
811 		in->seq++;
812 		(*tr->packMac)(in->sec, in->sec->mackey, seq, header, p, len, hmac);
813 		if(unpad_len < in->sec->maclen)
814 			rcvError(tr, EBadRecordMac, "short record mac");
815 		if(memcmp(hmac, p+len, in->sec->maclen) != 0)
816 			rcvError(tr, EBadRecordMac, "record mac mismatch");
817 		b->wp = b->rp + len;
818 	}
819 	qunlock(&in->seclock);
820 	poperror();
821 	if(len < 0)
822 		rcvError(tr, EDecodeError, "runt record message");
823 
824 	switch(type) {
825 	default:
826 		rcvError(tr, EIllegalParameter, "invalid record message 0x%x", type);
827 		break;
828 	case RChangeCipherSpec:
829 		if(len != 1 || p[0] != 1)
830 			rcvError(tr, EDecodeError, "invalid change cipher spec");
831 		qlock(&in->seclock);
832 		if(in->new == nil){
833 			qunlock(&in->seclock);
834 			rcvError(tr, EUnexpectedMessage, "unexpected change cipher spec");
835 		}
836 		freeSec(in->sec);
837 		in->sec = in->new;
838 		in->new = nil;
839 		in->seq = 0;
840 		qunlock(&in->seclock);
841 		break;
842 	case RAlert:
843 		if(len != 2)
844 			rcvError(tr, EDecodeError, "invalid alert");
845 		if(p[0] == 2)
846 			rcvAlert(tr, p[1]);
847 		if(p[0] != 1)
848 			rcvError(tr, EIllegalParameter, "invalid alert fatal code");
849 
850 		/*
851 		 * propate non-fatal alerts to handshaker
852 		 */
853 		if(p[1] == ECloseNotify) {
854 			tlsclosed(tr, SRClose);
855 			if(tr->opened)
856 				error("tls hungup");
857 			error("close notify");
858 		}
859 		if(p[1] == ENoRenegotiation)
860 			alertHand(tr, "no renegotiation");
861 		else if(p[1] == EUserCanceled)
862 			alertHand(tr, "handshake canceled by user");
863 		else
864 			rcvError(tr, EIllegalParameter, "invalid alert code");
865 		break;
866 	case RHandshake:
867 		/*
868 		 * don't worry about dropping the block
869 		 * qbwrite always queues even if flow controlled and interrupted.
870 		 *
871 		 * if there isn't any handshaker, ignore the request,
872 		 * but notify the other side we are doing so.
873 		 */
874 		lock(&tr->hqlock);
875 		if(tr->handq != nil){
876 			tr->hqref++;
877 			unlock(&tr->hqlock);
878 			if(waserror()){
879 				dechandq(tr);
880 				nexterror();
881 			}
882 			b = padblock(b, 1);
883 			*b->rp = RHandshake;
884 			qbwrite(tr->handq, b);
885 			b = nil;
886 			poperror();
887 			dechandq(tr);
888 		}else{
889 			unlock(&tr->hqlock);
890 			if(tr->verset && tr->version != SSL3Version && !waserror()){
891 				sendAlert(tr, ENoRenegotiation);
892 				poperror();
893 			}
894 		}
895 		break;
896 	case SSL2ClientHello:
897 		lock(&tr->hqlock);
898 		if(tr->handq != nil){
899 			tr->hqref++;
900 			unlock(&tr->hqlock);
901 			if(waserror()){
902 				dechandq(tr);
903 				nexterror();
904 			}
905 			/* Pass the SSL2 format data, so that the handshake code can compute
906 				the correct checksums.  HSSL2ClientHello = HandshakeType 9 is
907 				unused in RFC2246. */
908 			b = padblock(b, 8);
909 			b->rp[0] = RHandshake;
910 			b->rp[1] = HSSL2ClientHello;
911 			put24(&b->rp[2], len+3);
912 			b->rp[5] = SSL2ClientHello;
913 			put16(&b->rp[6], ver);
914 			qbwrite(tr->handq, b);
915 			b = nil;
916 			poperror();
917 			dechandq(tr);
918 		}else{
919 			unlock(&tr->hqlock);
920 			if(tr->verset && tr->version != SSL3Version && !waserror()){
921 				sendAlert(tr, ENoRenegotiation);
922 				poperror();
923 			}
924 		}
925 		break;
926 	case RApplication:
927 		if(!tr->opened)
928 			rcvError(tr, EUnexpectedMessage, "application message received before handshake completed");
929 		if(BLEN(b) > 0){
930 			tr->processed = b;
931 			b = nil;
932 		}
933 		break;
934 	}
935 	if(b != nil)
936 		freeb(b);
937 	poperror();
938 }
939 
940 /*
941  * got a fatal alert message
942  */
943 static void
rcvAlert(TlsRec * tr,int err)944 rcvAlert(TlsRec *tr, int err)
945 {
946 	char *s;
947 	int i;
948 
949 	s = "unknown error";
950 	for(i=0; i < nelem(tlserrs); i++){
951 		if(tlserrs[i].err == err){
952 			s = tlserrs[i].msg;
953 			break;
954 		}
955 	}
956 if(tr->debug) pprint("rcvAlert: %s\n", s);
957 
958 	tlsError(tr, s);
959 	if(!tr->opened)
960 		error(s);
961 	error("tls error");
962 }
963 
964 /*
965  * found an error while decoding the input stream
966  */
967 static void
rcvError(TlsRec * tr,int err,char * fmt,...)968 rcvError(TlsRec *tr, int err, char *fmt, ...)
969 {
970 	char msg[ERRMAX];
971 	va_list arg;
972 
973 	va_start(arg, fmt);
974 	vseprint(msg, msg+sizeof(msg), fmt, arg);
975 	va_end(arg);
976 if(tr->debug) pprint("rcvError: %s\n", msg);
977 
978 	sendAlert(tr, err);
979 
980 	if(!tr->opened)
981 		error(msg);
982 	error("tls error");
983 }
984 
985 /*
986  * make sure the next hand operation returns with a 'msg' error
987  */
988 static void
alertHand(TlsRec * tr,char * msg)989 alertHand(TlsRec *tr, char *msg)
990 {
991 	Block *b;
992 	int n;
993 
994 	lock(&tr->hqlock);
995 	if(tr->handq == nil){
996 		unlock(&tr->hqlock);
997 		return;
998 	}
999 	tr->hqref++;
1000 	unlock(&tr->hqlock);
1001 
1002 	n = strlen(msg);
1003 	if(waserror()){
1004 		dechandq(tr);
1005 		nexterror();
1006 	}
1007 	b = allocb(n + 2);
1008 	*b->wp++ = RAlert;
1009 	memmove(b->wp, msg, n + 1);
1010 	b->wp += n + 1;
1011 
1012 	qbwrite(tr->handq, b);
1013 
1014 	poperror();
1015 	dechandq(tr);
1016 }
1017 
1018 static void
checkstate(TlsRec * tr,int ishand,int ok)1019 checkstate(TlsRec *tr, int ishand, int ok)
1020 {
1021 	int state;
1022 
1023 	lock(&tr->statelk);
1024 	state = tr->state;
1025 	unlock(&tr->statelk);
1026 	if(state & ok)
1027 		return;
1028 	switch(state){
1029 	case SHandshake:
1030 	case SOpen:
1031 		break;
1032 	case SError:
1033 	case SAlert:
1034 		if(ishand)
1035 			error(tr->err);
1036 		error("tls error");
1037 	case SRClose:
1038 	case SLClose:
1039 	case SClosed:
1040 		error("tls hungup");
1041 	}
1042 	error("tls improperly configured");
1043 }
1044 
1045 static Block*
tlsbread(Chan * c,long n,ulong offset)1046 tlsbread(Chan *c, long n, ulong offset)
1047 {
1048 	int ty;
1049 	Block *b;
1050 	TlsRec *volatile tr;
1051 
1052 	ty = TYPE(c->qid);
1053 	switch(ty) {
1054 	default:
1055 		return devbread(c, n, offset);
1056 	case Qhand:
1057 	case Qdata:
1058 		break;
1059 	}
1060 
1061 	tr = tlsdevs[CONV(c->qid)];
1062 	if(tr == nil)
1063 		panic("tlsbread");
1064 
1065 	if(waserror()){
1066 		qunlock(&tr->in.io);
1067 		nexterror();
1068 	}
1069 	qlock(&tr->in.io);
1070 	if(ty == Qdata){
1071 		checkstate(tr, 0, SOpen);
1072 		while(tr->processed == nil)
1073 			tlsrecread(tr);
1074 
1075 		/* return at most what was asked for */
1076 		b = qgrab(&tr->processed, n);
1077 if(tr->debug) pprint("consumed processed %d\n", BLEN(b));
1078 if(tr->debug) pdump(BLEN(b), b->rp, "consumed:");
1079 		qunlock(&tr->in.io);
1080 		poperror();
1081 		tr->datain += BLEN(b);
1082 	}else{
1083 		checkstate(tr, 1, SOpen|SHandshake|SLClose);
1084 
1085 		/*
1086 		 * it's ok to look at state without the lock
1087 		 * since it only protects reading records,
1088 		 * and we have that tr->in.io held.
1089 		 */
1090 		while(!tr->opened && tr->hprocessed == nil && !qcanread(tr->handq))
1091 			tlsrecread(tr);
1092 
1093 		qunlock(&tr->in.io);
1094 		poperror();
1095 
1096 		if(waserror()){
1097 			qunlock(&tr->hqread);
1098 			nexterror();
1099 		}
1100 		qlock(&tr->hqread);
1101 		if(tr->hprocessed == nil){
1102 			b = qbread(tr->handq, MaxRecLen + 1);
1103 			if(*b->rp++ == RAlert){
1104 				kstrcpy(up->errstr, (char*)b->rp, ERRMAX);
1105 				freeb(b);
1106 				nexterror();
1107 			}
1108 			tr->hprocessed = b;
1109 		}
1110 		b = qgrab(&tr->hprocessed, n);
1111 		poperror();
1112 		qunlock(&tr->hqread);
1113 		tr->handin += BLEN(b);
1114 	}
1115 
1116 	return b;
1117 }
1118 
1119 static long
tlsread(Chan * c,void * a,long n,vlong off)1120 tlsread(Chan *c, void *a, long n, vlong off)
1121 {
1122 	Block *volatile b;
1123 	Block *nb;
1124 	uchar *va;
1125 	int i, ty;
1126 	char *buf, *s, *e;
1127 	ulong offset = off;
1128 	TlsRec * tr;
1129 
1130 	if(c->qid.type & QTDIR)
1131 		return devdirread(c, a, n, 0, 0, tlsgen);
1132 
1133 	tr = tlsdevs[CONV(c->qid)];
1134 	ty = TYPE(c->qid);
1135 	switch(ty) {
1136 	default:
1137 		error(Ebadusefd);
1138 	case Qstatus:
1139 		buf = smalloc(Statlen);
1140 		qlock(&tr->in.seclock);
1141 		qlock(&tr->out.seclock);
1142 		s = buf;
1143 		e = buf + Statlen;
1144 		s = seprint(s, e, "State: %s\n", tlsstate(tr->state));
1145 		s = seprint(s, e, "Version: 0x%x\n", tr->version);
1146 		if(tr->in.sec != nil)
1147 			s = seprint(s, e, "EncIn: %s\nHashIn: %s\n", tr->in.sec->encalg, tr->in.sec->hashalg);
1148 		if(tr->in.new != nil)
1149 			s = seprint(s, e, "NewEncIn: %s\nNewHashIn: %s\n", tr->in.new->encalg, tr->in.new->hashalg);
1150 		if(tr->out.sec != nil)
1151 			s = seprint(s, e, "EncOut: %s\nHashOut: %s\n", tr->out.sec->encalg, tr->out.sec->hashalg);
1152 		if(tr->out.new != nil)
1153 			seprint(s, e, "NewEncOut: %s\nNewHashOut: %s\n", tr->out.new->encalg, tr->out.new->hashalg);
1154 		qunlock(&tr->in.seclock);
1155 		qunlock(&tr->out.seclock);
1156 		n = readstr(offset, a, n, buf);
1157 		free(buf);
1158 		return n;
1159 	case Qstats:
1160 		buf = smalloc(Statlen);
1161 		s = buf;
1162 		e = buf + Statlen;
1163 		s = seprint(s, e, "DataIn: %lld\n", tr->datain);
1164 		s = seprint(s, e, "DataOut: %lld\n", tr->dataout);
1165 		s = seprint(s, e, "HandIn: %lld\n", tr->handin);
1166 		seprint(s, e, "HandOut: %lld\n", tr->handout);
1167 		n = readstr(offset, a, n, buf);
1168 		free(buf);
1169 		return n;
1170 	case Qctl:
1171 		buf = smalloc(Statlen);
1172 		snprint(buf, Statlen, "%llud", CONV(c->qid));
1173 		n = readstr(offset, a, n, buf);
1174 		free(buf);
1175 		return n;
1176 	case Qdata:
1177 	case Qhand:
1178 		b = tlsbread(c, n, offset);
1179 		break;
1180 	case Qencalgs:
1181 		return readstr(offset, a, n, encalgs);
1182 	case Qhashalgs:
1183 		return readstr(offset, a, n, hashalgs);
1184 	}
1185 
1186 	if(waserror()){
1187 		freeblist(b);
1188 		nexterror();
1189 	}
1190 
1191 	n = 0;
1192 	va = a;
1193 	for(nb = b; nb; nb = nb->next){
1194 		i = BLEN(nb);
1195 		memmove(va+n, nb->rp, i);
1196 		n += i;
1197 	}
1198 
1199 	freeblist(b);
1200 	poperror();
1201 
1202 	return n;
1203 }
1204 
1205 /*
1206  *  write a block in tls records
1207  */
1208 static void
tlsrecwrite(TlsRec * tr,int type,Block * b)1209 tlsrecwrite(TlsRec *tr, int type, Block *b)
1210 {
1211 	Block *volatile bb;
1212 	Block *nb;
1213 	uchar *p, seq[8];
1214 	OneWay *volatile out;
1215 	int n, maclen, pad, ok;
1216 
1217 	out = &tr->out;
1218 	bb = b;
1219 	if(waserror()){
1220 		qunlock(&out->io);
1221 		if(bb != nil)
1222 			freeb(bb);
1223 		nexterror();
1224 	}
1225 	qlock(&out->io);
1226 if(tr->debug)pprint("send %d\n", BLEN(b));
1227 if(tr->debug)pdump(BLEN(b), b->rp, "sent:");
1228 
1229 
1230 	ok = SHandshake|SOpen|SRClose;
1231 	if(type == RAlert)
1232 		ok |= SAlert;
1233 	while(bb != nil){
1234 		checkstate(tr, type != RApplication, ok);
1235 
1236 		/*
1237 		 * get at most one maximal record's input,
1238 		 * with padding on the front for header and
1239 		 * back for mac and maximal block padding.
1240 		 */
1241 		if(waserror()){
1242 			qunlock(&out->seclock);
1243 			nexterror();
1244 		}
1245 		qlock(&out->seclock);
1246 		maclen = 0;
1247 		pad = 0;
1248 		if(out->sec != nil){
1249 			maclen = out->sec->maclen;
1250 			pad = maclen + out->sec->block;
1251 		}
1252 		n = BLEN(bb);
1253 		if(n > MaxRecLen){
1254 			n = MaxRecLen;
1255 			nb = allocb(n + pad + RecHdrLen);
1256 			memmove(nb->wp + RecHdrLen, bb->rp, n);
1257 			bb->rp += n;
1258 		}else{
1259 			/*
1260 			 * carefully reuse bb so it will get freed if we're out of memory
1261 			 */
1262 			bb = padblock(bb, RecHdrLen);
1263 			if(pad)
1264 				nb = padblock(bb, -pad);
1265 			else
1266 				nb = bb;
1267 			bb = nil;
1268 		}
1269 
1270 		p = nb->rp;
1271 		p[0] = type;
1272 		put16(p+1, tr->version);
1273 		put16(p+3, n);
1274 
1275 		if(out->sec != nil){
1276 			put64(seq, out->seq);
1277 			out->seq++;
1278 			(*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, p + RecHdrLen + n);
1279 			n += maclen;
1280 
1281 			/* encrypt */
1282 			n = (*out->sec->enc)(out->sec, p + RecHdrLen, n);
1283 			nb->wp = p + RecHdrLen + n;
1284 
1285 			/* update length */
1286 			put16(p+3, n);
1287 		}
1288 		if(type == RChangeCipherSpec){
1289 			if(out->new == nil)
1290 				error("change cipher without a new cipher");
1291 			freeSec(out->sec);
1292 			out->sec = out->new;
1293 			out->new = nil;
1294 			out->seq = 0;
1295 		}
1296 		qunlock(&out->seclock);
1297 		poperror();
1298 
1299 		/*
1300 		 * if bwrite error's, we assume the block is queued.
1301 		 * if not, we're out of sync with the receiver and will not recover.
1302 		 */
1303 		if(waserror()){
1304 			if(strcmp(up->errstr, "interrupted") != 0)
1305 				tlsError(tr, "channel error");
1306 			nexterror();
1307 		}
1308 		devtab[tr->c->type]->bwrite(tr->c, nb, 0);
1309 		poperror();
1310 	}
1311 	qunlock(&out->io);
1312 	poperror();
1313 }
1314 
1315 static long
tlsbwrite(Chan * c,Block * b,ulong offset)1316 tlsbwrite(Chan *c, Block *b, ulong offset)
1317 {
1318 	int ty;
1319 	ulong n;
1320 	TlsRec *tr;
1321 
1322 	n = BLEN(b);
1323 
1324 	tr = tlsdevs[CONV(c->qid)];
1325 	if(tr == nil)
1326 		panic("tlsbread");
1327 
1328 	ty = TYPE(c->qid);
1329 	switch(ty) {
1330 	default:
1331 		return devbwrite(c, b, offset);
1332 	case Qhand:
1333 		tlsrecwrite(tr, RHandshake, b);
1334 		tr->handout += n;
1335 		break;
1336 	case Qdata:
1337 		checkstate(tr, 0, SOpen);
1338 		tlsrecwrite(tr, RApplication, b);
1339 		tr->dataout += n;
1340 		break;
1341 	}
1342 
1343 	return n;
1344 }
1345 
1346 typedef struct Hashalg Hashalg;
1347 struct Hashalg
1348 {
1349 	char	*name;
1350 	int	maclen;
1351 	void	(*initkey)(Hashalg *, int, Secret *, uchar*);
1352 };
1353 
1354 static void
initmd5key(Hashalg * ha,int version,Secret * s,uchar * p)1355 initmd5key(Hashalg *ha, int version, Secret *s, uchar *p)
1356 {
1357 	s->maclen = ha->maclen;
1358 	if(version == SSL3Version)
1359 		s->mac = sslmac_md5;
1360 	else
1361 		s->mac = hmac_md5;
1362 	memmove(s->mackey, p, ha->maclen);
1363 }
1364 
1365 static void
initclearmac(Hashalg * unused1,int unused2,Secret * s,uchar * unused3)1366 initclearmac(Hashalg *unused1, int unused2, Secret *s, uchar *unused3)
1367 {
1368 	s->maclen = 0;
1369 	s->mac = nomac;
1370 }
1371 
1372 static void
initsha1key(Hashalg * ha,int version,Secret * s,uchar * p)1373 initsha1key(Hashalg *ha, int version, Secret *s, uchar *p)
1374 {
1375 	s->maclen = ha->maclen;
1376 	if(version == SSL3Version)
1377 		s->mac = sslmac_sha1;
1378 	else
1379 		s->mac = hmac_sha1;
1380 	memmove(s->mackey, p, ha->maclen);
1381 }
1382 
1383 static Hashalg hashtab[] =
1384 {
1385 	{ "clear", 0, initclearmac, },
1386 	{ "md5", MD5dlen, initmd5key, },
1387 	{ "sha1", SHA1dlen, initsha1key, },
1388 	{ 0 }
1389 };
1390 
1391 static Hashalg*
parsehashalg(char * p)1392 parsehashalg(char *p)
1393 {
1394 	Hashalg *ha;
1395 
1396 	for(ha = hashtab; ha->name; ha++)
1397 		if(strcmp(p, ha->name) == 0)
1398 			return ha;
1399 	error("unsupported hash algorithm");
1400 	return nil;
1401 }
1402 
1403 typedef struct Encalg Encalg;
1404 struct Encalg
1405 {
1406 	char	*name;
1407 	int	keylen;
1408 	int	ivlen;
1409 	void	(*initkey)(Encalg *ea, Secret *, uchar*, uchar*);
1410 };
1411 
1412 static void
initRC4key(Encalg * ea,Secret * s,uchar * p,uchar * unused1)1413 initRC4key(Encalg *ea, Secret *s, uchar *p, uchar *unused1)
1414 {
1415 	s->enckey = smalloc(sizeof(RC4state));
1416 	s->enc = rc4enc;
1417 	s->dec = rc4enc;
1418 	s->block = 0;
1419 	setupRC4state(s->enckey, p, ea->keylen);
1420 }
1421 
1422 static void
initDES3key(Encalg * unused1,Secret * s,uchar * p,uchar * iv)1423 initDES3key(Encalg *unused1, Secret *s, uchar *p, uchar *iv)
1424 {
1425 	s->enckey = smalloc(sizeof(DES3state));
1426 	s->enc = des3enc;
1427 	s->dec = des3dec;
1428 	s->block = 8;
1429 	setupDES3state(s->enckey, (uchar(*)[8])p, iv);
1430 }
1431 
1432 static void
initclearenc(Encalg * unused1,Secret * s,uchar * unused2,uchar * unused3)1433 initclearenc(Encalg *unused1, Secret *s, uchar *unused2, uchar *unused3)
1434 {
1435 	s->enc = noenc;
1436 	s->dec = noenc;
1437 	s->block = 0;
1438 }
1439 
1440 static Encalg encrypttab[] =
1441 {
1442 	{ "clear", 0, 0, initclearenc },
1443 	{ "rc4_128", 128/8, 0, initRC4key },
1444 	{ "3des_ede_cbc", 3 * 8, 8, initDES3key },
1445 	{ 0 }
1446 };
1447 
1448 static Encalg*
parseencalg(char * p)1449 parseencalg(char *p)
1450 {
1451 	Encalg *ea;
1452 
1453 	for(ea = encrypttab; ea->name; ea++)
1454 		if(strcmp(p, ea->name) == 0)
1455 			return ea;
1456 	error("unsupported encryption algorithm");
1457 	return nil;
1458 }
1459 
1460 static long
tlswrite(Chan * c,void * a,long n,vlong off)1461 tlswrite(Chan *c, void *a, long n, vlong off)
1462 {
1463 	Encalg *ea;
1464 	Hashalg *ha;
1465 	TlsRec *volatile tr;
1466 	Secret *volatile tos, *volatile toc;
1467 	Block *volatile b;
1468 	Cmdbuf *volatile cb;
1469 	int m, ty;
1470 	char *p, *e;
1471 	uchar *volatile x;
1472 	ulong offset = off;
1473 
1474 	tr = tlsdevs[CONV(c->qid)];
1475 	if(tr == nil)
1476 		panic("tlswrite");
1477 
1478 	ty = TYPE(c->qid);
1479 	switch(ty){
1480 	case Qdata:
1481 	case Qhand:
1482 		p = a;
1483 		e = p + n;
1484 		do{
1485 			m = e - p;
1486 			if(m > MaxRecLen)
1487 				m = MaxRecLen;
1488 
1489 			b = allocb(m);
1490 			if(waserror()){
1491 				freeb(b);
1492 				nexterror();
1493 			}
1494 			memmove(b->wp, p, m);
1495 			poperror();
1496 			b->wp += m;
1497 
1498 			tlsbwrite(c, b, offset);
1499 
1500 			p += m;
1501 		}while(p < e);
1502 		return n;
1503 	case Qctl:
1504 		break;
1505 	default:
1506 		error(Ebadusefd);
1507 		return -1;
1508 	}
1509 
1510 	cb = parsecmd(a, n);
1511 	if(waserror()){
1512 		free(cb);
1513 		nexterror();
1514 	}
1515 	if(cb->nf < 1)
1516 		error("short control request");
1517 
1518 	/* mutex with operations using what we're about to change */
1519 	if(waserror()){
1520 		qunlock(&tr->in.seclock);
1521 		qunlock(&tr->out.seclock);
1522 		nexterror();
1523 	}
1524 	qlock(&tr->in.seclock);
1525 	qlock(&tr->out.seclock);
1526 
1527 	if(strcmp(cb->f[0], "fd") == 0){
1528 		if(cb->nf != 3)
1529 			error("usage: fd open-fd version");
1530 		if(tr->c != nil)
1531 			error(Einuse);
1532 		m = strtol(cb->f[2], nil, 0);
1533 		if(m < MinProtoVersion || m > MaxProtoVersion)
1534 			error("unsupported version");
1535 		tr->c = buftochan(cb->f[1]);
1536 		tr->version = m;
1537 		tlsSetState(tr, SHandshake, SClosed);
1538 	}else if(strcmp(cb->f[0], "version") == 0){
1539 		if(cb->nf != 2)
1540 			error("usage: version vers");
1541 		if(tr->c == nil)
1542 			error("must set fd before version");
1543 		if(tr->verset)
1544 			error("version already set");
1545 		m = strtol(cb->f[1], nil, 0);
1546 		if(m == SSL3Version)
1547 			tr->packMac = sslPackMac;
1548 		else if(m == TLSVersion)
1549 			tr->packMac = tlsPackMac;
1550 		else
1551 			error("unsupported version");
1552 		tr->verset = 1;
1553 		tr->version = m;
1554 	}else if(strcmp(cb->f[0], "secret") == 0){
1555 		if(cb->nf != 5)
1556 			error("usage: secret hashalg encalg isclient secretdata");
1557 		if(tr->c == nil || !tr->verset)
1558 			error("must set fd and version before secrets");
1559 
1560 		if(tr->in.new != nil){
1561 			freeSec(tr->in.new);
1562 			tr->in.new = nil;
1563 		}
1564 		if(tr->out.new != nil){
1565 			freeSec(tr->out.new);
1566 			tr->out.new = nil;
1567 		}
1568 
1569 		ha = parsehashalg(cb->f[1]);
1570 		ea = parseencalg(cb->f[2]);
1571 
1572 		p = cb->f[4];
1573 		m = (strlen(p)*3)/2;
1574 		x = smalloc(m);
1575 		tos = nil;
1576 		toc = nil;
1577 		if(waserror()){
1578 			freeSec(tos);
1579 			freeSec(toc);
1580 			free(x);
1581 			nexterror();
1582 		}
1583 		m = dec64(x, m, p, strlen(p));
1584 		if(m < 2 * ha->maclen + 2 * ea->keylen + 2 * ea->ivlen)
1585 			error("not enough secret data provided");
1586 
1587 		tos = smalloc(sizeof(Secret));
1588 		toc = smalloc(sizeof(Secret));
1589 		if(!ha->initkey || !ea->initkey)
1590 			error("misimplemented secret algorithm");
1591 		(*ha->initkey)(ha, tr->version, tos, &x[0]);
1592 		(*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]);
1593 		(*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]);
1594 		(*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]);
1595 
1596 		if(!tos->mac || !tos->enc || !tos->dec
1597 		|| !toc->mac || !toc->enc || !toc->dec)
1598 			error("missing algorithm implementations");
1599 		if(strtol(cb->f[3], nil, 0) == 0){
1600 			tr->in.new = tos;
1601 			tr->out.new = toc;
1602 		}else{
1603 			tr->in.new = toc;
1604 			tr->out.new = tos;
1605 		}
1606 		if(tr->version == SSL3Version){
1607 			toc->unpad = sslunpad;
1608 			tos->unpad = sslunpad;
1609 		}else{
1610 			toc->unpad = tlsunpad;
1611 			tos->unpad = tlsunpad;
1612 		}
1613 		toc->encalg = ea->name;
1614 		toc->hashalg = ha->name;
1615 		tos->encalg = ea->name;
1616 		tos->hashalg = ha->name;
1617 
1618 		free(x);
1619 		poperror();
1620 	}else if(strcmp(cb->f[0], "changecipher") == 0){
1621 		if(cb->nf != 1)
1622 			error("usage: changecipher");
1623 		if(tr->out.new == nil)
1624 			error("cannot change cipher spec without setting secret");
1625 
1626 		qunlock(&tr->in.seclock);
1627 		qunlock(&tr->out.seclock);
1628 		poperror();
1629 		free(cb);
1630 		poperror();
1631 
1632 		/*
1633 		 * the real work is done as the message is written
1634 		 * so the stream is encrypted in sync.
1635 		 */
1636 		b = allocb(1);
1637 		*b->wp++ = 1;
1638 		tlsrecwrite(tr, RChangeCipherSpec, b);
1639 		return n;
1640 	}else if(strcmp(cb->f[0], "opened") == 0){
1641 		if(cb->nf != 1)
1642 			error("usage: opened");
1643 		if(tr->in.sec == nil || tr->out.sec == nil)
1644 			error("cipher must be configured before enabling data messages");
1645 		lock(&tr->statelk);
1646 		if(tr->state != SHandshake && tr->state != SOpen){
1647 			unlock(&tr->statelk);
1648 			error("cannot enable data messages");
1649 		}
1650 		tr->state = SOpen;
1651 		unlock(&tr->statelk);
1652 		tr->opened = 1;
1653 	}else if(strcmp(cb->f[0], "alert") == 0){
1654 		if(cb->nf != 2)
1655 			error("usage: alert n");
1656 		if(tr->c == nil)
1657 			error("must set fd before sending alerts");
1658 		m = strtol(cb->f[1], nil, 0);
1659 
1660 		qunlock(&tr->in.seclock);
1661 		qunlock(&tr->out.seclock);
1662 		poperror();
1663 		free(cb);
1664 		poperror();
1665 
1666 		sendAlert(tr, m);
1667 
1668 		if(m == ECloseNotify)
1669 			tlsclosed(tr, SLClose);
1670 
1671 		return n;
1672 	} else if(strcmp(cb->f[0], "debug") == 0){
1673 		if(cb->nf == 2){
1674 			if(strcmp(cb->f[1], "on") == 0)
1675 				tr->debug = 1;
1676 			else
1677 				tr->debug = 0;
1678 		} else
1679 			tr->debug = 1;
1680 	} else
1681 		error(Ebadarg);
1682 
1683 	qunlock(&tr->in.seclock);
1684 	qunlock(&tr->out.seclock);
1685 	poperror();
1686 	free(cb);
1687 	poperror();
1688 
1689 	return n;
1690 }
1691 
1692 static void
tlsinit(void)1693 tlsinit(void)
1694 {
1695 	struct Encalg *e;
1696 	struct Hashalg *h;
1697 	int n;
1698 	char *cp;
1699 	static int already;
1700 
1701 	if(!already){
1702 		fmtinstall('H', encodefmt);
1703 		already = 1;
1704 	}
1705 
1706 	tlsdevs = smalloc(sizeof(TlsRec*) * maxtlsdevs);
1707 	trnames = smalloc((sizeof *trnames) * maxtlsdevs);
1708 
1709 	n = 1;
1710 	for(e = encrypttab; e->name != nil; e++)
1711 		n += strlen(e->name) + 1;
1712 	cp = encalgs = smalloc(n);
1713 	for(e = encrypttab;;){
1714 		strcpy(cp, e->name);
1715 		cp += strlen(e->name);
1716 		e++;
1717 		if(e->name == nil)
1718 			break;
1719 		*cp++ = ' ';
1720 	}
1721 	*cp = 0;
1722 
1723 	n = 1;
1724 	for(h = hashtab; h->name != nil; h++)
1725 		n += strlen(h->name) + 1;
1726 	cp = hashalgs = smalloc(n);
1727 	for(h = hashtab;;){
1728 		strcpy(cp, h->name);
1729 		cp += strlen(h->name);
1730 		h++;
1731 		if(h->name == nil)
1732 			break;
1733 		*cp++ = ' ';
1734 	}
1735 	*cp = 0;
1736 }
1737 
1738 Dev tlsdevtab = {
1739 	'a',
1740 	"tls",
1741 
1742 	devreset,
1743 	tlsinit,
1744 	devshutdown,
1745 	tlsattach,
1746 	tlswalk,
1747 	tlsstat,
1748 	tlsopen,
1749 	devcreate,
1750 	tlsclose,
1751 	tlsread,
1752 	tlsbread,
1753 	tlswrite,
1754 	tlsbwrite,
1755 	devremove,
1756 	tlswstat,
1757 };
1758 
1759 /* get channel associated with an fd */
1760 static Chan*
buftochan(char * p)1761 buftochan(char *p)
1762 {
1763 	Chan *c;
1764 	int fd;
1765 
1766 	if(p == 0)
1767 		error(Ebadarg);
1768 	fd = strtoul(p, 0, 0);
1769 	if(fd < 0)
1770 		error(Ebadarg);
1771 	c = fdtochan(fd, -1, 0, 1);	/* error check and inc ref */
1772 	return c;
1773 }
1774 
1775 static void
sendAlert(TlsRec * tr,int err)1776 sendAlert(TlsRec *tr, int err)
1777 {
1778 	Block *b;
1779 	int i, fatal;
1780 	char *msg;
1781 
1782 if(tr->debug)pprint("sendAlert %d\n", err);
1783 	fatal = 1;
1784 	msg = "tls unknown alert";
1785 	for(i=0; i < nelem(tlserrs); i++) {
1786 		if(tlserrs[i].err == err) {
1787 			msg = tlserrs[i].msg;
1788 			if(tr->version == SSL3Version)
1789 				err = tlserrs[i].sslerr;
1790 			else
1791 				err = tlserrs[i].tlserr;
1792 			fatal = tlserrs[i].fatal;
1793 			break;
1794 		}
1795 	}
1796 
1797 	if(!waserror()){
1798 		b = allocb(2);
1799 		*b->wp++ = fatal + 1;
1800 		*b->wp++ = err;
1801 		if(fatal)
1802 			tlsSetState(tr, SAlert, SOpen|SHandshake|SRClose);
1803 		tlsrecwrite(tr, RAlert, b);
1804 		poperror();
1805 	}
1806 	if(fatal)
1807 		tlsError(tr, msg);
1808 }
1809 
1810 static void
tlsError(TlsRec * tr,char * msg)1811 tlsError(TlsRec *tr, char *msg)
1812 {
1813 	int s;
1814 
1815 if(tr->debug)pprint("tleError %s\n", msg);
1816 	lock(&tr->statelk);
1817 	s = tr->state;
1818 	tr->state = SError;
1819 	if(s != SError){
1820 		strncpy(tr->err, msg, ERRMAX - 1);
1821 		tr->err[ERRMAX - 1] = '\0';
1822 	}
1823 	unlock(&tr->statelk);
1824 	if(s != SError)
1825 		alertHand(tr, msg);
1826 }
1827 
1828 static void
tlsSetState(TlsRec * tr,int new,int old)1829 tlsSetState(TlsRec *tr, int new, int old)
1830 {
1831 	lock(&tr->statelk);
1832 	if(tr->state & old)
1833 		tr->state = new;
1834 	unlock(&tr->statelk);
1835 }
1836 
1837 /* hand up a digest connection */
1838 static void
tlshangup(TlsRec * tr)1839 tlshangup(TlsRec *tr)
1840 {
1841 	Block *b;
1842 
1843 	qlock(&tr->in.io);
1844 	for(b = tr->processed; b; b = tr->processed){
1845 		tr->processed = b->next;
1846 		freeb(b);
1847 	}
1848 	if(tr->unprocessed != nil){
1849 		freeb(tr->unprocessed);
1850 		tr->unprocessed = nil;
1851 	}
1852 	qunlock(&tr->in.io);
1853 
1854 	tlsSetState(tr, SClosed, ~0);
1855 }
1856 
1857 static TlsRec*
newtls(Chan * ch)1858 newtls(Chan *ch)
1859 {
1860 	TlsRec **pp, **ep, **np;
1861 	char **nmp;
1862 	int t, newmax;
1863 
1864 	if(waserror()) {
1865 		unlock(&tdlock);
1866 		nexterror();
1867 	}
1868 	lock(&tdlock);
1869 	ep = &tlsdevs[maxtlsdevs];
1870 	for(pp = tlsdevs; pp < ep; pp++)
1871 		if(*pp == nil)
1872 			break;
1873 	if(pp >= ep) {
1874 		if(maxtlsdevs >= MaxTlsDevs) {
1875 			unlock(&tdlock);
1876 			poperror();
1877 			return nil;
1878 		}
1879 		newmax = 2 * maxtlsdevs;
1880 		if(newmax > MaxTlsDevs)
1881 			newmax = MaxTlsDevs;
1882 		np = smalloc(sizeof(TlsRec*) * newmax);
1883 		memmove(np, tlsdevs, sizeof(TlsRec*) * maxtlsdevs);
1884 		tlsdevs = np;
1885 		pp = &tlsdevs[maxtlsdevs];
1886 		memset(pp, 0, sizeof(TlsRec*)*(newmax - maxtlsdevs));
1887 
1888 		nmp = smalloc(sizeof *nmp * newmax);
1889 		memmove(nmp, trnames, sizeof *nmp * maxtlsdevs);
1890 		trnames = nmp;
1891 
1892 		maxtlsdevs = newmax;
1893 	}
1894 	*pp = mktlsrec();
1895 	if(pp - tlsdevs >= tdhiwat)
1896 		tdhiwat++;
1897 	t = TYPE(ch->qid);
1898 	if(t == Qclonus)
1899 		t = Qctl;
1900 	ch->qid.path = QID(pp - tlsdevs, t);
1901 	ch->qid.vers = 0;
1902 	unlock(&tdlock);
1903 	poperror();
1904 	return *pp;
1905 }
1906 
1907 static TlsRec *
mktlsrec(void)1908 mktlsrec(void)
1909 {
1910 	TlsRec *tr;
1911 
1912 	tr = mallocz(sizeof(*tr), 1);
1913 	if(tr == nil)
1914 		error(Enomem);
1915 	tr->state = SClosed;
1916 	tr->ref = 1;
1917 	kstrdup(&tr->user, up->user);
1918 	tr->perm = 0660;
1919 	return tr;
1920 }
1921 
1922 static char*
tlsstate(int s)1923 tlsstate(int s)
1924 {
1925 	switch(s){
1926 	case SHandshake:
1927 		return "Handshaking";
1928 	case SOpen:
1929 		return "Established";
1930 	case SRClose:
1931 		return "RemoteClosed";
1932 	case SLClose:
1933 		return "LocalClosed";
1934 	case SAlert:
1935 		return "Alerting";
1936 	case SError:
1937 		return "Errored";
1938 	case SClosed:
1939 		return "Closed";
1940 	}
1941 	return "Unknown";
1942 }
1943 
1944 static void
freeSec(Secret * s)1945 freeSec(Secret *s)
1946 {
1947 	if(s != nil){
1948 		free(s->enckey);
1949 		free(s);
1950 	}
1951 }
1952 
1953 static int
noenc(Secret * unused1,uchar * unused2,int n)1954 noenc(Secret *unused1, uchar *unused2, int n)
1955 {
1956 	return n;
1957 }
1958 
1959 static int
rc4enc(Secret * sec,uchar * buf,int n)1960 rc4enc(Secret *sec, uchar *buf, int n)
1961 {
1962 	rc4(sec->enckey, buf, n);
1963 	return n;
1964 }
1965 
1966 static int
tlsunpad(uchar * buf,int n,int block)1967 tlsunpad(uchar *buf, int n, int block)
1968 {
1969 	int pad, nn;
1970 
1971 	pad = buf[n - 1];
1972 	nn = n - 1 - pad;
1973 	if(nn <= 0 || n % block)
1974 		return -1;
1975 	while(--n > nn)
1976 		if(pad != buf[n - 1])
1977 			return -1;
1978 	return nn;
1979 }
1980 
1981 static int
sslunpad(uchar * buf,int n,int block)1982 sslunpad(uchar *buf, int n, int block)
1983 {
1984 	int pad, nn;
1985 
1986 	pad = buf[n - 1];
1987 	nn = n - 1 - pad;
1988 	if(nn <= 0 || n % block)
1989 		return -1;
1990 	return nn;
1991 }
1992 
1993 static int
blockpad(uchar * buf,int n,int block)1994 blockpad(uchar *buf, int n, int block)
1995 {
1996 	int pad, nn;
1997 
1998 	nn = n + block;
1999 	nn -= nn % block;
2000 	pad = nn - (n + 1);
2001 	while(n < nn)
2002 		buf[n++] = pad;
2003 	return nn;
2004 }
2005 
2006 static int
des3enc(Secret * sec,uchar * buf,int n)2007 des3enc(Secret *sec, uchar *buf, int n)
2008 {
2009 	n = blockpad(buf, n, 8);
2010 	des3CBCencrypt(buf, n, sec->enckey);
2011 	return n;
2012 }
2013 
2014 static int
des3dec(Secret * sec,uchar * buf,int n)2015 des3dec(Secret *sec, uchar *buf, int n)
2016 {
2017 	des3CBCdecrypt(buf, n, sec->enckey);
2018 	return (*sec->unpad)(buf, n, 8);
2019 }
2020 static DigestState*
nomac(uchar * unused1,ulong unused2,uchar * unused3,ulong unused4,uchar * unused5,DigestState * unused6)2021 nomac(uchar *unused1, ulong unused2, uchar *unused3, ulong unused4,
2022 	uchar *unused5, DigestState *unused6)
2023 {
2024 	return nil;
2025 }
2026 
2027 /*
2028  * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac.
2029  */
2030 static DigestState*
sslmac_x(uchar * p,ulong len,uchar * key,ulong klen,uchar * digest,DigestState * s,DigestState * (* x)(uchar *,ulong,uchar *,DigestState *),int xlen,int padlen)2031 sslmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
2032 	DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen, int padlen)
2033 {
2034 	int i;
2035 	uchar pad[48], innerdigest[20];
2036 
2037 	if(xlen > sizeof(innerdigest)
2038 	|| padlen > sizeof(pad))
2039 		return nil;
2040 
2041 	if(klen>64)
2042 		return nil;
2043 
2044 	/* first time through */
2045 	if(s == nil){
2046 		for(i=0; i<padlen; i++)
2047 			pad[i] = 0x36;
2048 		s = (*x)(key, klen, nil, nil);
2049 		s = (*x)(pad, padlen, nil, s);
2050 		if(s == nil)
2051 			return nil;
2052 	}
2053 
2054 	s = (*x)(p, len, nil, s);
2055 	if(digest == nil)
2056 		return s;
2057 
2058 	/* last time through */
2059 	for(i=0; i<padlen; i++)
2060 		pad[i] = 0x5c;
2061 	(*x)(nil, 0, innerdigest, s);
2062 	s = (*x)(key, klen, nil, nil);
2063 	s = (*x)(pad, padlen, nil, s);
2064 	(*x)(innerdigest, xlen, digest, s);
2065 	return nil;
2066 }
2067 
2068 static DigestState*
sslmac_sha1(uchar * p,ulong len,uchar * key,ulong klen,uchar * digest,DigestState * s)2069 sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
2070 {
2071 	return sslmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen, 40);
2072 }
2073 
2074 static DigestState*
sslmac_md5(uchar * p,ulong len,uchar * key,ulong klen,uchar * digest,DigestState * s)2075 sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
2076 {
2077 	return sslmac_x(p, len, key, klen, digest, s, md5, MD5dlen, 48);
2078 }
2079 
2080 static void
sslPackMac(Secret * sec,uchar * mackey,uchar * seq,uchar * header,uchar * body,int len,uchar * mac)2081 sslPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac)
2082 {
2083 	DigestState *s;
2084 	uchar buf[11];
2085 
2086 	memmove(buf, seq, 8);
2087 	buf[8] = header[0];
2088 	buf[9] = header[3];
2089 	buf[10] = header[4];
2090 
2091 	s = (*sec->mac)(buf, 11, mackey, sec->maclen, 0, 0);
2092 	(*sec->mac)(body, len, mackey, sec->maclen, mac, s);
2093 }
2094 
2095 static void
tlsPackMac(Secret * sec,uchar * mackey,uchar * seq,uchar * header,uchar * body,int len,uchar * mac)2096 tlsPackMac(Secret *sec, uchar *mackey, uchar *seq, uchar *header, uchar *body, int len, uchar *mac)
2097 {
2098 	DigestState *s;
2099 	uchar buf[13];
2100 
2101 	memmove(buf, seq, 8);
2102 	memmove(&buf[8], header, 5);
2103 
2104 	s = (*sec->mac)(buf, 13, mackey, sec->maclen, 0, 0);
2105 	(*sec->mac)(body, len, mackey, sec->maclen, mac, s);
2106 }
2107 
2108 static void
put32(uchar * p,u32int x)2109 put32(uchar *p, u32int x)
2110 {
2111 	p[0] = x>>24;
2112 	p[1] = x>>16;
2113 	p[2] = x>>8;
2114 	p[3] = x;
2115 }
2116 
2117 static void
put64(uchar * p,vlong x)2118 put64(uchar *p, vlong x)
2119 {
2120 	put32(p, (u32int)(x >> 32));
2121 	put32(p+4, (u32int)x);
2122 }
2123 
2124 static void
put24(uchar * p,int x)2125 put24(uchar *p, int x)
2126 {
2127 	p[0] = x>>16;
2128 	p[1] = x>>8;
2129 	p[2] = x;
2130 }
2131 
2132 static void
put16(uchar * p,int x)2133 put16(uchar *p, int x)
2134 {
2135 	p[0] = x>>8;
2136 	p[1] = x;
2137 }
2138 
2139 /*
2140 static u32int
2141 get32(uchar *p)
2142 {
2143 	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
2144 }
2145 */
2146 
2147 static int
get16(uchar * p)2148 get16(uchar *p)
2149 {
2150 	return (p[0]<<8)|p[1];
2151 }
2152 
2153 static char *charmap = "0123456789abcdef";
2154 
2155 static void
pdump(int len,void * a,char * tag)2156 pdump(int len, void *a, char *tag)
2157 {
2158 	uchar *p;
2159 	int i;
2160 	char buf[65+32];
2161 	char *q;
2162 
2163 	p = a;
2164 	strcpy(buf, tag);
2165 	while(len > 0){
2166 		q = buf + strlen(tag);
2167 		for(i = 0; len > 0 && i < 32; i++){
2168 			if(*p >= ' ' && *p < 0x7f){
2169 				*q++ = ' ';
2170 				*q++ = *p;
2171 			} else {
2172 				*q++ = charmap[*p>>4];
2173 				*q++ = charmap[*p & 0xf];
2174 			}
2175 			len--;
2176 			p++;
2177 		}
2178 		*q = 0;
2179 
2180 		if(len > 0)
2181 			pprint("%s...\n", buf);
2182 		else
2183 			pprint("%s\n", buf);
2184 	}
2185 }
2186