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

feat(identity): make Keypair and Publickey opaque #3866

Merged
merged 35 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
e525203
work in progress Keypair
tcoratger May 2, 2023
65d6546
clean up
tcoratger May 2, 2023
7940834
remove KeypairType return and replace by Keypair
tcoratger May 4, 2023
8670e74
move pub Keypair to the top of file and replace KeypairType by Inner
tcoratger May 4, 2023
1be78fa
add ? to let ed25519_keypair
tcoratger May 4, 2023
2ae737c
clean up and remove some deprecated warnings
tcoratger May 4, 2023
bf065eb
remove other deprecated warnings
tcoratger May 4, 2023
fdd2b51
encapsulate PublicKeyType
tcoratger May 4, 2023
c649da8
clean up
tcoratger May 4, 2023
c5c5125
clean up
tcoratger May 4, 2023
f4b172f
move doc from private to public struct
tcoratger May 4, 2023
5c7d3cb
remove keypair_dummy.rs
tcoratger May 4, 2023
c3ad64f
Merge branch 'master' into identity-keypair-publickey-opaque
tcoratger May 4, 2023
894d22b
rename Inner to KeyPairInner and PublicKeyType to PublicKeyInner
tcoratger May 4, 2023
d96e3f5
pub(crate) publickey
tcoratger May 4, 2023
9d4fe3d
keypair module def unconditional
tcoratger May 4, 2023
1eb59bb
pub(crate) enum PublicKeyInner
tcoratger May 4, 2023
bb38ced
Merge branch 'master' into identity-keypair-publickey-opaque
tcoratger May 4, 2023
ab11cd1
clean up after merge
tcoratger May 4, 2023
e1dcbdb
clean up
tcoratger May 5, 2023
2e6baef
clean up useless ok()?
tcoratger May 5, 2023
e852a0c
clean up cfg
tcoratger May 5, 2023
c71b26e
Merge branch 'master' into identity-keypair-publickey-opaque
tcoratger May 5, 2023
d9969f9
remove all allow(deprecated) in keypair.rs
tcoratger May 5, 2023
a0d9267
add changelog
tcoratger May 5, 2023
c3bd310
clean up and fix quick_protobuf dependencies
tcoratger May 5, 2023
a6e45ec
fix self.keypair
tcoratger May 5, 2023
18e77d1
fix clippy
tcoratger May 5, 2023
60808fa
fix clippy
tcoratger May 5, 2023
f5781f0
Merge branch 'master' into identity-keypair-publickey-opaque
tcoratger May 5, 2023
9cb06fa
fix clippy
tcoratger May 5, 2023
c98dfd1
fix clippy
tcoratger May 5, 2023
b255326
fix due to keypair_protobuf_roundtrip_secp256k1 update
tcoratger May 5, 2023
e65f045
add features to keypair_from_protobuf_encoding test
tcoratger May 5, 2023
b998372
Minor tidy-up
thomaseizinger May 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 65 additions & 70 deletions identity/src/keypair.rs
thomaseizinger marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ use crate::secp256k1;
#[cfg(feature = "ecdsa")]
use crate::ecdsa;

#[derive(Debug, Clone)]
pub struct Keypair {
tcoratger marked this conversation as resolved.
Show resolved Hide resolved
keypair: Inner,
}

/// Identity keypair of a node.
///
/// # Example: Generating RSA keys with OpenSSL
Expand All @@ -55,57 +60,44 @@ use crate::ecdsa;
///
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum Keypair {
enum Inner {
/// An Ed25519 keypair.
#[cfg(feature = "ed25519")]
#[deprecated(
since = "0.1.0",
note = "This enum will be made opaque in the future, use `Keypair::try_into_ed25519` instead."
)]
Ed25519(ed25519::Keypair),
/// An RSA keypair.
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
#[deprecated(
since = "0.1.0",
note = "This enum will be made opaque in the future, use `Keypair::try_into_rsa` instead."
)]
Rsa(rsa::Keypair),
/// A Secp256k1 keypair.
#[cfg(feature = "secp256k1")]
#[deprecated(
since = "0.1.0",
note = "This enum will be made opaque in the future, use `Keypair::try_into_secp256k1` instead."
)]
Secp256k1(secp256k1::Keypair),
/// An ECDSA keypair.
#[cfg(feature = "ecdsa")]
#[deprecated(
since = "0.1.0",
note = "This enum will be made opaque in the future, use `Keypair::try_into_ecdsa` instead."
)]
Ecdsa(ecdsa::Keypair),
}

