Skip to content

Commit

Permalink
feat(server): add a "helper" feature for TlsIdentityCtx
Browse files Browse the repository at this point in the history
This snippet is useful for server implementations, as long as the server
must be configured with a tokio-rustls TlsAcceptor, and not directly
with certificate paths for examples.

Signed-off-by: Marc-André Lureau <[email protected]>
  • Loading branch information
elmarco committed Oct 29, 2024
1 parent f62d143 commit 05037b1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/ironrdp-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ categories.workspace = true
doctest = true
test = false

[features]
helper = ["dep:x509-cert", "dep:rustls-pemfile"]

[dependencies]
anyhow = "1.0"
tokio = { version = "1", features = ["net", "macros", "sync", "rt"] }
Expand All @@ -33,6 +36,8 @@ ironrdp-acceptor.workspace = true
ironrdp-graphics.workspace = true
ironrdp-rdpsnd.workspace = true
tracing.workspace = true
x509-cert = { version = "0.2.5", optional = true }
rustls-pemfile = { version = "2.2.0", optional = true }

[dev-dependencies]
tokio = { version = "1", features = ["sync"] }
Expand Down
54 changes: 54 additions & 0 deletions crates/ironrdp-server/src/helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use std::{fs::File, io::BufReader, path::Path, sync::Arc};

use anyhow::Context;
use rustls_pemfile::{certs, pkcs8_private_keys};
use tokio_rustls::{rustls, TlsAcceptor};

pub struct TlsIdentityCtx {
pub cert: rustls::pki_types::CertificateDer<'static>,
pub priv_key: rustls::pki_types::PrivateKeyDer<'static>,
pub pub_key: Vec<u8>,
}

impl TlsIdentityCtx {
pub fn init_from_paths(cert_path: &Path, key_path: &Path) -> anyhow::Result<Self> {
use x509_cert::der::Decode as _;

let cert = certs(&mut BufReader::new(File::open(cert_path)?))
.next()
.context("no certificate")??;

let pub_key = {
let cert = x509_cert::Certificate::from_der(&cert).map_err(std::io::Error::other)?;
cert.tbs_certificate
.subject_public_key_info
.subject_public_key
.as_bytes()
.ok_or_else(|| std::io::Error::other("subject public key BIT STRING is not aligned"))?
.to_owned()
};

let priv_key = pkcs8_private_keys(&mut BufReader::new(File::open(key_path)?))
.next()
.context("no private key")?
.map(rustls::pki_types::PrivateKeyDer::from)?;

Ok(Self {
cert,
priv_key,
pub_key,
})
}

pub fn make_acceptor(&self) -> anyhow::Result<TlsAcceptor> {
let mut server_config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(vec![self.cert.clone()], self.priv_key.clone_key())
.context("bad certificate/key")?;

// This adds support for the SSLKEYLOGFILE env variable (https://wiki.wireshark.org/TLS#using-the-pre-master-secret)
server_config.key_log = Arc::new(rustls::KeyLogFile::new());

Ok(TlsAcceptor::from(Arc::new(server_config)))
}
}
4 changes: 4 additions & 0 deletions crates/ironrdp-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ mod clipboard;
mod display;
mod encoder;
mod handler;
#[cfg(feature = "helper")]
mod helper;
mod server;
mod sound;

pub use clipboard::*;
pub use display::*;
pub use handler::*;
#[cfg(feature = "helper")]
pub use helper::*;
pub use server::*;
pub use sound::*;

0 comments on commit 05037b1

Please sign in to comment.