diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2016-11-25 18:16:05 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2016-11-25 18:16:05 +0000 |
commit | 018025f0f36a4847df265c9948dbaf7073ed3245 (patch) | |
tree | 984c9a4bba06ef8abc02d0fbe81a70ec28c6f529 /src/sbearssl/sbearssl_s6tlsc.c | |
parent | 6421a5e923b0f695047b429e4176bca2873c5189 (diff) | |
download | s6-networking-018025f0f36a4847df265c9948dbaf7073ed3245.tar.xz |
Alpha version of the SSL work.
Doesn't build yet, but I'm scared of losing it, so using git as
storage.
Will fix the stupid bugs now, the tricky bugs later.
Diffstat (limited to 'src/sbearssl/sbearssl_s6tlsc.c')
-rw-r--r-- | src/sbearssl/sbearssl_s6tlsc.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/sbearssl/sbearssl_s6tlsc.c b/src/sbearssl/sbearssl_s6tlsc.c new file mode 100644 index 0000000..a8a6582 --- /dev/null +++ b/src/sbearssl/sbearssl_s6tlsc.c @@ -0,0 +1,82 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <bearssl.h> +#include <skalibs/strerr2.h> +#include <skalibs/tai.h> +#include <skalibs/env.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/random.h> +#include <s6-networking/sbearssl.h> + +int sbearssl_s6tlsc (char const *const *argv, char const *const *envp, tain_t const *tto, uint32_t preoptions, uint32_t options, uid_t uid, gid_t gid, unsigned int verbosity, int *sfd) +{ + int fds[4] = { sfd[0], sfd[1], sfd[0], sfd[1] } ; + stralloc storage = STRALLOC_ZERO ; + genalloc tas = GENALLOC_ZERO ; + size_t chainlen ; + int r ; + + if (preoptions & 1) + strerr_dief1x(100, "client certificates are not supported by BearSSL yet") ; + + x = env_get2(envp, "CADIR") ; + if (x) + r = sbearssl_ta_readdir(x, &tas, &storage) ; + else + { + x = env_get2(envp, "CAFILE") ; + if (!x) strerr_dienotset(100, "CADIR or CAFILE") ; + r = sbearssl_ta_readfile(x, &tas, &storage) ; + } + + if (r < 0) + strerr_diefu2sys(111, "read trust anchors in ", x) ; + else if (r) + strerr_diefu4x(96, "read trust anchors in ", x, ": ", sbearssl_error_str(r)) ; + + talen = genalloc_len(sbearssl_ta, &tas) ; + if (!talen) + strerr_dief2x(96, "no trust anchor found in ", x) ; + + { + unsigned char buf[BR_SSL_BUFSIZE_BIDI] ; + br_x509_minimal_context xc ; + br_ssl_client_context cc ; + br_x509_trust_anchor btas[talen] ; + size_t i = talen ; + pid_t pid ; + + stralloc_shrink(&storage) ; + while (i--) + sbearssl_ta_to(genalloc_s(sbearssl_ta, &tas) + i, btas + i, storage.s) ; + genalloc_free(sbearssl_ta, &tas) ; + br_ssl_client_init_full(&cc, &xc, btas, talen) ; + + if (!random_init()) + strerr_diefu1sys(111, "initialize random generator") ; + random_string(buf, 32) ; + br_ssl_engine_inject_entropy(&cc.eng, buf, 32) ; + random_finish() ; + + pid = child_spawn2(argv[0], argv, envp, fds) ; + if (gid && setgid(gid) < 0) strerr_diefu1sys(111, "setgid") ; + if (uid && setuid(uid) < 0) strerr_diefu1sys(111, "setuid") ; + + br_ssl_engine_set_buffer(&cc.eng, buf, sizeof(buf), 1) ; + br_ssl_client_reset(&cc) ; + + { + int wstat ; + int r = sbearssl_run(&cc.eng, fds, verbosity, options, tto) ; + if (r < 0) strerr_diefu1sys(111, "run SSL engine") ; + else if (r) strerr_diefu3x(98, "run SSL engine", ": ", sbearssl_error_str(r)) ; + if (wait_pid(pid, &wstat) < 0) strerr_diefu1sys(111, "wait_pid") ; + return wait_estatus(wstat) ; + } + } +} |