impl Keypair {
/// Generate a new Ed25519 keypair.
#[cfg(feature = "ed25519")]
pub fn generate_ed25519() -> Keypair {
#[allow(deprecated)]
Keypair::Ed25519(ed25519::Keypair::generate())
Keypair {
keypair: Inner::Ed25519(ed25519::Keypair::generate()),
}
}

/// Generate a new Secp256k1 keypair.
#[cfg(feature = "secp256k1")]
pub fn generate_secp256k1() -> Keypair {
#[allow(deprecated)]
Keypair::Secp256k1(secp256k1::Keypair::generate())
Keypair {
keypair: Inner::Secp256k1(secp256k1::Keypair::generate()),
}
}

/// Generate a new ECDSA keypair.
#[cfg(feature = "ecdsa")]
pub fn generate_ecdsa() -> Keypair {
#[allow(deprecated)]
Keypair::Ecdsa(ecdsa::Keypair::generate())
Keypair {
keypair: Inner::Ecdsa(ecdsa::Keypair::generate()),
}
}

#[cfg(feature = "ed25519")]
Expand Down Expand Up @@ -167,34 +159,37 @@ impl Keypair {
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<Keypair, DecodingError> {
#[allow(deprecated)]
tcoratger marked this conversation as resolved.
Show resolved Hide resolved
rsa::Keypair::from_pkcs8(pkcs8_der).map(Keypair::Rsa)
Ok(rsa::Keypair::from_pkcs8(pkcs8_der).map(|kp| Keypair {
keypair: Inner::Rsa(kp),
})?)
}

/// Decode a keypair from a DER-encoded Secp256k1 secret key in an ECPrivateKey
/// structure as defined in [RFC5915].
///
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
#[cfg(feature = "secp256k1")]
pub fn secp256k1_from_der(der: &mut [u8]) -> Result<Keypair, DecodingError> {
pub fn secp256k1_from_der(der: &mut [u8]) -> Result<Inner, DecodingError> {
tcoratger marked this conversation as resolved.
Show resolved Hide resolved
#[allow(deprecated)]
secp256k1::SecretKey::from_der(der)
.map(|sk| Keypair::Secp256k1(secp256k1::Keypair::from(sk)))
secp256k1::SecretKey::from_der(der).map(|sk| Inner::Secp256k1(secp256k1::Keypair::from(sk)))
}

#[cfg(feature = "ed25519")]
pub fn ed25519_from_bytes(bytes: impl AsMut<[u8]>) -> Result<Keypair, DecodingError> {
#[allow(deprecated)]
Ok(Keypair::Ed25519(ed25519::Keypair::from(
ed25519::SecretKey::from_bytes(bytes)?,
)))
Ok(Keypair {
keypair: Inner::Ed25519(ed25519::Keypair::from(ed25519::SecretKey::from_bytes(
bytes,
)?)),
})
}

/// Sign a message using the private key of this keypair, producing
/// a signature that can be verified using the corresponding public key.
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
use Keypair::*;
use Inner::*;
#[allow(deprecated)]
match self {
match self.keypair {
#[cfg(feature = "ed25519")]
Ed25519(ref pair) => Ok(pair.sign(msg)),
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Expand All @@ -208,9 +203,9 @@ impl Keypair {

/// Get the public key of this keypair.
pub fn public(&self) -> PublicKey {
use Keypair::*;
use Inner::*;
#[allow(deprecated)]
match self {
match &self.keypair {
#[cfg(feature = "ed25519")]
Ed25519(pair) => PublicKey::Ed25519(pair.public()),
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Expand All @@ -234,18 +229,18 @@ impl Keypair {
return Err(DecodingError::missing_feature("ed25519"));

#[allow(deprecated)]
let pk: proto::PrivateKey = match self {
let pk: proto::PrivateKey = match &self.keypair {
#[cfg(feature = "ed25519")]
Self::Ed25519(data) => proto::PrivateKey {
Inner::Ed25519(data) => proto::PrivateKey {
Type: proto::KeyType::Ed25519,
Data: data.encode().to_vec(),
},
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Self::Rsa(_) => return Err(DecodingError::encoding_unsupported("RSA")),
Inner::Rsa(_) => return Err(DecodingError::encoding_unsupported("RSA")),
#[cfg(feature = "secp256k1")]
Self::Secp256k1(_) => return Err(DecodingError::encoding_unsupported("secp256k1")),
Inner::Secp256k1(_) => return Err(DecodingError::encoding_unsupported("secp256k1")),
#[cfg(feature = "ecdsa")]
Self::Ecdsa(_) => return Err(DecodingError::encoding_unsupported("ECDSA")),
Inner::Ecdsa(_) => return Err(DecodingError::encoding_unsupported("ECDSA")),
};

let mut buf = Vec::with_capacity(pk.get_size());
Expand All @@ -270,7 +265,11 @@ impl Keypair {
proto::KeyType::Ed25519 =>
{
#[allow(deprecated)]
ed25519::Keypair::decode(&mut private_key.Data).map(Keypair::Ed25519)
Ok(
ed25519::Keypair::decode(&mut private_key.Data).map(|kp| Keypair {
keypair: Inner::Ed25519(kp),
})?,
)
}
#[cfg(not(feature = "ed25519"))]
proto::KeyType::Ed25519 => Err(DecodingError::missing_feature("ed25519")),
Expand All @@ -284,32 +283,32 @@ impl Keypair {
#[cfg(feature = "ecdsa")]
impl From<ecdsa::Keypair> for Keypair {
fn from(kp: ecdsa::Keypair) -> Self {
#[allow(deprecated)]
Keypair::Ecdsa(kp)
Inner::Ecdsa(kp)
}
}

#[cfg(feature = "ed25519")]
impl From<ed25519::Keypair> for Keypair {
fn from(kp: ed25519::Keypair) -> Self {
#[allow(deprecated)]
Keypair::Ed25519(kp)
Keypair {
keypair: Inner::Ed25519(kp),
}
}
}

#[cfg(feature = "secp256k1")]
impl From<secp256k1::Keypair> for Keypair {
fn from(kp: secp256k1::Keypair) -> Self {
#[allow(deprecated)]
Keypair::Secp256k1(kp)
Inner::Secp256k1(kp)
}
}

#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
impl From<rsa::Keypair> for Keypair {
fn from(kp: rsa::Keypair) -> Self {
#[allow(deprecated)]
Keypair::Rsa(kp)
Keypair {
keypair: Inner::Rsa(kp),
}
}
}

Expand All @@ -318,15 +317,14 @@ impl TryInto<ed25519::Keypair> for Keypair {
type Error = OtherVariantError;

fn try_into(self) -> Result<ed25519::Keypair, Self::Error> {
#[allow(deprecated)]
match self {
Keypair::Ed25519(inner) => Ok(inner),
match self.keypair {
Inner::Ed25519(inner) => Ok(inner),
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Keypair::Rsa(_) => Err(OtherVariantError::new(KeyType::RSA)),
Inner::Rsa(_) => Err(OtherVariantError::new(KeyType::RSA)),
#[cfg(feature = "secp256k1")]
Keypair::Secp256k1(_) => Err(OtherVariantError::new(KeyType::Secp256k1)),
Inner::Secp256k1(_) => Err(OtherVariantError::new(KeyType::Secp256k1)),
#[cfg(feature = "ecdsa")]
Keypair::Ecdsa(_) => Err(OtherVariantError::new(KeyType::Ecdsa)),
Inner::Ecdsa(_) => Err(OtherVariantError::new(KeyType::Ecdsa)),
}
}
}
Expand All @@ -336,15 +334,14 @@ impl TryInto<ecdsa::Keypair> for Keypair {
type Error = OtherVariantError;

fn try_into(self) -> Result<ecdsa::Keypair, Self::Error> {
#[allow(deprecated)]
match self {
tcoratger marked this conversation as resolved.
Show resolved Hide resolved
Keypair::Ecdsa(inner) => Ok(inner),
Inner::Ecdsa(inner) => Ok(inner),
#[cfg(feature = "ed25519")]
Keypair::Ed25519(_) => Err(OtherVariantError::new(KeyType::Ed25519)),
Inner::Ed25519(_) => Err(OtherVariantError::new(KeyType::Ed25519)),
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Keypair::Rsa(_) => Err(OtherVariantError::new(KeyType::RSA)),
Inner::Rsa(_) => Err(OtherVariantError::new(KeyType::RSA)),
#[cfg(feature = "secp256k1")]
Keypair::Secp256k1(_) => Err(OtherVariantError::new(KeyType::Secp256k1)),
Inner::Secp256k1(_) => Err(OtherVariantError::new(KeyType::Secp256k1)),
}
}
}
Expand All @@ -354,15 +351,14 @@ impl TryInto<secp256k1::Keypair> for Keypair {
type Error = OtherVariantError;

fn try_into(self) -> Result<secp256k1::Keypair, Self::Error> {
#[allow(deprecated)]
match self {
Keypair::Secp256k1(inner) => Ok(inner),
Inner::Secp256k1(inner) => Ok(inner),
#[cfg(feature = "ed25519")]
Keypair::Ed25519(_) => Err(OtherVariantError::new(KeyType::Ed25519)),
Inner::Ed25519(_) => Err(OtherVariantError::new(KeyType::Ed25519)),
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
Keypair::Rsa(_) => Err(OtherVariantError::new(KeyType::RSA)),
Inner::Rsa(_) => Err(OtherVariantError::new(KeyType::RSA)),
#[cfg(feature = "ecdsa")]
Keypair::Ecdsa(_) => Err(OtherVariantError::new(KeyType::Ecdsa)),
Inner::Ecdsa(_) => Err(OtherVariantError::new(KeyType::Ecdsa)),
}
}
}
Expand All @@ -372,15 +368,14 @@ impl TryInto<rsa::Keypair> for Keypair {
type Error = OtherVariantError;

fn try_into(self) -> Result<rsa::Keypair, Self::Error> {
#[allow(deprecated)]
match self {
Keypair::Rsa(inner) => Ok(inner),
match self.keypair {
Inner::Rsa(inner) => Ok(inner),
#[cfg(feature = "ed25519")]
Keypair::Ed25519(_) => Err(OtherVariantError::new(KeyType::Ed25519)),
Inner::Ed25519(_) => Err(OtherVariantError::new(KeyType::Ed25519)),
#[cfg(feature = "secp256k1")]
Keypair::Secp256k1(_) => Err(OtherVariantError::new(KeyType::Secp256k1)),
Inner::Secp256k1(_) => Err(OtherVariantError::new(KeyType::Secp256k1)),
#[cfg(feature = "ecdsa")]
Keypair::Ecdsa(_) => Err(OtherVariantError::new(KeyType::Ecdsa)),
Inner::Ecdsa(_) => Err(OtherVariantError::new(KeyType::Ecdsa)),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions identity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl From<&PublicKey> for proto::PublicKey {

pub use error::{DecodingError, OtherVariantError, SigningError};
pub use keypair::{Keypair, PublicKey};

#[cfg(feature = "peerid")]
pub use peer_id::{ParseError, PeerId};

Expand Down
24 changes: 10 additions & 14 deletions transports/noise/src/protocol/x25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,20 +161,16 @@ impl Keypair<X25519> {
/// > * [Noise: Static Key Reuse](http://www.noiseprotocol.org/noise.html#security-considerations)
#[allow(unreachable_patterns)]
pub fn from_identity(id_keys: &identity::Keypair) -> Option<AuthenticKeypair<X25519>> {
match id_keys {
identity::Keypair::Ed25519(p) => {
let kp = Keypair::from(SecretKey::from_ed25519(&p.secret()));
let id = KeypairIdentity {
public: id_keys.public(),
signature: None,
};
Some(AuthenticKeypair {
keypair: kp,
identity: id,
})
}
_ => None,
}
let ed25519_keypair = id_keys.clone().try_into_ed25519().ok()?;
let kp = Keypair::from(SecretKey::from_ed25519(&ed25519_keypair.secret()));
let id = KeypairIdentity {
public: id_keys.public(),
signature: None,
};
Some(AuthenticKeypair {
keypair: kp,
identity: id,
})
}
}

Expand Down