Skip to content

Commit

Permalink
chore: upgrade rustls and tokio-rustls, use rustls-native-certs
Browse files Browse the repository at this point in the history
  • Loading branch information
soywod authored and duesee committed May 8, 2024
1 parent 84830b8 commit 4af3e1a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup | Install NASM (Windows)
uses: ilammy/setup-nasm@v1
if: matrix.os == 'windows-latest'

- name: Setup | Install toolchain
run: |
rustup update --no-self-update stable
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ bounded-static = "0.5.0"
bytes = "1.5.0"
imap-codec = { version = "2.0.0", features = ["quirk_crlf_relaxed", "bounded-static"] }
imap-types = { version = "2.0.0" }
rustls = { version = "0.21.11", optional = true }
rustls = { version = "0.23.1", optional = true }
thiserror = "1.0.49"
tokio = { version = "1.32.0", optional = true, features = ["io-util", "macros", "net"] }
tokio-rustls = { version = "0.24.1", optional = true }
tokio-rustls = { version = "0.26.0", optional = true }
tracing = "0.1.40"

[dev-dependencies]
Expand Down
6 changes: 3 additions & 3 deletions proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ colored = "2.0.4"
imap-codec = { version = "2.0.0", features = ["bounded-static", "quirk_crlf_relaxed", "ext_id"] }
imap-flow = { path = ".." }
imap-types = { version = "2.0.0", features = ["bounded-static", "ext_id"] }
rustls = "0.21.7"
once_cell = "1.19.0"
rustls-native-certs = "0.7.0"
rustls-pemfile = "2.0.0-alpha.1"
serde = { version = "1.0.171", features = ["derive"] }
thiserror = "1.0.49"
tokio = { version = "1.28", features = ["full"] }
tokio-rustls = "0.24.1"
tokio-rustls = "0.26.0"
toml = "0.8.2"
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
webpki-roots = "0.25.2"
43 changes: 19 additions & 24 deletions proxy/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,30 @@ use imap_types::{
extensions::idle::IdleDone,
response::{Code, Status},
};
use rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore, ServerName};
use once_cell::sync::Lazy;
use thiserror::Error;
use tokio::net::{TcpListener, TcpStream};
use tokio_rustls::{TlsAcceptor, TlsConnector};
use tokio_rustls::{
rustls::{pki_types::ServerName, ClientConfig, RootCertStore, ServerConfig},
TlsAcceptor, TlsConnector,
};
use tracing::{error, info, trace};

use crate::{
config::{Bind, Connect, Identity, Service},
util::{self, ControlFlow, IdentityError},
};

static ROOT_CERT_STORE: Lazy<RootCertStore> = Lazy::new(|| {
let mut root_store = RootCertStore::empty();

for cert in rustls_native_certs::load_native_certs().unwrap() {
root_store.add(cert).unwrap();
}

root_store
});

const LITERAL_ACCEPT_TEXT: &str = "proxy: Literal accepted by proxy";
const LITERAL_REJECT_TEXT: &str = "proxy: Literal rejected by proxy";
const COMMAND_REJECTED_TEXT: &str = "proxy: Command rejected by server";
Expand All @@ -35,7 +48,7 @@ pub enum ProxyError {
#[error(transparent)]
Identity(#[from] IdentityError),
#[error(transparent)]
Tls(#[from] rustls::Error),
Tls(#[from] tokio_rustls::rustls::Error),
}

pub trait State: Send + 'static {}
Expand Down Expand Up @@ -84,8 +97,7 @@ impl Proxy<BoundState> {
}
};

let mut config = rustls::ServerConfig::builder()
.with_safe_defaults()
let mut config = ServerConfig::builder()
.with_no_client_auth()
// Note: The name is misleading. We provide the full chain here.
.with_single_cert(certificate_chain, leaf_key)?;
Expand Down Expand Up @@ -134,25 +146,8 @@ impl Proxy<ClientAcceptedState> {
let proxy_to_server = match self.service.connect {
Connect::Tls { ref host, .. } => {
let config = {
let root_store = {
let mut root_store = RootCertStore::empty();

root_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(
|ta| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
},
));

root_store
};

let mut config = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_root_certificates(ROOT_CERT_STORE.clone())
.with_no_client_auth();

// See <https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids>
Expand All @@ -162,7 +157,7 @@ impl Proxy<ClientAcceptedState> {
};

let connector = TlsConnector::from(Arc::new(config));
let dnsname = ServerName::try_from(host.as_str()).unwrap();
let dnsname = ServerName::try_from(host.clone()).unwrap();

info!(?server_addr_port, "Starting TLS with server");
Stream::tls(connector.connect(dnsname, stream_to_server).await?.into())
Expand Down
14 changes: 8 additions & 6 deletions proxy/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use imap_types::{
Greeting, Status, StatusBody, Tagged,
},
};
use rustls::{Certificate, PrivateKey};
use thiserror::Error;
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use tracing::warn;

pub enum ControlFlow {
Expand Down Expand Up @@ -144,9 +144,9 @@ pub enum IdentityError {
UnexpectedKeyCount { path: String, found: usize },
}

pub fn load_certificate_chain_pem<P: AsRef<Path>>(
pub fn load_certificate_chain_pem<'a, P: AsRef<Path>>(
path: P,
) -> Result<Vec<Certificate>, IdentityError> {
) -> Result<Vec<CertificateDer<'a>>, IdentityError> {
let display_path = path.as_ref().display().to_string();

let mut reader = BufReader::new(File::open(path).map_err(|error| IdentityError::Io {
Expand All @@ -156,7 +156,7 @@ pub fn load_certificate_chain_pem<P: AsRef<Path>>(

rustls_pemfile::certs(&mut reader)
.map(|res| {
res.map(|der| Certificate(der.to_vec()))
res.map(|der| CertificateDer::from(der.to_vec()))
.map_err(|source| IdentityError::Io {
source,
path: display_path.clone(),
Expand All @@ -165,7 +165,7 @@ pub fn load_certificate_chain_pem<P: AsRef<Path>>(
.collect()
}

pub fn load_leaf_key_pem<P: AsRef<Path>>(path: P) -> Result<PrivateKey, IdentityError> {
pub fn load_leaf_key_pem<'a, P: AsRef<Path>>(path: P) -> Result<PrivateKeyDer<'a>, IdentityError> {
let display_path = path.as_ref().display().to_string();

let mut reader = BufReader::new(File::open(&path).map_err(|source| IdentityError::Io {
Expand All @@ -180,7 +180,9 @@ pub fn load_leaf_key_pem<P: AsRef<Path>>(path: P) -> Result<PrivateKey, Identity
source,
path: display_path.clone(),
})?;
keys.push(PrivateKey(key.secret_pkcs8_der().to_vec()));
keys.push(PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
key.secret_pkcs8_der().to_vec(),
)));
}

match keys.len() {
Expand Down

0 comments on commit 4af3e1a

Please sign in to comment.