-
Notifications
You must be signed in to change notification settings - Fork 706
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
test: pin static testing policies to numbered versions #4845
Conversation
de8b1c3
to
ab53864
Compare
ab53864
to
33440bb
Compare
if (!s2n_in_unit_test()) { | ||
*override = S2N_TESTING_POLICY_NO_OVERRIDE; | ||
} else { | ||
*override = s2n_testing_override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this additional logic necessary? If we're not in a unit tests, won't s2n_testing_override
always be S2N_TESTING_POLICY_NO_OVERRIDE
, just like s2n_use_default_tls13_config_flag
was always false?
In general I think it's better to limit decisions based on s2n_in_unit_test()
, since these decisions can't be tested in unit tests.
if (!s2n_in_unit_test()) { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment - I'm not sure if this branch is needed.
bool uses_tls13 = false; | ||
switch (s2n_testing_override) { | ||
case S2N_TESTING_POLICY_OVERRIDE_TLS12: | ||
break; | ||
case S2N_TESTING_POLICY_OVERRIDE_TLS13: | ||
uses_tls13 = true; | ||
break; | ||
case S2N_TESTING_POLICY_NO_OVERRIDE: | ||
break; | ||
} | ||
return uses_tls13; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be clearer:
bool uses_tls13 = false; | |
switch (s2n_testing_override) { | |
case S2N_TESTING_POLICY_OVERRIDE_TLS12: | |
break; | |
case S2N_TESTING_POLICY_OVERRIDE_TLS13: | |
uses_tls13 = true; | |
break; | |
case S2N_TESTING_POLICY_NO_OVERRIDE: | |
break; | |
} | |
return uses_tls13; | |
switch (s2n_testing_override) { | |
case S2N_TESTING_POLICY_OVERRIDE_TLS13: | |
return true; | |
default: | |
return false; | |
} |
*override = s2n_testing_override; | ||
} | ||
return S2N_RESULT_OK; | ||
} | ||
|
||
bool s2n_use_default_tls13_config() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this function still needed? Wasn't it only used to select the default TLS 1.3 config, which has now been replaced with your new selection logic?
typedef enum { | ||
S2N_TESTING_POLICY_OVERRIDE_TLS12 = 0, | ||
S2N_TESTING_POLICY_OVERRIDE_TLS13, | ||
S2N_TESTING_POLICY_NO_OVERRIDE, | ||
} s2n_testing_security_policy_override; | ||
|
||
S2N_RESULT s2n_get_testing_security_policy_override(s2n_testing_security_policy_override *override); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming nits - I think we usually say "for test" or "for testing" if something is for testing. So these names might be more consistent and might make their purposes more clear:
typedef enum { | |
S2N_TESTING_POLICY_OVERRIDE_TLS12 = 0, | |
S2N_TESTING_POLICY_OVERRIDE_TLS13, | |
S2N_TESTING_POLICY_NO_OVERRIDE, | |
} s2n_testing_security_policy_override; | |
S2N_RESULT s2n_get_testing_security_policy_override(s2n_testing_security_policy_override *override); | |
typedef enum { | |
S2N_TLS12_POLICY_OVERRIDE = 0, | |
S2N_TLS13_POLICY_OVERRIDE, | |
S2N_NO_POLICY_OVERRIDE, | |
} s2n_security_policy_override_for_testing; | |
S2N_RESULT s2n_get_get_security_policy_override_for_testing(s2n_security_policy_override_for_testing *override); |
} | ||
|
||
return &s2n_default_config; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems safer to remove this default config return and instead add a default to the switch statement.
@@ -23,176 +23,122 @@ | |||
#include "tls/s2n_security_policies.h" | |||
#include "tls/s2n_tls13.h" | |||
|
|||
int main(int argc, char **argv) | |||
S2N_RESULT test_policy_behavior(const struct s2n_security_policy *policy, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit - we try to keep the s2n namespace, even in tests.
S2N_RESULT test_policy_behavior(const struct s2n_security_policy *policy, | |
S2N_RESULT s2n_test_policy_behavior(const struct s2n_security_policy *policy, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff is currently very difficult to review. Is there any way to improve it? If not, it might be easier to review as a separate file with the old one deleted. Then we can always rename it back in another PR.
EXPECT_SUCCESS(s2n_connection_free(conn)); | ||
} | ||
|
||
EXPECT_SUCCESS(s2n_disable_tls13_in_test()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed? I don't think these tests override anything.
@@ -118,6 +124,41 @@ int main(int argc, char **argv) | |||
EXPECT_SUCCESS(s2n_connection_free(conn)); | |||
} | |||
|
|||
/* For fips */ | |||
if (s2n_is_in_fips_mode()) { | |||
struct s2n_connection *conn = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit - defer cleanup is better for new tests.
struct s2n_connection *conn = NULL; | |
DEFER_CLEANUP(struct s2n_connection *conn = s2n_connection_new(S2N_CLIENT), s2n_connection_ptr_free); |
/* Dedicated configs for testing different protocols since tests can override the | ||
* default security policy behavior. | ||
*/ | ||
static struct s2n_config s2n_testing_default_tls12_config = { 0 }; | ||
static struct s2n_config s2n_testing_default_tls12_fips_config = { 0 }; | ||
static struct s2n_config s2n_testing_default_tls13_config = { 0 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these need to live in the main source? Or can they be moved to the testing library? You're adding more complexity to the source here than I think you need to. See if you can simplify.
("default" and "default_fips" have real customer use cases. "default_tls13" had real customer use cases when it was first added, before we changed how we configured tls1.3, but could probably be removed now)
Problem:
Currently, a new s2n_config object is configured with one of three static configs based on runtime settings and testing overrides.
The security policy selection depends on testing override function calls and makes use of the "default" and "default_fips" policies.
As we attempt to evolve the default* policies, maintaining the current behavior becomes cumbersome. Specifically, along with adding TLS1.3 support to the "default" policy, we will also add a new test which temporarily set the "default" to TLS1.2. This "toggling" of the "default" policy will make the current config selection very complicated.
Description of changes:
To solve this issue, this PR creates dedicated static configs for testing override and pins them to numbered policies rather than rely on the "default" policy.
The cost of this strategy is 2 additional static configs, however, since these are only used in testing, we are able to avoid extra costs of the
s2n_config_load_system_certs
by gating initialization of test configs behind as2n_in_unit_test
check.Callout:
I have made other refactor changes to make reasoning about testing overrides and policy selection easier to reason about:
s2n_default_security_policy_selection
ands2n_testing_security_policy_override
s2n_config_testing_defaults_init_tls13_certs
: was used to avoid the costs ofs2n_config_load_system_certs
, however we can fully avoid the costs by gating initialization to unit tests.Testing:
Added unit testing with and without the testing overrides.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.