diff options
Diffstat (limited to 'src/sbearssl')
-rw-r--r-- | src/sbearssl/sbearssl_client_init_and_run.c | 9 | ||||
-rw-r--r-- | src/sbearssl/sbearssl_run.c | 258 | ||||
-rw-r--r-- | src/sbearssl/sbearssl_server_init_and_run.c | 9 |
3 files changed, 138 insertions, 138 deletions
diff --git a/src/sbearssl/sbearssl_client_init_and_run.c b/src/sbearssl/sbearssl_client_init_and_run.c index 18ce86c..82c3ff3 100644 --- a/src/sbearssl/sbearssl_client_init_and_run.c +++ b/src/sbearssl/sbearssl_client_init_and_run.c @@ -29,9 +29,10 @@ void sbearssl_client_init_and_run (int *fds, tain const *tto, uint32_t preoption union br_skey_u key ; br_ssl_client_context cc ; sbearssl_x509_small_context xc ; + unsigned char bufi[BR_SSL_BUFSIZE_INPUT] ; + unsigned char bufo[BR_SSL_BUFSIZE_OUTPUT] ; br_x509_certificate chain[chainlen ? chainlen : 1] ; br_x509_trust_anchor btas[n] ; - unsigned char buf[BR_SSL_BUFSIZE_BIDI] ; for (size_t i = 0 ; i < chainlen ; i++) sbearssl_cert_to(genalloc_s(sbearssl_cert, &certs) + i, chain + i, storage.s) ; @@ -79,9 +80,9 @@ void sbearssl_client_init_and_run (int *fds, tain const *tto, uint32_t preoption } br_ssl_engine_add_flags(&cc.eng, BR_OPT_NO_RENEGOTIATION) ; - random_buf((char *)buf, 32) ; - br_ssl_engine_inject_entropy(&cc.eng, buf, 32) ; - br_ssl_engine_set_buffer(&cc.eng, buf, sizeof(buf), 1) ; + random_buf((char *)bufi, 32) ; + br_ssl_engine_inject_entropy(&cc.eng, bufi, 32) ; + br_ssl_engine_set_buffers_bidi(&cc.eng, bufi, sizeof(bufi), bufo, sizeof(bufo)) ; if (!br_ssl_client_reset(&cc, servername, 0)) strerr_diefu2x(97, "reset client context: ", sbearssl_error_str(br_ssl_engine_last_error(&cc.eng))) ; diff --git a/src/sbearssl/sbearssl_run.c b/src/sbearssl/sbearssl_run.c index a6204d4..a0eba96 100644 --- a/src/sbearssl/sbearssl_run.c +++ b/src/sbearssl/sbearssl_run.c @@ -15,176 +15,162 @@ #include <s6-networking/sbearssl.h> #include "sbearssl-internal.h" -void sbearssl_run (br_ssl_engine_context *ctx, int *fds, tain const *tto, uint32_t options, unsigned int verbosity, sbearssl_handshake_cbfunc_ref cb, sbearssl_handshake_cbarg *cbarg) + + /* declared in bearssl's inner.h */ +extern void br_ssl_engine_fail (br_ssl_engine_context *, int) ; + + /* XXX: breaks encapsulation; see make_ready_in() in src/ssl/ssl_engine.c in bearssl */ +static int br_ssl_engine_in_isempty (br_ssl_engine_context *ctx) +{ + return !ctx->iomode || (ctx->iomode == 3 && !ctx->ixa && !ctx->ixb) ; +} + +static void close_sendrec (br_ssl_engine_context *ctx, int *fd, int closenotify) +{ + if (closenotify) br_ssl_engine_close(ctx) ; + else + { + fd_shutdown(*fd, 1) ; + fd_close(*fd) ; + *fd = -1 ; + } +} + +void sbearssl_run (br_ssl_engine_context *ctx, int const *fds, tain const *tto, uint32_t options, unsigned int verbosity, sbearssl_handshake_cbfunc_ref cb, sbearssl_handshake_cbarg *cbarg) { - iopause_fd x[4] ; - unsigned int xindex[4] ; - int markedforflush = 0 ; + iopause_fd x[4] = { { .fd = fds[0], .revents = 0 }, { .fd = fds[1], .revents = 0 }, { .fd = fds[2] }, { .fd = fds[3] } } ; + unsigned int state = br_ssl_engine_current_state(ctx) ; int handshake_done = 0 ; + tain deadline ; - if (ndelay_on(fds[0]) < 0 - || ndelay_on(fds[1]) < 0 - || ndelay_on(fds[2]) < 0 - || ndelay_on(fds[3]) < 0) + if (ndelay_on(x[0].fd) == -1 + || ndelay_on(x[1].fd) == -1 + || ndelay_on(x[2].fd) == -1 + || ndelay_on(x[3].fd) == -1) strerr_diefu1sys(111, "set fds non-blocking") ; + tain_add_g(&deadline, tto) ; - for (;;) + while (x[0].fd >= 0 || x[1].fd >= 0 || x[3].fd >= 0) { - tain deadline = TAIN_INFINITE ; - unsigned int j = 0 ; - unsigned int state = br_ssl_engine_current_state(ctx) ; - int r ; - if (state & BR_SSL_CLOSED) { - r = br_ssl_engine_last_error(ctx) ; + int r = br_ssl_engine_last_error(ctx) ; if (r) strerr_dief4x(98, "the TLS engine closed the connection ", handshake_done ? "after" : "during", " the handshake: ", sbearssl_error_str(r)) ; - break ; + else break ; } - if (fds[0] >= 0 && state & BR_SSL_SENDAPP) + + /* Preparation */ + + if (x[0].fd >= 0 && state & BR_SSL_SENDAPP) { - x[j].fd = fds[0] ; - x[j].events = IOPAUSE_READ ; - xindex[0] = j++ ; + x[0].events = IOPAUSE_READ ; if (!handshake_done) { if (!(*cb)(ctx, cbarg)) strerr_dief1sys(111, "post-handshake callback failed") ; handshake_done = 1 ; + deadline = tain_infinite ; } } - else xindex[0] = 4 ; - if (fds[1] >= 0 && state & BR_SSL_RECVAPP) - { - x[j].fd = fds[1] ; - x[j].events = IOPAUSE_WRITE ; - xindex[1] = j++ ; - } - else xindex[1] = 4 ; - if (fds[2] >= 0 && state & BR_SSL_RECVREC) - { - x[j].fd = fds[2] ; - x[j].events = IOPAUSE_READ ; - xindex[2] = j++ ; - } - else xindex[2] = 4 ; - if (fds[3] >= 0 && state & BR_SSL_SENDREC) - { - x[j].fd = fds[3] ; - x[j].events = IOPAUSE_WRITE ; - xindex[3] = j++ ; - } - else xindex[3] = 4 ; + else x[0].events = 0 ; - if (xindex[0] == 4 && xindex[1] == 4 && xindex[3] == 4) - { - if (!j || handshake_done) break ; - tain_add_g(&deadline, tto) ; - } + if (x[1].fd >= 0) + x[1].events = IOPAUSE_EXCEPT | (state & BR_SSL_RECVAPP ? IOPAUSE_WRITE : 0) ; - r = iopause_g(x, j, &deadline) ; - if (r < 0) strerr_diefu1sys(111, "iopause") ; - else if (!r) + if (x[2].fd >= 0 && state & BR_SSL_RECVREC) x[2].events = IOPAUSE_READ ; + else x[2].events = 0 ; + + if (x[3].fd >= 0) + x[3].events = IOPAUSE_EXCEPT | (state & BR_SSL_SENDREC ? IOPAUSE_WRITE : 0) ; + + + /* Wait for events */ + + switch (iopause_g(handshake_done ? x : x+2, handshake_done ? 4 : 2, &deadline)) { - if (verbosity) strerr_dief1x(98, "handshake timed out") ; - else _exit(98) ; + case -1 : strerr_diefu1sys(111, "iopause") ; + case 0 : + if (verbosity) strerr_dief1x(98, "handshake timed out") ; + else _exit(98) ; } - while (j--) - if (x[j].revents & IOPAUSE_EXCEPT) - x[j].revents |= IOPAUSE_READ | IOPAUSE_WRITE ; - /* Flush to local */ - if (state & BR_SSL_RECVAPP && xindex[1] < 4 && x[xindex[1]].events & x[xindex[1]].revents & IOPAUSE_WRITE) + if (x[1].revents && state & BR_SSL_RECVAPP) { size_t len ; - unsigned char const *s = br_ssl_engine_recvapp_buf(ctx, &len) ; - size_t w = allwrite(fds[1], (char const *)s, len) ; - if (!w) - { - if (!error_isagain(errno)) - strerr_diefu1sys(111, "write to application") ; - } - else + for (;;) { - br_ssl_engine_recvapp_ack(ctx, w) ; - if (fds[2] < 0 && w == len) + ssize_t w ; + unsigned char const *s = br_ssl_engine_recvapp_buf(ctx, &len) ; + if (!len) break ; + w = fd_write(x[1].fd, (char const *)s, len) ; + if (w == -1) { - fd_close(fds[1]) ; fds[1] = -1 ; + if (error_isagain(errno)) break ; + strerr_diefu1sys(111, "write to local") ; } - state = br_ssl_engine_current_state(ctx) ; + br_ssl_engine_recvapp_ack(ctx, w) ; } + if (x[2].fd == -1 && !len) + { + fd_close(x[1].fd) ; + x[1].fd = -1 ; + } + state = br_ssl_engine_current_state(ctx) ; } - /* Flush to remote */ - if (state & BR_SSL_SENDREC && xindex[3] < 4 && x[xindex[3]].events & x[xindex[3]].revents & IOPAUSE_WRITE) + if (x[3].revents && state & BR_SSL_SENDREC) { size_t len ; - unsigned char const *s = br_ssl_engine_sendrec_buf(ctx, &len) ; - size_t w = allwrite(fds[3], (char const *)s, len) ; - if (!w) + for (;;) { - if (!error_isagain(errno)) - strerr_diefu1sys(111, "write to peer") ; - } - else - { - br_ssl_engine_sendrec_ack(ctx, w) ; - if (fds[0] < 0 && w == len) + ssize_t w ; + unsigned char const *s = br_ssl_engine_sendrec_buf(ctx, &len) ; + if (!len) break ; + w = fd_write(x[3].fd, (char const *)s, len) ; + if (w == -1) { - if (options & 1) - { - fd_shutdown(fds[3], 1) ; - fd_close(fds[3]) ; fds[3] = -1 ; - } - else br_ssl_engine_close(ctx) ; + if (error_isagain(errno)) break ; + strerr_diefu1sys(111, "write to remote") ; } - state = br_ssl_engine_current_state(ctx) ; + br_ssl_engine_sendrec_ack(ctx, w) ; } + if (x[0].fd == -1 && !len) + close_sendrec(ctx, &x[3].fd, options & 1) ; + state = br_ssl_engine_current_state(ctx) ; } - /* Fill from local */ - if (state & BR_SSL_SENDAPP && xindex[0] < 4 && x[xindex[0]].events & IOPAUSE_READ && (markedforflush || x[xindex[0]].revents & IOPAUSE_READ)) + if (x[0].revents & IOPAUSE_READ && state & BR_SSL_SENDAPP) { - size_t len ; - unsigned char *s = br_ssl_engine_sendapp_buf(ctx, &len) ; - size_t w ; - errno = 0 ; - w = allread(fds[0], (char *)s, len) ; - if (!w) + for (;;) { - br_ssl_engine_flush(ctx, 0) ; - markedforflush = 0 ; - if (!error_isagain(errno)) + size_t len ; + ssize_t r ; + unsigned char *s = br_ssl_engine_sendapp_buf(ctx, &len) ; + if (!len) break ; + r = fd_read(x[0].fd, (char *)s, len) ; + if (r == -1 && !error_isagain(errno)) + strerr_diefu1sys(111, "read from local") ; + else if (r <= 0) { - fd_close(fds[0]) ; fds[0] = -1 ; - if (!br_ssl_engine_sendrec_buf(ctx, &len)) + br_ssl_engine_flush(ctx, 0) ; + if (!r) { - if (options & 1) - { - fd_shutdown(fds[3], 1) ; - fd_close(fds[3]) ; fds[3] = -1 ; - } - else br_ssl_engine_close(ctx) ; + fd_close(x[0].fd) ; + x[0].fd = -1 ; + if (!br_ssl_engine_sendrec_buf(ctx, &len)) + close_sendrec(ctx, &x[3].fd, options & 1) ; } + break ; } - } - else - { - br_ssl_engine_sendapp_ack(ctx, w) ; - if (w == len) markedforflush = 1 ; - else - { - br_ssl_engine_flush(ctx, 0) ; - markedforflush = 0 ; - } + br_ssl_engine_sendapp_ack(ctx, r) ; } state = br_ssl_engine_current_state(ctx) ; } @@ -192,27 +178,39 @@ void sbearssl_run (br_ssl_engine_context *ctx, int *fds, tain const *tto, uint32 /* Fill from remote */ - if (state & BR_SSL_RECVREC && xindex[2] < 4 && x[xindex[2]].events & x[xindex[2]].revents & IOPAUSE_READ) + if (x[2].revents & IOPAUSE_READ && state & BR_SSL_RECVREC) { - size_t len ; - unsigned char *s = br_ssl_engine_recvrec_buf(ctx, &len) ; - size_t w ; - errno = 0 ; - w = allread(fds[2], (char *)s, len) ; - if (!w) + for (;;) { - if (!error_isagain(errno)) + size_t len ; + ssize_t r ; + unsigned char *s = br_ssl_engine_recvrec_buf(ctx, &len) ; + if (!s) break ; + r = fd_read(x[2].fd, (char *)s, len) ; + if (r == -1) + { + if (error_isagain(errno)) break ; + else strerr_diefu1sys(111, "read from remote") ; + } + else if (!r) { - if (options & 1) fd_shutdown(fds[2], 0) ; - fd_close(fds[2]) ; fds[2] = -1 ; - if (fds[1] >= 0 && !br_ssl_engine_recvapp_buf(ctx, &len)) + fd_shutdown(x[2].fd, 0) ; + fd_close(x[2].fd) ; + x[2].fd = -1 ; + if (!br_ssl_engine_recvapp_buf(ctx, &len)) { - fd_close(fds[1]) ; fds[1] = -1 ; + fd_close(x[1].fd) ; + x[1].fd = -1 ; } + if (!br_ssl_engine_in_isempty(ctx)) + br_ssl_engine_fail(ctx, BR_ERR_IO) ; + break ; } + br_ssl_engine_recvrec_ack(ctx, r) ; } - else br_ssl_engine_recvrec_ack(ctx, w) ; + state = br_ssl_engine_current_state(ctx) ; } } + _exit(0) ; } diff --git a/src/sbearssl/sbearssl_server_init_and_run.c b/src/sbearssl/sbearssl_server_init_and_run.c index d7817f0..01abb32 100644 --- a/src/sbearssl/sbearssl_server_init_and_run.c +++ b/src/sbearssl/sbearssl_server_init_and_run.c @@ -77,14 +77,15 @@ void sbearssl_server_init_and_run (int *fds, tain const *tto, uint32_t preoption stralloc tastorage = STRALLOC_ZERO ; genalloc tas = GENALLOC_ZERO ; /* sbearssl_ta */ size_t n = preoptions & 1 ? sbearssl_get_tas(&tas, &tastorage) : 0 ; - unsigned char buf[BR_SSL_BUFSIZE_BIDI] ; + unsigned char bufi[BR_SSL_BUFSIZE_INPUT] ; + unsigned char bufo[BR_SSL_BUFSIZE_OUTPUT] ; br_x509_trust_anchor btas[n ? n : 1] ; sbearssl_sctx_init_full_generic(&sc) ; sbearssl_sctx_set_policy_sni(&sc, &pol) ; - random_buf((char *)buf, 32) ; - br_ssl_engine_inject_entropy(&sc.eng, buf, 32) ; - br_ssl_engine_set_buffer(&sc.eng, buf, sizeof(buf), 1) ; + random_buf((char *)bufi, 32) ; + br_ssl_engine_inject_entropy(&sc.eng, bufi, 32) ; + br_ssl_engine_set_buffers_bidi(&sc.eng, bufi, sizeof(bufi), bufo, sizeof(bufo)) ; { uint32_t flags = BR_OPT_ENFORCE_SERVER_PREFERENCES | BR_OPT_NO_RENEGOTIATION ; |