Skip to content
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

Closed
wants to merge 5 commits into from
Closed

Exporting all components of RSA and ED25519 secret keys #582

wants to merge 5 commits into from

Conversation

P-E-Meunier
Copy link
Contributor

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).

This also makes it possible to derive a public key from a secret key.
@P-E-Meunier P-E-Meunier changed the title Exporting all components of RSA secret keys Exporting all components of RSA and ED25519 secret keys Oct 18, 2017
@coveralls
Copy link

coveralls commented Oct 19, 2017

Coverage Status

Coverage decreased (-0.7%) to 94.813% when pulling e892a5c on P-E-Meunier:master into 33784df on briansmith:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.8%) to 94.754% when pulling e892a5c on P-E-Meunier:master into 33784df on briansmith:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.8%) to 94.754% when pulling e892a5c on P-E-Meunier:master into 33784df on briansmith:master.

@P-E-Meunier
Copy link
Contributor Author

Success! I just implemented an ssh-agent client, might add a server later today.

@coveralls
Copy link

coveralls commented Oct 19, 2017

Coverage Status

Coverage decreased (-0.7%) to 94.813% when pulling e892a5c on P-E-Meunier:master into 33784df on briansmith:master.

@P-E-Meunier
Copy link
Contributor Author

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?

@briansmith
Copy link
Owner

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.

/// 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],
Copy link
Owner

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.

/// `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)?;
Copy link
Owner

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)
Copy link
Owner

@briansmith briansmith Oct 20, 2017

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.

Copy link
Contributor Author

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.

Copy link
Owner

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?

/// 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)
Copy link
Owner

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.

Copy link
Owner

@briansmith briansmith left a 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()`
}

}

/// Returns a reference to the little-endian-encoded public key bytes.
pub fn public_key_bytes(&'a self) -> &'a [u8] {
Copy link
Owner

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.

/// Prime factor of n (big endian).
pub p: untrusted::Input<'a>,
/// Prime factor of n (big endian).
pub q: untrusted::Input<'a>,
Copy link
Owner

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,
Copy link
Owner

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};
Copy link
Owner

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.

@P-E-Meunier
Copy link
Contributor Author

P-E-Meunier commented Oct 20, 2017

They're already in the input. Notice in the code these two lines:

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!

@P-E-Meunier
Copy link
Contributor Author

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.

@coveralls
Copy link

coveralls commented Oct 20, 2017

Coverage Status

Coverage decreased (-0.6%) to 94.993% when pulling 8c36772 on P-E-Meunier:master into 33784df on briansmith:master.

@coveralls
Copy link

coveralls commented Oct 21, 2017

Coverage Status

Coverage decreased (-0.6%) to 94.993% when pulling 8c36772 on P-E-Meunier:master into 33784df on briansmith:master.

@P-E-Meunier
Copy link
Contributor Author

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).

@coveralls
Copy link

coveralls commented Oct 25, 2017

Coverage Status

Coverage decreased (-0.6%) to 94.946% when pulling ba228e1 on P-E-Meunier:master into 33784df on briansmith:master.

@@ -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> {
Copy link
Owner

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.

Copy link
Owner

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.

@briansmith
Copy link
Owner

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.

@briansmith
Copy link
Owner

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.

@briansmith briansmith closed this Dec 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants