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