From 3c6441b97c7ef58b6284ab11243b8fbd8694ffc6 Mon Sep 17 00:00:00 2001 From: Zotho Date: Fri, 18 Jun 2021 19:10:25 +0500 Subject: [PATCH 1/2] oid_append!() macro --- src/lib.rs | 5 ++- src/oid.rs | 9 +++++ src/oid_append.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/oid_append.rs diff --git a/src/lib.rs b/src/lib.rs index 17065f3..b1ce97d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -208,7 +208,7 @@ //! (DER)." #![deny(/*missing_docs,*/ - unstable_features, + /*unstable_features,*/ unused_import_braces, unused_qualifications, unreachable_pub)] @@ -226,8 +226,11 @@ attr(deny(warnings/*, rust_2018_idioms*/), allow(dead_code, unused_variables)) ))] +#![feature(const_precise_live_drops)] + #[macro_use] mod macros; +mod oid_append; #[allow(clippy::module_inception)] pub mod ber; diff --git a/src/oid.rs b/src/oid.rs index a7c61b5..96e2c85 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -114,6 +114,15 @@ impl<'a> Oid<'a> { } } + /// Get the encoded oid without the header. Const version. + /// Only works when memory is not allocated on the heap, otherwise it returns an empty array. + pub const fn bytes_from_borrowed(&self) -> &[u8] { + match &self.asn1 { + Cow::Borrowed(b) => *b, + _ => &[] + } + } + /// Build an OID from an array of object identifier components. /// This method allocates memory on the heap. // we do not use .copied() for compatibility with 1.34 diff --git a/src/oid_append.rs b/src/oid_append.rs new file mode 100644 index 0000000..ffcf387 --- /dev/null +++ b/src/oid_append.rs @@ -0,0 +1,86 @@ +/// Internal OID arrays concatenation. +#[doc(hidden)] +#[macro_export] +macro_rules! array_concat( + ($first:expr, $second:expr) => { + &{ + let mut x = [0; $first.len() + 1 + $second.len()]; + + let mut i = 0; + while i < $first.len() { + x[i] = $first[i]; + i += 1; + } + + x[$first.len()] = $second[0] / 40; + x[$first.len() + 1] = $second[0] % 40; + let start = $first.len() + 1; + + let mut i = 1; + while i < $second.len() { + x[start + i] = $second[i]; + i += 1; + } + + x + } + }; +); + +/// Create OID from two others. +#[macro_export] +macro_rules! oid_append( + // oid_append!(A, B) + ($parent:ident, $appendix:ident) => ({ + const CONCATENATED: &[u8] = der_parser::array_concat!( + &$parent.bytes_from_borrowed(), + &$appendix.bytes_from_borrowed() + ); + Oid::new(std::borrow::Cow::Borrowed(CONCATENATED)) + }); + + // oid_append!(A, 3.4) + ($parent:expr, $appendix_start:tt$(.$appendix_item:tt)*) => ({ + const PARENT: Oid = $parent; + const APPENDIX: Oid = oid!($appendix_start$(.$appendix_item)*); + oid_append!(PARENT, APPENDIX) + }); + + // oid_append!(oid!(1.2), oid!(3.4)) + ($parent:expr, $appendix:expr) => ({ + const PARENT: Oid = $parent; + const APPENDIX: Oid = $appendix; + oid_append!(PARENT, APPENDIX) + }); +); + +#[cfg(test)] +mod tests { + use crate::oid::Oid; + use crate::oid; + // oid!() macro used crate as `der_parser` + use crate as der_parser; + + const A: Oid = oid!(1.2.3); + const B: Oid = oid_append!(A, 4.5); + const C: Oid = oid_append!(A, B); + const D: Oid = oid_append!(C, C); + + #[test] + fn test_oid_inheritance() { + assert_eq!(B, oid!(1.2.3.4.5)); + assert_eq!(C, oid!(1.2.3.1.2.3.4.5)); + assert_eq!(D, oid!(1.2.3.1.2.3.4.5.1.2.3.1.2.3.4.5)); + } + + const E: Oid = oid_append!(oid!(1.2.3), oid!(3.0)); + const F: Oid = oid_append!(oid!(0.0.3), oid!(0.3.0)); + const G: Oid = oid_append!(oid!(3.7.32452), oid!(2.29.34536)); + + #[test] + fn test_oid_correct_concatenated() { + assert_eq!(E, oid!(1.2.3.3.0)); + assert_eq!(F, oid!(0.0.3.0.3.0)); + assert_eq!(G, oid!(3.7.32452.2.29.34536)); + } +} \ No newline at end of file From f596c80bf72495cbc25c666964c405b764601f00 Mon Sep 17 00:00:00 2001 From: Zotho Date: Fri, 18 Jun 2021 19:19:14 +0500 Subject: [PATCH 2/2] Rustfmt --- src/lib.rs | 1 - src/oid.rs | 2 +- src/oid_append.rs | 6 ++++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b1ce97d..3f32521 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -225,7 +225,6 @@ no_crate_inject, attr(deny(warnings/*, rust_2018_idioms*/), allow(dead_code, unused_variables)) ))] - #![feature(const_precise_live_drops)] #[macro_use] diff --git a/src/oid.rs b/src/oid.rs index 96e2c85..4905862 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -119,7 +119,7 @@ impl<'a> Oid<'a> { pub const fn bytes_from_borrowed(&self) -> &[u8] { match &self.asn1 { Cow::Borrowed(b) => *b, - _ => &[] + _ => &[], } } diff --git a/src/oid_append.rs b/src/oid_append.rs index ffcf387..49429f8 100644 --- a/src/oid_append.rs +++ b/src/oid_append.rs @@ -56,8 +56,8 @@ macro_rules! oid_append( #[cfg(test)] mod tests { - use crate::oid::Oid; use crate::oid; + use crate::oid::Oid; // oid!() macro used crate as `der_parser` use crate as der_parser; @@ -67,6 +67,7 @@ mod tests { const D: Oid = oid_append!(C, C); #[test] + #[rustfmt::skip] fn test_oid_inheritance() { assert_eq!(B, oid!(1.2.3.4.5)); assert_eq!(C, oid!(1.2.3.1.2.3.4.5)); @@ -78,9 +79,10 @@ mod tests { const G: Oid = oid_append!(oid!(3.7.32452), oid!(2.29.34536)); #[test] + #[rustfmt::skip] fn test_oid_correct_concatenated() { assert_eq!(E, oid!(1.2.3.3.0)); assert_eq!(F, oid!(0.0.3.0.3.0)); assert_eq!(G, oid!(3.7.32452.2.29.34536)); } -} \ No newline at end of file +}