-
Notifications
You must be signed in to change notification settings - Fork 69
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
Switch storage to Cow<'a, X>
and implement ToOwned
?
#76
Comments
Cow<'a, X>
and implement ToOwned
Cow<'a, X>
and implement ToOwned
?
Hi, |
I have committed a work-in-progress in branch cow-v0.1 I did not implement @indygreg can you test this branch and give some feedback? |
@chifflier Hi! I am facing a similar issue where I want to pass and persist the parsed X.509 structure somewhere. So using a Cow backing store makes sense to me. However, trying to build the dev/cow-v0.1 branch, I get compiler errors: cargo build output
Is that expected or am I holding it wrong? |
I had a similar need and first thought it would be great to use I ended up using ouroboros instead: use std::fmt;
use ouroboros::self_referencing;
use x509_parser::{certificate::X509Certificate, prelude::FromDer};
#[self_referencing]
pub struct X509Cert {
der_buf: Vec<u8>,
#[borrows(der_buf)]
#[covariant]
cert: X509Certificate<'this>,
}
impl X509Cert {
pub fn from_der(der: &[u8]) -> Result<Self, ()> {
// Because we're self-referencing the buffer and the parsed certificate
// we need to parse it twice.
// Once to get the actual length of the buffer (and cut off any tail).
// And a second time to actually store the parsed value.
let (rest, _cert) = X509Certificate::from_der(der).map_err(|_| ())?;
let der_buf: Vec<u8> = der[..(der.len() - rest.len())].into();
X509CertTryBuilder {
der_buf,
cert_builder: |buf| match X509Certificate::from_der(&buf[..]) {
Err(_) => Err(()),
Ok((_rest, cert)) => Ok(cert),
},
}
.try_build()
}
pub fn cert(&self) -> &X509Certificate<'_> {
self.borrow_cert()
}
}
impl fmt::Debug for X509Cert {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.borrow_cert().fmt(f)
}
} That works for me, for now. |
I'm curious if this issue is still on the roadmap? I recently ran into a similar problem, and I'll prefer not to use the |
I accidentally [1] implemented my own x509 parser as part of implementing RFC 5652 for https://crates.io/crates/cryptographic-message-syntax. When I realized the horrors I had committed, I wanted to switch to using this crate. However, I couldn't coerce it into working easily because data types in this crate have lifetimes and always hold references. e.g.
&'a [u8]
. There's no option to obtain an owned version of the data structures. And since Rust doesn't allow you to have self-referential data structures [easily], I couldn't get this crate to work given some of my constraints that need'static
/ owned lifetimes.Are the maintainers of this crate receptive to the idea of mass changing all references in structs to
Cow<'a, X>
and implementingToOwned
so all data types can be owned, cloned, and not subjected to lifetime constraints? If you are, perhaps I'll find time to do the work so I can delete the one-off x509 crate (https://crates.io/crates/x509-certificate) I begrudgingly created.[1] This was accidental because when I was following the rabbit hole of recursively defining ASN.1 types for RFC 5652, I didn't realize I was reinventing x509 certificate parsing because this was the first time I was exposed to the internals of x509 certificates. Only after I had implemented a full RFC 5652 ASN.1 decoder did I realize many of the types were foundational and general crypto primitives. Oops!
The text was updated successfully, but these errors were encountered: