xref: /inferno-os/appl/lib/crypt/sslsession.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth#
2*37da2899SCharles.Forsyth# SSL Session Cache
3*37da2899SCharles.Forsyth#
4*37da2899SCharles.Forsythimplement SSLsession;
5*37da2899SCharles.Forsyth
6*37da2899SCharles.Forsythinclude "sys.m";
7*37da2899SCharles.Forsyth	sys					: Sys;
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythinclude "daytime.m";
10*37da2899SCharles.Forsyth	daytime					: Daytime;
11*37da2899SCharles.Forsyth
12*37da2899SCharles.Forsythinclude "sslsession.m";
13*37da2899SCharles.Forsyth
14*37da2899SCharles.Forsyth
15*37da2899SCharles.Forsyth# default session id timeout
16*37da2899SCharles.ForsythTIMEOUT_SECS 					: con 5*60; # sec
17*37da2899SCharles.Forsyth
18*37da2899SCharles.ForsythSessionCache: adt {
19*37da2899SCharles.Forsyth	db					: list of ref Session;
20*37da2899SCharles.Forsyth	time_out				: int;
21*37da2899SCharles.Forsyth};
22*37da2899SCharles.Forsyth
23*37da2899SCharles.Forsyth# The shared session cache by all ssl contexts is available for efficiently resumming
24*37da2899SCharles.Forsyth# sessions for different run time contexts.
25*37da2899SCharles.Forsyth
26*37da2899SCharles.ForsythSession_Cache					: ref SessionCache;
27*37da2899SCharles.Forsyth
28*37da2899SCharles.Forsyth
29*37da2899SCharles.Forsythinit(): string
30*37da2899SCharles.Forsyth{
31*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
32*37da2899SCharles.Forsyth	if(sys == nil)
33*37da2899SCharles.Forsyth		return "sslsession: load sys module failed";
34*37da2899SCharles.Forsyth
35*37da2899SCharles.Forsyth	daytime = load Daytime Daytime->PATH;
36*37da2899SCharles.Forsyth	if(daytime == nil)
37*37da2899SCharles.Forsyth		return "sslsession: load Daytime module failed";
38*37da2899SCharles.Forsyth
39*37da2899SCharles.Forsyth	Session_Cache = ref SessionCache(nil, TIMEOUT_SECS);
40*37da2899SCharles.Forsyth
41*37da2899SCharles.Forsyth	return "";
42*37da2899SCharles.Forsyth}
43*37da2899SCharles.Forsyth
44*37da2899SCharles.ForsythSession.new(peer: string, time: int, ver: array of byte): ref Session
45*37da2899SCharles.Forsyth{
46*37da2899SCharles.Forsyth	s := ref Session;
47*37da2899SCharles.Forsyth
48*37da2899SCharles.Forsyth	s.peer = peer;
49*37da2899SCharles.Forsyth	s.connection_time = time;
50*37da2899SCharles.Forsyth	s.version = array [2] of byte;
51*37da2899SCharles.Forsyth	s.version[0:] = ver;
52*37da2899SCharles.Forsyth	s.session_id = nil;
53*37da2899SCharles.Forsyth	s.suite = nil;
54*37da2899SCharles.Forsyth	s.master_secret = nil;
55*37da2899SCharles.Forsyth	s.peer_certs = nil;
56*37da2899SCharles.Forsyth
57*37da2899SCharles.Forsyth	return s;
58*37da2899SCharles.Forsyth}
59*37da2899SCharles.Forsyth
60*37da2899SCharles.ForsythSession.duplicate(s: self ref Session): ref Session
61*37da2899SCharles.Forsyth{
62*37da2899SCharles.Forsyth	new := ref Session;
63*37da2899SCharles.Forsyth
64*37da2899SCharles.Forsyth	new.peer = s.peer;
65*37da2899SCharles.Forsyth	new.connection_time = s.connection_time;
66*37da2899SCharles.Forsyth	new.version = array [len s.version] of byte;
67*37da2899SCharles.Forsyth	new.version[0:] = s.version;
68*37da2899SCharles.Forsyth	new.session_id = array [len s.session_id] of byte;
69*37da2899SCharles.Forsyth	new.session_id[0:] = s.session_id;
70*37da2899SCharles.Forsyth	new.suite = array [len s.suite] of byte;
71*37da2899SCharles.Forsyth	new.suite[0:] = s.suite;
72*37da2899SCharles.Forsyth	new.master_secret = array [len s.master_secret] of byte;
73*37da2899SCharles.Forsyth	new.master_secret[0:] = s.master_secret;
74*37da2899SCharles.Forsyth	l: list of array of byte;
75*37da2899SCharles.Forsyth	pcs := s.peer_certs;
76*37da2899SCharles.Forsyth	while(pcs != nil) {
77*37da2899SCharles.Forsyth		a := hd pcs;
78*37da2899SCharles.Forsyth		b := array [len a] of byte;
79*37da2899SCharles.Forsyth		b[0:] = a;
80*37da2899SCharles.Forsyth		l = b :: l;
81*37da2899SCharles.Forsyth		pcs = tl pcs;
82*37da2899SCharles.Forsyth	}
83*37da2899SCharles.Forsyth	while(l != nil) {
84*37da2899SCharles.Forsyth		new.peer_certs = (hd l) :: new.peer_certs;
85*37da2899SCharles.Forsyth		l = tl l;
86*37da2899SCharles.Forsyth	}
87*37da2899SCharles.Forsyth	return new;
88*37da2899SCharles.Forsyth}
89*37da2899SCharles.Forsyth
90*37da2899SCharles.Forsyth# Each request process should get a copy of a session. A session will be
91*37da2899SCharles.Forsyth# removed from database if it is expired. The garbage
92*37da2899SCharles.Forsyth# collector will finally remove it from memory if there are no more
93*37da2899SCharles.Forsyth# references to it.
94*37da2899SCharles.Forsyth
95*37da2899SCharles.Forsythget_session_byname(peer: string): ref Session
96*37da2899SCharles.Forsyth{
97*37da2899SCharles.Forsyth	s: ref Session;
98*37da2899SCharles.Forsyth	now := daytime->now(); # not accurate but more efficient
99*37da2899SCharles.Forsyth
100*37da2899SCharles.Forsyth	l := Session_Cache.db;
101*37da2899SCharles.Forsyth	while(l != nil) {
102*37da2899SCharles.Forsyth		if((hd l).peer == peer) {
103*37da2899SCharles.Forsyth			s = hd l;
104*37da2899SCharles.Forsyth			# TODO: remove expired session
105*37da2899SCharles.Forsyth			if(now > s.connection_time+Session_Cache.time_out)
106*37da2899SCharles.Forsyth				s = nil;
107*37da2899SCharles.Forsyth			break;
108*37da2899SCharles.Forsyth		}
109*37da2899SCharles.Forsyth		l = tl l;
110*37da2899SCharles.Forsyth	}
111*37da2899SCharles.Forsyth	if(s == nil)
112*37da2899SCharles.Forsyth		s = Session.new(peer, now, nil);
113*37da2899SCharles.Forsyth	else
114*37da2899SCharles.Forsyth		s = s.duplicate();
115*37da2899SCharles.Forsyth
116*37da2899SCharles.Forsyth	return s;
117*37da2899SCharles.Forsyth}
118*37da2899SCharles.Forsyth
119*37da2899SCharles.Forsyth# replace the old by the new one
120*37da2899SCharles.Forsythadd_session(s: ref Session)
121*37da2899SCharles.Forsyth{
122*37da2899SCharles.Forsyth	#old : ref Session;
123*37da2899SCharles.Forsyth
124*37da2899SCharles.Forsyth	#ls := Session_Cache.db;
125*37da2899SCharles.Forsyth	#while(ls != nil) {
126*37da2899SCharles.Forsyth	#	old = hd ls;
127*37da2899SCharles.Forsyth	#	if(s.session_id == old.session_id) {
128*37da2899SCharles.Forsyth	#		# old = s;
129*37da2899SCharles.Forsyth	#		return;
130*37da2899SCharles.Forsyth	#	}
131*37da2899SCharles.Forsyth	#}
132*37da2899SCharles.Forsyth
133*37da2899SCharles.Forsyth	# always resume the most recent
134*37da2899SCharles.Forsyth	if(s != nil)
135*37da2899SCharles.Forsyth		Session_Cache.db = s :: Session_Cache.db;
136*37da2899SCharles.Forsyth}
137*37da2899SCharles.Forsyth
138*37da2899SCharles.Forsythget_session_byid(session_id: array of byte): ref Session
139*37da2899SCharles.Forsyth{
140*37da2899SCharles.Forsyth	s: ref Session;
141*37da2899SCharles.Forsyth	now := daytime->now(); # not accurate but more efficient
142*37da2899SCharles.Forsyth	l := Session_Cache.db;
143*37da2899SCharles.Forsyth	while(l != nil) {
144*37da2899SCharles.Forsyth		if(bytes_cmp((hd l).session_id, session_id) == 0) {
145*37da2899SCharles.Forsyth			s = hd l;
146*37da2899SCharles.Forsyth			# replace expired session
147*37da2899SCharles.Forsyth			if(now > s.connection_time+Session_Cache.time_out)
148*37da2899SCharles.Forsyth				s = Session.new(s.peer, now, nil);
149*37da2899SCharles.Forsyth			else
150*37da2899SCharles.Forsyth				s = s.duplicate();
151*37da2899SCharles.Forsyth			break;
152*37da2899SCharles.Forsyth		}
153*37da2899SCharles.Forsyth		l = tl l;
154*37da2899SCharles.Forsyth	}
155*37da2899SCharles.Forsyth	return s;
156*37da2899SCharles.Forsyth}
157*37da2899SCharles.Forsyth
158*37da2899SCharles.Forsythset_timeout(t: int)
159*37da2899SCharles.Forsyth{
160*37da2899SCharles.Forsyth	Session_Cache.time_out = t;
161*37da2899SCharles.Forsyth}
162*37da2899SCharles.Forsyth
163*37da2899SCharles.Forsythbytes_cmp(a, b: array of byte): int
164*37da2899SCharles.Forsyth{
165*37da2899SCharles.Forsyth	if(len a != len b)
166*37da2899SCharles.Forsyth		return -1;
167*37da2899SCharles.Forsyth
168*37da2899SCharles.Forsyth	n := len a;
169*37da2899SCharles.Forsyth	for(i := 0; i < n; i++) {
170*37da2899SCharles.Forsyth		if(a[i] != b[i])
171*37da2899SCharles.Forsyth			return -1;
172*37da2899SCharles.Forsyth	}
173*37da2899SCharles.Forsyth
174*37da2899SCharles.Forsyth	return 0;
175*37da2899SCharles.Forsyth}
176*37da2899SCharles.Forsyth
177