diff --git a/Cargo.toml b/Cargo.toml index 35ddab0..6241b8c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,15 +5,15 @@ authors = ["Adam Wick "] description = "A simple DER/ASN.1 encoding/decoding library." categories = ["encoding"] keywords = ["ASN1","encoding","DER"] -license-file = "LICENSE" +license = "ISC" repository = "https://github.com/acw/simple_asn1" edition = "2018" [dependencies] -chrono = "^0.4.0" -num-bigint = "^0.2.0" -num-traits = "^0.2.0" +chrono = { default-features = false, features = ["alloc"], version = "0.4" } +num-bigint = { default-features = false, version = "0.3" } +num-traits = { default-features = false, version = "0.2" } [dev-dependencies] -quickcheck = "^0.7.1" -rand = "0.5.5" +quickcheck = "0.9" +rand = "0.7" diff --git a/src/lib.rs b/src/lib.rs index 1878d2d..174b883 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,7 @@ pub use num_bigint::{BigInt, BigUint}; use num_traits::{FromPrimitive, One, ToPrimitive, Zero}; #[cfg(test)] use quickcheck::quickcheck; +use std::error::Error; use std::fmt; use std::iter::FromIterator; use std::mem::size_of; @@ -335,22 +336,42 @@ pub enum ASN1EncodeErr { ObjectIdentVal2TooLarge, } -impl fmt::Display for ASN1EncodeErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl ASN1EncodeErr { + fn description(&self) -> &str { match self { ASN1EncodeErr::ObjectIdentHasTooFewFields => { - write!(f, "ASN1 object identifier has too few fields.") + "ASN1 object identifier has too few fields." } ASN1EncodeErr::ObjectIdentVal1TooLarge => { - write!(f, "First value in ASN1 OID is too big.") + "First value in ASN1 OID is too big." } ASN1EncodeErr::ObjectIdentVal2TooLarge => { - write!(f, "Second value in ASN1 OID is too big.") + "Second value in ASN1 OID is too big." } } } } +impl fmt::Display for ASN1EncodeErr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.description()) + } +} + +impl Error for ASN1EncodeErr { + fn description(&self) -> &str { + self.description() + } + + fn cause(&self) -> Option<&dyn Error> { + None + } + + fn source(&self) -> Option<&(dyn Error + 'static)> { + None + } +} + /// Translate a binary blob into a series of `ASN1Block`s, or provide an /// error if it didn't work. pub fn from_der(i: &[u8]) -> Result, ASN1DecodeErr> { @@ -1072,7 +1093,7 @@ mod tests { use super::*; use chrono::offset::LocalResult; use quickcheck::{Arbitrary, Gen}; - use rand::{distributions::Standard, Rng}; + use rand::{distributions::Standard, prelude::SliceRandom, Rng}; use std::fs::File; use std::io::Read; @@ -1178,7 +1199,7 @@ mod tests { impl Arbitrary for OID { fn arbitrary(g: &mut G) -> OID { - let count = g.gen_range::(0, 40); + let count = g.gen_range::(0, 40); let val1 = g.gen::() % 3; let v2mod = if val1 == 2 { 176 } else { 40 }; let val2 = g.gen::() % v2mod; @@ -1201,7 +1222,7 @@ mod tests { } fn arb_seq(g: &mut G, d: usize) -> ASN1Block { - let count = g.gen_range::(1, 64); + let count = g.gen_range::(1, 64); let mut items = Vec::new(); for _ in 0..count { @@ -1212,7 +1233,7 @@ mod tests { } fn arb_set(g: &mut G, d: usize) -> ASN1Block { - let count = g.gen_range::(1, 64); + let count = g.gen_range::(1, 64); let mut items = Vec::new(); for _ in 0..count { @@ -1223,11 +1244,11 @@ mod tests { } fn arb_print(g: &mut G, _d: usize) -> ASN1Block { - let count = g.gen_range::(0, 384); + let count = g.gen_range::(0, 384); let mut items = Vec::new(); for _ in 0..count { - let v = g.choose(PRINTABLE_CHARS.as_bytes()).unwrap(); + let v = PRINTABLE_CHARS.as_bytes().choose(g).unwrap(); items.push(*v as char); } @@ -1235,7 +1256,7 @@ mod tests { } fn arb_ia5(g: &mut G, _d: usize) -> ASN1Block { - let count = g.gen_range::(0, 384); + let count = g.gen_range::(0, 384); let mut items = Vec::new(); for _ in 0..count { @@ -1267,15 +1288,15 @@ mod tests { fn arb_utc(g: &mut G, _d: usize) -> ASN1Block { loop { - let y = g.gen_range::(1970, 2069); - let m = g.gen_range::(1, 13); - let d = g.gen_range::(1, 32); + let y = g.gen_range::(1970, 2069); + let m = g.gen_range::(1, 13); + let d = g.gen_range::(1, 32); match Utc.ymd_opt(y, m, d) { LocalResult::None => {} LocalResult::Single(d) => { - let h = g.gen_range::(0, 24); - let m = g.gen_range::(0, 60); - let s = g.gen_range::(0, 60); + let h = g.gen_range::(0, 24); + let m = g.gen_range::(0, 60); + let s = g.gen_range::(0, 60); let t = d.and_hms(h, m, s); return ASN1Block::UTCTime(0, t); } @@ -1286,16 +1307,16 @@ mod tests { fn arb_time(g: &mut G, _d: usize) -> ASN1Block { loop { - let y = g.gen_range::(0, 10000); - let m = g.gen_range::(1, 13); - let d = g.gen_range::(1, 32); + let y = g.gen_range::(0, 10000); + let m = g.gen_range::(1, 13); + let d = g.gen_range::(1, 32); match Utc.ymd_opt(y, m, d) { LocalResult::None => {} LocalResult::Single(d) => { - let h = g.gen_range::(0, 24); - let m = g.gen_range::(0, 60); - let s = g.gen_range::(0, 60); - let n = g.gen_range::(0, 1000000000); + let h = g.gen_range::(0, 24); + let m = g.gen_range::(0, 60); + let s = g.gen_range::(0, 60); + let n = g.gen_range::(0, 1000000000); let t = d.and_hms_nano(h, m, s, n); return ASN1Block::GeneralizedTime(0, t); } @@ -1319,7 +1340,7 @@ mod tests { fn arb_unknown(g: &mut G, _d: usize) -> ASN1Block { let class = ASN1Class::arbitrary(g); let tag = RandomUint::arbitrary(g); - let size = g.gen_range::(0, 128); + let size = g.gen_range::(0, 128); let items = g.sample_iter::(&Standard).take(size).collect(); ASN1Block::Unknown(class, false, 0, tag.x, items) @@ -1350,7 +1371,7 @@ mod tests { possibles.push(arb_explicit); } - match g.choose(&possibles[..]) { + match possibles[..].choose(g) { Some(f) => f(g, d), None => panic!("Couldn't generate arbitrary value."), }