💾 Archived View for gemi.dev › gemini-mailing-list › 001022.gmi captured on 2023-11-04 at 13:16:27. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2023-12-28)

-=-=-=-=-=-=-

A simple/toy client in C

stack@tilde.club <stack (a) tilde.club>

I've been trying to put together a very simple C toy client - just enought 
to connect to a Gemini server and get a page (no UI).  My goal is to 
figure out how a client connects, wrap a Common Lisp CFFI and make a 
Common Lisp client (which is why C is a requirement).

I am using BearSSL (for its minimalism). I started with the sample 
provided, modified for the Gemini request.  I keep getting stuck with 
error 62 (probably because I don't understand how to deal with TLS).  I 
attempted to generate the CA boilerplate code, but there are some ominous 
hints that the code is HTTPS-specific.

Could someone point me in the right direction (Ideally, to a repo with a C 
example :) I am not married to BearSSL - it just seemed an OK starting 
point.

Many thanks.

Link to individual message.

Omar Polo <op (a) omarpolo.com>


stack at tilde.club writes:

> I've been trying to put together a very simple C toy client - just
> enought to connect to a Gemini server and get a page (no UI).  My goal
> is to figure out how a client connects, wrap a Common Lisp CFFI and
> make a Common Lisp client (which is why C is a requirement).

My common lisp knowledge is pretty limited, but there's a reason you
can't use cl+ssl?  AFAIK it should works.  I know there are at least one
server (which I forgot the name, sorry) and a client (tinmop) which are
written entirely in common lisp.

> I am using BearSSL (for its minimalism). I started with the sample
> provided, modified for the Gemini request.  I keep getting stuck with
> error 62 (probably because I don't understand how to deal with TLS).
> I attempted to generate the CA boilerplate code, but there are some
> ominous hints that the code is HTTPS-specific.
>
> Could someone point me in the right direction (Ideally, to a repo with
> a C example :) I am not married to BearSSL - it just seemed an OK
> starting point.

I've never used anything else beside libtls, so I can't comment (or
compare it to) other libraries, but I'm quite fond of it.  It's really
well-documented (well, it's from OpenBSD after all :P) and really nice
to use.

As part of the regress suite of gmid (a gemini server) I've wrote a
really simple gemini client which should fits your criteria:

https://git.omarpolo.com/gmid/tree/regress/gg.c

It's mean to be compiled as part of gmid, but it's really easy to
extract (just define GEMINI_URL_LEN and replace strlcat/strlcpy or add
libbsd as deps)

Cheers!

> Many thanks.

Link to individual message.

stack@tilde.club <stack (a) tilde.club>

Thanks, Omar

I tried poking around in telescope, but isolating the network interaction 
looked painful.  I will look at your test client.

I looked at tinmop, but like most mature clients it does so much that it's 
hard to pull it apart.  I was hoping to get a simple example up, as I am 
obviously missing something related to certificates, and all examples seem 
to be HTTPS-related or just hardwired hand-made certificates.

HTTP+SSL is probably a fine solution (once I know what I'm doing), 
although libtls is probably better, and writing a CFFI is not a problem 
for me.

Link to individual message.

Jason McBrayer <jmcbray (a) carcosa.net>


stack at tilde.club writes:

> Thanks, Omar
>
> I tried poking around in telescope, but isolating the network
> interaction looked painful.  I will look at your test client.
>

I wrote a CL Gemini client library, which you can find at
https://git.carcosa.net/jmcbray/cl-gemini-client/. There is also a
complete server at https://git.carcosa.net/jmcbray/germinal/. Both of
them are written with CL+SSL.

-- 
Jason McBrayer      | ?Strange is the night where black stars rise,
jmcbray at carcosa.net | and strange moons circle through the skies,
                    | but stranger still is lost Carcosa.?
                    | ? Robert W. Chambers,The King in Yellow

Link to individual message.

Omar Polo <op (a) omarpolo.com>


stack at tilde.club writes:

> [...]
>
> I am using BearSSL (for its minimalism). I started with the sample
> provided, modified for the Gemini request.  I keep getting stuck with
> error 62 (probably because I don't understand how to deal with TLS).
> I attempted to generate the CA boilerplate code, but there are some
> ominous hints that the code is HTTPS-specific.

It's just a wild guess, I never touched BearSSL, but smell like a
possible failure in verifying the certificates.  In geminispace the
usage of TOFU and self-signed certificates is way more popular than in
the web, and TLS libraries by defaults try to verify the certificate
against the installed CAs.  For the record, on libtls is the function is
tls_config_insecure_noverifycert.

regarding the other mail: the code in gemini.c for telescope <= 0.4 is
probably a bit easier to grasp.  With telescope 0.5 gemini.c renamed
net.c and handles gopher and finger too.  Moreover, both telescope and
gmid use async I/O and relies a lot on libevent, so the code may seem a
bit harder to follow at first given how it's splitted in more functions.

The code in the test program gg.c uses blocking I/O and is a single
function in contrast.

HTH

Omar Polo

Link to individual message.

stack@tilde.club <stack (a) tilde.club>

Jason, thanks - a client library in CL is exactly what I need.  I can't 
believe I missed it in my searches.
Omar, thanks for the tips.

Link to individual message.

Michael Forney <mforney (a) mforney.org>

On 2021-09-21, Omar Polo <op at omarpolo.com> wrote:
> stack at tilde.club writes:
>
>> [...]
>>
>> I am using BearSSL (for its minimalism). I started with the sample
>> provided, modified for the Gemini request.  I keep getting stuck with
>> error 62 (probably because I don't understand how to deal with TLS).
>> I attempted to generate the CA boilerplate code, but there are some
>> ominous hints that the code is HTTPS-specific.
>
> It's just a wild guess, I never touched BearSSL, but smell like a
> possible failure in verifying the certificates.  In geminispace the
> usage of TOFU and self-signed certificates is way more popular than in
> the web, and TLS libraries by defaults try to verify the certificate
> against the installed CAs.  For the record, on libtls is the function is
> tls_config_insecure_noverifycert.

I have a lot of experience with BearSSL, and I think this is a good
guess. Error code 62 is BR_ERR_X509_NOT_TRUSTED, which means that the
server is using a certificate that was not accepted by the X.509
engine you configured your client to use.

stack, I'm assuming you were just using br_x509_minimal_context, which
is configured with a set of CAs, one of which must be found in the
certificate chain sent by servers. As Omar said, with gemini it is
common practice to use self-signed certificates, which will need a
different X.509 engine.

For an example, check out Drew DeVault's gmni client, which uses
BearSSL and implements an `x509_tofu_context`:
https://git.sr.ht/~sircmpwn/gmni/tree/master/item/src/tofu.c

Link to individual message.

---

Previous Thread: Not always online capsules

Next Thread: The /now page