|  | @@ -1,9 +1,12 @@
 | 
											
												
													
														|  |  //! Code which enables sending messages between processes in the blocktree system.
 |  |  //! Code which enables sending messages between processes in the blocktree system.
 | 
											
												
													
														|  |  use btlib::{
 |  |  use btlib::{
 | 
											
												
													
														|  |      bterr,
 |  |      bterr,
 | 
											
												
													
														|  | -    crypto::{rand_array, ConcreteCreds, CredsPriv, CredsPub},
 |  | 
 | 
											
												
													
														|  | 
 |  | +    crypto::{
 | 
											
												
													
														|  | 
 |  | +        rand_array, AsymKey, ConcreteCreds, CredsPriv, CredsPub, HashKind, Private, Scheme, Sign,
 | 
											
												
													
														|  | 
 |  | +        Signer, Verifier,
 | 
											
												
													
														|  | 
 |  | +    },
 | 
											
												
													
														|  |      error::BoxInIoErr,
 |  |      error::BoxInIoErr,
 | 
											
												
													
														|  | -    BlockPath, Result,
 |  | 
 | 
											
												
													
														|  | 
 |  | +    BlockPath, Principal, Result, Writecap,
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  |  use btserde::{read_from, write_to};
 |  |  use btserde::{read_from, write_to};
 | 
											
												
													
														|  |  use bytes::{BufMut, BytesMut};
 |  |  use bytes::{BufMut, BytesMut};
 | 
											
										
											
												
													
														|  | @@ -23,7 +26,12 @@ use lazy_static::lazy_static;
 | 
											
												
													
														|  |  use log::error;
 |  |  use log::error;
 | 
											
												
													
														|  |  use quinn::{ClientConfig, Endpoint, SendStream, ServerConfig};
 |  |  use quinn::{ClientConfig, Endpoint, SendStream, ServerConfig};
 | 
											
												
													
														|  |  use rustls::{
 |  |  use rustls::{
 | 
											
												
													
														|  | -    Certificate, ConfigBuilder, ConfigSide, PrivateKey, WantsCipherSuites, WantsVerifier,
 |  | 
 | 
											
												
													
														|  | 
 |  | +    client::ResolvesClientCert,
 | 
											
												
													
														|  | 
 |  | +    internal::msgs::base::PayloadU16,
 | 
											
												
													
														|  | 
 |  | +    server::ClientCertVerified,
 | 
											
												
													
														|  | 
 |  | +    sign::{CertifiedKey, SigningKey},
 | 
											
												
													
														|  | 
 |  | +    Certificate, ConfigBuilder, ConfigSide, PrivateKey, SignatureAlgorithm, SignatureScheme,
 | 
											
												
													
														|  | 
 |  | +    WantsCipherSuites, WantsVerifier,
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  |  use serde::{de::DeserializeOwned, Deserialize, Serialize};
 |  |  use serde::{de::DeserializeOwned, Deserialize, Serialize};
 | 
											
												
													
														|  |  use std::{
 |  |  use std::{
 | 
											
										
											
												
													
														|  | @@ -55,7 +63,7 @@ mod private {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      /// Returns a [Router] which can be used to make a [Receiver] for the given path and
 |  |      /// Returns a [Router] which can be used to make a [Receiver] for the given path and
 | 
											
												
													
														|  |      ///  [Sender] instances for any path.
 |  |      ///  [Sender] instances for any path.
 | 
											
												
													
														|  | -    pub fn router(addr: Arc<BlockAddr>, creds: &ConcreteCreds) -> Result<impl Router> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    pub fn router(addr: Arc<BlockAddr>, creds: Arc<ConcreteCreds>) -> Result<impl Router> {
 | 
											
												
													
														|  |          QuicRouter::new(addr, creds)
 |  |          QuicRouter::new(addr, creds)
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -91,20 +99,196 @@ mod private {
 | 
											
												
													
														|  |          for cert in chain {
 |  |          for cert in chain {
 | 
											
												
													
														|  |              cert_chain.push(Certificate(cert))
 |  |              cert_chain.push(Certificate(cert))
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        let key = PrivateKey(creds.private_sign().to_der()?);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let key = PrivateKey(creds.sign_pair().private().to_der()?);
 | 
											
												
													
														|  |          let server_config = common_config(rustls::ServerConfig::builder())?
 |  |          let server_config = common_config(rustls::ServerConfig::builder())?
 | 
											
												
													
														|  | -            .with_no_client_auth()
 |  | 
 | 
											
												
													
														|  | 
 |  | +            .with_client_cert_verifier(Arc::new(ClientCertVerifier))
 | 
											
												
													
														|  |              .with_single_cert(cert_chain, key)?;
 |  |              .with_single_cert(cert_chain, key)?;
 | 
											
												
													
														|  |          Ok(ServerConfig::with_crypto(Arc::new(server_config)))
 |  |          Ok(ServerConfig::with_crypto(Arc::new(server_config)))
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    fn client_config() -> Result<ClientConfig> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +    fn client_config(
 | 
											
												
													
														|  | 
 |  | +        server_path: Arc<BlockPath>,
 | 
											
												
													
														|  | 
 |  | +        creds: Arc<ConcreteCreds>,
 | 
											
												
													
														|  | 
 |  | +    ) -> Result<ClientConfig> {
 | 
											
												
													
														|  |          let client_config = common_config(rustls::ClientConfig::builder())?
 |  |          let client_config = common_config(rustls::ClientConfig::builder())?
 | 
											
												
													
														|  | -            .with_custom_certificate_verifier(CertVerifier::new())
 |  | 
 | 
											
												
													
														|  | -            .with_no_client_auth();
 |  | 
 | 
											
												
													
														|  | 
 |  | +            .with_custom_certificate_verifier(Arc::new(ServerCertVerifier::new(server_path)))
 | 
											
												
													
														|  | 
 |  | +            .with_client_cert_resolver(Arc::new(ClientCertResolver::new(creds)?));
 | 
											
												
													
														|  |          Ok(ClientConfig::new(Arc::new(client_config)))
 |  |          Ok(ClientConfig::new(Arc::new(client_config)))
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    fn to_cert_err(err: btlib::Error) -> rustls::Error {
 | 
											
												
													
														|  | 
 |  | +        rustls::Error::InvalidCertificateData(err.to_string())
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    struct ServerCertVerifier {
 | 
											
												
													
														|  | 
 |  | +        peer_path: Arc<BlockPath>,
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl ServerCertVerifier {
 | 
											
												
													
														|  | 
 |  | +        fn new(path: Arc<BlockPath>) -> Self {
 | 
											
												
													
														|  | 
 |  | +            Self { peer_path: path }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl rustls::client::ServerCertVerifier for ServerCertVerifier {
 | 
											
												
													
														|  | 
 |  | +        fn verify_server_cert(
 | 
											
												
													
														|  | 
 |  | +            &self,
 | 
											
												
													
														|  | 
 |  | +            end_entity: &Certificate,
 | 
											
												
													
														|  | 
 |  | +            intermediates: &[Certificate],
 | 
											
												
													
														|  | 
 |  | +            _server_name: &rustls::ServerName,
 | 
											
												
													
														|  | 
 |  | +            _scts: &mut dyn Iterator<Item = &[u8]>,
 | 
											
												
													
														|  | 
 |  | +            _ocsp_response: &[u8],
 | 
											
												
													
														|  | 
 |  | +            _now: std::time::SystemTime,
 | 
											
												
													
														|  | 
 |  | +        ) -> std::result::Result<rustls::client::ServerCertVerified, rustls::Error> {
 | 
											
												
													
														|  | 
 |  | +            let (writecap, ..) =
 | 
											
												
													
														|  | 
 |  | +                Writecap::from_cert_chain(end_entity, intermediates).map_err(to_cert_err)?;
 | 
											
												
													
														|  | 
 |  | +            writecap
 | 
											
												
													
														|  | 
 |  | +                .assert_valid_for(&self.peer_path)
 | 
											
												
													
														|  | 
 |  | +                .map_err(to_cert_err)?;
 | 
											
												
													
														|  | 
 |  | +            Ok(rustls::client::ServerCertVerified::assertion())
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    struct ClientCertVerifier;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl rustls::server::ClientCertVerifier for ClientCertVerifier {
 | 
											
												
													
														|  | 
 |  | +        fn verify_client_cert(
 | 
											
												
													
														|  | 
 |  | +            &self,
 | 
											
												
													
														|  | 
 |  | +            end_entity: &Certificate,
 | 
											
												
													
														|  | 
 |  | +            intermediates: &[Certificate],
 | 
											
												
													
														|  | 
 |  | +            _now: std::time::SystemTime,
 | 
											
												
													
														|  | 
 |  | +        ) -> std::result::Result<rustls::server::ClientCertVerified, rustls::Error> {
 | 
											
												
													
														|  | 
 |  | +            let (writecap, ..) =
 | 
											
												
													
														|  | 
 |  | +                Writecap::from_cert_chain(end_entity, intermediates).map_err(to_cert_err)?;
 | 
											
												
													
														|  | 
 |  | +            writecap
 | 
											
												
													
														|  | 
 |  | +                .assert_valid_for(writecap.path())
 | 
											
												
													
														|  | 
 |  | +                .map_err(to_cert_err)?;
 | 
											
												
													
														|  | 
 |  | +            Ok(ClientCertVerified::assertion())
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        fn client_auth_root_subjects(&self) -> Option<rustls::DistinguishedNames> {
 | 
											
												
													
														|  | 
 |  | +            let der = match Principal::default().to_name_der() {
 | 
											
												
													
														|  | 
 |  | +                Ok(der) => der,
 | 
											
												
													
														|  | 
 |  | +                Err(err) => {
 | 
											
												
													
														|  | 
 |  | +                    error!("failed to create distinguished name from root principal: {err}");
 | 
											
												
													
														|  | 
 |  | +                    return None;
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +            };
 | 
											
												
													
														|  | 
 |  | +            Some(vec![PayloadU16(der)])
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        fn verify_tls13_signature(
 | 
											
												
													
														|  | 
 |  | +            &self,
 | 
											
												
													
														|  | 
 |  | +            message: &[u8],
 | 
											
												
													
														|  | 
 |  | +            cert: &Certificate,
 | 
											
												
													
														|  | 
 |  | +            dss: &rustls::DigitallySignedStruct,
 | 
											
												
													
														|  | 
 |  | +        ) -> std::result::Result<rustls::client::HandshakeSignatureValid, rustls::Error> {
 | 
											
												
													
														|  | 
 |  | +            let (_, subject_key) = Writecap::from_cert_chain(cert, &[]).map_err(to_cert_err)?;
 | 
											
												
													
														|  | 
 |  | +            subject_key
 | 
											
												
													
														|  | 
 |  | +                .verify(std::iter::once(message), dss.signature())
 | 
											
												
													
														|  | 
 |  | +                .map_err(|_| rustls::Error::InvalidCertificateSignature)?;
 | 
											
												
													
														|  | 
 |  | +            Ok(rustls::client::HandshakeSignatureValid::assertion())
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    struct ClientCertResolver {
 | 
											
												
													
														|  | 
 |  | +        cert_key: Arc<CertifiedKey>,
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl ClientCertResolver {
 | 
											
												
													
														|  | 
 |  | +        fn new(creds: Arc<ConcreteCreds>) -> Result<Self> {
 | 
											
												
													
														|  | 
 |  | +            let writecap = creds.writecap().ok_or(btlib::BlockError::MissingWritecap)?;
 | 
											
												
													
														|  | 
 |  | +            let sign_pair = creds.sign_pair();
 | 
											
												
													
														|  | 
 |  | +            let chain = writecap.to_cert_chain(sign_pair.public())?;
 | 
											
												
													
														|  | 
 |  | +            let mut certs = Vec::with_capacity(chain.len());
 | 
											
												
													
														|  | 
 |  | +            for cert in chain {
 | 
											
												
													
														|  | 
 |  | +                certs.push(Certificate(cert))
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            let key = Arc::new(SignKey(creds));
 | 
											
												
													
														|  | 
 |  | +            let cert_key = Arc::new(CertifiedKey {
 | 
											
												
													
														|  | 
 |  | +                cert: certs,
 | 
											
												
													
														|  | 
 |  | +                key,
 | 
											
												
													
														|  | 
 |  | +                ocsp: None,
 | 
											
												
													
														|  | 
 |  | +                sct_list: None,
 | 
											
												
													
														|  | 
 |  | +            });
 | 
											
												
													
														|  | 
 |  | +            Ok(Self { cert_key })
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl ResolvesClientCert for ClientCertResolver {
 | 
											
												
													
														|  | 
 |  | +        fn resolve(
 | 
											
												
													
														|  | 
 |  | +            &self,
 | 
											
												
													
														|  | 
 |  | +            _acceptable_issuers: &[&[u8]],
 | 
											
												
													
														|  | 
 |  | +            _sigschemes: &[rustls::SignatureScheme],
 | 
											
												
													
														|  | 
 |  | +        ) -> Option<Arc<rustls::sign::CertifiedKey>> {
 | 
											
												
													
														|  | 
 |  | +            Some(self.cert_key.clone())
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        fn has_certs(&self) -> bool {
 | 
											
												
													
														|  | 
 |  | +            true
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    trait SignExt {
 | 
											
												
													
														|  | 
 |  | +        fn as_signature_scheme(&self) -> rustls::SignatureScheme;
 | 
											
												
													
														|  | 
 |  | +        fn as_signature_algorithm(&self) -> rustls::SignatureAlgorithm;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl SignExt for Sign {
 | 
											
												
													
														|  | 
 |  | +        fn as_signature_scheme(&self) -> SignatureScheme {
 | 
											
												
													
														|  | 
 |  | +            match self {
 | 
											
												
													
														|  | 
 |  | +                Self::RsaSsaPss(scheme) => match scheme.hash_kind() {
 | 
											
												
													
														|  | 
 |  | +                    HashKind::Sha2_256 => SignatureScheme::RSA_PSS_SHA256,
 | 
											
												
													
														|  | 
 |  | +                    HashKind::Sha2_512 => SignatureScheme::RSA_PSS_SHA512,
 | 
											
												
													
														|  | 
 |  | +                },
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        fn as_signature_algorithm(&self) -> SignatureAlgorithm {
 | 
											
												
													
														|  | 
 |  | +            match self {
 | 
											
												
													
														|  | 
 |  | +                Self::RsaSsaPss(..) => SignatureAlgorithm::RSA,
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    struct SignKey(Arc<ConcreteCreds>);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl SignKey {
 | 
											
												
													
														|  | 
 |  | +        fn key(&self) -> &AsymKey<Private, Sign> {
 | 
											
												
													
														|  | 
 |  | +            self.0.sign_pair().private()
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl SigningKey for SignKey {
 | 
											
												
													
														|  | 
 |  | +        fn choose_scheme(
 | 
											
												
													
														|  | 
 |  | +            &self,
 | 
											
												
													
														|  | 
 |  | +            offered: &[rustls::SignatureScheme],
 | 
											
												
													
														|  | 
 |  | +        ) -> Option<Box<dyn rustls::sign::Signer>> {
 | 
											
												
													
														|  | 
 |  | +            if offered.contains(&self.key().scheme().as_signature_scheme()) {
 | 
											
												
													
														|  | 
 |  | +                Some(Box::new(SignKey(self.0.clone())))
 | 
											
												
													
														|  | 
 |  | +            } else {
 | 
											
												
													
														|  | 
 |  | +                None
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        fn algorithm(&self) -> rustls::SignatureAlgorithm {
 | 
											
												
													
														|  | 
 |  | +            self.key().scheme().as_signature_algorithm()
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    impl rustls::sign::Signer for SignKey {
 | 
											
												
													
														|  | 
 |  | +        fn sign(&self, message: &[u8]) -> std::result::Result<Vec<u8>, rustls::Error> {
 | 
											
												
													
														|  | 
 |  | +            self.0
 | 
											
												
													
														|  | 
 |  | +                .sign(std::iter::once(message))
 | 
											
												
													
														|  | 
 |  | +                .map(|sig| sig.take_data())
 | 
											
												
													
														|  | 
 |  | +                .map_err(|err| rustls::Error::General(err.to_string()))
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        fn scheme(&self) -> rustls::SignatureScheme {
 | 
											
												
													
														|  | 
 |  | +            self.key().scheme().as_signature_scheme()
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      /// An identifier for a block. Persistent blocks (files, directories, and servers) are
 |  |      /// An identifier for a block. Persistent blocks (files, directories, and servers) are
 | 
											
												
													
														|  |      /// identified by the `Inode` variant and transient blocks (processes) are identified by the
 |  |      /// identified by the `Inode` variant and transient blocks (processes) are identified by the
 | 
											
												
													
														|  |      /// PID variant.
 |  |      /// PID variant.
 | 
											
										
											
												
													
														|  | @@ -470,15 +654,17 @@ mod private {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      struct QuicRouter {
 |  |      struct QuicRouter {
 | 
											
												
													
														|  |          recv_addr: Arc<BlockAddr>,
 |  |          recv_addr: Arc<BlockAddr>,
 | 
											
												
													
														|  | 
 |  | +        creds: Arc<ConcreteCreds>,
 | 
											
												
													
														|  |          endpoint: Endpoint,
 |  |          endpoint: Endpoint,
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      impl QuicRouter {
 |  |      impl QuicRouter {
 | 
											
												
													
														|  | -        fn new(recv_addr: Arc<BlockAddr>, creds: &ConcreteCreds) -> Result<Self> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        fn new(recv_addr: Arc<BlockAddr>, creds: Arc<ConcreteCreds>) -> Result<Self> {
 | 
											
												
													
														|  |              let socket_addr = recv_addr.socket_addr();
 |  |              let socket_addr = recv_addr.socket_addr();
 | 
											
												
													
														|  | -            let endpoint = Endpoint::server(server_config(creds)?, socket_addr)?;
 |  | 
 | 
											
												
													
														|  | 
 |  | +            let endpoint = Endpoint::server(server_config(creds.as_ref())?, socket_addr)?;
 | 
											
												
													
														|  |              Ok(Self {
 |  |              Ok(Self {
 | 
											
												
													
														|  |                  endpoint,
 |  |                  endpoint,
 | 
											
												
													
														|  | 
 |  | +                creds,
 | 
											
												
													
														|  |                  recv_addr,
 |  |                  recv_addr,
 | 
											
												
													
														|  |              })
 |  |              })
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
										
											
												
													
														|  | @@ -502,7 +688,9 @@ mod private {
 | 
											
												
													
														|  |          type SenderFut<'a> = Pin<Box<dyn 'a + Future<Output = Result<QuicSender>> + Send>>;
 |  |          type SenderFut<'a> = Pin<Box<dyn 'a + Future<Output = Result<QuicSender>> + Send>>;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          fn sender(&self, addr: Arc<BlockAddr>) -> Self::SenderFut<'_> {
 |  |          fn sender(&self, addr: Arc<BlockAddr>) -> Self::SenderFut<'_> {
 | 
											
												
													
														|  | -            Box::pin(async { QuicSender::from_endpoint(self.endpoint.clone(), addr).await })
 |  | 
 | 
											
												
													
														|  | 
 |  | +            Box::pin(async {
 | 
											
												
													
														|  | 
 |  | +                QuicSender::from_endpoint(self.endpoint.clone(), addr, self.creds.clone()).await
 | 
											
												
													
														|  | 
 |  | +            })
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -587,38 +775,24 @@ mod private {
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    struct CertVerifier;
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    impl CertVerifier {
 |  | 
 | 
											
												
													
														|  | -        fn new() -> Arc<Self> {
 |  | 
 | 
											
												
													
														|  | -            Arc::new(Self)
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    impl rustls::client::ServerCertVerifier for CertVerifier {
 |  | 
 | 
											
												
													
														|  | -        fn verify_server_cert(
 |  | 
 | 
											
												
													
														|  | -            &self,
 |  | 
 | 
											
												
													
														|  | -            _end_entity: &Certificate,
 |  | 
 | 
											
												
													
														|  | -            _intermediates: &[Certificate],
 |  | 
 | 
											
												
													
														|  | -            _server_name: &rustls::ServerName,
 |  | 
 | 
											
												
													
														|  | -            _scts: &mut dyn Iterator<Item = &[u8]>,
 |  | 
 | 
											
												
													
														|  | -            _ocsp_response: &[u8],
 |  | 
 | 
											
												
													
														|  | -            _now: std::time::SystemTime,
 |  | 
 | 
											
												
													
														|  | -        ) -> std::result::Result<rustls::client::ServerCertVerified, rustls::Error> {
 |  | 
 | 
											
												
													
														|  | -            // TODO: Implement certificate verification.
 |  | 
 | 
											
												
													
														|  | -            Ok(rustls::client::ServerCertVerified::assertion())
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |      struct QuicSender {
 |  |      struct QuicSender {
 | 
											
												
													
														|  |          addr: Arc<BlockAddr>,
 |  |          addr: Arc<BlockAddr>,
 | 
											
												
													
														|  |          sink: FramedWrite<SendStream, MsgEncoder>,
 |  |          sink: FramedWrite<SendStream, MsgEncoder>,
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      impl QuicSender {
 |  |      impl QuicSender {
 | 
											
												
													
														|  | -        async fn from_endpoint(endpoint: Endpoint, addr: Arc<BlockAddr>) -> Result<Self> {
 |  | 
 | 
											
												
													
														|  | 
 |  | +        async fn from_endpoint(
 | 
											
												
													
														|  | 
 |  | +            endpoint: Endpoint,
 | 
											
												
													
														|  | 
 |  | +            addr: Arc<BlockAddr>,
 | 
											
												
													
														|  | 
 |  | +            creds: Arc<ConcreteCreds>,
 | 
											
												
													
														|  | 
 |  | +        ) -> Result<Self> {
 | 
											
												
													
														|  |              let socket_addr = addr.socket_addr();
 |  |              let socket_addr = addr.socket_addr();
 | 
											
												
													
														|  | -            let connecting = endpoint.connect_with(client_config()?, socket_addr, "localhost")?;
 |  | 
 | 
											
												
													
														|  | 
 |  | +            let connecting = endpoint.connect_with(
 | 
											
												
													
														|  | 
 |  | +                client_config(addr.path.clone(), creds)?,
 | 
											
												
													
														|  | 
 |  | +                socket_addr,
 | 
											
												
													
														|  | 
 |  | +                // The ServerCertVerifier ensures we connect to the correct path.
 | 
											
												
													
														|  | 
 |  | +                "INDETERMINANT",
 | 
											
												
													
														|  | 
 |  | +            )?;
 | 
											
												
													
														|  |              let connection = connecting.await?;
 |  |              let connection = connecting.await?;
 | 
											
												
													
														|  |              let send_stream = connection.open_uni().await?;
 |  |              let send_stream = connection.open_uni().await?;
 | 
											
												
													
														|  |              let sink = FramedWrite::new(send_stream, MsgEncoder::new());
 |  |              let sink = FramedWrite::new(send_stream, MsgEncoder::new());
 | 
											
										
											
												
													
														|  | @@ -738,7 +912,7 @@ mod tests {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          async fn endpoint(&self, inode: u64) -> (impl Sender, impl Receiver<BodyOwned>) {
 |  |          async fn endpoint(&self, inode: u64) -> (impl Sender, impl Receiver<BodyOwned>) {
 | 
											
												
													
														|  |              let addr = Arc::new(block_addr([self.instance_num, inode].iter()));
 |  |              let addr = Arc::new(block_addr([self.instance_num, inode].iter()));
 | 
											
												
													
														|  | -            let router = router(addr.clone(), &NODE_CREDS).unwrap();
 |  | 
 | 
											
												
													
														|  | 
 |  | +            let router = router(addr.clone(), Arc::new(NODE_CREDS.clone())).unwrap();
 | 
											
												
													
														|  |              let receiver = router.receiver::<BodyOwned>().await.unwrap();
 |  |              let receiver = router.receiver::<BodyOwned>().await.unwrap();
 | 
											
												
													
														|  |              let sender = router.sender(addr).await.unwrap();
 |  |              let sender = router.sender(addr).await.unwrap();
 | 
											
												
													
														|  |              (sender, receiver)
 |  |              (sender, receiver)
 |