mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vm-migration: client-side of a TLS connection
TLS connections have a TLS server (listens for incoming connections) and a TLS client (initiates the connection). This commit adds the code for the client side, which is the sender of a migration On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
6e501cc2dc
commit
8e9d779688
211
Cargo.lock
generated
211
Cargo.lock
generated
@@ -71,7 +71,7 @@ version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -82,7 +82,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -182,7 +182,7 @@ dependencies = [
|
||||
"polling",
|
||||
"rustix",
|
||||
"slab",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -240,7 +240,7 @@ dependencies = [
|
||||
"rustix",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -272,6 +272,28 @@ version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.16.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.39.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cmake",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.76"
|
||||
@@ -482,6 +504,15 @@ dependencies = [
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.5"
|
||||
@@ -668,9 +699,15 @@ dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.16.0"
|
||||
@@ -750,7 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -840,6 +877,12 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.32"
|
||||
@@ -1784,7 +1827,7 @@ dependencies = [
|
||||
"hermit-abi",
|
||||
"pin-project-lite",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2017,6 +2060,20 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom 0.2.17",
|
||||
"libc",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.27"
|
||||
@@ -2039,7 +2096,44 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
|
||||
dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2249,6 +2343,12 @@ version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
@@ -2270,7 +2370,7 @@ dependencies = [
|
||||
"getrandom 0.4.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2280,7 +2380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2420,7 +2520,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||
dependencies = [
|
||||
"memoffset",
|
||||
"tempfile",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2441,6 +2541,12 @@ version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
@@ -2677,6 +2783,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"log",
|
||||
"rustls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -2907,6 +3015,15 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
@@ -2916,6 +3033,70 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "1.0.3"
|
||||
@@ -3047,7 +3228,7 @@ dependencies = [
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"uuid",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"winnow",
|
||||
"zbus_macros",
|
||||
"zbus_names",
|
||||
@@ -3100,6 +3281,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
|
||||
@@ -95,6 +95,7 @@ itertools = "0.14.0"
|
||||
jiff = { version = "0.2", default-features = false, features = ["std"] }
|
||||
libc = "0.2.186"
|
||||
log = "0.4.30"
|
||||
rustls = { version = "0.23.40", features = ["ring"] }
|
||||
sha2 = "0.11.0"
|
||||
signal-hook = "0.4.4"
|
||||
thiserror = "2.0.18"
|
||||
|
||||
@@ -8,6 +8,8 @@ version = "0.1.0"
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rustls = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive", "rc"] }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::protocol::MemoryRangeTable;
|
||||
mod bitpos_iterator;
|
||||
mod context;
|
||||
pub mod protocol;
|
||||
pub mod tls;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum UffdError {
|
||||
@@ -102,6 +103,9 @@ pub enum MigratableError {
|
||||
|
||||
#[error("Lifecycle operation skipped for disconnected component {0}")]
|
||||
DeviceDisconnected(String),
|
||||
|
||||
#[error("Error setting up a TLS-encrypted connection")]
|
||||
Tls(#[source] tls::TlsError),
|
||||
}
|
||||
|
||||
/// A Pausable component can be paused and resumed.
|
||||
|
||||
167
vm-migration/src/tls.rs
Normal file
167
vm-migration/src/tls.rs
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright © 2026 Cyberus Technology GmbH
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
//! TLS support for migration streams over TCP.
|
||||
//!
|
||||
//! This module wraps `rustls` to provide a blocking [`TlsStream`] for migration
|
||||
//! traffic. [`TlsStream::new_client`] authenticates the server against
|
||||
//! `ca-cert.pem` and the expected hostname, and presents `client-cert.pem` and
|
||||
//! `client-key.pem` for mutual TLS (mTLS) authentication. [`TlsServerConfig`] loads
|
||||
//! `server-cert.pem` and `server-key.pem`, trusts client certificates issued by
|
||||
//! the CA in `ca-cert.pem`, and [`TlsStream::new_server`] uses that
|
||||
//! configuration to establish the server side of the connection.
|
||||
//!
|
||||
//! [`TlsStream`] implements [`Read`], [`Write`], [`ReadVolatile`],
|
||||
//! [`WriteVolatile`], and [`AsFd`] so it can be used by the transport layer like
|
||||
//! other migration streams. All data must pass through rustls; direct I/O on the
|
||||
//! underlying socket would bypass TLS processing and break the connection.
|
||||
|
||||
use std::net::TcpStream;
|
||||
use std::path::Path;
|
||||
use std::result;
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::warn;
|
||||
use rustls::pki_types::pem::PemObject;
|
||||
use rustls::pki_types::{CertificateDer, InvalidDnsNameError, PrivateKeyDer, ServerName};
|
||||
use rustls::server::VerifierBuilderError;
|
||||
use rustls::{ClientConfig, ClientConnection, RootCertStore, StreamOwned};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::MigratableError;
|
||||
|
||||
const CA_CERT_FILE: &str = "ca-cert.pem";
|
||||
const CLIENT_CERT_FILE: &str = "client-cert.pem";
|
||||
const CLIENT_KEY_FILE: &str = "client-key.pem";
|
||||
|
||||
/// Errors that can occur when establishing a TLS-encrypted migration channel.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum TlsError {
|
||||
#[error("The provided hostname could not be parsed")]
|
||||
InvalidDnsName(#[source] InvalidDnsNameError),
|
||||
|
||||
#[error("Rustls protocol error")]
|
||||
RustlsError(#[from] rustls::Error),
|
||||
|
||||
#[error("Rustls verifier configuration error")]
|
||||
RustlsVerifierBuilderError(#[source] VerifierBuilderError),
|
||||
|
||||
#[error("Rustls protocol IO error")]
|
||||
RustlsIoError(#[from] std::io::Error),
|
||||
|
||||
#[error("TLS handshake stalled: no read/write progress while handshake is still in progress")]
|
||||
HandshakeError,
|
||||
|
||||
#[error("Error handling PEM file")]
|
||||
RustlsPemError(#[from] rustls::pki_types::pem::Error),
|
||||
}
|
||||
|
||||
/// Wraps the concrete rustls stream for either side (server or client) of the
|
||||
/// TLS connection.
|
||||
///
|
||||
/// [`TlsStream`] uses this enum to store a [`StreamOwned`] with either a
|
||||
/// [`ClientConnection`] or [`ServerConnection`] while exposing a single
|
||||
/// transport-agnostic API.
|
||||
#[derive(Debug)]
|
||||
enum TlsStreamParticipant {
|
||||
Client(StreamOwned<ClientConnection, TcpStream>),
|
||||
}
|
||||
|
||||
/// Server/Client-agnostic TLS stream.
|
||||
pub struct TlsStream {
|
||||
stream: TlsStreamParticipant,
|
||||
}
|
||||
|
||||
impl TlsStream {
|
||||
/// Creates a client [`TlsStream`].
|
||||
///
|
||||
/// The client verifies the server certificate against `ca-cert.pem` and the
|
||||
/// provided `hostname`, and presents the certificate chain in
|
||||
/// `client-cert.pem` together with the private key in `client-key.pem` for
|
||||
/// mutual TLS authentication.
|
||||
pub fn new_client(
|
||||
socket: TcpStream,
|
||||
cert_dir: &Path,
|
||||
hostname: &str,
|
||||
) -> result::Result<Self, MigratableError> {
|
||||
let root_store = load_root_store(&cert_dir.join(CA_CERT_FILE))?;
|
||||
let client_certs = load_cert_chain(&cert_dir.join(CLIENT_CERT_FILE))?;
|
||||
let client_key = load_private_key(&cert_dir.join(CLIENT_KEY_FILE))?;
|
||||
|
||||
let config = ClientConfig::builder()
|
||||
.with_root_certificates(root_store)
|
||||
.with_client_auth_cert(client_certs, client_key)
|
||||
.map_err(TlsError::RustlsError)
|
||||
.map_err(MigratableError::Tls)?;
|
||||
let config = Arc::new(config);
|
||||
|
||||
let server_name = ServerName::try_from(hostname.to_string())
|
||||
.map_err(TlsError::InvalidDnsName)
|
||||
.map_err(MigratableError::Tls)?;
|
||||
let conn = ClientConnection::new(config, server_name)
|
||||
.map_err(TlsError::RustlsError)
|
||||
.map_err(MigratableError::Tls)?;
|
||||
|
||||
let mut tls = StreamOwned::new(conn, socket);
|
||||
while tls.conn.is_handshaking() {
|
||||
let (rd, wr) = tls
|
||||
.conn
|
||||
.complete_io(&mut tls.sock)
|
||||
.map_err(TlsError::RustlsIoError)
|
||||
.map_err(MigratableError::Tls)?;
|
||||
// No handshake progress on a connection that should be handshaking, we treat
|
||||
// that as a failure.
|
||||
if rd == 0 && wr == 0 {
|
||||
return Err(MigratableError::Tls(TlsError::HandshakeError));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
stream: TlsStreamParticipant::Client(tls),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads trusted CA certificates into a root store, i.e. the set of trust anchors
|
||||
/// used to verify the peer's certificate chain.
|
||||
fn load_root_store(cert_path: &Path) -> result::Result<RootCertStore, MigratableError> {
|
||||
let mut root_store = RootCertStore::empty();
|
||||
let (_, ignored) = root_store.add_parsable_certificates(
|
||||
CertificateDer::pem_file_iter(cert_path)
|
||||
.map_err(TlsError::RustlsPemError)
|
||||
.map_err(MigratableError::Tls)?
|
||||
.map(|cert| cert.map_err(TlsError::RustlsPemError))
|
||||
.collect::<Result<Vec<CertificateDer<'static>>, TlsError>>()
|
||||
.map_err(MigratableError::Tls)?,
|
||||
);
|
||||
|
||||
if ignored > 0 {
|
||||
warn!(
|
||||
"Ignored {ignored} certificate(s) while loading TLS CA file {}",
|
||||
cert_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(root_store)
|
||||
}
|
||||
|
||||
/// Loads a certificate chain to present during the TLS handshake.
|
||||
fn load_cert_chain(
|
||||
cert_path: &Path,
|
||||
) -> result::Result<Vec<CertificateDer<'static>>, MigratableError> {
|
||||
CertificateDer::pem_file_iter(cert_path)
|
||||
.map_err(TlsError::RustlsPemError)
|
||||
.map_err(MigratableError::Tls)?
|
||||
.map(|cert| cert.map_err(TlsError::RustlsPemError))
|
||||
.collect::<Result<Vec<CertificateDer<'static>>, TlsError>>()
|
||||
.map_err(MigratableError::Tls)
|
||||
}
|
||||
|
||||
/// Loads the private key that proves ownership of the presented certificate chain.
|
||||
fn load_private_key(key_path: &Path) -> result::Result<PrivateKeyDer<'static>, MigratableError> {
|
||||
PrivateKeyDer::from_pem_file(key_path)
|
||||
.map_err(TlsError::RustlsPemError)
|
||||
.map_err(MigratableError::Tls)
|
||||
}
|
||||
Reference in New Issue
Block a user