Skip to content

Commit 5be1bb1

Browse files
committed
feat(server): make TlsIdentityCtx accept PEM files
This is in general more convenient than DER files. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
1 parent 114098b commit 5be1bb1

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

crates/ironrdp-server/src/helper.rs

+29-14
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,43 @@ use std::sync::Arc;
55

66
use anyhow::Context;
77
use rustls_pemfile::{certs, pkcs8_private_keys};
8-
use tokio_rustls::{rustls, TlsAcceptor};
8+
use tokio_rustls::rustls::pki_types::pem::PemObject;
9+
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer};
10+
use tokio_rustls::rustls::{self};
11+
use tokio_rustls::TlsAcceptor;
912

1013
pub struct TlsIdentityCtx {
11-
pub cert: rustls::pki_types::CertificateDer<'static>,
12-
pub priv_key: rustls::pki_types::PrivateKeyDer<'static>,
14+
pub certs: Vec<CertificateDer<'static>>,
15+
pub priv_key: PrivateKeyDer<'static>,
1316
pub pub_key: Vec<u8>,
1417
}
1518

1619
impl TlsIdentityCtx {
20+
/// A constructor to create a `TlsIdentityCtx` from the given certificate and key paths.
21+
///
22+
/// The file format can be either PEM (if the file extension ends with .pem) or DER.
1723
pub fn init_from_paths(cert_path: &Path, key_path: &Path) -> anyhow::Result<Self> {
18-
use x509_cert::der::Decode as _;
24+
let certs: Vec<_> = if cert_path.extension().map_or(false, |ext| ext == "pem") {
25+
CertificateDer::pem_file_iter(cert_path)
26+
} else {
27+
certs(&mut BufReader::new(File::open(cert_path)?))
28+
}
29+
.collect::<Result<_, _>>()
30+
.context(format!("reading server cert `{cert_path:?}`"))?;
1931

20-
let cert = certs(&mut BufReader::new(File::open(cert_path)?))
21-
.next()
22-
.context("no certificate")??;
32+
let priv_key = if key_path.extension().map_or(false, |ext| ext == "pem") {
33+
PrivateKeyDer::from_pem_file(key_path).context("reading server key `{key_path:?}`")?
34+
} else {
35+
pkcs8_private_keys(&mut BufReader::new(File::open(key_path)?))
36+
.next()
37+
.context("no private key")?
38+
.map(PrivateKeyDer::from)?
39+
};
2340

2441
let pub_key = {
42+
use x509_cert::der::Decode as _;
43+
44+
let cert = certs.first().ok_or_else(|| std::io::Error::other("invalid cert"))?;
2545
let cert = x509_cert::Certificate::from_der(&cert).map_err(std::io::Error::other)?;
2646
cert.tbs_certificate
2747
.subject_public_key_info
@@ -31,13 +51,8 @@ impl TlsIdentityCtx {
3151
.to_owned()
3252
};
3353

34-
let priv_key = pkcs8_private_keys(&mut BufReader::new(File::open(key_path)?))
35-
.next()
36-
.context("no private key")?
37-
.map(rustls::pki_types::PrivateKeyDer::from)?;
38-
3954
Ok(Self {
40-
cert,
55+
certs,
4156
priv_key,
4257
pub_key,
4358
})
@@ -46,7 +61,7 @@ impl TlsIdentityCtx {
4661
pub fn make_acceptor(&self) -> anyhow::Result<TlsAcceptor> {
4762
let mut server_config = rustls::ServerConfig::builder()
4863
.with_no_client_auth()
49-
.with_single_cert(vec![self.cert.clone()], self.priv_key.clone_key())
64+
.with_single_cert(self.certs.clone(), self.priv_key.clone_key())
5065
.context("bad certificate/key")?;
5166

5267
// This adds support for the SSLKEYLOGFILE env variable (https://wiki.wireshark.org/TLS#using-the-pre-master-secret)

0 commit comments

Comments
 (0)