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 s2n_x509_validator_validate_cert_chain to support an async callback #3500

Merged
merged 14 commits into from
Sep 28, 2022

Conversation

goatgoose
Copy link
Contributor

Resolved issues:

Part of #3499

Description of changes:

This PR refactors s2n_x509_validator_validate_cert_chain to support adding the async CRL callback.

A new validator state has been added, PRE_VALIDATE, which splits this function into two stages: INIT, and PRE_VALIDATE. In the INIT stage, when the function is first called, the cert chain is read, the host name is validated, and the CRL callback will be triggered. After triggering the CRL callback, the function may returned blocked. After unblocking, the function will continue and enter the PRE_VALIDATE stage, which will skip everything in the INIT stage and proceed to validate the certificate chain.

Splitting up this function into stages ensures that work is not duplicated after blocking due to invoking the async callback.

Call-outs:

A lot of pkey_types were set to S2N_PKEY_TYPE_UNKNOWN in this PR. This is because the default value for s2n_pkey_type is S2N_PKEY_TYPE_RSA, which is the value being checked in the tests. Setting the value to unknown ensures this value is actually changing.

Additionally, checks for S2N_PKEY_TYPE_RSA were removed in tests where s2n_x509_validator_validate_cert_chain is expected to fail. This is because public_key_out is now set later in this function, and is no longer set before this function fails in these tests.

Testing:

How is this change tested (unit tests, fuzz tests, etc.)? Are there any testing steps to be verified by the reviewer?

Is this a refactor change? If so, how have you proved that the intended behavior hasn't changed?

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 Sep 19, 2022
This was referenced Sep 19, 2022
@goatgoose goatgoose marked this pull request as ready for review September 19, 2022 16:25
@goatgoose goatgoose requested a review from a team as a code owner September 19, 2022 16:25
@goatgoose goatgoose requested review from lrstewart and removed request for a team September 20, 2022 18:10
tests/unit/s2n_x509_validator_test.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
Comment on lines 34 to 36
INIT,
PRE_VALIDATE,
VALIDATED,
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't love this name. How about "PARSED"? Or "CERT_READ"?

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 chose something like PRE_VALIDATE, because this stage kind of does more than just parse the cert chain. It also calls s2n_verify_host_information, and will also call s2n_crl_lookup in the next PR. How about CERT_CHAIN_PROCESSED? I added this in a9c024e. Let me know if you don't like this name.

Also, switching to the PRE_VALIDATE state sort of implied that skip_cert_validation was false, so I checked for this before switching states. With CERT_CHAIN_PROCESSED, this isn't clear, So in a9c024e I made it always enter this state and skip the verify parts in s2n_x509_validator_verify_cert_chain.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe "READY_TO_VALIDATE"? Or just "READY"? Names are hard :\

Copy link
Contributor Author

Choose a reason for hiding this comment

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

READY_TO_VALIDATE makes sense. I switched it to READY_TO_VERIFY, to keep the state name the same as s2n_x509_validator_verify_cert_chain, which does the actual X509_verify_cert call now. 876a33b

tls/s2n_x509_validator.c Outdated Show resolved Hide resolved
tls/s2n_x509_validator.c 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
tests/unit/s2n_x509_validator_test.c Outdated Show resolved Hide resolved
Comment on lines 427 to 433
if (conn->actual_protocol_version >= S2N_TLS13) {
s2n_parsed_extensions_list parsed_extensions_list = { 0 };
RESULT_GUARD_POSIX(s2n_extension_list_parse(&cert_chain_in_stuffer, &parsed_extensions_list));

/* RFC 8446: if an extension applies to the entire chain, it SHOULD be included in the first CertificateEntry */
*first_certificate_extensions = parsed_extensions_list;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Not directly related to your change, and I know we already only processed the extensions from the first certificate, but it still feels like very wrong behavior to me. Can we put a comment somewhere (either here or down where the extensions are processed) making this behavior very clear and mentioning that it's an s2n-tls choice not specified by the RFC?

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 added a comment where the extensions are processed: 2b5f26e

I also moved the existing RFC SHOULD comment to here.

Copy link
Contributor

@lrstewart lrstewart left a comment

Choose a reason for hiding this comment

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

This is a nice refactor! Besides setting up for your next change, it makes this module much more readable.

@goatgoose goatgoose enabled auto-merge (squash) September 28, 2022 14:31
@goatgoose goatgoose merged commit bed17a3 into aws:main Sep 28, 2022
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.

None yet

3 participants