xref: /inferno-os/appl/lib/ssl.b (revision 9b29ac7ea714507a9c0690620c02c8ca5ab25f90)
1implement SSL;
2
3include "sys.m";
4	sys: Sys;
5
6include "keyring.m";
7include "security.m";
8
9sslclone(): (ref Sys->Connection, string)
10{
11	if(sys == nil)
12		sys = load Sys Sys->PATH;
13	(rc, nil) := sys->stat("#D");	# only the local device will work, because local file descriptors are used
14	if(rc < 0)
15		return (nil, sys->sprint("cannot access SSL device #D: %r"));
16	c := ref Sys->Connection;
17	c.dir = "#D";
18	if(rc >= 0){
19		(rc, nil) = sys->stat("#D/ssl");	# another variant
20		if(rc >= 0)
21			c.dir = "#D/ssl";
22	}
23	clonef := c.dir+"/clone";
24	c.cfd = sys->open(clonef, Sys->ORDWR);
25	if(c.cfd == nil)
26		return (nil, sys->sprint("cannot open %s: %r", clonef));
27	s := readstring(c.cfd);
28	if(s == nil)
29		return (nil, sys->sprint("cannot read %s: %r", clonef));
30	c.dir += "/" + s;
31	return (c, nil);
32}
33
34connect(fd: ref Sys->FD): (string, ref Sys->Connection)
35{
36	(c, err) := sslclone();
37	if(c == nil)
38		return (err, nil);
39	c.dfd = sys->open(c.dir + "/data", Sys->ORDWR);
40	if(c.dfd == nil)
41		return (sys->sprint("cannot open data: %r"), nil);
42	if(sys->fprint(c.cfd, "fd %d", fd.fd) < 0)
43		return (sys->sprint("cannot push fd: %r"), nil);
44	return (nil, c);
45}
46
47secret(c: ref Sys->Connection, secretin, secretout: array of byte): string
48{
49	if(sys == nil)
50		sys = load Sys Sys->PATH;
51
52	if(secretin != nil){
53		fd := sys->open(c.dir + "/secretin", Sys->ORDWR);
54		if(fd == nil)
55			return sys->sprint("cannot open %s: %r", c.dir + "/secretin");
56		if(sys->write(fd, secretin, len secretin) < 0)
57			return sys->sprint("cannot write %s: %r", c.dir + "/secretin");
58	}
59
60	if(secretout != nil){
61		fd := sys->open(c.dir + "/secretout", Sys->ORDWR);
62		if(fd == nil)
63			return sys->sprint("cannot open %s: %r", c.dir + "/secretout");
64		if(sys->write(fd, secretout, len secretout) < 0)
65			return sys->sprint("cannot open %s: %r", c.dir + "/secretout");
66	}
67	return nil;
68}
69
70algs(): (list of string, list of string)
71{
72	(c, nil) := sslclone();
73	if(c == nil)
74		return (nil, nil);
75	c.dfd = nil;
76	(nil, encalgs) := sys->tokenize(readstring(sys->open(c.dir+"/encalgs", Sys->OREAD)), " \t\n");
77	(nil, hashalgs) := sys->tokenize(readstring(sys->open(c.dir+"/hashalgs", Sys->OREAD)), " \t\n");
78	return (encalgs, hashalgs);
79}
80
81readstring(fd: ref Sys->FD): string
82{
83	if(fd == nil)
84		return nil;
85	buf := array[256] of byte;
86	n := sys->read(fd, buf, len buf);
87	if(n < 0)
88		return nil;
89	return string buf[0:n];
90}
91