#[cfg(test)]
mod tests {
use crate::{
callbacks::{SessionTicket, SessionTicketCallback},
config::ConnectionInitializer,
connection::{self, Connection},
testing::*,
};
use futures_test::task::noop_waker;
use std::{error::Error, sync::Mutex, time::SystemTime};
#[derive(Default, Clone)]
pub struct SessionTicketHandler {
stored_ticket: Arc<Mutex<Option<Vec<u8>>>>,
}
impl SessionTicketCallback for SessionTicketHandler {
fn on_session_ticket(
&self,
_connection: &mut connection::Connection,
session_ticket: &SessionTicket,
) {
let size = session_ticket.len().unwrap();
let mut data = vec![0; size];
session_ticket.data(&mut data).unwrap();
let mut ptr = (*self.stored_ticket).lock().unwrap();
if ptr.is_none() {
*ptr = Some(data);
}
}
}
impl ConnectionInitializer for SessionTicketHandler {
fn initialize_connection(
&self,
connection: &mut crate::connection::Connection,
) -> crate::callbacks::ConnectionFutureResult {
if let Some(ticket) = (*self.stored_ticket).lock().unwrap().as_deref() {
connection.set_session_ticket(ticket)?;
}
Ok(None)
}
}
const KEY: [u8; 16] = [0; 16];
const KEYNAME: [u8; 3] = [1, 3, 4];
fn validate_session_ticket(conn: &Connection) -> Result<(), Box<dyn Error>> {
assert!(conn.session_ticket_length()? > 0);
let mut session = vec![0; conn.session_ticket_length()?];
assert_eq!(
conn.session_ticket(&mut session)?,
conn.session_ticket_length()?
);
assert_ne!(session, vec![0; conn.session_ticket_length()?]);
Ok(())
}
#[test]
fn resume_tls12_session() -> Result<(), Box<dyn Error>> {
let keypair = CertKeyPair::default();
let mut server_config_builder = Builder::new();
server_config_builder
.add_session_ticket_key(&KEYNAME, &KEY, SystemTime::now())?
.set_security_policy(&security::TESTING_TLS12)?
.load_pem(keypair.cert(), keypair.key())?;
let server_config = server_config_builder.build()?;
let handler = SessionTicketHandler::default();
let mut client_config_builder = Builder::new();
client_config_builder
.enable_session_tickets(true)?
.set_session_ticket_callback(handler.clone())?
.trust_pem(keypair.cert())?
.set_verify_host_callback(InsecureAcceptAllCertificatesHandler {})?
.set_security_policy(&security::TESTING_TLS12)?
.set_connection_initializer(handler)?;
let client_config = client_config_builder.build()?;
{
let mut pair = TestPair::from_configs(&client_config, &server_config);
pair.client.set_waker(Some(&noop_waker()))?;
pair.handshake()?;
assert!(!pair.client.resumed());
validate_session_ticket(&pair.client)?;
}
{
let mut pair = TestPair::from_configs(&client_config, &server_config);
pair.client.set_waker(Some(&noop_waker()))?;
pair.handshake()?;
assert!(pair.client.resumed());
validate_session_ticket(&pair.client)?;
validate_session_ticket(&pair.server)?;
}
Ok(())
}
#[test]
fn resume_tls13_session() -> Result<(), Box<dyn Error>> {
let keypair = CertKeyPair::default();
let mut server_config_builder = Builder::new();
server_config_builder
.add_session_ticket_key(&KEYNAME, &KEY, SystemTime::now())?
.load_pem(keypair.cert(), keypair.key())?
.set_security_policy(&security::DEFAULT_TLS13)?;
let server_config = server_config_builder.build()?;
let handler = SessionTicketHandler::default();
let mut client_config_builder = Builder::new();
client_config_builder
.enable_session_tickets(true)?
.set_session_ticket_callback(handler.clone())?
.set_connection_initializer(handler)?
.trust_pem(keypair.cert())?
.set_verify_host_callback(InsecureAcceptAllCertificatesHandler {})?
.set_security_policy(&security::DEFAULT_TLS13)?;
let client_config = client_config_builder.build()?;
for expected_resumption in [false, true] {
let mut pair = TestPair::from_configs(&client_config, &server_config);
pair.client.set_waker(Some(&noop_waker()))?;
pair.handshake()?;
assert!(pair.client.poll_recv(&mut [0]).is_pending());
assert_eq!(pair.client.resumed(), expected_resumption);
validate_session_ticket(&pair.client)?;
}
Ok(())
}
}