briansmith / ring

Safe, fast, small crypto using Rust
Other
3.75k stars 705 forks source link

Exporting components of secret keys #579

Open P-E-Meunier opened 7 years ago

P-E-Meunier commented 7 years ago

Following up on #545, I'd like to get access to the components of RSA and Ed25519 secret keys, in order to send them to an SSH agent.

If there is a strong reason not to have them public, I would like to know more about that: if I really need secret key components (which I really do), I can use another library.

briansmith commented 7 years ago

If there is a strong reason not to have them public, I would like to know more about that: if I really need secret key components (which I really do), I can use another library.

We intentionally don't allow extracting the private/secret components of key objects, because we want to promise that if you pass a &RSAKeyPair or &Ed25519KeyPair to a function, that function won't be able to break the abstraction and leak the private key (without doing nasty transmute()s and similar).

I suggest that we expose an API that lets you do the parsing of a private key into the raw key material fields. That is, parse the &[u8] into a struct that consists of &[u8] components of the key. These new public functions should live in ring::signature::primitive. The code is already available; it just needs to be extracted out of the *KeyPair constructor functions. The code that constructs RSAKeyPair and Ed25519KeyPairs and ECDSAKeyPairs should be updated to the new functions that were extracted out of the existing code..

P-E-Meunier commented 7 years ago

I suggest that we expose an API that lets you do the parsing of a private key into the raw key material fields.

That would be amazing!

jprider63 commented 6 years ago

I need to serialize keys to a different format, so I need this functionality as well. It looks like #582 is a work in progress implementing this. If it's helpful at all, I can help with the implementation.

One thing I noticed is that RSAKeyPairComponents is made of Input's. Would it make more sense to use big integers or Vec<u8>'s, so that users can more easily inspect the fields? I suppose users can always call bigint::Positive::from_be_bytes themselves.

In the meantime to get things working, it seems like the first 16 bytes of pkcs8 ed25519 keys are constant, followed by 32 bytes of the private key, followed by a 5 byte constant, followed by 32 bytes of the public key. Do you think it's safe to (temporarily) pull the private and public keys out of these positions from the output of from_pkcs8?

rphmeier commented 6 years ago

A strong API which prevents leakage of the private key is great. But there should also be an API which does allow inspecting the private key. Maybe expose a KeyPair/OpaqueKeyPair duality where KeyPair: Into<OpaqueKeyPair> but not vice-versa? Another alternative is to do signing via traits and not inherent implementations.

fn foo<S: SignEd25519>(s: &S) or fn foo(s: &SignEd25519) doesn't leak any info about the underlying type.

I have a use-case where I really have to have access to the private key directly (bip32-ed25519 HD derivation) and am a little frustrated by the opacity of the API.

jprider63 commented 6 years ago

@rphmeier For now, I've been storing keys as the [u8; 85] from the output of Ed25519KeyPair::generate_pkcs8. Then you can just pull out the bytes you need. Here's an example.

jdonszelmann commented 5 years ago

We also just stumbled into this problem. We need to get key components to a file which should be readable by other programming languages. Is this pull request still alive?

kim commented 4 years ago

I am a bit confused by this discussion, but perhaps things have evolved since. It is possible to construct an Ed25519KeyPair from seed + public key (which I could have generated elsewhere), and it's also possible to export private key material in pkcs#8 format via generate_pkcs8. It seems to me like nothing would be lost if we could also expose getting a pkcs#8 doc, regardless of how the key pair was obtained.

@briansmith Would you be able to shed some light on this? Pointing me to another crate which supports outputting pkcs#8 would also be fine :)

P-E-Meunier commented 4 years ago

@kim: my "thrussh-keys" crate (which was the initial motivation for this issue) can do this:

https://docs.rs/thrussh-keys/0.11.9/thrussh_keys/fn.encode_pkcs8_pem.html

It is much more modest in scope than ring, and probably not paranoid enough (it's never been audited, and it is a side project of mine).

kim commented 4 years ago

@P-E-Meunier Thanks, I found it shortly after posting :) I'm for now copy&pasta-ing the relevant bits, so as to not pull in a lot of dependencies. If I get to it, I might take a stab at extracting just the PKCS bits.