Skip to content
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

feat: add cert key preferences #4434

Merged
merged 21 commits into from
Feb 23, 2024
Merged

feat: add cert key preferences #4434

merged 21 commits into from
Feb 23, 2024

Conversation

jmayclin
Copy link
Contributor

Description of changes:

s2n-tls does not currently offer a way to define cert key preferences in cert policies, this PR adds them.

These cert key preferences can apply in 3 difference places

  1. config_validate_loaded_certs: for certs that are loaded in a config to send to a peer
  2. validator check cert preferences: for certs received from a peer
  3. validator check root cert: for local certs in a trust store

While cert signature preferences were no enforced against self signed certs, the key type of a self signed cert does influence the security of the chain so we do enforce the cert key preferences.

Call-outs:

There was previous discussion about using the openssl verify_cb for enforcing the root preferences, but that turns out to have little benefit since the libcrypto's I looked at where not capable of backtracking and trying alternate chains given a failed verify callback. Instead we prefer to use the more boring get_chain API.

CI won't pass until #4433 is merged into mainline

Testing:

New unit tests were added to cover new functionality.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@github-actions github-actions bot added the s2n-core team label Feb 21, 2024
@jmayclin jmayclin marked this pull request as ready for review February 21, 2024 08:59
crypto/s2n_certificate.h Show resolved Hide resolved
crypto/s2n_certificate.c Outdated Show resolved Hide resolved
crypto/s2n_certificate.c Outdated Show resolved Hide resolved
tls/s2n_certificate_keys.h Show resolved Hide resolved
tls/s2n_certificate_keys.h Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Show resolved Hide resolved
tls/s2n_x509_validator.c Show resolved Hide resolved
tests/unit/s2n_openssl_x509_test.c Show resolved Hide resolved
tests/unit/s2n_security_policy_cert_preferences_test.c Outdated Show resolved Hide resolved
- remove unused struct field
- remove incorrect comment
- move validation to openssl_x509 get info
- move apply local check up in the check root cert function
- refactor x509 test to use explicit expected info
- add more explicit comment for valid chain scope
- move valid cert case into test loop
@jmayclin jmayclin requested a review from goatgoose February 21, 2024 18:04
tls/s2n_signature_scheme.h Outdated Show resolved Hide resolved
crypto/s2n_openssl_x509.c Show resolved Hide resolved
tests/unit/s2n_security_policy_cert_preferences_test.c Outdated Show resolved Hide resolved
struct s2n_cert_info info = { 0 };
RESULT_GUARD(s2n_openssl_x509_get_cert_info(root, &info));

