In the previous page/post/article whatever I've created a TLS CA certificate and a certificate that's signed by it. So far it seems I can use the same certificate at both the client side and server side. Since there are so many TLS crypto algorithms I'm not sure if this is secure. Anyway, move on.
So first I need 2 CA and device certificates.
So I modified the program such that it can output the certs in a given name.
It takes 3 arguments: the user name, the device name, the domain name.
It's at the commit 633facd886e7d66e152f9fd96aca72957c5332ce in the project repo (https://git.jxzqj.com/chat2026.git).
Having the certs the next step is going to be the creation of a TLS server and TLS client that can connect together. I think I will use rustls, which is TLS library written in pure Rust (only the TLS itself is implemented in Rust).
So let's start with the server...
But I've just noticed that we don't save the private key in the certificate generator.
So I need to fix that first. So we are at commit 705c40a6a527fa252a13b511fdb63d4ea4e50065 now.
So back to the server implementation.
So I first took the simple server example from the rustls GitHub and made it compile (apparently that code is obsolete an no one cares).
The following compiles and sort of works if I connect to it using openssl s_client:
use std::{
io::{Read, Write},
net::TcpListener,
sync::Arc,
};
use rustls::{
self,
pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject},
};
pub type BoxedError = Box<dyn std::error::Error + Send + Sync>;
pub type GenResult<T> = Result<T, BoxedError>;
fn main() -> GenResult<()> {
let mut args = std::env::args();
args.next();
let cert_file = args.next().expect("missing certificate file argument");
let private_key_file = args.next().expect("missing private key file argument");
let certs: Vec<CertificateDer> = CertificateDer::pem_file_iter(cert_file)
.unwrap()
.map(|cert| cert.unwrap())
.collect();
let private_key = PrivateKeyDer::from_pem_file(private_key_file).unwrap();
let config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, private_key)?;
let listener = TcpListener::bind(format!("[::]:{}", 4443)).unwrap();
println!("Server is listening.");
let (mut tcp_stream, _) = listener.accept()?;
println!("Client came.");
let mut conn = rustls::ServerConnection::new(Arc::new(config))?;
let mut tls_stream = rustls::Stream::new(&mut conn, &mut tcp_stream);
tls_stream.write_all(b"Hello from the server")?;
tls_stream.flush()?;
let mut buf = [0; 64];
let len = tls_stream.read(&mut buf)?;
println!("Received message from client: {:?}", &buf[..len]);
Ok(())
}
I've committed this for the time being, we are at commit 53eee9dafbca78daabcab8e73d2c085b2f5cffa3 now.
Of course this server doesn't do any client authentication, it also doesn't send the whole certificate chain, so the OpenSSL client cannot find of verify the CA certificate. Based on a quick web search it seems the server can send the whole chain, and it seems the example code which I used also supports it. So I need to find a way to build a certificate chain, it appears it can be saved in one file. The internet says I can just concatenate them together and it should work, and indeed it does.
Maybe I can build my own Vec of certs instead of relying on the PEM file iterator.
And indeed I can use PrivateKeyDer::from_pem_file for the device then CA cert and then put them into a Vec myself
and it works that way.
I think that's how we end up using it.
So I've committed it and we are at the commit d4696efe95266e684104cbf6b93d54977683ab2d right now.
So today I've learned a bit more about TLS stuff and run out of the time I allocated for this session. So no time to do the client as well in this post.
See the latest posts below, click the "..." to see them all. Click the tags to filter by tag. You can also subscribe to RSS in those lists.
Double entry bookkeeping explained - english finance
Chat2026 part 10: continuing application design - english chat2026-devblog
If you want privacy, please use a desktop PC - english privacy
YouTube is now practically unsearchable - english rants
Chat2026 part 9: using CRL in the server and client examples - english chat2026-devblog