From 334d807b924427434b42d4fbae745d3d1b38a218 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 10 Jan 2017 02:17:16 +0000 Subject: Types fix, first pass XXX marks what must change when skalibs changes. Also started writing functions for client certificate support in sbearssl, but it's not working yet (need more high-level support from BearSSL before it can work) --- src/sbearssl/deps-lib/sbearssl | 2 ++ src/sbearssl/sbearssl-internal.h | 1 + src/sbearssl/sbearssl_cert_readfile.c | 2 +- src/sbearssl/sbearssl_clean_tls_and_spawn.c | 1 + src/sbearssl/sbearssl_pem_decode_from_buffer.c | 11 ++++--- src/sbearssl/sbearssl_run.c | 1 + src/sbearssl/sbearssl_s6tlsc.c | 1 + src/sbearssl/sbearssl_s6tlsd.c | 45 ++++++++++++++++++++++++-- src/sbearssl/sbearssl_setclientcert.c | 29 +++++++++++++++++ src/sbearssl/sbearssl_skey_readfile.c | 2 +- src/sbearssl/sbearssl_x500_from_ta.c | 19 +++++++++++ src/sbearssl/sbearssl_x500_name_len.c | 15 +++++++++ src/sbearssl/sbearssl_x509_minimal_set_tai.c | 2 +- 13 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 src/sbearssl/sbearssl_setclientcert.c create mode 100644 src/sbearssl/sbearssl_x500_from_ta.c create mode 100644 src/sbearssl/sbearssl_x500_name_len.c (limited to 'src/sbearssl') diff --git a/src/sbearssl/deps-lib/sbearssl b/src/sbearssl/deps-lib/sbearssl index b3e69bb..4945ad8 100644 --- a/src/sbearssl/deps-lib/sbearssl +++ b/src/sbearssl/deps-lib/sbearssl @@ -30,6 +30,8 @@ sbearssl_ta_from.o sbearssl_ta_readdir.o sbearssl_ta_readfile.o sbearssl_ta_to.o +sbearssl_x500_name_len.o +sbearssl_x500_from_ta.o sbearssl_x509_minimal_set_tai.o sbearssl_s6tlsc.o sbearssl_s6tlsd.o diff --git a/src/sbearssl/sbearssl-internal.h b/src/sbearssl/sbearssl-internal.h index ac5e4e2..df3e3e5 100644 --- a/src/sbearssl/sbearssl-internal.h +++ b/src/sbearssl/sbearssl-internal.h @@ -4,6 +4,7 @@ #define SBEARSSL_INTERNAL_H #include +#include #include #include #include diff --git a/src/sbearssl/sbearssl_cert_readfile.c b/src/sbearssl/sbearssl_cert_readfile.c index dd34270..f63fde4 100644 --- a/src/sbearssl/sbearssl_cert_readfile.c +++ b/src/sbearssl/sbearssl_cert_readfile.c @@ -19,7 +19,7 @@ int sbearssl_cert_readfile (char const *fn, genalloc *certs, stralloc *sa) int certswasnull = !genalloc_s(sbearssl_cert, certs) ; int sawasnull = !sa->s ; { - register int r = openreadnclose(fn, buf, SBEARSSL_MAXCERTFILESIZE) ; + register ssize_t r = openreadnclose(fn, buf, SBEARSSL_MAXCERTFILESIZE) ; if (r < 0) return r ; n = r ; } diff --git a/src/sbearssl/sbearssl_clean_tls_and_spawn.c b/src/sbearssl/sbearssl_clean_tls_and_spawn.c index 258db90..d1bc9d8 100644 --- a/src/sbearssl/sbearssl_clean_tls_and_spawn.c +++ b/src/sbearssl/sbearssl_clean_tls_and_spawn.c @@ -1,6 +1,7 @@ /* ISC license. */ #include +#include #include #include #include "sbearssl-internal.h" diff --git a/src/sbearssl/sbearssl_pem_decode_from_buffer.c b/src/sbearssl/sbearssl_pem_decode_from_buffer.c index 8aecfda..e246b87 100644 --- a/src/sbearssl/sbearssl_pem_decode_from_buffer.c +++ b/src/sbearssl/sbearssl_pem_decode_from_buffer.c @@ -21,15 +21,15 @@ int sbearssl_pem_decode_from_buffer (buffer *b, genalloc *list, stralloc *sa) int listwasnull = !genalloc_s(sbearssl_pemobject, list) ; int sawasnull = !sa->s ; int inobj = 0 ; - int r ; + int r = -1 ; br_pem_decoder_init(&ctx) ; for (;;) { siovec_t v[2] ; - r = buffer_fill(b) ; - if (r < 0) goto fail ; - if (!r) break ; + ssize_t rr = buffer_fill(b) ; + if (rr < 0) goto rfail ; + if (!rr) break ; buffer_rpeek(b, v) ; r = sbearssl_pem_push(&ctx, v[0].s, v[0].len, &po, list, &blah, &inobj) ; if (r) goto fail ; @@ -42,8 +42,9 @@ int sbearssl_pem_decode_from_buffer (buffer *b, genalloc *list, stralloc *sa) } if (!inobj) return 0 ; - r = -1 ; errno = EPROTO ; + rfail: + r = -1 ; fail: if (listwasnull) genalloc_free(sbearssl_pemobject, list) ; else genalloc_setlen(sbearssl_pemobject, list, listbase) ; diff --git a/src/sbearssl/sbearssl_run.c b/src/sbearssl/sbearssl_run.c index ca4a79e..c496cba 100644 --- a/src/sbearssl/sbearssl_run.c +++ b/src/sbearssl/sbearssl_run.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/src/sbearssl/sbearssl_s6tlsc.c b/src/sbearssl/sbearssl_s6tlsc.c index 3a257a5..1a0b5f0 100644 --- a/src/sbearssl/sbearssl_s6tlsc.c +++ b/src/sbearssl/sbearssl_s6tlsc.c @@ -1,6 +1,7 @@ /* ISC license. */ #include +#include #include #include #include diff --git a/src/sbearssl/sbearssl_s6tlsd.c b/src/sbearssl/sbearssl_s6tlsd.c index 6cb3f51..66d0542 100644 --- a/src/sbearssl/sbearssl_s6tlsd.c +++ b/src/sbearssl/sbearssl_s6tlsd.c @@ -1,6 +1,7 @@ /* ISC license. */ #include +#include #include #include #include @@ -20,9 +21,10 @@ int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t co sbearssl_skey skey ; genalloc certs = GENALLOC_ZERO ; size_t chainlen ; - - if (preoptions & 1) - strerr_dief1x(100, "client certificates are not supported by BearSSL yet") ; + size_t x500n = 1 ; + size_t x500len = 1 ; + stralloc tastorage = STRALLOC_ZERO ; + genalloc tas = GENALLOC_ZERO ; { char const *x = env_get2(envp, "KEYFILE") ; @@ -44,17 +46,45 @@ int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t co chainlen = genalloc_len(sbearssl_cert, &certs) ; if (!chainlen) strerr_diefu2x(96, "find a certificate in ", x) ; + + if (preoptions & 1) + { + x = env_get2(envp, "CADIR") ; + if (x) r = sbearssl_ta_readdir(x, &tas, &tastorage) ; + else + { + x = env_get2(envp, "CAFILE") ; + if (!x) strerr_dienotset(100, "CADIR or CAFILE") ; + r = sbearssl_ta_readfile(x, &tas, &tastorage) ; + } + + 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)) ; + x500n = genalloc_len(sbearssl_ta, &tas) ; + if (!x500n) strerr_dief2x(96, "no trust anchor found in ", x) ; + x500len = sbearssl_x500_name_len(genalloc_s(sbearssl_ta, &tas), x500n) ; + } } { int fds[4] = { 0, 1, 0, 1 } ; unsigned char buf[BR_SSL_BUFSIZE_BIDI] ; + char x500storage[x500len] ; br_ssl_server_context sc ; union br_skey_u key ; br_x509_certificate chain[chainlen] ; + br_x500_name x500names[x500n] ; size_t i = chainlen ; pid_t pid ; + if (preoptions & 1) + { + sbearssl_x500_from_ta(x500names, genalloc_s(sbearssl_ta, &tas), x500n, x500storage, tastorage.s) ; + genalloc_free(sbearssl_ta, &tas) ; + stralloc_free(&tastorage) ; + } stralloc_shrink(&storage) ; while (i--) sbearssl_cert_to(genalloc_s(sbearssl_cert, &certs) + i, chain + i, storage.s) ; @@ -96,6 +126,15 @@ int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t co if (gid && setgid(gid) < 0) strerr_diefu1sys(111, "setgid") ; if (uid && setuid(uid) < 0) strerr_diefu1sys(111, "setuid") ; + { + uint32_t flags = BR_OPT_ENFORCE_SERVER_PREFERENCES | BR_OPT_NO_RENEGOTIATION ; + if (preoptions & 1) + { + br_ssl_server_set_trust_anchor_names(&sc, x500names, x500n) ; + if (!(preoptions & 4)) flags |= BR_OPT_TOLERATE_NO_CLIENT_AUTH ; + } + br_ssl_engine_add_flags(&sc.eng, flags) ; + } br_ssl_engine_set_buffer(&sc.eng, buf, sizeof(buf), 1) ; br_ssl_server_reset(&sc) ; tain_now_g() ; diff --git a/src/sbearssl/sbearssl_setclientcert.c b/src/sbearssl/sbearssl_setclientcert.c new file mode 100644 index 0000000..07b1385 --- /dev/null +++ b/src/sbearssl/sbearssl_setclientcert.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#include +#include +#include + +int sbearssl_setclientcert (br_ssl_client_context *cc, br_x509_certificate const *certs, size_t certlen, br_skey const *key) +{ + if (!certlen) return 0 ; + switch (key.type) + { + case BR_KEYTYPE_RSA : + br_ssl_client_set_single_rsa(cc, certs, certlen, &key->rsa, &br_rsa_i31_pkcs1_sign) ; + break ; + case BR_KEYTYPE_EC : + { + int kt, r ; + r = sbearssl_ec_issuer_keytype(&kt, &certs[0]) ; + if (r) return r ; + br_ssl_client_set_single_ec(cc, certs, certlen, &key->ec, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, kt, &br_ec_prime_i31, ) ; + break ; + } + default : + strerr_dief1x(96, "unsupported private key type") ; + } + + + return 0 ; +} diff --git a/src/sbearssl/sbearssl_skey_readfile.c b/src/sbearssl/sbearssl_skey_readfile.c index 675ba5b..c406de0 100644 --- a/src/sbearssl/sbearssl_skey_readfile.c +++ b/src/sbearssl/sbearssl_skey_readfile.c @@ -38,7 +38,7 @@ int sbearssl_skey_readfile (char const *fn, sbearssl_skey *key, stralloc *sa) sbearssl_pemobject *p ; size_t n ; size_t i = 0 ; - int r = openreadnclose(fn, buf, SBEARSSL_MAXSKEYFILESIZE) ; + int r = openreadnclose(fn, buf, SBEARSSL_MAXSKEYFILESIZE) ; /* fits in an int */ if (r < 0) return r ; n = r ; if (sbearssl_isder((unsigned char *)buf, n)) return decode_key(key, buf, n, sa) ; diff --git a/src/sbearssl/sbearssl_x500_from_ta.c b/src/sbearssl/sbearssl_x500_from_ta.c new file mode 100644 index 0000000..50a132b --- /dev/null +++ b/src/sbearssl/sbearssl_x500_from_ta.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include +#include +#include + +void sbearssl_x500_from_ta (br_x500_name *names, sbearssl_ta const *sta, size_t n, char *storage, char const *tastorage) +{ + while (n--) + { + register size_t len = sta->dnlen ; + byte_copy(storage, len, tastorage + sta->dn) ; + sta++ ; + names->data = (unsigned char *)storage ; + names->len = len ; + names++ ; + storage += len ; + } +} diff --git a/src/sbearssl/sbearssl_x500_name_len.c b/src/sbearssl/sbearssl_x500_name_len.c new file mode 100644 index 0000000..02bc9d7 --- /dev/null +++ b/src/sbearssl/sbearssl_x500_name_len.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include +#include + +size_t sbearssl_x500_name_len (sbearssl_ta const *sta, size_t n) +{ + size_t total = 0 ; + while (n--) + { + total += sta->dnlen ; + sta++ ; + } + return total ; +} diff --git a/src/sbearssl/sbearssl_x509_minimal_set_tai.c b/src/sbearssl/sbearssl_x509_minimal_set_tai.c index 3d1a51d..11b1ad6 100644 --- a/src/sbearssl/sbearssl_x509_minimal_set_tai.c +++ b/src/sbearssl/sbearssl_x509_minimal_set_tai.c @@ -1,6 +1,6 @@ /* ISC license. */ -#include +#include #include #include #include -- cgit v1.2.3