-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
certificate: add a get_extension
helper
#8892
Conversation
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Should be good to go now, modulo coverage -- I've rewritten existing The existing exception behavior is preserved by having the |
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
@@ -13,6 +14,12 @@ pub struct Certificate<'a> { | |||
pub signature: asn1::BitString<'a>, | |||
} | |||
|
|||
impl<'a> Certificate<'a> { | |||
pub fn extensions(&'a self) -> Result<Option<Extensions<'a>>, asn1::ObjectIdentifier> { | |||
self.tbs_cert.extensions() |
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.
Not sure it's worth it to have the method on TBS, is there a use case?
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.
That was mostly for tbs_precertificate_bytes
, since we need TbcCertificate.extensions()
in that context to perform the poison extension filtering. But maybe there's another way I should be getting the extensions there?
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.
Ah yep, I can get rid of this entirely.
Edit: Nope, I don't think I can directly get rid of this -- the TBS precert should have its extensions checked like the others but it doesn't go through the caching layer here (since all we're doing is munging the cert).
src/rust/src/x509/crl.rs
Outdated
let extensions = match tbs_cert_list.extensions() { | ||
Ok(exts) => exts, | ||
Err(oid) => { | ||
let oid_obj = oid_to_py_oid(py, &oid)?; | ||
return Err(exceptions::DuplicateExtension::new_err(( | ||
format!("Duplicate {} extension found", oid), | ||
oid_obj.into_py(py), | ||
))); | ||
} | ||
}; | ||
|
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 shouldn't be repeated in every extensions
method, it should be in parse_and_cache_extensions
which can take the result of calling extensions()
on the cert.
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.
Making sure I understand: in that case, parse_and_cache_extensions
should take a Result<Option<Extensions>>
? Because that'll be the return type from extensions()
.
(Or are you thinking it should take the RawExtensions
, and then convert it to an Extensions
internally? That would avoid passing a potential Err
variant through as a parameter.)
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.
I've done this with RawExtensions
; the error handling is now pushed fully into parse_and_cache_extensions
.
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
clippy |
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
GitHub is struggling today, but I've added some coverage for the new |
Signed-off-by: William Woodruff <[email protected]>
Remaining coverage items:
|
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
This should be fully good to go: I've removed |
raw: Option<&RawExtensions<'a>>, | ||
) -> Result<Option<Self>, asn1::ObjectIdentifier> { |
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.
I'm not super happy with this signature -- we end up pushing an Option
through as a no-op to avoid having to destructure the optional extensions in multiple other places, but that results in more invalid states than are strictly needed here (and the smelly Result<Option<...>>
type).
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.
I think a reasonable follow up is, instead of as_raw()
, we make Extensions
into an iterator, and just handle the Option<>
internally. But let's do that in a seperate PR, this one is already complicated enough.
Signed-off-by: William Woodruff <[email protected]>
Signed-off-by: William Woodruff <[email protected]>
raw: Option<&RawExtensions<'a>>, | ||
) -> Result<Option<Self>, asn1::ObjectIdentifier> { |
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.
I think a reasonable follow up is, instead of as_raw()
, we make Extensions
into an iterator, and just handle the Option<>
internally. But let's do that in a seperate PR, this one is already complicated enough.
Err(oid) => { | ||
let oid_obj = oid_to_py_oid(py, &oid)?; | ||
Err(exceptions::DuplicateExtension::new_err(( | ||
format!("Duplicate {} extension found", oid), | ||
oid_obj.into_py(py), | ||
)) | ||
.into()) | ||
} |
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.
To avoid needing to repeat this stanza anywhere we touch extensions, can we make extensions
return a more-specific error type and then we can do a From
impl on that?
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.
Yeah, good idea -- I'll do that now.
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.
212b75f is my attempt at this -- it saves us the repetition of this error clause in exchange for a new error enum + From
implementation.
@@ -391,27 +390,30 @@ pub(crate) fn parse_and_cache_extensions< | |||
>( | |||
py: pyo3::Python<'p>, | |||
cached_extensions: &mut Option<pyo3::PyObject>, | |||
raw_exts: &Option<Extensions<'_>>, | |||
raw_extensions: &Option<RawExtensions<'_>>, |
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.
I think we actually want this method to take an Option<Extensions>
and then the callers can obtain the extensions, via an extensions()
method on the various cryptography-x509
types. That way those types have the right methods that can be used from the validator crate.
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.
That SGTM, although if I understand correctly doing that will require us to make the Iterator
change mentioned in #8892 (comment): without that change, we'd need to perform the fallible conversion from RawExtensions -> Extensions
before parse_and_cache_extensions
, defeating the point of having it inside of that function. Or did I miss something?
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.
Ok, let's leave this change for a seperate PR.
Signed-off-by: William Woodruff <[email protected]> extensions: unwrap -> expect Signed-off-by: William Woodruff <[email protected]>
This reverts commit 212b75f.
Breakout from #8873.
Needs tests, but just to get something up for review.