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

refactor: ossl x509 parsing #4351

Merged
merged 16 commits into from
Jan 22, 2024
Merged

refactor: ossl x509 parsing #4351

merged 16 commits into from
Jan 22, 2024

Conversation

jmayclin
Copy link
Contributor

Resolved issues:

#4163

Description of changes:

This commit introduces a helper method to standardize our openssl X509
parsing, and also restructures the validator and cert loading to remove
some cert reparsing that was occurring.

Co-authored-by: Sam Clark <[email protected]>

This PR borrows work from #4176 and also applies it to local cert loading.

  1. All parsing of s2n blob's into X509* is moved to s2n_openssl_x509_parse* methods.
  2. remove extra parsing of leaf cert in s2n validator
  3. remove extra parsing of leaf cert in s2n cert loading

This makes s2n-tls of peer and local certificate more standard, and is necessary for #4339

Call-outs:

Historical Behavior: I would love to make all cert parsing enforce the trailing byte restriction, but it would be a behavior change, and therefore probably not a polite thing to do ☹️

Parsing APIs: I don't love the multiple APIs for the openssl x509 parsing, but it seemed better than forcing people to needlessly declare a length variable or including a boolean toggle.

Whitespace: Sorry for the extra noise in the diff. My IDE removes all trailing whitespace. I'll open an issue for a linting step to just do this to our entire codebase.

Testing:

Added the unit tests from Sam's PR with some slight modifications, and all existing unit tests pass with the commented caveat in s2n_certificate_test.c

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 Jan 10, 2024
@@ -903,7 +903,7 @@ int main(int argc, char **argv)
EXPECT_SUCCESS(s2n_stuffer_copy(&input, &server->handshake.io,
s2n_stuffer_data_available(&input)));

EXPECT_FAILURE_WITH_ERRNO(s2n_client_cert_recv(server), S2N_ERR_CERT_INVALID);
EXPECT_FAILURE_WITH_ERRNO(s2n_client_cert_recv(server), S2N_ERR_DECODE_CERTIFICATE);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only behavior change here is that failing the openssl x509 parsing call returns a "decode certificate" error rather than the previous "cert invalid error". The same d2i_X509 failure is occurring that previously occurred.

        server_cert = d2i_X509(NULL, &data, asn1_cert.size);
        RESULT_ENSURE(server_cert, S2N_ERR_DECODE_CERTIFICATE);

I'm confused by this comment on the test case

Validate that the certificate chain we generated is parseable.

The certificate is "readable" by s2n_x509_validator_read_asn1_cert, but not parseable by openssl.

This commit introduces a helper method to standardize our openssl X509
parsing, and also restructures the validator and cert loading to remove
some cert-reparsing that was occuring.
@jmayclin jmayclin marked this pull request as ready for review January 10, 2024 17:10
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
crypto/s2n_certificate.c Show resolved Hide resolved
crypto/s2n_certificate.c Outdated Show resolved Hide resolved
crypto/s2n_certificate.c Show resolved Hide resolved
crypto/s2n_openssl_x509.c Outdated Show resolved Hide resolved
crypto/s2n_openssl_x509.c Show resolved Hide resolved
crypto/s2n_pkey.c Show resolved Hide resolved
tests/unit/s2n_openssl_x509_test.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.h Outdated Show resolved Hide resolved
jmayclin and others added 2 commits January 10, 2024 14:22
* add additional ENSURE_REFs
* switch load_cert method to parse with validation
* make asn1_cert_parse non-static and forward declare
* rename server-cert to cert
* explicitly zero-initialize variables
tests/unit/s2n_openssl_x509_test.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
@goatgoose
Copy link
Contributor

Thanks for fixing the duplicate parsing!

Comment on lines -300 to +303
*
*
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm aware of the option to hide whitespace, but I would suggest setting up your IDE so that it doesn't make these changes to lines you don't touch. Since it seems like none of our linters care, you're going to end up with some messy diffs otherwise.

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 have disabled for the time being, but this is the default preference of clang-format and I would be in favor of just adding a linter that does care 😄. Opened #4362 to track this

tests/unit/s2n_examples_test.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
crypto/s2n_pkey.h Outdated Show resolved Hide resolved
crypto/s2n_openssl_x509.h Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
- remove unnecessary test header in openssl_x509_tests
- RESULT_GUARD for s2n_pkey_zero_init
- move version check to start of method
- initialize public-key along with other structs
- remove unnecessary pkey_zero_init
- add extra line for trailing byte validation
- use RESULT_GUARD_OSSL instead of manual check
- rename s2n_pkey_x509... method
- remove param information from internal comments
- manually format function definition

I really thought that clang format would handle this for me :'(
@jmayclin jmayclin enabled auto-merge (squash) January 19, 2024 03:33
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tests/unit/s2n_x509_validator_test.c Show resolved Hide resolved
- use gte rather than equal for 1.3 check
- use explicit ZERO_TO_DISABLE_DEFER_CLEANUP method
- the given preference was to address the TEST_DEBUG_PRINT issues
  systematically rather than in this specific instance
@jmayclin jmayclin merged commit 2cf6a52 into aws:main Jan 22, 2024
30 checks passed
@jmayclin jmayclin deleted the ossl-x509-refactor branch July 1, 2024 07:26
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