From e7cedcb881c048f7d0a42cd1df2ed19ddf92f169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 25 May 2021 09:31:00 +0000 Subject: [PATCH 01/51] Initial draft work for introducing a separate TLS provider replaceing ruslts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added support for openssl * Testing out Boringssl * Compilation features flags (openssl-tls, rustls-tls, boring-tls) Signed-off-by: Arnar Páll --- .gitignore | 3 + Cargo.toml | 2 +- linkerd/app/Cargo.toml | 3 + linkerd/app/core/Cargo.toml | 5 + linkerd/app/inbound/src/direct.rs | 4 +- linkerd/dns/name/src/name.rs | 4 +- linkerd/identity/Cargo.toml | 12 +- linkerd/identity/src/imp/openssl.rs | 345 +++++++++++++++++++++ linkerd/identity/src/imp/rustls.rs | 415 ++++++++++++++++++++++++++ linkerd/identity/src/lib.rs | 375 +++++++++-------------- linkerd/io/src/lib.rs | 12 - linkerd/proxy/identity/src/certify.rs | 1 + linkerd/tls/Cargo.toml | 16 +- linkerd/tls/src/client.rs | 77 ++++- linkerd/tls/src/imp/boring.rs | 243 +++++++++++++++ linkerd/tls/src/imp/openssl.rs | 318 ++++++++++++++++++++ linkerd/tls/src/imp/rustls.rs | 258 ++++++++++++++++ linkerd/tls/src/lib.rs | 131 ++++---- linkerd/tls/src/protocol.rs | 73 +++++ linkerd/tls/src/server/mod.rs | 116 ++++--- linkerd2-proxy/Cargo.toml | 5 +- 21 files changed, 2030 insertions(+), 388 deletions(-) create mode 100644 linkerd/identity/src/imp/openssl.rs create mode 100644 linkerd/identity/src/imp/rustls.rs create mode 100644 linkerd/tls/src/imp/boring.rs create mode 100644 linkerd/tls/src/imp/openssl.rs create mode 100644 linkerd/tls/src/imp/rustls.rs create mode 100644 linkerd/tls/src/protocol.rs diff --git a/.gitignore b/.gitignore index c9a1e9c950..eb9c94e832 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ target **/target **/corpus **/artifacts + +.idea/ +.vscode/ \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index daacdffce9..3b8d01cca2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ members = [ [profile.dev] debug = false [profile.test] -debug = false +debug = true [patch.crates-io] trust-dns-proto = { git = "https://github.com/bluejekyll/trust-dns", branch = "main" } diff --git a/linkerd/app/Cargo.toml b/linkerd/app/Cargo.toml index 9cef22c60d..d738cd2f7d 100644 --- a/linkerd/app/Cargo.toml +++ b/linkerd/app/Cargo.toml @@ -13,6 +13,9 @@ This is used by tests and the executable. [features] allow-loopback = ["linkerd-app-outbound/allow-loopback"] +openssl-tls = ["linkerd-app-core/openssl-tls"] +boring-tls = ["linkerd-app-core/boring-tls"] +rustls-tls = ["linkerd-app-core/rustls-tls"] [dependencies] futures = "0.3.9" diff --git a/linkerd/app/core/Cargo.toml b/linkerd/app/core/Cargo.toml index aec1e39869..1279a22d2d 100644 --- a/linkerd/app/core/Cargo.toml +++ b/linkerd/app/core/Cargo.toml @@ -12,6 +12,11 @@ This crate conglomerates proxy configuration, runtime administration, etc, independently of the inbound and outbound proxy logic. """ +[features] +rustls-tls = ["linkerd-identity/rustls-tls", "linkerd-tls/rustls-tls"] +openssl-tls = ["linkerd-identity/openssl-tls", "linkerd-tls/openssl-tls"] +boring-tls = ["linkerd-identity/boring-tls", "linkerd-tls/boring-tls"] + [dependencies] bytes = "1" http = "0.2" diff --git a/linkerd/app/inbound/src/direct.rs b/linkerd/app/inbound/src/direct.rs index 3386e3339e..6d51855f87 100644 --- a/linkerd/app/inbound/src/direct.rs +++ b/linkerd/app/inbound/src/direct.rs @@ -230,9 +230,7 @@ impl svc::Param for WithTransportHeaderAlpn { // be preferable if rustls::ServerConfig wrapped individual fields in an // Arc so they could be overridden independently. let mut config = self.0.server_config().as_ref().clone(); - config - .alpn_protocols - .push(transport_header::PROTOCOL.into()); + config.add_protocols(transport_header::PROTOCOL.into()); config.into() } } diff --git a/linkerd/dns/name/src/name.rs b/linkerd/dns/name/src/name.rs index 4868295c21..c1437cdf39 100644 --- a/linkerd/dns/name/src/name.rs +++ b/linkerd/dns/name/src/name.rs @@ -25,8 +25,7 @@ impl Name { impl fmt::Debug for Name { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - let s: &str = AsRef::::as_ref(&self.0); - s.fmt(f) + fmt::Display::fmt(self, f) } } @@ -93,6 +92,7 @@ mod tests { ]; for (host, expected_result) in cases { let dns_name = Name::try_from(host.as_bytes()).unwrap(); + println!("Hello {:?}", dns_name); assert_eq!(dns_name.is_localhost(), *expected_result, "{:?}", dns_name) } } diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 9c254813a5..54a90cc090 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -6,15 +6,19 @@ license = "Apache-2.0" edition = "2018" [features] -default = [] +default = ["rustls-tls"] test-util = [] +rustls-tls = ["ring", "rustls"] +openssl-tls = ["openssl"] +boring-tls = ["boring"] [dependencies] linkerd-dns-name = { path = "../dns/name" } -ring = "0.16.19" -rustls = "0.19" +ring = { version = "0.16.19", optional = true } +rustls = { version = "0.19", optional = true } thiserror = "1.0" tracing = "0.1.2" untrusted = "0.7" webpki = "=0.21.4" - +openssl = { version = "0.10.32", optional = true } +boring = { version = "1.1.2", optional = true } diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs new file mode 100644 index 0000000000..0b68b7021f --- /dev/null +++ b/linkerd/identity/src/imp/openssl.rs @@ -0,0 +1,345 @@ +use std::sync::Arc; +use std::time::SystemTime; +use std::{error, fmt}; + +// #[cfg(feature = "boring-tls")] +// use boring::{ +// error::ErrorStack, +// pkey::{PKey, Private}, +// stack::Stack, +// x509::{ +// {X509, X509StoreContext, X509VerifyResult}, +// store::{X509Store, X509StoreBuilder}, +// }, +// }; +// #[cfg(not(feature = "boring-tls"))] +use openssl::{ + error::ErrorStack, + pkey::{PKey, Private}, + stack::Stack, + x509::{ + store::{X509Store, X509StoreBuilder}, + {X509StoreContext, X509VerifyResult, X509}, + }, +}; + +use tracing::{debug, warn}; + +use crate::{LocalId, Name}; +use std::fmt::Formatter; + +#[derive(Clone, Debug)] +pub struct Key(pub Arc>); + +impl Key { + pub fn from_pkcs8(b: &[u8]) -> Result { + let key = PKey::private_key_from_pkcs8(b)?; + Ok(Key(Arc::new(key))) + } +} + +#[derive(Clone, Debug)] +pub struct Error(ErrorStack); + +impl From for Error { + fn from(err: ErrorStack) -> Self { + Self(err) + } +} + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + self.0.source() + } +} + +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self, fmt) + } +} + +#[derive(Clone)] +pub struct TrustAnchors(Arc); + +impl TrustAnchors { + #[cfg(any(test, feature = "test-util"))] + pub fn empty() -> Self { + Self(Arc::new(X509StoreBuilder::new().unwrap().build())) + } + + pub fn from_pem(s: &str) -> Option { + debug!("Loading {} into x509", s); + let mut store = X509StoreBuilder::new().unwrap(); + + match X509::from_pem(s.as_bytes()) { + Ok(cert) => { + debug!("Adding trust {:?}", cert); + store.add_cert(cert).unwrap(); + } + Err(err) => warn!("unable to construct trust anchor {}", err), + } + + Some(Self(Arc::new(store.build()))) + } + + pub fn certify(&self, key: Key, crt: Crt) -> Result { + let cert = crt.cert.clone(); + if cert + .subject_alt_names() + .unwrap() + .iter() + .filter(|n| n.dnsname().unwrap().to_string() == crt.id.to_string()) + .next() + .is_none() + { + return Err(InvalidCrt::SubjectAltName(crt.id.to_string())); + } + + let mut chain = Stack::new().unwrap(); + chain.push(cert.clone()).unwrap(); + for chain_crt in crt.chain.clone() { + chain.push(chain_crt).unwrap(); + } + + let mut context = X509StoreContext::new().unwrap(); + match context.init(&self.0, &cert, &chain, |c| match c.verify_cert() { + Ok(true) => Ok(Ok(true)), + Ok(false) => Ok(Err(InvalidCrt::Verify(c.error()))), + Err(err) => Err(err), + }) { + Ok(verify) => { + let server_config = + ServerConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); + let client_config = + ClientConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); + + match verify { + Ok(_) => Ok(CrtKey { + id: crt.id.clone(), + expiry: crt.expiry.clone(), + client_config: Arc::new(client_config), + server_config: Arc::new(server_config), + }), + Err(err) => Err(err), + } + } + Err(err) => Err(err.into()), + } + } + + pub fn client_config(&self) -> Arc { + println!("Returning empty client config"); + Arc::new(ClientConfig::new(vec![], self.0.clone(), None, None)) + } +} + +impl fmt::Debug for TrustAnchors { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "OpenSSL trust anchors") + } +} + +#[derive(Clone, Debug)] +pub enum InvalidCrt { + SubjectAltName(String), + Verify(X509VerifyResult), + General(Error), +} + +impl From for InvalidCrt { + fn from(err: Error) -> Self { + InvalidCrt::General(err) + } +} + +impl From for InvalidCrt { + fn from(err: ErrorStack) -> Self { + InvalidCrt::General(err.into()) + } +} + +impl fmt::Display for InvalidCrt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + InvalidCrt::SubjectAltName(name) => write!(f, "Subject alt name incorrect {}", name), + InvalidCrt::Verify(err) => err.fmt(f), + InvalidCrt::General(err) => err.fmt(f), + } + } +} + +impl error::Error for InvalidCrt { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + InvalidCrt::Verify(err) => err.source(), + InvalidCrt::General(err) => err.source(), + _ => None, + } + } +} + +#[derive(Clone)] +pub struct CrtKey { + id: LocalId, + expiry: SystemTime, + client_config: Arc, + server_config: Arc, +} + +// === CrtKey === +impl CrtKey { + pub fn name(&self) -> &Name { + self.id.as_ref() + } + + pub fn expiry(&self) -> SystemTime { + self.expiry + } + + pub fn id(&self) -> &LocalId { + &self.id + } + + pub fn client_config(&self) -> Arc { + self.client_config.clone() + } + + pub fn server_config(&self) -> Arc { + self.server_config.clone() + } +} + +impl fmt::Debug for CrtKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_struct("CrtKey") + .field("id", &self.id) + .field("expiry", &self.expiry) + .finish() + } +} + +#[derive(Clone, Debug)] +pub struct Crt { + pub(crate) id: LocalId, + expiry: SystemTime, + pub cert: X509, + pub chain: Vec, +} + +impl Crt { + pub fn new( + id: LocalId, + leaf: Vec, + intermediates: Vec>, + expiry: SystemTime, + ) -> Self { + let mut chain = Vec::with_capacity(intermediates.len() + 1); + let cert = X509::from_der(&leaf).unwrap(); + chain.extend( + intermediates + .into_iter() + .map(|crt| X509::from_der(&crt).unwrap()), + ); + + Self { + id, + cert, + chain, + expiry, + } + } + + pub fn name(&self) -> &Name { + self.id.as_ref() + } +} + +#[derive(Clone)] +pub struct ClientConfig { + pub root_certs: Arc, + pub key: Option>, + pub cert: Option>, + pub protocols: Arc>>, +} + +impl fmt::Debug for ClientConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.protocols, f) + } +} + +impl ClientConfig { + pub fn new( + protocols: Vec>, + root_certs: Arc, + cert: Option, + key: Option, + ) -> Self { + Self { + root_certs, + protocols: Arc::new(protocols), + key: key.map(Arc::new), + cert: cert.map(Arc::new), + } + } + pub fn empty() -> Self { + ClientConfig::new( + Vec::new(), + Arc::new(X509StoreBuilder::new().unwrap().build()), + None, + None, + ) + } + + pub fn set_protocols(&mut self, protocols: Vec>) { + self.protocols = Arc::new(protocols) + } +} + +#[derive(Clone)] +pub struct ServerConfig { + pub root_certs: Arc, + pub key: Option>, + pub cert: Option>, + pub alpn_protocols: Arc>>, +} + +impl ServerConfig { + pub fn new( + alpn_protocols: Vec>, + root_certs: Arc, + cert: Option, + key: Option, + ) -> Self { + Self { + alpn_protocols: Arc::new(alpn_protocols), + root_certs, + key: key.map(Arc::new), + cert: cert.map(Arc::new), + } + } + /// Produces a server config that fails to handshake all connections. + pub fn empty() -> Self { + ServerConfig::new( + Vec::new(), + Arc::new(X509StoreBuilder::new().unwrap().build()), + None, + None, + ) + } + + pub fn add_protocols(&mut self, protocols: Vec) { + self.alpn_protocols.as_ref().clone().push(protocols) + } +} + +impl fmt::Debug for ServerConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "alpn_protocols: {:?}, key: {:?}", + self.alpn_protocols, self.key + ) + } +} diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs new file mode 100644 index 0000000000..ed20f8c19f --- /dev/null +++ b/linkerd/identity/src/imp/rustls.rs @@ -0,0 +1,415 @@ +use crate::{LocalId, Name}; +use ring::error::KeyRejected; +use ring::rand; +use ring::signature::EcdsaKeyPair; +use std::sync::Arc; +use std::time::SystemTime; +use std::{error, fmt}; +use tracing::{debug, warn}; + +// These must be kept in sync: +static SIGNATURE_ALG_RING_SIGNING: &ring::signature::EcdsaSigningAlgorithm = + &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING; +const SIGNATURE_ALG_RUSTLS_SCHEME: rustls::SignatureScheme = + rustls::SignatureScheme::ECDSA_NISTP256_SHA256; +const SIGNATURE_ALG_RUSTLS_ALGORITHM: rustls::internal::msgs::enums::SignatureAlgorithm = + rustls::internal::msgs::enums::SignatureAlgorithm::ECDSA; +const TLS_VERSIONS: &[rustls::ProtocolVersion] = &[ + rustls::ProtocolVersion::TLSv1_2, + rustls::ProtocolVersion::TLSv1_3, +]; + +struct SigningKey(Arc); +struct Signer(Arc); + +#[derive(Clone, Debug)] +pub struct Key(Arc); + +impl Key { + pub fn from_pkcs8(b: &[u8]) -> Result { + let k = EcdsaKeyPair::from_pkcs8(SIGNATURE_ALG_RING_SIGNING, b)?; + Ok(Key(Arc::new(k))) + } +} + +pub struct Error(KeyRejected); + +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + None + } +} + +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, fmt) + } +} + +impl fmt::Debug for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.0, fmt) + } +} + +impl From for Error { + fn from(error: ring::error::KeyRejected) -> Error { + Error(error) + } +} + +#[derive(Clone)] +pub struct TrustAnchors(Arc); + +impl TrustAnchors { + #[cfg(any(test, feature = "test-util"))] + pub fn empty() -> Self { + TrustAnchors(Arc::new(ClientConfig(rustls::ClientConfig::new()))) + } + + pub fn from_pem(s: &str) -> Option { + use std::io::Cursor; + + let mut roots = rustls::RootCertStore::empty(); + let (added, skipped) = roots.add_pem_file(&mut Cursor::new(s)).ok()?; + if skipped != 0 { + warn!("skipped {} trust anchors in trust anchors file", skipped); + } + if added == 0 { + return None; + } + + let mut c = rustls::ClientConfig::new(); + + // XXX: Rustls's built-in verifiers don't let us tweak things as fully + // as we'd like (e.g. controlling the set of trusted signature + // algorithms), but they provide good enough defaults for now. + // TODO: lock down the verification further. + // TODO: Change Rustls's API to Avoid needing to clone `root_cert_store`. + c.root_store = roots; + + // Disable session resumption for the time-being until resumption is + // more tested. + c.enable_tickets = false; + + Some(TrustAnchors(Arc::new(ClientConfig(c)))) + } + + pub fn certify(&self, key: Key, crt: Crt) -> Result { + let mut client = self.0.as_ref().clone().as_ref().clone(); + + // Ensure the certificate is valid for the services we terminate for + // TLS. This assumes that server cert validation does the same or + // more validation than client cert validation. + // + // XXX: Rustls currently only provides access to a + // `ServerCertVerifier` through + // `rustls::ClientConfig::get_verifier()`. + // + // XXX: Once `rustls::ServerCertVerified` is exposed in Rustls's + // safe API, use it to pass proof to CertCertResolver::new.... + // + // TODO: Restrict accepted signature algorithms. + static NO_OCSP: &[u8] = &[]; + client + .get_verifier() + .verify_server_cert(&client.root_store, &crt.chain, (&crt.id).into(), NO_OCSP) + .map_err(InvalidCrt)?; + + let k = SigningKey(key.0); + let key = rustls::sign::CertifiedKey::new(crt.chain, Arc::new(Box::new(k))); + let resolver = Arc::new(CertResolver(key)); + + // Enable client authentication. + client.client_auth_cert_resolver = resolver.clone(); + + // Ask TLS clients for a certificate and accept any certificate issued + // by our trusted CA(s). + // + // XXX: Rustls's built-in verifiers don't let us tweak things as fully + // as we'd like (e.g. controlling the set of trusted signature + // algorithms), but they provide good enough defaults for now. + // TODO: lock down the verification further. + // + // TODO: Change Rustls's API to Avoid needing to clone `root_cert_store`. + let mut server = rustls::ServerConfig::new( + rustls::AllowAnyAnonymousOrAuthenticatedClient::new(client.root_store.clone()), + ); + server.versions = TLS_VERSIONS.to_vec(); + server.cert_resolver = resolver; + + Ok(CrtKey { + id: crt.id, + expiry: crt.expiry, + client_config: Arc::new(ClientConfig(client)), + server_config: Arc::new(ServerConfig(server)), + }) + } + + pub fn client_config(&self) -> Arc { + self.0.clone() + } +} + +impl fmt::Debug for TrustAnchors { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("TrustAnchors") + .field(self.0.as_ref()) + .finish() + } +} + +#[derive(Clone, Debug)] +pub struct InvalidCrt(rustls::TLSError); + +impl fmt::Display for InvalidCrt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl error::Error for InvalidCrt { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + self.0.source() + } +} + +impl rustls::sign::SigningKey for SigningKey { + fn choose_scheme( + &self, + offered: &[rustls::SignatureScheme], + ) -> Option> { + if offered.contains(&SIGNATURE_ALG_RUSTLS_SCHEME) { + Some(Box::new(Signer(self.0.clone()))) + } else { + None + } + } + + fn algorithm(&self) -> rustls::internal::msgs::enums::SignatureAlgorithm { + SIGNATURE_ALG_RUSTLS_ALGORITHM + } +} + +impl rustls::sign::Signer for Signer { + fn sign(&self, message: &[u8]) -> Result, rustls::TLSError> { + let rng = rand::SystemRandom::new(); + self.0 + .sign(&rng, message) + .map(|signature| signature.as_ref().to_owned()) + .map_err(|ring::error::Unspecified| { + rustls::TLSError::General("Signing Failed".to_owned()) + }) + } + + fn get_scheme(&self) -> rustls::SignatureScheme { + SIGNATURE_ALG_RUSTLS_SCHEME + } +} + +#[derive(Clone)] +pub struct CrtKey { + id: LocalId, + expiry: SystemTime, + client_config: Arc, + server_config: Arc, +} + +// === CrtKey === +impl CrtKey { + pub fn name(&self) -> &Name { + self.id.as_ref() + } + + pub fn expiry(&self) -> SystemTime { + self.expiry + } + + pub fn id(&self) -> &LocalId { + &self.id + } + + pub fn client_config(&self) -> Arc { + self.client_config.clone() + } + + pub fn server_config(&self) -> Arc { + self.server_config.clone() + } +} + +impl fmt::Debug for CrtKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_struct("CrtKey") + .field("id", &self.id) + .field("expiry", &self.expiry) + .finish() + } +} + +pub struct CertResolver(rustls::sign::CertifiedKey); + +impl rustls::ResolvesClientCert for CertResolver { + fn resolve( + &self, + _acceptable_issuers: &[&[u8]], + sigschemes: &[rustls::SignatureScheme], + ) -> Option { + // The proxy's server-side doesn't send the list of acceptable issuers so + // don't bother looking at `_acceptable_issuers`. + self.resolve_(sigschemes) + } + + fn has_certs(&self) -> bool { + true + } +} + +impl CertResolver { + fn resolve_( + &self, + sigschemes: &[rustls::SignatureScheme], + ) -> Option { + if !sigschemes.contains(&SIGNATURE_ALG_RUSTLS_SCHEME) { + debug!("signature scheme not supported -> no certificate"); + return None; + } + Some(self.0.clone()) + } +} + +impl rustls::ResolvesServerCert for CertResolver { + fn resolve(&self, hello: rustls::ClientHello<'_>) -> Option { + let server_name = if let Some(server_name) = hello.server_name() { + server_name + } else { + debug!("no SNI -> no certificate"); + return None; + }; + + // Verify that our certificate is valid for the given SNI name. + let c = (&self.0.cert) + .first() + .map(rustls::Certificate::as_ref) + .unwrap_or(&[]); // An empty input will fail to parse. + if let Err(err) = + webpki::EndEntityCert::from(c).and_then(|c| c.verify_is_valid_for_dns_name(server_name)) + { + debug!( + "our certificate is not valid for the SNI name -> no certificate: {:?}", + err + ); + return None; + } + + self.resolve_(hello.sigschemes()) + } +} + +#[derive(Clone, Debug)] +pub struct Crt { + pub(crate) id: LocalId, + expiry: SystemTime, + chain: Vec, +} + +impl Crt { + pub fn new( + id: LocalId, + leaf: Vec, + intermediates: Vec>, + expiry: SystemTime, + ) -> Self { + let mut chain = Vec::with_capacity(intermediates.len() + 1); + chain.push(rustls::Certificate(leaf)); + chain.extend(intermediates.into_iter().map(rustls::Certificate)); + + Self { id, chain, expiry } + } + + pub fn name(&self) -> &Name { + self.id.as_ref() + } +} + +#[derive(Clone)] +pub struct ClientConfig(rustls::ClientConfig); + +impl ClientConfig { + pub fn empty() -> Self { + Self(rustls::ClientConfig::new()) + } + + pub fn set_protocols(&mut self, protocols: Vec>) { + self.0.set_protocols(&*protocols) + } +} + +impl Into> for ClientConfig { + fn into(self) -> Arc { + Arc::new(self.into()) + } +} + +impl Into for ClientConfig { + fn into(self) -> rustls::ClientConfig { + self.0 + } +} + +impl AsRef for ClientConfig { + fn as_ref(&self) -> &rustls::ClientConfig { + &self.0 + } +} + +impl fmt::Debug for ClientConfig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("") + .field("alpn", &self.0.alpn_protocols) + .field("protocols", &self.0.versions) + .finish() + } +} + +#[derive(Clone)] +pub struct ServerConfig(rustls::ServerConfig); + +impl ServerConfig { + /// Produces a server config that fails to handshake all connections. + pub fn empty() -> Self { + let verifier = rustls::NoClientAuth::new(); + Self(rustls::ServerConfig::new(verifier)) + } + + pub fn add_protocols(&mut self, protocols: Vec) { + self.0.alpn_protocols.push(protocols) + } +} + +impl Into> for ServerConfig { + fn into(self) -> Arc { + Arc::new(self.into()) + } +} + +impl Into for ServerConfig { + fn into(self) -> rustls::ServerConfig { + self.0 + } +} + +impl AsRef for ServerConfig { + fn as_ref(&self) -> &rustls::ServerConfig { + &self.0 + } +} + +impl fmt::Debug for ServerConfig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("") + .field("alpn", &self.0.alpn_protocols) + .field("protocols", &self.0.versions) + .finish() + } +} \ No newline at end of file diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index bf4b428461..0c1391f715 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -2,13 +2,17 @@ #![forbid(unsafe_code)] #![allow(clippy::inconsistent_struct_constructor)] -pub use ring::error::KeyRejected; -use ring::rand; -use ring::signature::EcdsaKeyPair; use std::{convert::TryFrom, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime}; use thiserror::Error; use tracing::{debug, warn}; +#[cfg(feature = "rustls-tls")] +#[path = "imp/rustls.rs"] +mod imp; +#[cfg(not(feature = "rustls-tls"))] +#[path = "imp/openssl.rs"] +mod imp; + #[cfg(any(test, feature = "test-util"))] pub mod test_util; @@ -18,58 +22,61 @@ pub use linkerd_dns_name::InvalidName; #[derive(Clone, Debug)] pub struct Csr(Arc>); -/// An endpoint's identity. -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct Name(Arc); +/// An error returned from the TLS implementation. +pub struct Error(imp::Error); -#[derive(Clone, Debug)] -pub struct Key(Arc); +impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + error::Error::source(&self.0) + } +} -struct SigningKey(Arc); -struct Signer(Arc); +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, fmt) + } +} -#[derive(Clone)] -pub struct TrustAnchors(Arc); +impl fmt::Debug for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.0, fmt) + } +} -#[derive(Clone, Debug)] -pub struct TokenSource(Arc); +impl From for Error { + fn from(err: imp::Error) -> Error { + Error(err) + } +} #[derive(Clone, Debug)] -pub struct Crt { - id: LocalId, - expiry: SystemTime, - chain: Vec, -} +pub struct Key(imp::Key); -#[derive(Clone)] -pub struct CrtKey { - id: LocalId, - expiry: SystemTime, - client_config: Arc, - server_config: Arc, -} +#[derive(Clone, Debug)] +pub struct TokenSource(Arc); -struct CertResolver(rustls::sign::CertifiedKey); +#[derive(Clone, Debug)] +pub struct Crt(imp::Crt); #[derive(Clone, Debug, Error)] #[error(transparent)] -pub struct InvalidCrt(rustls::TLSError); +pub struct InvalidCrt(imp::InvalidCrt); + +impl From for InvalidCrt { + fn from(err: imp::InvalidCrt) -> Self { + InvalidCrt(err) + } +} /// A newtype for local server identities. #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct LocalId(pub Name); -// These must be kept in sync: -static SIGNATURE_ALG_RING_SIGNING: &ring::signature::EcdsaSigningAlgorithm = - &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING; -const SIGNATURE_ALG_RUSTLS_SCHEME: rustls::SignatureScheme = - rustls::SignatureScheme::ECDSA_NISTP256_SHA256; -const SIGNATURE_ALG_RUSTLS_ALGORITHM: rustls::internal::msgs::enums::SignatureAlgorithm = - rustls::internal::msgs::enums::SignatureAlgorithm::ECDSA; -const TLS_VERSIONS: &[rustls::ProtocolVersion] = &[ - rustls::ProtocolVersion::TLSv1_2, - rustls::ProtocolVersion::TLSv1_3, -]; +impl<'t> Into> for &'t LocalId { + fn into(self) -> webpki::DNSNameRef<'t> { + (&self.0).into() + } +} // === impl Csr === @@ -90,50 +97,32 @@ impl Csr { // === impl Key === impl Key { - pub fn from_pkcs8(b: &[u8]) -> Result { - let k = EcdsaKeyPair::from_pkcs8(SIGNATURE_ALG_RING_SIGNING, b)?; - Ok(Key(Arc::new(k))) + pub fn from_pkcs8(b: &[u8]) -> Result { + let key = imp::Key::from_pkcs8(b)?; + Ok(Key(key)) } } -impl rustls::sign::SigningKey for SigningKey { - fn choose_scheme( - &self, - offered: &[rustls::SignatureScheme], - ) -> Option> { - if offered.contains(&SIGNATURE_ALG_RUSTLS_SCHEME) { - Some(Box::new(Signer(self.0.clone()))) - } else { - None - } - } +// === impl Name === +/// An endpoint's identity. +#[derive(Clone, Eq, PartialEq, Hash)] +pub struct Name(Arc); - fn algorithm(&self) -> rustls::internal::msgs::enums::SignatureAlgorithm { - SIGNATURE_ALG_RUSTLS_ALGORITHM +impl From for Name { + fn from(n: linkerd_dns_name::Name) -> Self { + Name(Arc::new(n)) } } -impl rustls::sign::Signer for Signer { - fn sign(&self, message: &[u8]) -> Result, rustls::TLSError> { - let rng = rand::SystemRandom::new(); - self.0 - .sign(&rng, message) - .map(|signature| signature.as_ref().to_owned()) - .map_err(|ring::error::Unspecified| { - rustls::TLSError::General("Signing Failed".to_owned()) - }) - } - - fn get_scheme(&self) -> rustls::SignatureScheme { - SIGNATURE_ALG_RUSTLS_SCHEME +impl Into for Name { + fn into(self) -> linkerd_dns_name::Name { + self.0.as_ref().clone() } } -// === impl Name === - -impl From for Name { - fn from(n: linkerd_dns_name::Name) -> Self { - Name(Arc::new(n)) +impl From<&Name> for Name { + fn from(n: &Name) -> Self { + Self(n.0.clone()) } } @@ -210,102 +199,31 @@ impl TokenSource { } } -// === impl TrustAnchors === +// === TrustAnchors === +#[derive(Clone, Debug)] +pub struct TrustAnchors(imp::TrustAnchors); impl TrustAnchors { #[cfg(any(test, feature = "test-util"))] fn empty() -> Self { - TrustAnchors(Arc::new(rustls::ClientConfig::new())) + TrustAnchors(imp::TrustAnchors::empty()) } - pub fn from_pem(s: &str) -> Option { - use std::io::Cursor; - - let mut roots = rustls::RootCertStore::empty(); - let (added, skipped) = roots.add_pem_file(&mut Cursor::new(s)).ok()?; - if skipped != 0 { - warn!("skipped {} trust anchors in trust anchors file", skipped); + pub fn from_pem(s: &str) -> Option { + match imp::TrustAnchors::from_pem(s) { + None => None, + Some(ta) => Some(TrustAnchors(ta)), } - if added == 0 { - return None; - } - - let mut c = rustls::ClientConfig::new(); - - // XXX: Rustls's built-in verifiers don't let us tweak things as fully - // as we'd like (e.g. controlling the set of trusted signature - // algorithms), but they provide good enough defaults for now. - // TODO: lock down the verification further. - // TODO: Change Rustls's API to Avoid needing to clone `root_cert_store`. - c.root_store = roots; - - // Disable session resumption for the time-being until resumption is - // more tested. - c.enable_tickets = false; - - Some(TrustAnchors(Arc::new(c))) } pub fn certify(&self, key: Key, crt: Crt) -> Result { - let mut client = self.0.as_ref().clone(); - - // Ensure the certificate is valid for the services we terminate for - // TLS. This assumes that server cert validation does the same or - // more validation than client cert validation. - // - // XXX: Rustls currently only provides access to a - // `ServerCertVerifier` through - // `rustls::ClientConfig::get_verifier()`. - // - // XXX: Once `rustls::ServerCertVerified` is exposed in Rustls's - // safe API, use it to pass proof to CertCertResolver::new.... - // - // TODO: Restrict accepted signatutre algorithms. - static NO_OCSP: &[u8] = &[]; - client - .get_verifier() - .verify_server_cert(&client.root_store, &crt.chain, (&crt.id).into(), NO_OCSP) - .map_err(InvalidCrt)?; - debug!("certified {}", crt.id); - - let k = SigningKey(key.0); - let key = rustls::sign::CertifiedKey::new(crt.chain, Arc::new(Box::new(k))); - let resolver = Arc::new(CertResolver(key)); - - // Enable client authentication. - client.client_auth_cert_resolver = resolver.clone(); - - // Ask TLS clients for a certificate and accept any certificate issued - // by our trusted CA(s). - // - // XXX: Rustls's built-in verifiers don't let us tweak things as fully - // as we'd like (e.g. controlling the set of trusted signature - // algorithms), but they provide good enough defaults for now. - // TODO: lock down the verification further. - // - // TODO: Change Rustls's API to Avoid needing to clone `root_cert_store`. - let mut server = rustls::ServerConfig::new( - rustls::AllowAnyAnonymousOrAuthenticatedClient::new(self.0.root_store.clone()), - ); - server.versions = TLS_VERSIONS.to_vec(); - server.cert_resolver = resolver; - - Ok(CrtKey { - id: crt.id, - expiry: crt.expiry, - client_config: Arc::new(client), - server_config: Arc::new(server), - }) - } - - pub fn client_config(&self) -> Arc { - self.0.clone() - } -} - -impl fmt::Debug for TrustAnchors { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TrustAnchors").finish() + let key = self.0.certify(key.0, crt.0).map(CrtKey)?; + debug!("Certified {}", key.id()); + Ok(key) + } + + pub fn client_config(&self) -> Arc { + Arc::new(ClientConfig(self.0.client_config().as_ref().clone())) } } @@ -318,139 +236,120 @@ impl Crt { intermediates: Vec>, expiry: SystemTime, ) -> Self { - let mut chain = Vec::with_capacity(intermediates.len() + 1); - chain.push(rustls::Certificate(leaf)); - chain.extend(intermediates.into_iter().map(rustls::Certificate)); - - Self { id, chain, expiry } + Self(imp::Crt::new(id, leaf, intermediates, expiry)) } pub fn name(&self) -> &Name { - self.id.as_ref() + self.0.name() } } impl From<&'_ Crt> for LocalId { fn from(crt: &Crt) -> LocalId { - crt.id.clone() + crt.0.id.clone() } } // === CrtKey === +#[derive(Clone, Debug)] +pub struct CrtKey(imp::CrtKey); impl CrtKey { pub fn name(&self) -> &Name { - self.id.as_ref() + self.0.name() } pub fn expiry(&self) -> SystemTime { - self.expiry + self.0.expiry() } pub fn id(&self) -> &LocalId { - &self.id + &self.0.id() } - pub fn client_config(&self) -> Arc { - self.client_config.clone() + pub fn client_config(&self) -> Arc { + Arc::new(ClientConfig(self.0.client_config().as_ref().clone())) } - pub fn server_config(&self) -> Arc { - self.server_config.clone() + pub fn server_config(&self) -> Arc { + Arc::new(ServerConfig(self.0.server_config().as_ref().clone())) } } -impl fmt::Debug for CrtKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.debug_struct("CrtKey") - .field("id", &self.id) - .field("expiry", &self.expiry) - .finish() +// === impl LocalId === + +impl From for LocalId { + fn from(n: Name) -> Self { + Self(n) } } -// === impl CertResolver === - -impl rustls::ResolvesClientCert for CertResolver { - fn resolve( - &self, - _acceptable_issuers: &[&[u8]], - sigschemes: &[rustls::SignatureScheme], - ) -> Option { - // The proxy's server-side doesn't send the list of acceptable issuers so - // don't bother looking at `_acceptable_issuers`. - self.resolve_(sigschemes) +impl From for Name { + fn from(LocalId(name): LocalId) -> Name { + name } +} - fn has_certs(&self) -> bool { - true +impl AsRef for LocalId { + fn as_ref(&self) -> &Name { + &self.0 } } -impl CertResolver { - fn resolve_( - &self, - sigschemes: &[rustls::SignatureScheme], - ) -> Option { - if !sigschemes.contains(&SIGNATURE_ALG_RUSTLS_SCHEME) { - debug!("signature scheme not supported -> no certificate"); - return None; - } - Some(self.0.clone()) +impl fmt::Display for LocalId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) } } -impl rustls::ResolvesServerCert for CertResolver { - fn resolve(&self, hello: rustls::ClientHello<'_>) -> Option { - let server_name = if let Some(server_name) = hello.server_name() { - server_name - } else { - debug!("no SNI -> no certificate"); - return None; - }; +// === impl InvalidCrt === - // Verify that our certificate is valid for the given SNI name. - let c = (&self.0.cert) - .first() - .map(rustls::Certificate::as_ref) - .unwrap_or(&[]); // An empty input will fail to parse. - if let Err(err) = - webpki::EndEntityCert::from(c).and_then(|c| c.verify_is_valid_for_dns_name(server_name)) - { - debug!( - "our certificate is not valid for the SNI name -> no certificate: {:?}", - err - ); - return None; - } +impl fmt::Display for InvalidCrt { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} - self.resolve_(hello.sigschemes()) +impl error::Error for InvalidCrt { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + self.0.source() } } -// === impl LocalId === +#[derive(Clone)] +pub struct ClientConfig(pub imp::ClientConfig); -impl From for LocalId { - fn from(n: Name) -> Self { - Self(n) +impl ClientConfig { + pub fn empty() -> Self { + Self(imp::ClientConfig::empty()) + } + pub fn set_protocols(&mut self, protocols: Vec>) { + self.0.set_protocols(protocols); } } -impl From for Name { - fn from(LocalId(name): LocalId) -> Name { - name +impl From for ClientConfig { + fn from(conf: imp::ClientConfig) -> Self { + Self(conf) } } -impl AsRef for LocalId { - fn as_ref(&self) -> &Name { - &self.0 +#[derive(Clone, Debug)] +pub struct ServerConfig(pub imp::ServerConfig); + +impl ServerConfig { + pub fn empty() -> Self { + Self(imp::ServerConfig::empty()) + } + + pub fn add_protocols(&mut self, protocols: Vec) { + self.0.add_protocols(protocols); } } -impl fmt::Display for LocalId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) +impl From for ServerConfig { + fn from(conf: imp::ServerConfig) -> Self { + Self(conf) } } diff --git a/linkerd/io/src/lib.rs b/linkerd/io/src/lib.rs index 76b001c0f7..3fee833b1f 100644 --- a/linkerd/io/src/lib.rs +++ b/linkerd/io/src/lib.rs @@ -65,18 +65,6 @@ impl PeerAddr for tokio::net::TcpStream { } } -impl PeerAddr for tokio_rustls::client::TlsStream { - fn peer_addr(&self) -> Result { - self.get_ref().0.peer_addr() - } -} - -impl PeerAddr for tokio_rustls::server::TlsStream { - fn peer_addr(&self) -> Result { - self.get_ref().0.peer_addr() - } -} - #[cfg(feature = "tokio-test")] impl PeerAddr for tokio_test::io::Mock { fn peer_addr(&self) -> Result { diff --git a/linkerd/proxy/identity/src/certify.rs b/linkerd/proxy/identity/src/certify.rs index 253cb88b18..579ff6893c 100644 --- a/linkerd/proxy/identity/src/certify.rs +++ b/linkerd/proxy/identity/src/certify.rs @@ -98,6 +98,7 @@ impl Daemon { } = self; debug!("Identity daemon running"); + let mut curr_expiry = UNIX_EPOCH; let mut client = api::identity_client::IdentityClient::new(client); diff --git a/linkerd/tls/Cargo.toml b/linkerd/tls/Cargo.toml index 06bb6228a7..e0d6942d3c 100644 --- a/linkerd/tls/Cargo.toml +++ b/linkerd/tls/Cargo.toml @@ -6,6 +6,12 @@ license = "Apache-2.0" edition = "2018" publish = false +[features] +default = ["rustls-tls"] +rustls-tls = ["linkerd-identity/rustls-tls", "rustls", "tokio-rustls"] +openssl-tls = ["linkerd-identity/openssl-tls", "openssl", "tokio-openssl"] +boring-tls = ["linkerd-identity/boring-tls", "boring", "tokio-boring"] + [dependencies] async-trait = "0.1" bytes = "1" @@ -16,10 +22,14 @@ linkerd-error = { path = "../error" } linkerd-identity = { path = "../identity" } linkerd-io = { path = "../io" } linkerd-stack = { path = "../stack" } -rustls = "0.19" -thiserror = "1.0" tokio = { version = "1", features = ["macros", "time"] } -tokio-rustls = "0.22" +rustls = { version = "0.19", optional = true } +tokio-rustls = { version = "0.22", optional = true } +tokio-openssl = { version = "0.6.1", optional = true } +openssl = { version = "0.10.32", optional = true } +boring = { version = "1.1.2", optional = true } +tokio-boring = { version = "2.1.1", optional = true } +thiserror = "1.0" tower = "0.4.7" tracing = "0.1.23" webpki = "0.21" diff --git a/linkerd/tls/src/client.rs b/linkerd/tls/src/client.rs index 0762f9b293..31f5cc3094 100644 --- a/linkerd/tls/src/client.rs +++ b/linkerd/tls/src/client.rs @@ -2,11 +2,11 @@ use futures::{ future::{Either, MapOk}, prelude::*, }; +use io::ReadBuf; use linkerd_conditional::Conditional; use linkerd_identity as id; use linkerd_io as io; use linkerd_stack::{layer, Param}; -use rustls::Session; use std::{ fmt, future::Future, @@ -15,9 +15,70 @@ use std::{ sync::Arc, task::{Context, Poll}, }; -pub use tokio_rustls::client::TlsStream; use tracing::{debug, trace}; +use crate::imp; +use crate::{HasNegotiatedProtocol, NegotiatedProtocolRef, TlsConnector}; + +#[derive(Debug)] +pub struct TlsStream(imp::client::TlsStream); + +impl TlsStream { + pub fn get_alpn_protocol(&self) -> Option<&[u8]> { + self.0.get_alpn_protocol() + } +} + +impl From> for TlsStream { + fn from(stream: imp::client::TlsStream) -> Self { + TlsStream(stream) + } +} + +impl io::AsyncRead for TlsStream +where + IO: io::AsyncRead + io::AsyncWrite + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } +} + +impl io::AsyncWrite for TlsStream +where + IO: io::AsyncRead + io::AsyncWrite + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } +} + +impl HasNegotiatedProtocol for TlsStream +where + IO: HasNegotiatedProtocol, +{ + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.0.negotiated_protocol() + } +} + /// A newtype for target server identities. #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct ServerId(pub id::Name); @@ -54,7 +115,7 @@ pub enum NoClientTls { /// known TLS identity. pub type ConditionalClientTls = Conditional; -pub type Config = Arc; +pub type Config = Arc; #[derive(Clone, Debug)] pub struct Client { @@ -128,11 +189,11 @@ where // TODO it would be better to avoid cloning the whole TLS config // per-connection. match alpn { - None => tokio_rustls::TlsConnector::from(local.param()), + None => TlsConnector::from(local.param()), Some(AlpnProtocols(protocols)) => { - let mut config: rustls::ClientConfig = local.param().as_ref().clone(); - config.alpn_protocols = protocols; - tokio_rustls::TlsConnector::from(Arc::new(config)) + let mut config: id::ClientConfig = local.param().as_ref().clone(); + config.set_protocols(protocols); + TlsConnector::from(Arc::new(config)) } } } @@ -147,7 +208,7 @@ where Either::Right(Box::pin(async move { let io = connect.await?; let io = handshake.connect((&server_id.0).into(), io).await?; - if let Some(alpn) = io.get_ref().1.get_alpn_protocol() { + if let Some(alpn) = io.get_alpn_protocol() { debug!(alpn = ?std::str::from_utf8(alpn)); } Ok(io::EitherIo::Right(io)) diff --git a/linkerd/tls/src/imp/boring.rs b/linkerd/tls/src/imp/boring.rs new file mode 100644 index 0000000000..f3b4861a91 --- /dev/null +++ b/linkerd/tls/src/imp/boring.rs @@ -0,0 +1,243 @@ +use crate::{ClientId, HasNegotiatedProtocol, NegotiatedProtocolRef}; +use linkerd_identity::{ClientConfig, Name, ServerConfig}; +use linkerd_io::{AsyncRead, AsyncWrite, Error, ErrorKind, PeerAddr, ReadBuf, Result}; +use std::net::SocketAddr; +use std::{ + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; + +use { + boring::{ + ssl, + ssl::{SslVerifyMode, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, SslMethod}, + x509::store::X509StoreBuilder, + }, + tokio_boring::SslStream, +}; +use tracing::debug; +use std::str::FromStr; + +#[derive(Clone)] +pub struct TlsConnector(ssl::SslConnector); + +impl TlsConnector { + pub async fn connect(&self, domain: Name, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + let conf = self + .0 + .configure() + .unwrap(); + match tokio_boring::connect(conf, domain.as_ref(), stream).await { + Ok(ss) => Ok(ss.into()), + Err(err) => { + let _ = err.ssl(); + Err(Error::new(ErrorKind::Other, "Ble")) + } + } + } +} + +impl From for TlsConnector { + fn from(connector: SslConnector) -> Self { + Self(connector) + } +} + +impl From for TlsConnector { + fn from(builder: SslConnectorBuilder) -> Self { + builder.build().into() + } +} + +impl From> for TlsConnector { + fn from(conf: Arc) -> Self { + println!("Setting up ssl connector"); + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + + match conf.0.key.clone() { + None => debug!("No private key provided"), + Some(key) => { + debug!("Setting private key {:?}", key); + builder.set_private_key(key.as_ref().0.as_ref()).unwrap(); + } + } + + match conf.0.cert.clone() { + None => debug!("No certificate provided"), + Some(cert) => { + println!("Setting certificate {:?}", cert); + builder.set_certificate(cert.cert.as_ref()).unwrap(); + + for cert in &cert.chain { + println!("Adding extra chain certificate {:?}", cert); + builder.add_extra_chain_cert(cert.clone()).unwrap() + } + } + } + + builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); + conf.0 + .root_certs + .objects() + .iter() + .map(|x| x.x509().unwrap().to_owned()) + .for_each(|cert| { + println!("Adding Root certificate {:?}", cert); + builder.cert_store_mut().add_cert(cert).unwrap() + }); + + builder.into() + } +} + +#[derive(Clone)] +pub struct TlsAcceptor(ssl::SslAcceptor); + +impl TlsAcceptor { + pub async fn accept(&self, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + match tokio_boring::accept(&self.0, stream).await { + Ok(ss) => Ok(ss.into()), + Err(err) => { + let _ = err.ssl(); + Err(Error::new(ErrorKind::Other, "Ble")) + } + } + } +} + +impl From for TlsAcceptor { + fn from(acceptor: SslAcceptor) -> Self { + Self(acceptor) + } +} + +impl From for TlsAcceptor { + fn from(builder: SslAcceptorBuilder) -> Self { + builder.build().into() + } +} + +impl From> for TlsAcceptor { + fn from(conf: Arc) -> Self { + println!("Setting up ssl acceptor with mozilla intermediate"); + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + + let key = conf.0.key.as_ref().unwrap().as_ref().0.as_ref(); + println!("Setting private key {:?}", key); + builder.set_private_key(key).unwrap(); + + let cert = conf.0.cert.as_ref().unwrap().as_ref(); + println!("Setting certificate {:?}", cert); + builder.set_certificate(cert.cert.as_ref()).unwrap(); + + for cert in &cert.chain { + println!("Adding extra chain certificate {:?}", cert); + builder.add_extra_chain_cert(cert.clone()).unwrap() + } + + builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); + conf.0 + .root_certs + .objects() + .iter() + .map(|x| x.x509().unwrap().to_owned()) + .for_each(|cert| { + println!("Adding Root certificate {:?}", cert); + builder.cert_store_mut().add_cert(cert).unwrap() + }); + + builder.set_verify(SslVerifyMode::PEER); + builder.check_private_key().unwrap(); + builder.build().into() + } +} + +#[derive(Debug)] +pub struct TlsStream(SslStream); + +impl TlsStream { + pub fn get_alpn_protocol(&self) -> Option<&[u8]> { + self.0.ssl().selected_alpn_protocol() + } + + pub fn client_identity(&self) -> Option { + let cert = self.0.ssl().peer_certificate()?; + let peer = cert.subject_alt_names()?.pop()?; + + match ClientId::from_str(peer.dnsname().unwrap()) { + Ok(client) => Some(client), + Err(_) => None, + } + } +} + +impl From> for TlsStream { + fn from(stream: SslStream) -> Self { + TlsStream(stream) + } +} + +impl PeerAddr for TlsStream { + fn peer_addr(&self) -> Result { + unimplemented!() + } +} + +impl HasNegotiatedProtocol for TlsStream { + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.0 + .ssl() + .selected_alpn_protocol() + .map(NegotiatedProtocolRef) + } +} + +impl AsyncRead for TlsStream +where + IO: AsyncRead + AsyncWrite + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } +} + +impl AsyncWrite for TlsStream +where + IO: AsyncRead + AsyncWrite + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0.get_mut()).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } +} + +pub mod client { + pub use super::TlsStream; +} + +pub mod server { + pub use super::TlsStream; +} diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs new file mode 100644 index 0000000000..14a29b3035 --- /dev/null +++ b/linkerd/tls/src/imp/openssl.rs @@ -0,0 +1,318 @@ +use crate::{ClientId, HasNegotiatedProtocol, NegotiatedProtocolRef}; +use linkerd_identity::{ClientConfig, Name, ServerConfig}; +use linkerd_io::{self as io, AsyncRead, AsyncWrite, ErrorKind, PeerAddr, ReadBuf, Result}; +use std::net::SocketAddr; +use std::{ + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; + +use openssl::ssl::SslVerifyMode; +use std::str::FromStr; +use { + openssl::{ + ssl, + ssl::{Ssl, SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod}, + x509::store::X509StoreBuilder, + }, + tokio_openssl::SslStream, +}; +use tracing::debug; + +#[derive(Clone)] +pub struct TlsConnector(ssl::SslConnector); + +impl TlsConnector { + pub async fn connect(&self, domain: Name, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + let ssl = self + .0 + .configure() + .unwrap() + .into_ssl(domain.as_ref()) + .unwrap(); + let mut s = TlsStream::new(ssl, stream); + match Pin::new(&mut s.0).connect().await { + Ok(_) => Ok(s), + Err(err) => Err(io::Error::new(ErrorKind::Other, err)), + } + } +} + +impl From for TlsConnector { + fn from(connector: SslConnector) -> Self { + Self(connector) + } +} + +impl From for TlsConnector { + fn from(builder: SslConnectorBuilder) -> Self { + builder.build().into() + } +} + +impl From> for TlsConnector { + fn from(conf: Arc) -> Self { + println!("Setting up ssl connector"); + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + + match conf.0.key.clone() { + None => debug!("No private key provided"), + Some(key) => { + debug!("Setting private key {:?}", key); + builder.set_private_key(key.as_ref().0.as_ref()).unwrap(); + } + } + + match conf.0.cert.clone() { + None => debug!("No certificate provided"), + Some(cert) => { + println!("Setting certificate {:?}", cert); + builder.set_certificate(cert.cert.as_ref()).unwrap(); + + for cert in &cert.chain { + println!("Adding extra chain certificate {:?}", cert); + builder.add_extra_chain_cert(cert.clone()).unwrap() + } + } + } + + builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); + conf.0 + .root_certs + .objects() + .iter() + .map(|x| x.x509().unwrap().to_owned()) + .for_each(|cert| { + println!("Adding Root certificate {:?}", cert); + builder.cert_store_mut().add_cert(cert).unwrap() + }); + + builder.into() + } +} + +#[derive(Clone)] +pub struct TlsAcceptor(ssl::SslAcceptor); + +impl TlsAcceptor { + pub async fn accept(&self, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + let ssl = Ssl::new(self.0.context()).unwrap(); + let mut s = TlsStream::new(ssl, stream); + + match Pin::new(&mut s.0).accept().await { + Ok(_) => Ok(s), + Err(err) => Err(io::Error::new(ErrorKind::Other, err)), + } + } +} + +impl From for TlsAcceptor { + fn from(acceptor: SslAcceptor) -> Self { + Self(acceptor) + } +} + +impl From> for TlsAcceptor { + fn from(conf: Arc) -> Self { + println!("Setting up ssl acceptor with mozilla intermediate"); + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); + + let key = conf.0.key.as_ref().unwrap().as_ref().0.as_ref(); + println!("Setting private key {:?}", key); + builder.set_private_key(key).unwrap(); + + let cert = conf.0.cert.as_ref().unwrap().as_ref(); + println!("Setting certificate {:?}", cert); + builder.set_certificate(cert.cert.as_ref()).unwrap(); + + for cert in &cert.chain { + println!("Adding extra chain certificate {:?}", cert); + builder.add_extra_chain_cert(cert.clone()).unwrap() + } + + builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); + conf.0 + .root_certs + .objects() + .iter() + .map(|x| x.x509().unwrap().to_owned()) + .for_each(|cert| { + println!("Adding Root certificate {:?}", cert); + builder.cert_store_mut().add_cert(cert).unwrap() + }); + + builder.set_verify(SslVerifyMode::PEER); + builder.check_private_key().unwrap(); + builder.build().into() + } +} + +#[derive(Debug)] +pub struct TlsStream(SslStream); + +impl TlsStream +where + IO: AsyncRead + AsyncWrite, +{ + pub fn new(ssl: Ssl, stream: IO) -> Self { + Self(SslStream::new(ssl, stream).unwrap()) + } +} + +impl TlsStream { + pub fn get_alpn_protocol(&self) -> Option<&[u8]> { + self.0.ssl().selected_alpn_protocol() + } + + pub fn client_identity(&self) -> Option { + let cert = self.0.ssl().peer_certificate()?; + let peer = cert.subject_alt_names()?.pop()?; + + match ClientId::from_str(peer.dnsname().unwrap()) { + Ok(client) => Some(client), + Err(_) => None, + } + } +} + +impl From> for TlsStream { + fn from(stream: SslStream) -> Self { + TlsStream(stream) + } +} + +impl PeerAddr for TlsStream { + fn peer_addr(&self) -> Result { + self.0.get_ref().peer_addr() + } +} + +impl HasNegotiatedProtocol for TlsStream { + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.0 + .ssl() + .selected_alpn_protocol() + .map(NegotiatedProtocolRef) + } +} + +impl AsyncRead for TlsStream +where + IO: AsyncRead + AsyncWrite + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } +} + +impl AsyncWrite for TlsStream +where + IO: AsyncRead + AsyncWrite + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } +} + +pub mod client { + pub use super::TlsStream; +} + +pub mod server { + pub use super::TlsStream; +} + +// mod tests { +// use super::TlsConnector; +// use crate::imp::TlsAcceptor; +// use linkerd_identity::{ClientConfig, Name, ServerConfig}; +// use linkerd_io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; +// use std::pin::Pin; +// use std::str::FromStr; +// use std::sync::Arc; +// use tokio::net::{TcpListener, TcpStream}; +// use std::net::ToSocketAddrs; +// +// #[tokio::test] +// async fn google() { +// let addr = "google.com:443".to_socket_addrs().unwrap().next().unwrap(); +// let stream = TcpStream::connect(&addr).await.unwrap(); +// let connector = TlsConnector::from(Arc::new(ClientConfig::empty())); +// let domain = Name::from_str("google.com").unwrap(); +// let mut stream = connector.connect(domain, stream).await.unwrap(); +// +// stream.write_all(b"GET / HTTP/1.0\r\n\r\n").await.unwrap(); +// +// let mut buf = vec![]; +// stream.read_to_end(&mut buf).await.unwrap(); +// let response = String::from_utf8_lossy(&buf); +// let response = response.trim_end(); + +// any response code is fine +// assert!(response.starts_with("HTTP/1.0 ")); +// assert!(response.ends_with("") || response.ends_with("")); +// } +// +// #[tokio::test] +// async fn server() { +// let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); +// let addr = listener.local_addr().unwrap(); +// +// let server = async move { +// let acceptor = TlsAcceptor::from(Arc::new(ServerConfig::empty())); +// +// let stream = listener.accept().await.unwrap().0; +// let mut stream = acceptor.accept(stream).await.unwrap(); +// +// let mut buf = [0; 4]; +// stream.read_exact(&mut buf).await.unwrap(); +// assert_eq!(&buf, b"asdf"); +// +// stream.write_all(b"jkl;").await.unwrap(); +// +// futures::future::poll_fn(|ctx| Pin::new(&mut stream).poll_shutdown(ctx)) +// .await +// .unwrap() +// }; +// +// let client = async { +// let connector = TlsConnector::from(Arc::new(ClientConfig::empty())); +// let name = Name::from_str("localhost").unwrap(); +// +// let stream = TcpStream::connect(&addr).await.unwrap(); +// let mut stream = connector.connect(name, stream).await.unwrap(); +// +// stream.write_all(b"asdf").await.unwrap(); +// +// let mut buf = vec![]; +// stream.read_to_end(&mut buf).await.unwrap(); +// assert_eq!(buf, b"jkl;"); +// }; +// +// futures::future::join(server, client).await; +// } +// } diff --git a/linkerd/tls/src/imp/rustls.rs b/linkerd/tls/src/imp/rustls.rs new file mode 100644 index 0000000000..d1406f1697 --- /dev/null +++ b/linkerd/tls/src/imp/rustls.rs @@ -0,0 +1,258 @@ +use futures::Future; +use linkerd_identity::{ClientConfig, Name, ServerConfig}; +use linkerd_io::{AsyncRead, AsyncWrite, Result}; +use std::{ + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; +use webpki::DNSNameRef; + +#[derive(Clone)] +pub struct TlsConnector(tokio_rustls::TlsConnector); + +impl TlsConnector { + pub fn connect(&self, domain: Name, stream: IO) -> Connect + where + IO: AsyncRead + AsyncWrite + Unpin, + { + let dns = DNSNameRef::try_from_ascii_str(domain.as_ref()).unwrap(); + Connect(self.0.connect(dns, stream)) + } +} + +impl From for TlsConnector { + fn from(connector: tokio_rustls::TlsConnector) -> Self { + TlsConnector(connector) + } +} + +impl From> for TlsConnector { + fn from(conf: Arc) -> Self { + let rustls_config: Arc = conf.as_ref().clone().0.into(); + tokio_rustls::TlsConnector::from(rustls_config).into() + } +} + +pub struct Connect(tokio_rustls::Connect); + +impl Future for Connect { + type Output = Result>; + + #[inline] + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.0).poll(cx).map(|f| f.map(|s| s.into())) + } +} + +#[derive(Clone)] +pub struct TlsAcceptor(tokio_rustls::TlsAcceptor); + +impl TlsAcceptor { + pub fn accept(&self, stream: IO) -> Accept + where + IO: AsyncRead + AsyncWrite + Unpin, + { + Accept(self.0.accept(stream)) + } +} + +impl From for TlsAcceptor { + fn from(acceptor: tokio_rustls::TlsAcceptor) -> Self { + TlsAcceptor(acceptor) + } +} + +impl From> for TlsAcceptor { + fn from(conf: Arc) -> Self { + let rustls_config: Arc = conf.as_ref().clone().0.into(); + tokio_rustls::TlsAcceptor::from(rustls_config).into() + } +} + +pub mod client { + use std::{ + net::SocketAddr, + pin::Pin, + task::{Context, Poll}, + }; + + use linkerd_io::{AsyncRead, AsyncWrite, PeerAddr, ReadBuf, Result}; + use rustls::Session; + + use crate::{HasNegotiatedProtocol, NegotiatedProtocolRef}; + + #[derive(Debug)] + pub struct TlsStream(tokio_rustls::client::TlsStream); + + impl TlsStream { + pub fn get_alpn_protocol(&self) -> Option<&[u8]> { + self.0.get_ref().1.get_alpn_protocol() + } + } + + impl From> for TlsStream { + fn from(stream: tokio_rustls::client::TlsStream) -> Self { + TlsStream(stream) + } + } + + impl PeerAddr for TlsStream { + fn peer_addr(&self) -> Result { + self.0.get_ref().0.peer_addr() + } + } + + impl HasNegotiatedProtocol for TlsStream { + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.0 + .get_ref() + .1 + .get_alpn_protocol() + .map(NegotiatedProtocolRef) + } + } + + impl AsyncRead for TlsStream + where + IO: AsyncRead + AsyncWrite + Unpin, + { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } + } + + impl AsyncWrite for TlsStream + where + IO: AsyncRead + AsyncWrite + Unpin, + { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } + } +} + +pub mod server { + use std::{ + net::SocketAddr, + pin::Pin, + task::{Context, Poll}, + }; + + use linkerd_dns_name as dns; + use linkerd_identity::Name; + use linkerd_io::{AsyncRead, AsyncWrite, PeerAddr, ReadBuf, Result}; + use rustls::Session; + + use crate::{ClientId, HasNegotiatedProtocol, NegotiatedProtocolRef}; + + #[derive(Debug)] + pub struct TlsStream(tokio_rustls::server::TlsStream); + + impl TlsStream { + pub fn client_identity(&self) -> Option { + use webpki::GeneralDNSNameRef; + + let (_io, session) = self.0.get_ref(); + let certs = session.get_peer_certificates()?; + let c = certs.first().map(rustls::Certificate::as_ref)?; + let end_cert = webpki::EndEntityCert::from(c).ok()?; + let dns_names = end_cert.dns_names().ok()?; + + match dns_names.first()? { + GeneralDNSNameRef::DNSName(n) => { + Some(ClientId(Name::from(dns::Name::from(n.to_owned())))) + } + GeneralDNSNameRef::Wildcard(_) => { + // Wildcards can perhaps be handled in a future path... + None + } + } + } + } + + impl From> for TlsStream { + fn from(stream: tokio_rustls::server::TlsStream) -> Self { + TlsStream(stream) + } + } + + impl PeerAddr for TlsStream { + fn peer_addr(&self) -> Result { + self.0.get_ref().0.peer_addr() + } + } + + impl AsyncRead for TlsStream + where + IO: AsyncRead + AsyncWrite + Unpin, + { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } + } + + impl AsyncWrite for TlsStream + where + IO: AsyncRead + AsyncWrite + Unpin, + { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } + } + + impl HasNegotiatedProtocol for TlsStream { + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.0 + .get_ref() + .1 + .get_alpn_protocol() + .map(|b| NegotiatedProtocolRef(b)) + } + } +} + +pub struct Accept(tokio_rustls::Accept); + +impl Future for Accept { + type Output = Result>; + + #[inline] + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.0).poll(cx).map(|f| f.map(|s| s.into())) + } +} diff --git a/linkerd/tls/src/lib.rs b/linkerd/tls/src/lib.rs index e76583168d..edc7338bd8 100755 --- a/linkerd/tls/src/lib.rs +++ b/linkerd/tls/src/lib.rs @@ -3,114 +3,83 @@ #![allow(clippy::inconsistent_struct_constructor)] pub use linkerd_identity::LocalId; -use linkerd_io as io; -pub use rustls::Session; +use linkerd_identity::{ClientConfig, Name, ServerConfig}; +use linkerd_io::{AsyncRead, AsyncWrite, Result}; + +#[cfg(feature = "rustls-tls")] +#[path = "imp/rustls.rs"] +mod imp; +#[cfg(all(not(feature = "boring-tls"), not(feature = "rustls-tls")))] +#[path = "imp/openssl.rs"] +mod imp; +#[cfg(all(feature = "boring-tls", not(feature = "rustls-tls")))] +#[path = "imp/boring.rs"] +mod imp; + +mod protocol; pub mod client; pub mod server; pub use self::{ client::{Client, ClientTls, ConditionalClientTls, NoClientTls, ServerId}, + protocol::{HasNegotiatedProtocol, NegotiatedProtocol, NegotiatedProtocolRef}, server::{ClientId, ConditionalServerTls, NewDetectTls, NoServerTls, ServerTls}, }; +use std::sync::Arc; -/// A trait implented by transport streams to indicate its negotiated protocol. -pub trait HasNegotiatedProtocol { - fn negotiated_protocol(&self) -> Option>; -} - -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct NegotiatedProtocol(pub Vec); - -/// Indicates a negotiated protocol. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct NegotiatedProtocolRef<'t>(pub &'t [u8]); - -impl NegotiatedProtocol { - pub fn as_ref(&self) -> NegotiatedProtocolRef<'_> { - NegotiatedProtocolRef(&self.0) - } -} - -impl std::fmt::Debug for NegotiatedProtocol { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - NegotiatedProtocolRef(&self.0).fmt(f) - } -} +#[derive(Clone)] +pub struct TlsConnector(imp::TlsConnector); -impl NegotiatedProtocolRef<'_> { - pub fn to_owned(&self) -> NegotiatedProtocol { - NegotiatedProtocol(self.0.into()) +impl TlsConnector { + pub async fn connect(&self, domain: Name, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + self.0.connect(domain, stream).await.map(|s| s.into()) } } -impl From> for NegotiatedProtocol { - fn from(protocol: NegotiatedProtocolRef<'_>) -> NegotiatedProtocol { - protocol.to_owned() +impl From for TlsConnector { + fn from(connector: imp::TlsConnector) -> Self { + TlsConnector(connector) } } -impl std::fmt::Debug for NegotiatedProtocolRef<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match std::str::from_utf8(self.0) { - Ok(s) => s.fmt(f), - Err(_) => self.0.fmt(f), - } +impl From> for TlsConnector { + fn from(conf: Arc) -> Self { + imp::TlsConnector::from(conf).into() } } -impl HasNegotiatedProtocol for self::client::TlsStream { - #[inline] - fn negotiated_protocol(&self) -> Option> { - self.get_ref() - .1 - .get_alpn_protocol() - .map(NegotiatedProtocolRef) - } -} +#[derive(Clone)] +pub struct TlsAcceptor(imp::TlsAcceptor); -impl HasNegotiatedProtocol for self::server::TlsStream { - #[inline] - fn negotiated_protocol(&self) -> Option> { - self.get_ref() - .1 - .get_alpn_protocol() - .map(NegotiatedProtocolRef) +impl TlsAcceptor { + pub async fn accept(&self, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + self.0.accept(stream).await.map(|s| s.into()) } } -impl HasNegotiatedProtocol for tokio::net::TcpStream { - #[inline] - fn negotiated_protocol(&self) -> Option> { - None +impl From for TlsAcceptor { + fn from(acceptor: imp::TlsAcceptor) -> Self { + TlsAcceptor(acceptor) } } -impl HasNegotiatedProtocol for io::ScopedIo { - #[inline] - fn negotiated_protocol(&self) -> Option> { - self.get_ref().negotiated_protocol() - } -} - -impl HasNegotiatedProtocol for io::EitherIo -where - L: HasNegotiatedProtocol, - R: HasNegotiatedProtocol, -{ - #[inline] - fn negotiated_protocol(&self) -> Option> { - match self { - io::EitherIo::Left(l) => l.negotiated_protocol(), - io::EitherIo::Right(r) => r.negotiated_protocol(), - } +impl From> for TlsAcceptor { + fn from(conf: Arc) -> Self { + imp::TlsAcceptor::from(conf).into() } } /// Needed for tests. -impl HasNegotiatedProtocol for io::BoxedIo { - #[inline] - fn negotiated_protocol(&self) -> Option> { - None - } -} +// impl HasNegotiatedProtocol for io::BoxedIo { +// #[inline] +// fn negotiated_protocol(&self) -> Option> { +// None +// } +// } diff --git a/linkerd/tls/src/protocol.rs b/linkerd/tls/src/protocol.rs new file mode 100644 index 0000000000..92c3a8b129 --- /dev/null +++ b/linkerd/tls/src/protocol.rs @@ -0,0 +1,73 @@ +use linkerd_io as io; +/// A trait implented by transport streams to indicate its negotiated protocol. +pub trait HasNegotiatedProtocol { + fn negotiated_protocol(&self) -> Option>; +} + +#[derive(Clone, Eq, PartialEq, Hash)] +pub struct NegotiatedProtocol(pub Vec); + +/// Indicates a negotiated protocol. +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct NegotiatedProtocolRef<'t>(pub &'t [u8]); + +impl NegotiatedProtocol { + pub fn as_ref(&self) -> NegotiatedProtocolRef<'_> { + NegotiatedProtocolRef(&self.0) + } +} + +impl std::fmt::Debug for NegotiatedProtocol { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + NegotiatedProtocolRef(&self.0).fmt(f) + } +} + +impl NegotiatedProtocolRef<'_> { + pub fn to_owned(&self) -> NegotiatedProtocol { + NegotiatedProtocol(self.0.into()) + } +} + +impl Into for NegotiatedProtocolRef<'_> { + fn into(self) -> NegotiatedProtocol { + self.to_owned() + } +} + +impl std::fmt::Debug for NegotiatedProtocolRef<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match std::str::from_utf8(self.0) { + Ok(s) => s.fmt(f), + Err(_) => self.0.fmt(f), + } + } +} + +impl HasNegotiatedProtocol for tokio::net::TcpStream { + #[inline] + fn negotiated_protocol(&self) -> Option> { + None + } +} + +impl HasNegotiatedProtocol for io::ScopedIo { + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.get_ref().negotiated_protocol() + } +} + +impl HasNegotiatedProtocol for io::EitherIo +where + L: HasNegotiatedProtocol, + R: HasNegotiatedProtocol, +{ + #[inline] + fn negotiated_protocol(&self) -> Option> { + match self { + io::EitherIo::Left(l) => l.negotiated_protocol(), + io::EitherIo::Right(r) => r.negotiated_protocol(), + } + } +} diff --git a/linkerd/tls/src/server/mod.rs b/linkerd/tls/src/server/mod.rs index 1b83c048fa..012021c51b 100644 --- a/linkerd/tls/src/server/mod.rs +++ b/linkerd/tls/src/server/mod.rs @@ -1,17 +1,19 @@ mod client_hello; -use crate::{LocalId, NegotiatedProtocol, ServerId}; +use crate::{ + HasNegotiatedProtocol, LocalId, NegotiatedProtocol, NegotiatedProtocolRef, ServerId, + TlsAcceptor, +}; use bytes::BytesMut; use futures::prelude::*; use linkerd_conditional::Conditional; -use linkerd_dns_name as dns; use linkerd_error::Error; use linkerd_identity as id; -use linkerd_io::{self as io, AsyncReadExt, EitherIo, PrefixedIo}; +use linkerd_io::{self as io, AsyncReadExt, EitherIo, PeerAddr, PrefixedIo, ReadBuf}; use linkerd_stack::{layer, NewService, Param}; -use rustls::Session; use std::{ fmt, + net::SocketAddr, pin::Pin, str::FromStr, sync::Arc, @@ -19,16 +21,78 @@ use std::{ }; use thiserror::Error; use tokio::time::{self, Duration}; -pub use tokio_rustls::server::TlsStream; use tower::util::ServiceExt; use tracing::{debug, trace, warn}; -pub type Config = Arc; +use crate::imp; + +#[derive(Debug)] +pub struct TlsStream(imp::server::TlsStream); + +impl TlsStream { + pub fn client_identity(&self) -> Option { + self.0.client_identity() + } +} + +impl From> for TlsStream { + fn from(stream: imp::server::TlsStream) -> Self { + TlsStream(stream) + } +} + +impl io::AsyncRead for TlsStream +where + IO: io::AsyncRead + io::AsyncWrite + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } +} + +impl io::AsyncWrite for TlsStream +where + IO: io::AsyncRead + io::AsyncWrite + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } +} + +impl PeerAddr for TlsStream { + fn peer_addr(&self) -> io::Result { + self.0.peer_addr() + } +} + +impl HasNegotiatedProtocol for TlsStream { + #[inline] + fn negotiated_protocol(&self) -> Option> { + self.0.negotiated_protocol() + } +} + +pub type Config = Arc; /// Produces a server config that fails to handshake all connections. pub fn empty_config() -> Config { - let verifier = rustls::NoClientAuth::new(); - Arc::new(rustls::ServerConfig::new(verifier)) + Arc::new(id::ServerConfig::empty()) } /// A newtype for remote client idenities. @@ -270,18 +334,12 @@ async fn handshake(tls_config: Config, io: T) -> io::Result<(ServerTls, TlsSt where T: io::AsyncRead + io::AsyncWrite + Unpin, { - let io = tokio_rustls::TlsAcceptor::from(tls_config) - .accept(io) - .await?; + let io = TlsAcceptor::from(tls_config).accept(io).await?; // Determine the peer's identity, if it exist. - let client_id = client_identity(&io); - - let negotiated_protocol = io - .get_ref() - .1 - .get_alpn_protocol() - .map(|b| NegotiatedProtocol(b.into())); + let client_id = io.client_identity(); + // Extract the negotiated protocol for the stream. + let negotiated_protocol = io.negotiated_protocol().map(|p| p.to_owned()); debug!(client.id = ?client_id, alpn = ?negotiated_protocol, "Accepted TLS connection"); let tls = ServerTls::Established { @@ -291,26 +349,14 @@ where Ok((tls, io)) } -fn client_identity(tls: &TlsStream) -> Option { - use webpki::GeneralDNSNameRef; - - let (_io, session) = tls.get_ref(); - let certs = session.get_peer_certificates()?; - let c = certs.first().map(rustls::Certificate::as_ref)?; - let end_cert = webpki::EndEntityCert::from(c).ok()?; - let dns_names = end_cert.dns_names().ok()?; - - match dns_names.first()? { - GeneralDNSNameRef::DNSName(n) => { - Some(ClientId(id::Name::from(dns::Name::from(n.to_owned())))) - } - GeneralDNSNameRef::Wildcard(_) => { - // Wildcards can perhaps be handled in a future path... - None - } +impl fmt::Display for DetectTimeout { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "TLS detection timeout") } } +impl std::error::Error for DetectTimeout {} + // === impl ClientId === impl From for ClientId { diff --git a/linkerd2-proxy/Cargo.toml b/linkerd2-proxy/Cargo.toml index 1b5451c8dc..95908532a4 100644 --- a/linkerd2-proxy/Cargo.toml +++ b/linkerd2-proxy/Cargo.toml @@ -8,8 +8,11 @@ publish = false description = "The main proxy executable" [features] -default = ["multicore"] +default = ["multicore", "rustls-tls"] multicore = ["tokio/rt-multi-thread", "num_cpus"] +rustls-tls = ["linkerd-app/rustls-tls"] +openssl-tls = ["linkerd-app/openssl-tls"] +boring-tls = ["linkerd-app/boring-tls"] [dependencies] futures = "0.3.9" From 4f8ab56d9bb18010c4dde164d4269d99c54deab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 15 Feb 2021 11:35:26 +0000 Subject: [PATCH 02/51] Initial draft work for introducing a separate TLS provider replaceing ruslts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added support for openssl * Testing out Boringssl * Compilation features flags (openssl-tls, rustls-tls, boring-tls) Signed-off-by: Arnar Páll --- Cargo.lock | 319 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 316 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34f8f61b8e..539bac0cf1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -77,6 +86,17 @@ dependencies = [ "syn", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -89,12 +109,58 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bindgen" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which 3.1.1", +] + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "boring" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de45976d3e185902843f8ac67fcdc3f10f47cb96e275a545218273bf09a592f6" +dependencies = [ + "bitflags", + "boring-sys", + "foreign-types", + "lazy_static", + "libc", +] + +[[package]] +name = "boring-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2416bce1bcabf0d7995ce0338ec2425b8766a4d5a39d758a3638008911642fc" +dependencies = [ + "bindgen", + "cmake", +] + [[package]] name = "bumpalo" version = "3.6.0" @@ -119,12 +185,47 @@ version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" +[[package]] +name = "cexpr" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +dependencies = [ + "nom 5.1.2", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clang-sys" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term 0.11.0", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "cmake" version = "0.1.45" @@ -195,6 +296,19 @@ dependencies = [ "syn", ] +[[package]] +name = "env_logger" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "fixedbitset" version = "0.2.0" @@ -219,6 +333,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.0.0" @@ -335,6 +464,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + [[package]] name = "gzip-header" version = "0.3.0" @@ -457,6 +592,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.4" @@ -572,6 +713,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.86" @@ -588,6 +735,16 @@ dependencies = [ "cc", ] +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "libmimalloc-sys" version = "0.1.20" @@ -999,7 +1156,9 @@ dependencies = [ name = "linkerd-identity" version = "0.1.0" dependencies = [ + "boring", "linkerd-dns-name", + "openssl", "ring", "rustls", "thiserror", @@ -1373,6 +1532,7 @@ name = "linkerd-tls" version = "0.1.0" dependencies = [ "async-trait", + "boring", "bytes", "futures", "linkerd-conditional", @@ -1383,9 +1543,12 @@ dependencies = [ "linkerd-proxy-transport", "linkerd-stack", "linkerd-tracing", + "openssl", "rustls", "thiserror", "tokio", + "tokio-boring", + "tokio-openssl", "tokio-rustls", "tower", "tracing", @@ -1583,6 +1746,16 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" +[[package]] +name = "nom" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +dependencies = [ + "memchr", + "version_check", +] + [[package]] name = "ntapi" version = "0.3.6" @@ -1628,6 +1801,33 @@ dependencies = [ "tonic-build", ] +[[package]] +name = "openssl" +version = "0.10.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-sys" +version = "0.9.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b0d6fb7d80f877617dfcb014e605e2b5ab2fb0afdf27935219bb6bd984cb98" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.11.1" @@ -1653,6 +1853,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1701,6 +1907,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + [[package]] name = "ppv-lite86" version = "0.2.10" @@ -1736,7 +1948,7 @@ checksum = "6ab1427f3d2635891f842892dda177883dca0639e05fe66796a62c9d2f23b49c" dependencies = [ "byteorder", "libc", - "nom", + "nom 2.2.1", "rustc_version", ] @@ -1765,7 +1977,7 @@ dependencies = [ "prost", "prost-types", "tempfile", - "which", + "which 4.0.2", ] [[package]] @@ -1926,6 +2138,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2011,6 +2229,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" + [[package]] name = "signal-hook-registry" version = "1.3.0" @@ -2049,6 +2273,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "syn" version = "1.0.60" @@ -2074,6 +2304,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.23" @@ -2139,6 +2387,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "tokio-boring" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14a691f1783bcff212705a7be3ce90428511f7012d085b948741b40a81acb8dd" +dependencies = [ + "boring", + "boring-sys", + "tokio", +] + [[package]] name = "tokio-macros" version = "1.1.0" @@ -2150,6 +2409,18 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-openssl" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1bec5c0a4aa71e3459802c7a12e8912c2091ce2151004f9ce95cc5d1c6124e" +dependencies = [ + "futures", + "openssl", + "pin-project", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.22.0" @@ -2364,7 +2635,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "705096c6f83bf68ea5d357a6aa01829ddbdac531b357b45abeca842938085baa" dependencies = [ - "ansi_term", + "ansi_term 0.12.1", "lazy_static", "matchers", "parking_lot", @@ -2453,6 +2724,12 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -2483,6 +2760,24 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9071ac216321a4470a69fb2b28cfc68dcd1a39acd877c8be8e014df6772d8efa" +[[package]] +name = "vcpkg" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "want" version = "0.3.0" @@ -2572,6 +2867,15 @@ dependencies = [ "untrusted", ] +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + [[package]] name = "which" version = "4.0.2" @@ -2604,6 +2908,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" From db8435e5fb5ab4985af92a80d1db76b4eca47f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 22 Mar 2021 13:57:29 +0000 Subject: [PATCH 03/51] Fixing formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnar Páll --- linkerd/identity/src/imp/rustls.rs | 4 ++-- linkerd/tls/src/imp/boring.rs | 14 +++++++------- linkerd/tls/src/imp/openssl.rs | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index ed20f8c19f..8971e64e51 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -293,7 +293,7 @@ impl rustls::ResolvesServerCert for CertResolver { .map(rustls::Certificate::as_ref) .unwrap_or(&[]); // An empty input will fail to parse. if let Err(err) = - webpki::EndEntityCert::from(c).and_then(|c| c.verify_is_valid_for_dns_name(server_name)) + webpki::EndEntityCert::from(c).and_then(|c| c.verify_is_valid_for_dns_name(server_name)) { debug!( "our certificate is not valid for the SNI name -> no certificate: {:?}", @@ -412,4 +412,4 @@ impl fmt::Debug for ServerConfig { .field("protocols", &self.0.versions) .finish() } -} \ No newline at end of file +} diff --git a/linkerd/tls/src/imp/boring.rs b/linkerd/tls/src/imp/boring.rs index f3b4861a91..9c040ce419 100644 --- a/linkerd/tls/src/imp/boring.rs +++ b/linkerd/tls/src/imp/boring.rs @@ -8,16 +8,19 @@ use std::{ task::{Context, Poll}, }; +use std::str::FromStr; +use tracing::debug; use { boring::{ ssl, - ssl::{SslVerifyMode, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, SslMethod}, + ssl::{ + SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, SslMethod, + SslVerifyMode, + }, x509::store::X509StoreBuilder, }, tokio_boring::SslStream, }; -use tracing::debug; -use std::str::FromStr; #[derive(Clone)] pub struct TlsConnector(ssl::SslConnector); @@ -27,10 +30,7 @@ impl TlsConnector { where IO: AsyncRead + AsyncWrite + Unpin, { - let conf = self - .0 - .configure() - .unwrap(); + let conf = self.0.configure().unwrap(); match tokio_boring::connect(conf, domain.as_ref(), stream).await { Ok(ss) => Ok(ss.into()), Err(err) => { diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 14a29b3035..d74707061b 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -10,6 +10,7 @@ use std::{ use openssl::ssl::SslVerifyMode; use std::str::FromStr; +use tracing::debug; use { openssl::{ ssl, @@ -18,7 +19,6 @@ use { }, tokio_openssl::SslStream, }; -use tracing::debug; #[derive(Clone)] pub struct TlsConnector(ssl::SslConnector); From d148149f012523a5fc85f4617e2d12329ac7c23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 22 Mar 2021 15:11:49 +0000 Subject: [PATCH 04/51] Cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnar Páll --- linkerd/dns/name/src/name.rs | 1 - linkerd/identity/src/lib.rs | 5 +-- linkerd/tls/src/imp/openssl.rs | 71 ---------------------------------- 3 files changed, 1 insertion(+), 76 deletions(-) diff --git a/linkerd/dns/name/src/name.rs b/linkerd/dns/name/src/name.rs index c1437cdf39..7e03e71c77 100644 --- a/linkerd/dns/name/src/name.rs +++ b/linkerd/dns/name/src/name.rs @@ -92,7 +92,6 @@ mod tests { ]; for (host, expected_result) in cases { let dns_name = Name::try_from(host.as_bytes()).unwrap(); - println!("Hello {:?}", dns_name); assert_eq!(dns_name.is_localhost(), *expected_result, "{:?}", dns_name) } } diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index 0c1391f715..daf4c3af44 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -210,10 +210,7 @@ impl TrustAnchors { } pub fn from_pem(s: &str) -> Option { - match imp::TrustAnchors::from_pem(s) { - None => None, - Some(ta) => Some(TrustAnchors(ta)), - } + imp::TrustAnchors::from_pem(s).map(TrustAnchors) } pub fn certify(&self, key: Key, crt: Crt) -> Result { diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index d74707061b..51b2ae0b50 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -245,74 +245,3 @@ pub mod client { pub mod server { pub use super::TlsStream; } - -// mod tests { -// use super::TlsConnector; -// use crate::imp::TlsAcceptor; -// use linkerd_identity::{ClientConfig, Name, ServerConfig}; -// use linkerd_io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; -// use std::pin::Pin; -// use std::str::FromStr; -// use std::sync::Arc; -// use tokio::net::{TcpListener, TcpStream}; -// use std::net::ToSocketAddrs; -// -// #[tokio::test] -// async fn google() { -// let addr = "google.com:443".to_socket_addrs().unwrap().next().unwrap(); -// let stream = TcpStream::connect(&addr).await.unwrap(); -// let connector = TlsConnector::from(Arc::new(ClientConfig::empty())); -// let domain = Name::from_str("google.com").unwrap(); -// let mut stream = connector.connect(domain, stream).await.unwrap(); -// -// stream.write_all(b"GET / HTTP/1.0\r\n\r\n").await.unwrap(); -// -// let mut buf = vec![]; -// stream.read_to_end(&mut buf).await.unwrap(); -// let response = String::from_utf8_lossy(&buf); -// let response = response.trim_end(); - -// any response code is fine -// assert!(response.starts_with("HTTP/1.0 ")); -// assert!(response.ends_with("") || response.ends_with("")); -// } -// -// #[tokio::test] -// async fn server() { -// let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); -// let addr = listener.local_addr().unwrap(); -// -// let server = async move { -// let acceptor = TlsAcceptor::from(Arc::new(ServerConfig::empty())); -// -// let stream = listener.accept().await.unwrap().0; -// let mut stream = acceptor.accept(stream).await.unwrap(); -// -// let mut buf = [0; 4]; -// stream.read_exact(&mut buf).await.unwrap(); -// assert_eq!(&buf, b"asdf"); -// -// stream.write_all(b"jkl;").await.unwrap(); -// -// futures::future::poll_fn(|ctx| Pin::new(&mut stream).poll_shutdown(ctx)) -// .await -// .unwrap() -// }; -// -// let client = async { -// let connector = TlsConnector::from(Arc::new(ClientConfig::empty())); -// let name = Name::from_str("localhost").unwrap(); -// -// let stream = TcpStream::connect(&addr).await.unwrap(); -// let mut stream = connector.connect(name, stream).await.unwrap(); -// -// stream.write_all(b"asdf").await.unwrap(); -// -// let mut buf = vec![]; -// stream.read_to_end(&mut buf).await.unwrap(); -// assert_eq!(buf, b"jkl;"); -// }; -// -// futures::future::join(server, client).await; -// } -// } From ee23261cf25d988c8eade8c57cc40dbc2a441191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 23 Mar 2021 09:47:41 +0000 Subject: [PATCH 05/51] Reducing the amount of duplicate for the boring implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnar Páll --- linkerd/identity/src/imp/openssl.rs | 22 +-- linkerd/tls/src/imp/boring.rs | 243 ---------------------------- linkerd/tls/src/imp/openssl.rs | 44 ++++- linkerd/tls/src/lib.rs | 5 +- 4 files changed, 54 insertions(+), 260 deletions(-) delete mode 100644 linkerd/tls/src/imp/boring.rs diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 0b68b7021f..34f5af5936 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -2,17 +2,17 @@ use std::sync::Arc; use std::time::SystemTime; use std::{error, fmt}; -// #[cfg(feature = "boring-tls")] -// use boring::{ -// error::ErrorStack, -// pkey::{PKey, Private}, -// stack::Stack, -// x509::{ -// {X509, X509StoreContext, X509VerifyResult}, -// store::{X509Store, X509StoreBuilder}, -// }, -// }; -// #[cfg(not(feature = "boring-tls"))] +#[cfg(feature = "boring-tls")] +use boring::{ + error::ErrorStack, + pkey::{PKey, Private}, + stack::Stack, + x509::{ + {X509, X509StoreContext, X509VerifyResult}, + store::{X509Store, X509StoreBuilder}, + }, +}; +#[cfg(not(feature = "boring-tls"))] use openssl::{ error::ErrorStack, pkey::{PKey, Private}, diff --git a/linkerd/tls/src/imp/boring.rs b/linkerd/tls/src/imp/boring.rs deleted file mode 100644 index 9c040ce419..0000000000 --- a/linkerd/tls/src/imp/boring.rs +++ /dev/null @@ -1,243 +0,0 @@ -use crate::{ClientId, HasNegotiatedProtocol, NegotiatedProtocolRef}; -use linkerd_identity::{ClientConfig, Name, ServerConfig}; -use linkerd_io::{AsyncRead, AsyncWrite, Error, ErrorKind, PeerAddr, ReadBuf, Result}; -use std::net::SocketAddr; -use std::{ - pin::Pin, - sync::Arc, - task::{Context, Poll}, -}; - -use std::str::FromStr; -use tracing::debug; -use { - boring::{ - ssl, - ssl::{ - SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, SslMethod, - SslVerifyMode, - }, - x509::store::X509StoreBuilder, - }, - tokio_boring::SslStream, -}; - -#[derive(Clone)] -pub struct TlsConnector(ssl::SslConnector); - -impl TlsConnector { - pub async fn connect(&self, domain: Name, stream: IO) -> Result> - where - IO: AsyncRead + AsyncWrite + Unpin, - { - let conf = self.0.configure().unwrap(); - match tokio_boring::connect(conf, domain.as_ref(), stream).await { - Ok(ss) => Ok(ss.into()), - Err(err) => { - let _ = err.ssl(); - Err(Error::new(ErrorKind::Other, "Ble")) - } - } - } -} - -impl From for TlsConnector { - fn from(connector: SslConnector) -> Self { - Self(connector) - } -} - -impl From for TlsConnector { - fn from(builder: SslConnectorBuilder) -> Self { - builder.build().into() - } -} - -impl From> for TlsConnector { - fn from(conf: Arc) -> Self { - println!("Setting up ssl connector"); - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - - match conf.0.key.clone() { - None => debug!("No private key provided"), - Some(key) => { - debug!("Setting private key {:?}", key); - builder.set_private_key(key.as_ref().0.as_ref()).unwrap(); - } - } - - match conf.0.cert.clone() { - None => debug!("No certificate provided"), - Some(cert) => { - println!("Setting certificate {:?}", cert); - builder.set_certificate(cert.cert.as_ref()).unwrap(); - - for cert in &cert.chain { - println!("Adding extra chain certificate {:?}", cert); - builder.add_extra_chain_cert(cert.clone()).unwrap() - } - } - } - - builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); - conf.0 - .root_certs - .objects() - .iter() - .map(|x| x.x509().unwrap().to_owned()) - .for_each(|cert| { - println!("Adding Root certificate {:?}", cert); - builder.cert_store_mut().add_cert(cert).unwrap() - }); - - builder.into() - } -} - -#[derive(Clone)] -pub struct TlsAcceptor(ssl::SslAcceptor); - -impl TlsAcceptor { - pub async fn accept(&self, stream: IO) -> Result> - where - IO: AsyncRead + AsyncWrite + Unpin, - { - match tokio_boring::accept(&self.0, stream).await { - Ok(ss) => Ok(ss.into()), - Err(err) => { - let _ = err.ssl(); - Err(Error::new(ErrorKind::Other, "Ble")) - } - } - } -} - -impl From for TlsAcceptor { - fn from(acceptor: SslAcceptor) -> Self { - Self(acceptor) - } -} - -impl From for TlsAcceptor { - fn from(builder: SslAcceptorBuilder) -> Self { - builder.build().into() - } -} - -impl From> for TlsAcceptor { - fn from(conf: Arc) -> Self { - println!("Setting up ssl acceptor with mozilla intermediate"); - let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - - let key = conf.0.key.as_ref().unwrap().as_ref().0.as_ref(); - println!("Setting private key {:?}", key); - builder.set_private_key(key).unwrap(); - - let cert = conf.0.cert.as_ref().unwrap().as_ref(); - println!("Setting certificate {:?}", cert); - builder.set_certificate(cert.cert.as_ref()).unwrap(); - - for cert in &cert.chain { - println!("Adding extra chain certificate {:?}", cert); - builder.add_extra_chain_cert(cert.clone()).unwrap() - } - - builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); - conf.0 - .root_certs - .objects() - .iter() - .map(|x| x.x509().unwrap().to_owned()) - .for_each(|cert| { - println!("Adding Root certificate {:?}", cert); - builder.cert_store_mut().add_cert(cert).unwrap() - }); - - builder.set_verify(SslVerifyMode::PEER); - builder.check_private_key().unwrap(); - builder.build().into() - } -} - -#[derive(Debug)] -pub struct TlsStream(SslStream); - -impl TlsStream { - pub fn get_alpn_protocol(&self) -> Option<&[u8]> { - self.0.ssl().selected_alpn_protocol() - } - - pub fn client_identity(&self) -> Option { - let cert = self.0.ssl().peer_certificate()?; - let peer = cert.subject_alt_names()?.pop()?; - - match ClientId::from_str(peer.dnsname().unwrap()) { - Ok(client) => Some(client), - Err(_) => None, - } - } -} - -impl From> for TlsStream { - fn from(stream: SslStream) -> Self { - TlsStream(stream) - } -} - -impl PeerAddr for TlsStream { - fn peer_addr(&self) -> Result { - unimplemented!() - } -} - -impl HasNegotiatedProtocol for TlsStream { - #[inline] - fn negotiated_protocol(&self) -> Option> { - self.0 - .ssl() - .selected_alpn_protocol() - .map(NegotiatedProtocolRef) - } -} - -impl AsyncRead for TlsStream -where - IO: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_read( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut ReadBuf<'_>, - ) -> Poll> { - Pin::new(&mut self.0).poll_read(cx, buf) - } -} - -impl AsyncWrite for TlsStream -where - IO: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_write( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - Pin::new(&mut self.0).poll_write(cx, buf) - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0.get_mut()).poll_flush(cx) - } - - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0).poll_shutdown(cx) - } -} - -pub mod client { - pub use super::TlsStream; -} - -pub mod server { - pub use super::TlsStream; -} diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 51b2ae0b50..a4a28c0f9f 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -8,13 +8,23 @@ use std::{ task::{Context, Poll}, }; -use openssl::ssl::SslVerifyMode; use std::str::FromStr; use tracing::debug; + +#[cfg(feature = "boring-tls")] +use { + boring::{ + ssl, + ssl::{SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, + x509::store::X509StoreBuilder, + }, + tokio_boring::SslStream, +}; +#[cfg(not(feature = "boring-tls"))] use { openssl::{ ssl, - ssl::{Ssl, SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod}, + ssl::{Ssl, SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, x509::store::X509StoreBuilder, }, tokio_openssl::SslStream, @@ -24,6 +34,7 @@ use { pub struct TlsConnector(ssl::SslConnector); impl TlsConnector { + #[cfg(not(feature = "boring-tls"))] pub async fn connect(&self, domain: Name, stream: IO) -> Result> where IO: AsyncRead + AsyncWrite + Unpin, @@ -40,6 +51,20 @@ impl TlsConnector { Err(err) => Err(io::Error::new(ErrorKind::Other, err)), } } + #[cfg(feature = "boring-tls")] + pub async fn connect(&self, domain: Name, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + let conf = self.0.configure().unwrap(); + match tokio_boring::connect(conf, domain.as_ref(), stream).await { + Ok(ss) => Ok(ss.into()), + Err(err) => { + let _ = err.ssl(); + Err(io::Error::new(ErrorKind::Other, "Ble")) + } + } + } } impl From for TlsConnector { @@ -99,6 +124,7 @@ impl From> for TlsConnector { pub struct TlsAcceptor(ssl::SslAcceptor); impl TlsAcceptor { + #[cfg(not(feature = "boring-tls"))] pub async fn accept(&self, stream: IO) -> Result> where IO: AsyncRead + AsyncWrite + Unpin, @@ -111,6 +137,19 @@ impl TlsAcceptor { Err(err) => Err(io::Error::new(ErrorKind::Other, err)), } } + #[cfg(feature = "boring-tls")] + pub async fn accept(&self, stream: IO) -> Result> + where + IO: AsyncRead + AsyncWrite + Unpin, + { + match tokio_boring::accept(&self.0, stream).await { + Ok(ss) => Ok(ss.into()), + Err(err) => { + let _ = err.ssl(); + Err(io::Error::new(ErrorKind::Other, "Ble")) + } + } + } } impl From for TlsAcceptor { @@ -161,6 +200,7 @@ impl TlsStream where IO: AsyncRead + AsyncWrite, { + #[cfg(not(feature = "boring-tls"))] pub fn new(ssl: Ssl, stream: IO) -> Self { Self(SslStream::new(ssl, stream).unwrap()) } diff --git a/linkerd/tls/src/lib.rs b/linkerd/tls/src/lib.rs index edc7338bd8..0f7dc4f574 100755 --- a/linkerd/tls/src/lib.rs +++ b/linkerd/tls/src/lib.rs @@ -9,12 +9,9 @@ use linkerd_io::{AsyncRead, AsyncWrite, Result}; #[cfg(feature = "rustls-tls")] #[path = "imp/rustls.rs"] mod imp; -#[cfg(all(not(feature = "boring-tls"), not(feature = "rustls-tls")))] +#[cfg(not(feature = "rustls-tls"))] #[path = "imp/openssl.rs"] mod imp; -#[cfg(all(feature = "boring-tls", not(feature = "rustls-tls")))] -#[path = "imp/boring.rs"] -mod imp; mod protocol; From b1bec69ae274d5caf59164f2715afc0991e11885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 23 Mar 2021 09:54:44 +0000 Subject: [PATCH 06/51] Fixing mistakenly committed cargo change where debug symbols are generated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnar Páll --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3b8d01cca2..daacdffce9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ members = [ [profile.dev] debug = false [profile.test] -debug = true +debug = false [patch.crates-io] trust-dns-proto = { git = "https://github.com/bluejekyll/trust-dns", branch = "main" } From a33f1256c51e1036b98ded599d5a493d92b0b423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 31 Mar 2021 07:50:57 +0000 Subject: [PATCH 07/51] BoringSSL will now be built in FIPS mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to achieve this we have to build from a fork of boring since a pull request is still in flight Signed-off-by: Arnar Páll --- Cargo.toml | 4 ++++ Dockerfile | 14 +++++++++++--- linkerd/identity/Cargo.toml | 6 +++--- linkerd/tls/Cargo.toml | 6 +++--- linkerd/tls/src/imp/openssl.rs | 10 ++++++++++ linkerd2-proxy/Cargo.toml | 2 +- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index daacdffce9..f5f45dbaa1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,3 +70,7 @@ debug = false trust-dns-proto = { git = "https://github.com/bluejekyll/trust-dns", branch = "main" } trust-dns-resolver = { git = "https://github.com/bluejekyll/trust-dns", branch = "main" } webpki = { git = "https://github.com/linkerd/webpki", branch = "cert-dns-names-0.21" } +boring = { git = 'https://github.com/netapp/boring', branch = "feat/fips-support"} +boring-sys = { git = 'https://github.com/netapp/boring', branch = "feat/fips-support"} +tokio-boring = { git = 'https://github.com/netapp/boring', branch = "feat/fips-support"} + diff --git a/Dockerfile b/Dockerfile index fe8bddde17..2f354efcdb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,15 @@ ARG PROXY_FEATURES RUN --mount=type=cache,target=/var/lib/apt/lists \ --mount=type=cache,target=/var/tmp \ - apt update && apt install -y time cmake + apt update && \ + apt install -y \ + time \ + cmake \ + golang \ + clang + +ENV CC=/usr/bin/clang +ENV CXX=/usr/bin/clang++ WORKDIR /usr/src/linkerd2-proxy COPY . . @@ -44,10 +52,10 @@ RUN --mount=type=cache,target=target \ --mount=type=cache,from=rust:1.52.1-buster,source=/usr/local/cargo,target=/usr/local/cargo \ mkdir -p /out && \ if [ -n "$PROXY_UNOPTIMIZED" ]; then \ - (cd linkerd2-proxy && /usr/bin/time -v cargo build --locked --features="$PROXY_FEATURES") && \ + (cd linkerd2-proxy && /usr/bin/time -v cargo build --locked --no-default-features --features="$PROXY_FEATURES") && \ mv target/debug/linkerd2-proxy /out/linkerd2-proxy ; \ else \ - (cd linkerd2-proxy && /usr/bin/time -v cargo build --locked --release --features="$PROXY_FEATURES") && \ + (cd linkerd2-proxy && /usr/bin/time -v cargo build --locked --release --no-default-features --features="$PROXY_FEATURES") && \ mv target/release/linkerd2-proxy /out/linkerd2-proxy ; \ fi diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 54a90cc090..9878fb717d 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -6,7 +6,7 @@ license = "Apache-2.0" edition = "2018" [features] -default = ["rustls-tls"] +default = [] test-util = [] rustls-tls = ["ring", "rustls"] openssl-tls = ["openssl"] @@ -20,5 +20,5 @@ thiserror = "1.0" tracing = "0.1.2" untrusted = "0.7" webpki = "=0.21.4" -openssl = { version = "0.10.32", optional = true } -boring = { version = "1.1.2", optional = true } +boring = { version = "1.1.4", optional = true, features = ["fips"]} +openssl = { version = "0.10.33", optional = true } diff --git a/linkerd/tls/Cargo.toml b/linkerd/tls/Cargo.toml index e0d6942d3c..cb212af252 100644 --- a/linkerd/tls/Cargo.toml +++ b/linkerd/tls/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" publish = false [features] -default = ["rustls-tls"] +default = [] rustls-tls = ["linkerd-identity/rustls-tls", "rustls", "tokio-rustls"] openssl-tls = ["linkerd-identity/openssl-tls", "openssl", "tokio-openssl"] boring-tls = ["linkerd-identity/boring-tls", "boring", "tokio-boring"] @@ -26,8 +26,8 @@ tokio = { version = "1", features = ["macros", "time"] } rustls = { version = "0.19", optional = true } tokio-rustls = { version = "0.22", optional = true } tokio-openssl = { version = "0.6.1", optional = true } -openssl = { version = "0.10.32", optional = true } -boring = { version = "1.1.2", optional = true } +openssl = { version = "0.10.33", optional = true } +boring = { version = "1.1.4", optional = true, features = ["fips"]} tokio-boring = { version = "2.1.1", optional = true } thiserror = "1.0" tower = "0.4.7" diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index a4a28c0f9f..d31cd9172a 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -14,6 +14,8 @@ use tracing::debug; #[cfg(feature = "boring-tls")] use { boring::{ + version, + fips, ssl, ssl::{SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, x509::store::X509StoreBuilder, @@ -23,6 +25,8 @@ use { #[cfg(not(feature = "boring-tls"))] use { openssl::{ + version, + fips, ssl, ssl::{Ssl, SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, x509::store::X509StoreBuilder, @@ -160,6 +164,12 @@ impl From for TlsAcceptor { impl From> for TlsAcceptor { fn from(conf: Arc) -> Self { + println!("SSL Version {}", version::version()); + match fips::enable(true) { + Err(err) => tracing::error!("FIPS mode can not be enabled {:?}", err), + _ => debug!("FIPS mode is enabled") + } + println!("Setting up ssl acceptor with mozilla intermediate"); let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); diff --git a/linkerd2-proxy/Cargo.toml b/linkerd2-proxy/Cargo.toml index 95908532a4..cbd582bfca 100644 --- a/linkerd2-proxy/Cargo.toml +++ b/linkerd2-proxy/Cargo.toml @@ -21,4 +21,4 @@ num_cpus = { version = "1", optional = true } linkerd-app = { path = "../linkerd/app" } linkerd-signal = { path = "../linkerd/signal" } tokio = { version = "1", features = ["rt", "time", "net"] } -tracing = "0.1.23" +tracing = "0.1.23" \ No newline at end of file From 0cf011c09092df4016b14f3a4ee8abaafc7e6ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 31 Mar 2021 09:08:49 +0000 Subject: [PATCH 08/51] Formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnar Páll --- linkerd/identity/src/imp/openssl.rs | 2 +- linkerd/tls/src/imp/openssl.rs | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 34f5af5936..719134cb53 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -8,8 +8,8 @@ use boring::{ pkey::{PKey, Private}, stack::Stack, x509::{ - {X509, X509StoreContext, X509VerifyResult}, store::{X509Store, X509StoreBuilder}, + {X509StoreContext, X509VerifyResult, X509}, }, }; #[cfg(not(feature = "boring-tls"))] diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index d31cd9172a..4c42c62b65 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -14,10 +14,9 @@ use tracing::debug; #[cfg(feature = "boring-tls")] use { boring::{ - version, - fips, - ssl, + fips, ssl, ssl::{SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, + version, x509::store::X509StoreBuilder, }, tokio_boring::SslStream, @@ -25,10 +24,9 @@ use { #[cfg(not(feature = "boring-tls"))] use { openssl::{ - version, - fips, - ssl, + fips, ssl, ssl::{Ssl, SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, + version, x509::store::X509StoreBuilder, }, tokio_openssl::SslStream, @@ -167,7 +165,7 @@ impl From> for TlsAcceptor { println!("SSL Version {}", version::version()); match fips::enable(true) { Err(err) => tracing::error!("FIPS mode can not be enabled {:?}", err), - _ => debug!("FIPS mode is enabled") + _ => debug!("FIPS mode is enabled"), } println!("Setting up ssl acceptor with mozilla intermediate"); From b7ece50d94c908a1a30a8ce9b0b6c202ad4280e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 25 May 2021 10:39:45 +0000 Subject: [PATCH 09/51] Rebasing from main --- Cargo.lock | 9 ++---- linkerd/app/core/src/telemetry/process.rs | 2 +- linkerd/identity/src/lib.rs | 38 ++++++++++------------- linkerd/tls/src/lib.rs | 7 ----- linkerd/tls/src/protocol.rs | 8 +++++ linkerd/tls/src/server/mod.rs | 8 ----- 6 files changed, 28 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 539bac0cf1..ee91fee662 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,8 +141,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "boring" version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de45976d3e185902843f8ac67fcdc3f10f47cb96e275a545218273bf09a592f6" +source = "git+https://github.com/netapp/boring?branch=feat/fips-support#85d02f09741053f7af55a1074d5c272d0a79b27c" dependencies = [ "bitflags", "boring-sys", @@ -154,8 +153,7 @@ dependencies = [ [[package]] name = "boring-sys" version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2416bce1bcabf0d7995ce0338ec2425b8766a4d5a39d758a3638008911642fc" +source = "git+https://github.com/netapp/boring?branch=feat/fips-support#85d02f09741053f7af55a1074d5c272d0a79b27c" dependencies = [ "bindgen", "cmake", @@ -2390,8 +2388,7 @@ dependencies = [ [[package]] name = "tokio-boring" version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a691f1783bcff212705a7be3ce90428511f7012d085b948741b40a81acb8dd" +source = "git+https://github.com/netapp/boring?branch=feat/fips-support#85d02f09741053f7af55a1074d5c272d0a79b27c" dependencies = [ "boring", "boring-sys", diff --git a/linkerd/app/core/src/telemetry/process.rs b/linkerd/app/core/src/telemetry/process.rs index 47e1148c62..1a72f6642d 100644 --- a/linkerd/app/core/src/telemetry/process.rs +++ b/linkerd/app/core/src/telemetry/process.rs @@ -25,7 +25,7 @@ impl Report { .as_secs(); #[cfg(not(target_os = "linux"))] - info!("System-level metrics are only supported on Linux"); + tracing::info!("System-level metrics are only supported on Linux"); Self { start_time: Arc::new(t0.into()), diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index daf4c3af44..bbe75a5c3f 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -2,9 +2,9 @@ #![forbid(unsafe_code)] #![allow(clippy::inconsistent_struct_constructor)] -use std::{convert::TryFrom, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime}; +use std::{convert::TryFrom, error as stdErr, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime}; use thiserror::Error; -use tracing::{debug, warn}; +use tracing::debug; #[cfg(feature = "rustls-tls")] #[path = "imp/rustls.rs"] @@ -25,9 +25,9 @@ pub struct Csr(Arc>); /// An error returned from the TLS implementation. pub struct Error(imp::Error); -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - error::Error::source(&self.0) +impl stdErr::Error for Error { + fn source(&self) -> Option<&(dyn stdErr::Error + 'static)> { + stdErr::Error::source(&self.0) } } @@ -72,12 +72,6 @@ impl From for InvalidCrt { #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct LocalId(pub Name); -impl<'t> Into> for &'t LocalId { - fn into(self) -> webpki::DNSNameRef<'t> { - (&self.0).into() - } -} - // === impl Csr === impl Csr { @@ -301,17 +295,17 @@ impl fmt::Display for LocalId { // === impl InvalidCrt === -impl fmt::Display for InvalidCrt { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl error::Error for InvalidCrt { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - self.0.source() - } -} +// impl fmt::Display for InvalidCrt { +// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +// self.0.fmt(f) +// } +// } +// +// impl stdErr::Error for InvalidCrt { +// fn source(&self) -> Option<&(dyn stdErr::Error + 'static)> { +// self.0.source() +// } +// } #[derive(Clone)] pub struct ClientConfig(pub imp::ClientConfig); diff --git a/linkerd/tls/src/lib.rs b/linkerd/tls/src/lib.rs index 0f7dc4f574..bfbdd5acaf 100755 --- a/linkerd/tls/src/lib.rs +++ b/linkerd/tls/src/lib.rs @@ -73,10 +73,3 @@ impl From> for TlsAcceptor { } } -/// Needed for tests. -// impl HasNegotiatedProtocol for io::BoxedIo { -// #[inline] -// fn negotiated_protocol(&self) -> Option> { -// None -// } -// } diff --git a/linkerd/tls/src/protocol.rs b/linkerd/tls/src/protocol.rs index 92c3a8b129..927d23a50e 100644 --- a/linkerd/tls/src/protocol.rs +++ b/linkerd/tls/src/protocol.rs @@ -71,3 +71,11 @@ where } } } + +/// Needed for tests. +impl HasNegotiatedProtocol for io::BoxedIo { + #[inline] + fn negotiated_protocol(&self) -> Option> { + None + } +} \ No newline at end of file diff --git a/linkerd/tls/src/server/mod.rs b/linkerd/tls/src/server/mod.rs index 012021c51b..eee17ebf55 100644 --- a/linkerd/tls/src/server/mod.rs +++ b/linkerd/tls/src/server/mod.rs @@ -349,14 +349,6 @@ where Ok((tls, io)) } -impl fmt::Display for DetectTimeout { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "TLS detection timeout") - } -} - -impl std::error::Error for DetectTimeout {} - // === impl ClientId === impl From for ClientId { From 87d3bafd7cd77e88da06e0aead52f9164fc0b773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 25 May 2021 11:10:48 +0000 Subject: [PATCH 10/51] Updated boring to 1.1.6 --- linkerd/identity/Cargo.toml | 2 +- linkerd/tls/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 9878fb717d..063797acb4 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -20,5 +20,5 @@ thiserror = "1.0" tracing = "0.1.2" untrusted = "0.7" webpki = "=0.21.4" -boring = { version = "1.1.4", optional = true, features = ["fips"]} +boring = { version = "1.1.6", optional = true, features = ["fips"]} openssl = { version = "0.10.33", optional = true } diff --git a/linkerd/tls/Cargo.toml b/linkerd/tls/Cargo.toml index cb212af252..660ea58a4d 100644 --- a/linkerd/tls/Cargo.toml +++ b/linkerd/tls/Cargo.toml @@ -27,8 +27,8 @@ rustls = { version = "0.19", optional = true } tokio-rustls = { version = "0.22", optional = true } tokio-openssl = { version = "0.6.1", optional = true } openssl = { version = "0.10.33", optional = true } -boring = { version = "1.1.4", optional = true, features = ["fips"]} -tokio-boring = { version = "2.1.1", optional = true } +boring = { version = "1.1.6", optional = true, features = ["fips"]} +tokio-boring = { version = "2.1.3", optional = true } thiserror = "1.0" tower = "0.4.7" tracing = "0.1.23" From 20059f1aa39b175da481b423b426938f6f1c7afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Wed, 2 Jun 2021 14:53:01 +0000 Subject: [PATCH 11/51] Removing application specific ignores from .gitignore Co-authored-by: Oliver Gould --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index eb9c94e832..c9a1e9c950 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,3 @@ target **/target **/corpus **/artifacts - -.idea/ -.vscode/ \ No newline at end of file From 9d4fe1e49942025bccc89cd9419b4b309d464a92 Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Wed, 2 Jun 2021 15:20:16 +0000 Subject: [PATCH 12/51] fmt --- linkerd/identity/src/lib.rs | 4 +++- linkerd/tls/src/lib.rs | 1 - linkerd/tls/src/protocol.rs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index bbe75a5c3f..7e68c7d33d 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -2,7 +2,9 @@ #![forbid(unsafe_code)] #![allow(clippy::inconsistent_struct_constructor)] -use std::{convert::TryFrom, error as stdErr, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime}; +use std::{ + convert::TryFrom, error as stdErr, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime, +}; use thiserror::Error; use tracing::debug; diff --git a/linkerd/tls/src/lib.rs b/linkerd/tls/src/lib.rs index bfbdd5acaf..ab98e0cf18 100755 --- a/linkerd/tls/src/lib.rs +++ b/linkerd/tls/src/lib.rs @@ -72,4 +72,3 @@ impl From> for TlsAcceptor { imp::TlsAcceptor::from(conf).into() } } - diff --git a/linkerd/tls/src/protocol.rs b/linkerd/tls/src/protocol.rs index 927d23a50e..993213bc19 100644 --- a/linkerd/tls/src/protocol.rs +++ b/linkerd/tls/src/protocol.rs @@ -78,4 +78,4 @@ impl HasNegotiatedProtocol for io::BoxedIo { fn negotiated_protocol(&self) -> Option> { None } -} \ No newline at end of file +} From 89392bb31ea78667cceee88a0b9f6b77eb74f0b5 Mon Sep 17 00:00:00 2001 From: Oliver Gould Date: Wed, 2 Jun 2021 15:24:47 +0000 Subject: [PATCH 13/51] Appease clippy --- linkerd/identity/src/imp/rustls.rs | 24 ++++++++++++------------ linkerd/identity/src/lib.rs | 6 +++--- linkerd/tls/src/protocol.rs | 6 +++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index 8971e64e51..c8a4a9027a 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -345,15 +345,15 @@ impl ClientConfig { } } -impl Into> for ClientConfig { - fn into(self) -> Arc { - Arc::new(self.into()) +impl From for Arc { + fn from(cc: ClientConfig) -> Arc { + Arc::new(cc.into()) } } -impl Into for ClientConfig { - fn into(self) -> rustls::ClientConfig { - self.0 +impl From for rustls::ClientConfig { + fn from(cc: ClientConfig) -> rustls::ClientConfig { + cc.0 } } @@ -387,15 +387,15 @@ impl ServerConfig { } } -impl Into> for ServerConfig { - fn into(self) -> Arc { - Arc::new(self.into()) +impl From for Arc { + fn from(sc: ServerConfig) -> Arc { + Arc::new(sc.into()) } } -impl Into for ServerConfig { - fn into(self) -> rustls::ServerConfig { - self.0 +impl From for rustls::ServerConfig { + fn from(sc: ServerConfig) -> rustls::ServerConfig { + sc.0 } } diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index 7e68c7d33d..d42b7af781 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -110,9 +110,9 @@ impl From for Name { } } -impl Into for Name { - fn into(self) -> linkerd_dns_name::Name { - self.0.as_ref().clone() +impl From for linkerd_dns_name::Name { + fn from(n: Name) -> linkerd_dns_name::Name { + n.0.as_ref().clone() } } diff --git a/linkerd/tls/src/protocol.rs b/linkerd/tls/src/protocol.rs index 993213bc19..1cc43e90aa 100644 --- a/linkerd/tls/src/protocol.rs +++ b/linkerd/tls/src/protocol.rs @@ -29,9 +29,9 @@ impl NegotiatedProtocolRef<'_> { } } -impl Into for NegotiatedProtocolRef<'_> { - fn into(self) -> NegotiatedProtocol { - self.to_owned() +impl From> for NegotiatedProtocol { + fn from(npr: NegotiatedProtocolRef<'_>) -> NegotiatedProtocol { + npr.to_owned() } } From 7c54e1de8e91dc3d56631cb795c96aea5c37e5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Fri, 4 Jun 2021 13:35:32 +0000 Subject: [PATCH 14/51] Simplifying implemenation of the Error trait by using thiserror:Error --- linkerd/identity/Cargo.toml | 2 +- linkerd/identity/src/imp/openssl.rs | 23 +++-------------- linkerd/identity/src/imp/rustls.rs | 29 +++------------------- linkerd/identity/src/lib.rs | 38 ++++------------------------- 4 files changed, 13 insertions(+), 79 deletions(-) diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 063797acb4..57c58e19a8 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -14,7 +14,7 @@ boring-tls = ["boring"] [dependencies] linkerd-dns-name = { path = "../dns/name" } -ring = { version = "0.16.19", optional = true } +ring = { version = "0.16.19", optional = true, features = ["std"] } rustls = { version = "0.19", optional = true } thiserror = "1.0" tracing = "0.1.2" diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 719134cb53..b66bc0d860 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -38,26 +38,9 @@ impl Key { } } -#[derive(Clone, Debug)] -pub struct Error(ErrorStack); - -impl From for Error { - fn from(err: ErrorStack) -> Self { - Self(err) - } -} - -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - self.0.source() - } -} - -impl fmt::Display for Error { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self, fmt) - } -} +#[derive(Clone, Debug, Error)] +#[error(transparent)] +pub struct Error(#[from] ErrorStack); #[derive(Clone)] pub struct TrustAnchors(Arc); diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index c8a4a9027a..e832adce69 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use std::time::SystemTime; use std::{error, fmt}; use tracing::{debug, warn}; +use thiserror::Error; // These must be kept in sync: static SIGNATURE_ALG_RING_SIGNING: &ring::signature::EcdsaSigningAlgorithm = @@ -32,31 +33,9 @@ impl Key { } } -pub struct Error(KeyRejected); - -impl error::Error for Error { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - None - } -} - -impl fmt::Display for Error { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, fmt) - } -} - -impl fmt::Debug for Error { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.0, fmt) - } -} - -impl From for Error { - fn from(error: ring::error::KeyRejected) -> Error { - Error(error) - } -} +#[derive(Clone, Debug, Error)] +#[error(transparent)] +pub struct Error(#[from] KeyRejected); #[derive(Clone)] pub struct TrustAnchors(Arc); diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index d42b7af781..9c65d594bd 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -3,7 +3,7 @@ #![allow(clippy::inconsistent_struct_constructor)] use std::{ - convert::TryFrom, error as stdErr, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime, + convert::TryFrom, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime, }; use thiserror::Error; use tracing::debug; @@ -25,31 +25,9 @@ pub use linkerd_dns_name::InvalidName; pub struct Csr(Arc>); /// An error returned from the TLS implementation. -pub struct Error(imp::Error); - -impl stdErr::Error for Error { - fn source(&self) -> Option<&(dyn stdErr::Error + 'static)> { - stdErr::Error::source(&self.0) - } -} - -impl fmt::Display for Error { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, fmt) - } -} - -impl fmt::Debug for Error { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.0, fmt) - } -} - -impl From for Error { - fn from(err: imp::Error) -> Error { - Error(err) - } -} +#[derive(Clone, Debug, Error)] +#[error(transparent)] +pub struct Error(#[from] imp::Error); #[derive(Clone, Debug)] pub struct Key(imp::Key); @@ -62,13 +40,7 @@ pub struct Crt(imp::Crt); #[derive(Clone, Debug, Error)] #[error(transparent)] -pub struct InvalidCrt(imp::InvalidCrt); - -impl From for InvalidCrt { - fn from(err: imp::InvalidCrt) -> Self { - InvalidCrt(err) - } -} +pub struct InvalidCrt(#[from] imp::InvalidCrt); /// A newtype for local server identities. #[derive(Clone, Debug, Eq, PartialEq, Hash)] From e5efdd21de684692c04eddca3138e6d567f2e5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Fri, 4 Jun 2021 13:51:58 +0000 Subject: [PATCH 15/51] Addressing comments and removing more error trait boilerplate --- linkerd/identity/src/imp/openssl.rs | 40 +++++++---------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index b66bc0d860..08c3a2f4af 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -112,28 +112,26 @@ impl TrustAnchors { } pub fn client_config(&self) -> Arc { - println!("Returning empty client config"); Arc::new(ClientConfig::new(vec![], self.0.clone(), None, None)) } } impl fmt::Debug for TrustAnchors { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "OpenSSL trust anchors") + f.debug_tuple("openssl::TrustAnchors") + .field(self.0.as_ref()) + .finish() } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug. Error)] pub enum InvalidCrt { + #[error("subject alt name incorrect ({0})")] SubjectAltName(String), - Verify(X509VerifyResult), - General(Error), -} - -impl From for InvalidCrt { - fn from(err: Error) -> Self { - InvalidCrt::General(err) - } + #[error("{0}")] + Verify(#[source] X509VerifyResult), + #[error(transparent)] + General(#[from] Error), } impl From for InvalidCrt { @@ -142,26 +140,6 @@ impl From for InvalidCrt { } } -impl fmt::Display for InvalidCrt { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - InvalidCrt::SubjectAltName(name) => write!(f, "Subject alt name incorrect {}", name), - InvalidCrt::Verify(err) => err.fmt(f), - InvalidCrt::General(err) => err.fmt(f), - } - } -} - -impl error::Error for InvalidCrt { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - InvalidCrt::Verify(err) => err.source(), - InvalidCrt::General(err) => err.source(), - _ => None, - } - } -} - #[derive(Clone)] pub struct CrtKey { id: LocalId, From 3f25b9f432c7f2d8ee41e0d7377d54209eaa9ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Fri, 4 Jun 2021 14:15:12 +0000 Subject: [PATCH 16/51] Simplifying verication on subject alt names Co-authored-by: Eliza Weisman --- linkerd/identity/src/imp/openssl.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 08c3a2f4af..fb6c09f793 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -68,13 +68,11 @@ impl TrustAnchors { pub fn certify(&self, key: Key, crt: Crt) -> Result { let cert = crt.cert.clone(); - if cert + if !cert .subject_alt_names() - .unwrap() - .iter() - .filter(|n| n.dnsname().unwrap().to_string() == crt.id.to_string()) - .next() - .is_none() + .into_iter() + .flat_map(|alt_names| alt_names.iter()) + .any(|n| n.dnsname().unwrap() == crt.id.0.as_ref()) { return Err(InvalidCrt::SubjectAltName(crt.id.to_string())); } From 1b0ec2078547ef6ee1fdaa15eac44f071f8a1253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Fri, 4 Jun 2021 14:28:22 +0000 Subject: [PATCH 17/51] Formatting --- linkerd/identity/src/imp/rustls.rs | 2 +- linkerd/identity/src/lib.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index e832adce69..d2af18bb16 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -5,8 +5,8 @@ use ring::signature::EcdsaKeyPair; use std::sync::Arc; use std::time::SystemTime; use std::{error, fmt}; -use tracing::{debug, warn}; use thiserror::Error; +use tracing::{debug, warn}; // These must be kept in sync: static SIGNATURE_ALG_RING_SIGNING: &ring::signature::EcdsaSigningAlgorithm = diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index 9c65d594bd..a7f775377b 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -2,9 +2,7 @@ #![forbid(unsafe_code)] #![allow(clippy::inconsistent_struct_constructor)] -use std::{ - convert::TryFrom, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime, -}; +use std::{convert::TryFrom, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime}; use thiserror::Error; use tracing::debug; From 0d35990270b11197b80e79885b5fe2496f472d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Fri, 4 Jun 2021 14:55:31 +0000 Subject: [PATCH 18/51] Additional improvements, println removals --- linkerd/identity/src/imp/openssl.rs | 11 +++++------ linkerd/tls/src/imp/openssl.rs | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index fb6c09f793..9f4c8bc0f5 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -1,6 +1,6 @@ use std::sync::Arc; use std::time::SystemTime; -use std::{error, fmt}; +use std::fmt; #[cfg(feature = "boring-tls")] use boring::{ @@ -27,6 +27,7 @@ use tracing::{debug, warn}; use crate::{LocalId, Name}; use std::fmt::Formatter; +use thiserror::Error; #[derive(Clone, Debug)] pub struct Key(pub Arc>); @@ -71,7 +72,7 @@ impl TrustAnchors { if !cert .subject_alt_names() .into_iter() - .flat_map(|alt_names| alt_names.iter()) + .flat_map(|alt_names| alt_names.iter().collect()) .any(|n| n.dnsname().unwrap() == crt.id.0.as_ref()) { return Err(InvalidCrt::SubjectAltName(crt.id.to_string())); @@ -116,13 +117,11 @@ impl TrustAnchors { impl fmt::Debug for TrustAnchors { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_tuple("openssl::TrustAnchors") - .field(self.0.as_ref()) - .finish() + f.pad("openssl::TrustAnchors") } } -#[derive(Clone, Debug. Error)] +#[derive(Clone, Debug, Error)] pub enum InvalidCrt { #[error("subject alt name incorrect ({0})")] SubjectAltName(String), diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 4c42c62b65..135e7a9418 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -9,7 +9,7 @@ use std::{ }; use std::str::FromStr; -use tracing::debug; +use tracing::{debug, trace}; #[cfg(feature = "boring-tls")] use { @@ -83,7 +83,7 @@ impl From for TlsConnector { impl From> for TlsConnector { fn from(conf: Arc) -> Self { - println!("Setting up ssl connector"); + trace!("Setting up ssl connector"); let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); match conf.0.key.clone() { @@ -97,11 +97,11 @@ impl From> for TlsConnector { match conf.0.cert.clone() { None => debug!("No certificate provided"), Some(cert) => { - println!("Setting certificate {:?}", cert); + trace!("Setting certificate {:?}", cert); builder.set_certificate(cert.cert.as_ref()).unwrap(); for cert in &cert.chain { - println!("Adding extra chain certificate {:?}", cert); + trace!("Adding extra chain certificate {:?}", cert); builder.add_extra_chain_cert(cert.clone()).unwrap() } } @@ -114,7 +114,7 @@ impl From> for TlsConnector { .iter() .map(|x| x.x509().unwrap().to_owned()) .for_each(|cert| { - println!("Adding Root certificate {:?}", cert); + trace!("Adding Root certificate {:?}", cert); builder.cert_store_mut().add_cert(cert).unwrap() }); @@ -162,25 +162,24 @@ impl From for TlsAcceptor { impl From> for TlsAcceptor { fn from(conf: Arc) -> Self { - println!("SSL Version {}", version::version()); + debug!("SSL Version {}", version::version()); match fips::enable(true) { Err(err) => tracing::error!("FIPS mode can not be enabled {:?}", err), _ => debug!("FIPS mode is enabled"), } - println!("Setting up ssl acceptor with mozilla intermediate"); let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); let key = conf.0.key.as_ref().unwrap().as_ref().0.as_ref(); - println!("Setting private key {:?}", key); + trace!("Setting private key {:?}", key); builder.set_private_key(key).unwrap(); let cert = conf.0.cert.as_ref().unwrap().as_ref(); - println!("Setting certificate {:?}", cert); + trace!("Setting certificate {:?}", cert); builder.set_certificate(cert.cert.as_ref()).unwrap(); for cert in &cert.chain { - println!("Adding extra chain certificate {:?}", cert); + trace!("Adding extra chain certificate {:?}", cert); builder.add_extra_chain_cert(cert.clone()).unwrap() } @@ -191,7 +190,7 @@ impl From> for TlsAcceptor { .iter() .map(|x| x.x509().unwrap().to_owned()) .for_each(|cert| { - println!("Adding Root certificate {:?}", cert); + trace!("Adding Root certificate {:?}", cert); builder.cert_store_mut().add_cert(cert).unwrap() }); From c78694ba3c79463c50b2dadaa317856320c17fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Fri, 4 Jun 2021 14:57:21 +0000 Subject: [PATCH 19/51] Simplifying client id construction Co-authored-by: Eliza Weisman --- linkerd/tls/src/imp/openssl.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 135e7a9418..4b9005046f 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -222,10 +222,7 @@ impl TlsStream { let cert = self.0.ssl().peer_certificate()?; let peer = cert.subject_alt_names()?.pop()?; - match ClientId::from_str(peer.dnsname().unwrap()) { - Ok(client) => Some(client), - Err(_) => None, - } + ClientId::from_str(peer.dnsname().unwrap()).ok() } } From 7c4218160e6716b324e6affa8ae394de19f33b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Fri, 4 Jun 2021 15:22:33 +0000 Subject: [PATCH 20/51] Reducing field visibility since no access is needed. Co-authored-by: Eliza Weisman --- linkerd/identity/src/imp/openssl.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 9f4c8bc0f5..cefabd9cb1 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -215,10 +215,10 @@ impl Crt { #[derive(Clone)] pub struct ClientConfig { - pub root_certs: Arc, - pub key: Option>, - pub cert: Option>, - pub protocols: Arc>>, + root_certs: Arc, + key: Option>, + cert: Option>, + protocols: Arc>>, } impl fmt::Debug for ClientConfig { From d8bd349165a1a73236889c22473511a11ac74465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Fri, 4 Jun 2021 15:25:19 +0000 Subject: [PATCH 21/51] Client config display made more idiomatic Co-authored-by: Eliza Weisman --- linkerd/identity/src/imp/openssl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index cefabd9cb1..e1a34a2db3 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -223,7 +223,7 @@ pub struct ClientConfig { impl fmt::Debug for ClientConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.protocols, f) + f.debug_struct("ClientConfig").field("protocols", &self.protocols).finish() } } From 9afc8aec93226a25892266d3ed26b26edef7c1f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Fri, 4 Jun 2021 15:28:43 +0000 Subject: [PATCH 22/51] Continuing with idiomatic improvements --- linkerd/identity/src/imp/openssl.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index e1a34a2db3..51df1062ac 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -257,10 +257,10 @@ impl ClientConfig { #[derive(Clone)] pub struct ServerConfig { - pub root_certs: Arc, - pub key: Option>, - pub cert: Option>, - pub alpn_protocols: Arc>>, + root_certs: Arc, + key: Option>, + cert: Option>, + alpn_protocols: Arc>>, } impl ServerConfig { @@ -294,10 +294,9 @@ impl ServerConfig { impl fmt::Debug for ServerConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!( - f, - "alpn_protocols: {:?}, key: {:?}", - self.alpn_protocols, self.key - ) + f.debug_struct("ServerConfig") + .field("alpn_protocols", &self.alpn_protocols) + .field("key", &self.key) + .finish() } } From 607226ed446582e1b380a0effe15386cbaff1103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 7 Jun 2021 14:01:01 +0000 Subject: [PATCH 23/51] Starting to remove the abundant amount of unwrap() calls that are not really wanted. --- linkerd/identity/src/imp/openssl.rs | 18 ++-- linkerd/tls/src/imp/openssl.rs | 155 +++++++++++++++------------- 2 files changed, 92 insertions(+), 81 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 51df1062ac..03bda8fa79 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -1,6 +1,6 @@ +use std::fmt; use std::sync::Arc; use std::time::SystemTime; -use std::fmt; #[cfg(feature = "boring-tls")] use boring::{ @@ -215,15 +215,17 @@ impl Crt { #[derive(Clone)] pub struct ClientConfig { - root_certs: Arc, - key: Option>, - cert: Option>, + pub root_certs: Arc, + pub key: Option>, + pub cert: Option>, protocols: Arc>>, } impl fmt::Debug for ClientConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("ClientConfig").field("protocols", &self.protocols).finish() + f.debug_struct("ClientConfig") + .field("protocols", &self.protocols) + .finish() } } @@ -257,9 +259,9 @@ impl ClientConfig { #[derive(Clone)] pub struct ServerConfig { - root_certs: Arc, - key: Option>, - cert: Option>, + pub root_certs: Arc, + pub key: Option>, + pub cert: Option>, alpn_protocols: Arc>>, } diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 4b9005046f..762933b58b 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -9,7 +9,7 @@ use std::{ }; use std::str::FromStr; -use tracing::{debug, trace}; +use tracing::{debug, trace, warn}; #[cfg(feature = "boring-tls")] use { @@ -36,17 +36,54 @@ use { pub struct TlsConnector(ssl::SslConnector); impl TlsConnector { + fn new(conf: Arc) -> Result { + trace!("Setting up ssl connector"); + let mut builder = SslConnector::builder(SslMethod::tls())?; + + match conf.0.key.clone() { + None => debug!("No private key provided"), + Some(key) => { + debug!("Setting private key {:?}", key); + builder.set_private_key(key.as_ref().0.as_ref())?; + } + } + + match conf.0.cert.clone() { + None => debug!("No certificate provided"), + Some(cert) => { + trace!("Setting certificate {:?}", cert); + builder.set_certificate(cert.cert.as_ref())?; + + for cert in &cert.chain { + trace!("Adding extra chain certificate {:?}", cert); + builder.add_extra_chain_cert(cert.clone())?; + } + } + } + + builder.set_cert_store(X509StoreBuilder::new()?.build()); + conf.0 + .root_certs + .objects() + .iter() + .map(|x| x.x509().expect("Unable to get x509 certificate").to_owned()) + .for_each(|cert| { + trace!("Adding Root certificate {:?}", cert); + builder + .cert_store_mut() + .add_cert(cert) + .expect("unable to add root certificate") + }); + + Ok(builder.into()) + } + #[cfg(not(feature = "boring-tls"))] pub async fn connect(&self, domain: Name, stream: IO) -> Result> where IO: AsyncRead + AsyncWrite + Unpin, { - let ssl = self - .0 - .configure() - .unwrap() - .into_ssl(domain.as_ref()) - .unwrap(); + let ssl = self.0.configure()?.into_ssl(domain.as_ref())?; let mut s = TlsStream::new(ssl, stream); match Pin::new(&mut s.0).connect().await { Ok(_) => Ok(s), @@ -58,7 +95,7 @@ impl TlsConnector { where IO: AsyncRead + AsyncWrite + Unpin, { - let conf = self.0.configure().unwrap(); + let conf = self.0.configure()?; match tokio_boring::connect(conf, domain.as_ref(), stream).await { Ok(ss) => Ok(ss.into()), Err(err) => { @@ -83,55 +120,61 @@ impl From for TlsConnector { impl From> for TlsConnector { fn from(conf: Arc) -> Self { - trace!("Setting up ssl connector"); - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + TlsConnector::new(conf).expect("unable to create TlsConnector") + } +} - match conf.0.key.clone() { - None => debug!("No private key provided"), - Some(key) => { - debug!("Setting private key {:?}", key); - builder.set_private_key(key.as_ref().0.as_ref()).unwrap(); - } +#[derive(Clone)] +pub struct TlsAcceptor(ssl::SslAcceptor); + +impl TlsAcceptor { + fn new(conf: Arc) -> Result { + debug!("SSL provider version {}", version::version()); + match fips::enable(true) { + Err(err) => warn!("FIPS mode can not be enabled {:?}", err), + _ => debug!("FIPS mode is enabled"), } - match conf.0.cert.clone() { - None => debug!("No certificate provided"), - Some(cert) => { - trace!("Setting certificate {:?}", cert); - builder.set_certificate(cert.cert.as_ref()).unwrap(); + let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls())?; - for cert in &cert.chain { - trace!("Adding extra chain certificate {:?}", cert); - builder.add_extra_chain_cert(cert.clone()).unwrap() - } - } + let key = conf.0.key.as_ref().unwrap().as_ref().0.as_ref(); + trace!("Setting private key {:?}", key); + builder.set_private_key(key)?; + + let cert = conf.0.cert.as_ref().unwrap().as_ref(); + trace!("Setting certificate {:?}", cert); + builder.set_certificate(cert.cert.as_ref())?; + + for cert in &cert.chain { + trace!("Adding extra chain certificate {:?}", cert); + builder.add_extra_chain_cert(cert.clone())?; } - builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); + builder.set_cert_store(X509StoreBuilder::new()?.build()); conf.0 .root_certs .objects() .iter() - .map(|x| x.x509().unwrap().to_owned()) + .map(|x| x.x509().expect("Unable to get x509 certificate").to_owned()) .for_each(|cert| { trace!("Adding Root certificate {:?}", cert); - builder.cert_store_mut().add_cert(cert).unwrap() + builder + .cert_store_mut() + .add_cert(cert) + .expect("unable to add root certificate") }); - builder.into() + builder.set_verify(SslVerifyMode::PEER); + builder.check_private_key()?; + Ok(builder.build().into()) } -} -#[derive(Clone)] -pub struct TlsAcceptor(ssl::SslAcceptor); - -impl TlsAcceptor { #[cfg(not(feature = "boring-tls"))] pub async fn accept(&self, stream: IO) -> Result> where IO: AsyncRead + AsyncWrite + Unpin, { - let ssl = Ssl::new(self.0.context()).unwrap(); + let ssl = Ssl::new(self.0.context())?; let mut s = TlsStream::new(ssl, stream); match Pin::new(&mut s.0).accept().await { @@ -162,41 +205,7 @@ impl From for TlsAcceptor { impl From> for TlsAcceptor { fn from(conf: Arc) -> Self { - debug!("SSL Version {}", version::version()); - match fips::enable(true) { - Err(err) => tracing::error!("FIPS mode can not be enabled {:?}", err), - _ => debug!("FIPS mode is enabled"), - } - - let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); - - let key = conf.0.key.as_ref().unwrap().as_ref().0.as_ref(); - trace!("Setting private key {:?}", key); - builder.set_private_key(key).unwrap(); - - let cert = conf.0.cert.as_ref().unwrap().as_ref(); - trace!("Setting certificate {:?}", cert); - builder.set_certificate(cert.cert.as_ref()).unwrap(); - - for cert in &cert.chain { - trace!("Adding extra chain certificate {:?}", cert); - builder.add_extra_chain_cert(cert.clone()).unwrap() - } - - builder.set_cert_store(X509StoreBuilder::new().unwrap().build()); - conf.0 - .root_certs - .objects() - .iter() - .map(|x| x.x509().unwrap().to_owned()) - .for_each(|cert| { - trace!("Adding Root certificate {:?}", cert); - builder.cert_store_mut().add_cert(cert).unwrap() - }); - - builder.set_verify(SslVerifyMode::PEER); - builder.check_private_key().unwrap(); - builder.build().into() + TlsAcceptor::new(conf).expect("unable to create TlsAcceptor") } } @@ -209,7 +218,7 @@ where { #[cfg(not(feature = "boring-tls"))] pub fn new(ssl: Ssl, stream: IO) -> Self { - Self(SslStream::new(ssl, stream).unwrap()) + Self(SslStream::new(ssl, stream).expect("unable to create ssl stream")) } } @@ -222,7 +231,7 @@ impl TlsStream { let cert = self.0.ssl().peer_certificate()?; let peer = cert.subject_alt_names()?.pop()?; - ClientId::from_str(peer.dnsname().unwrap()).ok() + ClientId::from_str(peer.dnsname()?).ok() } } From 0b396b26b0b4abb615794e28caf33ca7365bd9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 7 Jun 2021 14:03:40 +0000 Subject: [PATCH 24/51] Temporarily reverting the SAN verification for the openssl/boringssl Reverting this check since it `flat_map` is not compiling due to the borrowing of the `alt_names` variable. I'll circle back to this --- linkerd/identity/src/imp/openssl.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 03bda8fa79..3d7e9818c0 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -69,11 +69,13 @@ impl TrustAnchors { pub fn certify(&self, key: Key, crt: Crt) -> Result { let cert = crt.cert.clone(); - if !cert + if cert .subject_alt_names() - .into_iter() - .flat_map(|alt_names| alt_names.iter().collect()) - .any(|n| n.dnsname().unwrap() == crt.id.0.as_ref()) + .unwrap() + .iter() + .filter(|n| n.dnsname().unwrap().to_string() == crt.id.to_string()) + .next() + .is_none() { return Err(InvalidCrt::SubjectAltName(crt.id.to_string())); } From 612e4c7d200b4db76b5b3c80c2a632a9955671c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Mon, 7 Jun 2021 14:11:14 +0000 Subject: [PATCH 25/51] Removing nested match call for certifications Co-authored-by: Eliza Weisman --- linkerd/identity/src/imp/openssl.rs | 33 ++++++++++++----------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 3d7e9818c0..014372a40f 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -87,28 +87,23 @@ impl TrustAnchors { } let mut context = X509StoreContext::new().unwrap(); - match context.init(&self.0, &cert, &chain, |c| match c.verify_cert() { + let verify = context.init(&self.0, &cert, &chain, |c| match c.verify_cert() { Ok(true) => Ok(Ok(true)), Ok(false) => Ok(Err(InvalidCrt::Verify(c.error()))), Err(err) => Err(err), - }) { - Ok(verify) => { - let server_config = - ServerConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); - let client_config = - ClientConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); - - match verify { - Ok(_) => Ok(CrtKey { - id: crt.id.clone(), - expiry: crt.expiry.clone(), - client_config: Arc::new(client_config), - server_config: Arc::new(server_config), - }), - Err(err) => Err(err), - } - } - Err(err) => Err(err.into()), + })??; + + let server_config = + ServerConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); + let client_config = + ClientConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); + + Ok(CrtKey { + id: crt.id.clone(), + expiry: crt.expiry.clone(), + client_config: Arc::new(client_config), + server_config: Arc::new(server_config), + }), } } From 93e19a35e5de075735a378447cfa47f996aa40c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 7 Jun 2021 14:17:27 +0000 Subject: [PATCH 26/51] Cleaning up the certificate verification --- linkerd/identity/src/imp/openssl.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 014372a40f..8e9e9bfd3f 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -87,24 +87,23 @@ impl TrustAnchors { } let mut context = X509StoreContext::new().unwrap(); - let verify = context.init(&self.0, &cert, &chain, |c| match c.verify_cert() { + context.init(&self.0, &cert, &chain, |c| match c.verify_cert() { Ok(true) => Ok(Ok(true)), Ok(false) => Ok(Err(InvalidCrt::Verify(c.error()))), Err(err) => Err(err), })??; - + let server_config = ServerConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); let client_config = - ClientConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); - + ClientConfig::new(vec![], self.0.clone(), Some(crt.clone()), Some(key.clone())); + Ok(CrtKey { id: crt.id.clone(), expiry: crt.expiry.clone(), client_config: Arc::new(client_config), server_config: Arc::new(server_config), - }), - } + }) } pub fn client_config(&self) -> Arc { From d359e11aa89179f25fa09012c47dd718f8762cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Mon, 7 Jun 2021 15:55:00 +0000 Subject: [PATCH 27/51] Some additional cleanup and validation --- linkerd/identity/src/imp/openssl.rs | 48 +++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 8e9e9bfd3f..19c7969b91 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -23,7 +23,7 @@ use openssl::{ }, }; -use tracing::{debug, warn}; +use tracing::{debug, error}; use crate::{LocalId, Name}; use std::fmt::Formatter; @@ -47,24 +47,34 @@ pub struct Error(#[from] ErrorStack); pub struct TrustAnchors(Arc); impl TrustAnchors { + fn store() -> X509StoreBuilder { + X509StoreBuilder::new().expect("unable to create certificate store") + } + #[cfg(any(test, feature = "test-util"))] pub fn empty() -> Self { - Self(Arc::new(X509StoreBuilder::new().unwrap().build())) + Self(Arc::new(TrustAnchors::store().build())) } pub fn from_pem(s: &str) -> Option { debug!("Loading {} into x509", s); - let mut store = X509StoreBuilder::new().unwrap(); - match X509::from_pem(s.as_bytes()) { + return match X509::from_pem(s.as_bytes()) { Ok(cert) => { + let mut store = TrustAnchors::store(); debug!("Adding trust {:?}", cert); - store.add_cert(cert).unwrap(); + if store.add_cert(cert).is_err() { + error!("unable to add certificate to trust anchors"); + return None + } + + Some(Self(Arc::new(store.build()))) } - Err(err) => warn!("unable to construct trust anchor {}", err), + Err(err) => { + error!("unable to construct trust anchor {}", err); + None + }, } - - Some(Self(Arc::new(store.build()))) } pub fn certify(&self, key: Key, crt: Crt) -> Result { @@ -73,20 +83,20 @@ impl TrustAnchors { .subject_alt_names() .unwrap() .iter() - .filter(|n| n.dnsname().unwrap().to_string() == crt.id.to_string()) + .filter(|n| n.dnsname().expect("unable to convert to dns name") == crt.name().as_ref()) .next() .is_none() { - return Err(InvalidCrt::SubjectAltName(crt.id.to_string())); + return Err(InvalidCrt::SubjectAltName(crt.id)); } - let mut chain = Stack::new().unwrap(); - chain.push(cert.clone()).unwrap(); + let mut chain = Stack::new()?; + chain.push(cert.clone())?; for chain_crt in crt.chain.clone() { - chain.push(chain_crt).unwrap(); + chain.push(chain_crt)?; } - let mut context = X509StoreContext::new().unwrap(); + let mut context = X509StoreContext::new()?; context.init(&self.0, &cert, &chain, |c| match c.verify_cert() { Ok(true) => Ok(Ok(true)), Ok(false) => Ok(Err(InvalidCrt::Verify(c.error()))), @@ -120,7 +130,7 @@ impl fmt::Debug for TrustAnchors { #[derive(Clone, Debug, Error)] pub enum InvalidCrt { #[error("subject alt name incorrect ({0})")] - SubjectAltName(String), + SubjectAltName(LocalId), #[error("{0}")] Verify(#[source] X509VerifyResult), #[error(transparent)] @@ -189,11 +199,11 @@ impl Crt { expiry: SystemTime, ) -> Self { let mut chain = Vec::with_capacity(intermediates.len() + 1); - let cert = X509::from_der(&leaf).unwrap(); + let cert = X509::from_der(&leaf).expect("unable to convert to a x509 certificate"); chain.extend( intermediates .into_iter() - .map(|crt| X509::from_der(&crt).unwrap()), + .map(|crt| X509::from_der(&crt).expect("unable to add intermediate certificate")), ); Self { @@ -242,7 +252,7 @@ impl ClientConfig { pub fn empty() -> Self { ClientConfig::new( Vec::new(), - Arc::new(X509StoreBuilder::new().unwrap().build()), + Arc::new(X509StoreBuilder::new().expect("unable to construct root certs").build()), None, None, ) @@ -279,7 +289,7 @@ impl ServerConfig { pub fn empty() -> Self { ServerConfig::new( Vec::new(), - Arc::new(X509StoreBuilder::new().unwrap().build()), + Arc::new(X509StoreBuilder::new().expect("unable to construct root certs").build()), None, None, ) From c503c218c500fa043579cf7361840d7b17b927fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 08:59:44 +0000 Subject: [PATCH 28/51] Minor logging fixes --- linkerd/identity/src/imp/openssl.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 19c7969b91..b94f899391 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -23,7 +23,7 @@ use openssl::{ }, }; -use tracing::{debug, error}; +use tracing::{debug, error, trace}; use crate::{LocalId, Name}; use std::fmt::Formatter; @@ -57,12 +57,11 @@ impl TrustAnchors { } pub fn from_pem(s: &str) -> Option { - debug!("Loading {} into x509", s); - + debug!("constructing trust trust anchors from pem {}", s); return match X509::from_pem(s.as_bytes()) { Ok(cert) => { let mut store = TrustAnchors::store(); - debug!("Adding trust {:?}", cert); + trace!("adding certificate to trust anchors {:?}", cert); if store.add_cert(cert).is_err() { error!("unable to add certificate to trust anchors"); return None From 6ac549e0ed522f03d98489b1d2af1d1b9f7187d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 09:37:25 +0000 Subject: [PATCH 29/51] Formatting --- linkerd/identity/src/imp/openssl.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index b94f899391..2b441fc2ef 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -64,7 +64,7 @@ impl TrustAnchors { trace!("adding certificate to trust anchors {:?}", cert); if store.add_cert(cert).is_err() { error!("unable to add certificate to trust anchors"); - return None + return None; } Some(Self(Arc::new(store.build()))) @@ -72,8 +72,8 @@ impl TrustAnchors { Err(err) => { error!("unable to construct trust anchor {}", err); None - }, - } + } + }; } pub fn certify(&self, key: Key, crt: Crt) -> Result { @@ -251,7 +251,11 @@ impl ClientConfig { pub fn empty() -> Self { ClientConfig::new( Vec::new(), - Arc::new(X509StoreBuilder::new().expect("unable to construct root certs").build()), + Arc::new( + X509StoreBuilder::new() + .expect("unable to construct root certs") + .build(), + ), None, None, ) @@ -288,7 +292,11 @@ impl ServerConfig { pub fn empty() -> Self { ServerConfig::new( Vec::new(), - Arc::new(X509StoreBuilder::new().expect("unable to construct root certs").build()), + Arc::new( + X509StoreBuilder::new() + .expect("unable to construct root certs") + .build(), + ), None, None, ) From 13db857525c4353068fd8056b416a5278331504a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 09:56:32 +0000 Subject: [PATCH 30/51] Removing commented out blocks --- linkerd/identity/src/lib.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index a7f775377b..ec7db9e491 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -265,20 +265,6 @@ impl fmt::Display for LocalId { } } -// === impl InvalidCrt === - -// impl fmt::Display for InvalidCrt { -// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -// self.0.fmt(f) -// } -// } -// -// impl stdErr::Error for InvalidCrt { -// fn source(&self) -> Option<&(dyn stdErr::Error + 'static)> { -// self.0.source() -// } -// } - #[derive(Clone)] pub struct ClientConfig(pub imp::ClientConfig); From 5c3440c22e5b6dd3f6384e44e096c92a64debb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 10:47:11 +0000 Subject: [PATCH 31/51] Reducing visibility of new constructor methods for both ClientConfig and ServerConfig --- linkerd/identity/src/imp/openssl.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 2b441fc2ef..090289e303 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -235,7 +235,7 @@ impl fmt::Debug for ClientConfig { } impl ClientConfig { - pub fn new( + fn new( protocols: Vec>, root_certs: Arc, cert: Option, @@ -275,7 +275,7 @@ pub struct ServerConfig { } impl ServerConfig { - pub fn new( + fn new( alpn_protocols: Vec>, root_certs: Arc, cert: Option, From 7916a1217d6ceee2e3bb192f48079d9ba9e00a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 12:45:11 +0000 Subject: [PATCH 32/51] Reverting change done to the dns name debug method and trust anchors debug for rustls --- linkerd/dns/name/src/name.rs | 3 ++- linkerd/identity/src/imp/rustls.rs | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/linkerd/dns/name/src/name.rs b/linkerd/dns/name/src/name.rs index 7e03e71c77..4868295c21 100644 --- a/linkerd/dns/name/src/name.rs +++ b/linkerd/dns/name/src/name.rs @@ -25,7 +25,8 @@ impl Name { impl fmt::Debug for Name { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - fmt::Display::fmt(self, f) + let s: &str = AsRef::::as_ref(&self.0); + s.fmt(f) } } diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index d2af18bb16..543b4d542c 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -132,9 +132,7 @@ impl TrustAnchors { impl fmt::Debug for TrustAnchors { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("TrustAnchors") - .field(self.0.as_ref()) - .finish() + f.debug_tuple("rustls::TrustAnchors").finish() } } From 9a94bdc8c03d25d954eb10b66c0df890715e80b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 14:21:43 +0000 Subject: [PATCH 33/51] Swapping if statement to an if-let statement --- linkerd/identity/src/imp/openssl.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 090289e303..945318b525 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -62,9 +62,9 @@ impl TrustAnchors { Ok(cert) => { let mut store = TrustAnchors::store(); trace!("adding certificate to trust anchors {:?}", cert); - if store.add_cert(cert).is_err() { - error!("unable to add certificate to trust anchors"); - return None; + if let Err(err) = store.add_cert(cert) { + error!("unable to add certificate to trust anchors, {}", err); + return None } Some(Self(Arc::new(store.build()))) From 81cccbb393bdeb9db58fe0b3f3b3dcf786dcad33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Tue, 8 Jun 2021 15:23:11 +0000 Subject: [PATCH 34/51] Using thiserror to implement InvalidCrt error Co-authored-by: Eliza Weisman --- linkerd/identity/src/imp/rustls.rs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index 543b4d542c..1938129014 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -136,20 +136,9 @@ impl fmt::Debug for TrustAnchors { } } -#[derive(Clone, Debug)] -pub struct InvalidCrt(rustls::TLSError); - -impl fmt::Display for InvalidCrt { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl error::Error for InvalidCrt { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - self.0.source() - } -} +#[derive(Clone, Debug, Error)] +#[error(transparent)] +pub struct InvalidCrt(#[from] rustls::TLSError); impl rustls::sign::SigningKey for SigningKey { fn choose_scheme( From a677a04a9dddc4b744863689992d7ab74f397c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 15:10:19 +0000 Subject: [PATCH 35/51] Additional improvements --- linkerd/identity/src/imp/openssl.rs | 10 +++++----- linkerd/tls/src/imp/openssl.rs | 12 ++++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 945318b525..8c7b41d9cf 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -62,9 +62,9 @@ impl TrustAnchors { Ok(cert) => { let mut store = TrustAnchors::store(); trace!("adding certificate to trust anchors {:?}", cert); - if let Err(err) = store.add_cert(cert) { + if let Err(err) = store.add_cert(cert) { error!("unable to add certificate to trust anchors, {}", err); - return None + return None; } Some(Self(Arc::new(store.build()))) @@ -175,7 +175,7 @@ impl CrtKey { impl fmt::Debug for CrtKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.debug_struct("CrtKey") + f.debug_struct("openssl::CrtKey") .field("id", &self.id) .field("expiry", &self.expiry) .finish() @@ -228,7 +228,7 @@ pub struct ClientConfig { impl fmt::Debug for ClientConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("ClientConfig") + f.debug_struct("openssl::ClientConfig") .field("protocols", &self.protocols) .finish() } @@ -309,7 +309,7 @@ impl ServerConfig { impl fmt::Debug for ServerConfig { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("ServerConfig") + f.debug_struct("openssl::ServerConfig") .field("alpn_protocols", &self.alpn_protocols) .field("key", &self.key) .finish() diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 762933b58b..b26c77e76c 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -1,6 +1,6 @@ use crate::{ClientId, HasNegotiatedProtocol, NegotiatedProtocolRef}; use linkerd_identity::{ClientConfig, Name, ServerConfig}; -use linkerd_io::{self as io, AsyncRead, AsyncWrite, ErrorKind, PeerAddr, ReadBuf, Result}; +use linkerd_io::{self as io, AsyncRead, AsyncWrite, PeerAddr, ReadBuf, Result}; use std::net::SocketAddr; use std::{ pin::Pin, @@ -87,7 +87,9 @@ impl TlsConnector { let mut s = TlsStream::new(ssl, stream); match Pin::new(&mut s.0).connect().await { Ok(_) => Ok(s), - Err(err) => Err(io::Error::new(ErrorKind::Other, err)), + Err(err) => Err(err + .into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))), } } #[cfg(feature = "boring-tls")] @@ -131,7 +133,7 @@ impl TlsAcceptor { fn new(conf: Arc) -> Result { debug!("SSL provider version {}", version::version()); match fips::enable(true) { - Err(err) => warn!("FIPS mode can not be enabled {:?}", err), + Err(err) => warn!("FIPS mode can not be enabled {}", err), _ => debug!("FIPS mode is enabled"), } @@ -179,7 +181,9 @@ impl TlsAcceptor { match Pin::new(&mut s.0).accept().await { Ok(_) => Ok(s), - Err(err) => Err(io::Error::new(ErrorKind::Other, err)), + Err(err) => Err(err + .into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))), } } #[cfg(feature = "boring-tls")] From 2dabb0aaf53eef386f168ff0f634b41b6ba4c0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 15:26:24 +0000 Subject: [PATCH 36/51] Removing std error --- linkerd/identity/src/imp/rustls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index 1938129014..f1163c42b1 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -4,7 +4,7 @@ use ring::rand; use ring::signature::EcdsaKeyPair; use std::sync::Arc; use std::time::SystemTime; -use std::{error, fmt}; +use std::fmt; use thiserror::Error; use tracing::{debug, warn}; From d8c25c8d55360cda0c0474090b1d1895083b06fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 15:38:15 +0000 Subject: [PATCH 37/51] Reimplemented Elisa's certificate SAN check --- Cargo.toml | 2 +- linkerd/identity/src/imp/openssl.rs | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4288135078..75f31f658c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ members = [ [profile.dev] debug = false [profile.test] -debug = false +debug = true [patch.crates-io] trust-dns-proto = { git = "https://github.com/bluejekyll/trust-dns", branch = "main" } diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/openssl.rs index 8c7b41d9cf..054d2064ae 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/openssl.rs @@ -78,13 +78,11 @@ impl TrustAnchors { pub fn certify(&self, key: Key, crt: Crt) -> Result { let cert = crt.cert.clone(); - if cert + if !cert .subject_alt_names() - .unwrap() - .iter() - .filter(|n| n.dnsname().expect("unable to convert to dns name") == crt.name().as_ref()) - .next() - .is_none() + .into_iter() + .flat_map(|alt_names| alt_names.into_iter()) + .any(|n| n.dnsname().expect("unable to convert to dns name") == crt.id.0.as_ref()) { return Err(InvalidCrt::SubjectAltName(crt.id)); } From 5d3e9c11e0a9b50491624e66bdbbdd9e670db88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Tue, 8 Jun 2021 15:40:20 +0000 Subject: [PATCH 38/51] Fixing debug implementations for rustls --- linkerd/identity/src/imp/rustls.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index f1163c42b1..0be62b7cdd 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -331,7 +331,7 @@ impl AsRef for ClientConfig { impl fmt::Debug for ClientConfig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("") + f.debug_struct("rustls::ClientConfig") .field("alpn", &self.0.alpn_protocols) .field("protocols", &self.0.versions) .finish() @@ -373,7 +373,7 @@ impl AsRef for ServerConfig { impl fmt::Debug for ServerConfig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("") + f.debug_struct("rustls::ServerConfig") .field("alpn", &self.0.alpn_protocols) .field("protocols", &self.0.versions) .finish() From bd2f7a37a149485f1a8e2b2c6c5506b834007b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll=20Arnarsson?= Date: Wed, 9 Jun 2021 08:43:58 +0000 Subject: [PATCH 39/51] Revering dev symbols --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 75f31f658c..4288135078 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ members = [ [profile.dev] debug = false [profile.test] -debug = true +debug = false [patch.crates-io] trust-dns-proto = { git = "https://github.com/bluejekyll/trust-dns", branch = "main" } From 78143309a2f9a05674e468510434a5c029ab0859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 9 Jun 2021 09:29:51 +0000 Subject: [PATCH 40/51] Minor code organization --- linkerd/identity/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index ec7db9e491..25a9a9bd5d 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -207,12 +207,6 @@ impl Crt { } } -impl From<&'_ Crt> for LocalId { - fn from(crt: &Crt) -> LocalId { - crt.0.id.clone() - } -} - // === CrtKey === #[derive(Clone, Debug)] pub struct CrtKey(imp::CrtKey); @@ -259,6 +253,12 @@ impl AsRef for LocalId { } } +impl From<&'_ Crt> for LocalId { + fn from(crt: &Crt) -> LocalId { + crt.name().clone().into() + } +} + impl fmt::Display for LocalId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) From ee1da3040f174bd9d8d3c11021ac5ac331014313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 9 Jun 2021 09:34:16 +0000 Subject: [PATCH 41/51] Formatting --- linkerd/identity/src/imp/rustls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/identity/src/imp/rustls.rs b/linkerd/identity/src/imp/rustls.rs index 0be62b7cdd..2ba36b758d 100644 --- a/linkerd/identity/src/imp/rustls.rs +++ b/linkerd/identity/src/imp/rustls.rs @@ -2,9 +2,9 @@ use crate::{LocalId, Name}; use ring::error::KeyRejected; use ring::rand; use ring::signature::EcdsaKeyPair; +use std::fmt; use std::sync::Arc; use std::time::SystemTime; -use std::fmt; use thiserror::Error; use tracing::{debug, warn}; From 1e5f92f115a05853fa7e4fe1a14204c636f8d99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 9 Jun 2021 13:45:01 +0000 Subject: [PATCH 42/51] Accept and Connect handling for Boringssl updated --- linkerd/tls/src/imp/openssl.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index b26c77e76c..6213d31920 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -98,13 +98,10 @@ impl TlsConnector { IO: AsyncRead + AsyncWrite + Unpin, { let conf = self.0.configure()?; - match tokio_boring::connect(conf, domain.as_ref(), stream).await { - Ok(ss) => Ok(ss.into()), - Err(err) => { - let _ = err.ssl(); - Err(io::Error::new(ErrorKind::Other, "Ble")) - } - } + tokio_boring::connect(conf, domain.as_ref(), stream) + .await + .map(|ss| ss.into()) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "unable to establish connection")) } } @@ -191,13 +188,10 @@ impl TlsAcceptor { where IO: AsyncRead + AsyncWrite + Unpin, { - match tokio_boring::accept(&self.0, stream).await { - Ok(ss) => Ok(ss.into()), - Err(err) => { - let _ = err.ssl(); - Err(io::Error::new(ErrorKind::Other, "Ble")) - } - } + tokio_boring::accept(&self.0, stream) + .await + .map(|ss| ss.into()) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "unable to accept connection")) } } From eb5f1cf272027a18eeb1843ce6f6925a53495c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 9 Jun 2021 14:07:36 +0000 Subject: [PATCH 43/51] Openssl implementation accept and connect modified slightly --- linkerd/tls/src/imp/openssl.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/openssl.rs index 6213d31920..2593596e97 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/openssl.rs @@ -85,12 +85,12 @@ impl TlsConnector { { let ssl = self.0.configure()?.into_ssl(domain.as_ref())?; let mut s = TlsStream::new(ssl, stream); - match Pin::new(&mut s.0).connect().await { - Ok(_) => Ok(s), - Err(err) => Err(err - .into_io_error() - .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))), - } + Pin::new(&mut s.0).connect().await.map_err(|err| { + err.into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)) + })?; + + Ok(s) } #[cfg(feature = "boring-tls")] pub async fn connect(&self, domain: Name, stream: IO) -> Result> @@ -176,12 +176,12 @@ impl TlsAcceptor { let ssl = Ssl::new(self.0.context())?; let mut s = TlsStream::new(ssl, stream); - match Pin::new(&mut s.0).accept().await { - Ok(_) => Ok(s), - Err(err) => Err(err - .into_io_error() - .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e))), - } + Pin::new(&mut s.0).accept().await.map_err(|err| { + err.into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)) + })?; + + Ok(s) } #[cfg(feature = "boring-tls")] pub async fn accept(&self, stream: IO) -> Result> From 00abf28fbaabb764a0d98cd2d5eac8c66af865af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 9 Jun 2021 14:25:56 +0000 Subject: [PATCH 44/51] Readded removed newline --- linkerd2-proxy/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd2-proxy/Cargo.toml b/linkerd2-proxy/Cargo.toml index a1026cad6f..d8325e5308 100644 --- a/linkerd2-proxy/Cargo.toml +++ b/linkerd2-proxy/Cargo.toml @@ -21,4 +21,4 @@ num_cpus = { version = "1", optional = true } linkerd-app = { path = "../linkerd/app" } linkerd-signal = { path = "../linkerd/signal" } tokio = { version = "1", features = ["rt", "time", "net"] } -tracing = "0.1.23" \ No newline at end of file +tracing = "0.1.23" From 0b36303627255ef19cdabbe9536450ec5443b868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 08:56:34 +0000 Subject: [PATCH 45/51] Fixing unused import --- linkerd/identity/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index 00195a3340..29e544e6e1 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -3,7 +3,6 @@ use std::{convert::TryFrom, fmt, fs, io, str::FromStr, sync::Arc, time::SystemTime}; use thiserror::Error; -use tokio_rustls::rustls; use tracing::debug; #[cfg(feature = "rustls-tls")] From a35e44b094ddae4b92e374436681efdd500e4ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 09:05:46 +0000 Subject: [PATCH 46/51] Fixing borrow reference that was immediately dereferenced --- linkerd/identity/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index 29e544e6e1..a31dc4de3b 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -220,7 +220,7 @@ impl CrtKey { } pub fn id(&self) -> &LocalId { - &self.0.id() + self.0.id() } pub fn client_config(&self) -> Arc { From 83fe38633d8364d9b5a2c10a6a4b19fb5c66f35b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 10:57:49 +0000 Subject: [PATCH 47/51] Removing openssl entirely Since openssl in it's current form is not going to be fips validated and a new version is in the works that will require api changes anyway the decision has been made that we should only support boringssl. This simplifies the feature flagging as well as feature compilations quite a bit --- Cargo.lock | 82 --------- linkerd/app/Cargo.toml | 1 - linkerd/app/core/Cargo.toml | 1 - .../integration/src/tests/telemetry/mod.rs | 162 +++++++++--------- linkerd/identity/Cargo.toml | 6 +- .../src/imp/{openssl.rs => boringssl.rs} | 15 +- linkerd/identity/src/lib.rs | 2 +- linkerd/tls/Cargo.toml | 7 +- .../tls/src/imp/{openssl.rs => boringssl.rs} | 37 ---- linkerd/tls/src/lib.rs | 2 +- linkerd2-proxy/Cargo.toml | 1 - 11 files changed, 89 insertions(+), 227 deletions(-) rename linkerd/identity/src/imp/{openssl.rs => boringssl.rs} (95%) rename linkerd/tls/src/imp/{openssl.rs => boringssl.rs} (87%) diff --git a/Cargo.lock b/Cargo.lock index 82878988b2..2a21a666be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,19 +410,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" -[[package]] -name = "futures-macro" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" -dependencies = [ - "autocfg", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "futures-sink" version = "0.3.17" @@ -445,14 +432,11 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "futures-macro", "futures-sink", "futures-task", "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -1171,7 +1155,6 @@ version = "0.1.0" dependencies = [ "boring", "linkerd-dns-name", - "openssl", "ring", "rustls", "thiserror", @@ -1548,12 +1531,10 @@ dependencies = [ "linkerd-proxy-transport", "linkerd-stack", "linkerd-tracing", - "openssl", "rustls", "thiserror", "tokio", "tokio-boring", - "tokio-openssl", "tokio-rustls", "tower", "tracing", @@ -1831,33 +1812,6 @@ dependencies = [ "tonic-build", ] -[[package]] -name = "openssl" -version = "0.10.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-sys" -version = "0.9.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b0d6fb7d80f877617dfcb014e605e2b5ab2fb0afdf27935219bb6bd984cb98" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -1937,30 +1891,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" version = "1.0.29" @@ -2455,18 +2391,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-openssl" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1bec5c0a4aa71e3459802c7a12e8912c2091ce2151004f9ce95cc5d1c6124e" -dependencies = [ - "futures", - "openssl", - "pin-project", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.22.0" @@ -2800,12 +2724,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cf7d77f457ef8dfa11e4cd5933c5ddb5dc52a94664071951219a97710f0a32b" -[[package]] -name = "vcpkg" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" - [[package]] name = "vec_map" version = "0.8.2" diff --git a/linkerd/app/Cargo.toml b/linkerd/app/Cargo.toml index 6a1b11f588..f3e1980cab 100644 --- a/linkerd/app/Cargo.toml +++ b/linkerd/app/Cargo.toml @@ -13,7 +13,6 @@ This is used by tests and the executable. [features] allow-loopback = ["linkerd-app-outbound/allow-loopback"] -openssl-tls = ["linkerd-app-core/openssl-tls"] boring-tls = ["linkerd-app-core/boring-tls"] rustls-tls = ["linkerd-app-core/rustls-tls"] diff --git a/linkerd/app/core/Cargo.toml b/linkerd/app/core/Cargo.toml index 606680beaa..4cfe083c0d 100644 --- a/linkerd/app/core/Cargo.toml +++ b/linkerd/app/core/Cargo.toml @@ -14,7 +14,6 @@ independently of the inbound and outbound proxy logic. [features] rustls-tls = ["linkerd-identity/rustls-tls", "linkerd-tls/rustls-tls"] -openssl-tls = ["linkerd-identity/openssl-tls", "linkerd-tls/openssl-tls"] boring-tls = ["linkerd-identity/boring-tls", "linkerd-tls/boring-tls"] [dependencies] diff --git a/linkerd/app/integration/src/tests/telemetry/mod.rs b/linkerd/app/integration/src/tests/telemetry/mod.rs index 4d56993e73..fdeb9b177e 100644 --- a/linkerd/app/integration/src/tests/telemetry/mod.rs +++ b/linkerd/app/integration/src/tests/telemetry/mod.rs @@ -1199,87 +1199,87 @@ mod transport { test_tcp_accept(TcpFixture::outbound()).await; } - #[tokio::test] - #[cfg(target_os = "macos")] - async fn inbound_tcp_connect_err() { - let _trace = trace_init(); - let srv = tcp::server() - .accept_fut(move |sock| { - drop(sock); - future::ok(()) - }) - .run() - .await; - let proxy = proxy::new().inbound(srv).run().await; - - let client = client::tcp(proxy.inbound); - let metrics = client::http1(proxy.metrics, "localhost"); - - let tcp_client = client.connect().await; - - tcp_client.write(TcpFixture::HELLO_MSG).await; - assert_eq!(tcp_client.read().await, &[]); - // Connection to the server should be a failure with the EXFULL error - metrics::metric("tcp_close_total") - .label("peer", "dst") - .label("direction", "inbound") - .label("tls", "disabled") - .label("errno", "EXFULL") - .value(1u64) - .assert_in(&metrics) - .await; - - // Connection from the client should have closed cleanly. - metrics::metric("tcp_close_total") - .label("peer", "src") - .label("direction", "inbound") - .label("tls", "disabled") - .label("errno", "") - .value(1u64) - .assert_in(&metrics) - .await; - } - - #[test] - #[cfg(target_os = "macos")] - fn outbound_tcp_connect_err() { - let _trace = trace_init(); - let srv = tcp::server() - .accept_fut(move |sock| { - drop(sock); - future::ok(()) - }) - .run() - .await; - let proxy = proxy::new().outbound(srv).run().await; - - let client = client::tcp(proxy.outbound); - let metrics = client::http1(proxy.metrics, "localhost"); - - let tcp_client = client.connect().await; - - tcp_client.write(TcpFixture::HELLO_MSG).await; - assert_eq!(tcp_client.read().await, &[]); - // Connection to the server should be a failure with the EXFULL error - metrics::metric("tcp_close_total") - .label("peer", "dst") - .label("direction", "outbound") - .label("tls", "disabled") - .label("errno", "EXFULL") - .value(1u64) - .assert_in(&metrics) - .await; - - // Connection from the client should have closed cleanly. - metrics::metric("tcp_close_total") - .label("peer", "src") - .label("direction", "outbound") - .label("tls", "disabled") - .label("errno", "") - .value(1u64) - .assert_in(&metrics) - .await; - } + // #[tokio::test] + // #[cfg(target_os = "macos")] + // async fn inbound_tcp_connect_err() { + // let _trace = trace_init(); + // let srv = tcp::server() + // .accept_fut(move |sock| { + // drop(sock); + // future::ok(()) + // }) + // .run() + // .await; + // let proxy = proxy::new().inbound(srv).run().await; + + // let client = client::tcp(proxy.inbound); + // let metrics = client::http1(proxy.metrics, "localhost"); + + // let tcp_client = client.connect().await; + + // tcp_client.write(TcpFixture::HELLO_MSG).await; + // assert_eq!(tcp_client.read().await, &[]); + // // Connection to the server should be a failure with the EXFULL error + // metrics::metric("tcp_close_total") + // .label("peer", "dst") + // .label("direction", "inbound") + // .label("tls", "disabled") + // .label("errno", "EXFULL") + // .value(1u64) + // .assert_in(&metrics) + // .await; + + // // Connection from the client should have closed cleanly. + // metrics::metric("tcp_close_total") + // .label("peer", "src") + // .label("direction", "inbound") + // .label("tls", "disabled") + // .label("errno", "") + // .value(1u64) + // .assert_in(&metrics) + // .await; + // } + + // #[test] + // #[cfg(target_os = "macos")] + // fn outbound_tcp_connect_err() { + // let _trace = trace_init(); + // let srv = tcp::server() + // .accept_fut(move |sock| { + // drop(sock); + // future::ok(()) + // }) + // .run() + // .await; + // let proxy = proxy::new().outbound(srv).run().await; + + // let client = client::tcp(proxy.outbound); + // let metrics = client::http1(proxy.metrics, "localhost"); + + // let tcp_client = client.connect().await; + + // tcp_client.write(TcpFixture::HELLO_MSG).await; + // assert_eq!(tcp_client.read().await, &[]); + // // Connection to the server should be a failure with the EXFULL error + // metrics::metric("tcp_close_total") + // .label("peer", "dst") + // .label("direction", "outbound") + // .label("tls", "disabled") + // .label("errno", "EXFULL") + // .value(1u64) + // .assert_in(&metrics) + // .await; + + // // Connection from the client should have closed cleanly. + // metrics::metric("tcp_close_total") + // .label("peer", "src") + // .label("direction", "outbound") + // .label("tls", "disabled") + // .label("errno", "") + // .value(1u64) + // .assert_in(&metrics) + // .await; + // } #[tokio::test] async fn inbound_tcp_write_bytes_total() { diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 44ebbfedcb..1c68548be4 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -6,10 +6,9 @@ license = "Apache-2.0" edition = "2018" [features] -default = [] +default = ["boring-tls"] test-util = [] rustls-tls = ["ring", "rustls"] -openssl-tls = ["openssl"] boring-tls = ["boring"] [dependencies] @@ -21,5 +20,4 @@ tokio-rustls = "0.22" tracing = "0.1.28" untrusted = "0.7" webpki = "=0.21.4" -boring = { version = "1.1.6", optional = true, features = ["fips"]} -openssl = { version = "0.10.33", optional = true } +boring = { version = "1.1.6", optional = true}#, features = ["fips"]} \ No newline at end of file diff --git a/linkerd/identity/src/imp/openssl.rs b/linkerd/identity/src/imp/boringssl.rs similarity index 95% rename from linkerd/identity/src/imp/openssl.rs rename to linkerd/identity/src/imp/boringssl.rs index 054d2064ae..e42e4d6af4 100644 --- a/linkerd/identity/src/imp/openssl.rs +++ b/linkerd/identity/src/imp/boringssl.rs @@ -2,7 +2,6 @@ use std::fmt; use std::sync::Arc; use std::time::SystemTime; -#[cfg(feature = "boring-tls")] use boring::{ error::ErrorStack, pkey::{PKey, Private}, @@ -12,16 +11,6 @@ use boring::{ {X509StoreContext, X509VerifyResult, X509}, }, }; -#[cfg(not(feature = "boring-tls"))] -use openssl::{ - error::ErrorStack, - pkey::{PKey, Private}, - stack::Stack, - x509::{ - store::{X509Store, X509StoreBuilder}, - {X509StoreContext, X509VerifyResult, X509}, - }, -}; use tracing::{debug, error, trace}; @@ -120,7 +109,7 @@ impl TrustAnchors { impl fmt::Debug for TrustAnchors { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.pad("openssl::TrustAnchors") + f.pad("boringssl::TrustAnchors") } } @@ -173,7 +162,7 @@ impl CrtKey { impl fmt::Debug for CrtKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.debug_struct("openssl::CrtKey") + f.debug_struct("boringssl::CrtKey") .field("id", &self.id) .field("expiry", &self.expiry) .finish() diff --git a/linkerd/identity/src/lib.rs b/linkerd/identity/src/lib.rs index a31dc4de3b..70c6cd0ee2 100644 --- a/linkerd/identity/src/lib.rs +++ b/linkerd/identity/src/lib.rs @@ -9,7 +9,7 @@ use tracing::debug; #[path = "imp/rustls.rs"] mod imp; #[cfg(not(feature = "rustls-tls"))] -#[path = "imp/openssl.rs"] +#[path = "imp/boringssl.rs"] mod imp; #[cfg(any(test, feature = "test-util"))] diff --git a/linkerd/tls/Cargo.toml b/linkerd/tls/Cargo.toml index 550be8ab20..b52d47cc8b 100644 --- a/linkerd/tls/Cargo.toml +++ b/linkerd/tls/Cargo.toml @@ -7,9 +7,8 @@ edition = "2018" publish = false [features] -default = [] +default = ["boring-tls"] rustls-tls = ["linkerd-identity/rustls-tls", "rustls", "tokio-rustls"] -openssl-tls = ["linkerd-identity/openssl-tls", "openssl", "tokio-openssl"] boring-tls = ["linkerd-identity/boring-tls", "boring", "tokio-boring"] [dependencies] @@ -25,9 +24,7 @@ linkerd-stack = { path = "../stack" } tokio = { version = "1", features = ["macros", "time"] } rustls = { version = "0.19", optional = true } tokio-rustls = { version = "0.22", optional = true } -tokio-openssl = { version = "0.6.1", optional = true } -openssl = { version = "0.10.33", optional = true } -boring = { version = "1.1.6", optional = true, features = ["fips"]} +boring = { version = "1.1.6", optional = true }#, features = ["fips"]} tokio-boring = { version = "2.1.3", optional = true } thiserror = "1.0" tower = "0.4.8" diff --git a/linkerd/tls/src/imp/openssl.rs b/linkerd/tls/src/imp/boringssl.rs similarity index 87% rename from linkerd/tls/src/imp/openssl.rs rename to linkerd/tls/src/imp/boringssl.rs index 2593596e97..46d8a1ab8d 100644 --- a/linkerd/tls/src/imp/openssl.rs +++ b/linkerd/tls/src/imp/boringssl.rs @@ -11,7 +11,6 @@ use std::{ use std::str::FromStr; use tracing::{debug, trace, warn}; -#[cfg(feature = "boring-tls")] use { boring::{ fips, ssl, @@ -21,16 +20,6 @@ use { }, tokio_boring::SslStream, }; -#[cfg(not(feature = "boring-tls"))] -use { - openssl::{ - fips, ssl, - ssl::{Ssl, SslAcceptor, SslConnector, SslConnectorBuilder, SslMethod, SslVerifyMode}, - version, - x509::store::X509StoreBuilder, - }, - tokio_openssl::SslStream, -}; #[derive(Clone)] pub struct TlsConnector(ssl::SslConnector); @@ -168,22 +157,6 @@ impl TlsAcceptor { Ok(builder.build().into()) } - #[cfg(not(feature = "boring-tls"))] - pub async fn accept(&self, stream: IO) -> Result> - where - IO: AsyncRead + AsyncWrite + Unpin, - { - let ssl = Ssl::new(self.0.context())?; - let mut s = TlsStream::new(ssl, stream); - - Pin::new(&mut s.0).accept().await.map_err(|err| { - err.into_io_error() - .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)) - })?; - - Ok(s) - } - #[cfg(feature = "boring-tls")] pub async fn accept(&self, stream: IO) -> Result> where IO: AsyncRead + AsyncWrite + Unpin, @@ -210,16 +183,6 @@ impl From> for TlsAcceptor { #[derive(Debug)] pub struct TlsStream(SslStream); -impl TlsStream -where - IO: AsyncRead + AsyncWrite, -{ - #[cfg(not(feature = "boring-tls"))] - pub fn new(ssl: Ssl, stream: IO) -> Self { - Self(SslStream::new(ssl, stream).expect("unable to create ssl stream")) - } -} - impl TlsStream { pub fn get_alpn_protocol(&self) -> Option<&[u8]> { self.0.ssl().selected_alpn_protocol() diff --git a/linkerd/tls/src/lib.rs b/linkerd/tls/src/lib.rs index b435228fc3..05f6b91681 100755 --- a/linkerd/tls/src/lib.rs +++ b/linkerd/tls/src/lib.rs @@ -9,7 +9,7 @@ use linkerd_io::{AsyncRead, AsyncWrite, Result}; #[path = "imp/rustls.rs"] mod imp; #[cfg(not(feature = "rustls-tls"))] -#[path = "imp/openssl.rs"] +#[path = "imp/boringssl.rs"] mod imp; mod protocol; diff --git a/linkerd2-proxy/Cargo.toml b/linkerd2-proxy/Cargo.toml index 5ac97b84e4..99d43c2379 100644 --- a/linkerd2-proxy/Cargo.toml +++ b/linkerd2-proxy/Cargo.toml @@ -11,7 +11,6 @@ description = "The main proxy executable" default = ["multicore", "rustls-tls"] multicore = ["tokio/rt-multi-thread", "num_cpus"] rustls-tls = ["linkerd-app/rustls-tls"] -openssl-tls = ["linkerd-app/openssl-tls"] boring-tls = ["linkerd-app/boring-tls"] [dependencies] From 08092f3bdd5a45f2877749f7efb1422c7068333c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 11:10:48 +0000 Subject: [PATCH 48/51] Fixing local changes that were committed by mistake --- .../integration/src/tests/telemetry/mod.rs | 162 +++++++++--------- linkerd/identity/Cargo.toml | 4 +- linkerd/tls/Cargo.toml | 4 +- 3 files changed, 85 insertions(+), 85 deletions(-) diff --git a/linkerd/app/integration/src/tests/telemetry/mod.rs b/linkerd/app/integration/src/tests/telemetry/mod.rs index fdeb9b177e..4d56993e73 100644 --- a/linkerd/app/integration/src/tests/telemetry/mod.rs +++ b/linkerd/app/integration/src/tests/telemetry/mod.rs @@ -1199,87 +1199,87 @@ mod transport { test_tcp_accept(TcpFixture::outbound()).await; } - // #[tokio::test] - // #[cfg(target_os = "macos")] - // async fn inbound_tcp_connect_err() { - // let _trace = trace_init(); - // let srv = tcp::server() - // .accept_fut(move |sock| { - // drop(sock); - // future::ok(()) - // }) - // .run() - // .await; - // let proxy = proxy::new().inbound(srv).run().await; - - // let client = client::tcp(proxy.inbound); - // let metrics = client::http1(proxy.metrics, "localhost"); - - // let tcp_client = client.connect().await; - - // tcp_client.write(TcpFixture::HELLO_MSG).await; - // assert_eq!(tcp_client.read().await, &[]); - // // Connection to the server should be a failure with the EXFULL error - // metrics::metric("tcp_close_total") - // .label("peer", "dst") - // .label("direction", "inbound") - // .label("tls", "disabled") - // .label("errno", "EXFULL") - // .value(1u64) - // .assert_in(&metrics) - // .await; - - // // Connection from the client should have closed cleanly. - // metrics::metric("tcp_close_total") - // .label("peer", "src") - // .label("direction", "inbound") - // .label("tls", "disabled") - // .label("errno", "") - // .value(1u64) - // .assert_in(&metrics) - // .await; - // } - - // #[test] - // #[cfg(target_os = "macos")] - // fn outbound_tcp_connect_err() { - // let _trace = trace_init(); - // let srv = tcp::server() - // .accept_fut(move |sock| { - // drop(sock); - // future::ok(()) - // }) - // .run() - // .await; - // let proxy = proxy::new().outbound(srv).run().await; - - // let client = client::tcp(proxy.outbound); - // let metrics = client::http1(proxy.metrics, "localhost"); - - // let tcp_client = client.connect().await; - - // tcp_client.write(TcpFixture::HELLO_MSG).await; - // assert_eq!(tcp_client.read().await, &[]); - // // Connection to the server should be a failure with the EXFULL error - // metrics::metric("tcp_close_total") - // .label("peer", "dst") - // .label("direction", "outbound") - // .label("tls", "disabled") - // .label("errno", "EXFULL") - // .value(1u64) - // .assert_in(&metrics) - // .await; - - // // Connection from the client should have closed cleanly. - // metrics::metric("tcp_close_total") - // .label("peer", "src") - // .label("direction", "outbound") - // .label("tls", "disabled") - // .label("errno", "") - // .value(1u64) - // .assert_in(&metrics) - // .await; - // } + #[tokio::test] + #[cfg(target_os = "macos")] + async fn inbound_tcp_connect_err() { + let _trace = trace_init(); + let srv = tcp::server() + .accept_fut(move |sock| { + drop(sock); + future::ok(()) + }) + .run() + .await; + let proxy = proxy::new().inbound(srv).run().await; + + let client = client::tcp(proxy.inbound); + let metrics = client::http1(proxy.metrics, "localhost"); + + let tcp_client = client.connect().await; + + tcp_client.write(TcpFixture::HELLO_MSG).await; + assert_eq!(tcp_client.read().await, &[]); + // Connection to the server should be a failure with the EXFULL error + metrics::metric("tcp_close_total") + .label("peer", "dst") + .label("direction", "inbound") + .label("tls", "disabled") + .label("errno", "EXFULL") + .value(1u64) + .assert_in(&metrics) + .await; + + // Connection from the client should have closed cleanly. + metrics::metric("tcp_close_total") + .label("peer", "src") + .label("direction", "inbound") + .label("tls", "disabled") + .label("errno", "") + .value(1u64) + .assert_in(&metrics) + .await; + } + + #[test] + #[cfg(target_os = "macos")] + fn outbound_tcp_connect_err() { + let _trace = trace_init(); + let srv = tcp::server() + .accept_fut(move |sock| { + drop(sock); + future::ok(()) + }) + .run() + .await; + let proxy = proxy::new().outbound(srv).run().await; + + let client = client::tcp(proxy.outbound); + let metrics = client::http1(proxy.metrics, "localhost"); + + let tcp_client = client.connect().await; + + tcp_client.write(TcpFixture::HELLO_MSG).await; + assert_eq!(tcp_client.read().await, &[]); + // Connection to the server should be a failure with the EXFULL error + metrics::metric("tcp_close_total") + .label("peer", "dst") + .label("direction", "outbound") + .label("tls", "disabled") + .label("errno", "EXFULL") + .value(1u64) + .assert_in(&metrics) + .await; + + // Connection from the client should have closed cleanly. + metrics::metric("tcp_close_total") + .label("peer", "src") + .label("direction", "outbound") + .label("tls", "disabled") + .label("errno", "") + .value(1u64) + .assert_in(&metrics) + .await; + } #[tokio::test] async fn inbound_tcp_write_bytes_total() { diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 1c68548be4..77cf79cd74 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -6,7 +6,7 @@ license = "Apache-2.0" edition = "2018" [features] -default = ["boring-tls"] +default = [] test-util = [] rustls-tls = ["ring", "rustls"] boring-tls = ["boring"] @@ -20,4 +20,4 @@ tokio-rustls = "0.22" tracing = "0.1.28" untrusted = "0.7" webpki = "=0.21.4" -boring = { version = "1.1.6", optional = true}#, features = ["fips"]} \ No newline at end of file +boring = { version = "1.1.6", optional = true, features = ["fips"]} \ No newline at end of file diff --git a/linkerd/tls/Cargo.toml b/linkerd/tls/Cargo.toml index b52d47cc8b..e1f9f9c7b2 100644 --- a/linkerd/tls/Cargo.toml +++ b/linkerd/tls/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" publish = false [features] -default = ["boring-tls"] +default = [] rustls-tls = ["linkerd-identity/rustls-tls", "rustls", "tokio-rustls"] boring-tls = ["linkerd-identity/boring-tls", "boring", "tokio-boring"] @@ -24,7 +24,7 @@ linkerd-stack = { path = "../stack" } tokio = { version = "1", features = ["macros", "time"] } rustls = { version = "0.19", optional = true } tokio-rustls = { version = "0.22", optional = true } -boring = { version = "1.1.6", optional = true }#, features = ["fips"]} +boring = { version = "1.1.6", optional = true, features = ["fips"]} tokio-boring = { version = "2.1.3", optional = true } thiserror = "1.0" tower = "0.4.8" From bbb88c29f83b1cc59e3968bfa58bcdb036f3741d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 11:12:46 +0000 Subject: [PATCH 49/51] Removing extra newline --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8a4eb9271e..d9842f54da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,4 +76,3 @@ webpki = { git = "https://github.com/linkerd/webpki", branch = "cert-dns-names-0 boring = { git = 'https://github.com/netapp/boring', branch = "feat/fips-support"} boring-sys = { git = 'https://github.com/netapp/boring', branch = "feat/fips-support"} tokio-boring = { git = 'https://github.com/netapp/boring', branch = "feat/fips-support"} - From 47a75d39e5e29a68450b30da80f80df533db8d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 11:15:26 +0000 Subject: [PATCH 50/51] Adding newline at the end of file --- linkerd/identity/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkerd/identity/Cargo.toml b/linkerd/identity/Cargo.toml index 77cf79cd74..4c819cc913 100644 --- a/linkerd/identity/Cargo.toml +++ b/linkerd/identity/Cargo.toml @@ -20,4 +20,4 @@ tokio-rustls = "0.22" tracing = "0.1.28" untrusted = "0.7" webpki = "=0.21.4" -boring = { version = "1.1.6", optional = true, features = ["fips"]} \ No newline at end of file +boring = { version = "1.1.6", optional = true, features = ["fips"]} From 2658a40765be8cc77912a290245d5819871f8736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnar=20P=C3=A1ll?= Date: Wed, 29 Sep 2021 11:25:22 +0000 Subject: [PATCH 51/51] Updating cargo lock for updated boring module --- Cargo.lock | 126 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a21a666be..1392cc437b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,9 +113,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bindgen" -version = "0.57.0" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4865004a46a0aafb2a0a5eb19d3c9fc46ee5f063a6cfc605c69ac9ecf5263d" +checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375" dependencies = [ "bitflags", "cexpr", @@ -140,10 +140,22 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "boring" version = "1.1.6" -source = "git+https://github.com/netapp/boring?branch=feat/fips-support#85d02f09741053f7af55a1074d5c272d0a79b27c" +source = "git+https://github.com/netapp/boring?branch=feat/fips-support#0f431cbc3be689c477b3a8e8bc8d1ae177cd1e4e" dependencies = [ "bitflags", "boring-sys", @@ -155,7 +167,7 @@ dependencies = [ [[package]] name = "boring-sys" version = "1.1.1" -source = "git+https://github.com/netapp/boring?branch=feat/fips-support#85d02f09741053f7af55a1074d5c272d0a79b27c" +source = "git+https://github.com/netapp/boring?branch=feat/fips-support#0f431cbc3be689c477b3a8e8bc8d1ae177cd1e4e" dependencies = [ "bindgen", "cmake", @@ -163,9 +175,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" [[package]] name = "byteorder" @@ -187,11 +199,11 @@ checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" [[package]] name = "cexpr" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89" dependencies = [ - "nom 5.1.2", + "nom 6.1.2", ] [[package]] @@ -202,9 +214,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +checksum = "10612c0ec0e0a1ff0e97980647cb058a6e7aedb913d01d009c406b8b7d0b26ee" dependencies = [ "glob", "libc", @@ -302,9 +314,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", "humantime", @@ -339,18 +351,30 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ + "foreign-types-macros", "foreign-types-shared", ] +[[package]] +name = "foreign-types-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63f713f8b2aa9e24fec85b0e290c56caee12e3b6ae0aeeda238a75b28251afd6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "foreign-types-shared" -version = "0.1.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "7684cf33bb7f28497939e8c7cf17e3e4e3b8d9a0080ffa4f8ae2f515442ee855" [[package]] name = "form_urlencoded" @@ -362,6 +386,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "futures" version = "0.3.17" @@ -657,9 +687,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" dependencies = [ "cfg-if", ] @@ -720,9 +750,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.102" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" [[package]] name = "libfuzzer-sys" @@ -1759,10 +1789,12 @@ checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" [[package]] name = "nom" -version = "5.1.2" +version = "6.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" dependencies = [ + "bitvec", + "funty", "memchr", "version_check", ] @@ -1993,6 +2025,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + [[package]] name = "rand" version = "0.8.4" @@ -2195,9 +2233,9 @@ dependencies = [ [[package]] name = "shlex" -version = "0.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook-registry" @@ -2216,9 +2254,9 @@ checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "socket2" @@ -2255,15 +2293,21 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.76" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.2.0" @@ -2327,9 +2371,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986" +checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" dependencies = [ "tinyvec_macros", ] @@ -2363,7 +2407,7 @@ dependencies = [ [[package]] name = "tokio-boring" version = "2.1.3" -source = "git+https://github.com/netapp/boring?branch=feat/fips-support#85d02f09741053f7af55a1074d5c272d0a79b27c" +source = "git+https://github.com/netapp/boring?branch=feat/fips-support#0f431cbc3be689c477b3a8e8bc8d1ae177cd1e4e" dependencies = [ "boring", "boring-sys", @@ -2618,9 +2662,9 @@ dependencies = [ [[package]] name = "trust-dns-proto" -version = "0.21.0-alpha.2" +version = "0.21.0-alpha.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09637dee9c56a62b9acd8ca59ab2ed9459d8430b005100d9063ea326a0a3590a" +checksum = "0c92f7753caf275df6cff04b2ecbade15d62dbe38edf57e764180ba011d077ce" dependencies = [ "async-trait", "cfg-if", @@ -2643,9 +2687,9 @@ dependencies = [ [[package]] name = "trust-dns-resolver" -version = "0.21.0-alpha.2" +version = "0.21.0-alpha.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d449ae262d022d3f273e46483adbb8553e66327baa5c18717d7790e60d7c6721" +checksum = "717ae0b892f6e9f251ee878f7d3625f145d53c5df2fd67f751e85dc00b5cc4f6" dependencies = [ "cfg-if", "futures-util", @@ -2690,9 +2734,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" @@ -2890,3 +2934,9 @@ checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" dependencies = [ "winapi", ] + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"