1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <mp.h>
5 #include <libsec.h>
6
7 enum {
8 TLSFinishedLen = 12,
9 HFinished = 20,
10 };
11
12 static int
finished(int hand,int isclient)13 finished(int hand, int isclient)
14 {
15 int i, n;
16 uchar buf[500], buf2[500];
17
18 buf[0] = HFinished;
19 buf[1] = TLSFinishedLen>>16;
20 buf[2] = TLSFinishedLen>>8;
21 buf[3] = TLSFinishedLen;
22 n = TLSFinishedLen+4;
23
24 for(i=0; i<2; i++){
25 if(i==0)
26 memmove(buf+4, "client finished", TLSFinishedLen);
27 else
28 memmove(buf+4, "server finished", TLSFinishedLen);
29 if(isclient == 1-i){
30 if(write(hand, buf, n) != n)
31 return -1;
32 }else{
33 if(readn(hand, buf2, n) != n || memcmp(buf,buf2,n) != 0)
34 return -1;
35 }
36 }
37 return 1;
38 }
39
40
41 // given a plain fd and secrets established beforehand, return encrypted connection
42 int
pushtls(int fd,char * hashalg,char * encalg,int isclient,char * secret,char * dir)43 pushtls(int fd, char *hashalg, char *encalg, int isclient, char *secret, char *dir)
44 {
45 char buf[8];
46 char dname[64];
47 int n, data, ctl, hand;
48
49 // open a new filter; get ctl fd
50 data = hand = -1;
51 // /net/tls uses decimal file descriptors to name channels, hence a
52 // user-level file server can't stand in for #a; may as well hard-code it.
53 ctl = open("#a/tls/clone", ORDWR);
54 if(ctl < 0)
55 goto error;
56 n = read(ctl, buf, sizeof(buf)-1);
57 if(n < 0)
58 goto error;
59 buf[n] = 0;
60 if(dir)
61 sprint(dir, "#a/tls/%s", buf);
62
63 // get application fd
64 sprint(dname, "#a/tls/%s/data", buf);
65 data = open(dname, ORDWR);
66 if(data < 0)
67 goto error;
68
69 // get handshake fd
70 sprint(dname, "#a/tls/%s/hand", buf);
71 hand = open(dname, ORDWR);
72 if(hand < 0)
73 goto error;
74
75 // speak a minimal handshake
76 if(fprint(ctl, "fd %d 0x301", fd) < 0 ||
77 fprint(ctl, "version 0x301") < 0 ||
78 fprint(ctl, "secret %s %s %d %s", hashalg, encalg, isclient, secret) < 0 ||
79 fprint(ctl, "changecipher") < 0 ||
80 finished(hand, isclient) < 0 ||
81 fprint(ctl, "opened") < 0){
82 close(hand);
83 hand = -1;
84 goto error;
85 }
86 close(ctl);
87 close(hand);
88 close(fd);
89 return data;
90
91 error:
92 if(data>=0)
93 close(data);
94 if(ctl>=0)
95 close(ctl);
96 if(hand>=0)
97 close(hand);
98 return -1;
99 }
100