diff --git a/Cargo.lock b/Cargo.lock index 85aa950657..7403ec2db2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5449,6 +5449,7 @@ dependencies = [ "rand 0.7.3", "rand_chacha 0.2.2", "rayon", + "rcgen", "solana-logger 1.16.0", "solana-measure", "solana-metrics", @@ -6430,6 +6431,7 @@ dependencies = [ "quinn", "quinn-proto", "quinn-udp", + "rcgen", "rustls 0.20.6", "solana-connection-cache", "solana-logger 1.16.0", diff --git a/connection-cache/Cargo.toml b/connection-cache/Cargo.toml index a70cabbbbc..c0d37f4001 100644 --- a/connection-cache/Cargo.toml +++ b/connection-cache/Cargo.toml @@ -18,6 +18,7 @@ indicatif = { workspace = true, optional = true } log = { workspace = true } rand = { workspace = true } rayon = { workspace = true } +rcgen = { workspace = true } solana-measure = { workspace = true } solana-metrics = { workspace = true } solana-sdk = { workspace = true } diff --git a/connection-cache/src/connection_cache.rs b/connection-cache/src/connection_cache.rs index 75e09c0ce8..2b086c2d9b 100644 --- a/connection-cache/src/connection_cache.rs +++ b/connection-cache/src/connection_cache.rs @@ -287,7 +287,7 @@ pub enum ConnectionPoolError { #[derive(Error, Debug)] pub enum ClientError { #[error("Certificate error: {0}")] - CertificateError(String), + CertificateError(#[from] rcgen::RcgenError), #[error("IO error: {0:?}")] IoError(#[from] std::io::Error), diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 7086152c21..a2d11fae68 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -4725,6 +4725,7 @@ dependencies = [ "log", "rand 0.7.3", "rayon", + "rcgen", "solana-measure", "solana-metrics", "solana-sdk 1.16.0", @@ -5392,6 +5393,7 @@ dependencies = [ "quinn", "quinn-proto", "quinn-udp", + "rcgen", "rustls 0.20.6", "solana-connection-cache", "solana-measure", diff --git a/quic-client/Cargo.toml b/quic-client/Cargo.toml index fa0a6796a7..28b5b780d1 100644 --- a/quic-client/Cargo.toml +++ b/quic-client/Cargo.toml @@ -19,6 +19,7 @@ log = { workspace = true } quinn = { workspace = true } quinn-proto = { workspace = true } quinn-udp = { workspace = true } +rcgen = { workspace = true } rustls = { workspace = true, features = ["dangerous_configuration"] } solana-connection-cache = { workspace = true } solana-measure = { workspace = true } diff --git a/quic-client/src/lib.rs b/quic-client/src/lib.rs index 2af3dddf2f..e9a6335bd9 100644 --- a/quic-client/src/lib.rs +++ b/quic-client/src/lib.rs @@ -15,6 +15,7 @@ use { quic_client::QuicClientConnection as BlockingQuicClientConnection, }, quinn::Endpoint, + rcgen::RcgenError, solana_connection_cache::{ connection_cache::{ BaseClientConnection, ClientError, ConnectionManager, ConnectionPool, @@ -29,7 +30,6 @@ use { tls_certificates::new_self_signed_tls_certificate, }, std::{ - error::Error, net::{IpAddr, Ipv4Addr, SocketAddr}, sync::{Arc, RwLock}, }, @@ -39,7 +39,7 @@ use { #[derive(Error, Debug)] pub enum QuicClientError { #[error("Certificate error: {0}")] - CertificateError(String), + CertificateError(#[from] RcgenError), } pub struct QuicPool { @@ -92,8 +92,7 @@ pub struct QuicConfig { impl NewConnectionConfig for QuicConfig { fn new() -> Result { let (cert, priv_key) = - new_self_signed_tls_certificate(&Keypair::new(), IpAddr::V4(Ipv4Addr::UNSPECIFIED)) - .map_err(|err| ClientError::CertificateError(err.to_string()))?; + new_self_signed_tls_certificate(&Keypair::new(), IpAddr::V4(Ipv4Addr::UNSPECIFIED))?; Ok(Self { client_certificate: Arc::new(QuicClientCertificate { certificate: cert, @@ -136,7 +135,7 @@ impl QuicConfig { &mut self, keypair: &Keypair, ipaddr: IpAddr, - ) -> Result<(), Box> { + ) -> Result<(), RcgenError> { let (cert, priv_key) = new_self_signed_tls_certificate(keypair, ipaddr)?; self.client_certificate = Arc::new(QuicClientCertificate { certificate: cert, diff --git a/streamer/src/nonblocking/quic.rs b/streamer/src/nonblocking/quic.rs index a49413cfb8..e2a7c385d0 100644 --- a/streamer/src/nonblocking/quic.rs +++ b/streamer/src/nonblocking/quic.rs @@ -101,11 +101,8 @@ pub fn spawn_server( info!("Start quic server on {:?}", sock); let (config, _cert) = configure_server(keypair, gossip_host)?; - let endpoint = { - Endpoint::new(EndpointConfig::default(), Some(config), sock, TokioRuntime) - .map_err(|_e| QuicServerError::EndpointFailed)? - }; - + let endpoint = Endpoint::new(EndpointConfig::default(), Some(config), sock, TokioRuntime) + .map_err(QuicServerError::EndpointFailed)?; let handle = tokio::spawn(run_server( endpoint.clone(), packet_sender, diff --git a/streamer/src/quic.rs b/streamer/src/quic.rs index 9bf15b3f6f..85616f13f5 100644 --- a/streamer/src/quic.rs +++ b/streamer/src/quic.rs @@ -57,8 +57,7 @@ pub(crate) fn configure_server( identity_keypair: &Keypair, gossip_host: IpAddr, ) -> Result<(ServerConfig, String), QuicServerError> { - let (cert, priv_key) = new_self_signed_tls_certificate(identity_keypair, gossip_host) - .map_err(|_e| QuicServerError::ConfigureFailed)?; + let (cert, priv_key) = new_self_signed_tls_certificate(identity_keypair, gossip_host)?; let cert_chain_pem_parts = vec![Pem { tag: "CERTIFICATE".to_string(), contents: cert.0.clone(), @@ -68,8 +67,7 @@ pub(crate) fn configure_server( let mut server_tls_config = rustls::ServerConfig::builder() .with_safe_defaults() .with_client_cert_verifier(SkipClientVerification::new()) - .with_single_cert(vec![cert], priv_key) - .map_err(|_e| QuicServerError::ConfigureFailed)?; + .with_single_cert(vec![cert], priv_key)?; server_tls_config.alpn_protocols = vec![ALPN_TPU_PROTOCOL_ID.to_vec()]; let mut server_config = ServerConfig::with_crypto(Arc::new(server_tls_config)); @@ -106,11 +104,12 @@ fn rt() -> Runtime { #[derive(thiserror::Error, Debug)] pub enum QuicServerError { - #[error("Server configure failed")] - ConfigureFailed, - - #[error("Endpoint creation failed")] - EndpointFailed, + #[error("Endpoint creation failed: {0}")] + EndpointFailed(std::io::Error), + #[error("Certificate error: {0}")] + CertificateError(#[from] rcgen::RcgenError), + #[error("TLS error: {0}")] + TlsError(#[from] rustls::Error), } #[derive(Default)] diff --git a/streamer/src/tls_certificates.rs b/streamer/src/tls_certificates.rs index d8c1c2c526..d4aaefcb2b 100644 --- a/streamer/src/tls_certificates.rs +++ b/streamer/src/tls_certificates.rs @@ -1,15 +1,15 @@ use { pkcs8::{der::Document, AlgorithmIdentifier, ObjectIdentifier}, - rcgen::{CertificateParams, DistinguishedName, DnType, SanType}, + rcgen::{CertificateParams, DistinguishedName, DnType, RcgenError, SanType}, solana_sdk::{pubkey::Pubkey, signature::Keypair}, - std::{error::Error, net::IpAddr}, + std::net::IpAddr, x509_parser::{prelude::*, public_key::PublicKey}, }; pub fn new_self_signed_tls_certificate( keypair: &Keypair, san: IpAddr, -) -> Result<(rustls::Certificate, rustls::PrivateKey), Box> { +) -> Result<(rustls::Certificate, rustls::PrivateKey), RcgenError> { // TODO(terorie): Is it safe to sign the TLS cert with the identity private key? // Unfortunately, rcgen does not accept a "raw" Ed25519 key.