mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-25 04:35:17 +00:00
Erase crypto::Session::HmacKey
EndpointConfig::default now depends on ring
This commit is contained in:
+18
-33
@@ -8,7 +8,7 @@ use crate::crypto::types::{Certificate, CertificateChain, PrivateKey};
|
||||
use crate::{
|
||||
cid_generator::{ConnectionIdGenerator, RandomConnectionIdGenerator},
|
||||
congestion,
|
||||
crypto::{self, HandshakeTokenKey as _, HmacKey as _},
|
||||
crypto::{self, HandshakeTokenKey as _, HmacKey},
|
||||
VarInt, VarIntBoundsExceeded, DEFAULT_SUPPORTED_VERSIONS,
|
||||
};
|
||||
|
||||
@@ -300,11 +300,9 @@ impl fmt::Debug for TransportConfig {
|
||||
/// Global configuration for the endpoint, affecting all connections
|
||||
///
|
||||
/// Default values should be suitable for most internet applications.
|
||||
pub struct EndpointConfig<S>
|
||||
where
|
||||
S: crypto::Session,
|
||||
{
|
||||
pub(crate) reset_key: Arc<S::HmacKey>,
|
||||
#[derive(Clone)]
|
||||
pub struct EndpointConfig {
|
||||
pub(crate) reset_key: Arc<dyn HmacKey>,
|
||||
pub(crate) max_udp_payload_size: VarInt,
|
||||
/// CID generator factory
|
||||
///
|
||||
@@ -315,16 +313,13 @@ where
|
||||
pub(crate) initial_version: u32,
|
||||
}
|
||||
|
||||
impl<S> EndpointConfig<S>
|
||||
where
|
||||
S: crypto::Session,
|
||||
{
|
||||
impl EndpointConfig {
|
||||
/// Create a default config with a particular `reset_key`
|
||||
pub fn new(reset_key: S::HmacKey) -> Self {
|
||||
pub fn new(reset_key: Arc<dyn HmacKey>) -> Self {
|
||||
let cid_factory: fn() -> Box<dyn ConnectionIdGenerator> =
|
||||
|| Box::new(RandomConnectionIdGenerator::default());
|
||||
Self {
|
||||
reset_key: Arc::new(reset_key),
|
||||
reset_key,
|
||||
max_udp_payload_size: 1480u32.into(), // Typical internet MTU minus IPv4 and UDP overhead, rounded up to a multiple of 8
|
||||
connection_id_generator_factory: Arc::new(cid_factory),
|
||||
initial_version: DEFAULT_SUPPORTED_VERSIONS[0],
|
||||
@@ -352,9 +347,9 @@ where
|
||||
|
||||
/// Private key used to send authenticated connection resets to peers who were
|
||||
/// communicating with a previous instance of this endpoint.
|
||||
pub fn reset_key(&mut self, value: &[u8]) -> Result<&mut Self, ConfigError> {
|
||||
self.reset_key = Arc::new(S::HmacKey::new(value)?);
|
||||
Ok(self)
|
||||
pub fn reset_key(&mut self, key: Arc<dyn HmacKey>) -> &mut Self {
|
||||
self.reset_key = key;
|
||||
self
|
||||
}
|
||||
|
||||
/// Maximum UDP payload size accepted from peers. Excludes UDP and IP overhead.
|
||||
@@ -394,7 +389,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: crypto::Session> fmt::Debug for EndpointConfig<S> {
|
||||
impl fmt::Debug for EndpointConfig {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt.debug_struct("EndpointConfig")
|
||||
.field("reset_key", &"[ elided ]")
|
||||
@@ -406,26 +401,16 @@ impl<S: crypto::Session> fmt::Debug for EndpointConfig<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: crypto::Session> Default for EndpointConfig<S> {
|
||||
#[cfg(feature = "ring")]
|
||||
impl Default for EndpointConfig {
|
||||
fn default() -> Self {
|
||||
let mut reset_key = vec![0; S::HmacKey::KEY_LEN];
|
||||
let mut reset_key = [0; 64];
|
||||
rand::thread_rng().fill_bytes(&mut reset_key);
|
||||
Self::new(
|
||||
S::HmacKey::new(&reset_key)
|
||||
.expect("HMAC key rejected random bytes; use EndpointConfig::new instead"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: crypto::Session> Clone for EndpointConfig<S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
reset_key: self.reset_key.clone(),
|
||||
max_udp_payload_size: self.max_udp_payload_size,
|
||||
connection_id_generator_factory: self.connection_id_generator_factory.clone(),
|
||||
supported_versions: self.supported_versions.clone(),
|
||||
initial_version: self.initial_version,
|
||||
}
|
||||
Self::new(Arc::new(ring::hmac::Key::new(
|
||||
ring::hmac::HMAC_SHA256,
|
||||
&reset_key,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ use std::{any::Any, str};
|
||||
use bytes::BytesMut;
|
||||
|
||||
use crate::{
|
||||
config::ConfigError, shared::ConnectionId, transport_parameters::TransportParameters,
|
||||
ConnectError, Side, TransportError,
|
||||
shared::ConnectionId, transport_parameters::TransportParameters, ConnectError, Side,
|
||||
TransportError,
|
||||
};
|
||||
|
||||
/// Cryptography interface based on *ring*
|
||||
@@ -31,8 +31,6 @@ pub(crate) mod types;
|
||||
pub trait Session: Send + Sized {
|
||||
/// Type used to hold configuration for client sessions
|
||||
type ClientConfig: ClientConfig<Self>;
|
||||
/// Type used to sign various values
|
||||
type HmacKey: HmacKey;
|
||||
/// Key used to generate one-time-use handshake token keys
|
||||
type HandshakeTokenKey: HandshakeTokenKey;
|
||||
/// Type of keys used to protect packet headers
|
||||
@@ -183,16 +181,11 @@ pub trait HeaderKey: Send {
|
||||
}
|
||||
|
||||
/// A key for signing with HMAC-based algorithms
|
||||
pub trait HmacKey: Send + Sized + Sync {
|
||||
/// Length of the key input
|
||||
const KEY_LEN: usize;
|
||||
/// Type of the signatures created by `sign()`
|
||||
type Signature: AsRef<[u8]>;
|
||||
|
||||
/// Method for creating a key
|
||||
fn new(key: &[u8]) -> Result<Self, ConfigError>;
|
||||
pub trait HmacKey: Send + Sync {
|
||||
/// Method for signing a message
|
||||
fn sign(&self, data: &[u8]) -> Self::Signature;
|
||||
fn sign(&self, data: &[u8], signature_out: &mut [u8]);
|
||||
/// Length of `sign`'s output
|
||||
fn signature_len(&self) -> usize;
|
||||
/// Method for verifying a message
|
||||
fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), CryptoError>;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
use ring::{aead, hkdf, hmac};
|
||||
|
||||
use crate::{
|
||||
config::ConfigError,
|
||||
crypto::{self, CryptoError},
|
||||
};
|
||||
use crate::crypto::{self, CryptoError};
|
||||
|
||||
impl crypto::HmacKey for hmac::Key {
|
||||
const KEY_LEN: usize = 64;
|
||||
type Signature = hmac::Tag;
|
||||
|
||||
fn new(key: &[u8]) -> Result<Self, ConfigError> {
|
||||
if key.len() == Self::KEY_LEN {
|
||||
Ok(hmac::Key::new(hmac::HMAC_SHA256, key))
|
||||
} else {
|
||||
Err(ConfigError::OutOfBounds)
|
||||
}
|
||||
fn sign(&self, data: &[u8], out: &mut [u8]) {
|
||||
out.copy_from_slice(hmac::sign(self, data).as_ref());
|
||||
}
|
||||
|
||||
fn sign(&self, data: &[u8]) -> Self::Signature {
|
||||
hmac::sign(self, data)
|
||||
fn signature_len(&self) -> usize {
|
||||
32
|
||||
}
|
||||
|
||||
fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{any::Any, convert::TryInto, io, str, sync::Arc};
|
||||
|
||||
use bytes::BytesMut;
|
||||
use ring::{aead, hkdf, hmac};
|
||||
use ring::{aead, hkdf};
|
||||
pub use rustls::Error;
|
||||
use rustls::{
|
||||
self,
|
||||
@@ -37,7 +37,6 @@ impl TlsSession {
|
||||
|
||||
impl crypto::Session for TlsSession {
|
||||
type ClientConfig = Arc<rustls::ClientConfig>;
|
||||
type HmacKey = hmac::Key;
|
||||
type HandshakeTokenKey = hkdf::Prk;
|
||||
type PacketKey = PacketKey;
|
||||
type HeaderKey = HeaderProtectionKey;
|
||||
|
||||
@@ -65,7 +65,7 @@ where
|
||||
connection_reset_tokens: ResetTokenTable,
|
||||
connections: Slab<ConnectionMeta>,
|
||||
local_cid_generator: Box<dyn ConnectionIdGenerator>,
|
||||
config: Arc<EndpointConfig<S>>,
|
||||
config: Arc<EndpointConfig>,
|
||||
server_config: Option<Arc<ServerConfig<S>>>,
|
||||
/// Whether incoming connections should be unconditionally rejected by a server
|
||||
///
|
||||
@@ -80,10 +80,7 @@ where
|
||||
/// Create a new endpoint
|
||||
///
|
||||
/// Returns `Err` if the configuration is invalid.
|
||||
pub fn new(
|
||||
config: Arc<EndpointConfig<S>>,
|
||||
server_config: Option<Arc<ServerConfig<S>>>,
|
||||
) -> Self {
|
||||
pub fn new(config: Arc<EndpointConfig>, server_config: Option<Arc<ServerConfig<S>>>) -> Self {
|
||||
Self {
|
||||
rng: StdRng::from_entropy(),
|
||||
transmits: VecDeque::new(),
|
||||
@@ -720,7 +717,7 @@ where
|
||||
}
|
||||
|
||||
/// Access the configuration used by this endpoint
|
||||
pub fn config(&self) -> &EndpointConfig<S> {
|
||||
pub fn config(&self) -> &EndpointConfig {
|
||||
&self.config
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ pub use crate::connection::{
|
||||
};
|
||||
|
||||
mod config;
|
||||
pub use config::{ConfigError, IdleTimeout, TransportConfig};
|
||||
pub use config::{ConfigError, EndpointConfig, IdleTimeout, TransportConfig};
|
||||
|
||||
pub mod crypto;
|
||||
#[cfg(feature = "rustls")]
|
||||
@@ -76,7 +76,7 @@ use token::{ResetToken, RetryToken};
|
||||
/// Types that are generic over the crypto protocol implementation
|
||||
pub mod generic {
|
||||
pub use crate::{
|
||||
config::{ClientConfig, EndpointConfig, ServerConfig},
|
||||
config::{ClientConfig, ServerConfig},
|
||||
connection::{Connection, Datagrams},
|
||||
endpoint::Endpoint,
|
||||
};
|
||||
@@ -96,8 +96,6 @@ mod rustls_impls {
|
||||
pub type Endpoint = generic::Endpoint<crypto::rustls::TlsSession>;
|
||||
/// A `ServerConfig` containing server-side rustls configuration
|
||||
pub type ServerConfig = generic::ServerConfig<crypto::rustls::TlsSession>;
|
||||
/// A `EndpointConfig` using rustls keys
|
||||
pub type EndpointConfig = generic::EndpointConfig<crypto::rustls::TlsSession>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
|
||||
@@ -137,7 +137,7 @@ fn server_stateless_reset() {
|
||||
rng.fill_bytes(&mut reset_key);
|
||||
let reset_key = hmac::Key::new(hmac::HMAC_SHA256, &reset_key);
|
||||
|
||||
let endpoint_config = Arc::new(EndpointConfig::new(reset_key));
|
||||
let endpoint_config = Arc::new(EndpointConfig::new(Arc::new(reset_key)));
|
||||
|
||||
let mut pair = Pair::new(endpoint_config.clone(), server_config());
|
||||
let (client_ch, _) = pair.connect();
|
||||
@@ -166,7 +166,7 @@ fn client_stateless_reset() {
|
||||
rng.fill_bytes(&mut reset_key);
|
||||
let reset_key = hmac::Key::new(hmac::HMAC_SHA256, &reset_key);
|
||||
|
||||
let endpoint_config = Arc::new(EndpointConfig::new(reset_key));
|
||||
let endpoint_config = Arc::new(EndpointConfig::new(Arc::new(reset_key)));
|
||||
|
||||
let mut pair = Pair::new(endpoint_config.clone(), server_config());
|
||||
let (_, server_ch) = pair.connect();
|
||||
|
||||
@@ -111,11 +111,12 @@ impl<'a> RetryToken<'a> {
|
||||
pub struct ResetToken([u8; RESET_TOKEN_SIZE]);
|
||||
|
||||
impl ResetToken {
|
||||
pub(crate) fn new(key: &impl HmacKey, id: &ConnectionId) -> Self {
|
||||
let signature = key.sign(id);
|
||||
pub(crate) fn new(key: &dyn HmacKey, id: &ConnectionId) -> Self {
|
||||
let mut signature = vec![0; key.signature_len()];
|
||||
key.sign(id, &mut signature);
|
||||
// TODO: Server ID??
|
||||
let mut result = [0; RESET_TOKEN_SIZE];
|
||||
result.copy_from_slice(&signature.as_ref()[..RESET_TOKEN_SIZE]);
|
||||
result.copy_from_slice(&signature[..RESET_TOKEN_SIZE]);
|
||||
result.into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ apply_params!(make_struct);
|
||||
impl TransportParameters {
|
||||
pub(crate) fn new<S>(
|
||||
config: &TransportConfig,
|
||||
endpoint_config: &EndpointConfig<S>,
|
||||
endpoint_config: &EndpointConfig,
|
||||
cid_gen: &dyn ConnectionIdGenerator,
|
||||
initial_src_cid: ConnectionId,
|
||||
server_config: Option<&ServerConfig<S>>,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::{io, net::SocketAddr, sync::Arc};
|
||||
|
||||
use proto::{
|
||||
generic::{ClientConfig, EndpointConfig, ServerConfig},
|
||||
ConnectionIdGenerator,
|
||||
generic::{ClientConfig, ServerConfig},
|
||||
ConnectionIdGenerator, EndpointConfig,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use tracing::error;
|
||||
@@ -22,7 +22,7 @@ where
|
||||
S: proto::crypto::Session,
|
||||
{
|
||||
server_config: Option<ServerConfig<S>>,
|
||||
config: EndpointConfig<S>,
|
||||
config: EndpointConfig,
|
||||
default_client_config: Option<ClientConfig<S>>,
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ where
|
||||
S: proto::crypto::Session + Send + 'static,
|
||||
{
|
||||
/// Start a builder with a specific initial low-level configuration
|
||||
pub fn new(config: EndpointConfig<S>, default_client_config: Option<ClientConfig<S>>) -> Self {
|
||||
pub fn new(config: EndpointConfig, default_client_config: Option<ClientConfig<S>>) -> Self {
|
||||
Self {
|
||||
server_config: None,
|
||||
config,
|
||||
@@ -112,6 +112,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tls-rustls")]
|
||||
impl<S> Default for EndpointBuilder<S>
|
||||
where
|
||||
S: proto::crypto::Session,
|
||||
|
||||
Reference in New Issue
Block a user