xref: /inferno-os/appl/lib/crypt/ssl3.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1#
2# SSL 3.0 protocol
3#
4implement SSL3;
5
6include "sys.m";
7	sys					: Sys;
8
9include "keyring.m";
10	keyring					: Keyring;
11	IPint, DigestState			: import keyring;
12
13include "security.m";
14	random					: Random;
15	ssl					: SSL;
16
17include "daytime.m";
18	daytime					: Daytime;
19
20include "asn1.m";
21	asn1					: ASN1;
22
23include "pkcs.m";
24	pkcs					: PKCS;
25	DHParams, DHPublicKey, DHPrivateKey,
26	RSAParams, RSAKey,
27	DSSPrivateKey, DSSPublicKey		: import PKCS;
28
29include "x509.m";
30	x509					: X509;
31	Signed,	Certificate, SubjectPKInfo	: import x509;
32
33include "sslsession.m";
34	sslsession				: SSLsession;
35	Session					: import sslsession;
36
37include "ssl3.m";
38
39#
40# debug mode
41#
42SSL_DEBUG					: con 0;
43logfd						: ref Sys->FD;
44
45#
46# version {major, minor}
47#
48SSL_VERSION_2_0					:= array [] of {byte 0, byte 16r02};
49SSL_VERSION_3_0					:= array [] of {byte 16r03, byte 0};
50
51
52# SSL Record Protocol
53
54SSL_CHANGE_CIPHER_SPEC 				: con 20;
55	SSL_ALERT				: con 21;
56	SSL_HANDSHAKE 				: con 22;
57	SSL_APPLICATION_DATA 			: con 23;
58	SSL_V2HANDSHAKE				: con 0; # escape to sslv2
59
60# SSL Application Protocol consists of alert protocol, change cipher spec protocol
61# v2 and v3 handshake protocol and application data protocol. The v2 handshake
62# protocol is included only for backward compatibility
63
64Protocol: adt {
65	pick {
66	pAlert =>
67		alert				: ref Alert;
68	pChangeCipherSpec =>
69		change_cipher_spec		: ref ChangeCipherSpec;
70	pHandshake =>
71		handshake			: ref Handshake;
72	pV2Handshake =>
73		handshake			: ref V2Handshake;
74	pApplicationData =>
75		data				: array of byte;
76	}
77
78	decode: fn(r: ref Record, ctx: ref Context): (ref Protocol, string);
79	encode: fn(p: self ref Protocol, vers: array of byte): (ref Record, string);
80	tostring: fn(p: self ref Protocol): string;
81};
82
83#
84# ssl alert protocol
85#
86SSL_WARNING	 				: con 1;
87	SSL_FATAL				: con 2;
88
89SSL_CLOSE_NOTIFY				: con 0;
90	SSL_UNEXPECTED_MESSAGE			: con 10;
91	SSL_BAD_RECORD_MAC			: con 20;
92	SSL_DECOMPRESSION_FAILURE		: con 30;
93	SSL_HANDSHAKE_FAILURE 			: con 40;
94	SSL_NO_CERTIFICATE			: con 41;
95	SSL_BAD_CERTIFICATE 			: con 42;
96	SSL_UNSUPPORTED_CERTIFICATE 		: con 43;
97	SSL_CERTIFICATE_REVOKED			: con 44;
98	SSL_CERTIFICATE_EXPIRED			: con 45;
99	SSL_CERTIFICATE_UNKNOWN			: con 46;
100	SSL_ILLEGAL_PARAMETER 			: con 47;
101
102Alert: adt {
103	level 					: int;
104	description 				: int;
105
106	tostring: fn(a: self ref Alert): string;
107};
108
109#
110# ssl change cipher spec protocol
111#
112ChangeCipherSpec: adt {
113	value					: int;
114};
115
116#
117# ssl handshake protocol
118#
119SSL_HANDSHAKE_HELLO_REQUEST	 		: con 0;
120	SSL_HANDSHAKE_CLIENT_HELLO 		: con 1;
121	SSL_HANDSHAKE_SERVER_HELLO 		: con 2;
122	SSL_HANDSHAKE_CERTIFICATE 		: con 11;
123	SSL_HANDSHAKE_SERVER_KEY_EXCHANGE 	: con 12;
124	SSL_HANDSHAKE_CERTIFICATE_REQUEST 	: con 13;
125	SSL_HANDSHAKE_SERVER_HELLO_DONE 	: con 14;
126	SSL_HANDSHAKE_CERTIFICATE_VERIFY 	: con 15;
127	SSL_HANDSHAKE_CLIENT_KEY_EXCHANGE 	: con 16;
128	SSL_HANDSHAKE_FINISHED	 		: con 20;
129
130Handshake: adt {
131	pick {
132       	HelloRequest =>
133        ClientHello =>
134		version 			: array of byte; # [2]
135		random 				: array of byte; # [32]
136		session_id 			: array of byte; # <0..32>
137		suites	 			: array of byte; # [2] x
138		compressions			: array of byte; # [1] x
139        ServerHello =>
140		version 			: array of byte; # [2]
141		random 				: array of byte; # [32]
142		session_id 			: array of byte; # <0..32>
143		suite	 			: array of byte; # [2]
144		compression			: byte; # [1]
145	Certificate =>
146		cert_list 			: list of array of byte; # X509 cert chain
147	ServerKeyExchange =>
148		xkey				: array of byte; # exchange_keys
149        CertificateRequest =>
150		cert_types 			: array of byte;
151		dn_list 			: list of array of byte; # DN list
152	ServerHelloDone =>
153        CertificateVerify =>
154		signature			: array of byte;
155        ClientKeyExchange =>
156		xkey				: array of byte;
157       	Finished =>
158		md5_hash			: array of byte; # [16] Keyring->MD5dlen
159		sha_hash 			: array of byte; # [20] Keyring->SHA1dlen
160	}
161
162	decode: fn(buf: array of byte): (ref Handshake, string);
163	encode: fn(hm: self ref Handshake): (array of byte, string);
164	tostring: fn(hm: self ref Handshake): string;
165};
166
167# cipher suites and cipher specs (default, not all supported)
168#	- key exchange, signature, encrypt and digest algorithms
169
170SSL3_Suites := array [] of {
171	NULL_WITH_NULL_NULL => 			array [] of {byte 0, byte 16r00},
172
173	RSA_WITH_NULL_MD5 => 			array [] of {byte 0, byte 16r01},
174	RSA_WITH_NULL_SHA => 			array [] of {byte 0, byte 16r02},
175	RSA_EXPORT_WITH_RC4_40_MD5 => 		array [] of {byte 0, byte 16r03},
176	RSA_WITH_RC4_128_MD5 => 		array [] of {byte 0, byte 16r04},
177	RSA_WITH_RC4_128_SHA => 		array [] of {byte 0, byte 16r05},
178	RSA_EXPORT_WITH_RC2_CBC_40_MD5 => 	array [] of {byte 0, byte 16r06},
179	RSA_WITH_IDEA_CBC_SHA => 		array [] of {byte 0, byte 16r07},
180	RSA_EXPORT_WITH_DES40_CBC_SHA => 	array [] of {byte 0, byte 16r08},
181	RSA_WITH_DES_CBC_SHA => 		array [] of {byte 0, byte 16r09},
182	RSA_WITH_3DES_EDE_CBC_SHA => 		array [] of {byte 0, byte 16r0A},
183
184	DH_DSS_EXPORT_WITH_DES40_CBC_SHA => 	array [] of {byte 0, byte 16r0B},
185	DH_DSS_WITH_DES_CBC_SHA => 		array [] of {byte 0, byte 16r0C},
186	DH_DSS_WITH_3DES_EDE_CBC_SHA => 	array [] of {byte 0, byte 16r0D},
187	DH_RSA_EXPORT_WITH_DES40_CBC_SHA => 	array [] of {byte 0, byte 16r0E},
188	DH_RSA_WITH_DES_CBC_SHA => 		array [] of {byte 0, byte 16r0F},
189	DH_RSA_WITH_3DES_EDE_CBC_SHA => 	array [] of {byte 0, byte 16r10},
190	DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =>	array [] of {byte 0, byte 16r11},
191	DHE_DSS_WITH_DES_CBC_SHA => 		array [] of {byte 0, byte 16r12},
192	DHE_DSS_WITH_3DES_EDE_CBC_SHA => 	array [] of {byte 0, byte 16r13},
193	DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =>	array [] of {byte 0, byte 16r14},
194	DHE_RSA_WITH_DES_CBC_SHA => 		array [] of {byte 0, byte 16r15},
195	DHE_RSA_WITH_3DES_EDE_CBC_SHA => 	array [] of {byte 0, byte 16r16},
196
197	DH_anon_EXPORT_WITH_RC4_40_MD5 => 	array [] of {byte 0, byte 16r17},
198	DH_anon_WITH_RC4_128_MD5 => 		array [] of {byte 0, byte 16r18},
199	DH_anon_EXPORT_WITH_DES40_CBC_SHA =>	array [] of {byte 0, byte 16r19},
200	DH_anon_WITH_DES_CBC_SHA => 		array [] of {byte 0, byte 16r1A},
201	DH_anon_WITH_3DES_EDE_CBC_SHA => 	array [] of {byte 0, byte 16r1B},
202
203	FORTEZZA_KEA_WITH_NULL_SHA => 		array [] of {byte 0, byte 16r1C},
204	FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA =>	array [] of {byte 0, byte 16r1D},
205	FORTEZZA_KEA_WITH_RC4_128_SHA => 	array [] of {byte 0, byte 16r1E},
206};
207
208#
209# key exchange algorithms
210#
211DHmodlen					: con 512; # default length
212
213
214#
215# certificate types
216#
217SSL_RSA_sign 					: con 1;
218	SSL_DSS_sign 				: con 2;
219	SSL_RSA_fixed_DH			: con 3;
220	SSL_DSS_fixed_DH			: con 4;
221	SSL_RSA_emhemeral_DH 			: con 5;
222	SSL_DSS_empemeral_DH 			: con 6;
223	SSL_FORTEZZA_MISSI			: con 20;
224
225#
226# cipher definitions
227#
228SSL_EXPORT_TRUE 				: con 0;
229	SSL_EXPORT_FALSE 			: con 1;
230
231SSL_NULL_CIPHER,
232	SSL_RC4,
233	SSL_RC2_CBC,
234	SSL_IDEA_CBC,
235	SSL_DES_CBC,
236	SSL_3DES_EDE_CBC,
237	SSL_FORTEZZA_CBC			: con iota;
238
239SSL_STREAM_CIPHER,
240	SSL_BLOCK_CIPHER			: con iota;
241
242SSL_NULL_MAC,
243	SSL_MD5,
244	SSL_SHA					: con iota;
245
246#
247# MAC paddings
248#
249SSL_MAX_MAC_PADDING 				: con 48;
250SSL_MAC_PAD1 := array [] of {
251	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
252	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
253	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
254	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
255	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
256	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
257	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
258	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
259	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
260	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
261	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
262	byte 16r36, byte 16r36, byte 16r36, byte 16r36,
263};
264SSL_MAC_PAD2 := array [] of {
265	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
266	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
267	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
268	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
269	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
270	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
271	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
272	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
273	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
274	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
275	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
276	byte 16r5c, byte 16r5c, byte 16r5c, byte 16r5c,
277};
278
279#
280# finished messages
281#
282SSL_CLIENT_SENDER := array [] of {
283	byte 16r43, byte 16r4C, byte 16r4E, byte 16r54};
284SSL_SERVER_SENDER := array [] of {
285	byte 16r53, byte 16r52, byte 16r56, byte 16r52};
286
287#
288# a default distiguished names
289#
290RSA_COMMERCIAL_CA_ROOT_SUBJECT_NAME := array [] of {
291	byte 16r30, byte 16r5F, byte 16r31, byte 16r0B,
292	byte 16r30, byte 16r09, byte 16r06, byte 16r03,
293	byte 16r55, byte 16r04, byte 16r06, byte 16r13,
294	byte 16r02, byte 16r55, byte 16r53, byte 16r31,
295	byte 16r20, byte 16r30, byte 16r1E, byte 16r06,
296	byte 16r03, byte 16r55, byte 16r04, byte 16r0A,
297	byte 16r13, byte 16r17, byte 16r52, byte 16r53,
298	byte 16r41, byte 16r20, byte 16r44, byte 16r61,
299	byte 16r74, byte 16r61, byte 16r20, byte 16r53,
300	byte 16r65, byte 16r63, byte 16r75, byte 16r72,
301	byte 16r69, byte 16r74, byte 16r79, byte 16r2C,
302	byte 16r20, byte 16r49, byte 16r6E, byte 16r63,
303	byte 16r2E, byte 16r31, byte 16r2E, byte 16r30,
304	byte 16r2C, byte 16r06, byte 16r03, byte 16r55,
305	byte 16r04, byte 16r0B, byte 16r13, byte 16r25,
306	byte 16r53, byte 16r65, byte 16r63, byte 16r75,
307	byte 16r72, byte 16r65, byte 16r20, byte 16r53,
308	byte 16r65, byte 16r72, byte 16r76, byte 16r65,
309	byte 16r72, byte 16r20, byte 16r43, byte 16r65,
310	byte 16r72, byte 16r74, byte 16r69, byte 16r66,
311	byte 16r69, byte 16r63, byte 16r61, byte 16r74,
312	byte 16r69, byte 16r6F, byte 16r6E, byte 16r20,
313	byte 16r41, byte 16r75, byte 16r74, byte 16r68,
314	byte 16r6F, byte 16r72, byte 16r69, byte 16r74,
315	byte 16r79,
316};
317
318# SSL internal status
319USE_DEVSSL,
320	SSL3_RECORD,
321	SSL3_HANDSHAKE,
322	SSL2_HANDSHAKE,
323	CLIENT_SIDE,
324	SESSION_RESUMABLE,
325	CLIENT_AUTH,
326	CERT_REQUEST,
327	CERT_SENT,
328	CERT_RECEIVED,
329	OUT_READY,
330	IN_READY				: con  1 << iota;
331
332# SSL internal state
333STATE_EXIT,
334	STATE_CHANGE_CIPHER_SPEC,
335	STATE_HELLO_REQUEST,
336	STATE_CLIENT_HELLO,
337	STATE_SERVER_HELLO,
338	STATE_CLIENT_KEY_EXCHANGE,
339	STATE_SERVER_KEY_EXCHANGE,
340	STATE_SERVER_HELLO_DONE,
341	STATE_CLIENT_CERTIFICATE,
342	STATE_SERVER_CERTIFICATE,
343	STATE_CERTIFICATE_VERIFY,
344	STATE_FINISHED				: con iota;
345
346#
347# load necessary modules
348#
349init(): string
350{
351	sys = load Sys Sys->PATH;
352	if(sys == nil)
353		return "ssl3: load sys module failed";
354	logfd = sys->fildes(1);
355
356	keyring = load Keyring Keyring->PATH;
357	if(keyring == nil)
358		return "ssl3: load keyring module failed";
359
360	random = load Random Random->PATH;
361	if(random == nil)
362		return "ssl3: load random module failed";
363
364	daytime = load Daytime Daytime->PATH;
365	if(daytime == nil)
366		return "ssl3: load Daytime module failed";
367
368	pkcs = load PKCS PKCS->PATH;
369	if(pkcs == nil)
370		return "ssl3: load pkcs module failed";
371	pkcs->init();
372
373	x509 = load X509 X509->PATH;
374	if(x509 == nil)
375		return "ssl3: load x509 module failed";
376	x509->init();
377
378	ssl = load SSL SSL->PATH;
379	if(ssl == nil)
380		return "ssl3: load SSL module failed";
381	sslsession = load SSLsession SSLsession->PATH;
382	if(sslsession == nil)
383		return "ssl3: load sslsession module failed";
384	e := sslsession->init();
385	if(e != nil)
386		return "ssl3: sslsession init failed: "+e;
387
388	return "";
389}
390
391log(s: string)
392{
393	a := array of byte (s + "\n");
394	sys->write(logfd, a, len a);
395}
396
397#
398# protocol context
399#
400
401Context.new(): ref Context
402{
403	ctx := ref Context;
404
405	ctx.c = nil;
406	ctx.session = nil;
407	ctx.local_info = nil;
408
409	ctx.sha_state = nil;
410	ctx.md5_state = nil;
411
412	ctx.status = 0;
413	ctx.state = 0;
414
415	ctx.client_random = array [32] of byte;
416	ctx.server_random = array [32] of byte;
417
418	ctx.cw_mac = nil;
419	ctx.sw_mac = nil;
420	ctx.cw_key = nil;
421	ctx.sw_key = nil;
422	ctx.cw_IV = nil;
423	ctx.sw_IV = nil;
424
425	ctx.in_queue = RecordQueue.new();
426	ctx.in_queue.data = ref Record(0, nil, array [1<<15] of byte) :: nil;
427	ctx.out_queue = RecordQueue.new();
428
429	# set session resumable as default
430	ctx.status |= SESSION_RESUMABLE;
431
432	return ctx;
433}
434
435Context.client(ctx: self ref Context, fd: ref Sys->FD, peername: string, ver: int, info: ref Authinfo)
436	: (string, int)
437{
438	if(SSL_DEBUG)
439		log(sys->sprint("ssl3: Context.Client peername=%s ver=%d\n", peername, ver));
440	if ((ckstr := cksuites(info.suites)) != nil)
441		return (ckstr, ver);
442	# the order is important
443	ctx.local_info = info;
444	ctx.state = STATE_HELLO_REQUEST;
445	e := ctx.connect(fd);
446	if(e != "")
447		return (e, ver);
448	ctx.session = sslsession->get_session_byname(peername);
449
450	# Request to resume an SSL 3.0 session should use an SSL 3.0 client hello
451	if(ctx.session.session_id != nil) {
452		if((ctx.session.version[0] == SSL_VERSION_3_0[0]) &&
453			(ctx.session.version[1] == SSL_VERSION_3_0[1])) {
454			ver = 3;
455			ctx.status |= SSL3_HANDSHAKE;
456			ctx.status &= ~SSL2_HANDSHAKE;
457		}
458	}
459	e = ctx.set_version(ver);
460	if(e != "")
461		return (e, ver);
462	reset_client_random(ctx);
463	ctx.status |= CLIENT_SIDE;
464	e = do_protocol(ctx);
465	if(e != nil)
466		return (e, ver);
467
468	if(ctx.status & SSL3_RECORD)
469		ver = 3;
470	else
471		ver = 2;
472	return (nil, ver);
473}
474
475Context.server(ctx: self ref Context, fd: ref Sys->FD, info: ref Authinfo, client_auth: int)
476	: string
477{
478	if ((ckstr := cksuites(info.suites)) != nil)
479		return ckstr;
480	ctx.local_info = info;
481	if(client_auth)
482		ctx.status |= CLIENT_AUTH;
483	ctx.state = STATE_CLIENT_HELLO;
484	e := ctx.connect(fd);
485	if(e != "")
486		return e;
487	reset_server_random(ctx);
488	e = ctx.set_version(3); # set ssl device to version 3
489	if(e != "")
490		return e;
491	ctx.status &= ~CLIENT_SIDE;
492	e = do_protocol(ctx);
493	if(e != nil)
494		return e;
495
496	return "";
497}
498
499
500Context.use_devssl(ctx: self ref Context)
501{
502	if(!(ctx.status & IN_READY) && !(ctx.status & OUT_READY))
503		ctx.status |= USE_DEVSSL;
504}
505
506Context.set_version(ctx: self ref Context, vers: int): string
507{
508	err := "";
509
510	if(ctx.c == nil) {
511		err = "no connection provided";
512	}
513	else {
514		if(SSL_DEBUG)
515			log("ssl3: record version = " + string vers);
516
517		if(vers == 2) {
518			ctx.status &= ~SSL3_RECORD;
519			ctx.status &= ~SSL3_HANDSHAKE;
520			ctx.status |= SSL2_HANDSHAKE;
521			if (ctx.session != nil)
522				ctx.session.version = SSL_VERSION_2_0;
523		}
524		else if(vers == 3) { # may be sslv2 handshake using ssl3 record
525			ctx.status |= SSL3_RECORD;
526			ctx.status |= SSL3_HANDSHAKE;
527			ctx.status &= ~SSL2_HANDSHAKE; # tmp test only
528			if (ctx.session != nil)
529				ctx.session.version = SSL_VERSION_3_0;
530		}
531		else if(vers == 23) { # may be sslv2 handshake using ssl3 record
532			ctx.status &= ~SSL3_RECORD;
533			ctx.status |= SSL3_HANDSHAKE;
534			ctx.status |= SSL2_HANDSHAKE;
535			vers = 2;
536		}
537		else
538			err = "unsupported ssl device version";
539
540		if((err == "") && (ctx.status & USE_DEVSSL)) {
541			if(sys->fprint(ctx.c.cfd, "ver %d", vers) < 0)
542				err = sys->sprint("ssl3: set ssl device version failed: %r");
543		}
544	}
545
546	return err;
547}
548
549Context.connect(ctx: self ref Context, fd: ref Sys->FD): string
550{
551	err := "";
552
553	if(ctx.status & USE_DEVSSL)
554		(err, ctx.c) = ssl->connect(fd);
555	else {
556		ctx.c = ref Sys->Connection(fd, nil, "");
557		ctx.in_queue.sequence_numbers[0] = 0;
558		ctx.out_queue.sequence_numbers[1] = 0;
559	}
560
561	return err;
562}
563
564Context.read(ctx: self ref Context, a: array of byte, n: int): int
565{
566	if(ctx.state != STATE_EXIT || !(ctx.status & IN_READY)) {
567		if(SSL_DEBUG)
568			log("ssl3: read not ready\n");
569		return -1;
570	}
571
572	if(ctx.out_queue.data != nil)
573		record_write_queue(ctx);
574
575	if(ctx.status & USE_DEVSSL) {
576		fd := ctx.c.dfd;
577		if(ctx.status & SSL3_RECORD) {
578			buf := array [n+3] of byte;
579			m := sys->read(fd, buf, n+3); # header + n bytes
580			if(m < 3) {
581				if(SSL_DEBUG)
582					log(sys->sprint("ssl3: read failure: %r"));
583				return -1;
584			}
585
586			if(buf[1] != SSL_VERSION_3_0[0] || buf[2] != SSL_VERSION_3_0[1]) {
587				if(SSL_DEBUG)
588					log("ssl3: not ssl version 3 data: header = [" + bastr(buf[0:3]) + "]");
589				return -1;
590			}
591
592			a[0:] = buf[3:m];
593
594			content_type := int buf[0];
595			case content_type {
596			SSL_APPLICATION_DATA =>
597				break;
598			SSL_ALERT =>
599				if(SSL_DEBUG)
600					log("ssl3: expect application data, got alert: [" + bastr(buf[3:m]) +"]");
601				return 0;
602			SSL_HANDSHAKE =>
603				if(SSL_DEBUG)
604					log("ssl3: expect application data, got handshake message");
605				return 0;
606			SSL_CHANGE_CIPHER_SPEC =>
607				if(SSL_DEBUG)
608					log("ssl3: dynamic change cipher spec not supported yet");
609				return 0;
610			}
611			return m-3;
612		}
613		else
614			return sys->read(fd, a, n);
615	}
616	else {
617		q := ctx.in_queue;
618		got := 0;
619		if(q.fragment) {
620			d := (hd q.data).data;
621			m := q.e - q.b;
622			i := q.e - q.fragment;
623			if(q.fragment > n) {
624				a[0:] = d[i:i+n];
625				q.fragment -= n;
626				got = n;
627			}
628			else {
629				a[0:] = d[i:q.e];
630				got = q.fragment;
631				q.fragment = 0;
632			}
633		}
634out:
635		while(got < n) {
636			err := q.read(ctx, ctx.c.dfd);
637			if(err != "") {
638				if(SSL_DEBUG)
639					log("ssl3: read: " + err);
640				break;
641			}
642			r := hd q.data;
643			if(ctx.status & SSL3_RECORD) {
644				case r.content_type {
645				SSL_APPLICATION_DATA =>
646					break;
647				SSL_ALERT =>
648					if(SSL_DEBUG)
649						log("ssl3: read: got alert\n\t\t" + bastr(r.data[q.b:q.e]));
650					# delete session id
651					ctx.session.session_id = nil;
652					ctx.status &= ~IN_READY;
653					break out;
654				SSL_CHANGE_CIPHER_SPEC =>
655					if(SSL_DEBUG)
656						log("ssl3: read: got change cipher spec\n");
657				SSL_HANDSHAKE =>
658					if(SSL_DEBUG)
659						log("ssl3: read: got handshake data\n");
660					#do_handshake(ctx, r); # ?
661				* =>
662					if(SSL_DEBUG)
663						log("ssl3: read: unknown data\n");
664				}
665			}
666
667			if((n - got) <= (q.e - q.b)) {
668				a[got:] = r.data[q.b:q.b+n-got];
669				q.fragment = q.e - q.b - n + got;
670				got = n;
671			}
672			else {
673				a[got:] = r.data[q.b:q.e];
674				q.fragment = 0;
675				got += q.e - q.b;
676			}
677		}
678		if(SSL_DEBUG)
679			log(sys->sprint("ssl3: read: returning %d bytes\n", got));
680		return got;
681	}
682}
683
684Context.write(ctx: self ref Context, a: array of byte, n: int): int
685{
686	if(ctx.state != STATE_EXIT || !(ctx.status & OUT_READY))
687		return-1;
688
689	if(ctx.out_queue.data != nil)
690		record_write_queue(ctx);
691
692	if(ctx.status & USE_DEVSSL) {
693		if(ctx.status & SSL3_RECORD) {
694			buf := array [n+3] of byte;
695			buf[0] = byte SSL_APPLICATION_DATA;
696			buf[1:] = SSL_VERSION_3_0;
697			buf[3:] = a[0:n];
698			n = sys->write(ctx.c.dfd, buf, n+3);
699			if(n > 0)
700				n -= 3;
701		}
702		else
703			n = sys->write(ctx.c.dfd, a, n);
704	}
705	else {
706		q := ctx.out_queue;
707		v := SSL_VERSION_2_0;
708		if(ctx.status&SSL3_RECORD)
709			v = SSL_VERSION_3_0;
710		for(i := 0; i < n;){
711			m := n-i;
712			if(m > q.length)
713				m = q.length;
714			r := ref Record(SSL_APPLICATION_DATA, v, a[i:i+m]);
715			record_write(r, ctx); # return error?
716			i += m;
717		}
718	}
719	return n;
720}
721
722devssl_read(ctx: ref Context): (ref Record, string)
723{
724	buf := array [Sys->ATOMICIO] of byte;
725	r: ref Record;
726	c := ctx.c;
727
728	n := sys->read(c.dfd, buf, 3);
729	if(n < 0)
730		return (nil, sys->sprint("record read: read failure: %r"));
731
732	# in case of undetermined, do auto record version detection
733	if((ctx.state == SSL2_STATE_SERVER_HELLO) &&
734		(ctx.status & SSL2_HANDSHAKE) && (ctx.status & SSL3_HANDSHAKE)) {
735
736		fstatus := sys->open(ctx.c.dir + "/status", Sys->OREAD);
737		if(fstatus == nil)
738			return (nil, "open status: " + sys->sprint("%r"));
739		status := array [64] of byte;
740		nbyte := sys->read(fstatus, status, len status);
741		if(nbyte != 1)
742			return (nil, "read status: " + sys->sprint("%r"));
743
744		ver := int status[0];
745
746		if(SSL_DEBUG)
747			log("ssl3: auto record version detect as: " + string ver);
748
749		# assert ctx.status & SSL2_RECORD true ? before reset
750		if(ver == 2) {
751			ctx.status &= ~SSL3_RECORD;
752			ctx.status |= SSL2_HANDSHAKE;
753			ctx.status &= ~SSL3_HANDSHAKE;
754		}
755		else {
756			ctx.status |= SSL3_RECORD;
757		}
758	}
759
760	if(ctx.status & SSL3_RECORD) {
761		if(n < 3)
762			return (nil, sys->sprint("record read: read failure: %r"));
763
764		# assert only major version number
765		if(buf[1] != SSL_VERSION_3_0[0])
766			return (nil, "record read: version mismatch");
767
768		case int buf[0] {
769		SSL_ALERT =>
770			n = sys->read(c.dfd, buf, 5); # read in header plus rest
771			if(n != 5)
772				return (nil, sys->sprint("read alert failed: %r"));
773			r = ref Record(SSL_ALERT, SSL_VERSION_3_0, buf[3:5]);
774
775		SSL_CHANGE_CIPHER_SPEC =>
776			n = sys->read(c.dfd, buf, 4); # read in header plus rest
777			if(n != 4)
778				return (nil, sys->sprint("read change_cipher_spec failed: %r"));
779			r = ref Record(SSL_CHANGE_CIPHER_SPEC, SSL_VERSION_3_0, buf[3:4]);
780
781		SSL_HANDSHAKE =>
782			n = sys->read(c.dfd, buf, 7); # header + msg length
783			if(n != 7)
784				return (nil, sys->sprint("read handshake header + msg length failed: %r"));
785			m := int_decode(buf[4:7]);
786			if(m < 0)
787				return (nil, "read handshake failed: unexpected length");
788			data := array [m+4] of byte;
789			data[0:] = buf[3:7]; # msg type + length
790			if(m != 0) {
791				# need exact m bytes (exclude header), otherwise failure
792				remain := m;
793				now := 4;
794				while(remain > 0) {
795					n = sys->read(c.dfd, buf, remain+3); # header + msg
796					if(n < 3 || int buf[0] != SSL_HANDSHAKE)
797						return (nil, sys->sprint("read handshake msg body failed: %r"));
798					sys->print("expect %d, got %d bytes\n", m, n-3);
799					remain -= n - 3;
800					data[now:] = buf[3:n];
801					now += n - 3;
802				}
803			}
804
805			r = ref Record(SSL_HANDSHAKE, SSL_VERSION_3_0, data);
806		* =>
807			return (nil, "trying to read unknown protocol message");
808		}
809
810		if(SSL_DEBUG)
811			log("ssl3: record_read: \n\theader = \n\t\t" + bastr(buf[0:3])
812			+ "\n\tdata = \n\t\t" + bastr(r.data) + "\n");
813	}
814	# v2 record layer
815	else {
816		# assume the handshake record size less than Sys->ATOMICIO
817		# in most case, this is ok
818		if(n == 3) {
819			n = sys->read(c.dfd, buf[3:], Sys->ATOMICIO - 3);
820			if(n < 0)
821				return (nil, sys->sprint("v2 record read: read failure: %r"));
822		}
823
824		r = ref Record(SSL_V2HANDSHAKE, SSL_VERSION_2_0, buf[0:n+3]);
825
826		if(SSL_DEBUG)
827			log("ssl3: v2 record_read: \n\tdata = \n\t\t" + bastr(r.data) + "\n");
828	}
829
830	return (r, nil);
831}
832
833record_read(ctx: ref Context): (ref Record, string)
834{
835	q := ctx.in_queue;
836	if(q.fragment == 0) {
837		err := q.read(ctx, ctx.c.dfd);
838		if(err != "")
839			return (nil, err);
840		q.fragment = q.e - q.b;
841	}
842
843	r := hd q.data;
844	if(ctx.status & SSL3_RECORD) {
845		# confirm only major version number
846		if(r.version[0] != SSL_VERSION_3_0[0])
847			return (nil, "record read: not v3 record");
848
849		case r.content_type {
850		SSL_ALERT =>
851			a := array [2] of byte;
852			n := fetch_data(ctx, a, 2);
853			if(n != 2)
854				return (nil, "read alert failed");
855			r = ref Record(SSL_ALERT, SSL_VERSION_3_0, a);
856
857		SSL_CHANGE_CIPHER_SPEC =>
858			a := array [1] of byte;
859			n := fetch_data(ctx, a, 1);
860			if(n != 1)
861				return (nil, "read change_cipher_spec failed");
862			r = ref Record(SSL_CHANGE_CIPHER_SPEC, SSL_VERSION_3_0, a);
863
864		SSL_HANDSHAKE =>
865			a := array [4] of byte;
866			n := fetch_data(ctx, a, 4);
867			if(n != 4)
868				return (nil, "read message length failed");
869			m := int_decode(a[1:]);
870			if(m < 0)
871				return (nil, "unexpected handshake message length");
872			b := array [m+4] of byte;
873			b[0:] = a;
874			n = fetch_data(ctx, b[4:], m);
875			if(n != m)
876				return (nil, "read message body failed");
877			r = ref Record(SSL_HANDSHAKE, SSL_VERSION_3_0, b);
878		* =>
879			return (nil, "trying to read unknown protocol message");
880		}
881	}
882	# v2 record layer
883	else {
884		r = ref Record(SSL_V2HANDSHAKE, SSL_VERSION_2_0, r.data[q.b:q.e]);
885		q.fragment = 0;
886	}
887
888	return (r, nil);
889}
890
891fetch_data(ctx: ref Context, a: array of byte, n: int): int
892{
893	q := ctx.in_queue;
894	r := hd q.data;
895
896	got := 0;
897	cnt := -1;
898out:
899	while(got < n) {
900		if(q.fragment) {
901			cnt = r.content_type;
902			i := q.e - q.fragment;
903			if(n-got <= q.fragment) {
904				a[got:] = r.data[i:i+n-got];
905				q.fragment -= n - got;
906				got = n;
907			}
908			else {
909				a[got:] = r.data[i:q.e];
910				got += q.fragment;
911				q.fragment = 0;
912			}
913		}
914		else {
915			err := q.read(ctx, ctx.c.dfd);
916			if(err != "")
917				break out;
918			if(cnt == -1)
919				cnt = r.content_type;
920			if(ctx.status & SSL3_RECORD) {
921				case r.content_type {
922				SSL_APPLICATION_DATA =>
923					break;
924				* =>
925					if(cnt != r.content_type)
926						break out;
927				}
928			}
929			else {
930				r.content_type = SSL_V2HANDSHAKE;
931			}
932		}
933	}
934	return got;
935}
936
937record_write(r: ref Record, ctx: ref Context)
938{
939	if(ctx.status & USE_DEVSSL) {
940		buf: array of byte;
941		n: int;
942		c := ctx.c;
943
944		if(ctx.status & SSL3_RECORD) {
945			buf = array [3 + len r.data] of byte;
946			buf[0] = byte r.content_type;
947			buf[1:] = r.version;
948			buf[3:] = r.data;
949			n = sys->write(c.dfd, buf, len buf);
950			if(n < 0 || n != len buf) {
951				if(SSL_DEBUG)
952					log(sys->sprint("ssl3: v3 record write error: %d %r", n));
953				return; # don't terminated until alerts being read
954			}
955		}
956		else {
957			buf = r.data;
958			n = sys->write(c.dfd, buf, len buf);
959			if(n < 0 || n != len buf) {
960				if(SSL_DEBUG)
961					log(sys->sprint("ssl3: v2 record write error: %d %r", n));
962				return; # don't terminated until alerts being read
963			}
964		}
965	}
966	else
967		ctx.out_queue.write(ctx, ctx.c.dfd, r);
968
969	# if(SSL_DEBUG)
970	#	log("ssl3: record_write: \n\t\t" + bastr(buf) + "\n");
971}
972
973RecordQueue.new(): ref RecordQueue
974{
975	q := ref RecordQueue(
976		ref MacState.null(0),
977		ref CipherState.null(1),
978		1 << 15,
979		array [2] of { * => 0},
980		nil,
981		0,
982		0, # b
983		0  # e
984	);
985	return q;
986}
987
988RecordQueue.read(q: self ref RecordQueue, ctx: ref Context, fd: ref Sys->FD): string
989{
990	r := hd q.data;
991	a := r.data;
992	if(ensure(fd, a, 2) < 0)
993		return "no more data";
994	# auto record version detection
995	m, h, pad: int = 0;
996	if(int a[0] < 20 || int a[0] > 23) {
997		ctx.status &= ~SSL3_RECORD;
998		if(int a[0] & 16r80) {
999			h = 2;
1000			m = ((int a[0] & 16r7f) << 8) | int a[1];
1001			pad = 0;
1002		} else {
1003			h = 3;
1004			m = ((int a[0] & 16r3f) << 8) | int a[1];
1005			if(ensure(fd, a[2:], 1) < 0)
1006				return "bad v2 record";
1007			pad = int a[2];
1008			if(pad > m)
1009				return "bad v2 pad";
1010		}
1011		r.content_type = SSL_V2HANDSHAKE;
1012		r.version = SSL_VERSION_2_0;
1013	}
1014	else {
1015		ctx.status |= SSL3_RECORD;
1016		h = 5;
1017		if(ensure(fd, a[2:], 3) < 0)
1018			return "bad v3 record";
1019		m = ((int a[3]) << 8) | int a[4];
1020		r.content_type = int a[0];
1021		r.version = a[1:3];
1022	}
1023	if(ensure(fd, a[h:], m) < 0)
1024#		return "data too short";
1025		return sys->sprint("data too short wanted %d", m);
1026	if(SSL_DEBUG) {
1027		log("ssl3: record read\n\tbefore decrypt\n\t\t" + bastr(a[0:m+h]));
1028		log(sys->sprint("SSL3=%d\n", ctx.status & SSL3_RECORD));
1029	}
1030
1031	# decrypt (data, pad, mac)
1032	pick dec := q.cipherState {
1033	null =>
1034	rc4 =>
1035		keyring->rc4(dec.es, a[h:], m);
1036		if (SSL_DEBUG) log("rc4 1");
1037	descbc =>
1038		keyring->descbc(dec.es, a[h:], m, 1);
1039		if (SSL_DEBUG) log("descbc 1");
1040	ideacbc =>
1041		keyring->ideacbc(dec.es, a[h:], m, 1);
1042		if (SSL_DEBUG) log("ideacbc 1");
1043	* =>
1044	}
1045
1046	if(SSL_DEBUG)
1047		log("ssl3: record read\n\tafter decrypt\n\t\t" + bastr(a[0:m]));
1048
1049	idata, imac, ipad: int = 0;
1050	if(ctx.status & SSL3_RECORD) {
1051		if(q.cipherState.block_size > 1){
1052			pad = int a[h + m - 1];
1053			if(pad >= q.cipherState.block_size)
1054				return "bad v3 pad";
1055			# pad++;
1056			ipad = h+m-pad-1;
1057		}
1058		else
1059			ipad = h+m-pad;
1060		imac = ipad - q.macState.hash_size;
1061		idata = h;
1062	}
1063	else {
1064		imac = h;
1065		idata = imac + q.macState.hash_size;
1066		ipad = h + m - pad;
1067	}
1068	if(tagof q.macState != tagof MacState.null) {
1069		if (ctx.status & SSL3_RECORD)
1070			mac := q.calcmac(ctx, r.content_type, a, idata, imac-idata);
1071		else
1072			mac = q.calcmac(ctx, r.content_type, a, idata, ipad+pad-idata);
1073		if(bytes_cmp(mac, a[imac:imac+len mac]) < 0)
1074			return "bad mac";
1075	}
1076	q.b = idata;
1077	if (ctx.status & SSL3_RECORD)
1078		q.e = imac;
1079	else
1080		q.e = ipad;
1081	q.fragment = q.e - q.b;
1082
1083	if((++q.sequence_numbers[0] == 0) && (ctx.status&SSL3_RECORD))
1084		++q.sequence_numbers[1];
1085
1086	return "";
1087}
1088
1089ensure(fd: ref Sys->FD, a: array of byte, n: int): int
1090{
1091	i, m: int = 0;
1092	while(i < n) {
1093		m = sys->read(fd, a[i:], n - i);
1094		if(m <= 0) {
1095			return -1;
1096		}
1097		i += m;
1098	}
1099	return n;
1100}
1101
1102RecordQueue.write(q: self ref RecordQueue, ctx: ref Context, fd: ref Sys->FD,
1103	r: ref Record): string
1104{
1105	m := len r.data;
1106	h, pad: int = 0;
1107	if(ctx.status & SSL3_RECORD) {
1108		h = 5;
1109		if(q.cipherState.block_size > 1) {
1110			pad = (m+q.macState.hash_size+1)%q.cipherState.block_size;
1111			if (pad)
1112				pad = q.cipherState.block_size - pad;
1113		}
1114	}
1115	else {
1116		h = 2;
1117		if(q.cipherState.block_size > 1) {
1118			pad = m%q.cipherState.block_size;
1119			if(pad) {
1120				pad = q.cipherState.block_size - pad;
1121				h++;
1122			}
1123		}
1124	}
1125
1126	m += pad + q.macState.hash_size;
1127	if ((ctx.status & SSL3_RECORD) && q.cipherState.block_size > 1)
1128		m++;
1129	a := array [h+m] of byte;
1130
1131	idata, imac, ipad: int = 0;
1132	if(ctx.status & SSL3_RECORD) {
1133		a[0] = byte r.content_type;
1134		a[1:] = r.version;
1135		a[3] = byte (m >> 8);			#CJL - netscape ssl3 traces do not show top bit set
1136#		a[3] = byte ((m >> 8) | 16r80);	#CJL
1137#		a[3] = byte (m | 16r8000) >> 8;
1138		a[4] = byte m;
1139		idata = h;
1140		imac = idata + len r.data;
1141		ipad = imac + q.macState.hash_size;
1142		if (q.cipherState.block_size > 1)
1143			a[h+m-1] = byte pad;
1144	}
1145	else {
1146		if(pad) {
1147			a[0] = byte m >> 8;
1148			a[2] = byte pad;
1149		}
1150		else
1151			a[0] = byte ((m >> 8) | 16r80);
1152		a[1] = byte m;
1153		imac = h;
1154		idata = imac + q.macState.hash_size;
1155		ipad = idata + len r.data;
1156	}
1157	a[idata:] = r.data;
1158	if(pad)
1159		a[ipad:] = array [pad] of { * => byte (pad-1)};
1160
1161	if(tagof q.macState != tagof MacState.null) {
1162		if (ctx.status & SSL3_RECORD)
1163			a[imac:] = q.calcmac(ctx, r.content_type, a, idata, len r.data);
1164		else
1165			a[imac:] = q.calcmac(ctx, r.content_type, a, idata, ipad+pad-idata);
1166	}
1167
1168	 if(SSL_DEBUG) {
1169		log("ssl3: record write\n\tbefore encrypt\n\t\t" + bastr(a));
1170		log(sys->sprint("SSL3=%d\n", ctx.status & SSL3_RECORD));
1171	}
1172
1173	# encrypt (data, pad, mac)
1174	pick enc := q.cipherState {
1175	null =>
1176	rc4 =>
1177		keyring->rc4(enc.es, a[h:], m);
1178		if (SSL_DEBUG) log("rc4 0");
1179	descbc =>
1180		keyring->descbc(enc.es, a[h:], m, 0);
1181		if (SSL_DEBUG) log(sys->sprint("descbc 0 %d", m));
1182	ideacbc =>
1183		keyring->ideacbc(enc.es, a[h:], m, 0);
1184		if (SSL_DEBUG) log(sys->sprint("ideacbc 0 %d", m));
1185	* =>
1186	}
1187
1188	 if(SSL_DEBUG)
1189		log("ssl3: record write\n\tafter encrypt\n\t\t" + bastr(a));
1190
1191	if(sys->write(fd, a, h+m) < 0)
1192		return sys->sprint("ssl3: record write: %r");
1193
1194	if((++q.sequence_numbers[0] == 0) && (ctx.status&SSL3_RECORD))
1195		++q.sequence_numbers[1];
1196
1197	return "";
1198}
1199
1200RecordQueue.calcmac(q: self ref RecordQueue, ctx: ref Context, cntype: int, a: array of byte,
1201	ofs, n: int) : array of byte
1202{
1203	digest, b: array of byte;
1204
1205	if(ctx.status & SSL3_RECORD) {
1206		b = array [11] of byte;
1207		i := putn(b, 0, q.sequence_numbers[1], 4);
1208		i = putn(b, i, q.sequence_numbers[0], 4);
1209		b[i++] = byte cntype;
1210		putn(b, i, n, 2);
1211	}
1212	else {
1213		b = array [4] of byte;
1214		putn(b, 0, q.sequence_numbers[0], 4);
1215	}
1216
1217	# if(SSL_DEBUG)
1218	#	log("ssl3: record mac\n\tother =\n\t\t" + bastr(b));
1219
1220	pick ms := q.macState {
1221	md5 =>
1222		digest = array [Keyring->MD5dlen] of byte;
1223		ds0 := ms.ds[0].copy();
1224		if(ctx.status & SSL3_RECORD) {
1225			keyring->md5(b, len b, nil, ds0);
1226			keyring->md5(a[ofs:], n, digest, ds0);
1227			ds1 := ms.ds[1].copy();
1228			keyring->md5(digest, len digest, digest, ds1);
1229		}
1230		else {
1231			keyring->md5(a[ofs:], n, nil, ds0);
1232			keyring->md5(b, len b, digest, ds0);
1233		}
1234	sha =>
1235		digest = array [Keyring->SHA1dlen] of byte;
1236		ds0 := ms.ds[0].copy();
1237		if(ctx.status & SSL3_RECORD) {
1238			keyring->sha1(b, len b, nil, ds0);
1239			keyring->sha1(a[ofs:], n, digest, ds0);
1240			ds1 := ms.ds[1].copy();
1241			keyring->sha1(digest, len digest, digest, ds1);
1242		}
1243		else {
1244			keyring->sha1(a[ofs:], n, nil, ds0);
1245			keyring->sha1(b, len b, digest, ds0);
1246		}
1247	}
1248	return digest;
1249}
1250
1251set_queues(ctx: ref Context): string
1252{
1253	sw: array of byte;
1254	if(ctx.sw_key != nil) {
1255		sw = array [len ctx.sw_key + len ctx.sw_IV] of byte;
1256		sw[0:] = ctx.sw_key;
1257		sw[len ctx.sw_key:] = ctx.sw_IV;
1258	}
1259	cw: array of byte;
1260	if(ctx.cw_key != nil) {
1261		cw = array [len ctx.cw_key + len ctx.cw_IV] of byte;
1262		cw[0:] = ctx.cw_key;
1263		cw[len ctx.cw_key:] = ctx.cw_IV;
1264	}
1265
1266	err := "";
1267	if(ctx.status & USE_DEVSSL) {
1268		err = set_secrets(ctx.c, ctx.sw_mac, ctx.cw_mac, sw, cw);
1269		if(err == "")
1270			err = set_cipher_algs(ctx);
1271	}
1272	else {
1273		err = set_out_queue(ctx);
1274		if(err == "")
1275			err = set_in_queue(ctx);
1276	}
1277
1278	return err;
1279}
1280
1281set_in_queue(ctx: ref Context): string
1282{
1283	sw: array of byte;
1284	if(ctx.sw_key != nil) {
1285		sw = array [len ctx.sw_key + len ctx.sw_IV] of byte;
1286		sw[0:] = ctx.sw_key;
1287		sw[len ctx.sw_key:] = ctx.sw_IV;
1288	}
1289
1290	err := "";
1291	if(ctx.status & USE_DEVSSL) {
1292		err = set_secrets(ctx.c, ctx.sw_mac, nil, sw, nil);
1293		if(err == "")
1294			err = set_cipher_algs(ctx);
1295	}
1296	else
1297		err = set_queue(ctx, ctx.in_queue, ctx.sw_mac, sw);
1298
1299	return err;
1300}
1301
1302set_out_queue(ctx: ref Context): string
1303{
1304	cw: array of byte;
1305	if(ctx.cw_key != nil) {
1306		cw = array [len ctx.cw_key + len ctx.cw_IV] of byte;
1307		cw[0:] = ctx.cw_key;
1308		cw[len ctx.cw_key:] = ctx.cw_IV;
1309	}
1310
1311	err := "";
1312	if(ctx.status & USE_DEVSSL) {
1313		err = set_secrets(ctx.c, nil, ctx.cw_mac, nil, cw);
1314		if(err == "")
1315			err = set_cipher_algs(ctx);
1316	}
1317	else
1318		err = set_queue(ctx, ctx.out_queue, ctx.cw_mac, cw);
1319
1320	return err;
1321}
1322
1323set_queue(ctx: ref Context, q: ref RecordQueue, mac, key: array of byte): string
1324{
1325	e := "";
1326
1327	case ctx.sel_ciph.mac_algorithm {
1328	SSL_NULL_MAC =>
1329		q.macState = ref MacState.null(0);
1330	SSL_MD5 =>
1331		ds: array of ref DigestState;
1332		if(ctx.status & SSL3_RECORD) {
1333			ds = array [2] of ref DigestState;
1334			ds[0] = keyring->md5(mac, len mac, nil, nil);
1335			ds[1] = keyring->md5(mac, len mac, nil, nil);
1336			ds[0] = keyring->md5(SSL_MAC_PAD1, 48, nil, ds[0]);
1337			ds[1] = keyring->md5(SSL_MAC_PAD2, 48, nil, ds[1]);
1338		}
1339		else {
1340			ds = array [1] of ref DigestState;
1341			ds[0] = keyring->md5(mac, len mac, nil, nil);
1342		}
1343		q.macState = ref MacState.md5(Keyring->MD5dlen, ds);
1344	SSL_SHA =>
1345		ds: array of ref DigestState;
1346		if(ctx.status & SSL3_RECORD) {
1347			ds = array [2] of ref DigestState;
1348			ds[0] = keyring->sha1(mac, len mac, nil, nil);
1349			ds[1] = keyring->sha1(mac, len mac, nil, nil);
1350			ds[0] = keyring->sha1(SSL_MAC_PAD1, 40, nil, ds[0]);
1351			ds[1] = keyring->sha1(SSL_MAC_PAD2, 40, nil, ds[1]);
1352		}
1353		else {
1354			ds = array [1] of ref DigestState;
1355			ds[0] = keyring->sha1(mac, len mac, nil, nil);
1356		}
1357		q.macState = ref MacState.sha(Keyring->SHA1dlen, ds);
1358	* =>
1359		e = "ssl3: digest method: unknown";
1360	}
1361
1362	case ctx.sel_ciph.bulk_cipher_algorithm {
1363	SSL_NULL_CIPHER =>
1364		q.cipherState = ref CipherState.null(1);
1365	SSL_RC4 =>
1366		if (SSL_DEBUG) log("rc4setup");
1367		rcs := keyring->rc4setup(key);
1368		q.cipherState = ref CipherState.rc4(1, rcs);
1369	SSL_DES_CBC =>
1370		dcs : ref keyring->DESstate;
1371
1372		if (SSL_DEBUG) log(sys->sprint("dessetup %d", len key));
1373		if (len key >= 16)
1374			dcs = keyring->dessetup(key[0:8], key[8:16]);
1375		else if (len key >= 8)
1376			dcs = keyring->dessetup(key[0:8], nil);
1377		else
1378			e = "ssl3: bad DES key length";
1379		q.cipherState = ref CipherState.descbc(8, dcs);
1380	SSL_IDEA_CBC =>
1381		ics : ref keyring->IDEAstate;
1382
1383		if (SSL_DEBUG) log(sys->sprint("ideasetup %d", len key));
1384		if (len key >= 24)
1385			ics = keyring->ideasetup(key[0:16], key[16:24]);
1386		else if (len key >= 16)
1387			ics = keyring->ideasetup(key[0:16], nil);
1388		else
1389			e = "ssl3: bad IDEA key length";
1390		q.cipherState = ref CipherState.ideacbc(8, ics);
1391	SSL_RC2_CBC or
1392	SSL_3DES_EDE_CBC or
1393	SSL_FORTEZZA_CBC =>
1394		e = "ssl3: unsupported cipher";
1395	* =>
1396		e = "ssl3: unknown cipher";
1397	}
1398
1399	if(ctx.status & SSL3_RECORD) {
1400		q.length = 1 << 14;
1401		if(tagof q.macState != tagof MacState.null)
1402			q.length += 2048;
1403	}
1404	else {
1405		if(q.cipherState.block_size > 1) {
1406			q.length = (1<<14) - q.macState.hash_size - 1;
1407			q.length -= q.length % q.cipherState.block_size;
1408		}
1409		else
1410			q.length = (1<<15) - q.macState.hash_size - 1;
1411	}
1412	if(ctx.status & SSL3_RECORD)
1413		q.sequence_numbers[0] = q.sequence_numbers[1] = 0;
1414
1415	return e;
1416}
1417
1418set_cipher_algs(ctx: ref Context) : string
1419{
1420	e: string;
1421
1422	algspec := "alg";
1423
1424	case enc := ctx.sel_ciph.bulk_cipher_algorithm {
1425	SSL_NULL_CIPHER =>
1426		algspec += " clear";
1427	SSL_RC4 => 	# stream cipher
1428		algspec += " rc4_128";
1429	SSL_DES_CBC => # block cipher
1430		algspec += " descbc";
1431	SSL_IDEA_CBC => # block cipher
1432		algspec += " ideacbc";
1433	SSL_RC2_CBC or
1434	SSL_3DES_EDE_CBC or
1435	SSL_FORTEZZA_CBC =>
1436		e = "ssl3: encrypt method: unsupported";
1437	* =>
1438		e = "ssl3: encrypt method: unknown";
1439	}
1440
1441	case mac := ctx.sel_ciph.mac_algorithm {
1442	SSL_NULL_MAC =>
1443		algspec += " clear";
1444	SSL_MD5 =>
1445		algspec += " md5";
1446	SSL_SHA =>
1447		algspec += " sha1";
1448	* =>
1449		e = "ssl3: digest method: unknown";
1450	}
1451
1452	e = set_ctl(ctx.c, algspec);
1453	if(e != "") {
1454		if(SSL_DEBUG)
1455			log("failed to set cipher algs: " + e);
1456	}
1457
1458	return e;
1459}
1460
1461set_ctl(c: ref Sys->Connection, s: string): string
1462{
1463	a := array of byte s;
1464	if(sys->write(c.cfd, a, len a) < 0)
1465		return sys->sprint("error writing sslctl: %r");
1466
1467	if(SSL_DEBUG)
1468		log("ssl3: set cipher algorithm:\n\t\t" + s + "\n");
1469
1470	return "";
1471}
1472
1473set_secrets(c: ref Sys->Connection, min, mout, sin, sout: array of byte) : string
1474{
1475	fmin := sys->open(c.dir + "/macin", Sys->OWRITE);
1476	fmout := sys->open(c.dir + "/macout", Sys->OWRITE);
1477	fsin := sys->open(c.dir + "/secretin", Sys->OWRITE);
1478	fsout := sys->open(c.dir + "/secretout", Sys->OWRITE);
1479	if(fmin == nil || fmout == nil || fsin == nil || fsout == nil)
1480		return sys->sprint("can't open ssl secret files: %r\n");
1481
1482	if(sin != nil) {
1483		if(SSL_DEBUG)
1484			log("ssl3: set encryption secret and IV\n\tsecretin:\n\t\t" + bastr(sin) + "\n");
1485		if(sys->write(fsin, sin, len sin) < 0)
1486			return sys->sprint("error writing secretin: %r");
1487	}
1488	if(sout != nil) {
1489		if(SSL_DEBUG)
1490			log("ssl3: set encryption secret and IV\n\tsecretout:\n\t\t" + bastr(sout) + "\n");
1491		if(sys->write(fsout, sout, len sout) < 0)
1492			return sys->sprint("error writing secretout: %r");
1493	}
1494	if(min != nil) {
1495		if(SSL_DEBUG)
1496			log("ssl3: set digest secret\n\tmacin:\n\t\t" + bastr(min) + "\n");
1497		if(sys->write(fmin, min, len min) < 0)
1498			return sys->sprint("error writing macin: %r");
1499	}
1500	if(mout != nil) {
1501		if(SSL_DEBUG)
1502			log("ssl3: set digest secret\n\tmacout:\n\t\t" + bastr(mout) + "\n");
1503		if(sys->write(fmout, mout, len mout) < 0)
1504			return sys->sprint("error writing macout: %r");
1505	}
1506
1507	return "";
1508}
1509
1510#
1511# description must be alert description
1512#
1513fatal(description: int, debug_msg: string, ctx: ref Context)
1514{
1515	if(SSL_DEBUG)
1516		log("ssl3: " + debug_msg);
1517
1518	# TODO: use V2Handshake.Error for v2
1519	alert_enque(ref Alert(SSL_FATAL, description), ctx);
1520
1521	# delete session id
1522	ctx.session.session_id = nil;
1523
1524	ctx.state = STATE_EXIT;
1525}
1526
1527alert_enque(a: ref Alert, ctx: ref Context)
1528{
1529	p := ref Protocol.pAlert(a);
1530
1531	protocol_write(p, ctx);
1532}
1533
1534# clean up out queue before switch cipher. this is why
1535# change cipher spec differs from handshake message by ssl spec
1536
1537ccs_enque(cs: ref ChangeCipherSpec, ctx: ref Context)
1538{
1539	p := ref Protocol.pChangeCipherSpec(cs);
1540
1541	protocol_write(p, ctx);
1542
1543	record_write_queue(ctx);
1544	ctx.out_queue.data = nil;
1545}
1546
1547handshake_enque(h: ref Handshake, ctx: ref Context)
1548{
1549	p := ref Protocol.pHandshake(h);
1550
1551	protocol_write(p, ctx);
1552}
1553
1554protocol_write(p: ref Protocol, ctx: ref Context)
1555{
1556	record_version := SSL_VERSION_2_0;
1557	if(ctx.status & SSL3_RECORD)
1558		record_version = SSL_VERSION_3_0;
1559	(r, e) := p.encode(record_version);
1560	if(e != "") {
1561		if(SSL_DEBUG)
1562			log("ssl3: protocol_write: " + e);
1563		exit;
1564	}
1565
1566	# Note: only for sslv3
1567	if((ctx.status&SSL2_HANDSHAKE) && (ctx.status&SSL3_HANDSHAKE)) {
1568		if(ctx.state == STATE_HELLO_REQUEST) {
1569			e = update_handshake_hash(ctx, r);
1570			if(e != "") {
1571				if(SSL_DEBUG)
1572					log("ssl3: protocol_write: " + e);
1573				exit;
1574			}
1575		}
1576	}
1577	if((ctx.status&SSL3_HANDSHAKE) && (r.content_type == SSL_HANDSHAKE)) {
1578		e = update_handshake_hash(ctx, r);
1579		if(e != "") {
1580			if(SSL_DEBUG)
1581				log("ssl3: protocol_write: " + e);
1582			exit;
1583		}
1584	}
1585
1586	ctx.out_queue.data = r :: ctx.out_queue.data;
1587}
1588
1589#feed_data(ctx: ref Context, a: array of byte, n: int): int
1590#{
1591#
1592#}
1593
1594# FIFO
1595record_write_queue(ctx: ref Context)
1596{
1597	write_queue : list of ref Record;
1598
1599	wq := ctx.out_queue.data;
1600	while(wq != nil) {
1601		write_queue = hd wq :: write_queue;
1602		wq = tl wq;
1603	}
1604
1605	wq = write_queue;
1606	while(wq != nil) {
1607		record_write(hd wq, ctx);
1608		wq = tl wq;
1609	}
1610}
1611
1612# Possible combinations are v2 only, v3 only and both (undetermined). The v2 only must be
1613# v2 handshake and v2 record layer. The v3 only must be v3 handshake and v3 record layer.
1614# If both v2 and v3 are supported, it may be v2 handshake and v2 record layer, or v3
1615# handshake and v3 record layer, or v2 handshake and v3 record layer. In the case of
1616# both, the client should send a v2 client hello message with handshake protocol version v3.
1617
1618do_protocol(ctx: ref Context): string
1619{
1620	r: ref Record;
1621	in: ref Protocol;
1622	e: string = nil;
1623
1624	while(ctx.state != STATE_EXIT) {
1625
1626		if(SSL_DEBUG)
1627			log("ssl3: state = " + state_info(ctx));
1628
1629		# init a new handshake
1630		if(ctx.state == STATE_HELLO_REQUEST) {
1631			# v2 and v3
1632			if((ctx.status&SSL2_HANDSHAKE) && (ctx.status&SSL3_HANDSHAKE)) {
1633				ch := ref V2Handshake.ClientHello(
1634						SSL_VERSION_3_0,
1635						v3tov2specs(ctx.local_info.suites),
1636						ctx.session.session_id,
1637						ctx.client_random
1638					);
1639				v2handshake_enque(ch, ctx);
1640				in = ref Protocol.pV2Handshake(ch);
1641			}
1642			# v3 only
1643			else if(ctx.status&SSL3_HANDSHAKE) {
1644				in = ref Protocol.pHandshake(ref Handshake.HelloRequest());
1645			}
1646			# v2 only
1647			else if(ctx.status&SSL2_HANDSHAKE) {
1648				ch := ref V2Handshake.ClientHello(
1649						SSL_VERSION_2_0,
1650						v3tov2specs(ctx.local_info.suites),
1651						ctx.session.session_id,
1652						ctx.client_random[32-SSL2_CHALLENGE_LENGTH:32]
1653					);
1654				v2handshake_enque(ch, ctx);
1655				in = ref Protocol.pV2Handshake(ch);
1656			}
1657			# unknown version
1658			else {
1659				e = "unknown ssl device version";
1660				fatal(SSL_CLOSE_NOTIFY, "ssl3: " + e, ctx);
1661				continue;
1662			}
1663		}
1664
1665		if(in == nil) {
1666			(r, in, e) = protocol_read(ctx);
1667			if(e != "") {
1668				fatal(SSL_CLOSE_NOTIFY, "ssl3: " + e, ctx);
1669				continue;
1670			}
1671			if(SSL_DEBUG)
1672				log("ssl3: protocol_read: ------\n" + in.tostring());
1673		}
1674
1675		pick p := in {
1676		pAlert =>
1677			do_alert(p.alert, ctx);
1678
1679		pChangeCipherSpec =>
1680			if(ctx.state != STATE_CHANGE_CIPHER_SPEC) {
1681				e += "ChangeCipherSpec";
1682				break;
1683			}
1684			do_change_cipher_spec(ctx);
1685
1686		pHandshake =>
1687			if(!(ctx.status & SSL3_HANDSHAKE)) {
1688				e = "Wrong Handshake";
1689				break;
1690			}
1691			if((ctx.status & SSL3_RECORD) &&
1692				(ctx.state == SSL2_STATE_SERVER_HELLO)) {
1693				ctx.state = STATE_SERVER_HELLO;
1694				ctx.status &= ~SSL2_HANDSHAKE;
1695			}
1696			e = do_handshake(p.handshake, ctx);
1697
1698		pV2Handshake =>
1699			if(ctx.state != STATE_HELLO_REQUEST) {
1700				if(!(ctx.status & SSL2_HANDSHAKE)) {
1701					e = "Wrong Handshake";
1702					break;
1703				}
1704				e = do_v2handshake(p.handshake, ctx);
1705			}
1706			else
1707				ctx.state = SSL2_STATE_SERVER_HELLO;
1708
1709
1710		* =>
1711			e = "unknown protocol message";
1712		}
1713
1714		if(e != nil) {
1715			e = "do_protocol: wrong protocol side or protocol message: " + e;
1716			fatal(SSL_UNEXPECTED_MESSAGE, e, ctx);
1717		}
1718
1719		in = nil;
1720
1721		record_write_queue(ctx);
1722		ctx.out_queue.data = nil;
1723	}
1724
1725	return e;
1726}
1727
1728state_info(ctx: ref Context): string
1729{
1730	info: string;
1731
1732	if(ctx.status & SSL3_RECORD)
1733		info = "\n\tRecord Version 3: ";
1734	else
1735		info = "\n\tRecord Version 2: ";
1736
1737	if(ctx.status & SSL2_HANDSHAKE) {
1738
1739		if(ctx.status & SSL3_HANDSHAKE) {
1740			info += "\n\tHandshake Version Undetermined: Client Hello";
1741		}
1742		else {
1743			info += "\n\tHandshake Version 2: ";
1744
1745			case ctx.state {
1746			SSL2_STATE_CLIENT_HELLO =>
1747				info += "Client Hello";
1748			SSL2_STATE_SERVER_HELLO =>
1749				info += "Server Hello";
1750			SSL2_STATE_CLIENT_MASTER_KEY =>
1751				info += "Client Master Key";
1752			SSL2_STATE_SERVER_VERIFY =>
1753				info += "Server Verify";
1754			SSL2_STATE_REQUEST_CERTIFICATE =>
1755				info += "Request Certificate";
1756			SSL2_STATE_CLIENT_CERTIFICATE =>
1757				info += "Client Certificate";
1758			SSL2_STATE_CLIENT_FINISHED =>
1759				info += "Client Finished";
1760			SSL2_STATE_SERVER_FINISHED =>
1761				info += "Server Finished";
1762			SSL2_STATE_ERROR =>
1763				info += "Error";
1764			}
1765		}
1766	}
1767	else {
1768		info = "\n\tHandshake Version 3: ";
1769
1770		case ctx.state {
1771		STATE_EXIT =>
1772			info += "Exit";
1773
1774		STATE_CHANGE_CIPHER_SPEC =>
1775			info += "Change Cipher Spec";
1776
1777		STATE_HELLO_REQUEST =>
1778			info += "Hello Request";
1779
1780		STATE_CLIENT_HELLO =>
1781			info += "Client Hello";
1782
1783		STATE_SERVER_HELLO =>
1784			info += "Server Hello";
1785
1786		STATE_CLIENT_KEY_EXCHANGE =>
1787			info += "Client Key Exchange";
1788
1789		STATE_SERVER_KEY_EXCHANGE =>
1790			info += "Server Key Exchange";
1791
1792		STATE_SERVER_HELLO_DONE =>
1793			info += "Server Hello Done";
1794
1795		STATE_CLIENT_CERTIFICATE =>
1796			info += "Client Certificate";
1797
1798		STATE_SERVER_CERTIFICATE =>
1799			info += "Server Certificate";
1800
1801		STATE_CERTIFICATE_VERIFY =>
1802			info += "Certificate Verify";
1803
1804		STATE_FINISHED =>
1805			info += "Finished";
1806		}
1807	}
1808
1809	if(ctx.status & CLIENT_AUTH)
1810		info += ": Client Auth";
1811	if(ctx.status & CERT_REQUEST)
1812		info += ": Cert Request";
1813	if(ctx.status & CERT_SENT)
1814		info += ": Cert Sent";
1815	if(ctx.status & CERT_RECEIVED)
1816		info += ": Cert Received";
1817
1818	return info;
1819}
1820
1821reset_client_random(ctx: ref Context)
1822{
1823	ctx.client_random[0:] = int_encode(ctx.session.connection_time, 4);
1824	ctx.client_random[4:] = random->randombuf(Random->NotQuiteRandom, 28);
1825}
1826
1827reset_server_random(ctx: ref Context)
1828{
1829	ctx.server_random[0:] = int_encode(ctx.session.connection_time, 4);
1830	ctx.server_random[4:] = random->randombuf(Random->NotQuiteRandom, 28);
1831}
1832
1833update_handshake_hash(ctx: ref Context, r: ref Record): string
1834{
1835	err := "";
1836
1837	ctx.sha_state = keyring->sha1(r.data, len r.data, nil, ctx.sha_state);
1838	ctx.md5_state = keyring->md5(r.data, len r.data, nil, ctx.md5_state);
1839	if(ctx.sha_state == nil || ctx.md5_state == nil)
1840		err = "update handshake hash failed";
1841
1842	# if(SSL_DEBUG)
1843	#	log("ssl3: update_handshake_hash\n\tmessage_data =\n\t\t" + bastr(r.data) + "\n");
1844
1845	return err;
1846}
1847
1848# Note:
1849#	this depends on the record protocol
1850protocol_read(ctx: ref Context): (ref Record, ref Protocol, string)
1851{
1852	p: ref Protocol;
1853	r: ref Record;
1854	e: string;
1855
1856	vers := SSL_VERSION_2_0;
1857	if(ctx.status & SSL3_RECORD)
1858		vers = SSL_VERSION_3_0;
1859	if(ctx.status & USE_DEVSSL)
1860		(r, e) = devssl_read(ctx);
1861	else
1862		(r, e) = record_read(ctx);
1863	if(e != "")
1864		return (nil, nil, e);
1865
1866	(p, e) = Protocol.decode(r, ctx);
1867	if(e != "")
1868		return (r, nil, e);
1869
1870	return (r, p, nil);
1871}
1872
1873# Alert messages with a level of fatal result in the immediate
1874# termination of the connection and zero out session.
1875
1876do_alert(a: ref Alert, ctx: ref Context)
1877{
1878	case a.level {
1879	SSL_FATAL =>
1880
1881		case a.description {
1882		SSL_UNEXPECTED_MESSAGE =>
1883
1884			# should never be observed in communication
1885			# between proper implementations.
1886			break;
1887
1888		SSL_HANDSHAKE_FAILURE =>
1889
1890			# unable to negotiate an acceptable set of security
1891			# parameters given the options available.
1892			break;
1893
1894		* =>
1895			break;
1896		}
1897
1898		ctx.session.session_id = nil;
1899		ctx.state = STATE_EXIT;
1900
1901	SSL_WARNING =>
1902
1903		case a.description {
1904		SSL_CLOSE_NOTIFY =>
1905
1906			if(SSL_DEBUG)
1907				log("ssl3: do_alert SSL_WARNING:SSL_CLOSE_NOTIFY\n");
1908			# notifies the recipient that the sender will not
1909			# send any more messages on this connection.
1910
1911			ctx.state = STATE_EXIT;
1912			fatal(SSL_CLOSE_NOTIFY, "ssl3: response close notify", ctx);
1913
1914		SSL_NO_CERTIFICATE =>
1915
1916			# A no_certificate alert message may be sent in
1917			# response to a certification request if no
1918			# appropriate certificate is available.
1919
1920			if(ctx.state == STATE_CLIENT_CERTIFICATE) {
1921				hm := ref Handshake.Certificate(ctx.local_info.certs);
1922				handshake_enque(hm, ctx);
1923			}
1924
1925		SSL_BAD_CERTIFICATE or
1926
1927			# A certificate was corrupt, contained signatures
1928			# that did not verify correctly, etc.
1929
1930		SSL_UNSUPPORTED_CERTIFICATE or
1931
1932			# A certificate was of an unsupported type.
1933
1934		SSL_CERTIFICATE_REVOKED or
1935
1936			# A certificate was revoked by its signer.
1937
1938		SSL_CERTIFICATE_EXPIRED or
1939
1940			# A certificate has expired or is not currently
1941			# valid.
1942
1943		SSL_CERTIFICATE_UNKNOWN =>
1944
1945			# Some other (unspecified) issue arose in
1946			# processing the certificate, rendering it
1947			# unacceptable.
1948			break;
1949
1950		* =>
1951			ctx.session.session_id = nil;
1952			fatal(SSL_ILLEGAL_PARAMETER, "ssl3: unknown alert description", ctx);
1953		}
1954
1955	* =>
1956		ctx.session.session_id = nil;
1957		fatal(SSL_ILLEGAL_PARAMETER, "ssl3: unknown alert level received", ctx);
1958	}
1959}
1960
1961# notify the receiving party that subsequent records will
1962# be protected under the just-negotiated CipherSpec and keys.
1963
1964do_change_cipher_spec(ctx: ref Context)
1965{
1966	# calculate and set new keys
1967	if(!(ctx.status & IN_READY)) {
1968		e := set_in_queue(ctx);
1969		if(e != "") {
1970			fatal(SSL_CLOSE_NOTIFY, "do_change_cipher_spec: setup new cipher failed", ctx);
1971			return;
1972		}
1973		ctx.status |= IN_READY;
1974
1975		if(SSL_DEBUG)
1976			log("ssl3: set in cipher done\n");
1977	}
1978
1979	ctx.state = STATE_FINISHED;
1980}
1981
1982
1983# process and advance handshake messages, update internal stack and switch to next
1984# expected state(s).
1985
1986do_handshake(handshake: ref Handshake, ctx: ref Context) : string
1987{
1988	e := "";
1989
1990	pick h := handshake {
1991	HelloRequest =>
1992		if(!(ctx.status & CLIENT_SIDE) || ctx.state != STATE_HELLO_REQUEST) {
1993			e = "HelloRequest";
1994			break;
1995		}
1996		do_hello_request(ctx);
1997
1998	ClientHello =>
1999		if((ctx.status & CLIENT_SIDE) || ctx.state != STATE_CLIENT_HELLO) {
2000			e = "ClientHello";
2001			break;
2002		}
2003		do_client_hello(h, ctx);
2004
2005	ServerHello =>
2006		if(!(ctx.status & CLIENT_SIDE) || ctx.state != STATE_SERVER_HELLO) {
2007			e = "ServerHello";
2008			break;
2009		}
2010		do_server_hello(h, ctx);
2011
2012	ClientKeyExchange =>
2013		if((ctx.status & CLIENT_SIDE) || ctx.state != STATE_CLIENT_KEY_EXCHANGE) {
2014			e = "ClientKeyExchange";
2015			break;
2016		}
2017		do_client_keyex(h, ctx);
2018
2019	ServerKeyExchange =>
2020		if(!(ctx.status & CLIENT_SIDE) ||
2021			(ctx.state != STATE_SERVER_KEY_EXCHANGE && ctx.state != STATE_SERVER_HELLO_DONE)) {
2022			e = "ServerKeyExchange";
2023			break;
2024		}
2025		do_server_keyex(h, ctx);
2026
2027	ServerHelloDone =>
2028		# diff from SSLRef, to support variant impl
2029		if(!(ctx.status & CLIENT_SIDE) ||
2030			(ctx.state != STATE_SERVER_HELLO_DONE && ctx.state != STATE_SERVER_KEY_EXCHANGE)) {
2031			e = "ServerHelloDone";
2032			break;
2033		}
2034		do_server_done(ctx);
2035
2036	Certificate =>
2037		if(ctx.status & CLIENT_SIDE) {
2038			if(ctx.state != STATE_SERVER_CERTIFICATE) {
2039				e = "ServerCertificate";
2040				break;
2041			}
2042			do_server_cert(h, ctx);
2043		}
2044		else {
2045			if(ctx.state != STATE_CLIENT_CERTIFICATE) {
2046				e = "ClientCertificate";
2047				break;
2048			}
2049			do_client_cert(h, ctx); # server_side
2050		}
2051
2052	CertificateRequest =>
2053		if(!(ctx.status & CLIENT_SIDE) || ctx.state != STATE_SERVER_HELLO_DONE
2054			|| ctx.state != STATE_SERVER_KEY_EXCHANGE) {
2055			e = "CertificateRequest";
2056			break;
2057		}
2058		do_cert_request(h, ctx);
2059
2060	CertificateVerify =>
2061		if((ctx.status & CLIENT_SIDE) || ctx.state != STATE_CERTIFICATE_VERIFY) {
2062			e = "CertificateVerify";
2063			break;
2064		}
2065		do_cert_verify(h, ctx);
2066
2067	Finished =>
2068		if(ctx.status & CLIENT_SIDE) {
2069			if(ctx.state != STATE_FINISHED) {
2070				e = "ClientFinished";
2071				break;
2072			}
2073			do_finished(SSL_CLIENT_SENDER, ctx);
2074		}
2075		else {
2076			if(ctx.state != STATE_FINISHED) {
2077				e = "ServerFinished";
2078				break;
2079			}
2080			do_finished(SSL_SERVER_SENDER, ctx);
2081		}
2082
2083	* =>
2084		e = "unknown handshake message";
2085	}
2086
2087	if(e != nil)
2088		e = "do_handshake: " + e;
2089
2090	return e;
2091}
2092
2093# [client side]
2094# The hello request message may be sent by server at any time, but will be ignored by
2095# the client if the handshake protocol is already underway. It is simple notification
2096# that the client should begin the negotiation process anew by sending a client hello
2097# message.
2098
2099do_hello_request(ctx: ref Context)
2100{
2101	# start from new handshake digest state
2102	ctx.sha_state = ctx.md5_state = nil;
2103
2104	# Note:
2105	# 	sending ctx.local_info.suites instead of ctx.session.suite,
2106	#	if session is resumable by server, ctx.session.suite will be used.
2107	handshake_enque(
2108		ref Handshake.ClientHello(
2109			ctx.session.version,
2110			ctx.client_random,
2111			ctx.session.session_id,
2112			ctx.local_info.suites,
2113			ctx.local_info.comprs
2114		),
2115		ctx
2116	);
2117
2118	ctx.state = STATE_SERVER_HELLO;
2119}
2120
2121# [client side]
2122# Processes the received server hello handshake message and determines if the session
2123# is resumable. (The client sends a client hello using the session id of the session
2124# to be resumed. The server then checks its session cache for a match. If a match is
2125# FOUND, and the server is WILLING to re-establish the connection under the specified
2126# session state, it will send a server hello with the SAME session id value.) If the
2127# session is resumed, at this point both client and server must send change cipher
2128# spec messages. If the session is not resumable, the client and server perform
2129# a full handshake. (On the server side, if a session id match is not found, the
2130# server generates a new session id or if the server is not willing to resume, the
2131# server uses a null session id).
2132
2133do_server_hello(hm: ref Handshake.ServerHello, ctx: ref Context)
2134{
2135	# trying to resume
2136	if(bytes_cmp(ctx.session.session_id, hm.session_id) == 0) {
2137
2138		if(SSL_DEBUG)
2139			log("ssl3: session resumed\n");
2140
2141		ctx.status |= SESSION_RESUMABLE;
2142		# avoid version attack
2143		if(ctx.session.version[0] != hm.version[0] ||
2144			ctx.session.version[1] != hm.version[1]) {
2145			fatal(SSL_CLOSE_NOTIFY,	"do_server_hello: version mismatch", ctx);
2146			return;
2147		}
2148
2149		ctx.server_random = hm.random;
2150
2151		# uses the retrieved session suite by server (should be same by client)
2152		(ciph, keyx, sign, e)
2153			:= suite_to_spec(hm.suite, SSL3_Suites);
2154		if(e != nil) {
2155			fatal(SSL_UNEXPECTED_MESSAGE, "server hello: suite not found", ctx);
2156			return;
2157		}
2158		ctx.sel_ciph = ciph;
2159		ctx.sel_keyx = keyx;
2160		ctx.sel_sign = sign;
2161		ctx.sel_cmpr = int ctx.session.compression; # not supported by ssl3 yet
2162
2163		# calculate keys
2164		(ctx.cw_mac, ctx.sw_mac, ctx.cw_key, ctx.sw_key, ctx.cw_IV, ctx.sw_IV)
2165			= calc_keys(ctx.sel_ciph, ctx.session.master_secret,
2166			ctx.client_random, ctx.server_random);
2167
2168
2169		ctx.state = STATE_CHANGE_CIPHER_SPEC;
2170	}
2171	else {
2172		ctx.status &= ~SESSION_RESUMABLE;
2173
2174		# On the server side, if a session id match is not found, the
2175		# server generates a new session id or if the server is not willing
2176		# to resume, the server uses an empty session id and cannot be
2177		# cached by both client and server.
2178
2179		ctx.session.session_id = hm.session_id;
2180		ctx.session.version = hm.version;
2181		ctx.server_random = hm.random;
2182
2183		if(SSL_DEBUG)
2184			log("ssl3: do_server_hello:\n\tselected cipher suite =\n\t\t"
2185			+ cipher_suite_info(hm.suite, SSL3_Suites) + "\n");
2186
2187		(ciph, keyx, sign, e) := suite_to_spec(hm.suite, SSL3_Suites);
2188		if(e != nil) {
2189			fatal(SSL_UNEXPECTED_MESSAGE, "server hello: suite not found", ctx);
2190			return;
2191		}
2192
2193		ctx.sel_ciph = ciph;
2194		ctx.sel_keyx = keyx;
2195		ctx.sel_sign = sign;
2196		ctx.sel_cmpr = int hm.compression; # not supported by ssl3 yet
2197
2198		# next state is determined by selected key exchange and signature methods
2199		# the ctx.sel_keyx and ctx.sel_sign are completed by the following handshake
2200		# Certificate and/or ServerKeyExchange
2201
2202		if(tagof ctx.sel_keyx == tagof KeyExAlg.DH &&
2203			tagof ctx.sel_sign == tagof SigAlg.anon)
2204			ctx.state = STATE_SERVER_KEY_EXCHANGE;
2205		else
2206			ctx.state = STATE_SERVER_CERTIFICATE;
2207	}
2208}
2209
2210# [client side]
2211# Processes the received server key exchange message. The server key exchange message
2212# is sent by the server if it has no certificate, has a certificate only used for
2213# signing, or FORTEZZA KEA key exchange is used.
2214
2215do_server_keyex(hm: ref Handshake.ServerKeyExchange, ctx: ref Context)
2216{
2217	# install exchange keys sent by server, this may require public key
2218	# retrieved from certificate sent by Handshake.Certificate message
2219
2220	(err, i) := install_server_xkey(hm.xkey, ctx.sel_keyx);
2221	if(err == "")
2222		err = verify_server_xkey(ctx.client_random, ctx.server_random, hm.xkey, i, ctx.sel_sign);
2223
2224	if(err == "")
2225		ctx.state = STATE_SERVER_HELLO_DONE;
2226	else
2227		fatal(SSL_HANDSHAKE_FAILURE, "do_server_keyex: " + err, ctx);
2228}
2229
2230# [client side]
2231# Processes the received server hello done message by verifying that the server
2232# provided a valid certificate if required and checking that the server hello
2233# parameters are acceptable.
2234
2235do_server_done(ctx: ref Context)
2236{
2237	# On client side, optionally send client cert chain if client_auth
2238	# is required by the server. The server may drop the connection,
2239	# if it does not receive client certificate in the following
2240	# Handshake.ClientCertificate message
2241	if(ctx.status & CLIENT_AUTH) {
2242		if(ctx.local_info.certs != nil) {
2243			handshake_enque(
2244				ref Handshake.Certificate(ctx.local_info.certs),
2245				ctx
2246			);
2247			ctx.status |= CERT_SENT;
2248		}
2249		else {
2250			alert_enque(
2251				ref Alert(SSL_WARNING, SSL_NO_CERTIFICATE),
2252				ctx
2253			);
2254		}
2255	}
2256
2257	# calculate premaster secrect, client exchange keys and update ref KeyExAlg
2258	# of the client side
2259	(x, pm, e) := calc_client_xkey(ctx.sel_keyx);
2260	if(e != "") {
2261		fatal(SSL_HANDSHAKE_FAILURE, e, ctx);
2262		return;
2263	}
2264	handshake_enque(ref Handshake.ClientKeyExchange(x), ctx);
2265
2266	ms := calc_master_secret(pm, ctx.client_random, ctx.server_random);
2267	if(ms == nil) {
2268		fatal(SSL_HANDSHAKE_FAILURE, "server hello done: calc master secret failed", ctx);
2269		return;
2270	}
2271	# ctx.premaster_secret = pm;
2272	ctx.session.master_secret = ms;
2273
2274	# sending certificate verifiy message if the client auth is required
2275	# and client certificate has been sent,
2276	if(ctx.status & CERT_SENT) {
2277		sig : array of byte;
2278		(md5_hash, sha_hash)
2279			:= calc_finished(nil, ctx.session.master_secret, ctx.sha_state, ctx.md5_state);
2280		# check type of client cert being sent
2281		pick sk := ctx.local_info.sk {
2282		RSA =>
2283			hashes := array [36] of byte;
2284			hashes[0:] = md5_hash;
2285			hashes[16:] = sha_hash;
2286			#(e, sig) = pkcs->rsa_sign(hashes, sk, PKCS->MD5_WithRSAEncryption);
2287		DSS =>
2288			#(e, sig) = pkcs->dss_sign(sha_hash, sk);
2289		* =>
2290			e = "unknown sign";
2291		}
2292		if(e != "") {
2293			fatal(SSL_HANDSHAKE_FAILURE, "server hello done: sign cert verify failed", ctx);
2294			return;
2295		}
2296		handshake_enque(ref Handshake.CertificateVerify(sig), ctx);
2297	}
2298
2299	ccs_enque(ref ChangeCipherSpec(1), ctx);
2300	(ctx.cw_mac, ctx.sw_mac, ctx.cw_key, ctx.sw_key, ctx.cw_IV, ctx.sw_IV)
2301		= calc_keys(ctx.sel_ciph, ctx.session.master_secret,
2302		ctx.client_random, ctx.server_random);
2303
2304	# set cipher on write channel
2305	e = set_out_queue(ctx);
2306	if(e != nil) {
2307		fatal(SSL_HANDSHAKE_FAILURE, "do_server_done: " + e, ctx);
2308		return;
2309	}
2310	ctx.status |= OUT_READY;
2311
2312	if(SSL_DEBUG)
2313		log("ssl3: set out cipher done\n");
2314	(mh, sh) := calc_finished(SSL_CLIENT_SENDER, ctx.session.master_secret,
2315		ctx.sha_state, ctx.md5_state);
2316# sending out the Finished msg causes MS https servers to hangup
2317#sys->print("RETURNING FROM DO_SERVER_DONE\n");
2318#return;
2319	handshake_enque(ref Handshake.Finished(mh, sh), ctx);
2320
2321	ctx.state = STATE_CHANGE_CIPHER_SPEC;
2322}
2323
2324# [client side]
2325# Process the received certificate message.
2326# Note:
2327#	according to current US export law, RSA moduli larger than 512 bits
2328# 	may not be used for key exchange in software exported from US. With
2329# 	this message, larger RSA keys may be used as signature only
2330# 	certificates to sign temporary shorter RSA keys for key exchange.
2331
2332do_server_cert(hm: ref Handshake.Certificate, ctx: ref Context)
2333{
2334	if(hm.cert_list == nil) {
2335		fatal(SSL_UNEXPECTED_MESSAGE, "nil peer certificate", ctx);
2336		return;
2337	}
2338
2339	# server's certificate is the last one in the chain (reverse required)
2340	cl := hm.cert_list;
2341	ctx.session.peer_certs = nil;
2342	while(cl != nil) {
2343		ctx.session.peer_certs = hd cl::ctx.session.peer_certs;
2344		cl = tl cl;
2345	}
2346
2347	# TODO: verify certificate chain
2348	#	check if in the acceptable dnlist
2349	# ctx.sel_keyx.peer_pk = x509->verify_chain(ctx.session.peer_certs);
2350	if(SSL_DEBUG)
2351		log("ssl3: number certificates got: " + string len ctx.session.peer_certs);
2352	peer_cert := hd ctx.session.peer_certs;
2353	(e, signed) := x509->Signed.decode(peer_cert);
2354	if(e != "") {
2355		if(SSL_DEBUG)
2356			log("ss3: server certificate: " + e);
2357		fatal(SSL_HANDSHAKE_FAILURE, "server certificate: " + e, ctx);
2358		return;
2359	}
2360
2361	srv_cert: ref Certificate;
2362	(e, srv_cert) = x509->Certificate.decode(signed.tobe_signed);
2363	if(e != "") {
2364		if(SSL_DEBUG)
2365			log("ss3: server certificate: " + e);
2366		fatal(SSL_HANDSHAKE_FAILURE, "server certificate: " + e, ctx);
2367		return;
2368	}
2369	if(SSL_DEBUG)
2370		log("ssl3: " + srv_cert.tostring());
2371
2372	# extract and determine byte of user certificate
2373	id: int;
2374	peer_pk: ref X509->PublicKey;
2375	(e, id, peer_pk) = srv_cert.subject_pkinfo.getPublicKey();
2376	if(e != "") {
2377		if(SSL_DEBUG)
2378			log("ss3: server certificate: " + e);
2379		fatal(SSL_HANDSHAKE_FAILURE, "server certificate:" + e, ctx);
2380		return;
2381	}
2382
2383	pick key := peer_pk {
2384	RSA =>
2385		# TODO: to allow checking X509v3 KeyUsage extension
2386		if((0 && key.pk.modulus.bits() > 512 && ctx.sel_ciph.is_exportable)
2387			|| id == PKCS->id_pkcs_md2WithRSAEncryption
2388			|| id == PKCS->id_pkcs_md4WithRSAEncryption
2389			|| id == PKCS->id_pkcs_md5WithRSAEncryption) {
2390			pick sign := ctx.sel_sign {
2391			anon =>
2392				break;
2393			RSA =>
2394				break;
2395			* =>
2396				# error
2397			}
2398			if(ctx.local_info.sk == nil)
2399				ctx.sel_sign = ref SigAlg.RSA(nil, key.pk);
2400			else {
2401				pick mysk := ctx.local_info.sk {
2402				RSA =>
2403					ctx.sel_sign = ref SigAlg.RSA(mysk.sk, key.pk);
2404				* =>
2405					ctx.sel_sign = ref SigAlg.RSA(nil, key.pk);
2406				}
2407			}
2408			# key exchange may be tmp RSA, emhemeral DH depending on cipher suite
2409			ctx.state = STATE_SERVER_KEY_EXCHANGE;
2410		}
2411		# TODO: allow id == PKCS->id_rsa
2412		else if(id == PKCS->id_pkcs_rsaEncryption) {
2413			pick sign := ctx.sel_sign {
2414			anon =>
2415				break;
2416			* =>
2417				# error
2418			}
2419			ctx.sel_sign = ref SigAlg.anon();
2420			pick keyx := ctx.sel_keyx {
2421			RSA =>
2422				keyx.peer_pk = key.pk;
2423			* =>
2424				# error
2425			}
2426			ctx.state = STATE_SERVER_HELLO_DONE;
2427		}
2428		else {
2429			# error
2430		}
2431	DSS =>
2432		pick sign := ctx.sel_sign {
2433		DSS =>
2434			sign.peer_pk = key.pk;
2435			break;
2436		* =>
2437			# error
2438		}
2439		# should be key exchagne such as emhemeral DH
2440		ctx.state = STATE_SERVER_KEY_EXCHANGE;
2441	DH =>
2442		# fixed DH signed in certificate either by RSA or DSS???
2443		pick keyx := ctx.sel_keyx {
2444		DH =>
2445			keyx.peer_pk = key.pk;
2446		* =>
2447			# error
2448		}
2449		ctx.state = STATE_SERVER_KEY_EXCHANGE;
2450	}
2451
2452	if(e != nil) {
2453		fatal(SSL_HANDSHAKE_FAILURE, "do_server_cert: " + e, ctx);
2454		return;
2455	}
2456}
2457
2458# [client side]
2459# Processes certificate request message. A non-anonymous server can optionally
2460# request a certificate from the client, if appropriate for the selected cipher
2461# suite It is a fatal handshake failure alert for an anonymous server to
2462# request client identification.
2463
2464# TODO: use another module to do x509 certs, lookup and matching rules
2465
2466do_cert_request(hm: ref Handshake.CertificateRequest, ctx: ref Context)
2467{
2468	found := 0;
2469	for(i := 0; i < len hm.cert_types; i++) {
2470		if(ctx.local_info.root_type == int hm.cert_types[i]) {
2471			found = 1;
2472			break;
2473		}
2474	}
2475	if(!found) {
2476		fatal(SSL_HANDSHAKE_FAILURE, "do_cert_request: no required type of cert", ctx);
2477		return;
2478	}
2479	if(dn_cmp(ctx.local_info.dns, hm.dn_list) < 0) {
2480		fatal(SSL_HANDSHAKE_FAILURE, "do_cert_request: no required dn", ctx);
2481		return;
2482	}
2483	if(ctx.session.peer_certs == nil) {
2484		fatal(SSL_NO_CERTIFICATE, "certificate request: no peer certificates", ctx);
2485		return;
2486	}
2487
2488	ctx.status |= CLIENT_AUTH;
2489}
2490
2491dn_cmp(a, b: list of array of byte): int
2492{
2493	return -1;
2494}
2495
2496# [server side]
2497# Process client hello message.
2498
2499do_client_hello(hm: ref Handshake.ClientHello, ctx: ref Context)
2500{
2501	sndm : ref Handshake;
2502	e : string;
2503
2504	if(hm.version[0] != SSL_VERSION_3_0[0] || hm.version[1] != SSL_VERSION_3_0[1]) {
2505		fatal(SSL_UNEXPECTED_MESSAGE, "client hello: version mismatch", ctx);
2506		return;
2507	}
2508	# else SSL_VERSION_2_0
2509
2510	if(hm.session_id != nil) { # trying to resume
2511		if(ctx.status & SESSION_RESUMABLE) {
2512			s := sslsession->get_session_byid(hm.session_id);
2513			if(s == nil) {
2514				fatal(SSL_UNEXPECTED_MESSAGE, "client hello: retrieve nil session", ctx);
2515				return;
2516			}
2517
2518			if(s.version[0] != hm.version[0] || s.version[1] != hm.version[1]) {
2519				# avoid version attack
2520				fatal(SSL_UNEXPECTED_MESSAGE, "client hello: protocol mismatch", ctx);
2521				return;
2522			}
2523
2524			reset_server_random(ctx);
2525			ctx.client_random = hm.random;
2526
2527			sndm = ref Handshake.ServerHello(s.version, ctx.server_random,
2528				s.session_id, s.suite, s.compression);
2529			handshake_enque(sndm, ctx);
2530
2531			ccs_enque(ref ChangeCipherSpec(1), ctx);
2532			# use existing master_secret, calc keys
2533			(ctx.cw_mac, ctx.sw_mac, ctx.cw_key, ctx.sw_key, ctx.cw_IV, ctx.sw_IV)
2534				= calc_keys(ctx.sel_ciph, ctx.session.master_secret, ctx.client_random,
2535				ctx.server_random);
2536			e = set_out_queue(ctx);
2537			if(e != nil) {
2538				fatal(SSL_CLOSE_NOTIFY,	"client hello: setup new cipher failure", ctx);
2539				return;
2540			}
2541			if(SSL_DEBUG)
2542				log("do_client_hello: set out cipher done\n");
2543
2544			(md5_hash, sha_hash) := calc_finished(SSL_SERVER_SENDER,
2545				s.master_secret, ctx.sha_state, ctx.md5_state);
2546
2547			handshake_enque(ref Handshake.Finished(md5_hash, sha_hash), ctx);
2548
2549			ctx.session = s;
2550			ctx.state = STATE_CHANGE_CIPHER_SPEC;
2551			return;
2552		}
2553
2554		fatal(SSL_CLOSE_NOTIFY,	"client hello: resume session failed", ctx);
2555		return;
2556	}
2557
2558	ctx.session.version = hm.version;
2559	if(ctx.session.peer != nil) {
2560		ctx.session.session_id = random->randombuf(Random->NotQuiteRandom, 32);
2561		if(ctx.session.session_id == nil) {
2562			fatal(SSL_CLOSE_NOTIFY,	"client hello: generate session id failed", ctx);
2563			return;
2564		}
2565	}
2566
2567	suite := find_cipher_suite(hm.suites, ctx.local_info.suites);
2568	if(suite != nil) {
2569		fatal(SSL_HANDSHAKE_FAILURE, "client hello: find cipher suite failed", ctx);
2570		return;
2571	}
2572
2573	(ctx.sel_ciph, ctx.sel_keyx, ctx.sel_sign, e) = suite_to_spec(suite, SSL3_Suites);
2574	if(e != nil) {
2575		fatal(SSL_HANDSHAKE_FAILURE, "client hello: find cipher suite failed" + e, ctx);
2576		return;
2577	}
2578
2579	# not supported by ssl3 yet
2580	ctx.sel_cmpr = int hm.compressions[0];
2581	ctx.client_random = hm.random;
2582	ctx.sha_state = nil;
2583	ctx.md5_state = nil;
2584
2585	sndm = ref Handshake.ServerHello(ctx.session.version, ctx.server_random,
2586		ctx.session.session_id, ctx.session.suite, ctx.session.compression);
2587	handshake_enque(sndm, ctx);
2588
2589	# set up keys based on algorithms
2590
2591	if(tagof ctx.sel_keyx != tagof KeyExAlg.DH) {
2592		if(ctx.local_info.certs == nil || ctx.local_info.sk == nil) {
2593			fatal(SSL_HANDSHAKE_FAILURE, "client hello: no local cert or key", ctx);
2594			return;
2595		}
2596
2597		sndm = ref Handshake.Certificate(ctx.local_info.certs);
2598		handshake_enque(sndm, ctx);
2599	}
2600
2601	if(tagof ctx.sel_keyx != tagof KeyExAlg.RSA ||
2602		tagof ctx.sel_sign != tagof SigAlg.anon) {
2603		params, signed_params, xkey: array of byte;
2604		(params, e) = calc_server_xkey(ctx.sel_keyx);
2605		if(e == "")
2606			(signed_params, e) = sign_server_xkey(ctx.sel_sign, params,
2607				ctx.client_random, ctx.server_random);
2608		if(e != "")
2609
2610		n := len params + 2 + len signed_params;
2611		xkey = array [n] of byte;
2612		xkey[0:] = params;
2613		xkey[len params:] = int_encode(len signed_params, 2);
2614		xkey[len params+2:] = signed_params;
2615		handshake_enque(ref Handshake.ServerKeyExchange(xkey), ctx);
2616	}
2617
2618	if(ctx.status & CLIENT_AUTH) {
2619		sndm = ref Handshake.CertificateRequest(ctx.local_info.types, ctx.local_info.dns);
2620		handshake_enque(sndm, ctx);
2621
2622		ctx.status |= CERT_REQUEST;
2623		ctx.state = STATE_CLIENT_CERTIFICATE;
2624	}
2625	else
2626		ctx.state = STATE_CLIENT_KEY_EXCHANGE;
2627
2628	handshake_enque(ref Handshake.ServerHelloDone(), ctx);
2629}
2630
2631# [server side]
2632# Process the received client key exchange message.
2633
2634do_client_keyex(hm: ref Handshake.ClientKeyExchange, ctx: ref Context)
2635{
2636	(premaster_secret, err) := install_client_xkey(hm.xkey, ctx.sel_keyx);
2637	if(err != "") {
2638		fatal(SSL_HANDSHAKE_FAILURE, err, ctx);
2639		return;
2640	}
2641
2642	ctx.session.master_secret = calc_master_secret(premaster_secret,
2643		ctx.client_random, ctx.server_random);
2644
2645	if(ctx.status & CERT_RECEIVED)
2646		ctx.state = STATE_CERTIFICATE_VERIFY;
2647	else
2648		ctx.state = STATE_CHANGE_CIPHER_SPEC;
2649}
2650
2651# [server side]
2652# Process the received certificate message from client.
2653
2654do_client_cert(hm: ref Handshake.Certificate, ctx: ref Context)
2655{
2656	ctx.session.peer_certs = hm.cert_list;
2657
2658	# verify cert chain and determine the type of cert
2659	# ctx.peer_info.sk = x509->verify_chain(ctx.session.peer_certs);
2660	# if(ctx.peer_info.key == nil) {
2661	#	fatal(SSL_HANDSHAKE_FAILURE, "client certificate: cert verify failed", ctx);
2662	#	return;
2663	# }
2664
2665	ctx.status |= CERT_RECEIVED;
2666
2667	ctx.state = STATE_CLIENT_KEY_EXCHANGE;
2668}
2669
2670# [server side]
2671# Process the received certificate verify message from client.
2672
2673do_cert_verify(hm: ref Handshake.CertificateVerify, ctx: ref Context)
2674{
2675	if(ctx.status & CERT_RECEIVED) {
2676		# exp : array of byte;
2677		(md5_hash, sha_hash)
2678			:= calc_finished(nil, ctx.session.master_secret, ctx.sha_state, ctx.md5_state);
2679		ok := 0;
2680		pick upk := ctx.sel_sign {
2681		RSA =>
2682			hashes := array [36] of byte;
2683			hashes[0:] = md5_hash;
2684			hashes[16:] = sha_hash;
2685			ok = pkcs->rsa_verify(hashes, hm.signature, upk.peer_pk, PKCS->MD5_WithRSAEncryption);
2686		DSS =>
2687			ok = pkcs->dss_verify(sha_hash, hm.signature, upk.peer_pk);
2688		}
2689
2690		if(!ok) {
2691			fatal(SSL_HANDSHAKE_FAILURE, "do_cert_verify: client auth failed", ctx);
2692			return;
2693		}
2694	}
2695	else {
2696		alert_enque(ref Alert(SSL_WARNING, SSL_NO_CERTIFICATE), ctx);
2697		return;
2698	}
2699
2700	ctx.state = STATE_CHANGE_CIPHER_SPEC;
2701}
2702
2703# [client or server side]
2704# Process the received finished message either from client or server.
2705
2706do_finished(sender: array of byte, ctx: ref Context)
2707{
2708	# setup write_cipher if not yet
2709	if(!(ctx.status & OUT_READY)) {
2710		ccs_enque(ref ChangeCipherSpec(1), ctx);
2711		e := set_out_queue(ctx);
2712		if(e != nil) {
2713			fatal(SSL_CLOSE_NOTIFY, "do_finished: setup new cipher failed", ctx);
2714			return;
2715		}
2716		ctx.status |= OUT_READY;
2717
2718		if(SSL_DEBUG)
2719			log("ssl3: set out cipher done\n");
2720
2721		(md5_hash, sha_hash) := calc_finished(sender, ctx.session.master_secret,
2722			ctx.sha_state, ctx.md5_state);
2723		handshake_enque(ref Handshake.Finished(md5_hash, sha_hash), ctx);
2724	}
2725
2726	ctx.state = STATE_EXIT; # normal
2727
2728	# clean read queue
2729	ctx.in_queue.fragment = 0;
2730
2731	sslsession->add_session(ctx.session);
2732
2733	if(SSL_DEBUG)
2734		log("ssl3: add session to session database done\n");
2735}
2736
2737install_client_xkey(a: array of byte, keyx: ref KeyExAlg): (array of byte, string)
2738{
2739	pmaster, x : array of byte;
2740	err := "";
2741	pick kx := keyx {
2742	DH =>
2743		i := 0;
2744		(kx.peer_pk, i) = dh_params_decode(a);
2745		if(kx.peer_pk != nil)
2746			pmaster = pkcs->computeDHAgreedKey(kx.sk.param, kx.sk.sk, kx.peer_pk.pk);
2747		else
2748			err = "decode dh params failed";
2749	RSA =>
2750		(err, x) = pkcs->rsa_decrypt(a, kx.sk, 2);
2751		if(err != "" || len x != 48) {
2752			err = "impl error";
2753		}
2754		else {
2755			if(x[0] != SSL_VERSION_3_0[0] && x[1] != SSL_VERSION_3_0[1])
2756				err = "version wrong: possible version attack";
2757			else
2758				pmaster = x[2:];
2759		}
2760	FORTEZZA_KEA =>
2761		err = "Fortezza unsupported";
2762	}
2763	return (pmaster, err);
2764}
2765
2766install_server_xkey(a: array of byte, keyx: ref KeyExAlg): (string, int)
2767{
2768	err := "";
2769	i := 0;
2770
2771	pick kx := keyx {
2772	DH =>
2773		(kx.peer_pk, i) = dh_params_decode(a);
2774		if(kx.peer_pk != nil)
2775			kx.peer_params = kx.peer_pk.param;
2776	RSA =>
2777		peer_tmp: ref RSAParams;
2778		(peer_tmp, i, err) = rsa_params_decode(a);
2779		if(err == "") {
2780			modlen := len peer_tmp.modulus.iptobebytes();
2781			kx.peer_pk = ref RSAKey(peer_tmp.modulus, modlen, peer_tmp.exponent);
2782		}
2783	FORTEZZA_KEA =>
2784		return ("Fortezza unsupported", i);
2785	}
2786
2787	return (err, i);
2788}
2789
2790verify_server_xkey(crand, srand: array of byte, a: array of byte, i : int, sign: ref SigAlg)
2791	: string
2792{
2793	pick sg := sign {
2794	anon =>
2795	RSA =>
2796		lb := a[0:i]::crand::srand::nil;
2797		(exp, nil, nil) := md5_sha_hash(lb, nil, nil);
2798		ok := pkcs->rsa_verify(exp, a[i+2:], sg.peer_pk, PKCS->MD5_WithRSAEncryption);
2799		if(!ok)
2800			return "RSA sigature verification failed";
2801	DSS =>
2802		lb := a[0:i]::crand::srand::nil;
2803		(exp, nil) := sha_hash(lb, nil);
2804		ok := pkcs->dss_verify(exp, a[i+2:], sg.peer_pk);
2805		if(!ok)
2806			return "DSS sigature verification failed";
2807	}
2808
2809	return "";
2810}
2811
2812calc_client_xkey(keyx: ref KeyExAlg): (array of byte, array of byte, string)
2813{
2814	pm, x : array of byte;
2815	err := "";
2816	pick kx := keyx {
2817	DH =>
2818		# generate our own DH keys based on DH params of peer side
2819		(kx.sk, kx.exch_pk) = pkcs->setupDHAgreement(kx.peer_params);
2820		# TODO: need check type of client cert if(!ctx.status & CLIENT_AUTH)
2821		# 	for implicit case
2822		(x, err) = dh_exchpub_encode(kx.exch_pk);
2823		pm = pkcs->computeDHAgreedKey(kx.sk.param, kx.sk.sk, kx.peer_pk.pk);
2824	RSA =>
2825		pm = array [48] of byte;
2826		pm[0:] = SSL_VERSION_3_0; # against version attack
2827		pm[2:] = random->randombuf(Random->NotQuiteRandom, 46);
2828		(err, x) = pkcs->rsa_encrypt(pm, kx.peer_pk, 2);
2829	FORTEZZA_KEA =>
2830		err = "Fortezza unsupported";
2831	}
2832	if(SSL_DEBUG)
2833		log("ssl3: calc_client_xkey: " + bastr(x));
2834	return (x, pm, err);
2835}
2836
2837calc_server_xkey(keyx: ref KeyExAlg): (array of byte, string)
2838{
2839	params: array of byte;
2840	err: string;
2841	pick kx := keyx {
2842	DH =>
2843		(kx.sk, kx.exch_pk) = pkcs->setupDHAgreement(kx.params);
2844		(params, err) = dh_params_encode(kx.exch_pk);
2845	RSA =>
2846		tmp := ref RSAParams(kx.export_key.modulus, kx.export_key.exponent);
2847		(params, err) = rsa_params_encode(tmp);
2848
2849	FORTEZZA_KEA =>
2850		err = "Fortezza unsupported";
2851	}
2852	return (params, err);
2853}
2854
2855sign_server_xkey(sign: ref SigAlg, params, cr, sr: array of byte): (array of byte, string)
2856{
2857	signed_params: array of byte;
2858	err: string;
2859	pick sg := sign {
2860	anon =>
2861	RSA =>
2862		lb := cr::sr::params::nil;
2863		(hashes, nil, nil) := md5_sha_hash(lb, nil, nil);
2864		(err, signed_params) = pkcs->rsa_sign(hashes, sg.sk, PKCS->MD5_WithRSAEncryption);
2865	DSS =>
2866		lb := cr::sr::params::nil;
2867		(hashes, nil) := sha_hash(lb, nil);
2868		(err, signed_params) = pkcs->dss_sign(hashes, sg.sk);
2869	}
2870	return (signed_params, err);
2871}
2872
2873# ssl encoding of DH exchange public key
2874
2875dh_exchpub_encode(dh: ref DHPublicKey): (array of byte, string)
2876{
2877	if(dh != nil) {
2878		yb := dh.pk.iptobebytes();
2879		if(yb != nil) {
2880			n := 2 + len yb;
2881			a := array [n] of byte;
2882			i := 0;
2883			a[i:] = int_encode(len yb, 2);
2884			i += 2;
2885			a[i:] = yb;
2886			return (a, nil);
2887		}
2888	}
2889	return (nil, "nil dh params");
2890}
2891
2892dh_params_encode(dh: ref DHPublicKey): (array of byte, string)
2893{
2894	if(dh != nil && dh.param != nil) {
2895		pb := dh.param.prime.iptobebytes();
2896		gb := dh.param.base.iptobebytes();
2897		yb := dh.pk.iptobebytes();
2898		if(pb != nil && gb != nil && yb != nil) {
2899			n := 6 + len pb + len gb + len yb;
2900			a := array [n] of byte;
2901			i := 0;
2902			a[i:] = int_encode(len pb, 2);
2903			i += 2;
2904			a[i:] = pb;
2905			i += len pb;
2906			a[i:] = int_encode(len gb, 2);
2907			i += 2;
2908			a[i:] = gb;
2909			i += len gb;
2910			a[i:] = int_encode(len yb, 2);
2911			i += 2;
2912			a[i:] = yb;
2913			i += len yb;
2914			return (a, nil);
2915		}
2916	}
2917	return (nil, "nil dh public key");
2918}
2919
2920dh_params_decode(a: array of byte): (ref DHPublicKey, int)
2921{
2922	i := 0;
2923	for(;;) {
2924		n := int_decode(a[i:i+2]);
2925		i += 2;
2926		if(i+n > len a)
2927			break;
2928		p := a[i:i+n];
2929		i += n;
2930		n = int_decode(a[i:i+2]);
2931		i += 2;
2932		if(i+n > len a)
2933			break;
2934		g := a[i:i+n];
2935		i += n;
2936		n = int_decode(a[i:i+2]);
2937		i += 2;
2938		if(i+n > len a)
2939			break;
2940		Ys := a[i:i+n];
2941		i += n;
2942
2943		if(SSL_DEBUG)
2944			log("ssl3: dh_params_decode:" + "\n\tp =\n\t\t" + bastr(p)
2945			+ "\n\tg =\n\t\t" + bastr(g) + "\n\tYs =\n\t\t" + bastr(Ys) + "\n");
2946
2947		# don't care privateValueLength
2948		param := ref DHParams(IPint.bebytestoip(p), IPint.bebytestoip(g), 0);
2949		return (ref DHPublicKey(param, IPint.bebytestoip(Ys)), i);
2950	}
2951	return (nil, i);
2952}
2953
2954rsa_params_encode(rsa_params: ref RSAParams): (array of byte, string)
2955{
2956	if(rsa_params != nil) {
2957		mod := rsa_params.modulus.iptobebytes();
2958		exp := rsa_params.exponent.iptobebytes();
2959		if(mod != nil || exp != nil) {
2960			n := 4 + len mod + len exp;
2961			a := array [n] of byte;
2962			i := 0;
2963			a[i:] = int_encode(len mod, 2);
2964			i += 2;
2965			a[i:] = mod;
2966			i += len mod;
2967			a[i:] = int_encode(len exp, 2);
2968			i += 2;
2969			a[i:] = exp;
2970			i += len exp;
2971			return (a, nil);
2972		}
2973	}
2974	return (nil, "nil rsa params");
2975}
2976
2977rsa_params_decode(a: array of byte): (ref RSAParams, int, string)
2978{
2979	i := 0;
2980	for(;;) {
2981		if(len a < 2)
2982			break;
2983		n := int_decode(a[i:i+2]);
2984		i += 2;
2985		if(n < 0 || n + i > len a)
2986			break;
2987		mod := a[i:i+n];
2988		i += n;
2989		n = int_decode(a[i:i+2]);
2990		i += 2;
2991		if(n < 0 || n + i > len a)
2992			break;
2993		exp := a[i:i+n];
2994		i += n;
2995		m := i;
2996		modulus := IPint.bebytestoip(mod);
2997		exponent := IPint.bebytestoip(exp);
2998
2999		if(SSL_DEBUG)
3000			log("ssl3: decode RSA params\n\tmodulus = \n\t\t" + bastr(mod)
3001			+ "\n\texponent = \n\t\t" + bastr(exp) + "\n");
3002
3003		if(len a < i+2)
3004			break;
3005		n = int_decode(a[i:i+2]);
3006		i += 2;
3007		if(len a != i + n)
3008			break;
3009		return (ref RSAParams(modulus, exponent), m, nil);
3010	}
3011	return (nil, i, "encoding error");
3012}
3013
3014# md5_hash       MD5(master_secret + pad2 +
3015#                     MD5(handshake_messages + Sender +
3016#                          master_secret + pad1));
3017# sha_hash       SHA(master_secret + pad2 +
3018#                     SHA(handshake_messages + Sender +
3019#                          master_secret + pad1));
3020#
3021# handshake_messages  All of the data from all handshake messages
3022#                     up to but not including this message.  This
3023#                     is only data visible at the handshake layer
3024#                     and does not include record layer headers.
3025#
3026# sender [4], master_secret [48]
3027# pad1 and pad2, 48 bytes for md5, 40 bytes for sha
3028
3029calc_finished(sender, master_secret: array of byte, sha_state, md5_state: ref DigestState)
3030	: (array of byte, array of byte)
3031{
3032	sha_value := array [Keyring->SHA1dlen] of byte;
3033	md5_value := array [Keyring->MD5dlen] of byte;
3034	sha_inner := array [Keyring->SHA1dlen] of byte;
3035	md5_inner := array [Keyring->MD5dlen] of byte;
3036
3037	lb := master_secret::SSL_MAC_PAD1[0:48]::nil;
3038	if(sender != nil)
3039		lb = sender::lb;
3040	(md5_inner, nil) = md5_hash(lb, md5_state);
3041
3042	lb = master_secret::SSL_MAC_PAD1[0:40]::nil;
3043	if(sender != nil)
3044		lb = sender::lb;
3045	(sha_inner, nil) = sha_hash(lb, sha_state);
3046
3047	(md5_value, nil) = md5_hash(master_secret::SSL_MAC_PAD2[0:48]::md5_inner::nil, nil);
3048	(sha_value, nil) = sha_hash(master_secret::SSL_MAC_PAD2[0:40]::sha_inner::nil, nil);
3049
3050	# if(SSL_DEBUG)
3051	#	log("ssl3: calc_finished:"
3052	#	+ "\n\tmd5_inner = \n\t\t" + bastr(md5_inner)
3053	#	+ "\n\tsha_inner = \n\t\t" + bastr(sha_inner)
3054	#	+ "\n\tmd5_value = \n\t\t" + bastr(md5_value)
3055	#	+ "\n\tsha_value = \n\t\t" + bastr(sha_value)
3056	#	+ "\n");
3057
3058	return (md5_value, sha_value);
3059}
3060
3061
3062# master_secret =
3063#	MD5(premaster_secret + SHA('A' + premaster_secret +
3064#		ClientHello.random + ServerHello.random)) +
3065#	MD5(premaster_secret + SHA('BB' + premaster_secret +
3066#		ClientHello.random + ServerHello.random)) +
3067#	MD5(premaster_secret + SHA('CCC' + premaster_secret +
3068#		ClientHello.random + ServerHello.random));
3069
3070calc_master_secret(pm, cr, sr: array of byte): array of byte
3071{
3072	ms := array [48] of byte;
3073	sha_value := array [Keyring->SHA1dlen] of byte;
3074	leader := array [3] of byte;
3075
3076	j := 0;
3077	lb := pm::cr::sr::nil;
3078	for(i := 1; i <= 3; i++) {
3079		leader[0] = leader[1] = leader[2] = byte (16r40 + i);
3080		(sha_value, nil) = sha_hash(leader[0:i]::lb, nil);
3081		(ms[j:], nil) = md5_hash(pm::sha_value::nil, nil);
3082		j += 16; # Keyring->MD5dlen
3083	}
3084
3085	if(SSL_DEBUG)
3086		log("ssl3: calc_master_secret:\n\tmaster_secret = \n\t\t" + bastr(ms) + "\n");
3087
3088	return ms;
3089}
3090
3091
3092# key_block =
3093# 	MD5(master_secret + SHA(`A' + master_secret +
3094#				ServerHello.random + ClientHello.random)) +
3095#       MD5(master_secret + SHA(`BB' + master_secret +
3096#				ServerHello.random + ClientHello.random)) +
3097#       MD5(master_secret + SHA(`CCC' + master_secret +
3098#				ServerHello.random + ClientHello.random)) +
3099#	[...];
3100
3101calc_key_material(n: int, ms, cr, sr: array of byte): array of byte
3102{
3103	key_block := array [n] of byte;
3104	sha_value := array [Keyring->SHA1dlen] of byte; # [20]
3105	md5_value := array [Keyring->MD5dlen] of byte; # [16]
3106	leader := array [10] of byte;
3107
3108	if(n > 16*(len leader)) {
3109		if(SSL_DEBUG)
3110			log(sys->sprint("ssl3: calc key block: key size too long [%d]", n));
3111		return nil;
3112	}
3113
3114	m := n;
3115	i, j, consumed, next : int = 0;
3116	lb := ms::sr::cr::nil;
3117	for(i = 0; m > 0; i++) {
3118		for(j = 0; j <= i; j++)
3119			leader[j] = byte (16r41 + i); # 'A', 'BB', 'CCC', etc.
3120
3121		(sha_value, nil) = sha_hash(leader[0:i+1]::lb, nil);
3122		(md5_value, nil) = md5_hash(ms::sha_value::nil, nil);
3123
3124		consumed = Keyring->MD5dlen;
3125		if(m < Keyring->MD5dlen)
3126			consumed = m;
3127		m -= consumed;
3128
3129		key_block[next:] = md5_value[0:consumed];
3130		next += consumed;
3131	}
3132
3133	if(SSL_DEBUG)
3134		log("ssl3: calc_key_material:" + "\n\tkey_block = \n\t\t" + bastr(key_block) + "\n");
3135
3136	return key_block;
3137}
3138
3139# Then the key_block is partitioned as follows.
3140#
3141#	client_write_MAC_secret[CipherSpec.hash_size]
3142#	server_write_MAC_secret[CipherSpec.hash_size]
3143#	client_write_key[CipherSpec.key_material]
3144#	server_write_key[CipherSpec.key_material]
3145#	client_write_IV[CipherSpec.IV_size] /* non-export ciphers */
3146#	server_write_IV[CipherSpec.IV_size] /* non-export ciphers */
3147#
3148# Any extra key_block material is discarded.
3149#
3150# Exportable encryption algorithms (for which
3151# CipherSpec.is_exportable is true) require additional processing as
3152# follows to derive their final write keys:
3153#
3154#	final_client_write_key = MD5(client_write_key +
3155#					ClientHello.random +
3156#					ServerHello.random);
3157#	final_server_write_key = MD5(server_write_key +
3158#					ServerHello.random +
3159#					ClientHello.random);
3160#
3161# Exportable encryption algorithms derive their IVs from the random
3162# messages:
3163#
3164#	client_write_IV = MD5(ClientHello.random + ServerHello.random);
3165#	server_write_IV = MD5(ServerHello.random + ClientHello.random);
3166
3167calc_keys(ciph: ref CipherSpec, ms, cr, sr: array of byte)
3168	: (array of byte, array of byte, array of byte, array of byte, array of byte, array of byte)
3169{
3170	cw_mac, sw_mac, cw_key, sw_key,	cw_IV, sw_IV: array of byte;
3171
3172	n := ciph.key_material + ciph.hash_size;
3173	if(ciph.is_exportable == SSL_EXPORT_FALSE)
3174		n += ciph.IV_size;
3175	n *= 2;
3176
3177	key_block := calc_key_material(n, ms, cr, sr);
3178
3179	i := 0;
3180	if(ciph.hash_size != 0) {
3181		cw_mac = key_block[i:i+ciph.hash_size];
3182		i += ciph.hash_size;
3183		sw_mac = key_block[i:i+ciph.hash_size];
3184		i += ciph.hash_size;
3185	}
3186
3187	if(ciph.is_exportable == SSL_EXPORT_FALSE) {
3188		if(ciph.key_material != 0) {
3189			cw_key = key_block[i:i+ciph.key_material];
3190			i += ciph.key_material;
3191			sw_key = key_block[i:i+ciph.key_material];
3192			i += ciph.key_material;
3193		}
3194		if(ciph.IV_size != 0) {
3195			cw_IV = key_block[i:i+ciph.IV_size];
3196			i += ciph.IV_size;
3197			sw_IV = key_block[i:i+ciph.IV_size];
3198			i += ciph.IV_size;
3199		}
3200	}
3201	else {
3202		if(ciph.key_material != 0) {
3203			cw_key = key_block[i:i+ciph.key_material];
3204			i += ciph.key_material;
3205			sw_key = key_block[i:i+ciph.key_material];
3206			i += ciph.key_material;
3207			(cw_key, nil) = md5_hash(cw_key::cr::sr::nil, nil);
3208			(sw_key, nil) = md5_hash(sw_key::sr::cr::nil, nil);
3209		}
3210		if(ciph.IV_size != 0) {
3211			(cw_IV, nil) = md5_hash(cr::sr::nil, nil);
3212			(sw_IV, nil) = md5_hash(sr::cr::nil, nil);
3213		}
3214	}
3215
3216	if(SSL_DEBUG)
3217		log("ssl3: calc_keys:"
3218		+ "\n\tclient_write_mac = \n\t\t" + bastr(cw_mac)
3219		+ "\n\tserver_write_mac = \n\t\t" + bastr(sw_mac)
3220		+ "\n\tclient_write_key = \n\t\t" + bastr(cw_key)
3221		+ "\n\tserver_write_key = \n\t\t" + bastr(sw_key)
3222 		+ "\n\tclient_write_IV  = \n\t\t" + bastr(cw_IV)
3223		+ "\n\tserver_write_IV = \n\t\t" + bastr(sw_IV) + "\n");
3224
3225	return (cw_mac, sw_mac, cw_key, sw_key, cw_IV, sw_IV);
3226}
3227
3228#
3229# decode protocol message
3230#
3231Protocol.decode(r: ref Record, ctx: ref Context): (ref Protocol, string)
3232{
3233	p : ref Protocol;
3234
3235	case r.content_type {
3236	SSL_ALERT =>
3237		if(len r.data != 2)
3238			return (nil, "alert decode failed");
3239
3240		p = ref Protocol.pAlert(ref Alert(int r.data[0], int r.data[1]));
3241
3242	SSL_CHANGE_CIPHER_SPEC =>
3243		if(len r.data != 1 || r.data[0] != byte 1)
3244			return (nil, "ChangeCipherSpec decode failed");
3245
3246		p = ref Protocol.pChangeCipherSpec(ref ChangeCipherSpec(1));
3247
3248	SSL_HANDSHAKE =>
3249		(hm, e) := Handshake.decode(r.data);
3250		if(e != nil)
3251			return (nil, e);
3252
3253		pick h := hm {
3254		Finished =>
3255			exp_sender := SSL_CLIENT_SENDER;
3256			if(ctx.status & CLIENT_SIDE)
3257				exp_sender = SSL_SERVER_SENDER;
3258
3259			(md5_hash, sha_hash) := calc_finished(exp_sender,
3260				ctx.session.master_secret, ctx.sha_state, ctx.md5_state);
3261
3262			if(SSL_DEBUG)
3263				log("ssl3: handshake_decode: finished"
3264				+ "\n\texpected_md5_hash = \n\t\t" + bastr(md5_hash)
3265				+ "\n\tgot_md5_hash = \n\t\t" + bastr(h.md5_hash)
3266				+ "\n\texpected_sha_hash = \n\t\t" + bastr(sha_hash)
3267				+ "\n\tgot_sha_hash = \n\t\t" + bastr(h.sha_hash) + "\n");
3268
3269			#if(string md5_hash != string h.md5_hash || string sha_hash != string h.sha_hash)
3270			if(bytes_cmp(md5_hash, h.md5_hash) < 0 || bytes_cmp(sha_hash, h.sha_hash) < 0)
3271				return (nil, "finished: sender mismatch");
3272
3273			e = update_handshake_hash(ctx, r);
3274			if(e != nil)
3275				return (nil, e);
3276
3277		CertificateVerify =>
3278
3279			e = update_handshake_hash(ctx, r);
3280			if(e != nil)
3281				return (nil, e);
3282
3283		* =>
3284			e = update_handshake_hash(ctx, r);
3285			if(e != nil)
3286				return (nil, e);
3287		}
3288
3289		p = ref Protocol.pHandshake(hm);
3290
3291	SSL_V2HANDSHAKE =>
3292
3293		(hm, e) := V2Handshake.decode(r.data);
3294		if(e != "")
3295			return (nil, e);
3296
3297		p = ref Protocol.pV2Handshake(hm);
3298
3299	* =>
3300		return (nil, "protocol read: unknown protocol");
3301	}
3302
3303	return (p, nil);
3304
3305}
3306
3307
3308# encode protocol message and return tuple of data record and error message,
3309# may be v2 or v3 record depending on vers.
3310
3311Protocol.encode(protocol: self ref Protocol, vers: array of byte): (ref Record, string)
3312{
3313	r: ref Record;
3314	e: string;
3315
3316	pick p := protocol {
3317	pAlert =>
3318		r = ref Record(
3319				SSL_ALERT,
3320				vers,
3321				array [] of {byte p.alert.level, byte p.alert.description}
3322			);
3323
3324	pChangeCipherSpec =>
3325		r = ref Record(
3326				SSL_CHANGE_CIPHER_SPEC,
3327				vers,
3328				array [] of {byte p.change_cipher_spec.value}
3329			);
3330
3331	pHandshake =>
3332		data: array of byte;
3333		(data, e) = p.handshake.encode();
3334		if(e != "")
3335			break;
3336		r = ref Record(
3337				SSL_HANDSHAKE,
3338				vers,
3339				data
3340			);
3341
3342	pV2Handshake =>
3343		data: array of byte;
3344		(data, e) = p.handshake.encode();
3345		if(e != "")
3346			break;
3347		r = ref Record(
3348				SSL_V2HANDSHAKE,
3349				vers,
3350				data
3351			);
3352
3353	* =>
3354		e = "unknown protocol";
3355	}
3356
3357	if(SSL_DEBUG)
3358		log("ssl3: protocol encode\n" + protocol.tostring());
3359
3360	return (r, e);
3361}
3362
3363#
3364# protocol message description
3365#
3366Protocol.tostring(protocol: self ref Protocol): string
3367{
3368	info : string;
3369
3370	pick p := protocol {
3371	pAlert =>
3372		info = "\tAlert\n" + p.alert.tostring();
3373
3374	pChangeCipherSpec =>
3375		info = "\tChangeCipherSpec\n";
3376
3377	pHandshake =>
3378		info = "\tHandshake\n" + p.handshake.tostring();
3379
3380	pV2Handshake =>
3381		info = "\tV2Handshake\n" + p.handshake.tostring();
3382
3383	pApplicationData =>
3384		info = "\tApplicationData\n";
3385
3386	* =>
3387		info = "\tUnknownProtocolType\n";
3388	}
3389
3390	return "ssl3: Protocol:\n" + info;
3391}
3392
3393Handshake.decode(buf: array of byte): (ref Handshake, string)
3394{
3395	m : ref Handshake;
3396	e : string;
3397
3398	a := buf[4:]; # ignore msg length
3399
3400	i := 0;
3401	case int buf[0] {
3402	SSL_HANDSHAKE_HELLO_REQUEST =>
3403		m = ref Handshake.HelloRequest();
3404
3405        SSL_HANDSHAKE_CLIENT_HELLO =>
3406    		if(len a < 38) {
3407			e = "client hello: unexpected message";
3408			break;
3409		}
3410    		cv := a[i:i+2];
3411		i += 2;
3412		rd := a[i:i+32];
3413		i += 32;
3414		lsi := int a[i++];
3415    		if(len a < 38 + lsi) {
3416			e = "client hello: unexpected message";
3417			break;
3418		}
3419		sid: array of byte;
3420		if(lsi != 0) {
3421			sid = a[i:i+lsi];
3422			i += lsi;
3423		}
3424		else
3425			sid = nil;
3426		lcs := int_decode(a[i:i+2]);
3427		i += 2;
3428		if((lcs & 1) || lcs < 2 || len a < 40 + lsi + lcs) {
3429			e = "client hello: unexpected message";
3430			break;
3431		}
3432		cs := array [lcs/2] of byte;
3433		cs = a[i:i+lcs];
3434		i += lcs;
3435		lcm := int a[i++];
3436		cr := a[i:i+lcm];
3437		i += lcm;
3438		# In the interest of forward compatibility, it is
3439		# permitted for a client hello message to include
3440		# extra data after the compression methods. This
3441		# data must be included in the handshake hashes,
3442		# but otherwise be ignored.
3443		# if(i != len a) {
3444		#	e = "client hello: unexpected message";
3445		#	break;
3446		# }
3447		m = ref Handshake.ClientHello(cv, rd, sid, cs, cr);
3448
3449        SSL_HANDSHAKE_SERVER_HELLO =>
3450		if(len a < 38) {
3451			e = "server hello: unexpected message";
3452			break;
3453		}
3454		sv := a[i:i+2];
3455		i += 2;
3456		rd := a[i:i+32];
3457		i += 32;
3458		lsi := int a[i++];
3459		if(len a < 38 + lsi) {
3460			e = "server hello: unexpected message";
3461			break;
3462		}
3463		sid : array of byte;
3464		if(lsi != 0) {
3465			sid = a[i:i+lsi];
3466			i += lsi;
3467		}
3468		else
3469			sid = nil;
3470		cs := a[i:i+2];
3471		i += 2;
3472		cr := a[i++];
3473		if(i != len a) {
3474			e = "server hello: unexpected message";
3475			break;
3476		}
3477		m = ref Handshake.ServerHello(sv, rd, sid, cs, cr);
3478
3479        SSL_HANDSHAKE_CERTIFICATE =>
3480		n := int_decode(a[i:i+3]);
3481		i += 3;
3482		if(len a != n + 3) {
3483			e = "certificate: unexpected message";
3484			break;
3485		}
3486		cl : list of array of byte;
3487		k : int;
3488		while(i < n) {
3489			k = int_decode(a[i:i+3]);
3490			i += 3;
3491			if(k < 0 || i + k > len a) {
3492				e = "certificate: unexpected message";
3493				break;
3494			}
3495			cl = a[i:i+k] :: cl;
3496			i += k;
3497		}
3498		if(e != nil)
3499			break;
3500		m = ref Handshake.Certificate(cl);
3501
3502        SSL_HANDSHAKE_SERVER_KEY_EXCHANGE =>
3503
3504		m = ref Handshake.ServerKeyExchange(a[i:]);
3505
3506        SSL_HANDSHAKE_CERTIFICATE_REQUEST =>
3507		ln := int_decode(a[i:i+2]);
3508		i += 2;
3509		types := a[i:i+ln];
3510		i += ln;
3511		ln = int_decode(a[i:i+2]);
3512		i += 2;
3513		auths : list of array of byte;
3514		for(j := 0; j < ln; j++) {
3515			ln = int_decode(a[i:i+2]);
3516			i += 2;
3517			auths = a[i:i+ln]::auths;
3518			i += ln;
3519		}
3520		m = ref Handshake.CertificateRequest(types, auths);
3521
3522        SSL_HANDSHAKE_SERVER_HELLO_DONE =>
3523		if(len a != 0) {
3524			e = "server hello done: unexpected message";
3525			break;
3526		}
3527		m = ref Handshake.ServerHelloDone();
3528
3529        SSL_HANDSHAKE_CERTIFICATE_VERIFY =>
3530		ln := int_decode(a[i:i+2]);
3531		i +=2;
3532		sig := a[i:];
3533		i += ln;
3534		if(i != len a) {
3535			e = "certificate verify: unexpected message";
3536			break;
3537		}
3538		m = ref Handshake.CertificateVerify(sig);
3539
3540        SSL_HANDSHAKE_CLIENT_KEY_EXCHANGE =>
3541		m = ref Handshake.ClientKeyExchange(a);
3542
3543        SSL_HANDSHAKE_FINISHED =>
3544		if(len a != Keyring->MD5dlen + Keyring->SHA1dlen) { # 16+20
3545			e = "finished: unexpected message";
3546			break;
3547		}
3548		md5_hash := a[i:i+Keyring->MD5dlen];
3549		i += Keyring->MD5dlen;
3550		sha_hash := a[i:i+Keyring->SHA1dlen];
3551		i += Keyring->SHA1dlen;
3552		if(i != len a) {
3553			e = "finished: unexpected message";
3554			break;
3555		}
3556		m = ref Handshake.Finished(md5_hash, sha_hash);
3557
3558	* =>
3559		e = "unknown message";
3560	}
3561
3562	if(e != nil)
3563		return (nil, "Handshake decode: " + e);
3564
3565	return (m, nil);
3566}
3567
3568Handshake.encode(hm: self ref Handshake): (array of byte, string)
3569{
3570	a : array of byte;
3571	n : int;
3572	e : string;
3573
3574	i := 0;
3575	pick m := hm {
3576	HelloRequest =>
3577		a = array [4] of byte;
3578		a[i++] = byte SSL_HANDSHAKE_HELLO_REQUEST;
3579		a[i:] = int_encode(n, 3);
3580		i += 3;
3581		if(i != 4)
3582			e = "hello request: wrong message length";
3583
3584        ClientHello =>
3585		lsi := len m.session_id;
3586		lcs := len m.suites;
3587		if((lcs &1) || lcs < 2) {
3588			e = "client hello: cipher suites is not multiple of 2 bytes";
3589			break;
3590		}
3591		lcm := len m.compressions;
3592		n = 38 + lsi + lcs + lcm; # 2+32+1+2+1
3593		a = array[n+4] of byte;
3594		a[i++] = byte SSL_HANDSHAKE_CLIENT_HELLO;
3595		a[i:] = int_encode(n, 3);
3596		i += 3;
3597		a[i:] = m.version;
3598		i += 2;
3599		a[i:] = m.random;
3600		i += 32;
3601		a[i++] = byte lsi;
3602		if(lsi != 0) {
3603			a[i:] = m.session_id;
3604			i += lsi;
3605		}
3606		a[i:] = int_encode(lcs, 2);
3607		i += 2;
3608		a[i:] = m.suites; # not nil
3609		i += lcs;
3610		a[i++] = byte lcm;
3611		a[i:] = m.compressions;	# not nil
3612		i += lcm;
3613		if(i != n+4)
3614			e = "client hello: wrong message length";
3615
3616        ServerHello =>
3617		lsi := len m.session_id;
3618		n = 38 + lsi; # 2+32+1+2+1
3619		a = array [n+4] of byte;
3620		a[i++] = byte SSL_HANDSHAKE_SERVER_HELLO;
3621		a[i:] = int_encode(n, 3);
3622		i += 3;
3623		a[i:] = m.version;
3624		i += 2;
3625		a[i:] = m.random;
3626		i += 32;
3627		a[i++] = byte lsi;
3628		if(lsi != 0) {
3629			a[i:] = m.session_id;
3630			i += lsi;
3631		}
3632		a[i:] = m.suite; # should be verified, not nil
3633		i += 2;
3634		a[i++] = m.compression; # should be verified, not nil
3635		if(i != n+4)
3636			e = "server hello: wrong message length";
3637
3638        Certificate =>
3639		cl := m.cert_list;
3640		while(cl != nil) {
3641			n += 3 + len hd cl;
3642			cl = tl cl;
3643		}
3644		a = array [n+7] of byte;
3645		a[i++] = byte SSL_HANDSHAKE_CERTIFICATE;
3646		a[i:] = int_encode(n+3, 3); # length of record
3647		i += 3;
3648		a[i:] = int_encode(n, 3); # total length of cert chain
3649		i += 3;
3650		cl = m.cert_list;
3651		while(cl != nil) {
3652			a[i:] = int_encode(len hd cl, 3);
3653			i += 3;
3654			a[i:] = hd cl;
3655			i += len hd cl;
3656			cl = tl cl;
3657		}
3658		if(i != n+7)
3659			e = "certificate: wrong message length";
3660
3661        ServerKeyExchange =>
3662		n = len m.xkey;
3663		a = array [n+4] of byte;
3664		a[i++] = byte SSL_HANDSHAKE_SERVER_KEY_EXCHANGE;
3665		a[i:] = int_encode(n, 3);
3666		i += 3;
3667		a[i:] = m.xkey;
3668		i += len m.xkey;
3669		if(i != n+4)
3670			e = "server key exchange: wrong message length";
3671
3672        CertificateRequest =>
3673		ntypes := len m.cert_types;
3674		nauths := len m.dn_list;
3675		n = 1 + ntypes;
3676		dl := m.dn_list;
3677		while(dl != nil) {
3678			n += 2 + len hd dl;
3679			dl = tl dl;
3680		}
3681		n += 2;
3682		a = array [n+4] of byte;
3683		a[i++] =  byte SSL_HANDSHAKE_CERTIFICATE_REQUEST;
3684		a[i:] = int_encode(n, 3);
3685		i += 3;
3686		a[i++] = byte ntypes;
3687		a[i:] = m.cert_types;
3688		i += ntypes;
3689		a[i:] = int_encode(nauths, 2);
3690		i += 2;
3691		dl = m.dn_list;
3692		while(dl != nil) {
3693			a[i:] = int_encode(len hd dl, 2);
3694			i += 2;
3695			a[i:] = hd dl;
3696			i += len hd dl;
3697			dl = tl dl;
3698		}
3699		if(i != n+4)
3700			e = "certificate request: wrong message length";
3701
3702        ServerHelloDone =>
3703		n = 0;
3704		a = array[n+4] of byte;
3705		a[i++] = byte SSL_HANDSHAKE_SERVER_HELLO_DONE;
3706		a[i:] = int_encode(0, 3); # message has 0 length
3707		i += 3;
3708		if(i != n+4)
3709			e = "server hello done: wrong message length";
3710
3711        CertificateVerify =>
3712		n = 2 + len m.signature;
3713		a = array [n+4] of byte;
3714		a[i++] = byte SSL_HANDSHAKE_CERTIFICATE_VERIFY;
3715		a[i:] = int_encode(n, 3);
3716		i += 3;
3717		a[i:] = int_encode(n-2, 2);
3718		i += 2;
3719		a[i:] = m.signature;
3720		i += n-2;
3721		if(i != n+4)
3722			e = "certificate verify: wrong message length";
3723
3724        ClientKeyExchange =>
3725		n = len m.xkey;
3726		a = array [n+4] of byte;
3727		a[i++] = byte SSL_HANDSHAKE_CLIENT_KEY_EXCHANGE;
3728		a[i:] = int_encode(n, 3);
3729		i += 3;
3730		a[i:] = m.xkey;
3731		i += n;
3732		if(i != n+4)
3733			e = "client key exchange: wrong message length";
3734
3735        Finished =>
3736		n = len m.md5_hash + len m.sha_hash;
3737		a = array [n+4] of byte;
3738		a[i++] = byte SSL_HANDSHAKE_FINISHED;
3739		a[i:] = int_encode(n, 3);
3740		i += 3;
3741		a[i:] = m.md5_hash;
3742		i += len m.md5_hash;
3743		a[i:] = m.sha_hash;
3744		i += len m.sha_hash;
3745		if(i != n+4)
3746			e = "finished: wrong message length";
3747
3748	* =>
3749		e = "unknown message";
3750	}
3751
3752	if(e != nil)
3753		return (nil, "Handshake encode: " + e);
3754
3755	return (a, e);
3756}
3757
3758Handshake.tostring(handshake: self ref Handshake): string
3759{
3760	info: string;
3761
3762	pick m := handshake {
3763        HelloRequest =>
3764		info = "\tHelloRequest\n";
3765
3766        ClientHello =>
3767		info = "\tClientHello\n" +
3768			"\tversion = \n\t\t" + bastr(m.version) + "\n" +
3769			"\trandom = \n\t\t" + bastr(m.random) + "\n" +
3770			"\tsession_id = \n\t\t" + bastr(m.session_id) + "\n" +
3771			"\tsuites = \n\t\t" + bastr(m.suites) + "\n" +
3772			"\tcomperssion_methods = \n\t\t" + bastr(m.compressions) +"\n";
3773
3774        ServerHello =>
3775		info = "\tServerHello\n" +
3776			"\tversion = \n\t\t" + bastr(m.version) + "\n" +
3777			"\trandom = \n\t\t" + bastr(m.random) + "\n" +
3778			"\tsession_id = \n\t\t" + bastr(m.session_id) + "\n" +
3779			"\tsuite = \n\t\t" + bastr(m.suite) + "\n" +
3780			"\tcomperssion_method = \n\t\t" + string m.compression +"\n";
3781
3782        Certificate =>
3783		info = "\tCertificate\n" +
3784			"\tcert_list = \n\t\t" + lbastr(m.cert_list) + "\n";
3785
3786        ServerKeyExchange =>
3787		info = "\tServerKeyExchange\n" +
3788			"\txkey = \n\t\t" + bastr(m.xkey) +"\n";
3789
3790        CertificateRequest =>
3791		info = "\tCertificateRequest\n" +
3792			"\tcert_types = \n\t\t" + bastr(m.cert_types) + "\n" +
3793			"\tdn_list = \n\t\t" + lbastr(m.dn_list) + "\n";
3794
3795        ServerHelloDone =>
3796		info = "\tServerDone\n";
3797
3798        CertificateVerify =>
3799		info = "\tCertificateVerify\n" +
3800			"\tsignature = \n\t\t" + bastr(m.signature) + "\n";
3801
3802        ClientKeyExchange =>
3803		info = "\tClientKeyExchange\n" +
3804			"\txkey = \n\t\t" + bastr(m.xkey) +"\n";
3805
3806        Finished =>
3807		info = "\tFinished\n" +
3808			"\tmd5_hash = \n\t\t" + bastr(m.md5_hash) + "\n" +
3809			"\tsha_hash = \n\t\t" + bastr(m.sha_hash) + "\n";
3810	}
3811
3812	return info;
3813}
3814
3815Alert.tostring(alert: self ref Alert): string
3816{
3817	info: string;
3818
3819	case alert.level {
3820	SSL_WARNING =>
3821		info += "\t\twarning: ";
3822
3823	SSL_FATAL =>
3824		info += "\t\tfatal: ";
3825
3826	*  =>
3827		info += sys->sprint("unknown alert level[%d]: ", alert.level);
3828	}
3829
3830	case alert.description {
3831	SSL_CLOSE_NOTIFY =>
3832		info += "close notify";
3833
3834	SSL_NO_CERTIFICATE =>
3835		info += "no certificate";
3836
3837	SSL_BAD_CERTIFICATE =>
3838		info += "bad certificate";
3839
3840	SSL_UNSUPPORTED_CERTIFICATE =>
3841		info += "unsupported certificate";
3842
3843	SSL_CERTIFICATE_REVOKED =>
3844		info += "certificate revoked";
3845
3846	SSL_CERTIFICATE_EXPIRED =>
3847		info += "certificate expired";
3848
3849	SSL_CERTIFICATE_UNKNOWN =>
3850		info += "certificate unknown";
3851
3852	SSL_UNEXPECTED_MESSAGE =>
3853		info += "unexpected message";
3854
3855	SSL_BAD_RECORD_MAC =>
3856		info += "bad record mac";
3857
3858	SSL_DECOMPRESSION_FAILURE =>
3859		info += "decompression failure";
3860
3861	SSL_HANDSHAKE_FAILURE =>
3862		info += "handshake failure";
3863
3864	SSL_ILLEGAL_PARAMETER =>
3865		info += "illegal parameter";
3866
3867	* =>
3868		info += sys->sprint("unknown alert description[%d]", alert.description);
3869	}
3870
3871	return info;
3872}
3873
3874find_cipher_suite(s, suites: array of byte) : array of byte
3875{
3876	i, j : int;
3877	a, b : array of byte;
3878
3879	n := len s;
3880	if((n & 1) || n < 2)
3881		return nil;
3882
3883	m := len suites;
3884	if((m & 1) || m < 2)
3885		return nil;
3886
3887	for(i = 0; i < n; ) {
3888		a = s[i:i+2];
3889		i += 2;
3890		for(j = 0; j < m; ) {
3891			b = suites[j:j+2];
3892			j += 2;
3893			if(a[0] == b[0] && a[1] == b[1])
3894				return b;
3895		}
3896	}
3897
3898	return nil;
3899}
3900
3901#
3902# cipher suites and specs
3903#
3904suite_to_spec(cs: array of byte, cipher_suites: array of array of byte)
3905	: (ref CipherSpec, ref KeyExAlg, ref SigAlg, string)
3906{
3907	cip : ref CipherSpec;
3908	kex : ref KeyExAlg;
3909	sig : ref SigAlg;
3910
3911	n := len cipher_suites;
3912	i : int;
3913	found := array [2] of byte;
3914	for(i = 0; i < n; i++) {
3915		found = cipher_suites[i];
3916		if(found[0]==cs[0] && found[1]==cs[1]) break;
3917	}
3918
3919	if(i == n)
3920		return (nil, nil, nil, "fail to find a matched spec");
3921
3922	case i {
3923	NULL_WITH_NULL_NULL =>
3924		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_NULL_CIPHER,
3925			SSL_STREAM_CIPHER, 0, 0, SSL_NULL_MAC, 0);
3926		kex = ref KeyExAlg.NULL();
3927		sig = ref SigAlg.anon();
3928
3929	RSA_WITH_NULL_MD5 => # sign only certificate
3930		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_NULL_CIPHER,
3931			SSL_STREAM_CIPHER, 0, 0, SSL_MD5, Keyring->MD5dlen);
3932		kex = ref KeyExAlg.RSA(nil, nil, nil);
3933		sig = ref SigAlg.anon();
3934
3935	RSA_WITH_NULL_SHA =>
3936		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_NULL_CIPHER,
3937			SSL_STREAM_CIPHER, 0, 0, SSL_SHA, Keyring->SHA1dlen);
3938		kex = ref KeyExAlg.RSA(nil, nil, nil);
3939		sig = ref SigAlg.anon();
3940
3941	RSA_EXPORT_WITH_RC4_40_MD5 =>
3942		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_RC4,
3943			SSL_STREAM_CIPHER, 5, 0, SSL_MD5, Keyring->MD5dlen);
3944		kex = ref KeyExAlg.RSA(nil, nil, nil);
3945		sig = ref SigAlg.anon();
3946
3947	RSA_WITH_RC4_128_MD5 =>
3948		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_RC4,
3949			SSL_STREAM_CIPHER, 16, 0, SSL_MD5, Keyring->MD5dlen);
3950		kex = ref KeyExAlg.RSA(nil, nil, nil);
3951		sig = ref SigAlg.anon();
3952
3953	RSA_WITH_RC4_128_SHA =>
3954		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_RC4,
3955			SSL_STREAM_CIPHER, 16, 0, SSL_SHA, Keyring->SHA1dlen);
3956		kex = ref KeyExAlg.RSA(nil, nil, nil);
3957		sig = ref SigAlg.anon();
3958
3959	RSA_EXPORT_WITH_RC2_CBC_40_MD5 =>
3960		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_RC2_CBC,
3961			SSL_BLOCK_CIPHER, 5, 8, SSL_MD5, Keyring->MD5dlen);
3962		kex = ref KeyExAlg.RSA(nil, nil, nil);
3963		sig = ref SigAlg.RSA(nil, nil);
3964
3965	RSA_WITH_IDEA_CBC_SHA =>
3966		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_IDEA_CBC,
3967			SSL_BLOCK_CIPHER, 16, 8, SSL_SHA, Keyring->SHA1dlen);
3968		kex = ref KeyExAlg.RSA(nil, nil, nil);
3969		sig = ref SigAlg.anon();
3970
3971	RSA_EXPORT_WITH_DES40_CBC_SHA =>
3972		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_DES_CBC,
3973			SSL_BLOCK_CIPHER, 5, 8, SSL_SHA, Keyring->SHA1dlen);
3974		kex = ref KeyExAlg.RSA(nil, nil, nil);
3975		sig = ref SigAlg.RSA(nil, nil);
3976
3977	RSA_WITH_DES_CBC_SHA =>
3978		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
3979			SSL_BLOCK_CIPHER, 8, 8, SSL_SHA, Keyring->SHA1dlen);
3980		kex = ref KeyExAlg.RSA(nil, nil, nil);
3981		sig = ref SigAlg.anon();
3982
3983	RSA_WITH_3DES_EDE_CBC_SHA =>
3984		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC,
3985			SSL_BLOCK_CIPHER, 24, 8, SSL_SHA, Keyring->SHA1dlen);
3986		kex = ref KeyExAlg.RSA(nil, nil, nil);
3987		sig = ref SigAlg.anon();
3988
3989	DH_DSS_EXPORT_WITH_DES40_CBC_SHA =>
3990		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_DES_CBC,
3991			SSL_BLOCK_CIPHER, 5, 8, SSL_SHA, Keyring->SHA1dlen);
3992		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
3993		sig = ref SigAlg.DSS(nil, nil);
3994
3995	DH_DSS_WITH_DES_CBC_SHA =>
3996		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
3997			SSL_BLOCK_CIPHER, 8, 8, SSL_SHA, Keyring->SHA1dlen);
3998		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
3999		sig = ref SigAlg.DSS(nil, nil);
4000
4001	DH_DSS_WITH_3DES_EDE_CBC_SHA =>
4002		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC,
4003			SSL_BLOCK_CIPHER, 24, 8, SSL_SHA, Keyring->SHA1dlen);
4004		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4005		sig = ref SigAlg.DSS(nil, nil);
4006
4007	DH_RSA_EXPORT_WITH_DES40_CBC_SHA =>
4008		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_DES_CBC,
4009			SSL_BLOCK_CIPHER, 5, 8, SSL_SHA, Keyring->SHA1dlen);
4010		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4011		sig = ref SigAlg.RSA(nil, nil);
4012
4013	DH_RSA_WITH_DES_CBC_SHA =>
4014		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
4015			SSL_STREAM_CIPHER, 8, 8, SSL_SHA, Keyring->SHA1dlen);
4016		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4017		sig = ref SigAlg.RSA(nil, nil);
4018
4019	DH_RSA_WITH_3DES_EDE_CBC_SHA =>
4020		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC,
4021			SSL_BLOCK_CIPHER, 24, 8, SSL_SHA, Keyring->SHA1dlen);
4022		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4023		sig = ref SigAlg.RSA(nil, nil);
4024
4025	DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =>
4026		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
4027			SSL_BLOCK_CIPHER, 5, 8, SSL_SHA, Keyring->SHA1dlen);
4028		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4029		sig = ref SigAlg.DSS(nil, nil);
4030
4031	DHE_DSS_WITH_DES_CBC_SHA =>
4032		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
4033			SSL_BLOCK_CIPHER, 8, 8, SSL_SHA, Keyring->SHA1dlen);
4034		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4035		sig = ref SigAlg.DSS(nil, nil);
4036
4037	DHE_DSS_WITH_3DES_EDE_CBC_SHA =>
4038		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC,
4039			SSL_BLOCK_CIPHER, 24, 8, SSL_SHA, Keyring->SHA1dlen);
4040		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4041		sig = ref SigAlg.DSS(nil, nil);
4042
4043	DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =>
4044		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_DES_CBC,
4045			SSL_BLOCK_CIPHER, 5, 8, SSL_SHA, Keyring->SHA1dlen);
4046		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4047		sig = ref SigAlg.RSA(nil, nil);
4048
4049	DHE_RSA_WITH_DES_CBC_SHA =>
4050		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
4051			SSL_BLOCK_CIPHER, 8, 8, SSL_SHA, Keyring->SHA1dlen);
4052		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4053		sig = ref SigAlg.RSA(nil, nil);
4054
4055	DHE_RSA_WITH_3DES_EDE_CBC_SHA =>
4056		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC,
4057			SSL_BLOCK_CIPHER, 24, 8, SSL_SHA, Keyring->SHA1dlen);
4058		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4059		sig = ref SigAlg.RSA(nil, nil);
4060
4061	DH_anon_EXPORT_WITH_RC4_40_MD5 =>
4062		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_RC4,
4063			SSL_STREAM_CIPHER, 5, 0, SSL_MD5, Keyring->MD5dlen);
4064		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4065		sig = ref SigAlg.anon();
4066
4067	DH_anon_WITH_RC4_128_MD5 =>
4068		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_RC4,
4069			SSL_STREAM_CIPHER, 16, 0, SSL_MD5, Keyring->MD5dlen);
4070		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4071		sig = ref SigAlg.anon();
4072
4073	DH_anon_EXPORT_WITH_DES40_CBC_SHA =>
4074		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_DES_CBC,
4075			SSL_BLOCK_CIPHER, 5, 8, SSL_SHA, Keyring->SHA1dlen);
4076		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4077		sig = ref SigAlg.anon();
4078
4079	DH_anon_WITH_DES_CBC_SHA =>
4080		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC,
4081			SSL_BLOCK_CIPHER, 8, 8, SSL_SHA, Keyring->SHA1dlen);
4082		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4083		sig = ref SigAlg.anon();
4084
4085	DH_anon_WITH_3DES_EDE_CBC_SHA =>
4086		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC,
4087			SSL_BLOCK_CIPHER, 24, 8, SSL_SHA, Keyring->SHA1dlen);
4088		kex = ref KeyExAlg.DH(nil, nil, nil, nil, nil);
4089		sig = ref SigAlg.anon();
4090
4091	FORTEZZA_KEA_WITH_NULL_SHA =>
4092		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_NULL_CIPHER,
4093			SSL_STREAM_CIPHER, 0, 0, SSL_SHA, Keyring->SHA1dlen);
4094		kex = ref KeyExAlg.FORTEZZA_KEA();
4095		sig = ref SigAlg.FORTEZZA_KEA();
4096
4097	FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA =>
4098		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_FORTEZZA_CBC,
4099			SSL_BLOCK_CIPHER, 0, 0, SSL_SHA, Keyring->SHA1dlen);
4100		kex = ref KeyExAlg.FORTEZZA_KEA();
4101		sig = ref SigAlg.FORTEZZA_KEA();
4102
4103	FORTEZZA_KEA_WITH_RC4_128_SHA =>
4104		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_RC4,
4105			SSL_STREAM_CIPHER, 16, 0, SSL_SHA, Keyring->SHA1dlen);
4106		kex = ref KeyExAlg.FORTEZZA_KEA();
4107		sig = ref SigAlg.FORTEZZA_KEA();
4108
4109	}
4110
4111	return (cip, kex, sig, nil);
4112}
4113
4114#
4115# use suites as default SSL3_Suites
4116#
4117cipher_suite_info(cs: array of byte, suites: array of array of byte) : string
4118{
4119	tag : string;
4120
4121	a := array [2] of byte;
4122	n := len suites;
4123	for(i := 0; i < n; i++) {
4124		a = suites[i];
4125		if(a[0]==cs[0] && a[1]==cs[1]) break;
4126	}
4127
4128	if(i == n)
4129		return "unknown cipher suite [" + string cs + "]";
4130
4131	case i {
4132	NULL_WITH_NULL_NULL =>
4133		tag = "NULL_WITH_NULL_NULL";
4134
4135	RSA_WITH_NULL_MD5 =>
4136		tag = "RSA_WITH_NULL_MD5";
4137
4138	RSA_WITH_NULL_SHA =>
4139		tag = "RSA_WITH_NULL_SHA";
4140
4141	RSA_EXPORT_WITH_RC4_40_MD5 =>
4142		tag = "RSA_EXPORT_WITH_RC4_40_MD5";
4143
4144	RSA_WITH_RC4_128_MD5 =>
4145		tag = "RSA_WITH_RC4_128_MD5";
4146
4147	RSA_WITH_RC4_128_SHA =>
4148		tag = "RSA_WITH_RC4_128_SHA";
4149
4150	RSA_EXPORT_WITH_RC2_CBC_40_MD5 =>
4151		tag = "RSA_EXPORT_WITH_RC2_CBC_40_MD5";
4152
4153	RSA_WITH_IDEA_CBC_SHA =>
4154		tag = "RSA_WITH_IDEA_CBC_SHA";
4155
4156	RSA_EXPORT_WITH_DES40_CBC_SHA =>
4157		tag ="RSA_EXPORT_WITH_DES40_CBC_SHA";
4158
4159	RSA_WITH_DES_CBC_SHA =>
4160		tag = "RSA_WITH_DES_CBC_SHA";
4161
4162	RSA_WITH_3DES_EDE_CBC_SHA =>
4163		tag = "RSA_WITH_3DES_EDE_CBC_SHA";
4164
4165	DH_DSS_EXPORT_WITH_DES40_CBC_SHA =>
4166		tag = "DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
4167
4168	DH_DSS_WITH_DES_CBC_SHA =>
4169		tag = "DH_DSS_WITH_DES_CBC_SHA";
4170
4171	DH_DSS_WITH_3DES_EDE_CBC_SHA =>
4172		tag = "DH_DSS_WITH_3DES_EDE_CBC_SHA";
4173
4174	DH_RSA_EXPORT_WITH_DES40_CBC_SHA =>
4175		tag = "DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
4176
4177	DH_RSA_WITH_DES_CBC_SHA =>
4178		tag = "DH_RSA_WITH_DES_CBC_SHA";
4179
4180	DH_RSA_WITH_3DES_EDE_CBC_SHA =>
4181		tag = "DH_RSA_WITH_3DES_EDE_CBC_SHA";
4182
4183	DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =>
4184		tag = "DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
4185
4186	DHE_DSS_WITH_DES_CBC_SHA =>
4187		tag = "DHE_DSS_WITH_DES_CBC_SHA";
4188
4189	DHE_DSS_WITH_3DES_EDE_CBC_SHA =>
4190		tag = "DHE_DSS_WITH_3DES_EDE_CBC_SHA";
4191
4192	DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =>
4193		tag = "DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
4194
4195	DHE_RSA_WITH_DES_CBC_SHA =>
4196		tag = "DHE_RSA_WITH_DES_CBC_SHA";
4197
4198	DHE_RSA_WITH_3DES_EDE_CBC_SHA =>
4199		tag = "DHE_RSA_WITH_3DES_EDE_CBC_SHA";
4200
4201	DH_anon_EXPORT_WITH_RC4_40_MD5 =>
4202		tag = "DH_anon_EXPORT_WITH_RC4_40_MD5";
4203
4204	DH_anon_WITH_RC4_128_MD5 =>
4205		tag = "DH_anon_WITH_RC4_128_MD5";
4206
4207	DH_anon_EXPORT_WITH_DES40_CBC_SHA =>
4208		tag = "DH_anon_EXPORT_WITH_DES40_CBC_SHA";
4209
4210	DH_anon_WITH_DES_CBC_SHA =>
4211		tag = "DH_anon_WITH_DES_CBC_SHA";
4212
4213	DH_anon_WITH_3DES_EDE_CBC_SHA =>
4214		tag = "DH_anon_WITH_3DES_EDE_CBC_SHA";
4215
4216	FORTEZZA_KEA_WITH_NULL_SHA =>
4217		tag = "FORTEZZA_KEA_WITH_NULL_SHA";
4218
4219	FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA =>
4220		tag = "FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA";
4221
4222	FORTEZZA_KEA_WITH_RC4_128_SHA =>
4223		tag = "FORTEZZA_KEA_WITH_RC4_128_SHA";
4224	}
4225
4226	return "cipher suite = [" + tag + "]";
4227}
4228
4229#################################
4230## FOR SSLv2 BACKWARD COMPATIBLE
4231#################################
4232
4233# Protocol Version Codes
4234SSL2_CLIENT_VERSION				:= array [] of {byte 0, byte 16r02};
4235SSL2_SERVER_VERSION				:= array [] of {byte 0, byte 16r02};
4236
4237# Protocol Message Codes
4238
4239SSL2_MT_ERROR,
4240	SSL2_MT_CLIENT_HELLO,
4241	SSL2_MT_CLIENT_MASTER_KEY,
4242	SSL2_MT_CLIENT_FINISHED,
4243	SSL2_MT_SERVER_HELLO,
4244	SSL2_MT_SERVER_VERIFY,
4245	SSL2_MT_SERVER_FINISHED,
4246	SSL2_MT_REQUEST_CERTIFICATE,
4247	SSL2_MT_CLIENT_CERTIFICATE		: con iota;
4248
4249# Error Message Codes
4250
4251SSL2_PE_NO_CIPHER				:= array [] of {byte 0, byte 16r01};
4252SSL2_PE_NO_CERTIFICATE				:= array [] of {byte 0, byte 16r02};
4253SSL2_PE_BAD_CERTIFICATE				:= array [] of {byte 0, byte 16r04};
4254SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE		:= array [] of {byte 0, byte 16r06};
4255
4256# Cipher Kind Values
4257
4258SSL2_CK_RC4_128_WITH_MD5,
4259	SSL2_CK_RC4_128_EXPORT40_WITH_MD5,
4260	SSL2_CK_RC2_CBC_128_CBC_WITH_MD5,
4261	SSL2_CK_RC2_CBC_128_CBC_EXPORT40_WITH_MD5,
4262	SSL2_CK_IDEA_128_CBC_WITH_MD5,
4263	SSL2_CK_DES_64_CBC_WITH_MD5,
4264	SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 	: con iota;
4265
4266SSL2_Cipher_Kinds := array [] of {
4267	SSL2_CK_RC4_128_WITH_MD5 => 		array [] of {byte 16r01, byte 0, byte 16r80},
4268	SSL2_CK_RC4_128_EXPORT40_WITH_MD5 => 	array [] of {byte 16r02, byte 0, byte 16r80},
4269	SSL2_CK_RC2_CBC_128_CBC_WITH_MD5 => 	array [] of {byte 16r03, byte 0, byte 16r80},
4270	SSL2_CK_RC2_CBC_128_CBC_EXPORT40_WITH_MD5 =>
4271						array [] of {byte 16r04, byte 0, byte 16r80},
4272	SSL2_CK_IDEA_128_CBC_WITH_MD5 => 	array [] of {byte 16r05, byte 0, byte 16r80},
4273	SSL2_CK_DES_64_CBC_WITH_MD5 => 		array [] of {byte 16r06, byte 0, byte 16r40},
4274	SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 => 	array [] of {byte 16r07, byte 0, byte 16rC0},
4275};
4276
4277# Certificate Type Codes
4278
4279SSL2_CT_X509_CERTIFICATE			: con 16r01; # encode as one byte
4280
4281# Authentication Type Codes
4282
4283SSL2_AT_MD5_WITH_RSA_ENCRYPTION			: con byte 16r01;
4284
4285# Upper/Lower Bounds
4286
4287SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS		: con 256;
4288SSL2_MAX_SESSION_ID_LENGTH_IN_BYTES		: con 16;
4289SSL2_MIN_RSA_MODULUS_LENGTH_IN_BYTES		: con 64;
4290SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER		: con 32767;
4291SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER		: con 16383;
4292
4293# Handshake Internal State
4294
4295SSL2_STATE_CLIENT_HELLO,
4296	SSL2_STATE_SERVER_HELLO,
4297	SSL2_STATE_CLIENT_MASTER_KEY,
4298	SSL2_STATE_SERVER_VERIFY,
4299	SSL2_STATE_REQUEST_CERTIFICATE,
4300	SSL2_STATE_CLIENT_CERTIFICATE,
4301	SSL2_STATE_CLIENT_FINISHED,
4302	SSL2_STATE_SERVER_FINISHED,
4303	SSL2_STATE_ERROR			: con iota;
4304
4305# The client's challenge to the server for the server to identify itself is a
4306# (near) arbitary length random. The v3 server will right justify the challenge
4307# data to become the ClientHello.random data (padding with leading zeros, if
4308# necessary). If the length of the challenge is greater than 32 bytes, then only
4309# the last 32 bytes are used. It is legitimate (but not necessary) for a v3
4310# server to reject a v2 ClientHello that has fewer than 16 bytes of challenge
4311# data.
4312
4313SSL2_CHALLENGE_LENGTH				: con 16;
4314
4315V2Handshake: adt {
4316	pick {
4317	Error =>
4318		code				: array of byte; # [2];
4319	ClientHello =>
4320		version				: array of byte; # [2]
4321		cipher_specs			: array of byte; # [3] x
4322		session_id			: array of byte;
4323		challenge			: array of byte;
4324	ServerHello =>
4325		session_id_hit			: int;
4326		certificate_type		: int;
4327		version				: array of byte; # [2]
4328		certificate			: array of byte; # only user certificate
4329		cipher_specs			: array of byte; # [3] x
4330		connection_id			: array of byte;
4331	ClientMasterKey =>
4332		cipher_kind			: array of byte; # [3]
4333		clear_key			: array of byte;
4334		encrypt_key			: array of byte;
4335		key_arg				: array of byte;
4336	ServerVerify =>
4337		challenge			: array of byte;
4338	RequestCertificate =>
4339		authentication_type		: int;
4340		certificate_challenge		: array of byte;
4341	ClientCertificate =>
4342		certificate_type		: int;
4343		certificate			: array of byte; # only user certificate
4344		response			: array of byte;
4345	ClientFinished =>
4346		connection_id			: array of byte;
4347	ServerFinished =>
4348		session_id			: array of byte;
4349	}
4350
4351	encode: fn(hm: self ref V2Handshake): (array of byte, string);
4352	decode: fn(a: array of byte): (ref V2Handshake, string);
4353	tostring: fn(h: self ref V2Handshake): string;
4354};
4355
4356
4357V2Handshake.tostring(handshake: self ref V2Handshake): string
4358{
4359	info := "";
4360
4361	pick m := handshake {
4362        ClientHello =>
4363		info += "\tClientHello\n" +
4364			"\tversion = \n\t\t" + bastr(m.version) + "\n" +
4365			"\tcipher_specs = \n\t\t" + bastr(m.cipher_specs) + "\n" +
4366			"\tsession_id = \n\t\t" + bastr(m.session_id) + "\n" +
4367			"\tchallenge = \n\t\t" + bastr(m.challenge) + "\n";
4368
4369        ServerHello =>
4370		info += "\tServerHello\n" +
4371			"\tsession_id_hit = \n\t\t" + string m.session_id_hit + "\n" +
4372			"\tcertificate_type = \n\t\t" + string m.certificate_type + "\n" +
4373			"\tversion = \n\t\t" + bastr(m.version) + "\n" +
4374			"\tcertificate = \n\t\t" + bastr(m.certificate) + "\n" +
4375			"\tcipher_specs = \n\t\t" + bastr(m.cipher_specs) + "\n" +
4376			"\tconnection_id = \n\t\t" + bastr(m.connection_id) + "\n";
4377
4378	ClientMasterKey =>
4379		info += "\tClientMasterKey\n" +
4380			"\tcipher_kind = \n\t\t" + bastr(m.cipher_kind) + "\n" +
4381			"\tclear_key = \n\t\t" + bastr(m.clear_key) + "\n" +
4382			"\tencrypt_key = \n\t\t" + bastr(m.encrypt_key) + "\n" +
4383			"\tkey_arg = \n\t\t" + bastr(m.key_arg) + "\n";
4384
4385	ServerVerify =>
4386		info += "\tServerVerify\n" +
4387			"\tchallenge = \n\t\t" + bastr(m.challenge) + "\n";
4388
4389	RequestCertificate =>
4390		info += "\tRequestCertificate\n" +
4391			"\tauthentication_type = \n\t\t" + string m.authentication_type + "\n" +
4392			"\tcertificate_challenge = \n\t\t" + bastr(m.certificate_challenge) + "\n";
4393
4394	ClientCertificate =>
4395		info += "ClientCertificate\n" +
4396			"\tcertificate_type = \n\t\t" + string m.certificate_type + "\n" +
4397			"\tcertificate = \n\t\t" + bastr(m.certificate) + "\n" +
4398			"\tresponse = \n\t\t" + bastr(m.response) + "\n";
4399
4400	ClientFinished =>
4401		info += "\tClientFinished\n" +
4402			"\tconnection_id = \n\t\t" + bastr(m.connection_id) + "\n";
4403
4404	ServerFinished =>
4405		info += "\tServerFinished\n" +
4406			"\tsession_id = \n\t\t" + bastr(m.session_id) + "\n";
4407	}
4408
4409	return info;
4410}
4411
4412
4413# v2 handshake protocol - message driven, v2 and v3 sharing the same context stack
4414
4415do_v2handshake(v2hs: ref V2Handshake, ctx: ref Context): string
4416{
4417	e: string = nil;
4418
4419	pick h := v2hs {
4420	Error =>
4421		do_v2error(h, ctx);
4422
4423	ClientHello =>
4424		if((ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_CLIENT_HELLO) {
4425			e = "V2ClientHello";
4426			break;
4427		}
4428		do_v2client_hello(h, ctx);
4429
4430	ServerHello =>
4431		if(!(ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_SERVER_HELLO) {
4432			e = "V2ServerHello";
4433			break;
4434		}
4435		do_v2server_hello(h, ctx);
4436
4437	ClientMasterKey =>
4438		if((ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_CLIENT_MASTER_KEY) {
4439			e = "V2ClientMasterKey";
4440			break;
4441		}
4442		do_v2client_master_key(h, ctx);
4443
4444	ServerVerify =>
4445		if(!(ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_SERVER_VERIFY) {
4446			e = "V2ServerVerify";
4447			break;
4448		}
4449		do_v2server_verify(h, ctx);
4450
4451	RequestCertificate =>
4452		if(!(ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_SERVER_VERIFY) {
4453			e = "V2RequestCertificate";
4454			break;
4455		}
4456		do_v2req_cert(h, ctx);
4457
4458	ClientCertificate =>
4459		if((ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_CLIENT_CERTIFICATE) {
4460			e = "V2ClientCertificate";
4461			break;
4462		}
4463		do_v2client_certificate(h, ctx);
4464
4465	ClientFinished =>
4466		if((ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_CLIENT_FINISHED) {
4467			e = "V2ClientFinished";
4468			break;
4469		}
4470		do_v2client_finished(h, ctx);
4471
4472	ServerFinished =>
4473		if(!(ctx.status & CLIENT_SIDE) || ctx.state != SSL2_STATE_SERVER_FINISHED) {
4474			e = "V2ServerFinished";
4475			break;
4476		}
4477		do_v2server_finished(h, ctx);
4478	}
4479
4480	return e;
4481}
4482
4483do_v2error(v2hs: ref V2Handshake.Error, ctx: ref Context)
4484{
4485	if(SSL_DEBUG)
4486		log("do_v2error: " + string v2hs.code);
4487	ctx.state = STATE_EXIT;
4488}
4489
4490# [server side]
4491do_v2client_hello(v2hs: ref V2Handshake.ClientHello, ctx: ref Context)
4492{
4493	if(v2hs.version[0] != SSL2_CLIENT_VERSION[0] || v2hs.version[1] != SSL2_CLIENT_VERSION[1]) {
4494		# promote this message to v3 handshake protocol
4495		ctx.state = STATE_CLIENT_HELLO;
4496		return;
4497	}
4498
4499	# trying to resume
4500	s: ref Session;
4501	if((v2hs.session_id != nil) && (ctx.status & SESSION_RESUMABLE))
4502		s = sslsession->get_session_byid(v2hs.session_id);
4503	if(s != nil) { # found a hit
4504		# prepare and send v2 handshake hello message
4505		v2handshake_enque(
4506			ref V2Handshake.ServerHello(
4507				1, # hit found
4508				0, # no certificate required
4509				SSL2_SERVER_VERSION,
4510				nil, # no authetication required
4511				s.suite, # use hit session cipher kind
4512				ctx.server_random # connection_id
4513			),
4514			ctx
4515		);
4516		# TODO: should in supported cipher_kinds
4517		err: string;
4518		(ctx.sel_ciph, ctx.sel_keyx, ctx.sel_sign, err)
4519			= v2suite_to_spec(ctx.session.suite, SSL2_Cipher_Kinds);
4520		if(err != "") {
4521			if(SSL_DEBUG)
4522				log("do_v2client_hello: " + err);
4523			ctx.state = SSL2_STATE_ERROR;
4524			return;
4525		}
4526		ctx.state = SSL2_STATE_SERVER_FINISHED;
4527	}
4528	else {
4529		# find matching cipher kinds
4530		n := len v2hs.cipher_specs;
4531		matchs := array [n] of byte;
4532		j, k: int = 0;
4533		while(j < n) {
4534			# ignore those not in SSL2_Cipher_Kinds
4535			matchs[k:] = v2hs.cipher_specs[j:j+3];
4536			for(i := 0; i < len SSL2_Cipher_Kinds; i++) {
4537				ck := SSL2_Cipher_Kinds[i];
4538				if(matchs[k] == ck[0] && matchs[k+1] == ck[1] && matchs[k+2] == ck[2])
4539					k +=3;
4540			}
4541			j += 3;
4542		}
4543		if(k == 0) {
4544			if(SSL_DEBUG)
4545				log("do_v2client_hello: No matching cipher kind");
4546			ctx.state = SSL2_STATE_ERROR;
4547		}
4548		else {
4549			matchs = matchs[0:k];
4550
4551			# Note:
4552			#	v2 challenge -> v3 client_random
4553			#	v2 connection_id -> v3 server_random
4554
4555			chlen := len v2hs.challenge;
4556			if(chlen > 32)
4557				chlen = 32;
4558			ctx.client_random = array [chlen] of byte;
4559			if(chlen > 32)
4560				ctx.client_random[0:] = v2hs.challenge[chlen-32:];
4561			else
4562				ctx.client_random[0:] = v2hs.challenge;
4563			ctx.server_random = random->randombuf(Random->NotQuiteRandom, 16);
4564			s.session_id = random->randombuf (
4565					Random->NotQuiteRandom,
4566					SSL2_MAX_SESSION_ID_LENGTH_IN_BYTES
4567				);
4568			s.suite = matchs;
4569			ctx.session = s;
4570			v2handshake_enque(
4571				ref V2Handshake.ServerHello(
4572					0, # no hit - not resumable
4573					SSL2_CT_X509_CERTIFICATE,
4574					SSL2_SERVER_VERSION,
4575					hd ctx.local_info.certs, # the first is user certificate
4576					ctx.session.suite, # matched cipher kinds
4577					ctx.server_random # connection_id
4578				),
4579				ctx
4580			);
4581			ctx.state = SSL2_STATE_CLIENT_MASTER_KEY;
4582		}
4583	}
4584}
4585
4586# [client side]
4587
4588do_v2server_hello(v2hs: ref V2Handshake.ServerHello, ctx: ref Context)
4589{
4590	# must be v2 server hello otherwise it will be v3 server hello
4591	# determined by auto record layer version detection
4592	if(v2hs.version[0] != SSL2_SERVER_VERSION[0]
4593		|| v2hs.version[1] != SSL2_SERVER_VERSION[1]) {
4594		if(SSL_DEBUG)
4595			log("do_v2server_hello: not a v2 version");
4596		ctx.state = SSL2_STATE_ERROR;
4597		return;
4598	}
4599
4600	ctx.session.version = SSL2_SERVER_VERSION;
4601	ctx.server_random = v2hs.connection_id;
4602
4603	# check if a resumable session is found
4604	if(v2hs.session_id_hit != 0) { # resume ok
4605		err: string;
4606		# TODO: should in supported cipher_kinds
4607		(ctx.sel_ciph, nil, nil, err) = v2suite_to_spec(ctx.session.suite, SSL2_Cipher_Kinds);
4608		if(err !=  "") {
4609			if(SSL_DEBUG)
4610				log("do_v2server_hello: " + err);
4611			ctx.state = SSL2_STATE_ERROR;
4612			return;
4613		}
4614	}
4615	else { 	# not resumable session
4616
4617		# use the first matched cipher kind; install cipher spec
4618		if(len v2hs.cipher_specs < 3) {
4619			if(SSL_DEBUG)
4620				log("do_v2server_hello: too few bytes");
4621			ctx.state = SSL2_STATE_ERROR;
4622			return;
4623		}
4624		ctx.session.suite = array [3] of byte;
4625		ctx.session.suite[0:] = v2hs.cipher_specs[0:3];
4626		err: string;
4627		(ctx.sel_ciph, nil, nil, err) = v2suite_to_spec(ctx.session.suite, SSL2_Cipher_Kinds);
4628		if(err != "") {
4629			if(SSL_DEBUG)
4630				log("do_v2server_hello: " + err);
4631			return;
4632		}
4633
4634		# decode x509 certificates, authenticate server and extract
4635		# public key from server certificate
4636		if(v2hs.certificate_type != int SSL2_CT_X509_CERTIFICATE) {
4637			if(SSL_DEBUG)
4638				log("do_v2server_hello: not x509 certificate");
4639			ctx.state = SSL2_STATE_ERROR;
4640			return;
4641		}
4642		ctx.session.peer_certs = v2hs.certificate :: nil;
4643		# TODO: decode v2hs.certificate as list of certificate
4644		# 	verify the list of certificate
4645		(e, signed) := x509->Signed.decode(v2hs.certificate);
4646		if(e != "") {
4647			if(SSL_DEBUG)
4648				log("do_v2server_hello: " + e);
4649			ctx.state = SSL2_STATE_ERROR;
4650			return;
4651		}
4652		certificate: ref Certificate;
4653		(e, certificate) = x509->Certificate.decode(signed.tobe_signed);
4654		if(e != "") {
4655			if(SSL_DEBUG)
4656				log("do_v2server_hello: " + e);
4657			ctx.state = SSL2_STATE_ERROR;
4658			return;
4659		}
4660		id: int;
4661		peer_pk: ref X509->PublicKey;
4662		(e, id, peer_pk) = certificate.subject_pkinfo.getPublicKey();
4663		if(e != nil) {
4664			ctx.state = SSL2_STATE_ERROR; # protocol error
4665			return;
4666		}
4667		pk: ref RSAKey;
4668		pick key := peer_pk {
4669		RSA =>
4670			pk = key.pk;
4671		* =>
4672		}
4673		# prepare and send client master key message
4674		# TODO: change CipherSpec adt for more key info
4675		# Temporary solution
4676		# mkey (master key), ckey (clear key), skey(secret key)
4677		mkey, ckey, skey, keyarg: array of byte;
4678		(mkeylen, ckeylen, keyarglen) := v2suite_more(ctx.sel_ciph);
4679		mkey = random->randombuf(Random->NotQuiteRandom, mkeylen);
4680		if(ckeylen != 0)
4681			ckey = mkey[0:ckeylen];
4682		if(mkeylen > ckeylen)
4683			skey = mkey[ckeylen:];
4684		if(keyarglen > 0)
4685			keyarg = random->randombuf(Random->NotQuiteRandom, keyarglen);
4686		ekey: array of byte;
4687		(e, ekey) = pkcs->rsa_encrypt(skey, pk, 2);
4688		if(e != nil) {
4689			if(SSL_DEBUG)
4690				log("do_v2server_hello: " + e);
4691			ctx.state = SSL2_STATE_ERROR;
4692			return;
4693		}
4694		ctx.session.master_secret = mkey;
4695		v2handshake_enque(
4696			ref V2Handshake.ClientMasterKey(ctx.session.suite, ckey, ekey, keyarg),
4697			ctx
4698		);
4699	}
4700
4701	# clean up out_queue before switch cipher
4702	record_write_queue(ctx);
4703	ctx.out_queue.data = nil;
4704
4705	# install keys onto ctx that will be pushed on ssl record when ready
4706	(ctx.cw_mac, ctx.sw_mac, ctx.cw_key, ctx.sw_key, ctx.cw_IV, ctx.sw_IV)
4707		= v2calc_keys(ctx.sel_ciph, ctx.session.master_secret,
4708		ctx.client_random, ctx.server_random);
4709	e := set_queues(ctx);
4710	if(e != "") {
4711		if(SSL_DEBUG)
4712			log("do_v2server_finished: " + e);
4713		ctx.state = SSL2_STATE_ERROR;
4714		return;
4715	}
4716	ctx.status |= IN_READY;
4717	ctx.status |= OUT_READY;
4718
4719	# prepare and send client finished message
4720	v2handshake_enque(
4721		ref V2Handshake.ClientFinished(ctx.server_random), # as connection_id
4722		ctx
4723	);
4724
4725	ctx.state = SSL2_STATE_SERVER_VERIFY;
4726}
4727
4728# [server side]
4729
4730do_v2client_master_key(v2hs: ref V2Handshake.ClientMasterKey, ctx: ref Context)
4731{
4732	#if(cmk.cipher == -1 || cipher_info[cmk.cipher].cryptalg == -1) {
4733	#	# return ("protocol error: bad cipher in masterkey", nullc);
4734	#	ctx.state = SSL2_STATE_ERROR; # protocol error
4735	#	return;
4736	#}
4737
4738	ctx.session.suite = v2hs.cipher_kind;
4739
4740	# TODO:
4741	#	someplace shall be able to install the key
4742	# need further encapsulate encrypt and decrypt functions from KeyExAlg adt
4743	master_key_length: int;
4744	secret_key: array of byte;
4745	pick alg := ctx.sel_keyx {
4746	RSA =>
4747		e: string;
4748		(e, secret_key) = pkcs->rsa_decrypt(v2hs.encrypt_key, alg.sk, 0);
4749		if(e != "") {
4750			if(SSL_DEBUG)
4751				log("do_v2client_master_key: " + e);
4752			ctx.state = SSL2_STATE_ERROR;
4753			return;
4754		}
4755		master_key_length = len v2hs.clear_key + len secret_key;
4756	* =>
4757		if(SSL_DEBUG)
4758			log("do_v2client_master_key: unknown public key algorithm");
4759		ctx.state = SSL2_STATE_ERROR;
4760		return;
4761	}
4762	#TODO: do the following lines after modifying the CipherSpec adt
4763	#if(master_key_length != ci.keylen) {
4764	#	ctx.state = SSL2_STATE_ERROR; # protocol error
4765	#	return;
4766	#}
4767
4768	ctx.session.master_secret = array [master_key_length] of byte;
4769	ctx.session.master_secret[0:] = v2hs.clear_key;
4770	ctx.session.master_secret[len v2hs.clear_key:] = secret_key;
4771
4772	# install keys onto ctx that will be pushed on ssl record when ready
4773	(ctx.cw_mac, ctx.sw_mac, ctx.cw_key, ctx.sw_key, ctx.cw_IV, ctx.sw_IV)
4774		= v2calc_keys(ctx.sel_ciph, ctx.session.master_secret,
4775		ctx.client_random, ctx.server_random);
4776	v2handshake_enque(
4777		ref V2Handshake.ServerVerify(ctx.client_random[16:]),
4778		ctx
4779	);
4780	v2handshake_enque(
4781		ref V2Handshake.ServerFinished(ctx.session.session_id),
4782		ctx
4783	);
4784	ctx.state = SSL2_STATE_CLIENT_FINISHED;
4785}
4786
4787# used by client side
4788do_v2server_verify(v2hs: ref V2Handshake.ServerVerify, ctx: ref Context)
4789{
4790	# TODO:
4791	#	the challenge length may not be 16 bytes
4792	if(bytes_cmp(v2hs.challenge, ctx.client_random[32-SSL2_CHALLENGE_LENGTH:]) < 0) {
4793		if(SSL_DEBUG)
4794			log("do_v2server_verify: challenge mismatch");
4795		ctx.state = SSL2_STATE_ERROR;
4796		return;
4797	}
4798
4799	ctx.state = SSL2_STATE_SERVER_FINISHED;
4800}
4801
4802# [client side]
4803
4804do_v2req_cert(v2hs: ref V2Handshake.RequestCertificate, ctx: ref Context)
4805{
4806	# not supported until v3
4807	if(SSL_DEBUG)
4808		log("do_v2req_cert: authenticate client not supported");
4809	v2hs = nil;
4810	ctx.state = SSL2_STATE_ERROR;
4811}
4812
4813# [server side]
4814
4815do_v2client_certificate(v2hs: ref V2Handshake.ClientCertificate, ctx: ref Context)
4816{
4817	# not supported until v3
4818	if(SSL_DEBUG)
4819		log("do_v2client_certificate: authenticate client not supported");
4820	v2handshake_enque (
4821		ref V2Handshake.Error(SSL2_PE_NO_CERTIFICATE),
4822		ctx
4823	);
4824	v2hs = nil;
4825	ctx.state = SSL2_STATE_ERROR;
4826}
4827
4828# [server side]
4829
4830do_v2client_finished(v2hs: ref V2Handshake.ClientFinished, ctx: ref Context)
4831{
4832	if(bytes_cmp(ctx.server_random, v2hs.connection_id) < 0) {
4833		ctx.session.session_id = nil;
4834		if(SSL_DEBUG)
4835			log("do_v2client_finished: connection id mismatch");
4836		ctx.state = SSL2_STATE_ERROR;
4837	}
4838	# TODO:
4839	#	the challenge length may not be 16 bytes
4840	v2handshake_enque(
4841		ref V2Handshake.ServerVerify(ctx.client_random[32-SSL2_CHALLENGE_LENGTH:]),
4842		ctx
4843	);
4844	if(ctx.session.session_id == nil)
4845		ctx.session.session_id = random->randombuf(Random->NotQuiteRandom, 16);
4846	v2handshake_enque(
4847		ref V2Handshake.ServerFinished(ctx.session.session_id),
4848		ctx
4849	);
4850	e := set_queues(ctx);
4851	if(e != "") {
4852		if(SSL_DEBUG)
4853			log("do_v2client_finished: " + e);
4854		ctx.state = SSL2_STATE_ERROR;
4855		return;
4856	}
4857	ctx.status |= IN_READY;
4858	ctx.status |= OUT_READY;
4859	sslsession->add_session(ctx.session);
4860
4861	ctx.state = STATE_EXIT;
4862}
4863
4864# [client side]
4865
4866do_v2server_finished(v2hs: ref V2Handshake.ServerFinished, ctx: ref Context)
4867{
4868	if(ctx.session.session_id == nil)
4869		ctx.session.session_id = array [16] of byte;
4870	ctx.session.session_id[0:] = v2hs.session_id[0:];
4871
4872	sslsession->add_session(ctx.session);
4873
4874	ctx.state = STATE_EXIT;
4875}
4876
4877
4878# Note:
4879#	the key partitioning for v2 is different from v3
4880
4881v2calc_keys(ciph: ref CipherSpec, ms, cr, sr: array of byte)
4882	: (array of byte, array of byte, array of byte, array of byte, array of byte, array of byte)
4883{
4884	cw_mac, sw_mac, cw_key, sw_key,	cw_IV, sw_IV: array of byte;
4885
4886	# TODO: check the size of key block if IV exists
4887	(mkeylen, ckeylen, keyarglen) := v2suite_more(ciph);
4888	kblen := 2*mkeylen;
4889	if(kblen%Keyring->MD5dlen != 0) {
4890		if(SSL_DEBUG)
4891			log("v2calc_keys: key block length is not multiple of MD5 hash length");
4892	}
4893	else {
4894		key_block := array [kblen] of byte;
4895
4896		challenge := cr[32-SSL2_CHALLENGE_LENGTH:32]; # TODO: if challenge length != 16 ?
4897		connection_id := sr[0:16]; # TODO: if connection_id length != 16 ?
4898		var := array [1] of byte;
4899		var[0] = byte 16r30;
4900		i := 0;
4901		while(i < kblen) {
4902			(hash, nil) := md5_hash(ms::var::challenge::connection_id::nil, nil);
4903			key_block[i:] = hash;
4904			i += Keyring->MD5dlen;
4905			++var[0];
4906		}
4907
4908		if(SSL_DEBUG)
4909			log("ssl3: calc_keys:"
4910			+ "\n\tmaster key = \n\t\t" + bastr(ms)
4911			+ "\n\tchallenge = \n\t\t" + bastr(challenge)
4912			+ "\n\tconnection id = \n\t\t" + bastr(connection_id)
4913			+ "\n\tkey block = \n\t\t" + bastr(key_block) + "\n");
4914
4915		i = 0;
4916		# server write key == client read key
4917		# server write mac == server write key
4918		sw_key = array [mkeylen] of byte;
4919		sw_key[0:] = key_block[i:mkeylen];
4920		sw_mac = array [mkeylen] of byte;
4921		sw_mac[0:] = key_block[i:mkeylen];
4922		# client write key == server read key
4923		# client write mac == client write key
4924		i += mkeylen;
4925		cw_key = array [mkeylen] of byte;
4926		cw_key[0:] = key_block[i:i+mkeylen];
4927		cw_mac = array [mkeylen] of byte;
4928		cw_mac[0:] = key_block[i:i+mkeylen];
4929		# client IV == server IV
4930		# Note:
4931		#	IV is a part of writing or reading key for ssl device
4932		#	this is composed again in setctl
4933		cw_IV = array [keyarglen] of byte;
4934		cw_IV[0:] = ms[mkeylen:mkeylen+keyarglen];
4935		sw_IV = array [keyarglen] of byte;
4936		sw_IV[0:] = ms[mkeylen:mkeylen+keyarglen];
4937	}
4938
4939	if(SSL_DEBUG)
4940		log("ssl3: calc_keys:"
4941		+ "\n\tclient_write_mac = \n\t\t" + bastr(cw_mac)
4942		+ "\n\tserver_write_mac = \n\t\t" + bastr(sw_mac)
4943		+ "\n\tclient_write_key = \n\t\t" + bastr(cw_key)
4944		+ "\n\tserver_write_key = \n\t\t" + bastr(sw_key)
4945 		+ "\n\tclient_write_IV  = \n\t\t" + bastr(cw_IV)
4946		+ "\n\tserver_write_IV = \n\t\t" + bastr(sw_IV) + "\n");
4947
4948	return (cw_mac, sw_mac, cw_key, sw_key, cw_IV, sw_IV);
4949}
4950
4951v3tov2specs(suites: array of byte): array of byte
4952{
4953	# v3 suite codes are 2 bytes each, v2 codes are 3 bytes
4954	n := len suites / 2;
4955	kinds := array [n*3*2] of byte;
4956	k := 0;
4957	for(i := 0; i < n;) {
4958		a := suites[i:i+2];
4959		i += 2;
4960		m := len SSL3_Suites;
4961		for(j := 0; j < m; j++) {
4962			b := SSL3_Suites[j];
4963			if(a[0]==b[0] && a[1]==b[1])
4964				break;
4965		}
4966		if (j == m) {
4967			if(SSL_DEBUG)
4968				log("ssl3: unknown v3 suite");
4969			continue;
4970		}
4971		case j {
4972		RSA_EXPORT_WITH_RC4_40_MD5 =>
4973			kinds[k:] = SSL2_Cipher_Kinds[SSL2_CK_RC4_128_EXPORT40_WITH_MD5];
4974			k += 3;
4975		RSA_WITH_RC4_128_MD5 =>
4976			kinds[k:] = SSL2_Cipher_Kinds[SSL2_CK_RC4_128_WITH_MD5];
4977			k += 3;
4978		RSA_WITH_IDEA_CBC_SHA =>
4979			kinds[k:] = SSL2_Cipher_Kinds[SSL2_CK_IDEA_128_CBC_WITH_MD5];
4980			k += 3;
4981		RSA_WITH_DES_CBC_SHA =>
4982			;
4983		* =>
4984			if(SSL_DEBUG)
4985				log("ssl3: unable to convert v3 suite to v2 kind");
4986		}
4987		# append v3 code in v2-safe manner
4988		# (suite[0] == 0) => will be ignored by v2 server, picked up by v3 server
4989		kinds[k] = byte 16r00;
4990		kinds[k+1:] = SSL3_Suites[j];
4991		k += 3;
4992	}
4993	return kinds[0:k];
4994}
4995
4996v2suite_to_spec(cs: array of byte, cipher_kinds: array of array of byte)
4997	: (ref CipherSpec, ref KeyExAlg, ref SigAlg, string)
4998{
4999	cip : ref CipherSpec;
5000	kex : ref KeyExAlg;
5001	sig : ref SigAlg;
5002
5003	n := len cipher_kinds;
5004	for(i := 0; i < n; i++) {
5005		found := cipher_kinds[i];
5006		if(found[0]==cs[0] && found[1]==cs[1] && found[2]==cs[2]) break;
5007	}
5008
5009	if(i == n)
5010		return (nil, nil, nil, "fail to find a matched spec");
5011
5012	case i {
5013	SSL2_CK_RC4_128_WITH_MD5 =>
5014		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_RC4, SSL_STREAM_CIPHER,
5015				16, 0, SSL_MD5, Keyring->MD4dlen);
5016
5017	SSL2_CK_RC4_128_EXPORT40_WITH_MD5 =>
5018		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_RC4, SSL_STREAM_CIPHER,
5019				5, 0, SSL_MD5, Keyring->MD4dlen);
5020
5021	SSL2_CK_RC2_CBC_128_CBC_WITH_MD5 =>
5022		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_RC2_CBC, SSL_BLOCK_CIPHER,
5023				16, 8, SSL_MD5, Keyring->MD4dlen);
5024
5025	SSL2_CK_RC2_CBC_128_CBC_EXPORT40_WITH_MD5 =>
5026		cip = ref CipherSpec(SSL_EXPORT_TRUE, SSL_RC2_CBC, SSL_BLOCK_CIPHER,
5027				5, 8, SSL_MD5, Keyring->MD4dlen);
5028
5029	SSL2_CK_IDEA_128_CBC_WITH_MD5 =>
5030		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_IDEA_CBC, SSL_BLOCK_CIPHER,
5031				16, 8, SSL_MD5, Keyring->MD4dlen);
5032
5033	SSL2_CK_DES_64_CBC_WITH_MD5 =>
5034		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_DES_CBC, SSL_BLOCK_CIPHER,
5035				8, 8, SSL_MD5, Keyring->MD4dlen);
5036
5037	SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 =>
5038		cip = ref CipherSpec(SSL_EXPORT_FALSE, SSL_3DES_EDE_CBC, SSL_BLOCK_CIPHER,
5039				24, 8, SSL_MD5, Keyring->MD4dlen);
5040	}
5041
5042	kex = ref KeyExAlg.RSA(nil, nil, nil);
5043	sig = ref SigAlg.RSA(nil, nil);
5044
5045	return (cip, kex, sig, nil);
5046}
5047
5048v2suite_more(ciph: ref CipherSpec): (int, int, int)
5049{
5050	mkeylen, ckeylen, keyarglen: int;
5051
5052	case ciph.bulk_cipher_algorithm {
5053	SSL_RC4 =>
5054		mkeylen = 16;
5055		if(ciph.key_material == 5)
5056			ckeylen = 16 - 5;
5057		else
5058			ckeylen = 0;
5059		keyarglen = 0;
5060
5061	SSL_RC2_CBC =>
5062		mkeylen = 16;
5063		if(ciph.key_material == 5)
5064			ckeylen = 16 - 5;
5065		else
5066			ckeylen = 0;
5067		keyarglen = 8;
5068
5069	SSL_IDEA_CBC =>
5070		mkeylen = 16;
5071		ckeylen = 0;
5072		keyarglen = 8;
5073
5074	SSL_DES_CBC =>
5075		mkeylen = 8;
5076		if(ciph.key_material == 5)
5077			ckeylen = 8 - 5;
5078		else
5079			ckeylen = 0;
5080		keyarglen = 8;
5081
5082	SSL_3DES_EDE_CBC =>
5083		mkeylen = 24;
5084		ckeylen = 0;
5085		keyarglen = 8;
5086	}
5087
5088	return (mkeylen, ckeylen, keyarglen);
5089}
5090
5091v2handshake_enque(h: ref V2Handshake, ctx: ref Context)
5092{
5093	p := ref Protocol.pV2Handshake(h);
5094
5095	protocol_write(p, ctx);
5096}
5097
5098V2Handshake.encode(hm: self ref V2Handshake): (array of byte, string)
5099{
5100	a : array of byte;
5101	n : int;
5102	e : string;
5103
5104	i := 0;
5105	pick m := hm {
5106	Error =>
5107		n = 3;
5108		a = array[n] of byte;
5109		a[i++] = byte SSL2_MT_ERROR;
5110		a[i:] = m.code;
5111
5112	ClientHello =>
5113		specslen := len m.cipher_specs;
5114		sidlen := len m.session_id;
5115		challen := len m.challenge;
5116		n = 9+specslen + sidlen + challen;
5117		a = array[n] of byte;
5118		a[i++] = byte SSL2_MT_CLIENT_HELLO;
5119		a[i:] = m.version;
5120		i += 2;
5121		a[i:] = int_encode(specslen, 2);
5122		i += 2;
5123		a[i:] = int_encode(sidlen, 2);
5124		i += 2;
5125		a[i:] = int_encode(challen, 2);
5126		i += 2;
5127		a[i:] = m.cipher_specs;
5128		i += specslen;
5129		if(sidlen != 0) {
5130			a[i:] = m.session_id;
5131			i += sidlen;
5132		}
5133		if(challen != 0) {
5134			a[i:] = m.challenge;
5135			i += challen;
5136		}
5137
5138	ServerHello =>
5139		# use only the user certificate
5140		certlen := len m.certificate;
5141#		specslen := 3*len m.cipher_specs;
5142		specslen := len m.cipher_specs;
5143		cidlen := len m.connection_id;
5144		n = 11 + certlen + specslen + cidlen;
5145		a = array[n] of byte;
5146		a[i++] = byte SSL2_MT_SERVER_HELLO;
5147		a[i++] = byte m.session_id_hit;
5148		a[i++] = byte m.certificate_type;
5149		a[i:] = m.version;
5150		i += 2;
5151		a[i:] = int_encode(certlen, 2);
5152		i += 2;
5153		a[i:] = int_encode(specslen, 2);
5154		i += 2;
5155		a[i:] = int_encode(cidlen, 2);
5156		i += 2;
5157		a[i:] = m.certificate;
5158		i += certlen;
5159		a[i:] = m.cipher_specs;
5160		i += specslen;
5161		a[i:] = m.connection_id;
5162		i += cidlen;
5163
5164	ClientMasterKey =>
5165		ckeylen := len m.clear_key;
5166		ekeylen := len m.encrypt_key;
5167		karglen := len m.key_arg;
5168		n = 10 + ckeylen + ekeylen + karglen;
5169		a = array[n] of byte;
5170		a[i++] = byte SSL2_MT_CLIENT_MASTER_KEY;
5171		a[i:] = m.cipher_kind;
5172		i += 3;
5173		a[i:] = int_encode(ckeylen, 2);
5174		i += 2;
5175		a[i:] = int_encode(ekeylen, 2);
5176		i += 2;
5177		a[i:] = int_encode(karglen, 2);
5178		i += 2;
5179		a[i:] = m.clear_key;
5180		i += ckeylen;
5181		a[i:] = m.encrypt_key;
5182		i += ekeylen;
5183		a[i:] = m.key_arg;
5184		i += karglen;
5185
5186	ServerVerify =>
5187		challen := len m.challenge;
5188		n = 1 + challen;
5189		a = array[n] of byte;
5190		a[i++] = byte SSL2_MT_SERVER_VERIFY;
5191		a[i:] = m.challenge;
5192
5193	RequestCertificate =>
5194		cclen := len m.certificate_challenge;
5195		n = 2 + cclen;
5196		a = array[n] of byte;
5197		a[i++] = byte SSL2_MT_REQUEST_CERTIFICATE;
5198		a[i++] = byte m.authentication_type;
5199		a[i:] = m.certificate_challenge;
5200		i += cclen;
5201
5202	ClientCertificate =>
5203		# use only the user certificate
5204		certlen := len m.certificate;
5205		resplen := len m.response;
5206		n = 6 + certlen + resplen;
5207		a = array[n] of byte;
5208		a[i++] = byte SSL2_MT_CLIENT_CERTIFICATE;
5209		a[i++] = byte m.certificate_type;
5210		a[i:] = int_encode(certlen, 2);
5211		i += 2;
5212		a[i:] = int_encode(resplen, 2);
5213		i += 2;
5214		a[i:] = m.certificate;
5215		i += certlen;
5216		a[i:] = m.response;
5217		i += resplen;
5218
5219	ClientFinished =>
5220		cidlen := len m.connection_id;
5221		n = 1 + cidlen;
5222		a = array[n] of byte;
5223		a[i++] = byte SSL2_MT_CLIENT_FINISHED;
5224		a[i:] = m.connection_id;
5225		i += cidlen;
5226
5227	ServerFinished =>
5228		sidlen := len m.session_id;
5229		n = 1 + sidlen;
5230		a = array[n] of byte;
5231		a[i++] = byte SSL2_MT_SERVER_FINISHED;
5232		a[i:] = m.session_id;
5233		i += sidlen;
5234	}
5235
5236	return (a, e);
5237}
5238
5239V2Handshake.decode(a: array of byte): (ref V2Handshake, string)
5240{
5241	m : ref V2Handshake;
5242	e : string;
5243
5244	n := len a;
5245	i := 1;
5246	case int a[0] {
5247	SSL2_MT_ERROR =>
5248		if(n != 3)
5249			break;
5250		code := a[i:i+2];
5251		i += 2;
5252		m = ref V2Handshake.Error(code);
5253
5254	SSL2_MT_CLIENT_HELLO =>
5255		if(n < 9) {
5256			e = "client hello: message too short";
5257			break;
5258		}
5259		ver := a[i:i+2];
5260		i += 2;
5261		specslen := int_decode(a[i:i+2]);
5262		i += 2;
5263		sidlen := int_decode(a[i:i+2]);
5264		i += 2;
5265		challen := int_decode(a[i:i+2]);
5266		i += 2;
5267		if(n != 9+specslen+sidlen+challen) {
5268			e = "client hello: length mismatch";
5269			break;
5270		}
5271		if(specslen%3 != 0) {
5272			e = "client hello: must multiple of 3 bytes";
5273			break;
5274		}
5275		specs: array of byte;
5276		if(specslen != 0) {
5277			specs = a[i:i+specslen];
5278			i += specslen;
5279		}
5280		sid: array of byte;
5281		if(sidlen != 0) {
5282			sid = a[i:i+sidlen];
5283			i += sidlen;
5284		}
5285		chal: array of byte;
5286		if(challen != 0) {
5287			chal = a[i:i+challen];
5288			i += challen;
5289		}
5290		m = ref V2Handshake.ClientHello(ver, specs, sid, chal);
5291
5292	SSL2_MT_CLIENT_MASTER_KEY =>
5293		if(n < 10) {
5294			e = "client master key: message too short";
5295			break;
5296		}
5297		kind := a[i:i+3];
5298		i += 3;
5299		ckeylen := int_decode(a[i:i+2]);
5300		i += 2;
5301		ekeylen := int_decode(a[i:i+2]);
5302		i += 2;
5303		karglen := int_decode(a[i:i+2]);
5304		i += 2;
5305		if(n != 10 + ckeylen + ekeylen + karglen) {
5306			e = "client master key: length mismatch";
5307			break;
5308		}
5309		ckey := a[i:i+ckeylen];
5310		i += ckeylen;
5311		ekey := a[i:i+ekeylen];
5312		i += ekeylen;
5313		karg := a[i:i+karglen];
5314		i += karglen;
5315		m = ref V2Handshake.ClientMasterKey(kind, ckey, ekey, karg);
5316
5317	SSL2_MT_CLIENT_FINISHED =>
5318		cid := a[i:n];
5319		i = n;
5320		m = ref V2Handshake.ClientFinished(cid);
5321
5322	SSL2_MT_SERVER_HELLO =>
5323		if(n < 11) {
5324			e = "server hello: messsage too short";
5325			break;
5326		}
5327		sidhit := int a[i++];
5328		certtype := int a[i++];
5329		ver := a[i:i+2];
5330		i += 2;
5331		certlen := int_decode(a[i:i+2]);
5332		i += 2;
5333		specslen := int_decode(a[i:i+2]);
5334		i += 2;
5335		cidlen := int_decode(a[i:i+2]);
5336		i += 2;
5337		if(n != 11+certlen+specslen+cidlen) {
5338			e = "server hello: length mismatch";
5339			break;
5340		}
5341		cert := a[i:i+certlen];
5342		i += certlen;
5343		if(specslen%3 != 0) {
5344			e = "server hello: must be multiple of 3 bytes";
5345			break;
5346		}
5347		specs := a[i:i+specslen];
5348		i += specslen;
5349		if(cidlen < 16 || cidlen > 32) {
5350			e = "server hello: connection id length out of range";
5351			break;
5352		}
5353		cid := a[i:i+cidlen];
5354		i += cidlen;
5355		m = ref V2Handshake.ServerHello(sidhit, certtype, ver, cert, specs, cid);
5356
5357	SSL2_MT_SERVER_VERIFY =>
5358		chal := a[i:n];
5359		i = n;
5360		m = ref V2Handshake.ServerVerify(chal);
5361
5362	SSL2_MT_SERVER_FINISHED =>
5363		sid := a[i:n];
5364		m = ref V2Handshake.ServerFinished(sid);
5365
5366	SSL2_MT_REQUEST_CERTIFICATE =>
5367		if(n < 2) {
5368			e = "request certificate: message too short";
5369			break;
5370		}
5371		authtype := int a[i++];
5372		certchal := a[i:n];
5373		i = n;
5374		m = ref V2Handshake.RequestCertificate(authtype, certchal);
5375
5376	SSL2_MT_CLIENT_CERTIFICATE =>
5377		if(n < 6) {
5378			e = "client certificate: message too short";
5379			break;
5380		}
5381		certtype := int a[i++];
5382		certlen := int_decode(a[i:i+2]);
5383		i += 2;
5384		resplen := int_decode(a[i:i+2]);
5385		i += 2;
5386		if(n != 6+certlen+resplen) {
5387			e = "client certificate: length mismatch";
5388			break;
5389		}
5390		cert := a[i:i+certlen];
5391		i += certlen;
5392		resp := a[i:i+resplen];
5393		m = ref V2Handshake.ClientCertificate(certtype, cert, resp);
5394
5395	* =>
5396		e = "unknown message [" + string a[0] + "]";
5397	}
5398
5399	return (m, e);
5400}
5401
5402# utilities
5403
5404md5_hash(input: list of array of byte, md5_ds: ref DigestState): (array of byte, ref DigestState)
5405{
5406	hash_value := array [Keyring->MD5dlen] of byte;
5407	ds : ref DigestState;
5408
5409	if(md5_ds != nil)
5410		ds = md5_ds.copy();
5411
5412	lab := input;
5413	for(i := 0; i < len input - 1; i++) {
5414		ds = keyring->md5(hd lab, len hd lab, nil, ds);
5415		lab = tl lab;
5416	}
5417	ds = keyring->md5(hd lab, len hd lab, hash_value, ds);
5418
5419	return (hash_value, ds);
5420}
5421
5422sha_hash(input: list of array of byte, sha_ds: ref DigestState): (array of byte, ref DigestState)
5423{
5424	hash_value := array [Keyring->SHA1dlen] of byte;
5425	ds : ref DigestState;
5426
5427	if(sha_ds != nil)
5428		ds = sha_ds.copy();
5429
5430	lab := input;
5431	for(i := 0; i < len input - 1; i++) {
5432		ds = keyring->sha1(hd lab, len hd lab, nil, ds);
5433		lab = tl lab;
5434	}
5435	ds = keyring->sha1(hd lab, len hd lab, hash_value, ds);
5436
5437	return (hash_value, ds);
5438}
5439
5440md5_sha_hash(input: list of array of byte, md5_ds, sha_ds: ref DigestState)
5441	: (array of byte, ref DigestState, ref DigestState)
5442{
5443	buf := array [Keyring->MD5dlen+Keyring->SHA1dlen] of byte;
5444
5445	(buf[0:], md5_ds) = md5_hash(input, md5_ds);
5446	(buf[Keyring->MD5dlen:], sha_ds) = sha_hash(input, sha_ds);
5447
5448	return (buf, md5_ds, sha_ds);
5449}
5450
5451int_decode(buf: array of byte): int
5452{
5453	val := 0;
5454	for(i := 0; i < len buf; i++)
5455		val = (val << 8) | (int buf[i]);
5456
5457	return val;
5458}
5459
5460int_encode(value, length: int): array of byte
5461{
5462	buf := array [length] of byte;
5463
5464	while(length--)	{
5465		buf[length] = byte value;
5466		value >>= 8;
5467	}
5468
5469	return buf;
5470}
5471
5472
5473bastr(a: array of byte) : string
5474{
5475	ans : string = "";
5476
5477	for(i := 0; i < len a; i++) {
5478		if(i < len a - 1 && i != 0 && i%10 == 0)
5479			ans += "\n\t\t";
5480		if(i == len a -1)
5481			ans += sys->sprint("%2x", int a[i]);
5482		else
5483			ans += sys->sprint("%2x ", int a[i]);
5484	}
5485
5486	return ans;
5487}
5488
5489bbastr(a: array of array of byte) : string
5490{
5491	info := "";
5492
5493	for(i := 0; i < len a; i++)
5494		info += bastr(a[i]);
5495
5496	return info;
5497}
5498
5499lbastr(a: list of array of byte) : string
5500{
5501	info := "";
5502
5503	l := a;
5504	while(l != nil) {
5505		info += bastr(hd l) + "\n\t\t";
5506		l = tl l;
5507	}
5508
5509	return info;
5510}
5511
5512# need to fix (string a == string b)
5513bytes_cmp(a, b: array of byte): int
5514{
5515	if(len a != len b)
5516		return -1;
5517
5518	n := len a;
5519	for(i := 0; i < n; i++) {
5520		if(a[i] != b[i])
5521			return -1;
5522	}
5523
5524	return 0;
5525}
5526
5527putn(a: array of byte, i, value, n: int): int
5528{
5529	j := n;
5530	while(j--) {
5531		a[i+j] = byte value;
5532		value >>= 8;
5533	}
5534	return i+n;
5535}
5536
5537INVALID_SUITE : con "invalid suite list";
5538ILLEGAL_SUITE : con "illegal suite list";
5539
5540cksuites(suites : array of byte) : string
5541{
5542	m := len suites;
5543	if (m == 0 || (m&1))
5544		return INVALID_SUITE;
5545	n := len SSL3_Suites;
5546	ssl3s := array [2] of byte;
5547	for (j := 0; j < m; j += 2) {
5548		for( i := 0; i < n; i++) {
5549			ssl3s = SSL3_Suites[i];
5550			if(suites[j] == ssl3s[0] && suites[j+1] == ssl3s[1])
5551				break;
5552		}
5553		if (i == n)
5554			return ILLEGAL_SUITE;
5555	}
5556	return nil;
5557}
5558