1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
use ed25519_dalek::{Keypair, PublicKey}; use libp2p::PeerId; use quinn_proto::crypto::Session; use quinn_proto::TransportConfig; use std::sync::Arc; pub struct CryptoConfig<K> { pub keypair: Keypair, pub psk: Option<[u8; 32]>, pub keylogger: Option<K>, pub transport: Arc<TransportConfig>, } #[cfg(feature = "noise")] impl<K> CryptoConfig<K> { fn clone_keypair(&self) -> Keypair { Keypair::from_bytes(&self.keypair.to_bytes()).expect("serde works") } } pub trait Crypto: std::fmt::Debug + Clone + 'static { type Session: Session + Unpin; type Keylogger: Send + Sync; fn new_server_config( config: &Arc<CryptoConfig<Self::Keylogger>>, ) -> <Self::Session as Session>::ServerConfig; fn new_client_config( config: &Arc<CryptoConfig<Self::Keylogger>>, remote_public: PublicKey, ) -> <Self::Session as Session>::ClientConfig; fn supported_quic_versions() -> Vec<u32>; fn default_quic_version() -> u32; fn peer_id(session: &Self::Session) -> Option<PeerId>; fn keylogger() -> Self::Keylogger; } #[cfg(feature = "noise")] #[derive(Clone, Copy, Debug)] pub struct NoiseCrypto; #[cfg(feature = "noise")] impl Crypto for NoiseCrypto { type Session = quinn_noise::NoiseSession; type Keylogger = Arc<dyn quinn_noise::KeyLog>; fn new_server_config( config: &Arc<CryptoConfig<Self::Keylogger>>, ) -> <Self::Session as Session>::ServerConfig { Arc::new( quinn_noise::NoiseServerConfig { keypair: config.clone_keypair(), psk: config.psk, keylogger: config.keylogger.clone(), supported_protocols: vec![b"libp2p".to_vec()], } .into(), ) } fn new_client_config( config: &Arc<CryptoConfig<Self::Keylogger>>, remote_public_key: PublicKey, ) -> <Self::Session as Session>::ClientConfig { quinn_noise::NoiseClientConfig { keypair: config.clone_keypair(), psk: config.psk, alpn: b"libp2p".to_vec(), remote_public_key, keylogger: config.keylogger.clone(), } .into() } fn supported_quic_versions() -> Vec<u32> { quinn_noise::SUPPORTED_QUIC_VERSIONS.to_vec() } fn default_quic_version() -> u32 { quinn_noise::DEFAULT_QUIC_VERSION } fn peer_id(session: &Self::Session) -> Option<PeerId> { use crate::ToLibp2p; Some(session.peer_identity()?.to_peer_id()) } fn keylogger() -> Self::Keylogger { Arc::new(quinn_noise::KeyLogFile::new()) } } #[cfg(feature = "tls")] #[derive(Clone, Copy, Debug)] pub struct TlsCrypto; #[cfg(feature = "tls")] impl Crypto for TlsCrypto { type Session = quinn_proto::crypto::rustls::TlsSession; type Keylogger = Arc<dyn rustls::KeyLog>; fn new_server_config( config: &Arc<CryptoConfig<Self::Keylogger>>, ) -> <Self::Session as Session>::ServerConfig { assert!(config.psk.is_none(), "invalid config"); use crate::ToLibp2p; let mut server = crate::tls::make_server_config(&config.keypair.to_keypair()).expect("invalid config"); if let Some(key_log) = config.keylogger.clone() { server.key_log = key_log; } Arc::new(server) } fn new_client_config( config: &Arc<CryptoConfig<Self::Keylogger>>, remote_public: PublicKey, ) -> <Self::Session as Session>::ClientConfig { assert!(config.psk.is_none(), "invalid config"); use crate::ToLibp2p; let mut client = crate::tls::make_client_config( &config.keypair.to_keypair(), remote_public.to_peer_id(), ) .expect("invalid config"); if let Some(key_log) = config.keylogger.clone() { client.key_log = key_log; } Arc::new(client) } fn supported_quic_versions() -> Vec<u32> { quinn_proto::DEFAULT_SUPPORTED_VERSIONS.to_vec() } fn default_quic_version() -> u32 { quinn_proto::DEFAULT_SUPPORTED_VERSIONS[0] } fn peer_id(session: &Self::Session) -> Option<PeerId> { let certificate = session.get_peer_certificates()?.into_iter().next()?; Some(crate::tls::extract_peerid_or_panic( quinn_proto::Certificate::from(certificate).as_der(), )) } fn keylogger() -> Self::Keylogger { Arc::new(rustls::KeyLogFile::new()) } }