RSA icon indicating copy to clipboard operation
RSA copied to clipboard

Public key import functions are not `const fn`s

Open LoganDark opened this issue 3 years ago • 5 comments

I want to embed keys directly into the binary, already-imported and ready to go, but since (in my specific case) RsaPublicKey::from_public_key_pem is not a const fn, I can't call it from a static context.

Perhaps this is because FromPublicKey is a trait. Maybe RsaPublicKey could expose non-trait methods for importing (which could then be const fns), and the trait methods could delegate to those.

Being unable to import public keys statically is a real disappointment. :(

LoganDark avatar Nov 26 '21 22:11 LoganDark

What you’re suggesting would require an entire const fn PEM decoder as well as a const fn ASN.1 DER decoder.

What is the issue with embedding the key as a str or [u8] and then decoding it when you need it?

tarcieri avatar Nov 27 '21 00:11 tarcieri

What you’re suggesting would require an entire const fn PEM decoder as well as a const fn ASN.1 DER decoder.

Is there an issue with converting the existing one to const?

What is the issue with embedding the key as a str or [u8] and then decoding it when you need it?

This can panic at runtime when I know that the keys I'm embedding are 100% valid. Regardless of that (suppose I use unwrap_unchecked) it still has to do PEM decoding at runtime that could have been performed at compile time.

LoganDark avatar Nov 27 '21 00:11 LoganDark

Is there an issue with converting the existing one to const?

Yes, that would be a herculean effort, as everything from the decoders to replacing the current heap-allocated bignum representation (which is planned, as it were) is incompatible with const fn.

The current decoder heavily leverages traits for pretty much everything in the decoding process, and as such it wouldn’t make much sense until const impl lands.

tarcieri avatar Nov 27 '21 01:11 tarcieri

After we migrate to crypto-bigint it should be possible to parse key files in build script, retrieve binary representation of n and e, and finally initialize RsaPublicKey as a constant using included bytes from the build script. I think (but not sure) that it should be possible to constify RsaPublicKey::new after the migration and since it's now possible to unwrap in const fns, it should satisfy your requirements, albeit in a somewhat roundabout way.

newpavlov avatar Nov 27 '21 01:11 newpavlov

@newpavlov That sounds like it would work just fine. LMK when you've migrated and I'll give it a go. Thanks!

Also sounds like a great opportunity to add a proc macro (for embedding keys directly) :)

LoganDark avatar Nov 27 '21 07:11 LoganDark

I'll close this with the suggestion of embedding the DER-encoded PKCS#1/SPKI public for now.

As @newpavlov mentioned, it will take a migration to crypto-bigint to make this possible. But also, when we do that it will likely involve using generics/traits so that we can support both stack-allocated and heap-allocated big integers, so I don't see something like this working without const impl.

Perhaps we could make some very basic functionality work with const fn inherent methods, like a from_const_components method or something, but again that's in a hypothetical future where we've migrated to crypto-bigint.

tl;dr: any solution here seems somewhat distant

tarcieri avatar Apr 27 '23 15:04 tarcieri