Hi all, I am looking for a solution to build a _small_, _statically linked_, minimal gemini client. My focus at the moment is to implement the basic communication layer (including TLS!): just enough to send a request to a gemini host and receive a response. Has anybody already built such a client? any pointer or suggestion? Where I stand as of now: --- I discarded OpenSSL. Bad memories of building small static executables a long time ago. Maybe it has improved and I am just prejudiced. --- LibreSSL: - not TLS v1.3 yet, but definitely alive and moving there. - easily builds static libraries, but no modular build: I mean I found no way to build libraries/executable with only a limited set of crypto algorithms => executables are large: The openssl command (similar to the OpenSSL one) is 2.5 MB (built on Linux with Musl libc, fully static, -Os, stripped). They also include the OpenBSD 'nc' command which supports TLS connections - 2 MB (for reference I have a small static nc without TLS support which is 50KB) --- BearSSL - very nice code. An impressive feat for a one-man project (Thomas Pornin) - not yet at TLS-1.3. The code looks maintained but I don't know if it is actively developed. I saw no sign of ed25519 cert signing, but may be wrong here. - code size: the whole libbearssl.a is ~ 860KB, basic client and server examples are in the 150KB range, which is very nice. --- WolfSSL - supports TLS-1.3. Is actively maintained by a company targeting embedded systems (but the code is GPL) - I don't know yet how to properly build small code, but with a default support for only TLS-1.3, and no ed25519 cert support, I could build basic client/server examples at ~ 260 KB. --- MatrixSSL - supports TLS-1.3 but the code of the last public (GPL) version hasn't changed in the last 6 months. - I have not yet succeeded in building static working examples with a cross compiler. So I don't have ballpark code size figures. --- Busybox ssl_client - some TLS support has been added in the recent busybox trees, based on MatrixSSLcode. As they say, "enough TLS to allow the busybox wget applet to retrieve a kernel source" from https://kernel.org/ - I built the ssl_client applet as a standalone static exe: 71 KB - it supports TLS-1.2 with a very limited set of crypto algos. and _no cert validation_. - I tried for fun to retrieve with it the root pages from all the gemini sites listed on Gus / known hosts: On a total of 116 sites, it managed to get 98 root pages and 18 TLS errors (I lack detailed error causes, but apparently mostly missing algos, and maybe some unsupported curves for ECDH(E).-- not so bad for such a small "client" - but clearly not enough for real use. Obviously, a big part of the equation is the evil number of combinations of ciphers, hashes and key exchange algos. Any guideline or best practice document about what ciphers/algos Gemini servers _should_ minimally support would help immensely! Again, any suggestion on how to build a small, static SSL client is more than welcome.Thanks in advance, Phil
netcat ? freD. ??????? Original Message ??????? On Thursday 2 July 2020 00:06, Phil Leblanc <philanc at gmail.com> wrote: > Hi all, > > I am looking for a solution to build a small, statically linked, > minimal gemini client. My focus at the moment is to implement the > basic communication layer (including TLS!): just enough to send a > request to a gemini host and receive a response. > > Has anybody already built such a client? any pointer or suggestion? > > Where I stand as of now: > > --- I discarded OpenSSL. Bad memories of building small static > executables a long time ago. Maybe it has improved and I am just > prejudiced. > > --- LibreSSL: > > - not TLS v1.3 yet, but definitely alive and moving there. > - easily builds static libraries, but no modular build: I mean I > found no way to build libraries/executable with only a limited set of > crypto algorithms > => executables are large: The openssl command (similar to the > > > OpenSSL one) is 2.5 MB (built on Linux with Musl libc, fully static, > -Os, stripped). They also include the OpenBSD 'nc' command which > supports TLS connections - 2 MB (for reference I have a small static > nc without TLS support which is 50KB) > > --- BearSSL > > - very nice code. An impressive feat for a one-man project (Thomas Pornin) > - not yet at TLS-1.3. The code looks maintained but I don't know if > it is actively developed. I saw no sign of ed25519 cert signing, but > may be wrong here. > > - code size: the whole libbearssl.a is ~ 860KB, basic client and > server examples are in the 150KB range, which is very nice. > > --- WolfSSL > > - supports TLS-1.3. Is actively maintained by a company targeting > embedded systems (but the code is GPL) > > - I don't know yet how to properly build small code, but with a > default support for only TLS-1.3, and no ed25519 cert support, I could > build basic client/server examples at ~ 260 KB. > > --- MatrixSSL > > - supports TLS-1.3 but the code of the last public (GPL) version > hasn't changed in the last 6 months. > > - I have not yet succeeded in building static working examples with > a cross compiler. So I don't have ballpark code size figures. > > --- Busybox ssl_client > > - some TLS support has been added in the recent busybox trees, based > on MatrixSSLcode. As they say, "enough TLS to allow the busybox wget > applet to retrieve a kernel source" from https://kernel.org/ > > - I built the ssl_client applet as a standalone static exe: 71 KB > - it supports TLS-1.2 with a very limited set of crypto algos. and > no cert validation. > > - I tried for fun to retrieve with it the root pages from all the > gemini sites listed on Gus / known hosts: On a total of 116 sites, it > managed to > get 98 root pages and 18 TLS errors (I lack detailed error causes, but > apparently mostly missing algos, and maybe some unsupported curves for > ECDH(E).-- not so bad for such a small "client" - but clearly not > enough for real use. > > Obviously, a big part of the equation is the evil number of > combinations of ciphers, hashes and key exchange algos. Any guideline > or best practice document about what ciphers/algos Gemini servers > should minimally support would help immensely! > > Again, any suggestion on how to build a small, static SSL client is > more than welcome.Thanks in advance, > > Phil >
On Wed, Jul 1, 2020 at 10:11 PM defdefred <defdefred at protonmail.com> wrote: > > netcat ? > Yes, something like netcat (or nc, or ncat) -- but with the following properties: - TLS support, - it can build as a _small_ _static_ executable (the libressl nc is at best 2 MB !!), - it can be built with a selected set of ciphers/protocols - and not the whole set, - and it allows to retrieve the server cert. Phil
On Thu, 2 Jul 2020 at 01:07, Phil Leblanc <philanc at gmail.com> wrote: > I am looking for a solution to build a _small_, _statically linked_, > minimal gemini client. My focus at the moment is to implement the > basic communication layer (including TLS!): just enough to send a > request to a gemini host and receive a response. > Sounds a bit like embedded development. Maybe look at Mbed TLS? (I haven't tried it.) https://github.com/ARMmbed/mbedtls -Hannu -------------- next part -------------- An HTML attachment was scrubbed... URL: <https://lists.orbitalfox.eu/archives/gemini/attachments/20200702/14cc 4b82/attachment-0001.htm>
On Wed, Jul 1, 2020 at 11:07 PM Hannu Hartikainen <hannu.hartikainen+gemini at gmail.com> wrote: > > Sounds a bit like embedded development. Maybe look at Mbed TLS? (I haven't tried it.) > https://github.com/ARMmbed/mbedtls > > -Hannu I will look into it. Thanks for the pointer. Phil
On 2020-07-01, Phil Leblanc <philanc at gmail.com> wrote: > --- BearSSL > - very nice code. An impressive feat for a one-man project (Thomas > Pornin) > - not yet at TLS-1.3. The code looks maintained but I don't know if > it is actively developed. I saw no sign of ed25519 cert signing, but > may be wrong here. > - code size: the whole libbearssl.a is ~ 860KB, basic client and > server examples are in the 150KB range, which is very nice. Have you looked at the TLS 1.3 page (https://bearssl.org/tls13.html)? It suggests that support for TLS 1.3 is planned, but there are some obstacles with Ed25519 that require more memory usage (buffering the complete certificate) and code size increase. I think it is a little out of date since RSA/PSS is now implemented in BearSSL, but you're right that there hasn't been much development for TLS 1.3 in a while. I'm hopeful that it will eventually be implemented. So if Ed25519 is what gemini servers are settling on for their certificates, then BearSSL is probably not a good option until support is available. Though, ECDSA uses comparable key/signature sizes and I believe it is fairly widely supported, so I think BearSSL would work quite well for that. I'm not sure if there are any existing gemini clients using libtls, but if there are, you might be interested in https://git.sr.ht/~mcf/libtls-bearssl. You could get a much smaller statically linked binary by just linking against libtls-bearssl instead of libtls from LibreSSL. -Michael
On Thu, Jul 2, 2020 at 12:37 AM Michael Forney <mforney at mforney.org> wrote: > > Have you looked at the TLS 1.3 page (https://bearssl.org/tls13.html)? > It suggests that support for TLS 1.3 is planned, [...] Thanks! I don't know how I missed this page :-) > > I'm not sure if there are any existing gemini clients using libtls, > but if there are, you might be interested in > https://git.sr.ht/~mcf/libtls-bearssl. You could get a much smaller > statically linked binary by just linking against libtls-bearssl > instead of libtls from LibreSSL. Your project is very nice! I built your libtls-bearssl library and then rebuilt the 'nc' client that comes with LibreSSL against your libtls.a and libbearssl.a. Just a minor issue: " undefined reference to `explicit_bzero' ". I provided it with a quick hack and I could build the libreSSL 'nc' with bearssl - Here are the executable sizes: LibreSSL nc 1,976 KB The _same_ nc linked against bearssl and your libtls-bearssl 276 KB -- Wow!! and it works fine! :-) (both are built static with musl libc, -Os, stripped) > -Michael Thanks! Phil
netcat is supporting tls :-) You can make a minimal client and a minimal server with it... freD. ??????? Original Message ??????? On Thursday 2 July 2020 00:22, Phil Leblanc <philanc at gmail.com> wrote: > On Wed, Jul 1, 2020 at 10:11 PM defdefred defdefred at protonmail.com wrote: > > > netcat ? > > Yes, something like netcat (or nc, or ncat) -- but with the following > properties: > > - TLS support, > - it can build as a small static executable (the libressl nc is > at best 2 MB !!), > > - it can be built with a selected set of ciphers/protocols - and not > the whole set, > > - and it allows to retrieve the server cert. > > Phil >
On 2020-07-01, Phil Leblanc <philanc at gmail.com> wrote: > Your project is very nice! Thanks :) > I built your libtls-bearssl library and > then rebuilt the 'nc' client that comes with LibreSSL against your > libtls.a and libbearssl.a. > > Just a minor issue: " undefined reference to `explicit_bzero' ". Are you using an old version of musl? It should be available since 1.1.20. I didn't add a compat implementation since it is pretty widely supported (glibc, musl, BSDs).
On Fri, Jul 3, 2020 at 8:59 PM Michael Forney <mforney at mforney.org> wrote: > > > Just a minor issue: " undefined reference to `explicit_bzero' ". > > Are you using an old version of musl? It should be available since > 1.1.20. I didn't add a compat implementation since it is pretty widely > supported (glibc, musl, BSDs). You are absolutely right. On this PC, I was still using 1.1.18. Time to update :-) Thanks for the head-up! Phil
On 7/1/20 6:06 PM, Phil Leblanc wrote: > Hi all, > > I am looking for a solution to build a _small_, _statically linked_, > minimal gemini client. My focus at the moment is to implement the > basic communication layer (including TLS!): just enough to send a > request to a gemini host and receive a response. I have long been planning to do the same thing, but haven't even started. The plan was to write it in Rust and use this: https://github.com/ctz/rustls Copied from README.md: ================================================================= ## Current features
On Mon Jul 6, 2020 at 4:09 PM CEST, Dave Gauer wrote: > Statically linked, yes. But I have no idea if it would meet the _small_ > goal! Hitting statically linked, small, and good TLS support simultaneously seems a little tricky. Which is a shame. Go produces static executables and has a pretty nice TLS library (with ED25519 support in the latest releases), but the executables sure ain't small. Something written in C using one of the TLS libraries targetting embedded systems seems the safest bet. Cheers, Solderpunk
On 7/6/20 10:32 AM, Solderpunk wrote: > On Mon Jul 6, 2020 at 4:09 PM CEST, Dave Gauer wrote: > >> Statically linked, yes. But I have no idea if it would meet the _small_ >> goal! > > Hitting statically linked, small, and good TLS support simultaneously > seems a little tricky. Which is a shame. Indeed! I was curious, so I built the "TLS client" example in the rustls repo. It compiles in the following 32 crates: aho-corasick, atty, base64, cfg-if, ct-logs, docopt, env_logger, humantime, lazy_static, log, memchr, mio, once_cell, quick-error, quote, regex, regex-syntax, ring, rustls, rustls-mio, sct, serde, serde_derive, spin, strsim, syn, termcolor, thread_local, unicode-xid, untrusted, webpki, webpki-roots (Note things like webpki are used in the example.) A `--release` build comes to 6,844,552 bytes. So no, not small. -Dave
---