Skip to content

Commit 0f68342

Browse files
committed
conf: implement Options SessionTicket/-SessionTicket cmd
1 parent a8ebfc5 commit 0f68342

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

rustls-libssl/src/conf.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,44 @@ impl SslConfigCtx {
279279
Ok(ActionResult::NotApplied)
280280
}
281281

282+
fn options(&mut self, opts: Option<&str>) -> Result<ActionResult, Error> {
283+
let opts = match opts {
284+
Some(path) => path,
285+
None => return Ok(ActionResult::ValueRequired),
286+
};
287+
288+
for part in opts.split(',').map(|part| part.trim()) {
289+
let flag = match part.starts_with('-') {
290+
true => OptionFlag::Disable,
291+
false => OptionFlag::Enable,
292+
};
293+
match part {
294+
"SessionTicket" | "-SessionTicket" => self.session_ticket_option(flag)?,
295+
_ => {}
296+
}
297+
}
298+
299+
Ok(ActionResult::Applied)
300+
}
301+
302+
fn session_ticket_option(&mut self, flag: OptionFlag) -> Result<(), Error> {
303+
if !self.flags.is_server() {
304+
return Err(Error::bad_data(
305+
"SessionTicket is only supported for servers",
306+
));
307+
}
308+
let opts = match &self.state {
309+
State::ApplyingToCtx(ctx) => &mut ctx.get_mut().raw_options,
310+
State::ApplyingToSsl(ssl) => &mut ssl.get_mut().raw_options,
311+
State::Validating => return Ok(()),
312+
};
313+
match flag {
314+
OptionFlag::Disable => *opts |= crate::SSL_OP_NO_TICKET,
315+
OptionFlag::Enable => *opts &= !crate::SSL_OP_NO_TICKET,
316+
}
317+
Ok(())
318+
}
319+
282320
fn parse_protocol_version(proto: Option<&str>) -> Option<u16> {
283321
Some(match proto {
284322
Some("None") => 0,
@@ -481,6 +519,14 @@ impl From<Flags> for c_uint {
481519
}
482520
}
483521

522+
/// Representation of whether an "Options" value flag should be enabled or disabled.
523+
enum OptionFlag {
524+
/// The option flag value begins with '-' indicating it should be disabled.
525+
Disable,
526+
/// The option flag does not begin with '-' indicating it should be enabled.
527+
Enable,
528+
}
529+
484530
/// All the [`Command`]s that are supported by [`SslConfigCtx`].
485531
const SUPPORTED_COMMANDS: &[Command] = &[
486532
Command {
@@ -539,10 +585,16 @@ const SUPPORTED_COMMANDS: &[Command] = &[
539585
value_type: ValueType::None,
540586
action: SslConfigCtx::no_tickets,
541587
},
588+
Command {
589+
name_file: Some("Options"),
590+
name_cmdline: None,
591+
flags: Flags(Flags::ANY),
592+
value_type: ValueType::String,
593+
action: SslConfigCtx::options,
594+
},
542595
// Some commands that would be reasonable to implement in the future:
543596
// - ClientCAFile/ClientCAPath
544597
// - Options
545-
// - SessionTicket
546598
// - CANames (?)
547599
// - Groups/-groups
548600
// - SignatureAlgorithms/-sigalgs

rustls-libssl/tests/config.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
#include <assert.h>
6+
#include <stdint.h>
67
#include <stdio.h>
78

89
#include <openssl/ssl.h>
@@ -403,6 +404,92 @@ void test_no_ticket(void) {
403404
SSL_free(ssl);
404405
}
405406

407+
void set_options_values(SSL_CONF_CTX *cctx, SSL_CTX *ctx, SSL *ssl,
408+
uint64_t opts, const char *values) {
409+
// Put the CTX and SSL_CTX into a known options state beforehand.
410+
if (ctx != NULL) {
411+
SSL_CTX_clear_options(ctx, UINT64_MAX);
412+
SSL_CTX_set_options(ctx, opts);
413+
printf("\t\tSSL_CTX_get_options before: 0x%lx\n", SSL_CTX_get_options(ctx));
414+
}
415+
if (ssl != NULL) {
416+
SSL_clear_options(ssl, UINT64_MAX);
417+
SSL_set_options(ssl, opts);
418+
printf("\t\tSSL_get_options before: 0x%lx\n", SSL_get_options(ssl));
419+
}
420+
421+
// Apply the Options command
422+
printf("\t\tSSL_CONF_cmd Options %s == %d\n",
423+
values == NULL ? "NULL" : values,
424+
SSL_CONF_cmd(cctx, "Options", values));
425+
426+
if (ctx != NULL) {
427+
printf("\t\tSSL_CTX_get_options after: 0x%lx\n", SSL_CTX_get_options(ctx));
428+
}
429+
if (ssl != NULL) {
430+
printf("\t\tSSL_get_options after: 0x%lx\n", SSL_get_options(ssl));
431+
}
432+
}
433+
434+
void test_options_session_ticket_variations(SSL_CONF_CTX *cctx, SSL_CTX *ctx,
435+
SSL *ssl) {
436+
// Try NULL
437+
set_options_values(cctx, ctx, ssl, 0, NULL);
438+
// NOTE: we don't try invalid/unknown values because Rustls will ignore them
439+
// without error
440+
// while OpenSSL will erorr.
441+
442+
// Test enabling the option when it has not been disabled, and when it has
443+
// been disabled
444+
set_options_values(cctx, ctx, ssl, 0, "SessionTicket");
445+
set_options_values(cctx, ctx, ssl, SSL_OP_NO_TICKET, "SessionTicket");
446+
447+
// Test disabling the option when it has been enabled, and when it has not
448+
// been enabled
449+
set_options_values(cctx, ctx, ssl, SSL_OP_NO_TICKET, "-SessionTicket");
450+
set_options_values(cctx, ctx, ssl, 0, "-SessionTicket");
451+
452+
// Test enabling and disabling the option in the same command for both initial
453+
// states
454+
set_options_values(cctx, ctx, ssl, 0, "SessionTicket,-SessionTicket");
455+
set_options_values(cctx, ctx, ssl, SSL_OP_NO_TICKET,
456+
"SessionTicket,-SessionTicket");
457+
set_options_values(cctx, ctx, ssl, SSL_OP_NO_TICKET,
458+
"-SessionTicket,SessionTicket");
459+
set_options_values(cctx, ctx, ssl, 0, "-SessionTicket,SessionTicket");
460+
}
461+
462+
void test_options_session_ticket(void) {
463+
SSL_CONF_CTX *cctx = SSL_CONF_CTX_new();
464+
assert(cctx != NULL);
465+
466+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
467+
468+
printf("\tPre-ctx, no server flag:\n");
469+
test_options_session_ticket_variations(cctx, NULL, NULL);
470+
471+
printf("\tPre-ctx, with server flag: \n");
472+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER);
473+
test_options_session_ticket_variations(cctx, NULL, NULL);
474+
475+
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
476+
assert(ctx != NULL);
477+
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
478+
printf("\tWith ctx\n");
479+
test_options_session_ticket_variations(cctx, ctx, NULL);
480+
481+
SSL *ssl = SSL_new(ctx);
482+
assert(ssl != NULL);
483+
SSL_CONF_CTX_set_ssl(cctx, ssl);
484+
printf("\tWith ssl\n");
485+
test_options_session_ticket_variations(cctx, NULL, ssl);
486+
487+
assert(SSL_CONF_CTX_finish(cctx));
488+
SSL_CONF_CTX_free(cctx);
489+
SSL_CTX_free(ctx);
490+
SSL_free(ssl);
491+
}
492+
406493
int main(void) {
407494
printf("Supported commands:\n");
408495
printf("no base flags, default prefix:\n");
@@ -437,4 +524,7 @@ int main(void) {
437524

438525
printf("no_ticket\n");
439526
test_no_ticket();
527+
528+
printf("Options SessionTicket\n");
529+
test_options_session_ticket();
440530
}

0 commit comments

Comments
 (0)