From cc08be523a2a647a999dcf82dcce9dee62b4162c Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 30 Nov 2016 16:00:29 +0000 Subject: sbearssl: allow DER-encoded certificates in TA directory --- src/sbearssl/deps-lib/sbearssl | 4 +- src/sbearssl/sbearssl-internal.h | 2 - src/sbearssl/sbearssl_cert_readbigpem.c | 54 +++++++++++++++++++++++++++ src/sbearssl/sbearssl_cert_readfile.c | 56 +++++++++++++++++----------- src/sbearssl/sbearssl_run.c | 2 - src/sbearssl/sbearssl_s6tlsc.c | 4 ++ src/sbearssl/sbearssl_s6tlsd.c | 3 +- src/sbearssl/sbearssl_skey_readfile.c | 6 +-- src/sbearssl/sbearssl_ta_certs.c | 36 ++++++++++++++++++ src/sbearssl/sbearssl_ta_readdir.c | 10 +++-- src/sbearssl/sbearssl_ta_readfile.c | 27 +++++++++++++- src/sbearssl/sbearssl_ta_readfile_internal.c | 46 ----------------------- src/sbearssl/sbearssl_x509_minimal_set_tai.c | 17 +++++++++ 13 files changed, 183 insertions(+), 84 deletions(-) create mode 100644 src/sbearssl/sbearssl_cert_readbigpem.c create mode 100644 src/sbearssl/sbearssl_ta_certs.c delete mode 100644 src/sbearssl/sbearssl_ta_readfile_internal.c create mode 100644 src/sbearssl/sbearssl_x509_minimal_set_tai.c (limited to 'src/sbearssl') diff --git a/src/sbearssl/deps-lib/sbearssl b/src/sbearssl/deps-lib/sbearssl index 4e2d76c..d5964e6 100644 --- a/src/sbearssl/deps-lib/sbearssl +++ b/src/sbearssl/deps-lib/sbearssl @@ -1,5 +1,6 @@ sbearssl_append.o sbearssl_cert_from.o +sbearssl_cert_readbigpem.o sbearssl_cert_readfile.o sbearssl_cert_to.o sbearssl_ec_issuer_keytype.o @@ -23,11 +24,12 @@ sbearssl_skey_from.o sbearssl_skey_readfile.o sbearssl_skey_to.o sbearssl_ta_cert.o +sbearssl_ta_certs.o sbearssl_ta_from.o sbearssl_ta_readdir.o sbearssl_ta_readfile.o -sbearssl_ta_readfile_internal.o sbearssl_ta_to.o +sbearssl_x509_minimal_set_tai.o sbearssl_s6tlsc.o sbearssl_s6tlsd.o -lbearssl diff --git a/src/sbearssl/sbearssl-internal.h b/src/sbearssl/sbearssl-internal.h index d2757b1..eee3b84 100644 --- a/src/sbearssl/sbearssl-internal.h +++ b/src/sbearssl/sbearssl-internal.h @@ -19,6 +19,4 @@ struct sbearssl_strallocerr_s extern void sbearssl_append (void *, void const *, size_t) ; extern int sbearssl_pem_push (br_pem_decoder_context *, char const *, size_t, sbearssl_pemobject *, genalloc *, sbearssl_strallocerr *, int *) ; -extern int sbearssl_ta_readfile_internal (char const *, genalloc *, stralloc *, genalloc *, stralloc *) ; - #endif diff --git a/src/sbearssl/sbearssl_cert_readbigpem.c b/src/sbearssl/sbearssl_cert_readbigpem.c new file mode 100644 index 0000000..d09c997 --- /dev/null +++ b/src/sbearssl/sbearssl_cert_readbigpem.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int sbearssl_cert_readbigpem (char const *fn, genalloc *certs, stralloc *sa) +{ + char buf[BUFFER_INSIZE] ; + int fd = open_readb(fn) ; + buffer b = BUFFER_INIT(&buffer_read, fd, buf, BUFFER_INSIZE) ; + genalloc pems = GENALLOC_ZERO ; + sbearssl_pemobject *p ; + size_t certsbase = genalloc_len(sbearssl_cert, certs) ; + size_t sabase = sa->len ; + size_t n ; + size_t i = 0 ; + int certswasnull = !genalloc_s(sbearssl_cert, certs) ; + int sawasnull = !sa->s ; + int r ; + if (fd < 0) return -1 ; + r = sbearssl_pem_decode_from_buffer(&b, &pems, sa) ; + if (r) { fd_close(fd) ; return r ; } + fd_close(fd) ; + p = genalloc_s(sbearssl_pemobject, &pems) ; + n = genalloc_len(sbearssl_pemobject, &pems) ; + for (; i < n ; i++) + { + char const *name = sa->s + p[i].name ; + if (!str_diff(name, "CERTIFICATE") + || !str_diff(name, "X509 CERTIFICATE")) + { + sbearssl_cert sc = { .data = p[i].data, .datalen = p[i].datalen } ; + if (!genalloc_append(sbearssl_cert, certs, &sc)) goto fail ; + } + } + + genalloc_free(sbearssl_pemobject, &pems) ; + return 0 ; + + fail: + if (certswasnull) genalloc_free(sbearssl_cert, certs) ; + else genalloc_setlen(sbearssl_cert, certs, certsbase) ; + if (sawasnull) stralloc_free(sa) ; + else sa->len = sabase ; + genalloc_free(sbearssl_pemobject, &pems) ; + return r ; +} diff --git a/src/sbearssl/sbearssl_cert_readfile.c b/src/sbearssl/sbearssl_cert_readfile.c index 4ad693d..dd34270 100644 --- a/src/sbearssl/sbearssl_cert_readfile.c +++ b/src/sbearssl/sbearssl_cert_readfile.c @@ -12,36 +12,49 @@ int sbearssl_cert_readfile (char const *fn, genalloc *certs, stralloc *sa) { - char buf[BUFFER_INSIZE] ; - int fd = open_readb(fn) ; - buffer b = BUFFER_INIT(&buffer_read, fd, buf, BUFFER_INSIZE) ; - genalloc pems = GENALLOC_ZERO ; - sbearssl_pemobject *p ; + char buf[SBEARSSL_MAXCERTFILESIZE] ; size_t certsbase = genalloc_len(sbearssl_cert, certs) ; size_t sabase = sa->len ; size_t n ; - size_t i = 0 ; int certswasnull = !genalloc_s(sbearssl_cert, certs) ; int sawasnull = !sa->s ; - int r ; - if (fd < 0) return -1 ; - r = sbearssl_pem_decode_from_buffer(&b, &pems, sa) ; - if (r) { fd_close(fd) ; return r ; } - fd_close(fd) ; - p = genalloc_s(sbearssl_pemobject, &pems) ; - n = genalloc_len(sbearssl_pemobject, &pems) ; - for (; i < n ; i++) { - char const *name = sa->s + p[i].name ; - if (!str_diff(name, "CERTIFICATE") - || !str_diff(name, "X509 CERTIFICATE")) + register int r = openreadnclose(fn, buf, SBEARSSL_MAXCERTFILESIZE) ; + if (r < 0) return r ; + n = r ; + } + if (sbearssl_isder((unsigned char *)buf, n)) + { + sbearssl_cert cert = { .data = sa->len, .datalen = n } ; + if (!stralloc_catb(sa, buf, n)) return -1 ; + if (!genalloc_append(sbearssl_cert, certs, &cert)) goto fail ; + } + else + { + genalloc pems = GENALLOC_ZERO ; + size_t i = 0 ; + sbearssl_pemobject *p ; + register int r = sbearssl_pem_decode_from_string(buf, n, &pems, sa) ; + if (r) return r ; + p = genalloc_s(sbearssl_pemobject, &pems) ; + n = genalloc_len(sbearssl_pemobject, &pems) ; + for (; i < n ; i++) { - sbearssl_cert sc = { .data = p[i].data, .datalen = p[i].datalen } ; - if (!genalloc_append(sbearssl_cert, certs, &sc)) goto fail ; + char const *name = sa->s + p[i].name ; + if (!str_diff(name, "CERTIFICATE") + || !str_diff(name, "X509 CERTIFICATE")) + { + sbearssl_cert cert = { .data = p[i].data, .datalen = p[i].datalen } ; + if (!genalloc_append(sbearssl_cert, certs, &cert)) + { + genalloc_free(sbearssl_pemobject, &pems) ; + goto fail ; + } + } + genalloc_free(sbearssl_pemobject, &pems) ; } } - genalloc_free(sbearssl_pemobject, &pems) ; return 0 ; fail: @@ -49,6 +62,5 @@ int sbearssl_cert_readfile (char const *fn, genalloc *certs, stralloc *sa) else genalloc_setlen(sbearssl_cert, certs, certsbase) ; if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ; - genalloc_free(sbearssl_pemobject, &pems) ; - return r ; + return -1 ; } diff --git a/src/sbearssl/sbearssl_run.c b/src/sbearssl/sbearssl_run.c index b5f6618..1617e98 100644 --- a/src/sbearssl/sbearssl_run.c +++ b/src/sbearssl/sbearssl_run.c @@ -34,8 +34,6 @@ int sbearssl_run (br_ssl_engine_context *ctx, int *fds, unsigned int verbosity, if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; - tain_now_g() ; - for (;;) { tain_t deadline ; diff --git a/src/sbearssl/sbearssl_s6tlsc.c b/src/sbearssl/sbearssl_s6tlsc.c index 6b12320..f20f293 100644 --- a/src/sbearssl/sbearssl_s6tlsc.c +++ b/src/sbearssl/sbearssl_s6tlsc.c @@ -58,6 +58,7 @@ int sbearssl_s6tlsc (char const *const *argv, char const *const *envp, tain_t co 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()) @@ -73,6 +74,9 @@ int sbearssl_s6tlsc (char const *const *argv, char const *const *envp, tain_t co br_ssl_engine_set_buffer(&cc.eng, buf, sizeof(buf), 1) ; if (!br_ssl_client_reset(&cc, servername, 0)) strerr_diefu2x(97, "reset client context: ", sbearssl_error_str(br_ssl_engine_last_error(&cc.eng))) ; + tain_now_g() ; + if (!sbearssl_x509_minimal_set_tain(&xc, &STAMP)) + strerr_diefu1sys(111, "initialize validation time") ; { int wstat ; diff --git a/src/sbearssl/sbearssl_s6tlsd.c b/src/sbearssl/sbearssl_s6tlsd.c index fa95fbb..2cb3d21 100644 --- a/src/sbearssl/sbearssl_s6tlsd.c +++ b/src/sbearssl/sbearssl_s6tlsd.c @@ -36,7 +36,7 @@ int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t co x = env_get2(envp, "CERTFILE") ; if (!x) strerr_dienotset(100, "CERTFILE") ; - r = sbearssl_cert_readfile(x, &certs, &storage) ; + r = sbearssl_cert_readbigpem(x, &certs, &storage) ; if (r < 0) strerr_diefu2sys(111, "read certificate chain in ", x) ; else if (r) @@ -98,6 +98,7 @@ int sbearssl_s6tlsd (char const *const *argv, char const *const *envp, tain_t co br_ssl_engine_set_buffer(&sc.eng, buf, sizeof(buf), 1) ; br_ssl_server_reset(&sc) ; + tain_now_g() ; { int wstat ; diff --git a/src/sbearssl/sbearssl_skey_readfile.c b/src/sbearssl/sbearssl_skey_readfile.c index d5cf2b5..675ba5b 100644 --- a/src/sbearssl/sbearssl_skey_readfile.c +++ b/src/sbearssl/sbearssl_skey_readfile.c @@ -9,8 +9,6 @@ #include #include -#define MAXKEYFILESIZE 8192 - static int decode_key (sbearssl_skey *key, char const *s, size_t len, stralloc *sa) { br_skey_decoder_context ctx ; @@ -34,13 +32,13 @@ static int decode_key (sbearssl_skey *key, char const *s, size_t len, stralloc * int sbearssl_skey_readfile (char const *fn, sbearssl_skey *key, stralloc *sa) { - char buf[MAXKEYFILESIZE] ; + char buf[SBEARSSL_MAXSKEYFILESIZE] ; stralloc tmp = STRALLOC_ZERO ; genalloc list = GENALLOC_ZERO ; sbearssl_pemobject *p ; size_t n ; size_t i = 0 ; - int r = openreadnclose(fn, buf, MAXKEYFILESIZE) ; + int r = openreadnclose(fn, buf, SBEARSSL_MAXSKEYFILESIZE) ; 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_ta_certs.c b/src/sbearssl/sbearssl_ta_certs.c new file mode 100644 index 0000000..42b6115 --- /dev/null +++ b/src/sbearssl/sbearssl_ta_certs.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +int sbearssl_ta_certs (genalloc *taga, stralloc *tasa, sbearssl_cert const *certs, size_t certn, char const *certstorage) +{ + size_t tagabase = genalloc_len(sbearssl_ta, taga) ; + size_t tasabase = tasa->len ; + size_t i = 0 ; + int tagawasnull = !genalloc_s(sbearssl_ta, taga) ; + int tasawasnull = !tasa->s ; + int r ; + + for (; i < certn ; i++) + { + sbearssl_ta ta ; + int r = sbearssl_ta_cert(&ta, certs + i, certstorage, tasa) ; + if (r) goto fail ; + if (!genalloc_append(sbearssl_ta, taga, &ta)) goto rfail ; + } + + return 0 ; + + rfail: + r = -1 ; + fail: + if (tagawasnull) genalloc_free(sbearssl_ta, taga) ; + else genalloc_setlen(sbearssl_ta, taga, tagabase) ; + if (tasawasnull) stralloc_free(tasa) ; + else tasa->len = tasabase ; + return r ; +} diff --git a/src/sbearssl/sbearssl_ta_readdir.c b/src/sbearssl/sbearssl_ta_readdir.c index 3d01dc8..de39eca 100644 --- a/src/sbearssl/sbearssl_ta_readdir.c +++ b/src/sbearssl/sbearssl_ta_readdir.c @@ -8,17 +8,16 @@ #include #include #include -#include "sbearssl-internal.h" int sbearssl_ta_readdir (char const *dirfn, genalloc *taga, stralloc *tasa) { - stralloc certsa = STRALLOC_ZERO ; - genalloc certga = GENALLOC_ZERO ; size_t tasabase = tasa->len ; size_t tagabase = genalloc_len(sbearssl_ta, taga) ; size_t dirfnlen = str_len(dirfn) ; int tasawasnull = !tasa->s ; int tagawasnull = !genalloc_s(sbearssl_ta, taga) ; + stralloc certsa = STRALLOC_ZERO ; + genalloc certga = GENALLOC_ZERO ; DIR *dir = opendir(dirfn) ; if (!dir) return -1 ; @@ -36,8 +35,11 @@ int sbearssl_ta_readdir (char const *dirfn, genalloc *taga, stralloc *tasa) fn[dirfnlen] = '/' ; byte_copy(fn + dirfnlen + 1, dlen, d->d_name) ; fn[dirfnlen + 1 + dlen] = 0 ; - sbearssl_ta_readfile_internal(fn, taga, tasa, &certga, &certsa) ; + genalloc_setlen(sbearssl_cert, &certga, 0) ; + certsa.len = 0 ; + if (sbearssl_cert_readfile(fn, &certga, &certsa)) continue ; } + sbearssl_ta_certs(taga, tasa, genalloc_s(sbearssl_cert, &certga), genalloc_len(sbearssl_cert, &certga), certsa.s) ; } if (errno) goto fail ; diff --git a/src/sbearssl/sbearssl_ta_readfile.c b/src/sbearssl/sbearssl_ta_readfile.c index 8e7cf8e..9411347 100644 --- a/src/sbearssl/sbearssl_ta_readfile.c +++ b/src/sbearssl/sbearssl_ta_readfile.c @@ -1,16 +1,39 @@ /* ISC license. */ +#include +#include #include #include #include -#include "sbearssl-internal.h" int sbearssl_ta_readfile (char const *file, genalloc *taga, stralloc *tasa) { stralloc certsa = STRALLOC_ZERO ; genalloc certga = GENALLOC_ZERO ; - int r = sbearssl_ta_readfile_internal(file, taga, tasa, &certsa, &certga) ; + size_t tasabase = tasa->len ; + size_t tagabase = genalloc_len(sbearssl_ta, taga) ; + int tasawasnull = !tasa->s ; + int tagawasnull = !genalloc_s(sbearssl_ta, taga) ; + int r = sbearssl_cert_readbigpem(file, &certga, &certsa) ; + if (r) return r ; + r = sbearssl_ta_certs(taga, tasa, genalloc_s(sbearssl_cert, &certga), genalloc_len(sbearssl_cert, &certga), certsa.s) ; + if (r) goto fail ; + genalloc_free(sbearssl_ta, &certga) ; stralloc_free(&certsa) ; + return 0 ; + + fail: + { + int e = errno ; + genalloc_free(sbearssl_cert, &certga) ; + stralloc_free(&certsa) ; + if (tagawasnull) genalloc_free(sbearssl_ta, taga) ; + else genalloc_setlen(sbearssl_ta, taga, tagabase) ; + if (tasawasnull) stralloc_free(tasa) ; + else tasa->len = tasabase ; + errno = e ; + } return r ; + } diff --git a/src/sbearssl/sbearssl_ta_readfile_internal.c b/src/sbearssl/sbearssl_ta_readfile_internal.c deleted file mode 100644 index 70a0453..0000000 --- a/src/sbearssl/sbearssl_ta_readfile_internal.c +++ /dev/null @@ -1,46 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include -#include -#include "sbearssl-internal.h" - -int sbearssl_ta_readfile_internal (char const *file, genalloc *taga, stralloc *tasa, genalloc *certga, stralloc *certsa) -{ - size_t i = 0 ; - size_t certsabase = certsa->len ; - size_t certgabase = genalloc_len(sbearssl_ta, certga) ; - size_t tasabase = tasa->len ; - size_t tagabase = genalloc_len(sbearssl_ta, taga) ; - int tasawasnull = !tasa->s ; - int tagawasnull = !genalloc_s(sbearssl_ta, taga) ; - int r = sbearssl_cert_readfile(file, certga, certsa) ; - sbearssl_cert *p = genalloc_s(sbearssl_cert, certga) ; - size_t n = genalloc_len(sbearssl_cert, certga) ; - if (r) return r ; - - for (; i < n ; i++) - { - sbearssl_ta ta ; - r = sbearssl_ta_cert(&ta, p + i, certsa->s, tasa) ; - if (r) goto fail ; - if (!genalloc_append(sbearssl_ta, taga, &ta)) goto rfail ; - } - - genalloc_setlen(sbearssl_ta, certga, certgabase) ; - certsa->len = certsabase ; - return 0 ; - - rfail: - r = -1 ; - fail: - genalloc_setlen(sbearssl_ta, certga, certgabase) ; - certsa->len = certsabase ; - if (tagawasnull) genalloc_free(sbearssl_ta, taga) ; - else genalloc_setlen(sbearssl_ta, taga, tagabase) ; - if (tasawasnull) stralloc_free(tasa) ; - else tasa->len = tasabase ; - return r ; -} diff --git a/src/sbearssl/sbearssl_x509_minimal_set_tai.c b/src/sbearssl/sbearssl_x509_minimal_set_tai.c new file mode 100644 index 0000000..3d1a51d --- /dev/null +++ b/src/sbearssl/sbearssl_x509_minimal_set_tai.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include +#include + +int sbearssl_x509_minimal_set_tai (br_x509_minimal_context *ctx, tai_t const *t) +{ + uint64 u ; + if (!utc_from_tai(&u, t)) return 0 ; + u -= TAI_MAGIC ; + br_x509_minimal_set_time(ctx, (uint32_t)(u / 86400 + 719528), u % 86400) ; + return 1 ; +} -- cgit v1.2.3