Create QUIC extension traits for ClientSession/ServerSession

This commit is contained in:
Dirkjan Ochtman 2018-04-24 13:58:06 +02:00 committed by ctz
parent 4a9c00ba8f
commit 9808983de7
6 changed files with 84 additions and 3 deletions

View File

@ -21,6 +21,7 @@ sct = "0.3"
default = ["logging"]
logging = ["log"]
dangerous_configuration = []
quic = []
[dev-dependencies]
log = "0.4"

View File

@ -439,7 +439,7 @@ impl ClientSessionImpl {
#[derive(Debug)]
pub struct ClientSession {
// We use the pimpl idiom to hide unimportant details.
imp: ClientSessionImpl,
pub(crate) imp: ClientSessionImpl,
}
impl ClientSession {

View File

@ -292,6 +292,19 @@ pub use keylog::{KeyLog, NoKeyLog, KeyLogFile};
/// Message signing interfaces and implementations.
pub mod sign;
#[cfg(feature = "quic")]
/// APIs for implementing QUIC TLS
pub mod quic;
#[cfg(not(feature = "quic"))]
// If QUIC support is disabled, just define a private module with an empty
// trait to allow Session having QuicExt as a trait bound.
mod quic {
pub trait QuicExt {}
impl QuicExt for super::ClientSession {}
impl QuicExt for super::ServerSession {}
}
#[cfg(feature = "dangerous_configuration")]
pub use verify::{ServerCertVerifier, ServerCertVerified,
ClientCertVerifier, ClientCertVerified};

66
src/quic.rs Normal file
View File

@ -0,0 +1,66 @@
/// This module contains optional APIs for implementing QUIC TLS.
use client::{ClientConfig, ClientSession, ClientSessionImpl};
use msgs::base::Payload;
use msgs::enums::ExtensionType;
use msgs::handshake::{ClientExtension, ServerExtension, UnknownExtension};
use server::{ServerConfig, ServerSession, ServerSessionImpl};
use std::sync::Arc;
use webpki;
/// Generic methods for QUIC sessions
pub trait QuicExt {
/// Return the TLS-encoded transport parameters for the session's peer.
fn get_quic_transport_parameters(&self) -> Option<&[u8]>;
}
impl QuicExt for ClientSession {
fn get_quic_transport_parameters(&self) -> Option<&[u8]> {
self.imp.quic_params.as_ref().map(|v| v.as_ref())
}
}
impl QuicExt for ServerSession {
fn get_quic_transport_parameters(&self) -> Option<&[u8]> {
self.imp.quic_params.as_ref().map(|v| v.as_ref())
}
}
/// Methods specific to QUIC client sessions
pub trait ClientQuicExt {
/// Make a new QUIC ClientSession. This differs from `ClientSession::new()`
/// in that it takes an extra argument, `params`, which contains the
/// TLS-encoded transport parameters to send.
fn new_quic(config: &Arc<ClientConfig>, hostname: webpki::DNSNameRef, params: Vec<u8>)
-> ClientSession {
let mut imp = ClientSessionImpl::new(config);
imp.start_handshake(hostname.into(), vec![
ClientExtension::Unknown(UnknownExtension {
typ: ExtensionType::TransportParameters,
payload: Payload::new(params),
})
]);
ClientSession { imp }
}
}
impl ClientQuicExt for ClientSession {}
/// Methods specific to QUIC server sessions
pub trait ServerQuicExt {
/// Make a new QUIC ServerSession. This differs from `ServerSession::new()`
/// in that it takes an extra argument, `params`, which contains the
/// TLS-encoded transport parameters to send.
fn new_quic(config: &Arc<ServerConfig>, params: Vec<u8>) -> ServerSession {
ServerSession {
imp: ServerSessionImpl::new(config, vec![
ServerExtension::Unknown(UnknownExtension {
typ: ExtensionType::TransportParameters,
payload: Payload::new(params),
}),
]),
}
}
}
impl ServerQuicExt for ServerSession {}

View File

@ -408,7 +408,7 @@ impl ServerSessionImpl {
#[derive(Debug)]
pub struct ServerSession {
// We use the pimpl idiom to hide unimportant details.
imp: ServerSessionImpl,
pub(crate) imp: ServerSessionImpl,
}
impl ServerSession {

View File

@ -16,12 +16,13 @@ use key;
use key_schedule::{SecretKind, KeySchedule};
use prf;
use rand;
use quic;
use std::io;
use std::collections::VecDeque;
/// Generalises `ClientSession` and `ServerSession`
pub trait Session: Read + Write + Send + Sync {
pub trait Session: quic::QuicExt + Read + Write + Send + Sync {
/// Read TLS content from `rd`. This method does internal
/// buffering, so `rd` can supply TLS messages in arbitrary-
/// sized chunks (like a socket or pipe might).