RESULT_ENSURE_OK(s2n_security_policy_validate_cert_key(sp, &info), S2N_ERR_CERT_UNTRUSTED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a protocol error or a usage error? It kind of seems like a usage error, since the invalid cert should have never been loaded into the trust store. Not sure, though. Would S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT potentially be more accurate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think usage error makes more since. And I agree that S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_CERT is more descriptive, so I went ahead and switched it to that.

How stingy are we with adding new Err's? The current description for that err is

"Incompatibility found between loaded certificates and chosen security policy"

which is technically accurate, but I think it might be nice to have a more explicit S2N_ERR_SECURITY_POLICY_INCOMPATIBLE_ROOT error for this situation, since I would imagine that some customers might not be thinking of the certs in their trust store as "loaded".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I feel like it does makes sense to describe certs as being "loaded" into the trust store, but that could definitely just be me. I don't think it would be bad to add a new error if you think it would be more clear.

If you do add a new error I would maybe go with something like INCOMPATIBLE_TRUSTED_CERT/TRUST_STORE_CERT since a cert in the trust store doesn't have to be a root.

- revert accidental sig scheme changes
- redefine buffers in each scope
- move validate cert chain test out of loop scope
- return different error code for failed root
- remove unnecessary uint16_t max check
- represent bits using int
- add approrpiate >0 check
@jmayclin jmayclin requested a review from goatgoose February 21, 2024 20:25
crypto/s2n_openssl_x509.c Show resolved Hide resolved
crypto/s2n_openssl_x509.c Outdated Show resolved Hide resolved
struct s2n_cert_info info = { 0 };
RESULT_GUARD(s2n_openssl_x509_get_cert_info(root, &info));

RESULT_ENSURE_OK(s2n_security_policy_validate_cert_key(sp, &info), S2N_ERR_CERT_UNTRUSTED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I feel like it does makes sense to describe certs as being "loaded" into the trust store, but that could definitely just be me. I don't think it would be bad to add a new error if you think it would be more clear.

If you do add a new error I would maybe go with something like INCOMPATIBLE_TRUSTED_CERT/TRUST_STORE_CERT since a cert in the trust store doesn't have to be a root.

- add null check for the ec_group before calling get_curve_name
- use get0_pubkey rather that doesn't increment reference count
- remove unused cleanup function
- clang format
crypto/s2n_openssl_x509.c Outdated Show resolved Hide resolved
crypto/s2n_openssl_x509.c Outdated Show resolved Hide resolved
tests/unit/s2n_openssl_x509_test.c Outdated Show resolved Hide resolved
Comment on lines +23 to +24
/* modulus for RSA key, size for EC key */
uint16_t bits;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember we had this conversation, but remind me: why use this definition of "bits" rather than the standard "bits of security" so that we can define it the same across key types? And is there a reason we need to enforce per-type and not a global "bits of security" minimum?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason we need to enforce per-type and not a global "bits of security" minimum?

Government compliance regimes might not agree with OpenSSL's, or even their own, definition of security or they might have some other motivations. For example, RSA3072 and EC256 both provide 128 bits of security, but RFC9151 only allows RSA3072, and does not allow EC256. This prevents us from configuring some global minimum.

why use this definition of "bits" rather than the standard "bits of security"

This "bits" value is only technically necessary for distinguishing between different RSA keys, and it seemed much more readable to check that s2n_rsa_rsae_2048 is using 2048 rather than 112

tls/s2n_certificate_keys.h Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tests/unit/s2n_security_policy_cert_preferences_test.c Outdated Show resolved Hide resolved
tests/unit/s2n_x509_validator_test.c Outdated Show resolved Hide resolved
tests/unit/s2n_x509_validator_test.c Outdated Show resolved Hide resolved
- revert get0_pubkey to address ci failures
- remove naught semicolon causing ci failures
- use variable in sizeof invocation rather than type
- pass in length to test fixture constructor
- make test fixtures const
- rename validator test case
- directly rely on stdint
- correct prefix on header include
- correct sloppy variable name
- add additionaly ensure ref on output of function
- move sha1 check more explicitly behind the conditions
- don't use get0_ec_key since it's not available everywhere
- ensure on != NID_undef
- pass in error to verify functions
- bail with a decode error if the pubkey is null
@jmayclin jmayclin requested a review from lrstewart February 22, 2024 11:03
- assert root cert key checks whenever cert key preferences are defined
- don't rely on silly initializer lists/memcmp
- change test case for new behavior in root key check
- clang format
tls/s2n_security_policies.h Outdated Show resolved Hide resolved
- add note about unresolved security policy structure
- add note about unresolved security policy structure
- try different compile definition to gate tests
- clang-format. I just set this up to format on save so we'll see how
  that goes.
@jmayclin jmayclin requested a review from goatgoose February 23, 2024 01:10
@jmayclin jmayclin enabled auto-merge (squash) February 23, 2024 01:11
tests/unit/s2n_x509_validator_test.c Outdated Show resolved Hide resolved
tests/unit/s2n_x509_validator_test.c Outdated Show resolved Hide resolved
jmayclin and others added 3 commits February 22, 2024 18:13
Co-authored-by: Sam Clark <3758302+goatgoose@users.noreply.github.com>
- remove unnecessary test + sp. Now that root cert validation is no
  longer conditional, remove negative test.
@jmayclin jmayclin disabled auto-merge February 23, 2024 02:29
@jmayclin jmayclin enabled auto-merge (squash) February 23, 2024 07:21
@jmayclin jmayclin merged commit a56e9bf into aws:main Feb 23, 2024
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants