diff --git a/Cargo.lock b/Cargo.lock index 459afe3ece5..dc4c8439718 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1226,18 +1226,32 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0-rc.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d4ba9852b42210c7538b75484f9daa0655e9a3ac04f693747bb0f02cf3cfe16" +checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" dependencies = [ "cfg-if 1.0.0", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", "fiat-crypto", - "packed_simd_2", "platforms", + "rustc_version", "subtle", "zeroize", ] +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + [[package]] name = "darling" version = "0.14.4" @@ -1469,24 +1483,25 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ - "signature 1.6.4", + "pkcs8 0.10.2", + "signature 2.1.0", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 3.2.0", + "curve25519-dalek 4.0.0", "ed25519", - "rand 0.7.3", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.7", "zeroize", ] @@ -2501,12 +2516,6 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "libm" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" - [[package]] name = "libp2p" version = "0.52.3" @@ -2783,7 +2792,7 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.2" +version = "0.2.3" dependencies = [ "asn1_der", "base64 0.21.2", @@ -3974,16 +3983,6 @@ dependencies = [ "sha2 0.10.7", ] -[[package]] -name = "packed_simd_2" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" -dependencies = [ - "cfg-if 1.0.0", - "libm", -] - [[package]] name = "parking" version = "2.1.0" @@ -5315,14 +5314,14 @@ dependencies = [ [[package]] name = "snow" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ccba027ba85743e09d15c03296797cad56395089b832b48b5a5217880f57733" +checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155" dependencies = [ "aes-gcm 0.9.2", "blake2", "chacha20poly1305", - "curve25519-dalek 4.0.0-rc.1", + "curve25519-dalek 4.0.0", "rand_core 0.6.4", "ring", "rustc_version", diff --git a/Cargo.toml b/Cargo.toml index 03b3833033b..e42a905bc39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ libp2p-dns = { version = "0.40.0", path = "transports/dns" } libp2p-floodsub = { version = "0.43.0", path = "protocols/floodsub" } libp2p-gossipsub = { version = "0.45.1", path = "protocols/gossipsub" } libp2p-identify = { version = "0.43.0", path = "protocols/identify" } -libp2p-identity = { version = "0.2.2" } +libp2p-identity = { version = "0.2.3" } libp2p-kad = { version = "0.44.4", path = "protocols/kad" } libp2p-mdns = { version = "0.44.0", path = "protocols/mdns" } libp2p-memory-connection-limits = { version = "0.1.0", path = "misc/memory-connection-limits" } diff --git a/identity/CHANGELOG.md b/identity/CHANGELOG.md index bfe46076a3a..b52f001827f 100644 --- a/identity/CHANGELOG.md +++ b/identity/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.3 + +- Fix [RUSTSEC-2022-0093] by updating `ed25519-dalek` to `2.0`. + See [PR 4337] + +[RUSTSEC-2022-0093]: https://rustsec.org/advisories/RUSTSEC-2022-0093 +[PR 4337]: https://github.com/libp2p/rust-libp2p/pull/4337 + ## 0.2.2 - Implement `from_protobuf_encoding` for RSA `Keypair`. diff --git a/identity/Cargo.toml b/identity/Cargo.toml index 09ba3c155ee..ed74c5e9836 100644 --- a/identity/Cargo.toml +++ b/identity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libp2p-identity" -version = "0.2.2" +version = "0.2.3" edition = "2021" description = "Data structures and algorithms for identifying peers in libp2p." rust-version = { workspace = true } @@ -14,7 +14,7 @@ categories = ["cryptography"] [dependencies] asn1_der = { version = "0.7.6", optional = true } bs58 = { version = "0.5.0", optional = true } -ed25519-dalek = { version = "1.0.1", optional = true } +ed25519-dalek = { version = "2.0", optional = true, features = ["rand_core"] } libsecp256k1 = { version = "0.7.0", optional = true } log = "0.4" multihash = { version = "0.19.0", optional = true } diff --git a/identity/src/ed25519.rs b/identity/src/ed25519.rs index bcd3eb44359..23d11932425 100644 --- a/identity/src/ed25519.rs +++ b/identity/src/ed25519.rs @@ -25,12 +25,12 @@ use core::cmp; use core::fmt; use core::hash; use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _}; -use rand::RngCore; use std::convert::TryFrom; use zeroize::Zeroize; /// An Ed25519 keypair. -pub struct Keypair(ed25519::Keypair); +#[derive(Clone)] +pub struct Keypair(ed25519::SigningKey); impl Keypair { /// Generate a new random Ed25519 keypair. @@ -42,7 +42,7 @@ impl Keypair { /// of the secret scalar and the compressed public point, /// an informal standard for encoding Ed25519 keypairs. pub fn to_bytes(&self) -> [u8; 64] { - self.0.to_bytes() + self.0.to_keypair_bytes() } /// Try to parse a keypair from the [binary format](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5) @@ -50,7 +50,10 @@ impl Keypair { /// /// Note that this binary format is the same as `ed25519_dalek`'s and `ed25519_zebra`'s. pub fn try_from_bytes(kp: &mut [u8]) -> Result { - ed25519::Keypair::from_bytes(kp) + let bytes = <[u8; 64]>::try_from(&*kp) + .map_err(|e| DecodingError::failed_to_parse("Ed25519 keypair", e))?; + + ed25519::SigningKey::from_keypair_bytes(&bytes) .map(|k| { kp.zeroize(); Keypair(k) @@ -65,60 +68,41 @@ impl Keypair { /// Get the public key of this keypair. pub fn public(&self) -> PublicKey { - PublicKey(self.0.public) + PublicKey(self.0.verifying_key()) } /// Get the secret key of this keypair. pub fn secret(&self) -> SecretKey { - SecretKey::try_from_bytes(&mut self.0.secret.to_bytes()) - .expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k") + SecretKey(self.0.to_bytes()) } } impl fmt::Debug for Keypair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Keypair") - .field("public", &self.0.public) + .field("public", &self.0.verifying_key()) .finish() } } -impl Clone for Keypair { - fn clone(&self) -> Keypair { - let mut sk_bytes = self.0.secret.to_bytes(); - let secret = SecretKey::try_from_bytes(&mut sk_bytes) - .expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k") - .0; - - Keypair(ed25519::Keypair { - secret, - public: self.0.public, - }) - } -} - /// Demote an Ed25519 keypair to a secret key. impl From for SecretKey { fn from(kp: Keypair) -> SecretKey { - SecretKey(kp.0.secret) + SecretKey(kp.0.to_bytes()) } } /// Promote an Ed25519 secret key into a keypair. impl From for Keypair { fn from(sk: SecretKey) -> Keypair { - let secret: ed25519::ExpandedSecretKey = (&sk.0).into(); - let public = ed25519::PublicKey::from(&secret); - Keypair(ed25519::Keypair { - secret: sk.0, - public, - }) + let signing = ed25519::SigningKey::from_bytes(&sk.0); + Keypair(signing) } } /// An Ed25519 public key. #[derive(Eq, Clone)] -pub struct PublicKey(ed25519::PublicKey); +pub struct PublicKey(ed25519::VerifyingKey); impl fmt::Debug for PublicKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -170,27 +154,22 @@ impl PublicKey { /// Try to parse a public key from a byte array containing the actual key as produced by `to_bytes`. pub fn try_from_bytes(k: &[u8]) -> Result { - ed25519::PublicKey::from_bytes(k) + let k = <[u8; 32]>::try_from(k) + .map_err(|e| DecodingError::failed_to_parse("Ed25519 public key", e))?; + ed25519::VerifyingKey::from_bytes(&k) .map_err(|e| DecodingError::failed_to_parse("Ed25519 public key", e)) .map(PublicKey) } } /// An Ed25519 secret key. +#[derive(Clone)] pub struct SecretKey(ed25519::SecretKey); /// View the bytes of the secret key. impl AsRef<[u8]> for SecretKey { fn as_ref(&self) -> &[u8] { - self.0.as_bytes() - } -} - -impl Clone for SecretKey { - fn clone(&self) -> SecretKey { - let mut sk_bytes = self.0.to_bytes(); - Self::try_from_bytes(&mut sk_bytes) - .expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k") + &self.0[..] } } @@ -203,13 +182,8 @@ impl fmt::Debug for SecretKey { impl SecretKey { /// Generate a new Ed25519 secret key. pub fn generate() -> SecretKey { - let mut bytes = [0u8; 32]; - rand::thread_rng().fill_bytes(&mut bytes); - SecretKey( - ed25519::SecretKey::from_bytes(&bytes).expect( - "this returns `Err` only if the length is wrong; the length is correct; qed", - ), - ) + let signing = ed25519::SigningKey::generate(&mut rand::rngs::OsRng); + SecretKey(signing.to_bytes()) } /// Try to parse an Ed25519 secret key from a byte slice @@ -218,7 +192,7 @@ impl SecretKey { /// returned. pub fn try_from_bytes(mut sk_bytes: impl AsMut<[u8]>) -> Result { let sk_bytes = sk_bytes.as_mut(); - let secret = ed25519::SecretKey::from_bytes(&*sk_bytes) + let secret = <[u8; 32]>::try_from(&*sk_bytes) .map_err(|e| DecodingError::failed_to_parse("Ed25519 secret key", e))?; sk_bytes.zeroize(); Ok(SecretKey(secret)) @@ -231,7 +205,7 @@ mod tests { use quickcheck::*; fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool { - kp1.public() == kp2.public() && kp1.0.secret.as_bytes() == kp2.0.secret.as_bytes() + kp1.public() == kp2.public() && kp1.0.to_bytes() == kp2.0.to_bytes() } #[test] @@ -249,7 +223,7 @@ mod tests { fn ed25519_keypair_from_secret() { fn prop() -> bool { let kp1 = Keypair::generate(); - let mut sk = kp1.0.secret.to_bytes(); + let mut sk = kp1.0.to_bytes(); let kp2 = Keypair::from(SecretKey::try_from_bytes(&mut sk).unwrap()); eq_keypairs(&kp1, &kp2) && sk == [0u8; 32] }