mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-29 09:41:34 +00:00
feat(identity): make Keypair
and Publickey
opaque
`Keypair` and `Publickey` are rendered opaque: - `Keypair` is replaced by a private `KeyPairInner` enum that is encapsulated inside the `Keypair` `pub struct` - `Publickey` is replaced by a private `PublickeyInner` enum that is encapsulated inside the `Publickey` `pub struct` Resolves #3860. Pull-Request: #3866.
This commit is contained in:
@ -5,8 +5,12 @@
|
|||||||
- Add support for exporting and importing ECDSA keys via the libp2p [protobuf format].
|
- Add support for exporting and importing ECDSA keys via the libp2p [protobuf format].
|
||||||
See [PR 3863].
|
See [PR 3863].
|
||||||
|
|
||||||
|
- Make `Keypair` and `PublicKey` opaque.
|
||||||
|
See [PR 3866].
|
||||||
|
|
||||||
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
|
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
|
||||||
[PR 3863]: https://github.com/libp2p/rust-libp2p/pull/3863
|
[PR 3863]: https://github.com/libp2p/rust-libp2p/pull/3863
|
||||||
|
[PR 3866]: https://github.com/libp2p/rust-libp2p/pull/3866
|
||||||
[protobuf format]: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#keys
|
[protobuf format]: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#keys
|
||||||
|
|
||||||
## 0.1.2
|
## 0.1.2
|
||||||
|
@ -20,7 +20,7 @@ log = "0.4"
|
|||||||
multiaddr = { version = "0.17.1", optional = true }
|
multiaddr = { version = "0.17.1", optional = true }
|
||||||
multihash = { version = "0.17.0", default-features = false, features = ["std"], optional = true }
|
multihash = { version = "0.17.0", default-features = false, features = ["std"], optional = true }
|
||||||
p256 = { version = "0.13", default-features = false, features = ["ecdsa", "std", "pem"], optional = true }
|
p256 = { version = "0.13", default-features = false, features = ["ecdsa", "std", "pem"], optional = true }
|
||||||
quick-protobuf = { version = "0.8.1", optional = true }
|
quick-protobuf = "0.8.1"
|
||||||
rand = { version = "0.8", optional = true }
|
rand = { version = "0.8", optional = true }
|
||||||
sec1 = { version = "0.7", default-features = false, optional = true }
|
sec1 = { version = "0.7", default-features = false, optional = true }
|
||||||
serde = { version = "1", optional = true, features = ["derive"] }
|
serde = { version = "1", optional = true, features = ["derive"] }
|
||||||
@ -33,10 +33,10 @@ zeroize = { version = "1.6", optional = true }
|
|||||||
ring = { version = "0.16.9", features = ["alloc", "std"], default-features = false, optional = true}
|
ring = { version = "0.16.9", features = ["alloc", "std"], default-features = false, optional = true}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
secp256k1 = [ "dep:libsecp256k1", "dep:asn1_der", "dep:rand", "dep:sha2", "dep:zeroize", "dep:quick-protobuf" ]
|
secp256k1 = [ "dep:libsecp256k1", "dep:asn1_der", "dep:rand", "dep:sha2", "dep:zeroize" ]
|
||||||
ecdsa = [ "dep:p256", "dep:rand", "dep:void", "dep:zeroize", "dep:sec1", "dep:quick-protobuf" ]
|
ecdsa = [ "dep:p256", "dep:rand", "dep:void", "dep:zeroize", "dep:sec1" ]
|
||||||
rsa = [ "dep:ring", "dep:asn1_der", "dep:rand", "dep:zeroize", "dep:quick-protobuf" ]
|
rsa = [ "dep:ring", "dep:asn1_der", "dep:rand", "dep:zeroize" ]
|
||||||
ed25519 = [ "dep:ed25519-dalek", "dep:rand", "dep:zeroize", "dep:quick-protobuf" ]
|
ed25519 = [ "dep:ed25519-dalek", "dep:rand", "dep:zeroize" ]
|
||||||
peerid = [ "dep:multihash", "dep:multiaddr", "dep:bs58", "dep:rand", "dep:thiserror", "dep:sha2" ]
|
peerid = [ "dep:multihash", "dep:multiaddr", "dep:bs58", "dep:rand", "dep:thiserror", "dep:sha2" ]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -33,6 +33,7 @@ pub struct DecodingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DecodingError {
|
impl DecodingError {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub(crate) fn missing_feature(feature_name: &'static str) -> Self {
|
pub(crate) fn missing_feature(feature_name: &'static str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
msg: format!("cargo feature `{feature_name}` is not enabled"),
|
msg: format!("cargo feature `{feature_name}` is not enabled"),
|
||||||
|
@ -20,6 +20,12 @@
|
|||||||
|
|
||||||
use crate::error::OtherVariantError;
|
use crate::error::OtherVariantError;
|
||||||
use crate::error::{DecodingError, SigningError};
|
use crate::error::{DecodingError, SigningError};
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
))]
|
||||||
use crate::proto;
|
use crate::proto;
|
||||||
use quick_protobuf::{BytesReader, Writer};
|
use quick_protobuf::{BytesReader, Writer};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@ -53,36 +59,25 @@ use crate::ecdsa;
|
|||||||
/// let keypair = Keypair::rsa_from_pkcs8(&mut bytes);
|
/// let keypair = Keypair::rsa_from_pkcs8(&mut bytes);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Keypair {
|
||||||
|
keypair: KeyPairInner,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum Keypair {
|
enum KeyPairInner {
|
||||||
/// An Ed25519 keypair.
|
/// An Ed25519 keypair.
|
||||||
#[cfg(feature = "ed25519")]
|
#[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),
|
Ed25519(ed25519::Keypair),
|
||||||
/// An RSA keypair.
|
/// An RSA keypair.
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[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),
|
Rsa(rsa::Keypair),
|
||||||
/// A Secp256k1 keypair.
|
/// A Secp256k1 keypair.
|
||||||
#[cfg(feature = "secp256k1")]
|
#[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),
|
Secp256k1(secp256k1::Keypair),
|
||||||
/// An ECDSA keypair.
|
/// An ECDSA keypair.
|
||||||
#[cfg(feature = "ecdsa")]
|
#[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),
|
Ecdsa(ecdsa::Keypair),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,22 +85,25 @@ impl Keypair {
|
|||||||
/// Generate a new Ed25519 keypair.
|
/// Generate a new Ed25519 keypair.
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
pub fn generate_ed25519() -> Keypair {
|
pub fn generate_ed25519() -> Keypair {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Ed25519(ed25519::Keypair::generate())
|
keypair: KeyPairInner::Ed25519(ed25519::Keypair::generate()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a new Secp256k1 keypair.
|
/// Generate a new Secp256k1 keypair.
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
pub fn generate_secp256k1() -> Keypair {
|
pub fn generate_secp256k1() -> Keypair {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Secp256k1(secp256k1::Keypair::generate())
|
keypair: KeyPairInner::Secp256k1(secp256k1::Keypair::generate()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a new ECDSA keypair.
|
/// Generate a new ECDSA keypair.
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
pub fn generate_ecdsa() -> Keypair {
|
pub fn generate_ecdsa() -> Keypair {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Ecdsa(ecdsa::Keypair::generate())
|
keypair: KeyPairInner::Ecdsa(ecdsa::Keypair::generate()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
@ -166,8 +164,9 @@ impl Keypair {
|
|||||||
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
|
/// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<Keypair, DecodingError> {
|
pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<Keypair, DecodingError> {
|
||||||
#[allow(deprecated)]
|
rsa::Keypair::try_decode_pkcs8(pkcs8_der).map(|kp| Keypair {
|
||||||
rsa::Keypair::from_pkcs8(pkcs8_der).map(Keypair::Rsa)
|
keypair: KeyPairInner::Rsa(kp),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decode a keypair from a DER-encoded Secp256k1 secret key in an ECPrivateKey
|
/// Decode a keypair from a DER-encoded Secp256k1 secret key in an ECPrivateKey
|
||||||
@ -176,72 +175,82 @@ impl Keypair {
|
|||||||
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
|
/// [RFC5915]: https://tools.ietf.org/html/rfc5915
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
pub fn secp256k1_from_der(der: &mut [u8]) -> Result<Keypair, DecodingError> {
|
pub fn secp256k1_from_der(der: &mut [u8]) -> Result<Keypair, DecodingError> {
|
||||||
#[allow(deprecated)]
|
secp256k1::SecretKey::from_der(der).map(|sk| Keypair {
|
||||||
secp256k1::SecretKey::from_der(der)
|
keypair: KeyPairInner::Secp256k1(secp256k1::Keypair::from(sk)),
|
||||||
.map(|sk| Keypair::Secp256k1(secp256k1::Keypair::from(sk)))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
pub fn ed25519_from_bytes(bytes: impl AsMut<[u8]>) -> Result<Keypair, DecodingError> {
|
pub fn ed25519_from_bytes(bytes: impl AsMut<[u8]>) -> Result<Keypair, DecodingError> {
|
||||||
#[allow(deprecated)]
|
Ok(Keypair {
|
||||||
Ok(Keypair::Ed25519(ed25519::Keypair::from(
|
keypair: KeyPairInner::Ed25519(ed25519::Keypair::from(
|
||||||
ed25519::SecretKey::from_bytes(bytes)?,
|
ed25519::SecretKey::try_from_bytes(bytes)?,
|
||||||
)))
|
)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sign a message using the private key of this keypair, producing
|
/// Sign a message using the private key of this keypair, producing
|
||||||
/// a signature that can be verified using the corresponding public key.
|
/// a signature that can be verified using the corresponding public key.
|
||||||
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
|
pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
|
||||||
use Keypair::*;
|
match self.keypair {
|
||||||
#[allow(deprecated)]
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Ed25519(ref pair) => Ok(pair.sign(msg)),
|
KeyPairInner::Ed25519(ref pair) => Ok(pair.sign(msg)),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Rsa(ref pair) => pair.sign(msg),
|
KeyPairInner::Rsa(ref pair) => pair.sign(msg),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Secp256k1(ref pair) => pair.secret().sign(msg),
|
KeyPairInner::Secp256k1(ref pair) => pair.secret().sign(msg),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Ecdsa(ref pair) => Ok(pair.secret().sign(msg)),
|
KeyPairInner::Ecdsa(ref pair) => Ok(pair.secret().sign(msg)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the public key of this keypair.
|
/// Get the public key of this keypair.
|
||||||
pub fn public(&self) -> PublicKey {
|
pub fn public(&self) -> PublicKey {
|
||||||
use Keypair::*;
|
match self.keypair {
|
||||||
#[allow(deprecated)]
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Ed25519(pair) => PublicKey::Ed25519(pair.public()),
|
KeyPairInner::Ed25519(ref pair) => PublicKey {
|
||||||
|
publickey: PublicKeyInner::Ed25519(pair.public()),
|
||||||
|
},
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Rsa(pair) => PublicKey::Rsa(pair.public()),
|
KeyPairInner::Rsa(ref pair) => PublicKey {
|
||||||
|
publickey: PublicKeyInner::Rsa(pair.public()),
|
||||||
|
},
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
|
KeyPairInner::Secp256k1(ref pair) => PublicKey {
|
||||||
|
publickey: PublicKeyInner::Secp256k1(pair.public().clone()),
|
||||||
|
},
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Ecdsa(pair) => PublicKey::Ecdsa(pair.public().clone()),
|
KeyPairInner::Ecdsa(ref pair) => PublicKey {
|
||||||
|
publickey: PublicKeyInner::Ecdsa(pair.public().clone()),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode a private key as protobuf structure.
|
/// Encode a private key as protobuf structure.
|
||||||
pub fn to_protobuf_encoding(&self) -> Result<Vec<u8>, DecodingError> {
|
pub fn to_protobuf_encoding(&self) -> Result<Vec<u8>, DecodingError> {
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
))]
|
||||||
|
{
|
||||||
use quick_protobuf::MessageWrite;
|
use quick_protobuf::MessageWrite;
|
||||||
|
let pk: proto::PrivateKey = match self.keypair {
|
||||||
#[allow(deprecated)]
|
|
||||||
let pk: proto::PrivateKey = match self {
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Self::Ed25519(data) => proto::PrivateKey {
|
KeyPairInner::Ed25519(ref data) => proto::PrivateKey {
|
||||||
Type: proto::KeyType::Ed25519,
|
Type: proto::KeyType::Ed25519,
|
||||||
Data: data.to_bytes().to_vec(),
|
Data: data.to_bytes().to_vec(),
|
||||||
},
|
},
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Self::Rsa(_) => return Err(DecodingError::encoding_unsupported("RSA")),
|
KeyPairInner::Rsa(_) => return Err(DecodingError::encoding_unsupported("RSA")),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Self::Secp256k1(data) => proto::PrivateKey {
|
KeyPairInner::Secp256k1(ref data) => proto::PrivateKey {
|
||||||
Type: proto::KeyType::Secp256k1,
|
Type: proto::KeyType::Secp256k1,
|
||||||
Data: data.secret().to_bytes().to_vec(),
|
Data: data.secret().to_bytes().to_vec(),
|
||||||
},
|
},
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Self::Ecdsa(data) => proto::PrivateKey {
|
KeyPairInner::Ecdsa(ref data) => proto::PrivateKey {
|
||||||
Type: proto::KeyType::ECDSA,
|
Type: proto::KeyType::ECDSA,
|
||||||
Data: data.secret().encode_der(),
|
Data: data.secret().encode_der(),
|
||||||
},
|
},
|
||||||
@ -254,8 +263,25 @@ impl Keypair {
|
|||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
)))]
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Decode a private key from a protobuf structure and parse it as a [`Keypair`].
|
/// Decode a private key from a protobuf structure and parse it as a [`Keypair`].
|
||||||
|
#[allow(unused_variables)]
|
||||||
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Keypair, DecodingError> {
|
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Keypair, DecodingError> {
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
))]
|
||||||
|
{
|
||||||
use quick_protobuf::MessageRead;
|
use quick_protobuf::MessageRead;
|
||||||
|
|
||||||
let mut reader = BytesReader::from_bytes(bytes);
|
let mut reader = BytesReader::from_bytes(bytes);
|
||||||
@ -263,60 +289,84 @@ impl Keypair {
|
|||||||
.map_err(|e| DecodingError::bad_protobuf("private key bytes", e))
|
.map_err(|e| DecodingError::bad_protobuf("private key bytes", e))
|
||||||
.map(zeroize::Zeroizing::new)?;
|
.map(zeroize::Zeroizing::new)?;
|
||||||
|
|
||||||
#[allow(deprecated, unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
match private_key.Type {
|
match private_key.Type {
|
||||||
proto::KeyType::Ed25519 => {
|
proto::KeyType::Ed25519 => {
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
return ed25519::Keypair::try_from_bytes(&mut private_key.Data)
|
return ed25519::Keypair::try_from_bytes(&mut private_key.Data).map(|sk| {
|
||||||
.map(Keypair::Ed25519);
|
Keypair {
|
||||||
|
keypair: KeyPairInner::Ed25519(sk),
|
||||||
|
}
|
||||||
|
});
|
||||||
Err(DecodingError::missing_feature("ed25519"))
|
Err(DecodingError::missing_feature("ed25519"))
|
||||||
}
|
}
|
||||||
proto::KeyType::RSA => Err(DecodingError::decoding_unsupported("RSA")),
|
proto::KeyType::RSA => Err(DecodingError::decoding_unsupported("RSA")),
|
||||||
proto::KeyType::Secp256k1 => {
|
proto::KeyType::Secp256k1 => {
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
return secp256k1::SecretKey::try_from_bytes(&mut private_key.Data)
|
return secp256k1::SecretKey::try_from_bytes(&mut private_key.Data).map(
|
||||||
.map(|key| Keypair::Secp256k1(key.into()));
|
|key| Keypair {
|
||||||
|
keypair: KeyPairInner::Secp256k1(key.into()),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Err(DecodingError::missing_feature("secp256k1"))
|
Err(DecodingError::missing_feature("secp256k1"))
|
||||||
}
|
}
|
||||||
proto::KeyType::ECDSA => {
|
proto::KeyType::ECDSA => {
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
return ecdsa::SecretKey::try_decode_der(&mut private_key.Data)
|
return ecdsa::SecretKey::try_decode_der(&mut private_key.Data).map(|key| {
|
||||||
.map(|key| Keypair::Ecdsa(key.into()));
|
Keypair {
|
||||||
|
keypair: KeyPairInner::Ecdsa(key.into()),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Err(DecodingError::missing_feature("ecdsa"))
|
Err(DecodingError::missing_feature("ecdsa"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
)))]
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
impl From<ecdsa::Keypair> for Keypair {
|
impl From<ecdsa::Keypair> for Keypair {
|
||||||
fn from(kp: ecdsa::Keypair) -> Self {
|
fn from(kp: ecdsa::Keypair) -> Self {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Ecdsa(kp)
|
keypair: KeyPairInner::Ecdsa(kp),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
impl From<ed25519::Keypair> for Keypair {
|
impl From<ed25519::Keypair> for Keypair {
|
||||||
fn from(kp: ed25519::Keypair) -> Self {
|
fn from(kp: ed25519::Keypair) -> Self {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Ed25519(kp)
|
keypair: KeyPairInner::Ed25519(kp),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
impl From<secp256k1::Keypair> for Keypair {
|
impl From<secp256k1::Keypair> for Keypair {
|
||||||
fn from(kp: secp256k1::Keypair) -> Self {
|
fn from(kp: secp256k1::Keypair) -> Self {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Secp256k1(kp)
|
keypair: KeyPairInner::Secp256k1(kp),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
impl From<rsa::Keypair> for Keypair {
|
impl From<rsa::Keypair> for Keypair {
|
||||||
fn from(kp: rsa::Keypair) -> Self {
|
fn from(kp: rsa::Keypair) -> Self {
|
||||||
#[allow(deprecated)]
|
Keypair {
|
||||||
Keypair::Rsa(kp)
|
keypair: KeyPairInner::Rsa(kp),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,15 +375,14 @@ impl TryInto<ed25519::Keypair> for Keypair {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<ed25519::Keypair, Self::Error> {
|
fn try_into(self) -> Result<ed25519::Keypair, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.keypair {
|
||||||
match self {
|
KeyPairInner::Ed25519(inner) => Ok(inner),
|
||||||
Keypair::Ed25519(inner) => Ok(inner),
|
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Keypair::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
KeyPairInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Keypair::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
KeyPairInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Keypair::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
KeyPairInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,15 +392,14 @@ impl TryInto<ecdsa::Keypair> for Keypair {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<ecdsa::Keypair, Self::Error> {
|
fn try_into(self) -> Result<ecdsa::Keypair, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.keypair {
|
||||||
match self {
|
KeyPairInner::Ecdsa(inner) => Ok(inner),
|
||||||
Keypair::Ecdsa(inner) => Ok(inner),
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Keypair::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
KeyPairInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Keypair::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
KeyPairInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Keypair::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
KeyPairInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,15 +409,14 @@ impl TryInto<secp256k1::Keypair> for Keypair {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<secp256k1::Keypair, Self::Error> {
|
fn try_into(self) -> Result<secp256k1::Keypair, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.keypair {
|
||||||
match self {
|
KeyPairInner::Secp256k1(inner) => Ok(inner),
|
||||||
Keypair::Secp256k1(inner) => Ok(inner),
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Keypair::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
KeyPairInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Keypair::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
KeyPairInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Keypair::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
KeyPairInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,71 +426,57 @@ impl TryInto<rsa::Keypair> for Keypair {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<rsa::Keypair, Self::Error> {
|
fn try_into(self) -> Result<rsa::Keypair, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.keypair {
|
||||||
match self {
|
KeyPairInner::Rsa(inner) => Ok(inner),
|
||||||
Keypair::Rsa(inner) => Ok(inner),
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Keypair::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
KeyPairInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Keypair::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
KeyPairInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Keypair::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
KeyPairInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The public key of a node's identity keypair.
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub enum PublicKey {
|
pub(crate) enum PublicKeyInner {
|
||||||
/// A public Ed25519 key.
|
/// A public Ed25519 key.
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
#[deprecated(
|
|
||||||
since = "0.1.0",
|
|
||||||
note = "This enum will be made opaque in the future, use `PublicKey::from` and `PublicKey::into_ed25519` instead."
|
|
||||||
)]
|
|
||||||
Ed25519(ed25519::PublicKey),
|
Ed25519(ed25519::PublicKey),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
/// A public RSA key.
|
/// A public RSA key.
|
||||||
|
|
||||||
#[deprecated(
|
|
||||||
since = "0.1.0",
|
|
||||||
note = "This enum will be made opaque in the future, use `PublicKey::from` and `PublicKey::into_rsa` instead."
|
|
||||||
)]
|
|
||||||
Rsa(rsa::PublicKey),
|
Rsa(rsa::PublicKey),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
/// A public Secp256k1 key.
|
/// A public Secp256k1 key.
|
||||||
#[deprecated(
|
|
||||||
since = "0.1.0",
|
|
||||||
note = "This enum will be made opaque in the future, use `PublicKey::from` and `PublicKey::into_secp256k1` instead."
|
|
||||||
)]
|
|
||||||
Secp256k1(secp256k1::PublicKey),
|
Secp256k1(secp256k1::PublicKey),
|
||||||
/// A public ECDSA key.
|
/// A public ECDSA key.
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
#[deprecated(
|
|
||||||
since = "0.1.0",
|
|
||||||
note = "This enum will be made opaque in the future, use `PublicKey::from` and `PublicKey::into_ecdsa` instead."
|
|
||||||
)]
|
|
||||||
Ecdsa(ecdsa::PublicKey),
|
Ecdsa(ecdsa::PublicKey),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The public key of a node's identity keypair.
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
pub struct PublicKey {
|
||||||
|
pub(crate) publickey: PublicKeyInner,
|
||||||
|
}
|
||||||
|
|
||||||
impl PublicKey {
|
impl PublicKey {
|
||||||
/// Verify a signature for a message using this public key, i.e. check
|
/// Verify a signature for a message using this public key, i.e. check
|
||||||
/// that the signature has been produced by the corresponding
|
/// that the signature has been produced by the corresponding
|
||||||
/// private key (authenticity), and that the message has not been
|
/// private key (authenticity), and that the message has not been
|
||||||
/// tampered with (integrity).
|
/// tampered with (integrity).
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
#[allow(unused_variables)]
|
||||||
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
|
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
|
||||||
use PublicKey::*;
|
match self.publickey {
|
||||||
#[allow(deprecated)]
|
|
||||||
match self {
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
Ed25519(pk) => pk.verify(msg, sig),
|
PublicKeyInner::Ed25519(ref pk) => pk.verify(msg, sig),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
Rsa(pk) => pk.verify(msg, sig),
|
PublicKeyInner::Rsa(ref pk) => pk.verify(msg, sig),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
Secp256k1(pk) => pk.verify(msg, sig),
|
PublicKeyInner::Secp256k1(ref pk) => pk.verify(msg, sig),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
Ecdsa(pk) => pk.verify(msg, sig),
|
PublicKeyInner::Ecdsa(ref pk) => pk.verify(msg, sig),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,8 +542,14 @@ impl PublicKey {
|
|||||||
/// Encode the public key into a protobuf structure for storage or
|
/// Encode the public key into a protobuf structure for storage or
|
||||||
/// exchange with other nodes.
|
/// exchange with other nodes.
|
||||||
pub fn encode_protobuf(&self) -> Vec<u8> {
|
pub fn encode_protobuf(&self) -> Vec<u8> {
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
))]
|
||||||
|
{
|
||||||
use quick_protobuf::MessageWrite;
|
use quick_protobuf::MessageWrite;
|
||||||
|
|
||||||
let public_key = proto::PublicKey::from(self);
|
let public_key = proto::PublicKey::from(self);
|
||||||
|
|
||||||
let mut buf = Vec::with_capacity(public_key.get_size());
|
let mut buf = Vec::with_capacity(public_key.get_size());
|
||||||
@ -522,6 +561,15 @@ impl PublicKey {
|
|||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
)))]
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Decode a public key from a protobuf structure, e.g. read from storage
|
/// Decode a public key from a protobuf structure, e.g. read from storage
|
||||||
/// or received from another node.
|
/// or received from another node.
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
@ -533,9 +581,16 @@ impl PublicKey {
|
|||||||
|
|
||||||
/// Decode a public key from a protobuf structure, e.g. read from storage
|
/// Decode a public key from a protobuf structure, e.g. read from storage
|
||||||
/// or received from another node.
|
/// or received from another node.
|
||||||
|
#[allow(unused_variables)]
|
||||||
pub fn try_decode_protobuf(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
|
pub fn try_decode_protobuf(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
))]
|
||||||
|
{
|
||||||
use quick_protobuf::MessageRead;
|
use quick_protobuf::MessageRead;
|
||||||
|
|
||||||
let mut reader = BytesReader::from_bytes(bytes);
|
let mut reader = BytesReader::from_bytes(bytes);
|
||||||
|
|
||||||
let pubkey = proto::PublicKey::from_reader(&mut reader, bytes)
|
let pubkey = proto::PublicKey::from_reader(&mut reader, bytes)
|
||||||
@ -544,6 +599,15 @@ impl PublicKey {
|
|||||||
pubkey.try_into()
|
pubkey.try_into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
)))]
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert the `PublicKey` into the corresponding `PeerId`.
|
/// Convert the `PublicKey` into the corresponding `PeerId`.
|
||||||
#[cfg(feature = "peerid")]
|
#[cfg(feature = "peerid")]
|
||||||
pub fn to_peer_id(&self) -> crate::PeerId {
|
pub fn to_peer_id(&self) -> crate::PeerId {
|
||||||
@ -551,41 +615,57 @@ impl PublicKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa"
|
||||||
|
))]
|
||||||
impl TryFrom<proto::PublicKey> for PublicKey {
|
impl TryFrom<proto::PublicKey> for PublicKey {
|
||||||
type Error = DecodingError;
|
type Error = DecodingError;
|
||||||
|
|
||||||
fn try_from(pubkey: proto::PublicKey) -> Result<Self, Self::Error> {
|
fn try_from(pubkey: proto::PublicKey) -> Result<Self, Self::Error> {
|
||||||
#[allow(deprecated)]
|
|
||||||
match pubkey.Type {
|
match pubkey.Type {
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
proto::KeyType::Ed25519 => {
|
proto::KeyType::Ed25519 => Ok(ed25519::PublicKey::try_from_bytes(&pubkey.Data).map(
|
||||||
ed25519::PublicKey::decode(&pubkey.Data).map(PublicKey::Ed25519)
|
|kp| PublicKey {
|
||||||
}
|
publickey: PublicKeyInner::Ed25519(kp),
|
||||||
|
},
|
||||||
|
)?),
|
||||||
#[cfg(not(feature = "ed25519"))]
|
#[cfg(not(feature = "ed25519"))]
|
||||||
proto::KeyType::Ed25519 => {
|
proto::KeyType::Ed25519 => {
|
||||||
log::debug!("support for ed25519 was disabled at compile-time");
|
log::debug!("support for ed25519 was disabled at compile-time");
|
||||||
Err(DecodingError::missing_feature("ed25519"))
|
Err(DecodingError::missing_feature("ed25519"))
|
||||||
}
|
}
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
proto::KeyType::RSA => rsa::PublicKey::decode_x509(&pubkey.Data).map(PublicKey::Rsa),
|
proto::KeyType::RSA => {
|
||||||
|
Ok(
|
||||||
|
rsa::PublicKey::try_decode_x509(&pubkey.Data).map(|kp| PublicKey {
|
||||||
|
publickey: PublicKeyInner::Rsa(kp),
|
||||||
|
})?,
|
||||||
|
)
|
||||||
|
}
|
||||||
#[cfg(any(not(feature = "rsa"), target_arch = "wasm32"))]
|
#[cfg(any(not(feature = "rsa"), target_arch = "wasm32"))]
|
||||||
proto::KeyType::RSA => {
|
proto::KeyType::RSA => {
|
||||||
log::debug!("support for RSA was disabled at compile-time");
|
log::debug!("support for RSA was disabled at compile-time");
|
||||||
Err(DecodingError::missing_feature("rsa"))
|
Err(DecodingError::missing_feature("rsa"))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
proto::KeyType::Secp256k1 => {
|
proto::KeyType::Secp256k1 => Ok(secp256k1::PublicKey::try_from_bytes(&pubkey.Data)
|
||||||
secp256k1::PublicKey::decode(&pubkey.Data).map(PublicKey::Secp256k1)
|
.map(|kp| PublicKey {
|
||||||
}
|
publickey: PublicKeyInner::Secp256k1(kp),
|
||||||
|
})?),
|
||||||
#[cfg(not(feature = "secp256k1"))]
|
#[cfg(not(feature = "secp256k1"))]
|
||||||
proto::KeyType::Secp256k1 => {
|
proto::KeyType::Secp256k1 => {
|
||||||
log::debug!("support for secp256k1 was disabled at compile-time");
|
log::debug!("support for secp256k1 was disabled at compile-time");
|
||||||
Err(DecodingError::missing_feature("secp256k1"))
|
Err(DecodingError::missing_feature("secp256k1"))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
proto::KeyType::ECDSA => {
|
proto::KeyType::ECDSA => Ok(ecdsa::PublicKey::try_decode_der(&pubkey.Data).map(
|
||||||
ecdsa::PublicKey::decode_der(&pubkey.Data).map(PublicKey::Ecdsa)
|
|kp| PublicKey {
|
||||||
}
|
publickey: PublicKeyInner::Ecdsa(kp),
|
||||||
|
},
|
||||||
|
)?),
|
||||||
#[cfg(not(feature = "ecdsa"))]
|
#[cfg(not(feature = "ecdsa"))]
|
||||||
proto::KeyType::ECDSA => {
|
proto::KeyType::ECDSA => {
|
||||||
log::debug!("support for ECDSA was disabled at compile-time");
|
log::debug!("support for ECDSA was disabled at compile-time");
|
||||||
@ -600,15 +680,14 @@ impl TryInto<ed25519::PublicKey> for PublicKey {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<ed25519::PublicKey, Self::Error> {
|
fn try_into(self) -> Result<ed25519::PublicKey, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.publickey {
|
||||||
match self {
|
PublicKeyInner::Ed25519(inner) => Ok(inner),
|
||||||
PublicKey::Ed25519(inner) => Ok(inner),
|
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
PublicKey::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
PublicKeyInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
PublicKey::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
PublicKeyInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
PublicKey::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
PublicKeyInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,15 +697,14 @@ impl TryInto<ecdsa::PublicKey> for PublicKey {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<ecdsa::PublicKey, Self::Error> {
|
fn try_into(self) -> Result<ecdsa::PublicKey, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.publickey {
|
||||||
match self {
|
PublicKeyInner::Ecdsa(inner) => Ok(inner),
|
||||||
PublicKey::Ecdsa(inner) => Ok(inner),
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
PublicKey::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
PublicKeyInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
PublicKey::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
PublicKeyInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
PublicKey::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
PublicKeyInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -636,15 +714,14 @@ impl TryInto<secp256k1::PublicKey> for PublicKey {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<secp256k1::PublicKey, Self::Error> {
|
fn try_into(self) -> Result<secp256k1::PublicKey, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.publickey {
|
||||||
match self {
|
PublicKeyInner::Secp256k1(inner) => Ok(inner),
|
||||||
PublicKey::Secp256k1(inner) => Ok(inner),
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
PublicKey::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
PublicKeyInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
PublicKey::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
PublicKeyInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
PublicKey::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
PublicKeyInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -654,15 +731,14 @@ impl TryInto<rsa::PublicKey> for PublicKey {
|
|||||||
type Error = OtherVariantError;
|
type Error = OtherVariantError;
|
||||||
|
|
||||||
fn try_into(self) -> Result<rsa::PublicKey, Self::Error> {
|
fn try_into(self) -> Result<rsa::PublicKey, Self::Error> {
|
||||||
#[allow(deprecated)]
|
match self.publickey {
|
||||||
match self {
|
PublicKeyInner::Rsa(inner) => Ok(inner),
|
||||||
PublicKey::Rsa(inner) => Ok(inner),
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
PublicKey::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
PublicKeyInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
PublicKey::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
PublicKeyInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
PublicKey::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
PublicKeyInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -670,32 +746,36 @@ impl TryInto<rsa::PublicKey> for PublicKey {
|
|||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
impl From<ed25519::PublicKey> for PublicKey {
|
impl From<ed25519::PublicKey> for PublicKey {
|
||||||
fn from(key: ed25519::PublicKey) -> Self {
|
fn from(key: ed25519::PublicKey) -> Self {
|
||||||
#[allow(deprecated)] // TODO: Remove when PublicKey::Ed25519 is made opaque
|
PublicKey {
|
||||||
PublicKey::Ed25519(key)
|
publickey: PublicKeyInner::Ed25519(key),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
impl From<secp256k1::PublicKey> for PublicKey {
|
impl From<secp256k1::PublicKey> for PublicKey {
|
||||||
fn from(key: secp256k1::PublicKey) -> Self {
|
fn from(key: secp256k1::PublicKey) -> Self {
|
||||||
#[allow(deprecated)] // TODO: Remove when PublicKey::Secp256k1 is made opaque
|
PublicKey {
|
||||||
PublicKey::Secp256k1(key)
|
publickey: PublicKeyInner::Secp256k1(key),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
impl From<ecdsa::PublicKey> for PublicKey {
|
impl From<ecdsa::PublicKey> for PublicKey {
|
||||||
fn from(key: ecdsa::PublicKey) -> Self {
|
fn from(key: ecdsa::PublicKey) -> Self {
|
||||||
#[allow(deprecated)] // TODO: Remove when PublicKey::Ecdsa is made opaque
|
PublicKey {
|
||||||
PublicKey::Ecdsa(key)
|
publickey: PublicKeyInner::Ecdsa(key),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
impl From<rsa::PublicKey> for PublicKey {
|
impl From<rsa::PublicKey> for PublicKey {
|
||||||
fn from(key: rsa::PublicKey) -> Self {
|
fn from(key: rsa::PublicKey) -> Self {
|
||||||
#[allow(deprecated)] // TODO: Remove when PublicKey::Rsa is made opaque
|
PublicKey {
|
||||||
PublicKey::Rsa(key)
|
publickey: PublicKeyInner::Rsa(key),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,7 +853,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "peerid")]
|
#[cfg(all(
|
||||||
|
feature = "ecdsa",
|
||||||
|
feature = "secp256k1",
|
||||||
|
feature = "ed25519",
|
||||||
|
feature = "rsa",
|
||||||
|
feature = "peerid"
|
||||||
|
))]
|
||||||
fn keypair_from_protobuf_encoding() {
|
fn keypair_from_protobuf_encoding() {
|
||||||
// E.g. retrieved from an IPFS config file.
|
// E.g. retrieved from an IPFS config file.
|
||||||
let base_64_encoded = "CAESQL6vdKQuznQosTrW7FWI9At+XX7EBf0BnZLhb6w+N+XSQSdfInl6c7U4NuxXJlhKcRBlBw9d0tj2dfBIVf6mcPA=";
|
let base_64_encoded = "CAESQL6vdKQuznQosTrW7FWI9At+XX7EBf0BnZLhb6w+N+XSQSdfInl6c7U4NuxXJlhKcRBlBw9d0tj2dfBIVf6mcPA=";
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
// Copyright 2023 Protocol Labs.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
|
||||||
// to deal in the Software without restriction, including without limitation
|
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
use crate::error::{DecodingError, SigningError};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Keypair {}
|
|
||||||
|
|
||||||
impl Keypair {
|
|
||||||
pub fn sign(&self, _: &[u8]) -> Result<Vec<u8>, SigningError> {
|
|
||||||
unreachable!("Can never construct empty enum")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn public(&self) -> PublicKey {
|
|
||||||
unreachable!("Can never construct empty enum")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_protobuf_encoding(&self) -> Result<Vec<u8>, DecodingError> {
|
|
||||||
unreachable!("Can never construct empty enum")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_protobuf_encoding(_: &[u8]) -> Result<Keypair, DecodingError> {
|
|
||||||
Err(DecodingError::missing_feature(
|
|
||||||
"ecdsa|rsa|ed25519|secp256k1",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
||||||
pub enum PublicKey {}
|
|
||||||
|
|
||||||
impl PublicKey {
|
|
||||||
#[must_use]
|
|
||||||
pub fn verify(&self, _: &[u8], _: &[u8]) -> bool {
|
|
||||||
unreachable!("Can never construct empty enum")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_protobuf_encoding(&self) -> Vec<u8> {
|
|
||||||
unreachable!("Can never construct empty enum")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_protobuf_encoding(_: &[u8]) -> Result<PublicKey, DecodingError> {
|
|
||||||
Err(DecodingError::missing_feature(
|
|
||||||
"ecdsa|rsa|ed25519|secp256k1",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "peerid")]
|
|
||||||
pub fn to_peer_id(&self) -> crate::PeerId {
|
|
||||||
unreachable!("Can never construct empty enum")
|
|
||||||
}
|
|
||||||
}
|
|
@ -60,20 +60,6 @@ pub mod rsa;
|
|||||||
pub mod secp256k1;
|
pub mod secp256k1;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
#[cfg(any(
|
|
||||||
feature = "ecdsa",
|
|
||||||
feature = "secp256k1",
|
|
||||||
feature = "ed25519",
|
|
||||||
feature = "rsa"
|
|
||||||
))]
|
|
||||||
mod keypair;
|
|
||||||
#[cfg(all(
|
|
||||||
not(feature = "ecdsa"),
|
|
||||||
not(feature = "secp256k1"),
|
|
||||||
not(feature = "ed25519"),
|
|
||||||
not(feature = "rsa")
|
|
||||||
))]
|
|
||||||
#[path = "./keypair_dummy.rs"]
|
|
||||||
mod keypair;
|
mod keypair;
|
||||||
#[cfg(feature = "peerid")]
|
#[cfg(feature = "peerid")]
|
||||||
mod peer_id;
|
mod peer_id;
|
||||||
@ -98,25 +84,24 @@ impl zeroize::Zeroize for proto::PrivateKey {
|
|||||||
))]
|
))]
|
||||||
impl From<&PublicKey> for proto::PublicKey {
|
impl From<&PublicKey> for proto::PublicKey {
|
||||||
fn from(key: &PublicKey) -> Self {
|
fn from(key: &PublicKey) -> Self {
|
||||||
#[allow(deprecated)]
|
match &key.publickey {
|
||||||
match key {
|
|
||||||
#[cfg(feature = "ed25519")]
|
#[cfg(feature = "ed25519")]
|
||||||
PublicKey::Ed25519(key) => proto::PublicKey {
|
keypair::PublicKeyInner::Ed25519(key) => proto::PublicKey {
|
||||||
Type: proto::KeyType::Ed25519,
|
Type: proto::KeyType::Ed25519,
|
||||||
Data: key.encode().to_vec(),
|
Data: key.to_bytes().to_vec(),
|
||||||
},
|
},
|
||||||
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
|
||||||
PublicKey::Rsa(key) => proto::PublicKey {
|
keypair::PublicKeyInner::Rsa(key) => proto::PublicKey {
|
||||||
Type: proto::KeyType::RSA,
|
Type: proto::KeyType::RSA,
|
||||||
Data: key.encode_x509(),
|
Data: key.encode_x509(),
|
||||||
},
|
},
|
||||||
#[cfg(feature = "secp256k1")]
|
#[cfg(feature = "secp256k1")]
|
||||||
PublicKey::Secp256k1(key) => proto::PublicKey {
|
keypair::PublicKeyInner::Secp256k1(key) => proto::PublicKey {
|
||||||
Type: proto::KeyType::Secp256k1,
|
Type: proto::KeyType::Secp256k1,
|
||||||
Data: key.encode().to_vec(),
|
Data: key.to_bytes().to_vec(),
|
||||||
},
|
},
|
||||||
#[cfg(feature = "ecdsa")]
|
#[cfg(feature = "ecdsa")]
|
||||||
PublicKey::Ecdsa(key) => proto::PublicKey {
|
keypair::PublicKeyInner::Ecdsa(key) => proto::PublicKey {
|
||||||
Type: proto::KeyType::ECDSA,
|
Type: proto::KeyType::ECDSA,
|
||||||
Data: key.encode_der(),
|
Data: key.encode_der(),
|
||||||
},
|
},
|
||||||
|
@ -307,7 +307,6 @@ mod tests {
|
|||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
let peer_id = PeerId::try_from_multiaddr(&address).unwrap();
|
let peer_id = PeerId::try_from_multiaddr(&address).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -322,7 +321,6 @@ mod tests {
|
|||||||
fn no_panic_on_extract_peer_id_from_multi_address_if_not_present() {
|
fn no_panic_on_extract_peer_id_from_multi_address_if_not_present() {
|
||||||
let address = "/memory/1234".to_string().parse().unwrap();
|
let address = "/memory/1234".to_string().parse().unwrap();
|
||||||
|
|
||||||
#[allow(deprecated)]
|
|
||||||
let maybe_empty = PeerId::try_from_multiaddr(&address);
|
let maybe_empty = PeerId::try_from_multiaddr(&address);
|
||||||
|
|
||||||
assert!(maybe_empty.is_none());
|
assert!(maybe_empty.is_none());
|
||||||
|
@ -127,8 +127,8 @@ impl Protocol<X25519> for X25519 {
|
|||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
fn linked(id_pk: &identity::PublicKey, dh_pk: &PublicKey<X25519>) -> bool {
|
fn linked(id_pk: &identity::PublicKey, dh_pk: &PublicKey<X25519>) -> bool {
|
||||||
if let identity::PublicKey::Ed25519(ref p) = id_pk {
|
if let Ok(p) = identity::PublicKey::try_into_ed25519(id_pk.clone()) {
|
||||||
PublicKey::from_ed25519(p).as_ref() == dh_pk.as_ref()
|
PublicKey::from_ed25519(&p).as_ref() == dh_pk.as_ref()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -161,9 +161,8 @@ impl Keypair<X25519> {
|
|||||||
/// > * [Noise: Static Key Reuse](http://www.noiseprotocol.org/noise.html#security-considerations)
|
/// > * [Noise: Static Key Reuse](http://www.noiseprotocol.org/noise.html#security-considerations)
|
||||||
#[allow(unreachable_patterns)]
|
#[allow(unreachable_patterns)]
|
||||||
pub fn from_identity(id_keys: &identity::Keypair) -> Option<AuthenticKeypair<X25519>> {
|
pub fn from_identity(id_keys: &identity::Keypair) -> Option<AuthenticKeypair<X25519>> {
|
||||||
match id_keys {
|
let ed25519_keypair = id_keys.clone().try_into_ed25519().ok()?;
|
||||||
identity::Keypair::Ed25519(p) => {
|
let kp = Keypair::from(SecretKey::from_ed25519(&ed25519_keypair.secret()));
|
||||||
let kp = Keypair::from(SecretKey::from_ed25519(&p.secret()));
|
|
||||||
let id = KeypairIdentity {
|
let id = KeypairIdentity {
|
||||||
public: id_keys.public(),
|
public: id_keys.public(),
|
||||||
signature: None,
|
signature: None,
|
||||||
@ -173,9 +172,6 @@ impl Keypair<X25519> {
|
|||||||
identity: id,
|
identity: id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Keypair<X25519> {
|
impl Default for Keypair<X25519> {
|
||||||
|
Reference in New Issue
Block a user