diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libc/9sys/pushtls.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libc/9sys/pushtls.c')
-rwxr-xr-x | sys/src/libc/9sys/pushtls.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/sys/src/libc/9sys/pushtls.c b/sys/src/libc/9sys/pushtls.c new file mode 100755 index 000000000..038aad748 --- /dev/null +++ b/sys/src/libc/9sys/pushtls.c @@ -0,0 +1,99 @@ +#include <u.h> +#include <libc.h> +#include <auth.h> +#include <mp.h> +#include <libsec.h> + +enum { + TLSFinishedLen = 12, + HFinished = 20, +}; + +static int +finished(int hand, int isclient) +{ + int i, n; + uchar buf[500], buf2[500]; + + buf[0] = HFinished; + buf[1] = TLSFinishedLen>>16; + buf[2] = TLSFinishedLen>>8; + buf[3] = TLSFinishedLen; + n = TLSFinishedLen+4; + + for(i=0; i<2; i++){ + if(i==0) + memmove(buf+4, "client finished", TLSFinishedLen); + else + memmove(buf+4, "server finished", TLSFinishedLen); + if(isclient == 1-i){ + if(write(hand, buf, n) != n) + return -1; + }else{ + if(readn(hand, buf2, n) != n || memcmp(buf,buf2,n) != 0) + return -1; + } + } + return 1; +} + + +// given a plain fd and secrets established beforehand, return encrypted connection +int +pushtls(int fd, char *hashalg, char *encalg, int isclient, char *secret, char *dir) +{ + char buf[8]; + char dname[64]; + int n, data, ctl, hand; + + // open a new filter; get ctl fd + data = hand = -1; + // /net/tls uses decimal file descriptors to name channels, hence a + // user-level file server can't stand in for #a; may as well hard-code it. + ctl = open("#a/tls/clone", ORDWR); + if(ctl < 0) + goto error; + n = read(ctl, buf, sizeof(buf)-1); + if(n < 0) + goto error; + buf[n] = 0; + if(dir) + sprint(dir, "#a/tls/%s", buf); + + // get application fd + sprint(dname, "#a/tls/%s/data", buf); + data = open(dname, ORDWR); + if(data < 0) + goto error; + + // get handshake fd + sprint(dname, "#a/tls/%s/hand", buf); + hand = open(dname, ORDWR); + if(hand < 0) + goto error; + + // speak a minimal handshake + if(fprint(ctl, "fd %d 0x301", fd) < 0 || + fprint(ctl, "version 0x301") < 0 || + fprint(ctl, "secret %s %s %d %s", hashalg, encalg, isclient, secret) < 0 || + fprint(ctl, "changecipher") < 0 || + finished(hand, isclient) < 0 || + fprint(ctl, "opened") < 0){ + close(hand); + hand = -1; + goto error; + } + close(ctl); + close(hand); + close(fd); + return data; + +error: + if(data>=0) + close(data); + if(ctl>=0) + close(ctl); + if(hand>=0) + close(hand); + return -1; +} |