From f42bdd649a397e9ab73c556b969aee792e77eda8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 15 Mar 2021 17:07:27 +0100 Subject: [PATCH 1/6] core: Update to asn1_der v0.7 --- core/Cargo.toml | 4 +- core/src/identity/rsa.rs | 172 +++++++++++++++++++++++---------- core/src/identity/secp256k1.rs | 14 +-- 3 files changed, 129 insertions(+), 61 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 21650fcb254..9edf21eca73 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] [dependencies] -asn1_der = "0.6.1" +asn1_der = "0.7.3" bs58 = "0.4.0" ed25519-dalek = "1.0.1" either = "1.5" @@ -47,6 +47,8 @@ libp2p-tcp = { path = "../transports/tcp" } multihash = { version = "0.13", default-features = false, features = ["arb"] } quickcheck = "0.9.0" wasm-timer = "0.2" +# TODO: For testing only. Remove. +libp2p-core-v026 = { version = "0.26.0", package = "libp2p-core" } [build-dependencies] prost-build = "0.7" diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index af1402ade0a..4f4ca83e880 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -20,8 +20,7 @@ //! RSA keys. -use asn1_der::{Asn1Der, FromDerObject, IntoDerObject, DerObject, DerTag, DerValue, Asn1DerError}; -use lazy_static::lazy_static; +use asn1_der::{typed::{DerEncodable, DerDecodable, Sequence}, DerObject, Asn1DerError, Asn1DerErrorVariant}; use super::error::*; use ring::rand::SystemRandom; use ring::signature::{self, RsaKeyPair, RSA_PKCS1_SHA256, RSA_PKCS1_2048_8192_SHA256}; @@ -93,15 +92,16 @@ impl PublicKey { }, 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.") + let mut buf = Vec::new(); + let buf = spki.encode(&mut buf).map(|_| buf) + .expect("RSA X.509 public key encoding failed."); + buf } /// 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()) + Asn1SubjectPublicKeyInfo::decode(pk) .map_err(|e| DecodingError::new("RSA X.509").source(e)) .map(|spki| spki.subjectPublicKey.0) } @@ -123,79 +123,111 @@ impl fmt::Debug for PublicKey { // 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 ] - } - }; -} +const ASN1_OBJECT_IDENTIFIER_TAG: u8 = 6; +/// 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 +const ASN1_RSA_ENCRYPTION_OID: [u8;9] = [ 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 asn1_der::typed::DerEncodable for Asn1OidRsaEncryption { + fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { + // TODO: `DerObject::write` is a hidden method. Should one use `new` or `new_from_source`? + // If so, I don't see a way to do that given that `S: Into<&'a [u8]` would be required. + asn1_der::DerObject::write( + ASN1_OBJECT_IDENTIFIER_TAG, + ASN1_RSA_ENCRYPTION_OID.len(), + &mut ASN1_RSA_ENCRYPTION_OID.iter(), + sink, + )?; + Ok(()) } } -impl FromDerObject for Asn1OidRsaEncryption { - fn from_der_object(o: DerObject) -> Result { - if o.tag != DerTag::x06 { - return Err(Asn1DerError::InvalidTag) +impl DerDecodable<'_> for Asn1OidRsaEncryption { + fn load(object: DerObject<'_>) -> Result { + if object.tag() != ASN1_OBJECT_IDENTIFIER_TAG { + return Err(Asn1DerError::new( + Asn1DerErrorVariant::InvalidData("DER object tag is not the object identifier tag."), + )); } - if o.value != OID_RSA_ENCRYPTION_DER.value { - return Err(Asn1DerError::InvalidEncoding) + + if object.value() != ASN1_RSA_ENCRYPTION_OID { + return Err(Asn1DerError::new( + Asn1DerErrorVariant::InvalidData("DER object is not the 'rsaEncryption' identifier."), + )); } + Ok(Asn1OidRsaEncryption()) } } /// The ASN.1 AlgorithmIdentifier for "rsaEncryption". -#[derive(Asn1Der)] struct Asn1RsaEncryption { algorithm: Asn1OidRsaEncryption, parameters: () } +impl asn1_der::typed::DerEncodable for Asn1RsaEncryption { + fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { + // TODO: Is there a way to write to `sink` directly? + let mut algorithm = Vec::new(); + self.algorithm.encode(&mut algorithm)?; + // TODO: Is the decode after the encode step needed? Passing a `Vec` to + // `Sequence::write` would not encode the payload with the right tag. + let algorithm = DerObject::decode(&algorithm)?; + + let mut parameters = Vec::new(); + self.parameters.encode(&mut parameters)?; + let parameters = DerObject::decode(¶meters)?; + + asn1_der::typed::Sequence::write(&[algorithm, parameters], sink) + } +} + +impl DerDecodable<'_> for Asn1RsaEncryption { + fn load(object: DerObject<'_>) -> Result { + let seq: Sequence = Sequence::load(object)?; + let r = Ok(Asn1RsaEncryption{ + algorithm: Asn1OidRsaEncryption::load(seq.get(0)?)?, + parameters: <()>::load(seq.get(1)?)?, + }); + r + } +} + /// 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; +impl asn1_der::typed::DerEncodable for Asn1SubjectPublicKey { + fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { + 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) + asn1_der::DerObject::write(3, bit_string.len(), &mut bit_string.iter(), sink)?; + Ok(()) } } -impl FromDerObject for Asn1SubjectPublicKey { - fn from_der_object(o: DerObject) -> Result { - if o.tag != DerTag::x03 { - return Err(Asn1DerError::InvalidTag) +impl DerDecodable<'_> for Asn1SubjectPublicKey { + fn load(object: DerObject<'_>) -> Result { + if object.tag() != 3 { + return Err(Asn1DerError::new( + Asn1DerErrorVariant::InvalidData("DER object tag is not the bit string tag."), + )); } - let pk_der: Vec = o.value.data.into_iter().skip(1).collect(); + + let pk_der: Vec = object.value().into_iter().skip(1).cloned().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))) @@ -203,13 +235,36 @@ impl FromDerObject for Asn1SubjectPublicKey { } /// ASN.1 SubjectPublicKeyInfo -#[derive(Asn1Der)] #[allow(non_snake_case)] struct Asn1SubjectPublicKeyInfo { algorithmIdentifier: Asn1RsaEncryption, subjectPublicKey: Asn1SubjectPublicKey } +impl asn1_der::typed::DerEncodable for Asn1SubjectPublicKeyInfo { + fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { + let mut identifier = Vec::new(); + self.algorithmIdentifier.encode(&mut identifier)?; + let identifier = DerObject::decode(&identifier)?; + + let mut key = Vec::new(); + self.subjectPublicKey.encode(&mut key)?; + let key = DerObject::decode(&key)?; + + asn1_der::typed::Sequence::write(&[identifier, key], sink) + } +} + +impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo { + fn load(object: DerObject<'_>) -> Result { + let seq: Sequence = Sequence::load(object)?; + Ok(Asn1SubjectPublicKeyInfo { + algorithmIdentifier: seq.get_as(0)?, + subjectPublicKey: Asn1SubjectPublicKey::load(seq.get(1)?)?, + }) + } +} + #[cfg(test)] mod tests { use super::*; @@ -221,8 +276,9 @@ mod tests { const KEY2: &'static [u8] = include_bytes!("test/rsa-3072.pk8"); const KEY3: &'static [u8] = include_bytes!("test/rsa-4096.pk8"); + // TODO: Remove libp2p_core_v026. For compatibility testing only. #[derive(Clone)] - struct SomeKeypair(Keypair); + struct SomeKeypair(Keypair, libp2p_core_v026::identity::rsa::Keypair); impl fmt::Debug for SomeKeypair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -233,7 +289,11 @@ mod tests { impl Arbitrary for SomeKeypair { fn arbitrary(g: &mut G) -> SomeKeypair { let mut key = [KEY1, KEY2, KEY3].choose(g).unwrap().to_vec(); - SomeKeypair(Keypair::from_pkcs8(&mut key).unwrap()) + let mut key2 = key.clone(); + SomeKeypair( + Keypair::from_pkcs8(&mut key).unwrap(), + libp2p_core_v026::identity::rsa::Keypair::from_pkcs8(&mut key2).unwrap(), + ) } } @@ -246,9 +306,16 @@ mod tests { #[test] fn rsa_x509_encode_decode() { - fn prop(SomeKeypair(kp): SomeKeypair) -> Result { + fn prop(SomeKeypair(kp, old_kp): SomeKeypair) -> Result { let pk = kp.public(); - PublicKey::decode_x509(&pk.encode_x509()) + let old_kp = old_kp.public(); + + let x509 = pk.encode_x509(); + let x509_old = old_kp.encode_x509(); + + assert_eq!(x509, x509_old); + + PublicKey::decode_x509(&x509) .map_err(|e| e.to_string()) .map(|pk2| pk2 == pk) } @@ -257,10 +324,9 @@ mod tests { #[test] fn rsa_sign_verify() { - fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec) -> Result { + fn prop(SomeKeypair(kp, _): SomeKeypair, msg: Vec) -> Result { kp.sign(&msg).map(|s| kp.public().verify(&msg, &s)) } QuickCheck::new().tests(10).quickcheck(prop as fn(_,_) -> _); } } - diff --git a/core/src/identity/secp256k1.rs b/core/src/identity/secp256k1.rs index a5df9969574..adec4ae67ed 100644 --- a/core/src/identity/secp256k1.rs +++ b/core/src/identity/secp256k1.rs @@ -20,7 +20,7 @@ //! Secp256k1 keys. -use asn1_der::{FromDerObject, DerObject}; +use asn1_der::typed::{DerDecodable, Sequence}; use rand::RngCore; use sha2::{Digest as ShaDigestTrait, Sha256}; use secp256k1::{Message, Signature}; @@ -110,21 +110,21 @@ impl SecretKey { } /// Decode a DER-encoded Secp256k1 secret key in an ECPrivateKey - /// structure as defined in [RFC5915]. + /// structure as defined in [RFC5915], zeroing the input slice on success. /// /// [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()) + let obj: Sequence = DerDecodable::decode(der_obj) .map_err(|e| DecodingError::new("Secp256k1 DER ECPrivateKey").source(e))?; - der_obj.zeroize(); - let sk_obj = obj.into_iter().nth(1) - .ok_or_else(|| DecodingError::new("Not enough elements in DER"))?; - let mut sk_bytes: Vec = FromDerObject::from_der_object(sk_obj) + let sk_obj = obj.get(1) + .map_err(|e| DecodingError::new("Not enough elements in DER").source(e))?; + let mut sk_bytes: Vec = asn1_der::typed::DerDecodable::load(sk_obj) .map_err(DecodingError::new)?; let sk = SecretKey::from_bytes(&mut sk_bytes)?; sk_bytes.zeroize(); + der_obj.zeroize(); Ok(sk) } From f73d67274b8e944e7125a9188763ddd968714114 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 15 Mar 2021 22:50:15 +0100 Subject: [PATCH 2/6] core/identity/rsa: Use Sequence::get_as --- core/src/identity/rsa.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index 4f4ca83e880..19683331cf1 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -195,8 +195,8 @@ impl DerDecodable<'_> for Asn1RsaEncryption { fn load(object: DerObject<'_>) -> Result { let seq: Sequence = Sequence::load(object)?; let r = Ok(Asn1RsaEncryption{ - algorithm: Asn1OidRsaEncryption::load(seq.get(0)?)?, - parameters: <()>::load(seq.get(1)?)?, + algorithm: seq.get_as(0)?, + parameters: seq.get_as(1)?, }); r } @@ -260,7 +260,7 @@ impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo { let seq: Sequence = Sequence::load(object)?; Ok(Asn1SubjectPublicKeyInfo { algorithmIdentifier: seq.get_as(0)?, - subjectPublicKey: Asn1SubjectPublicKey::load(seq.get(1)?)?, + subjectPublicKey: seq.get_as(1)?, }) } } From 2633d7290e180ef6eccab5a6694f4f0b6161ffab Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 19 Mar 2021 14:33:23 +0100 Subject: [PATCH 3/6] core/src/identity: Apply suggestions from review --- core/Cargo.toml | 2 +- core/src/identity/rsa.rs | 152 ++++++++++++++++++++++----------------- 2 files changed, 89 insertions(+), 65 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 9edf21eca73..aab52f6cdbf 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] [dependencies] -asn1_der = "0.7.3" +asn1_der = "0.7.4" bs58 = "0.4.0" ed25519-dalek = "1.0.1" either = "1.5" diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index 19683331cf1..1513d595547 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -20,7 +20,7 @@ //! RSA keys. -use asn1_der::{typed::{DerEncodable, DerDecodable, Sequence}, DerObject, Asn1DerError, Asn1DerErrorVariant}; +use asn1_der::{typed::{DerEncodable, DerDecodable, DerTypeView, Sequence}, DerObject, Asn1DerError, Asn1DerErrorVariant, Sink, VecBacking}; use super::error::*; use ring::rand::SystemRandom; use ring::signature::{self, RsaKeyPair, RSA_PKCS1_SHA256, RSA_PKCS1_2048_8192_SHA256}; @@ -87,7 +87,7 @@ impl PublicKey { pub fn encode_x509(&self) -> Vec { let spki = Asn1SubjectPublicKeyInfo { algorithmIdentifier: Asn1RsaEncryption { - algorithm: Asn1OidRsaEncryption(), + algorithm: Asn1OidRsaEncryption, parameters: () }, subjectPublicKey: Asn1SubjectPublicKey(self.clone()) @@ -123,48 +123,78 @@ impl fmt::Debug for PublicKey { // Primer: http://luca.ntop.org/Teaching/Appunti/asn1.html // Playground: https://lapo.it/asn1js/ -const ASN1_OBJECT_IDENTIFIER_TAG: u8 = 6; -/// 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 -const ASN1_RSA_ENCRYPTION_OID: [u8;9] = [ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ]; +/// A raw ASN1 OID. +#[derive(Copy, Clone)] +struct Asn1RawOid<'a> { + object: DerObject<'a> +} + +impl<'a> Asn1RawOid<'a> { + /// The underlying OID as byte literal. + pub fn oid(&self) -> &[u8] { + self.object.value() + } + + /// Writes an OID raw `value` as DER-object to `sink`. + pub fn write(value: &[u8], sink: &mut S) -> Result<(), Asn1DerError> { + DerObject::write(Self::TAG, value.len(), &mut value.iter(), sink) + } +} + +impl<'a> DerTypeView<'a> for Asn1RawOid<'a> { + const TAG: u8 = 6; + + fn object(&self) -> DerObject<'a> { + self.object + } +} + +impl<'a> DerEncodable for Asn1RawOid<'a> { + fn encode(&self, sink: &mut S) -> Result<(), Asn1DerError> { + self.object.encode(sink) + } +} + +impl<'a> DerDecodable<'a> for Asn1RawOid<'a> { + fn load(object: DerObject<'a>) -> Result { + if object.tag() != Self::TAG { + return Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData( + "DER object tag is not the object identifier tag.", + ))); + } + + Ok(Self { object }) + } +} /// The ASN.1 OID for "rsaEncryption". #[derive(Clone)] -struct Asn1OidRsaEncryption(); - -impl asn1_der::typed::DerEncodable for Asn1OidRsaEncryption { - fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { - // TODO: `DerObject::write` is a hidden method. Should one use `new` or `new_from_source`? - // If so, I don't see a way to do that given that `S: Into<&'a [u8]` would be required. - asn1_der::DerObject::write( - ASN1_OBJECT_IDENTIFIER_TAG, - ASN1_RSA_ENCRYPTION_OID.len(), - &mut ASN1_RSA_ENCRYPTION_OID.iter(), - sink, - )?; - Ok(()) +struct Asn1OidRsaEncryption; + +impl Asn1OidRsaEncryption { + /// 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 + const OID: [u8;9] = [ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ]; +} + +impl DerEncodable for Asn1OidRsaEncryption { + fn encode(&self, sink: &mut S) -> Result<(), Asn1DerError> { + Asn1RawOid::write(&Self::OID, sink) } } impl DerDecodable<'_> for Asn1OidRsaEncryption { fn load(object: DerObject<'_>) -> Result { - if object.tag() != ASN1_OBJECT_IDENTIFIER_TAG { - return Err(Asn1DerError::new( - Asn1DerErrorVariant::InvalidData("DER object tag is not the object identifier tag."), - )); + match Asn1RawOid::load(object)?.oid() { + oid if oid == Self::OID => Ok(Self), + _ => Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData( + "DER object is not the 'rsaEncryption' identifier.", + ))) } - - if object.value() != ASN1_RSA_ENCRYPTION_OID { - return Err(Asn1DerError::new( - Asn1DerErrorVariant::InvalidData("DER object is not the 'rsaEncryption' identifier."), - )); - } - - Ok(Asn1OidRsaEncryption()) } } @@ -174,31 +204,26 @@ struct Asn1RsaEncryption { parameters: () } -impl asn1_der::typed::DerEncodable for Asn1RsaEncryption { - fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { - // TODO: Is there a way to write to `sink` directly? - let mut algorithm = Vec::new(); - self.algorithm.encode(&mut algorithm)?; - // TODO: Is the decode after the encode step needed? Passing a `Vec` to - // `Sequence::write` would not encode the payload with the right tag. - let algorithm = DerObject::decode(&algorithm)?; +impl DerEncodable for Asn1RsaEncryption { + fn encode(&self, sink: &mut S) -> Result<(), Asn1DerError> { + let mut algorithm_buf = Vec::new(); + let algorithm = self.algorithm.der_object(VecBacking(&mut algorithm_buf))?; - let mut parameters = Vec::new(); - self.parameters.encode(&mut parameters)?; - let parameters = DerObject::decode(¶meters)?; + let mut parameters_buf = Vec::new(); + let parameters = self.parameters.der_object(VecBacking(&mut parameters_buf))?; - asn1_der::typed::Sequence::write(&[algorithm, parameters], sink) + Sequence::write(&[algorithm, parameters], sink) } } impl DerDecodable<'_> for Asn1RsaEncryption { fn load(object: DerObject<'_>) -> Result { let seq: Sequence = Sequence::load(object)?; - let r = Ok(Asn1RsaEncryption{ + + Ok(Self{ algorithm: seq.get_as(0)?, parameters: seq.get_as(1)?, - }); - r + }) } } @@ -206,15 +231,15 @@ impl DerDecodable<'_> for Asn1RsaEncryption { /// i.e. encoded as a DER BIT STRING. struct Asn1SubjectPublicKey(PublicKey); -impl asn1_der::typed::DerEncodable for Asn1SubjectPublicKey { - fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { +impl DerEncodable for Asn1SubjectPublicKey { + fn encode(&self, sink: &mut S) -> Result<(), Asn1DerError> { 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); - asn1_der::DerObject::write(3, bit_string.len(), &mut bit_string.iter(), sink)?; + DerObject::write(3, bit_string.len(), &mut bit_string.iter(), sink)?; Ok(()) } } @@ -230,7 +255,7 @@ impl DerDecodable<'_> for Asn1SubjectPublicKey { let pk_der: Vec = object.value().into_iter().skip(1).cloned().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))) + Ok(Self(PublicKey(pk_der))) } } @@ -241,24 +266,23 @@ struct Asn1SubjectPublicKeyInfo { subjectPublicKey: Asn1SubjectPublicKey } -impl asn1_der::typed::DerEncodable for Asn1SubjectPublicKeyInfo { - fn encode(&self, sink: &mut S) -> Result<(), asn1_der::Asn1DerError> { - let mut identifier = Vec::new(); - self.algorithmIdentifier.encode(&mut identifier)?; - let identifier = DerObject::decode(&identifier)?; +impl DerEncodable for Asn1SubjectPublicKeyInfo { + fn encode(&self, sink: &mut S) -> Result<(), Asn1DerError> { + let mut identifier_buf = Vec::new(); + let identifier = self.algorithmIdentifier.der_object(VecBacking(&mut identifier_buf))?; - let mut key = Vec::new(); - self.subjectPublicKey.encode(&mut key)?; - let key = DerObject::decode(&key)?; + let mut key_buf = Vec::new(); + let key = self.subjectPublicKey.der_object(VecBacking(&mut key_buf))?; - asn1_der::typed::Sequence::write(&[identifier, key], sink) + Sequence::write(&[identifier, key], sink) } } impl DerDecodable<'_> for Asn1SubjectPublicKeyInfo { fn load(object: DerObject<'_>) -> Result { let seq: Sequence = Sequence::load(object)?; - Ok(Asn1SubjectPublicKeyInfo { + + Ok(Self { algorithmIdentifier: seq.get_as(0)?, subjectPublicKey: seq.get_as(1)?, }) From 879c3ac142c696e92b191c4485fbf8cb29f17f01 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 22 Mar 2021 13:21:32 +0100 Subject: [PATCH 4/6] core/: Revert testing with libp2p-core v0.26 --- core/Cargo.toml | 2 -- core/src/identity/rsa.rs | 22 +++++----------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 5906374188c..fa25afd43ef 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -47,8 +47,6 @@ libp2p-tcp = { path = "../transports/tcp" } multihash = { version = "0.13", default-features = false, features = ["arb"] } quickcheck = "0.9.0" wasm-timer = "0.2" -# TODO: For testing only. Remove. -libp2p-core-v026 = { version = "0.26.0", package = "libp2p-core" } [build-dependencies] prost-build = "0.7" diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index 1513d595547..d229eed9af8 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -300,9 +300,8 @@ mod tests { const KEY2: &'static [u8] = include_bytes!("test/rsa-3072.pk8"); const KEY3: &'static [u8] = include_bytes!("test/rsa-4096.pk8"); - // TODO: Remove libp2p_core_v026. For compatibility testing only. #[derive(Clone)] - struct SomeKeypair(Keypair, libp2p_core_v026::identity::rsa::Keypair); + struct SomeKeypair(Keypair); impl fmt::Debug for SomeKeypair { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -313,11 +312,7 @@ mod tests { impl Arbitrary for SomeKeypair { fn arbitrary(g: &mut G) -> SomeKeypair { let mut key = [KEY1, KEY2, KEY3].choose(g).unwrap().to_vec(); - let mut key2 = key.clone(); - SomeKeypair( - Keypair::from_pkcs8(&mut key).unwrap(), - libp2p_core_v026::identity::rsa::Keypair::from_pkcs8(&mut key2).unwrap(), - ) + SomeKeypair(Keypair::from_pkcs8(&mut key).unwrap()) } } @@ -330,16 +325,9 @@ mod tests { #[test] fn rsa_x509_encode_decode() { - fn prop(SomeKeypair(kp, old_kp): SomeKeypair) -> Result { + fn prop(SomeKeypair(kp): SomeKeypair) -> Result { let pk = kp.public(); - let old_kp = old_kp.public(); - - let x509 = pk.encode_x509(); - let x509_old = old_kp.encode_x509(); - - assert_eq!(x509, x509_old); - - PublicKey::decode_x509(&x509) + PublicKey::decode_x509(&pk.encode_x509()) .map_err(|e| e.to_string()) .map(|pk2| pk2 == pk) } @@ -348,7 +336,7 @@ mod tests { #[test] fn rsa_sign_verify() { - fn prop(SomeKeypair(kp, _): SomeKeypair, msg: Vec) -> Result { + fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec) -> Result { kp.sign(&msg).map(|s| kp.public().verify(&msg, &s)) } QuickCheck::new().tests(10).quickcheck(prop as fn(_,_) -> _); From 77a6c7f936e32780d19c8daee729200e5476299b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 22 Mar 2021 13:23:37 +0100 Subject: [PATCH 5/6] *: Update changelogs and cargo tomls --- CHANGELOG.md | 1 + Cargo.toml | 2 +- core/CHANGELOG.md | 4 ++++ core/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06d18c965ee..b12dbda14ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ ## Version 0.37.0 [unreleased] - Update individual crates. + - `libp2p-core` - `libp2p-floodsub` - `libp2p-gossipsub` - `libp2p-kad` diff --git a/Cargo.toml b/Cargo.toml index 496afa5c500..88b4eb836b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ atomic = "0.5.0" bytes = "1" futures = "0.3.1" lazy_static = "1.2" -libp2p-core = { version = "0.28.0", path = "core", default-features = false } +libp2p-core = { version = "0.28.2", path = "core", default-features = false } libp2p-floodsub = { version = "0.29.0", path = "protocols/floodsub", optional = true } libp2p-gossipsub = { version = "0.30.0", path = "./protocols/gossipsub", optional = true } libp2p-identify = { version = "0.29.0", path = "protocols/identify", optional = true } diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 927e14dc634..f7d93c92bd6 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.28.2 [unreleased] + +- Update dependencies. + # 0.28.1 [2021-03-17] - Update `paritytech-multiaddr` to `>=v0.11.2`. diff --git a/core/Cargo.toml b/core/Cargo.toml index fa25afd43ef..6b91004240e 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -2,7 +2,7 @@ name = "libp2p-core" edition = "2018" description = "Core traits and structs of libp2p" -version = "0.28.1" +version = "0.28.2" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" From c19170b966ed913753c14ead445fedf259d66820 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 22 Mar 2021 13:26:16 +0100 Subject: [PATCH 6/6] core/src/identity/rsa: Wrap import line --- core/src/identity/rsa.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/identity/rsa.rs b/core/src/identity/rsa.rs index d229eed9af8..ffbfb975ff0 100644 --- a/core/src/identity/rsa.rs +++ b/core/src/identity/rsa.rs @@ -20,7 +20,8 @@ //! RSA keys. -use asn1_der::{typed::{DerEncodable, DerDecodable, DerTypeView, Sequence}, DerObject, Asn1DerError, Asn1DerErrorVariant, Sink, VecBacking}; +use asn1_der::typed::{DerEncodable, DerDecodable, DerTypeView, Sequence}; +use asn1_der::{DerObject, Asn1DerError, Asn1DerErrorVariant, Sink, VecBacking}; use super::error::*; use ring::rand::SystemRandom; use ring::signature::{self, RsaKeyPair, RSA_PKCS1_SHA256, RSA_PKCS1_2048_8192_SHA256};