SSL Socket C/C++ and dotnet core SSLSocket

I been writing socket programs for some time that run on internal networks now. Now I like to add proper SSL/TLS support. I do not have a registered domain. I do have DDNS. Would let's encrypt work to test how things work? Or I need full domain even for learning purposes? I know there is an OpenSSL developer certificate that I already played with. I like to try it on my own time with a proper certificate before I can pitch my work to my clients. So please let me know about DDNS. I am not interested in web development ASP, etc. Maybe some wss:// WebSockets.

My development is on Ubuntu 20.04 right now. I am running
$ certbot --version
certbot 1.9.0

What I am looking for is suggestions about how to generate the "best/secure" certificate for bsd sockets.

  1. I see quite a few examples of Web server certificates but very little about socket certificates?
  2. Is there a difference in how each certificate is generated?
  3. From my reading I have to renew the certificate every 90 days. It let's say I renew in 89 days do I have to restart my server for a new certificate to be loaded? Or is it that on each new socket connection, the certificate file is read from SSD so no reboot is required.
  4. Anyone has a good sample code to demonstrate all necessary steps initializing Secure Sockets. I like to see the steps and API used so I can go one by one and study,

Thank you all

1 Like

I can't help you with any coding, but I can help you get a cert from LE.
Which easily allows for (most) DDNS names.
If you have installed certbot from snap, then you are ready to get started.
For simplest authentication, you will need to allow HTTP (TCP port 80) to reach your server.
Then you can run certbot in stand alone mode to get that first cert.
Try it in staging first:
certbot certonly --standalone -d YOUR.DDNS.NAME --staging

2 Likes

Is there a difference between how certificate are generated for SSL socket and Https web server? This is my fundamental question. Also not sure what staging is. Yup I just started reading about this today.

Thank you all

1 Like

There shouldn't be.
There are very few types of certificates.
LE provides a very basic general use DV cert.
Which can be used by just about any program out there.
I don't believe there are any special requirements for web sockets.

The STAGING environment is a TEST simulation of the PRODUCTION environment.
It operates fundamentally in the exact same way, except it issues FAKE certs (not real ones).
But once you get that to work, switching to production is super simple.

3 Likes

From the perspective of Let's Encrypt certificates, they're the same.

HTTPS is just SSL/TLS wrapped around the HTTP protocol.

However, you can wrap SSL/TLS around any network protocol ... even around a UDP one.

Generating a certificate is generally the same process everywhere: you generate a CSR, you submit the CSR to the CA, and you get the certificate in return.

The protocol Let's Encrypt uses (ACME) is a higher-level protocol which, in addition to the CSR submission, handles the process of authenticating your control of the domain, before it's willing to issue you a certificate.

Let's Encrypt require you to demonstrate proof of control over your domain name (or DDNS subdomain) via DNS, or via an HTTP-based challenge, or a TLS-based challenge (https://letsencrypt.org/docs/challenge-types/).

A simple way to do this in a daemon: wait for a POSIX signal, reload the certificate and key from disk, update the SSL context with the new certificate.

This depends on what TLS library you use. e.g. using https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_use_certificate.html.

There is also the sane thing to do: use an external program like haproxy to act as the SSL/TLS server, allowing your application to be ignorant of SSL/TLS entirely. This also makes acquiring a certificate simpler.

Go look for OpenSSL example programs, I guess. The source code to openssl s_server is probably a good start. (Edit: on second thought, https://wiki.openssl.org/index.php/Simple_TLS_Server is probably a much better place to start).

What I would say is that it's a big task to do this in C or C++, and I wouldn't expect to get spooned answers. I think seriously considering whether you actually want to do this yourself or whether you can feasibly delegate the hard bits to haproxy/stunnel/whatever, is a good idea.

4 Likes

You can? I thought TLS is rather TCP-based (handshake requiring two-way traffic), but could be a erroneous thought on my part.

2 Likes

I was alluding to DTLS! But I think your take is the correct one; it's too much of a stretch to say that they're the same protocol.

3 Likes

But LE certificates should work for DTLS nonetheless!

2 Likes

Let's Encrypt certs are for domains/subdomains in general (any type of service that can have a TLS conversation). To get a "real" cert you need it to be globally trusted, that way you can show it to clients and it will work on their machine. For that you eventually need a domain (or subdomain) that you control (either you control the web server for http validation or the DNS for dns validation), and in general that domain/subdomain will resolve to an IP, but the port/service is unimportant/non-specific.

If your cert changes (it's renewed) you need to signal your process to load the new certificate, you don't need to restart your service if your service knows how to pick up and apply a new certificate, but I imagine you'll want to flush existing streams.

On the topic of examples, here is how you load a certificate from a file and use it for your socket stream (dotnet core/ ,net 5): https://docs.microsoft.com/en-us/dotnet/api/system.net.security.sslstream?view=net-5.0 - I'm guessing this also works on linux. A socket by itself doesn't provide TLS, it's the subsequent conversation that determines that.

2 Likes