itls: Add support for TOFU (Trusted On First Use) - sacc - sacc(omys), simple console gopher client Err bitreich.org 70 hgit clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sacc/ URL:git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sacc/ bitreich.org 70 1Log /scm/sacc/log.gph bitreich.org 70 1Files /scm/sacc/files.gph bitreich.org 70 1Refs /scm/sacc/refs.gph bitreich.org 70 1Tags /scm/sacc/tag bitreich.org 70 1LICENSE /scm/sacc/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit e8930420e7c31a3cea0484314bd38aba5197fa39 /scm/sacc/commit/e8930420e7c31a3cea0484314bd38aba5197fa39.gph bitreich.org 70 1parent 7d3b71e31c73e122b62fec68a7196586f1b93082 /scm/sacc/commit/7d3b71e31c73e122b62fec68a7196586f1b93082.gph bitreich.org 70 hAuthor: Quentin Rameau URL:mailto:quinq@fifth.space bitreich.org 70 iDate: Tue, 20 Sep 2022 23:04:00 +0200 Err bitreich.org 70 i Err bitreich.org 70 itls: Add support for TOFU (Trusted On First Use) Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M io_tls.c | 77 ++++++++++++++++++++++++++++++- Err bitreich.org 70 i M sacc.c | 2 +- Err bitreich.org 70 i Err bitreich.org 70 i2 files changed, 76 insertions(+), 3 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/io_tls.c b/io_tls.c /scm/sacc/file/io_tls.c.gph bitreich.org 70 i@@ -1,3 +1,5 @@ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i@@ -29,13 +31,36 @@ close_tls(struct cnx *c) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static int Err bitreich.org 70 i+savepem(struct tls *t, char *path) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ FILE *f; Err bitreich.org 70 i+ const char *s; Err bitreich.org 70 i+ size_t ln; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if ((s = tls_peer_cert_chain_pem(t, &ln)) == NULL) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ if ((f = fopen(path, "w")) == NULL) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ fprintf(f, "%.*s\n", ln, s); Err bitreich.org 70 i+ if (fclose(f) != 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i connect_tls(struct cnx *c, struct addrinfo *ai, const char *host) Err bitreich.org 70 i { Err bitreich.org 70 i+ char pempath[PATH_MAX]; Err bitreich.org 70 i struct tls *t; Err bitreich.org 70 i+ struct tls_config *tc; Err bitreich.org 70 i char *s; Err bitreich.org 70 i int r; Err bitreich.org 70 i Err bitreich.org 70 i c->tls = NULL; Err bitreich.org 70 i+ tc = NULL; Err bitreich.org 70 i+ s = NULL; Err bitreich.org 70 i+ r = -1; Err bitreich.org 70 i Err bitreich.org 70 i if (connect(c->sock, ai->ai_addr, ai->ai_addrlen) == -1) Err bitreich.org 70 i return -1; Err bitreich.org 70 i@@ -45,16 +70,60 @@ connect_tls(struct cnx *c, struct addrinfo *ai, const char *host) Err bitreich.org 70 i Err bitreich.org 70 i if ((t = tls_client()) == NULL) Err bitreich.org 70 i return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ snprintf(pempath, sizeof(pempath), "/home/quinq/share/sacc/%s.pem", host); Err bitreich.org 70 i+ switch (tls) { Err bitreich.org 70 i+ case 1: Err bitreich.org 70 i+ /* check if there is a local certificate for target */ Err bitreich.org 70 i+ if (access(pempath, R_OK) == 0) { Err bitreich.org 70 i+ if ((tc = tls_config_new()) == NULL) Err bitreich.org 70 i+ goto end; Err bitreich.org 70 i+ if (tls_config_set_ca_file(tc, pempath) == -1) Err bitreich.org 70 i+ goto end; Err bitreich.org 70 i+ if (tls_configure(t, tc) == -1) Err bitreich.org 70 i+ goto end; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 2: Err bitreich.org 70 i+ /* save target certificate to file */ Err bitreich.org 70 i+ if ((tc = tls_config_new()) == NULL) Err bitreich.org 70 i+ goto end; Err bitreich.org 70 i+ tls_config_insecure_noverifycert(tc); Err bitreich.org 70 i+ if (tls_configure(t, tc) == -1) Err bitreich.org 70 i+ goto end; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i if (tls_connect_socket(t, c->sock, host) == -1) Err bitreich.org 70 i return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i do { Err bitreich.org 70 i r = tls_handshake(t); Err bitreich.org 70 i } while (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT); Err bitreich.org 70 i+ Err bitreich.org 70 i if (r == 0) { Err bitreich.org 70 i- c->tls = t; Err bitreich.org 70 i+ switch (tls) { Err bitreich.org 70 i+ case 1: Err bitreich.org 70 i+ c->tls = t; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 2: Err bitreich.org 70 i+ r = savepem(t, pempath) == 0 ? -2 : -1; Err bitreich.org 70 i+ tls = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i } else { Err bitreich.org 70 i diag("Can't establish TLS with \"%s\": %s", Err bitreich.org 70 i host, tls_error(t)); Err bitreich.org 70 i+ Err bitreich.org 70 i+ s = uiprompt("Save certificate locally and retry? [yN]: "); Err bitreich.org 70 i+ switch (*s) { Err bitreich.org 70 i+ case 'Y': Err bitreich.org 70 i+ case 'y': Err bitreich.org 70 i+ tls = 2; Err bitreich.org 70 i+ r = -2; Err bitreich.org 70 i+ goto end; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i s = uiprompt("Retry on cleartext? [Yn]: "); Err bitreich.org 70 i switch (*s) { Err bitreich.org 70 i case 'Y': Err bitreich.org 70 i@@ -66,8 +135,12 @@ connect_tls(struct cnx *c, struct addrinfo *ai, const char *host) Err bitreich.org 70 i default: Err bitreich.org 70 i r = -3; Err bitreich.org 70 i } Err bitreich.org 70 i- free(s); Err bitreich.org 70 i } Err bitreich.org 70 i+end: Err bitreich.org 70 i+ free(s); Err bitreich.org 70 i+ tls_config_free(tc); Err bitreich.org 70 i+ if (r != 0) Err bitreich.org 70 i+ tls_free(t); Err bitreich.org 70 i Err bitreich.org 70 i return r; Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/sacc.c b/sacc.c /scm/sacc/file/sacc.c.gph bitreich.org 70 i@@ -581,7 +581,7 @@ connectto(const char *host, const char *port, struct cnx *c) Err bitreich.org 70 i err = errno; Err bitreich.org 70 i ioclose(c); Err bitreich.org 70 i } Err bitreich.org 70 i- /* retry on cleartext */ Err bitreich.org 70 i+ /* retry */ Err bitreich.org 70 i } while (r == -2); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 .