Skip to content

Initial server-side session ticket support #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions rustls-libssl/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions rustls-libssl/MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
| `SSL_CTX_get_info_callback` | | | |
| `SSL_CTX_get_keylog_callback` | | | |
| `SSL_CTX_get_max_early_data` | | :white_check_mark: | :white_check_mark: |
| `SSL_CTX_get_num_tickets` | | | |
| `SSL_CTX_get_num_tickets` | | | :white_check_mark: |
| `SSL_CTX_get_options` | | :white_check_mark: | :white_check_mark: |
| `SSL_CTX_get_quiet_shutdown` | | | |
| `SSL_CTX_get_record_padding_callback_arg` | | | |
Expand Down Expand Up @@ -165,7 +165,7 @@
| `SSL_CTX_set_next_proto_select_cb` [^nextprotoneg] | :white_check_mark: | | :exclamation: [^stub] |
| `SSL_CTX_set_next_protos_advertised_cb` [^nextprotoneg] | | :white_check_mark: | :exclamation: [^stub] |
| `SSL_CTX_set_not_resumable_session_callback` | | | |
| `SSL_CTX_set_num_tickets` | | | |
| `SSL_CTX_set_num_tickets` | | | :white_check_mark: |
| `SSL_CTX_set_options` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `SSL_CTX_set_post_handshake_auth` | :white_check_mark: | | :exclamation: [^stub] |
| `SSL_CTX_set_psk_client_callback` [^psk] | | | |
Expand Down Expand Up @@ -343,7 +343,7 @@
| `SSL_get_info_callback` | | | |
| `SSL_get_key_update_type` | | | |
| `SSL_get_max_early_data` | | | |
| `SSL_get_num_tickets` | | | |
| `SSL_get_num_tickets` | | | :white_check_mark: |
| `SSL_get_options` | | :white_check_mark: | :white_check_mark: |
| `SSL_get_peer_cert_chain` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `SSL_get_peer_finished` | | | |
Expand Down Expand Up @@ -444,7 +444,7 @@
| `SSL_set_max_early_data` | | | |
| `SSL_set_msg_callback` | | | |
| `SSL_set_not_resumable_session_callback` | | | |
| `SSL_set_num_tickets` | | | |
| `SSL_set_num_tickets` | | | :white_check_mark: |
| `SSL_set_options` | | :white_check_mark: | :white_check_mark: |
| `SSL_set_post_handshake_auth` | | | :exclamation: [^stub] |
| `SSL_set_psk_client_callback` [^psk] | | | |
Expand Down
4 changes: 4 additions & 0 deletions rustls-libssl/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const ENTRYPOINTS: &[&str] = &[
"SSL_CTX_get_client_CA_list",
"SSL_CTX_get_ex_data",
"SSL_CTX_get_max_early_data",
"SSL_CTX_get_num_tickets",
"SSL_CTX_get_options",
"SSL_CTX_get_timeout",
"SSL_CTX_get_verify_callback",
Expand Down Expand Up @@ -116,6 +117,7 @@ const ENTRYPOINTS: &[&str] = &[
"SSL_CTX_set_msg_callback",
"SSL_CTX_set_next_proto_select_cb",
"SSL_CTX_set_next_protos_advertised_cb",
"SSL_CTX_set_num_tickets",
"SSL_CTX_set_options",
"SSL_CTX_set_post_handshake_auth",
"SSL_CTX_set_session_id_context",
Expand Down Expand Up @@ -144,6 +146,7 @@ const ENTRYPOINTS: &[&str] = &[
"SSL_get_error",
"SSL_get_ex_data",
"SSL_get_ex_data_X509_STORE_CTX_idx",
"SSL_get_num_tickets",
"SSL_get_options",
"SSL_get_peer_cert_chain",
"SSL_get_peer_signature_type_nid",
Expand Down Expand Up @@ -190,6 +193,7 @@ const ENTRYPOINTS: &[&str] = &[
"SSL_set_connect_state",
"SSL_set_ex_data",
"SSL_set_fd",
"SSL_set_num_tickets",
"SSL_set_options",
"SSL_set_post_handshake_auth",
"SSL_set_quiet_shutdown",
Expand Down
83 changes: 79 additions & 4 deletions rustls-libssl/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,61 @@ impl SslConfigCtx {
}
}

fn no_tickets(&mut self, path: Option<&str>) -> Result<ActionResult, Error> {
debug_assert!(path.is_none());

match &self.state {
State::Validating => {}
State::ApplyingToCtx(ctx) => {
ctx.get_mut().set_options(crate::SSL_OP_NO_TICKET);
}
State::ApplyingToSsl(ssl) => {
ssl.get_mut().set_options(crate::SSL_OP_NO_TICKET);
}
};

// OpenSSL's implementation returns 1 (NotApplied) even when applying (???)
Ok(ActionResult::NotApplied)
}

fn options(&mut self, opts: Option<&str>) -> Result<ActionResult, Error> {
let opts = match opts {
Some(path) => path,
None => return Ok(ActionResult::ValueRequired),
};

for part in opts.split(',').map(|part| part.trim()) {
let flag = match part.starts_with('-') {
true => OptionFlag::Disable,
false => OptionFlag::Enable,
};
match part {
"SessionTicket" | "-SessionTicket" => self.session_ticket_option(flag)?,
_ => {}
}
}

Ok(ActionResult::Applied)
}

fn session_ticket_option(&mut self, flag: OptionFlag) -> Result<(), Error> {
if !self.flags.is_server() {
return Err(Error::bad_data(
"SessionTicket is only supported for servers",
));
}
let opts = match &self.state {
State::ApplyingToCtx(ctx) => &mut ctx.get_mut().raw_options,
State::ApplyingToSsl(ssl) => &mut ssl.get_mut().raw_options,
State::Validating => return Ok(()),
};
match flag {
OptionFlag::Disable => *opts |= crate::SSL_OP_NO_TICKET,
OptionFlag::Enable => *opts &= !crate::SSL_OP_NO_TICKET,
}
Ok(())
}

fn parse_protocol_version(proto: Option<&str>) -> Option<u16> {
Some(match proto {
Some("None") => 0,
Expand Down Expand Up @@ -318,8 +373,8 @@ pub(super) enum ValueType {
File = 0x2,
/// The option value is a directory name.
Dir = 0x3,
// The option value is not used.
//None = 0x4,
/// The option value is not used.
None = 0x4,
}

impl From<ValueType> for c_int {
Expand Down Expand Up @@ -401,7 +456,6 @@ enum ActionResult {
///
/// For example, if no `SSL_CTX` has been set a [`CommandAction`] may return `NotApplied` after
/// validating the command value.
#[allow(dead_code)] // TODO(XXX): remove with first ref.
NotApplied = 1,
/// The action value was recognized and applied.
Applied = 2,
Expand Down Expand Up @@ -465,6 +519,14 @@ impl From<Flags> for c_uint {
}
}

/// Representation of whether an "Options" value flag should be enabled or disabled.
enum OptionFlag {
/// The option flag value begins with '-' indicating it should be disabled.
Disable,
/// The option flag does not begin with '-' indicating it should be enabled.
Enable,
}

/// All the [`Command`]s that are supported by [`SslConfigCtx`].
const SUPPORTED_COMMANDS: &[Command] = &[
Command {
Expand Down Expand Up @@ -516,10 +578,23 @@ const SUPPORTED_COMMANDS: &[Command] = &[
value_type: ValueType::File,
action: SslConfigCtx::verify_ca_file,
},
Command {
name_file: None,
name_cmdline: Some("no_ticket"),
flags: Flags(Flags::ANY),
value_type: ValueType::None,
action: SslConfigCtx::no_tickets,
},
Command {
name_file: Some("Options"),
name_cmdline: None,
flags: Flags(Flags::ANY),
value_type: ValueType::String,
action: SslConfigCtx::options,
},
// Some commands that would be reasonable to implement in the future:
// - ClientCAFile/ClientCAPath
// - Options
// - SessionTicket/-no_ticket
// - CANames (?)
// - Groups/-groups
// - SignatureAlgorithms/-sigalgs
Expand Down
36 changes: 35 additions & 1 deletion rustls-libssl/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@ entry! {
}
}

entry! {
pub fn _SSL_CTX_set_num_tickets(ctx: *mut SSL_CTX, num_tickets: usize) -> c_int {
try_clone_arc!(ctx).get_mut().set_num_tickets(num_tickets);
C_INT_SUCCESS
}
}

entry! {
pub fn _SSL_CTX_get_num_tickets(ctx: *const SSL_CTX) -> usize {
try_clone_arc!(ctx).get().get_num_tickets()
}
}

entry! {
pub fn _SSL_CTX_ctrl(ctx: *mut SSL_CTX, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long {
let ctx = try_clone_arc!(ctx);
Expand Down Expand Up @@ -205,7 +218,9 @@ entry! {
C_INT_SUCCESS as c_long
}
Ok(SslCtrl::GetMaxProtoVersion) => ctx.get().get_max_protocol_version().into(),
Ok(SslCtrl::SetTlsExtHostname) | Ok(SslCtrl::SetTlsExtServerNameCallback) => {
Ok(SslCtrl::SetTlsExtHostname)
| Ok(SslCtrl::SetTlsExtServerNameCallback)
| Ok(SslCtrl::SetTlsExtTicketKeyCallback) => {
// not a defined operation in the OpenSSL API
0
}
Expand Down Expand Up @@ -622,6 +637,10 @@ entry! {
ctx.get_mut().set_servername_callback(fp);
C_INT_SUCCESS as c_long
}
Ok(SslCtrl::SetTlsExtTicketKeyCallback) => {
log::warn!("ignoring tls ext ticket key callback");
C_INT_SUCCESS as c_long
}
_ => 0,
}
}
Expand Down Expand Up @@ -842,6 +861,7 @@ entry! {
}
// not a defined operation in the OpenSSL API
Ok(SslCtrl::SetTlsExtServerNameCallback)
| Ok(SslCtrl::SetTlsExtTicketKeyCallback)
| Ok(SslCtrl::SetTlsExtServerNameArg)
| Ok(SslCtrl::SetSessCacheSize)
| Ok(SslCtrl::GetSessCacheSize)
Expand Down Expand Up @@ -872,6 +892,19 @@ entry! {
}
}

entry! {
pub fn _SSL_set_num_tickets(ssl: *mut SSL, num_tickets: usize) -> c_int {
try_clone_arc!(ssl).get_mut().set_num_tickets(num_tickets);
C_INT_SUCCESS
}
}

entry! {
pub fn _SSL_get_num_tickets(ssl: *const SSL) -> usize {
try_clone_arc!(ssl).get().get_num_tickets()
}
}

entry! {
pub fn _SSL_set_alpn_protos(
ssl: *mut SSL,
Expand Down Expand Up @@ -1859,6 +1892,7 @@ num_enum! {
SetTlsExtServerNameCallback = 53,
SetTlsExtServerNameArg = 54,
SetTlsExtHostname = 55,
SetTlsExtTicketKeyCallback = 72,
SetChain = 88,
SetMinProtoVersion = 123,
SetMaxProtoVersion = 124,
Expand Down
7 changes: 7 additions & 0 deletions rustls-libssl/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ impl From<Error> for c_int {
}
}

impl From<Error> for usize {
fn from(_: Error) -> Self {
// ditto
0
}
}

impl From<Error> for MysteriouslyOppositeReturnValue {
fn from(_: Error) -> Self {
// for a small subset of OpenSSL functions (return 1 on error)
Expand Down
Loading