Skip to content

Commit

Permalink
conf: implement VerifyCAPath/VerifyCAFile commands
Browse files Browse the repository at this point in the history
  • Loading branch information
cpu committed Jun 26, 2024
1 parent 36a50bc commit 180f6a9
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 16 deletions.
60 changes: 58 additions & 2 deletions rustls-libssl/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,48 @@ impl SslConfigCtx {
}
}

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

match &self.state {
State::Validating => Ok(ActionResult::Applied),
State::ApplyingToCtx(ctx) => {
ctx.get_mut().default_cert_dir = Some(path.into());
Ok(ActionResult::Applied)
}
State::ApplyingToSsl(_) => {
// NYI: would require setting a constructed `RootCertStore` on the `Ssl` instance.
Err(Error::not_supported(
"VerifyCAPath with SSL structure not supported",
))
}
}
}

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

match &self.state {
State::Validating => Ok(ActionResult::Applied),
State::ApplyingToCtx(ctx) => {
ctx.get_mut().default_cert_file = Some(path.into());
Ok(ActionResult::Applied)
}
State::ApplyingToSsl(_) => {
// NYI: would require setting a constructed `RootCertStore` on the `Ssl` instance.
Err(Error::not_supported(
"VerifyCAFile with SSL structure not supported",
))
}
}
}

fn parse_protocol_version(proto: Option<&str>) -> Option<u16> {
Some(match proto {
Some("None") => 0,
Expand Down Expand Up @@ -274,8 +316,8 @@ pub(super) enum ValueType {
String = 0x1,
/// The option value is a filename.
File = 0x2,
// The option value is a directory name.
//Dir = 0x3,
/// The option value is a directory name.
Dir = 0x3,
// The option value is not used.
//None = 0x4,
}
Expand Down Expand Up @@ -460,4 +502,18 @@ const SUPPORTED_COMMANDS: &[Command] = &[
value_type: ValueType::File,
action: SslConfigCtx::private_key,
},
Command {
name_file: Some("VerifyCAPath"),
name_cmdline: Some("verifyCApath"),
flags: Flags(Flags::CERTIFICATE),
value_type: ValueType::Dir,
action: SslConfigCtx::verify_ca_path,
},
Command {
name_file: Some("VerifyCAFile"),
name_cmdline: Some("verifyCAfile"),
flags: Flags(Flags::CERTIFICATE),
value_type: ValueType::File,
action: SslConfigCtx::verify_ca_file,
},
];
98 changes: 84 additions & 14 deletions rustls-libssl/tests/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,38 @@ static const int conf_flags[] = {SSL_CONF_FLAG_SERVER, SSL_CONF_FLAG_CLIENT,

#define NUM_FLAGS (sizeof(conf_flags) / sizeof(conf_flags[0]))

static const char *supported_cmds[] = {
"-min_protocol", CUSTOM_PREFIX "min_protocol",
"MinProtocol", CUSTOM_PREFIX "MinProtocol",

"-max_protocol", CUSTOM_PREFIX "max_protocol",
"MaxProtocol", CUSTOM_PREFIX "MaxProtocol",

"VerifyMode", CUSTOM_PREFIX "VerifyMode",

"-cert", CUSTOM_PREFIX "cert",
"Certificate", CUSTOM_PREFIX "Certificate",

"-key", CUSTOM_PREFIX "key",
"PrivateKey", CUSTOM_PREFIX "PrivateKey"};
static const char *supported_cmds[] = {"-min_protocol",
CUSTOM_PREFIX "min_protocol",
"MinProtocol",
CUSTOM_PREFIX "MinProtocol",

"-max_protocol",
CUSTOM_PREFIX "max_protocol",
"MaxProtocol",
CUSTOM_PREFIX "MaxProtocol",

"VerifyMode",
CUSTOM_PREFIX "VerifyMode",

"-cert",
CUSTOM_PREFIX "cert",
"Certificate",
CUSTOM_PREFIX "Certificate",

"-key",
CUSTOM_PREFIX "key",
"PrivateKey",
CUSTOM_PREFIX "PrivateKey"

"-verifyCApath",
CUSTOM_PREFIX "verifyCApath",
"VerifyCAPath",
CUSTOM_PREFIX "VerifyCAPath",

"-verifyCAfile",
CUSTOM_PREFIX "verifyCAfile",
"VerifyCAFile",
CUSTOM_PREFIX "VerifyCAFile"};

#define NUM_SUPPORTED_CMDS (sizeof(supported_cmds) / sizeof(supported_cmds[0]))

Expand Down Expand Up @@ -283,6 +301,55 @@ void test_certificate_and_private_key(void) {
SSL_CTX_free(ctx);
}

void set_verify_ca(SSL_CONF_CTX *cctx) {
// Note: we don't test invalid values here - our implementation diverges
// slightly due to later processing of the cert file/dir.
printf("\t\tcmd VerifyCAPath NULL returns %d\n",
SSL_CONF_cmd(cctx, "VerifyCAPath", NULL));
printf("\t\tcmd VerifyCAPath 'test-ca/rsa' returns %d\n",
SSL_CONF_cmd(cctx, "VerifyCAPath", "test-ca/rsa"));

printf("\t\tcmd VerifyCAFile NULL returns %d\n",
SSL_CONF_cmd(cctx, "VerifyCAFile", NULL));
printf("\t\tcmd VerifyCAFile 'test-ca/rsa/ca.cert' returns %d\n",
SSL_CONF_cmd(cctx, "VerifyCAFile", "test-ca/rsa/ca.cert"));
}

void test_verify_ca_path_file(void) {
SSL_CONF_CTX *cctx = SSL_CONF_CTX_new();
assert(cctx != NULL);

SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);

printf("\tPre-ctx (not certificate flag):\n");
set_verify_ca(cctx);

printf("\tPre-ctx (certificate flag):\n");
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
set_verify_ca(cctx);
SSL_CONF_CTX_clear_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);

SSL_CTX *ctx = SSL_CTX_new(TLS_method());
assert(ctx != NULL);
SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);

printf("\tWith ctx (not certificate flag):\n");
set_verify_ca(cctx);

printf("\tWith ctx (certificate flag):\n");
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);
set_verify_ca(cctx);
SSL_CONF_CTX_clear_flags(cctx, SSL_CONF_FLAG_CERTIFICATE);

// Note: we do not test with `SSL_CONF_set_ssl()` here - we lack
// support for the `Certificate` command updating an `SSL`
// struct at this time.

assert(SSL_CONF_CTX_finish(cctx));
SSL_CONF_CTX_free(cctx);
SSL_CTX_free(ctx);
}

int main(void) {
printf("Supported commands:\n");
printf("no base flags, default prefix:\n");
Expand Down Expand Up @@ -311,4 +378,7 @@ int main(void) {

printf("Certificate/PrivateKey:\n");
test_certificate_and_private_key();

printf("VerifyCAPath/VerifyCAFile:\n");
test_verify_ca_path_file();
}

0 comments on commit 180f6a9

Please sign in to comment.