use std::fmt; use std::fs::File; use std::future::Future; use std::io::{self, BufReader, Cursor, Read}; use std::net::SocketAddr; use std::path::{Path, PathBuf}; use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use futures_util::ready; use hyper::server::accept::Accept; use hyper::server::conn::{AddrIncoming, AddrStream}; use tokio_rustls::rustls::server::WebPkiClientVerifier; use tokio_rustls::rustls::{Error as TlsError, RootCertStore, ServerConfig};
usecrate::transport::Transport;
/// Represents errors that can occur building the TlsConfig #[derive(Debug)] pub(crate) enum TlsConfigError {
Io(io::Error), /// An Error parsing the Certificate
CertParseError, /// Identity PEM is invalid
InvalidIdentityPem, /// Identity PEM is missing a private key such as RSA, ECC or PKCS8
MissingPrivateKey, /// Unknown private key format
UnknownPrivateKeyFormat, /// An error from an empty key
EmptyKey, /// An error from an invalid key
InvalidKey(TlsError),
}
impl fmt::Display for TlsConfigError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { matchself {
TlsConfigError::Io(err) => err.fmt(f),
TlsConfigError::CertParseError => write!(f, "certificate parse error"),
TlsConfigError::UnknownPrivateKeyFormat => write!(f, "unknown private key format"),
TlsConfigError::MissingPrivateKey => write!(
f, "Identity PEM is missing a private key such as RSA, ECC or PKCS8"
),
TlsConfigError::InvalidIdentityPem => write!(f, "identity PEM is invalid"),
TlsConfigError::EmptyKey => write!(f, "key contains no private key"),
TlsConfigError::InvalidKey(err) => write!(f, "key contains an invalid key, {}", err),
}
}
}
impl std::error::Error for TlsConfigError {}
/// Tls client authentication configuration. pub(crate) enum TlsClientAuth { /// No client auth.
Off, /// Allow any anonymous or authenticated client.
Optional(Box<dyn Read + Send + Sync>), /// Allow any authenticated client.
Required(Box<dyn Read + Send + Sync>),
}
/// Builder to set the configuration for the Tls server. pub(crate) struct TlsConfigBuilder {
cert: Box<dyn Read + Send + Sync>,
key: Box<dyn Read + Send + Sync>,
client_auth: TlsClientAuth,
ocsp_resp: Vec<u8>,
}
/// Sets the trust anchor for optional Tls client authentication via file path. /// /// Anonymous and authenticated clients will be accepted. If no trust anchor is provided by any /// of the `client_auth_` methods, then client authentication is disabled by default. pub(crate) fn client_auth_optional_path(mutself, path: impl AsRef<Path>) -> Self { let file = Box::new(LazyFile {
path: path.as_ref().into(),
file: None,
}); self.client_auth = TlsClientAuth::Optional(file); self
}
/// Sets the trust anchor for optional Tls client authentication via bytes slice. /// /// Anonymous and authenticated clients will be accepted. If no trust anchor is provided by any /// of the `client_auth_` methods, then client authentication is disabled by default. pub(crate) fn client_auth_optional(mutself, trust_anchor: &[u8]) -> Self { let cursor = Box::new(Cursor::new(Vec::from(trust_anchor))); self.client_auth = TlsClientAuth::Optional(cursor); self
}
/// Sets the trust anchor for required Tls client authentication via file path. /// /// Only authenticated clients will be accepted. If no trust anchor is provided by any of the /// `client_auth_` methods, then client authentication is disabled by default. pub(crate) fn client_auth_required_path(mutself, path: impl AsRef<Path>) -> Self { let file = Box::new(LazyFile {
path: path.as_ref().into(),
file: None,
}); self.client_auth = TlsClientAuth::Required(file); self
}
/// Sets the trust anchor for required Tls client authentication via bytes slice. /// /// Only authenticated clients will be accepted. If no trust anchor is provided by any of the /// `client_auth_` methods, then client authentication is disabled by default. pub(crate) fn client_auth_required(mutself, trust_anchor: &[u8]) -> Self { let cursor = Box::new(Cursor::new(Vec::from(trust_anchor))); self.client_auth = TlsClientAuth::Required(cursor); self
}
impl Transport for TlsStream { fn remote_addr(&self) -> Option<SocketAddr> {
Some(self.remote_addr)
}
}
enum State {
Handshaking(tokio_rustls::Accept<AddrStream>),
Streaming(tokio_rustls::server::TlsStream<AddrStream>),
}
// tokio_rustls::server::TlsStream doesn't expose constructor methods, // so we have to TlsAcceptor::accept and handshake to have access to it // TlsStream implements AsyncRead/AsyncWrite handshaking tokio_rustls::Accept first pub(crate) struct TlsStream {
state: State,
remote_addr: SocketAddr,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.