diff --git a/Cargo.lock b/Cargo.lock index a4a602e..17765b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,12 +105,6 @@ dependencies = [ "asn1_der_derive", ] -[[package]] -name = "asn1_der" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" - [[package]] name = "asn1_der_derive" version = "0.1.2" @@ -929,7 +923,7 @@ dependencies = [ name = "fluence-keypair" version = "0.10.3" dependencies = [ - "asn1_der 0.6.3", + "asn1_der", "bs58 0.5.0", "ed25519-dalek", "eyre", @@ -1376,15 +1370,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2874d9c6575f1d7a151022af5c42bb0ffdcdfbafe0a6fd039de870b384835a2" dependencies = [ - "asn1_der 0.7.6", "bs58 0.5.0", "ed25519-dalek", - "libsecp256k1", "log", "multihash 0.19.0", "quick-protobuf", "rand 0.8.5", - "ring", "sha2 0.10.7", "thiserror", "zeroize", diff --git a/keypair/Cargo.toml b/keypair/Cargo.toml index 0feec47..e9c4243 100644 --- a/keypair/Cargo.toml +++ b/keypair/Cargo.toml @@ -20,7 +20,7 @@ sha2 = "0.10.6" zeroize = "1" serde_bytes = "0.11" eyre = "0.6.5" -libp2p-identity = { workspace = true, default-features = false, features = ["peerid", "rsa", "ed25519", "secp256k1"] } +libp2p-identity = { workspace = true, default-features = false, features = ["peerid", "ed25519"] } multihash = { version = "0.18.0", features = ["identity"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/keypair/src/key_pair.rs b/keypair/src/key_pair.rs index 7b6e7a6..b8d4056 100644 --- a/keypair/src/key_pair.rs +++ b/keypair/src/key_pair.rs @@ -22,9 +22,6 @@ use crate::ed25519; use crate::error::{DecodingError, Error, SigningError, VerificationError}; use crate::public_key::PublicKey; -#[cfg(not(target_arch = "wasm32"))] -use crate::rsa; -use crate::secp256k1; use crate::signature::Signature; use libp2p_identity::{KeyType, Keypair, PeerId}; use std::convert::TryFrom; @@ -50,9 +47,6 @@ use std::str::FromStr; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum KeyFormat { Ed25519, - #[cfg(not(target_arch = "wasm32"))] - Rsa, - Secp256k1, } impl FromStr for KeyFormat { @@ -62,9 +56,6 @@ impl FromStr for KeyFormat { fn from_str(s: &str) -> Result { match s { "ed25519" => Ok(KeyFormat::Ed25519), - "secp256k1" => Ok(KeyFormat::Secp256k1), - #[cfg(not(target_arch = "wasm32"))] - "rsa" => Ok(KeyFormat::Rsa), _ => Err(Error::InvalidKeyFormat(s.to_string())), } } @@ -76,9 +67,6 @@ impl TryFrom for KeyFormat { fn try_from(value: u8) -> Result { match value { 0 => Ok(KeyFormat::Ed25519), - #[cfg(not(target_arch = "wasm32"))] - 1 => Ok(KeyFormat::Rsa), - 2 => Ok(KeyFormat::Secp256k1), _ => Err(DecodingError::InvalidTypeByte), } } @@ -88,9 +76,6 @@ impl From for u8 { fn from(kf: KeyFormat) -> Self { match kf { KeyFormat::Ed25519 => 0, - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => 1, - KeyFormat::Secp256k1 => 2, } } } @@ -99,9 +84,6 @@ impl From for String { fn from(kf: KeyFormat) -> Self { match kf { KeyFormat::Ed25519 => "ed25519".to_string(), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => "rsa".to_string(), - KeyFormat::Secp256k1 => "secp256k1".to_string(), } } } @@ -110,20 +92,12 @@ impl From for String { pub enum KeyPair { /// An Ed25519 keypair. Ed25519(ed25519::Keypair), - #[cfg(not(target_arch = "wasm32"))] - /// An RSA keypair. - Rsa(rsa::Keypair), - /// A Secp256k1 keypair. - Secp256k1(secp256k1::Keypair), } impl KeyPair { pub fn generate(format: KeyFormat) -> KeyPair { match format { KeyFormat::Ed25519 => KeyPair::generate_ed25519(), - KeyFormat::Secp256k1 => KeyPair::generate_secp256k1(), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => todo!("rsa generation is not supported yet!"), } } @@ -132,40 +106,12 @@ impl KeyPair { KeyPair::Ed25519(ed25519::Keypair::generate()) } - /// Generate a new Secp256k1 keypair. - pub fn generate_secp256k1() -> KeyPair { - KeyPair::Secp256k1(secp256k1::Keypair::generate()) - } - - /// Decode an keypair from a DER-encoded secret key in PKCS#8 PrivateKeyInfo - /// format (i.e. unencrypted) as defined in [RFC5208]. - /// - /// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5 - #[cfg(not(target_arch = "wasm32"))] - pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result { - rsa::Keypair::from_pkcs8(pkcs8_der).map(KeyPair::Rsa) - } - - /// 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 - pub fn secp256k1_from_der(der: &mut [u8]) -> Result { - secp256k1::SecretKey::from_der(der) - .map(|sk| KeyPair::Secp256k1(secp256k1::Keypair::from(sk))) - } - /// 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 { use KeyPair::*; match self { Ed25519(ref pair) => Ok(Signature::Ed25519(ed25519::Signature(pair.sign(msg)?))), - #[cfg(not(target_arch = "wasm32"))] - Rsa(ref pair) => Ok(Signature::Rsa(rsa::Signature(pair.sign(msg)?))), - Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature( - pair.secret().sign(msg)?, - ))), } } @@ -175,9 +121,6 @@ impl KeyPair { match self { Ed25519(_) => KeyFormat::Ed25519, - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => KeyFormat::Rsa, - Secp256k1(_) => KeyFormat::Secp256k1, } } @@ -186,9 +129,6 @@ impl KeyPair { use KeyPair::*; match self { Ed25519(pair) => PublicKey::Ed25519(pair.public()), - #[cfg(not(target_arch = "wasm32"))] - Rsa(pair) => PublicKey::Rsa(pair.public()), - Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()), } } @@ -196,9 +136,6 @@ impl KeyPair { use KeyPair::*; match self { Ed25519(pair) => Ok(pair.secret().0.to_bytes().to_vec()), - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => Err(eyre::eyre!("secret key is not available for RSA")), - Secp256k1(pair) => Ok(pair.secret().to_bytes().to_vec()), } } @@ -215,9 +152,6 @@ impl KeyPair { use KeyPair::*; match self { Ed25519(kp) => kp.encode().to_vec(), - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => todo!("rsa encoding is not supported yet!"), - Secp256k1(kp) => kp.secret().to_bytes().to_vec(), } } @@ -226,9 +160,6 @@ impl KeyPair { match format { KeyFormat::Ed25519 => Ok(Ed25519(ed25519::Keypair::decode(&mut bytes)?)), - KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported), } } @@ -237,9 +168,6 @@ impl KeyPair { match format { KeyFormat::Ed25519 => Ok(Ed25519(ed25519::SecretKey::from_bytes(bytes)?.into())), - KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported), } } @@ -257,19 +185,6 @@ impl From for KeyPair { let raw_kp = ed25519::Keypair::decode(&mut kp.to_bytes())?; Ok(KeyPair::Ed25519(raw_kp)) } - #[cfg(not(target_arch = "wasm32"))] - KeyType::RSA => { - let kp = key.try_into_rsa()?; - let raw_kp = unsafe { - std::mem::transmute::(kp) - }; - Ok(KeyPair::Rsa(raw_kp)) - } - KeyType::Secp256k1 => { - let kp = key.try_into_secp256k1()?; - let raw_kp = secp256k1::SecretKey::from_bytes(kp.secret().to_bytes())?; - Ok(KeyPair::Secp256k1(secp256k1::Keypair::from(raw_kp))) - } _ => unreachable!(), } } @@ -288,23 +203,6 @@ impl From for libp2p_identity::Keypair { let kp = libp2p_identity::Keypair::ed25519_from_bytes(secret_bytes)?; Ok(kp) } - #[cfg(not(target_arch = "wasm32"))] - // safety: these Keypair structures are identical - KeyPair::Rsa(kp) => { - let kp = unsafe { - std::mem::transmute::(kp) - }; - let kp = Keypair::from(kp); - Ok(kp) - } - KeyPair::Secp256k1(kp) => { - let sk = libp2p_identity::secp256k1::SecretKey::try_from_bytes( - kp.secret().to_bytes(), - )?; - let kp = libp2p_identity::secp256k1::Keypair::from(sk); - let kp = Keypair::from(kp); - Ok(kp) - } } } convert_keypair(key).expect("Could not convert key pair") diff --git a/keypair/src/lib.rs b/keypair/src/lib.rs index 89aa067..10f26f4 100644 --- a/keypair/src/lib.rs +++ b/keypair/src/lib.rs @@ -30,9 +30,6 @@ mod ed25519; pub mod error; pub mod key_pair; pub mod public_key; -#[cfg(not(target_arch = "wasm32"))] -mod rsa; -mod secp256k1; pub mod signature; pub use crate::public_key::PublicKey; diff --git a/keypair/src/public_key.rs b/keypair/src/public_key.rs index 483b06b..4fac5fb 100644 --- a/keypair/src/public_key.rs +++ b/keypair/src/public_key.rs @@ -15,9 +15,6 @@ */ use crate::ed25519; use crate::error::{DecodingError, VerificationError}; -#[cfg(not(target_arch = "wasm32"))] -use crate::rsa; -use crate::secp256k1; use crate::signature::Signature; use crate::key_pair::KeyFormat; @@ -30,11 +27,6 @@ use std::convert::TryFrom; pub enum PublicKey { /// A public Ed25519 key. Ed25519(ed25519::PublicKey), - #[cfg(not(target_arch = "wasm32"))] - /// A public RSA key. - Rsa(rsa::PublicKey), - /// A public Secp256k1 key. - Secp256k1(secp256k1::PublicKey), } impl PublicKey { @@ -47,9 +39,6 @@ impl PublicKey { use PublicKey::*; match self { Ed25519(pk) => pk.verify(msg, sig.to_vec()), - #[cfg(not(target_arch = "wasm32"))] - Rsa(pk) => pk.verify(msg, sig.to_vec()), - Secp256k1(pk) => pk.verify(msg, sig.to_vec()), } } @@ -59,9 +48,6 @@ impl PublicKey { match self { Ed25519(pk) => result.extend(pk.encode().to_vec()), - #[cfg(not(target_arch = "wasm32"))] - Rsa(pk) => result.extend(pk.to_pkcs1()), - Secp256k1(pk) => result.extend(pk.encode().to_vec()), }; result @@ -70,13 +56,6 @@ impl PublicKey { pub fn decode(bytes: &[u8]) -> Result { match KeyFormat::try_from(bytes[0])? { KeyFormat::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::decode(&bytes[1..])?)), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => Ok(PublicKey::Rsa(rsa::PublicKey::from_pkcs1( - bytes[1..].to_owned(), - )?)), - KeyFormat::Secp256k1 => Ok(PublicKey::Secp256k1(secp256k1::PublicKey::decode( - &bytes[1..], - )?)), } } @@ -84,9 +63,6 @@ impl PublicKey { use PublicKey::*; match self { Ed25519(_) => KeyFormat::Ed25519.into(), - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => KeyFormat::Rsa.into(), - Secp256k1(_) => KeyFormat::Secp256k1.into(), } } @@ -102,9 +78,6 @@ impl PublicKey { match self { Ed25519(pk) => pk.encode().to_vec(), - #[cfg(not(target_arch = "wasm32"))] - Rsa(pk) => pk.to_pkcs1().to_vec(), - Secp256k1(pk) => pk.encode().to_vec(), } } @@ -117,9 +90,6 @@ impl PublicKey { match self { Ed25519(_) => KeyFormat::Ed25519, - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => KeyFormat::Rsa, - Secp256k1(_) => KeyFormat::Secp256k1, } } } @@ -133,17 +103,6 @@ impl From for PublicKey { let raw_pk = ed25519::PublicKey::decode(&pk.to_bytes())?; Ok(PublicKey::Ed25519(raw_pk)) } - #[cfg(not(target_arch = "wasm32"))] - KeyType::RSA => { - let pk = key.try_into_rsa()?; - let raw_pk = rsa::PublicKey::from_pkcs1(pk.encode_pkcs1())?; - Ok(PublicKey::Rsa(raw_pk)) - } - KeyType::Secp256k1 => { - let pk = key.try_into_secp256k1()?; - let raw_pk = secp256k1::PublicKey::decode(&pk.to_bytes())?; - Ok(PublicKey::Secp256k1(raw_pk)) - } _ => unreachable!(), } } @@ -162,19 +121,6 @@ impl From for libp2p_identity::PublicKey { let pk = libp2p_identity::PublicKey::from(raw_pk); Ok(pk) } - #[cfg(not(target_arch = "wasm32"))] - PublicKey::Rsa(key) => { - let raw_pk = - libp2p_identity::rsa::PublicKey::try_decode_x509(&key.encode_x509())?; - let pk = libp2p_identity::PublicKey::from(raw_pk); - Ok(pk) - } - PublicKey::Secp256k1(key) => { - let raw_pk = - libp2p_identity::secp256k1::PublicKey::try_from_bytes(&key.encode())?; - let pk = libp2p_identity::PublicKey::from(raw_pk); - Ok(pk) - } } } convert_key(key).expect("Could not convert key") @@ -216,17 +162,9 @@ mod tests { assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap()); } - #[test] - fn public_key_encode_decode_secp256k1() { - let kp = KeyPair::generate_secp256k1(); - let pk = kp.public(); - let encoded_pk = pk.encode(); - assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap()); - } - #[test] fn public_key_peer_id_conversions() { - let kp = KeyPair::generate_secp256k1(); + let kp = KeyPair::generate_ed25519(); let fluence_pk = kp.public(); let libp2p_pk: libp2p_identity::PublicKey = fluence_pk.clone().into(); let peer_id = PeerId::from_public_key(&libp2p_pk); diff --git a/keypair/src/rsa.rs b/keypair/src/rsa.rs deleted file mode 100644 index 5ec22cb..0000000 --- a/keypair/src/rsa.rs +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// -// 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. - -//! RSA keys. -use crate::error::{DecodingError, SigningError, VerificationError}; - -use asn1_der::{Asn1Der, Asn1DerError, DerObject, DerTag, DerValue, FromDerObject, IntoDerObject}; -use lazy_static::lazy_static; -use ring::rand::SystemRandom; -use ring::signature::KeyPair; -use ring::signature::{self, RsaKeyPair, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256}; -use serde::{Deserialize, Serialize}; -use std::{ - fmt::{self, Write}, - sync::Arc, -}; -use zeroize::Zeroize; - -/// An RSA keypair. -#[derive(Clone)] -pub struct Keypair(Arc); - -impl Keypair { - /// Decode an RSA keypair from a DER-encoded private key in PKCS#8 PrivateKeyInfo - /// format (i.e. unencrypted) as defined in [RFC5208]. - /// - /// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5 - pub fn from_pkcs8(der: &mut [u8]) -> Result { - let kp = RsaKeyPair::from_pkcs8(der).map_err(|_| DecodingError::Rsa)?; - der.zeroize(); - Ok(Keypair(Arc::new(kp))) - } - - /// Get the public key from the keypair. - pub fn public(&self) -> PublicKey { - PublicKey(self.0.public_key().as_ref().to_vec()) - } - - /// Sign a message with this keypair. - pub fn sign(&self, data: &[u8]) -> Result, SigningError> { - let mut signature = vec![0; self.0.public_modulus_len()]; - let rng = SystemRandom::new(); - match self.0.sign(&RSA_PKCS1_SHA256, &rng, data, &mut signature) { - Ok(()) => Ok(signature), - Err(_) => Err(SigningError::Rsa), - } - } -} - -/// An RSA public key. -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct PublicKey(Vec); - -impl PublicKey { - /// Verify an RSA signature on a message using the public key. - pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> { - let key = signature::UnparsedPublicKey::new(&RSA_PKCS1_2048_8192_SHA256, &self.0); - key.verify(msg, sig).map_err(|e| { - VerificationError::Rsa( - e, - bs58::encode(sig).into_string(), - bs58::encode(&self.0).into_string(), - ) - }) - } - - /// Encode the RSA public key in DER as a PKCS#1 RSAPublicKey structure, - /// as defined in [RFC3447]. - /// - /// [RFC3447]: https://tools.ietf.org/html/rfc3447#appendix-A.1.1 - pub fn to_pkcs1(&self) -> &[u8] { - // This is the encoding currently used in-memory, so it is trivial. - &self.0 - } - - pub fn from_pkcs1(pk: Vec) -> Result { - Ok(PublicKey(pk)) - } - - /// Encode the RSA public key in DER as a X.509 SubjectPublicKeyInfo structure, - /// as defined in [RFC5280]. - /// - /// [RFC5280]: https://tools.ietf.org/html/rfc5280#section-4.1 - pub fn encode_x509(&self) -> Vec { - let spki = Asn1SubjectPublicKeyInfo { - algorithmIdentifier: Asn1RsaEncryption { - algorithm: Asn1OidRsaEncryption(), - parameters: (), - }, - subjectPublicKey: Asn1SubjectPublicKey(self.clone()), - }; - let mut buf = vec![0u8; spki.serialized_len()]; - spki.serialize(buf.iter_mut()) - .map(|_| buf) - .expect("RSA X.509 public key encoding failed.") - } - - /// Decode an RSA public key from a DER-encoded X.509 SubjectPublicKeyInfo - /// structure. See also `encode_x509`. - pub fn decode_x509(pk: &[u8]) -> Result { - Asn1SubjectPublicKeyInfo::deserialize(pk.iter()) - .map_err(|_| DecodingError::Rsa) - .map(|spki| spki.subjectPublicKey.0) - } -} - -impl fmt::Debug for PublicKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let bytes = &self.0; - let mut hex = String::with_capacity(bytes.len() * 2); - - for byte in bytes { - write!(hex, "{byte:02x}").expect("Can't fail on writing to string"); - } - - f.debug_struct("PublicKey").field("pkcs1", &hex).finish() - } -} - -////////////////////////////////////////////////////////////////////////////// -// DER encoding / decoding of public keys -// -// Primer: http://luca.ntop.org/Teaching/Appunti/asn1.html -// Playground: https://lapo.it/asn1js/ - -lazy_static! { - /// The DER encoding of the object identifier (OID) 'rsaEncryption' for - /// RSA public keys defined for X.509 in [RFC-3279] and used in - /// SubjectPublicKeyInfo structures defined in [RFC-5280]. - /// - /// [RFC-3279]: https://tools.ietf.org/html/rfc3279#section-2.3.1 - /// [RFC-5280]: https://tools.ietf.org/html/rfc5280#section-4.1 - static ref OID_RSA_ENCRYPTION_DER: DerObject = - DerObject { - tag: DerTag::x06, - value: DerValue { - data: vec![ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ] - } - }; -} - -/// The ASN.1 OID for "rsaEncryption". -#[derive(Clone)] -struct Asn1OidRsaEncryption(); - -impl IntoDerObject for Asn1OidRsaEncryption { - fn into_der_object(self) -> DerObject { - OID_RSA_ENCRYPTION_DER.clone() - } - fn serialized_len(&self) -> usize { - OID_RSA_ENCRYPTION_DER.serialized_len() - } -} - -impl FromDerObject for Asn1OidRsaEncryption { - fn from_der_object(o: DerObject) -> Result { - if o.tag != DerTag::x06 { - return Err(Asn1DerError::InvalidTag); - } - if o.value != OID_RSA_ENCRYPTION_DER.value { - return Err(Asn1DerError::InvalidEncoding); - } - Ok(Asn1OidRsaEncryption()) - } -} - -/// The ASN.1 AlgorithmIdentifier for "rsaEncryption". -#[derive(Asn1Der)] -struct Asn1RsaEncryption { - algorithm: Asn1OidRsaEncryption, - parameters: (), -} - -/// The ASN.1 SubjectPublicKey inside a SubjectPublicKeyInfo, -/// i.e. encoded as a DER BIT STRING. -struct Asn1SubjectPublicKey(PublicKey); - -impl IntoDerObject for Asn1SubjectPublicKey { - fn into_der_object(self) -> DerObject { - let pk_der = (self.0).0; - let mut bit_string = Vec::with_capacity(pk_der.len() + 1); - // The number of bits in pk_der is trivially always a multiple of 8, - // so there are always 0 "unused bits" signaled by the first byte. - bit_string.push(0u8); - bit_string.extend(pk_der); - DerObject::new(DerTag::x03, bit_string.into()) - } - fn serialized_len(&self) -> usize { - DerObject::compute_serialized_len((self.0).0.len() + 1) - } -} - -impl FromDerObject for Asn1SubjectPublicKey { - fn from_der_object(o: DerObject) -> Result { - if o.tag != DerTag::x03 { - return Err(Asn1DerError::InvalidTag); - } - let pk_der: Vec = o.value.data.into_iter().skip(1).collect(); - // We don't parse pk_der further as an ASN.1 RsaPublicKey, since - // we only need the DER encoding for `verify`. - Ok(Asn1SubjectPublicKey(PublicKey(pk_der))) - } -} - -/// ASN.1 SubjectPublicKeyInfo -#[derive(Asn1Der)] -#[allow(non_snake_case)] -struct Asn1SubjectPublicKeyInfo { - algorithmIdentifier: Asn1RsaEncryption, - subjectPublicKey: Asn1SubjectPublicKey, -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Signature(pub Vec); - -#[cfg(test)] -mod tests { - use super::*; - use quickcheck::*; - use std::fmt; - - const KEY1: &'static [u8] = include_bytes!("test/rsa-2048.pk8"); - const KEY2: &'static [u8] = include_bytes!("test/rsa-3072.pk8"); - const KEY3: &'static [u8] = include_bytes!("test/rsa-4096.pk8"); - - #[derive(Clone)] - struct SomeKeypair(Keypair); - - impl fmt::Debug for SomeKeypair { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "SomeKeypair") - } - } - - impl Arbitrary for SomeKeypair { - fn arbitrary(g: &mut Gen) -> SomeKeypair { - let mut key = g.choose(&[KEY1, KEY2, KEY3]).unwrap().to_vec(); - SomeKeypair(Keypair::from_pkcs8(&mut key).unwrap()) - } - } - - #[test] - fn rsa_from_pkcs8() { - assert!(Keypair::from_pkcs8(&mut KEY1.to_vec()).is_ok()); - assert!(Keypair::from_pkcs8(&mut KEY2.to_vec()).is_ok()); - assert!(Keypair::from_pkcs8(&mut KEY3.to_vec()).is_ok()); - } - - #[test] - fn rsa_x509_encode_decode() { - fn prop(SomeKeypair(kp): SomeKeypair) -> Result { - let pk = kp.public(); - PublicKey::decode_x509(&pk.encode_x509()) - .map_err(|e| e.to_string()) - .map(|pk2| pk2 == pk) - } - QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _); - } - - #[test] - fn rsa_sign_verify() { - fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec) -> Result { - kp.sign(&msg).map(|s| kp.public().verify(&msg, &s).is_ok()) - } - QuickCheck::new() - .tests(10) - .quickcheck(prop as fn(_, _) -> _); - } -} diff --git a/keypair/src/secp256k1.rs b/keypair/src/secp256k1.rs deleted file mode 100644 index 64c4a85..0000000 --- a/keypair/src/secp256k1.rs +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2019 Parity Technologies (UK) Ltd. -// -// 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. - -//! Secp256k1 keys. -use crate::error::{DecodingError, SigningError, VerificationError}; - -use asn1_der::{DerObject, FromDerObject}; -use core::fmt; -use libsecp256k1::Message; -use rand::RngCore; -use serde::de::Error as SerdeError; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes}; -use sha2::{Digest as ShaDigestTrait, Sha256}; -use zeroize::Zeroize; - -/// A Secp256k1 keypair. -#[derive(Clone)] -pub struct Keypair { - secret: SecretKey, - public: PublicKey, -} - -impl Keypair { - /// Generate a new sec256k1 `Keypair`. - pub fn generate() -> Self { - Keypair::from(SecretKey::generate()) - } - - /// Get the public key of this keypair. - pub fn public(&self) -> &PublicKey { - &self.public - } - - /// Get the secret key of this keypair. - pub fn secret(&self) -> &SecretKey { - &self.secret - } -} - -impl fmt::Debug for Keypair { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Keypair") - .field("public", &self.public) - .finish() - } -} - -/// Promote a Secp256k1 secret key into a keypair. -impl From for Keypair { - fn from(secret: SecretKey) -> Self { - let public = PublicKey(libsecp256k1::PublicKey::from_secret_key(&secret.0)); - Keypair { secret, public } - } -} - -/// Demote a Secp256k1 keypair into a secret key. -impl From for SecretKey { - fn from(kp: Keypair) -> Self { - kp.secret - } -} - -/// A Secp256k1 secret key. -#[derive(Clone)] -pub struct SecretKey(libsecp256k1::SecretKey); - -impl fmt::Debug for SecretKey { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "SecretKey") - } -} - -impl SecretKey { - /// Generate a new Secp256k1 secret key. - pub fn generate() -> Self { - let mut r = rand::thread_rng(); - let mut b = [0; libsecp256k1::util::SECRET_KEY_SIZE]; - // This is how it is done in `secp256k1::SecretKey::random` which - // we do not use here because it uses `rand::Rng` from rand-0.4. - loop { - r.fill_bytes(&mut b); - if let Ok(k) = libsecp256k1::SecretKey::parse(&b) { - return SecretKey(k); - } - } - } - - /// Create a secret key from a byte slice, zeroing the slice on success. - /// If the bytes do not constitute a valid Secp256k1 secret key, an - /// error is returned. - pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result { - let sk_bytes = sk.as_mut(); - let secret = libsecp256k1::SecretKey::parse_slice(&*sk_bytes) - .map_err(|_| DecodingError::Secp256k1)?; - sk_bytes.zeroize(); - Ok(SecretKey(secret)) - } - - /// Decode a DER-encoded Secp256k1 secret key in an ECPrivateKey - /// structure as defined in [RFC5915]. - /// - /// [RFC5915]: https://tools.ietf.org/html/rfc5915 - pub fn from_der(mut der: impl AsMut<[u8]>) -> Result { - // TODO: Stricter parsing. - let der_obj = der.as_mut(); - let obj: Vec = - FromDerObject::deserialize((*der_obj).iter()).map_err(|_| DecodingError::Secp256k1)?; - der_obj.zeroize(); - let sk_obj = obj.into_iter().nth(1).ok_or(DecodingError::Secp256k1)?; - let mut sk_bytes: Vec = - FromDerObject::from_der_object(sk_obj).map_err(|_| DecodingError::Secp256k1)?; - let sk = SecretKey::from_bytes(&mut sk_bytes)?; - sk_bytes.zeroize(); - Ok(sk) - } - - /// Sign a message with this secret key, producing a DER-encoded - /// ECDSA signature, as defined in [RFC3278]. - /// - /// [RFC3278]: https://tools.ietf.org/html/rfc3278#section-8.2 - pub fn sign(&self, msg: &[u8]) -> Result, SigningError> { - self.sign_hashed(Sha256::digest(msg).as_ref()) - } - - /// Returns the raw bytes of the secret key. - pub fn to_bytes(&self) -> [u8; 32] { - self.0.serialize() - } - - /// Sign a raw message of length 256 bits with this secret key, produces a DER-encoded - /// ECDSA signature. - pub fn sign_hashed(&self, msg: &[u8]) -> Result, SigningError> { - let m = Message::parse_slice(msg).map_err(SigningError::Secp256k1)?; - Ok(libsecp256k1::sign(&m, &self.0) - .0 - .serialize_der() - .as_ref() - .into()) - } -} - -/// A Secp256k1 public key. -#[derive(PartialEq, Eq, Clone, Debug)] -pub struct PublicKey(libsecp256k1::PublicKey); - -impl PublicKey { - /// Verify the Secp256k1 signature on a message using the public key. - pub fn verify(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> { - self.verify_hashed(Sha256::digest(msg).as_ref(), sig) - } - - /// Verify the Secp256k1 DER-encoded signature on a raw 256-bit message using the public key. - pub fn verify_hashed(&self, msg: &[u8], sig: &[u8]) -> Result<(), VerificationError> { - Message::parse_slice(msg) - .and_then(|m| { - libsecp256k1::Signature::parse_der(sig) - .map(|s| libsecp256k1::verify(&m, &s, &self.0)) - }) - .map_err(|e| { - VerificationError::Secp256k1( - e, - bs58::encode(sig).into_string(), - bs58::encode(self.0.serialize_compressed()).into_string(), - ) - }) - .map(|_| ()) - } - - /// Encode the public key in compressed form, i.e. with one coordinate - /// represented by a single bit. - pub fn encode(&self) -> [u8; 33] { - self.0.serialize_compressed() - } - - /// Encode the public key in uncompressed form. - pub fn encode_uncompressed(&self) -> [u8; 65] { - self.0.serialize() - } - - /// Decode a public key from a byte slice in the the format produced - /// by `encode`. - pub fn decode(bytes: &[u8]) -> Result { - libsecp256k1::PublicKey::parse_slice(bytes, Some(libsecp256k1::PublicKeyFormat::Compressed)) - .map_err(|_| DecodingError::Secp256k1) - .map(PublicKey) - } -} - -impl Serialize for PublicKey { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - SerdeBytes::new(self.encode().to_vec().as_slice()).serialize(serializer) - } -} - -impl<'d> Deserialize<'d> for PublicKey { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'d>, - { - let bytes = ::deserialize(deserializer)?; - PublicKey::decode(bytes.as_slice()).map_err(SerdeError::custom) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub struct Signature(pub Vec); - -#[cfg(test)] -mod tests { - use super::*; - use crate::{key_pair, KeyFormat}; - use quickcheck::QuickCheck; - - fn eq_keypairs(kp1: key_pair::KeyPair, kp2: key_pair::KeyPair) -> bool { - kp1.public() == kp2.public() && kp1.secret().unwrap() == kp2.secret().unwrap() - } - - #[test] - fn secp256k1_secret_from_bytes() { - let sk1 = SecretKey::generate(); - let mut sk_bytes = [0; 32]; - sk_bytes.copy_from_slice(&sk1.0.serialize()[..]); - let sk2 = SecretKey::from_bytes(&mut sk_bytes).unwrap(); - assert_eq!(sk1.0.serialize(), sk2.0.serialize()); - assert_eq!(sk_bytes, [0; 32]); - } - - #[test] - fn secp256k1_keypair_encode_decode() { - fn prop() -> bool { - let kp1 = key_pair::KeyPair::generate(KeyFormat::Secp256k1); - let kp1_enc = libp2p_identity::Keypair::from(kp1.clone()); - let kp2 = key_pair::KeyPair::from(kp1_enc); - eq_keypairs(kp1, kp2) - } - QuickCheck::new().tests(10).quickcheck(prop as fn() -> _); - } -} diff --git a/keypair/src/signature.rs b/keypair/src/signature.rs index fc89472..20ab7e9 100644 --- a/keypair/src/signature.rs +++ b/keypair/src/signature.rs @@ -16,18 +16,12 @@ use crate::ed25519; use crate::error::DecodingError; use crate::key_pair::KeyFormat; -#[cfg(not(target_arch = "wasm32"))] -use crate::rsa; -use crate::secp256k1; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] pub enum Signature { Ed25519(ed25519::Signature), - #[cfg(not(target_arch = "wasm32"))] - Rsa(rsa::Signature), - Secp256k1(secp256k1::Signature), } pub struct RawSignature { @@ -40,9 +34,6 @@ impl Signature { use Signature::*; match self { Ed25519(_) => KeyFormat::Ed25519.into(), - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => KeyFormat::Rsa.into(), - Secp256k1(_) => KeyFormat::Secp256k1.into(), } } @@ -54,9 +45,6 @@ impl Signature { match self { Ed25519(sig) => result.extend(sig.0.clone()), - #[cfg(not(target_arch = "wasm32"))] - Rsa(sig) => result.extend(sig.0.clone()), - Secp256k1(sig) => result.extend(sig.0.clone()), } result @@ -66,11 +54,6 @@ impl Signature { pub fn decode(bytes: Vec) -> Result { match KeyFormat::try_from(bytes[0])? { KeyFormat::Ed25519 => Ok(Signature::Ed25519(ed25519::Signature(bytes[1..].to_vec()))), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => Ok(Signature::Rsa(rsa::Signature(bytes[1..].to_vec()))), - KeyFormat::Secp256k1 => Ok(Signature::Secp256k1(secp256k1::Signature( - bytes[1..].to_vec(), - ))), } } @@ -79,9 +62,6 @@ impl Signature { match self { Ed25519(sig) => &sig.0, - #[cfg(not(target_arch = "wasm32"))] - Rsa(sig) => &sig.0, - Secp256k1(sig) => &sig.0, } } @@ -90,9 +70,6 @@ impl Signature { match self { Ed25519(_) => KeyFormat::Ed25519, - #[cfg(not(target_arch = "wasm32"))] - Rsa(_) => KeyFormat::Rsa, - Secp256k1(_) => KeyFormat::Secp256k1, } } @@ -106,9 +83,6 @@ impl Signature { pub fn from_bytes(key_format: KeyFormat, bytes: Vec) -> Self { match key_format { KeyFormat::Ed25519 => Signature::Ed25519(ed25519::Signature(bytes)), - #[cfg(not(target_arch = "wasm32"))] - KeyFormat::Rsa => Signature::Rsa(rsa::Signature(bytes)), - KeyFormat::Secp256k1 => Signature::Secp256k1(secp256k1::Signature(bytes)), } } } @@ -121,19 +95,10 @@ mod tests { fn signature_encode_decode() { let bytes: Vec = (0..10).collect(); let ed25519_sig = Signature::Ed25519(crate::ed25519::Signature(bytes.clone())); - let secp256k1_sig = Signature::Secp256k1(crate::secp256k1::Signature(bytes.clone())); - #[cfg(not(target_arch = "wasm32"))] - let rsa_sig = Signature::Rsa(crate::rsa::Signature(bytes.clone())); assert_eq!( Signature::decode(ed25519_sig.encode()).unwrap(), ed25519_sig ); - assert_eq!( - Signature::decode(secp256k1_sig.encode()).unwrap(), - secp256k1_sig - ); - #[cfg(not(target_arch = "wasm32"))] - assert_eq!(Signature::decode(rsa_sig.encode()).unwrap(), rsa_sig); } }