-
Notifications
You must be signed in to change notification settings - Fork 141
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
x509-cert: Creating x509 certificates without allocations #689
Comments
The current implementation of the crate relies on However, Backing storage for For heapless X.509 parsing, a push parser may be a better approach so certificates can be validated on-the-fly as opposed to parsed into a data structure, however the It might be possible to make a heapless pull parser work using something like Which use cases are you interested in? Parsing? Serialization? |
Thank you for your answer. I am mostly interested in x509 serialization. |
Serialization shouldn't be too hard to support. It may require adding something like |
Great news. I will try implementing it, following what you advised. Then, If I'm successful, I'll open a PR. |
Hi, I tried to decorrelate parsing and serialization, to focus on serialization. To do so, I first implemented a Then, I tried defining Do you have some more advices? |
You don't actually have to implement the Instead just impl the |
For Edit: Another option is to build the DER in reverse (from end to beginning) into a pre-allocated buffer effectively “by hand”, the way e.g. the TPM2 Reference Implementation does it. |
@DemiMarie we've never sorted during serialization. Sorting occurs at construction time, and the implementation has been changed to ignore out-of-order SET OF elements during deserialization, which is unfortunately necessary to support real-world use cases (though ideally we'd introduce some sort of lint which would fail in that case) |
@tarcieri To elaborate: instead of building a data structure that is then serialized, it might use less resources to directly extend the buffer in back-to-front fashion in one pass. |
The serialization logic in this crate relies on knowing the entire document structure in advance, which is needed to calculate the many, many nested length tags. It's effectively two pass: the first pass calculates the lengths, and the second pass calculates the document. Off the top of my head I can't see a way to build a sort of on-the-fly serializer which works in two passes like that. |
@tarcieri One can avoid this by serializing in reverse order. In the case of an X.509 certificate, this would mean serializing the signature first and the length field last. The result is that length tags do not need to be calculated until after the things they are lengths of have already been serialized. The TPM 2.0 reference implementation does exactly this. |
I guess that's a possibility, but it would be a very radically different approach from the current implementation and couldn't reuse any of the existing traits |
ASN.1 objects also have a LOT of constant strings. For instance, it is much faster to serialize an AlgorithmIdentifier by |
That helps when the Anyway, that's a separate micro-optimization. |
I'll just say this: the crates in this repo tend largely follow a "DOM" approach which "pull" parses/serializes types which represent a constructed document. A "streaming" crate with a push parser/serializer would probably be a better API for heapless use cases, but also a radically different approach to the point it may be best to implement it as a separate crate. |
How does WebPKI do things? |
Since those PRs landed, We made those changes to make things like certificate builders easier. |
I've been building up x509-related tooling related to secure boot on a |
@kc8apf do you need certificate generation or just parsing? If the latter, then https://github.com/barebones-x509/barebones-x509 implements no-alloc certificate parsing, including signature checking. It does depend on ring but I would be open to a PR to replace it. |
For bootleby, only parsing is needed. For another part of the stack, I'll
need both parsing and generation. I'll also want to use a hardware
accelerator for RSA so having a way to supply my own RSA crate is important.
…On Wed, Apr 12, 2023, 6:16 PM Demi Marie Obenour ***@***.***> wrote:
@kc8apf <https://github.com/kc8apf> do you need certificate *generation*
or just *parsing*?
If the latter, then https://github.com/barebones-x509/barebones-x509
implements no-alloc certificate parsing, including signature checking. It
does depend on *ring* but I would be open to a PR to replace it.
—
Reply to this email directly, view it on GitHub
<#689 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACIEHF4J3LUUJQ3HIKUG3BDXA5HW5ANCNFSM54RVJKGQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@kc8apf Unrelated to the initial question, I'm definitely eager for feedback on the x509 builder (currently lives in master, it's not released yet). |
@kc8apf would you be willing to make a PR to barebones-x509? |
I find myself in a position where I need at least part of this, and are willing to put in the effort, but I might need some input as to which way you would prefer to see this going? Currently, all I need is alloc-less serialization, more specific I need to be able to serialize a CSR. I have read through related issues and PRs I could find, and see you are considering I also see in #765 the discussion on duplicating implementations for All I need for now is the serialization part, so I am looking for the shortest path to that, but would much rather contribute a bit more than I need, in favor of re-implementing in some private repo. Ping @tarcieri |
At this point given the level to which this crate has embraced an I think every part of the crate needs to be designed around those requirements, which presently this is not. One which was identified earlier was changing how encoding works so the serializer starts off writing the end of the certificate/document into the end of the buffer, i.e. recursing down through the document tree to the leaf nodes and iterating over those right-to-left, effectively walking the tree in complete reverse from how it is now. With the lengths of the children known they can be used to compute the parents, walking all the way back up to the root of the document. Another would be to have a different kind of builder API which borrows data everywhere and only for the duration of serializing that part of the document. Once the data has been written to the certificate-in-progress, the input no longer needs borrowed. This is a fairly radical departure from how the While we could put such a builder in this crate, it might make more sense to prototype out-of-tree, at least at first. |
Fair enough. |
@MathiasKoch What did you come up with? |
I ended up with a very rough minimal implementation through copy-paste, that so far only handles my needs of creating a CSR. https://github.com/FactbirdHQ/at-cryptoauth-rs/tree/feature/async/src/cert |
Hello,
I'm interested in using
x509-cert
in an environment where no heap allocation is possible. I'm still new to Rust but if I understand correctly,x509-cert
is working well in ano_std
setting but currently require an implementation foralloc
(mostly to useVec
).Do you think that having a "no_alloc" version of
x509-cert
is possible and desirable? The main drawback I see is that I think it will force the developper to set a maximum size for its x509 certifcate at compilation time.If you think it is a good idea to provide a version of
x509-cert
which does not requirealloc
, do you have a prefered approach for that (for example, replacing the use ofVec
withheapless::Vec
ortinyvec::ArrayVec
)? If needed, I can work on it myself but I'll be happy to follow any advice you can give me.The text was updated successfully, but these errors were encountered: