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

rust: Use extension policy mechanism to check for unaccounted critical extensions #6

Merged
merged 2 commits into from
Oct 24, 2023

Conversation

tetsuo-cpp
Copy link

No description provided.

@@ -369,6 +356,21 @@ impl<'a, B: CryptoOps> Policy<'a, B> {
}
}

// Check that all critical extensions in this certificate are accounted for.
for extension in extensions.iter() {
Copy link
Author

Choose a reason for hiding this comment

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

Wasn't exactly sure how best to unit test this in Rust. Perhaps via the chain validation API (so in cryptography-x509-validation/src/lib.rs)?

Copy link
Member

Choose a reason for hiding this comment

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

I think we should probably do it with a limbo test (if there isn't one already?) -- a leaf/intermediate with an unknown critical extension should fail validation.

(It's unclear to me whether a root with an unknown critical extension should fail validation -- roots are defined as a representation of a trust authority, and a TA is defined just in terms of a public key and subject.)

@tetsuo-cpp tetsuo-cpp requested a review from woodruffw October 24, 2023 07:24
Comment on lines 362 to 370
let policies_handle_extension = |policies: &Vec<ExtensionPolicy<B>>| {
policies.iter().any(|x| x.oid == extension.extn_id)
};
if !policies_handle_extension(&self.common_extension_policies)
&& !policies_handle_extension(&self.ca_extension_policies)
&& !policies_handle_extension(&self.ee_extension_policies)
{
return Err("certificate contains unaccounted critical extension".into());
}
Copy link
Member

Choose a reason for hiding this comment

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

FWIW, you can probably reduce this indirection by doing Iterator::chain + Iteratory::any instead, or set subtraction between the two. I'll play around with it and push something up 🙂

@woodruffw woodruffw force-pushed the alex/critical-extension-check branch from e823b33 to 9916348 Compare October 24, 2023 20:05
Comment on lines +359 to +379
// Check that all critical extensions in this certificate are accounted for.
let critical_extensions = extensions
.iter()
.filter(|e| e.critical)
.map(|e| e.extn_id)
.collect::<HashSet<_>>();
let checked_extensions = self
.common_extension_policies
.iter()
.chain(self.ca_extension_policies.iter())
.chain(self.ee_extension_policies.iter())
.map(|p| p.oid.clone())
.collect::<HashSet<_>>();
let unchecked_extensions = critical_extensions
.difference(&checked_extensions)
.collect::<Vec<_>>();

if !unchecked_extensions.is_empty() {
// TODO: Render the OIDs here.
return Err("certificate contains unaccounted-for critical extensions".into());
}
Copy link
Member

Choose a reason for hiding this comment

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

This is slightly more verbose, but should be more efficient than the previous critical extension sweep.

@woodruffw woodruffw merged commit ba37c80 into tob-x509-cv-skeleton Oct 24, 2023
@woodruffw woodruffw deleted the alex/critical-extension-check branch October 24, 2023 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants