-
Notifications
You must be signed in to change notification settings - Fork 715
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
Exporting all components of RSA and ED25519 secret keys #582
Conversation
This also makes it possible to derive a public key from a secret key.
1 similar comment
Success! I just implemented an ssh-agent client, might add a server later today. |
Ok, I'm almost done with the agent server. It works fine for Ed25519 keys, and the only thing missing now is to generate dP and dQ from d, p and q using the bigint module. Is there an easy answer? |
They're already in the input. Notice in the code these two lines: let _dP = der::positive_integer(input)?;
let _dQ = der::positive_integer(input)?; You just need to put dP and dQ into the RSAPrivateKeyComponents structure. |
src/ec/curve25519/ed25519.rs
Outdated
/// for signing, see [Ed25519KeyPair](./Ed25519KeyPair.html) instead. | ||
pub struct Ed25519KeyPairComponents { | ||
/// The 32-byte private part of this pair, i.e. the seed. | ||
pub private_key: [u8; 32], |
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 should be called seed
.
src/ec/curve25519/ed25519.rs
Outdated
/// `Ed25519KeyPair::from_pkcs8_maybe_unchecked()` instead. | ||
pub fn from_pkcs8(input: untrusted::Input) | ||
-> Result<Ed25519KeyPairComponents, error::Unspecified> { | ||
let (seed, public_key) = unwrap_pkcs8(pkcs8::Version::V2Only, input)?; |
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.
Once you have seed and public_key, you can return Ed25519KeyPairComponents { seed, public_key }
. In particular, you don't need to do any further validation.
/// public key). This also detects any corruption of the public or private | ||
/// key. | ||
pub fn from_seed_and_public_key(seed: untrusted::Input, | ||
public_key: untrusted::Input) |
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.
If you already have the seed and the public key, then you already had the components you needed so there's nothing to do. Thus, this function isn't necessary in Ed25519KeyPairComponents.
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.
Actually, I need it, because keys from SSH key files are not always in PKCS#8, and I still need to get their components.
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.
Sorry, I don't understand. There's already a public pub fn from_seed_and_public_key()
function in Ed25519KeyPair
so you can just use it directly without using Ed25519KeyPairComponents
at all, right?
src/ec/curve25519/ed25519.rs
Outdated
/// Since the public key is not given, the public key will be computed from | ||
/// the private key. It is not possible to detect misuse or corruption of | ||
/// the private key since the public key isn't given as input. | ||
pub fn from_seed_unchecked(seed: untrusted::Input) |
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.
Are you actually using this function in your key server? I suspect you're not, if not, let's remove it. Otherwise, I am curious why you need it, as I suspect you shouldn't need it.
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 looks like it's on the right track. Besides the changes I mentioned elsewhere, the constructors for RSAKeyPair
and Ed25519KeyPair
need to be rewritten in terms of RSAKeyPairComponents
and Ed25519KeyPairComponents
. For example, RSAKeyPair::from_pkcs8()
should be something like RSAKeyPairComponents::from_pkcs8(input).,map(Self::from_components)
where
/// Note: not public.
fn from_components<'a>(components: RSAKeyPairComponents<'a> -> Result<Self, error::Unspecified> {
// Most of the code that's currently in `from_der()`
}
src/ec/curve25519/ed25519.rs
Outdated
} | ||
|
||
/// Returns a reference to the little-endian-encoded public key bytes. | ||
pub fn public_key_bytes(&'a self) -> &'a [u8] { |
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 function isn't needed because self.public_key
is public.
src/rsa/signing.rs
Outdated
/// Prime factor of n (big endian). | ||
pub p: untrusted::Input<'a>, | ||
/// Prime factor of n (big endian). | ||
pub q: untrusted::Input<'a>, |
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 is missing dP and dQ. Also, make sure these are all in the same order as they're given in the RFC.
src/signature.rs
Outdated
@@ -302,14 +302,15 @@ pub use ec::curve25519::ed25519::{ | |||
ED25519, | |||
|
|||
Ed25519KeyPair, | |||
Ed25519KeyPairComponents, |
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 should be exposed from ring::signature::primitives
not from ring::signature
.
src/signature.rs
Outdated
ED25519_PKCS8_V2_LEN, | ||
ED25519_PUBLIC_KEY_LEN, | ||
}; | ||
|
||
pub use pkcs8::PKCS8Document; | ||
|
||
#[cfg(all(feature = "rsa_signing", feature = "use_heap"))] | ||
pub use rsa::signing::{RSAKeyPair, RSASigningState}; | ||
pub use rsa::signing::{RSAKeyPair, RSAKeyPairComponents, RSASigningState}; |
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.
Ditto; this should be exposed from ring::signature::primitives
, not ring::signature
.
Sorry, I was imprecise. They are not always in the input in all cases. Sure, in PKCS#8, they are, but they are not stored by the SSH agent. Oh wait, there's a "comment" field in the agent. Nevermind. Thanks for the rest of the review! |
Ok, this works, but my server is only be able to exchange RSA keys with my client (not with OpenSSH). I really need a way to compute dP and dQ from the other parameters. |
By the way, I just fixed my problem by using the num-bigint crate. I now have a client and server for SSH-agent (the only missing feature is smartcards). |
src/ec/curve25519/ed25519.rs
Outdated
@@ -228,6 +228,13 @@ impl<'a> Ed25519KeyPairComponents { | |||
Self::from_seed_unchecked(seed) | |||
} | |||
|
|||
/// Constructs an `Ed25519KeyPair` from these components. | |||
pub fn to_key_pair(&self) -> Result<Ed25519KeyPair, error::Unspecified> { |
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 specifically want to avoid having a to_key_pair
function here, so let's remove this commit. Users can implement this logic themselves if they want.
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 specifically want to avoid having a to_key_pair function here, so let's remove this commit. Users can implement this logic themselves if they want.
Never mind this, I misunderstood and I've changed my mind. Ignore the previous comment.
Sorry, I started to review this and then realized it's going to take too much time for me to do today. Ignore my earlier comments. I'll think through what I want to do here and return to the review another day. |
Thanks for submitting this. I understand it's not needed by the original submitter any longer so I'm closing this. I think we'll add this functionality one way or another soon. |
Solves #579 for my RSA keys.
This also makes it possible to derive a public key from a secret key (which is also something I really needed for RSA keys).