Add the ability to capture start indexes of components, and variants of FromASN1 that require the body contents.

This commit is contained in:
2017-12-21 21:44:06 -08:00
parent 5e8dde500e
commit c6a7d3039c

View File

@@ -9,25 +9,85 @@ use num::{BigInt,BigUint,FromPrimitive,One,ToPrimitive,Zero};
use std::iter::FromIterator; use std::iter::FromIterator;
use std::mem::size_of; use std::mem::size_of;
#[derive(Clone,Debug,PartialEq)] #[derive(Clone,Debug)]
pub enum ASN1Block { pub enum ASN1Block {
Boolean(ASN1Class, bool), Boolean(ASN1Class, usize, bool),
Integer(ASN1Class, BigInt), Integer(ASN1Class, usize, BigInt),
BitString(ASN1Class, usize, Vec<u8>), BitString(ASN1Class, usize, usize, Vec<u8>),
OctetString(ASN1Class, Vec<u8>), OctetString(ASN1Class, usize, Vec<u8>),
Null(ASN1Class), Null(ASN1Class, usize),
ObjectIdentifier(ASN1Class, OID), ObjectIdentifier(ASN1Class, usize, OID),
UTF8String(ASN1Class, String), UTF8String(ASN1Class, usize, String),
PrintableString(ASN1Class, String), PrintableString(ASN1Class, usize, String),
TeletexString(ASN1Class, String), TeletexString(ASN1Class, usize, String),
IA5String(ASN1Class, String), IA5String(ASN1Class, usize, String),
UTCTime(ASN1Class, DateTime<Utc>), UTCTime(ASN1Class, usize, DateTime<Utc>),
GeneralizedTime(ASN1Class, DateTime<Utc>), GeneralizedTime(ASN1Class, usize, DateTime<Utc>),
UniversalString(ASN1Class, String), UniversalString(ASN1Class, usize, String),
BMPString(ASN1Class, String), BMPString(ASN1Class, usize, String),
Sequence(ASN1Class, Vec<ASN1Block>), Sequence(ASN1Class, usize, Vec<ASN1Block>),
Set(ASN1Class, Vec<ASN1Block>), Set(ASN1Class, usize, Vec<ASN1Block>),
Unknown(ASN1Class, BigUint, Vec<u8>) Unknown(ASN1Class, usize, BigUint, Vec<u8>)
}
impl PartialEq for ASN1Block {
fn eq(&self, other: &ASN1Block) -> bool {
match (self, other) {
(&ASN1Block::Boolean(a1,_,b1),
&ASN1Block::Boolean(a2,_,b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::Integer(a1,_,ref b1),
&ASN1Block::Integer(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::BitString(a1,_,b1,ref c1),
&ASN1Block::BitString(a2,_,b2,ref c2)) =>
(a1 == a2) && (b1 == b2) && (c1 == c2),
(&ASN1Block::OctetString(a1,_,ref b1),
&ASN1Block::OctetString(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::Null(a1,_),
&ASN1Block::Null(a2,_)) =>
(a1 == a2),
(&ASN1Block::ObjectIdentifier(a1,_,ref b1),
&ASN1Block::ObjectIdentifier(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::UTF8String(a1,_,ref b1),
&ASN1Block::UTF8String(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::PrintableString(a1,_,ref b1),
&ASN1Block::PrintableString(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::TeletexString(a1,_,ref b1),
&ASN1Block::TeletexString(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::IA5String(a1,_,ref b1),
&ASN1Block::IA5String(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::UTCTime(a1,_,ref b1),
&ASN1Block::UTCTime(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::GeneralizedTime(a1,_,ref b1),
&ASN1Block::GeneralizedTime(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::UniversalString(a1,_,ref b1),
&ASN1Block::UniversalString(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::BMPString(a1,_,ref b1),
&ASN1Block::BMPString(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::Sequence(a1,_,ref b1),
&ASN1Block::Sequence(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::Set(a1,_,ref b1),
&ASN1Block::Set(a2,_,ref b2)) =>
(a1 == a2) && (b1 == b2),
(&ASN1Block::Unknown(a1,_,ref b1,ref c1),
&ASN1Block::Unknown(a2,_,ref b2,ref c2)) =>
(a1 == a2) && (b1 == b2) && (c1 == c2),
_ =>
false
}
}
} }
#[derive(Clone,Debug,PartialEq)] #[derive(Clone,Debug,PartialEq)]
@@ -94,11 +154,18 @@ pub enum ASN1EncodeErr {
} }
pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> { pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
from_der_(i, 0)
}
fn from_der_(i: &[u8], start_offset: usize)
-> Result<Vec<ASN1Block>,ASN1DecodeErr>
{
let mut result: Vec<ASN1Block> = Vec::new(); let mut result: Vec<ASN1Block> = Vec::new();
let mut index: usize = 0; let mut index: usize = 0;
let len = i.len(); let len = i.len();
while index < len { while index < len {
let soff = start_offset + index;
let (tag, class) = decode_tag(i, &mut index); let (tag, class) = decode_tag(i, &mut index);
let len = decode_length(i, &mut index)?; let len = decode_length(i, &mut index)?;
let body = &i[index .. (index + len)]; let body = &i[index .. (index + len)];
@@ -109,29 +176,29 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
if len != 1 { if len != 1 {
return Err(ASN1DecodeErr::BadBooleanLength); return Err(ASN1DecodeErr::BadBooleanLength);
} }
result.push(ASN1Block::Boolean(class, body[0] != 0)); result.push(ASN1Block::Boolean(class, soff, body[0] != 0));
} }
// INTEGER // INTEGER
Some(0x02) => { Some(0x02) => {
let res = BigInt::from_signed_bytes_be(&body); let res = BigInt::from_signed_bytes_be(&body);
result.push(ASN1Block::Integer(class, res)); result.push(ASN1Block::Integer(class, soff, res));
} }
// BIT STRING // BIT STRING
Some(0x03) if body.len() == 0 => { Some(0x03) if body.len() == 0 => {
result.push(ASN1Block::BitString(class, 0, Vec::new())) result.push(ASN1Block::BitString(class, soff, 0, Vec::new()))
} }
Some(0x03) => { Some(0x03) => {
let bits = (&body[1..]).to_vec(); let bits = (&body[1..]).to_vec();
let nbits = (bits.len() * 8) - (body[0] as usize); let nbits = (bits.len() * 8) - (body[0] as usize);
result.push(ASN1Block::BitString(class, nbits, bits)); result.push(ASN1Block::BitString(class, soff, nbits, bits))
} }
// OCTET STRING // OCTET STRING
Some(0x04) => { Some(0x04) => {
result.push(ASN1Block::OctetString(class, body.to_vec())); result.push(ASN1Block::OctetString(class, soff, body.to_vec()))
} }
// NULL // NULL
Some(0x05) => { Some(0x05) => {
result.push(ASN1Block::Null(class)); result.push(ASN1Block::Null(class, soff));
} }
// OBJECT IDENTIFIER // OBJECT IDENTIFIER
Some(0x06) => { Some(0x06) => {
@@ -155,32 +222,33 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
while bindex < body.len() { while bindex < body.len() {
oidres.push(decode_base127(body, &mut bindex)); oidres.push(decode_base127(body, &mut bindex));
} }
let res = OID(oidres);
result.push(ASN1Block::ObjectIdentifier(class, OID(oidres))); result.push(ASN1Block::ObjectIdentifier(class, soff, res))
} }
// UTF8STRING // UTF8STRING
Some(0x0C) => { Some(0x0C) => {
match String::from_utf8(body.to_vec()) { match String::from_utf8(body.to_vec()) {
Ok(v) => Ok(v) =>
result.push(ASN1Block::UTF8String(class, v)), result.push(ASN1Block::UTF8String(class, soff, v)),
Err(_) => Err(_) =>
return Err(ASN1DecodeErr::UTF8DecodeFailure) return Err(ASN1DecodeErr::UTF8DecodeFailure)
} }
} }
// SEQUENCE // SEQUENCE
Some(0x10) => { Some(0x10) => {
match from_der(body) { match from_der_(body, start_offset + index) {
Ok(items) => Ok(items) =>
result.push(ASN1Block::Sequence(class, items)), result.push(ASN1Block::Sequence(class, soff, items)),
Err(e) => Err(e) =>
return Err(e) return Err(e)
} }
} }
// SET // SET
Some(0x11) => { Some(0x11) => {
match from_der(body) { match from_der_(body, start_offset + index) {
Ok(items) => Ok(items) =>
result.push(ASN1Block::Set(class, items)), result.push(ASN1Block::Set(class, soff, items)),
Err(e) => Err(e) =>
return Err(e) return Err(e)
} }
@@ -197,13 +265,13 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
return Err(ASN1DecodeErr::PrintableStringDecodeFailure); return Err(ASN1DecodeErr::PrintableStringDecodeFailure);
} }
} }
result.push(ASN1Block::PrintableString(class, res)); result.push(ASN1Block::PrintableString(class, soff, res));
} }
// TELETEX STRINGS // TELETEX STRINGS
Some(0x14) => { Some(0x14) => {
match String::from_utf8(body.to_vec()) { match String::from_utf8(body.to_vec()) {
Ok(v) => Ok(v) =>
result.push(ASN1Block::TeletexString(class, v)), result.push(ASN1Block::TeletexString(class, soff, v)),
Err(_) => Err(_) =>
return Err(ASN1DecodeErr::UTF8DecodeFailure) return Err(ASN1DecodeErr::UTF8DecodeFailure)
} }
@@ -211,7 +279,8 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
// IA5 (ASCII) STRING // IA5 (ASCII) STRING
Some(0x16) => { Some(0x16) => {
let val = body.iter().map(|x| *x as char); let val = body.iter().map(|x| *x as char);
result.push(ASN1Block::IA5String(class, String::from_iter(val))) let res = String::from_iter(val);
result.push(ASN1Block::IA5String(class, soff, res))
} }
// UTCTime // UTCTime
Some(0x17) => { Some(0x17) => {
@@ -224,7 +293,7 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
Err(_) => Err(_) =>
return Err(ASN1DecodeErr::InvalidDateValue(v)), return Err(ASN1DecodeErr::InvalidDateValue(v)),
Ok(t) => { Ok(t) => {
result.push(ASN1Block::UTCTime(class, t)) result.push(ASN1Block::UTCTime(class, soff, t))
} }
} }
} }
@@ -243,12 +312,11 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
let idx = v.len() - 1; let idx = v.len() - 1;
v.insert(idx, '0'); v.insert(idx, '0');
} }
// FIXME (?): Zero padding
match Utc.datetime_from_str(&v, "%Y%m%d%H%M%S.%fZ") { match Utc.datetime_from_str(&v, "%Y%m%d%H%M%S.%fZ") {
Err(_) => Err(_) =>
return Err(ASN1DecodeErr::InvalidDateValue(v)), return Err(ASN1DecodeErr::InvalidDateValue(v)),
Ok(t) => { Ok(t) => {
result.push(ASN1Block::GeneralizedTime(class, t)) result.push(ASN1Block::GeneralizedTime(class, soff, t))
} }
} }
} }
@@ -256,7 +324,7 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
Some(0x1C) => { Some(0x1C) => {
match String::from_utf8(body.to_vec()) { match String::from_utf8(body.to_vec()) {
Ok(v) => Ok(v) =>
result.push(ASN1Block::UniversalString(class, v)), result.push(ASN1Block::UniversalString(class, soff, v)),
Err(_) => Err(_) =>
return Err(ASN1DecodeErr::UTF8DecodeFailure) return Err(ASN1DecodeErr::UTF8DecodeFailure)
} }
@@ -265,14 +333,14 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
Some(0x1E) => { Some(0x1E) => {
match String::from_utf8(body.to_vec()) { match String::from_utf8(body.to_vec()) {
Ok(v) => Ok(v) =>
result.push(ASN1Block::BMPString(class, v)), result.push(ASN1Block::BMPString(class, soff, v)),
Err(_) => Err(_) =>
return Err(ASN1DecodeErr::UTF8DecodeFailure) return Err(ASN1DecodeErr::UTF8DecodeFailure)
} }
} }
// Dunno. // Dunno.
_ => { _ => {
result.push(ASN1Block::Unknown(class, tag, body.to_vec())); result.push(ASN1Block::Unknown(class, soff, tag, body.to_vec()));
} }
} }
index += len; index += len;
@@ -355,7 +423,7 @@ fn decode_length(i: &[u8], index: &mut usize) -> Result<usize,ASN1DecodeErr> {
pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> { pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
match i { match i {
// BOOLEAN // BOOLEAN
&ASN1Block::Boolean(cl, val) => { &ASN1Block::Boolean(cl, _, val) => {
let inttag = BigUint::one(); let inttag = BigUint::one();
let mut tagbytes = encode_tag(cl, &inttag); let mut tagbytes = encode_tag(cl, &inttag);
tagbytes.push(1); tagbytes.push(1);
@@ -363,7 +431,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
Ok(tagbytes) Ok(tagbytes)
} }
// INTEGER // INTEGER
&ASN1Block::Integer(cl, ref int) => { &ASN1Block::Integer(cl, _, ref int) => {
let mut base = int.to_signed_bytes_be(); let mut base = int.to_signed_bytes_be();
let mut lenbytes = encode_len(base.len()); let mut lenbytes = encode_len(base.len());
let inttag = BigUint::from_u8(0x02).unwrap(); let inttag = BigUint::from_u8(0x02).unwrap();
@@ -376,7 +444,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
Ok(result) Ok(result)
} }
// BIT STRING // BIT STRING
&ASN1Block::BitString(cl, bits, ref vs) => { &ASN1Block::BitString(cl, _, bits, ref vs) => {
let inttag = BigUint::from_u8(0x03).unwrap(); let inttag = BigUint::from_u8(0x03).unwrap();
let mut tagbytes = encode_tag(cl, &inttag); let mut tagbytes = encode_tag(cl, &inttag);
@@ -396,7 +464,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
} }
} }
// OCTET STRING // OCTET STRING
&ASN1Block::OctetString(cl, ref bytes) => { &ASN1Block::OctetString(cl, _, ref bytes) => {
let inttag = BigUint::from_u8(0x04).unwrap(); let inttag = BigUint::from_u8(0x04).unwrap();
let mut tagbytes = encode_tag(cl, &inttag); let mut tagbytes = encode_tag(cl, &inttag);
let mut lenbytes = encode_len(bytes.len()); let mut lenbytes = encode_len(bytes.len());
@@ -408,14 +476,14 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
Ok(result) Ok(result)
} }
// NULL // NULL
&ASN1Block::Null(cl) => { &ASN1Block::Null(cl, _) => {
let inttag = BigUint::from_u8(0x05).unwrap(); let inttag = BigUint::from_u8(0x05).unwrap();
let mut result = encode_tag(cl, &inttag); let mut result = encode_tag(cl, &inttag);
result.push(0); result.push(0);
Ok(result) Ok(result)
} }
// OBJECT IDENTIFIER // OBJECT IDENTIFIER
&ASN1Block::ObjectIdentifier(cl, OID(ref nums)) => { &ASN1Block::ObjectIdentifier(cl, _, OID(ref nums)) => {
match (nums.get(0), nums.get(1)) { match (nums.get(0), nums.get(1)) {
(Some(v1), Some(v2)) => { (Some(v1), Some(v2)) => {
let two = BigUint::from_u8(2).unwrap(); let two = BigUint::from_u8(2).unwrap();
@@ -462,7 +530,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
} }
} }
// SEQUENCE // SEQUENCE
&ASN1Block::Sequence(cl, ref items) => { &ASN1Block::Sequence(cl, _, ref items) => {
let mut body = Vec::new(); let mut body = Vec::new();
// put all the subsequences into a block // put all the subsequences into a block
@@ -482,7 +550,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
Ok(res) Ok(res)
} }
// SET // SET
&ASN1Block::Set(cl, ref items) => { &ASN1Block::Set(cl, _, ref items) => {
let mut body = Vec::new(); let mut body = Vec::new();
// put all the subsequences into a block // put all the subsequences into a block
@@ -501,7 +569,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
res.append(&mut body); res.append(&mut body);
Ok(res) Ok(res)
} }
&ASN1Block::UTCTime(cl, ref time) => { &ASN1Block::UTCTime(cl, _, ref time) => {
let mut body = time.format("%y%m%d%H%M%SZ").to_string().into_bytes(); let mut body = time.format("%y%m%d%H%M%SZ").to_string().into_bytes();
let inttag = BigUint::from_u8(0x17).unwrap(); let inttag = BigUint::from_u8(0x17).unwrap();
let mut lenbytes = encode_len(body.len()); let mut lenbytes = encode_len(body.len());
@@ -513,7 +581,7 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
res.append(&mut body); res.append(&mut body);
Ok(res) Ok(res)
} }
&ASN1Block::GeneralizedTime(cl, ref time) => { &ASN1Block::GeneralizedTime(cl, _, ref time) => {
let base = time.format("%Y%m%d%H%M%S.%f").to_string(); let base = time.format("%Y%m%d%H%M%S.%f").to_string();
let zclear = base.trim_right_matches('0'); let zclear = base.trim_right_matches('0');
let dclear = zclear.trim_right_matches('.'); let dclear = zclear.trim_right_matches('.');
@@ -529,20 +597,20 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
res.append(&mut body); res.append(&mut body);
Ok(res) Ok(res)
} }
&ASN1Block::UTF8String(cl, ref str) => &ASN1Block::UTF8String(cl, _, ref str) =>
encode_asn1_string(0x0c, false, cl, str), encode_asn1_string(0x0c, false, cl, str),
&ASN1Block::PrintableString(cl, ref str) => &ASN1Block::PrintableString(cl, _, ref str) =>
encode_asn1_string(0x13, true, cl, str), encode_asn1_string(0x13, true, cl, str),
&ASN1Block::TeletexString(cl, ref str) => &ASN1Block::TeletexString(cl, _, ref str) =>
encode_asn1_string(0x14, false, cl, str), encode_asn1_string(0x14, false, cl, str),
&ASN1Block::UniversalString(cl, ref str) => &ASN1Block::UniversalString(cl, _, ref str) =>
encode_asn1_string(0x1c, false, cl, str), encode_asn1_string(0x1c, false, cl, str),
&ASN1Block::IA5String(cl, ref str) => &ASN1Block::IA5String(cl, _, ref str) =>
encode_asn1_string(0x16, true, cl, str), encode_asn1_string(0x16, true, cl, str),
&ASN1Block::BMPString(cl, ref str) => &ASN1Block::BMPString(cl, _, ref str) =>
encode_asn1_string(0x1e, false, cl, str), encode_asn1_string(0x1e, false, cl, str),
// Unknown blocks // Unknown blocks
&ASN1Block::Unknown(class, ref tag, ref bytes) => { &ASN1Block::Unknown(class, _, ref tag, ref bytes) => {
let mut tagbytes = encode_tag(class, &tag); let mut tagbytes = encode_tag(class, &tag);
let mut lenbytes = encode_len(bytes.len()); let mut lenbytes = encode_len(bytes.len());
@@ -654,16 +722,34 @@ fn encode_len(x: usize) -> Vec<u8> {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
pub trait FromASN1WithBody : Sized {
type Error : From<ASN1DecodeErr>;
fn from_asn1_with_body<'a>(v: &'a[ASN1Block], _b: &[u8])
-> Result<(Self,&'a[ASN1Block]),Self::Error>;
}
pub trait FromASN1 : Sized { pub trait FromASN1 : Sized {
type Error : From<ASN1DecodeErr>; type Error : From<ASN1DecodeErr>;
fn from_asn1(v: &[ASN1Block]) -> Result<(Self,&[ASN1Block]),Self::Error>; fn from_asn1(v: &[ASN1Block])
-> Result<(Self,&[ASN1Block]),Self::Error>;
} }
pub fn der_decode<T: FromASN1>(v: &[u8]) -> Result<T,T::Error> impl<T: FromASN1> FromASN1WithBody for T {
type Error = T::Error;
fn from_asn1_with_body<'a>(v: &'a[ASN1Block], _b: &[u8])
-> Result<(T,&'a[ASN1Block]),T::Error>
{
T::from_asn1(v)
}
}
pub fn der_decode<T: FromASN1WithBody>(v: &[u8]) -> Result<T,T::Error>
{ {
let vs = from_der(v)?; let vs = from_der(v)?;
T::from_asn1(&vs).and_then(|(a,_)| Ok(a)) T::from_asn1_with_body(&vs, v).and_then(|(a,_)| Ok(a))
} }
pub trait ToASN1 { pub trait ToASN1 {
@@ -768,13 +854,13 @@ mod tests {
fn arb_boolean<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_boolean<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let c = ASN1Class::arbitrary(g); let c = ASN1Class::arbitrary(g);
let v = g.gen::<bool>(); let v = g.gen::<bool>();
ASN1Block::Boolean(c, v) ASN1Block::Boolean(c, 0, v)
} }
fn arb_integer<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_integer<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let c = ASN1Class::arbitrary(g); let c = ASN1Class::arbitrary(g);
let d = RandomInt::arbitrary(g); let d = RandomInt::arbitrary(g);
ASN1Block::Integer(c, d.x) ASN1Block::Integer(c, 0, d.x)
} }
fn arb_bitstr<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_bitstr<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
@@ -786,19 +872,19 @@ mod tests {
{ maxbits } { maxbits }
else { maxbits - modbits }; else { maxbits - modbits };
let bytes = g.gen_iter::<u8>().take(size).collect(); let bytes = g.gen_iter::<u8>().take(size).collect();
ASN1Block::BitString(class, nbits, bytes) ASN1Block::BitString(class, 0, nbits, bytes)
} }
fn arb_octstr<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_octstr<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
let size = g.gen::<u16>() as usize % 16; let size = g.gen::<u16>() as usize % 16;
let bytes = g.gen_iter::<u8>().take(size).collect(); let bytes = g.gen_iter::<u8>().take(size).collect();
ASN1Block::OctetString(class, bytes) ASN1Block::OctetString(class, 0, bytes)
} }
fn arb_null<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_null<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
ASN1Block::Null(class) ASN1Block::Null(class, 0)
} }
impl Arbitrary for OID { impl Arbitrary for OID {
@@ -823,7 +909,7 @@ mod tests {
fn arb_objid<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_objid<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
let oid = OID::arbitrary(g); let oid = OID::arbitrary(g);
ASN1Block::ObjectIdentifier(class, oid) ASN1Block::ObjectIdentifier(class, 0, oid)
} }
fn arb_seq<G: Gen>(g: &mut G, d: usize) -> ASN1Block { fn arb_seq<G: Gen>(g: &mut G, d: usize) -> ASN1Block {
@@ -835,7 +921,7 @@ mod tests {
items.push(limited_arbitrary(g, d - 1)); items.push(limited_arbitrary(g, d - 1));
} }
ASN1Block::Sequence(class, items) ASN1Block::Sequence(class, 0, items)
} }
fn arb_set<G: Gen>(g: &mut G, d: usize) -> ASN1Block { fn arb_set<G: Gen>(g: &mut G, d: usize) -> ASN1Block {
@@ -847,7 +933,7 @@ mod tests {
items.push(limited_arbitrary(g, d - 1)); items.push(limited_arbitrary(g, d - 1));
} }
ASN1Block::Set(class, items) ASN1Block::Set(class, 0, items)
} }
fn arb_print<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_print<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
@@ -860,7 +946,7 @@ mod tests {
items.push(*v as char); items.push(*v as char);
} }
ASN1Block::PrintableString(class, String::from_iter(items.iter())) ASN1Block::PrintableString(class, 0, String::from_iter(items.iter()))
} }
fn arb_ia5<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_ia5<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
@@ -872,31 +958,31 @@ mod tests {
items.push(g.gen::<u8>() as char); items.push(g.gen::<u8>() as char);
} }
ASN1Block::IA5String(class, String::from_iter(items.iter())) ASN1Block::IA5String(class, 0, String::from_iter(items.iter()))
} }
fn arb_utf8<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_utf8<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
let val = String::arbitrary(g); let val = String::arbitrary(g);
ASN1Block::UTF8String(class, val) ASN1Block::UTF8String(class, 0, val)
} }
fn arb_tele<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_tele<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
let val = String::arbitrary(g); let val = String::arbitrary(g);
ASN1Block::TeletexString(class, val) ASN1Block::TeletexString(class, 0, val)
} }
fn arb_uni<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_uni<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
let val = String::arbitrary(g); let val = String::arbitrary(g);
ASN1Block::UniversalString(class, val) ASN1Block::UniversalString(class, 0, val)
} }
fn arb_bmp<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_bmp<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
let class = ASN1Class::arbitrary(g); let class = ASN1Class::arbitrary(g);
let val = String::arbitrary(g); let val = String::arbitrary(g);
ASN1Block::BMPString(class, val) ASN1Block::BMPString(class, 0, val)
} }
fn arb_utc<G: Gen>(g: &mut G, _d: usize) -> ASN1Block { fn arb_utc<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
@@ -913,7 +999,7 @@ mod tests {
let m = g.gen_range::<u32>(0,60); let m = g.gen_range::<u32>(0,60);
let s = g.gen_range::<u32>(0,60); let s = g.gen_range::<u32>(0,60);
let t = d.and_hms(h,m,s); let t = d.and_hms(h,m,s);
return ASN1Block::UTCTime(class, t); return ASN1Block::UTCTime(class, 0, t);
} }
LocalResult::Ambiguous(_,_) => {} LocalResult::Ambiguous(_,_) => {}
} }
@@ -935,7 +1021,7 @@ mod tests {
let s = g.gen_range::<u32>(0,60); let s = g.gen_range::<u32>(0,60);
let n = g.gen_range::<u32>(0,1000000000); let n = g.gen_range::<u32>(0,1000000000);
let t = d.and_hms_nano(h,m,s,n); let t = d.and_hms_nano(h,m,s,n);
return ASN1Block::GeneralizedTime(class, t); return ASN1Block::GeneralizedTime(class, 0, t);
} }
LocalResult::Ambiguous(_,_) => {} LocalResult::Ambiguous(_,_) => {}
} }
@@ -948,7 +1034,7 @@ mod tests {
let size = g.gen_range::<usize>(0, 128); let size = g.gen_range::<usize>(0, 128);
let items = g.gen_iter::<u8>().take(size).collect(); let items = g.gen_iter::<u8>().take(size).collect();
ASN1Block::Unknown(class, tag.x, items) ASN1Block::Unknown(class, 0, tag.x, items)
} }
fn limited_arbitrary<G: Gen>(g: &mut G, d: usize) -> ASN1Block { fn limited_arbitrary<G: Gen>(g: &mut G, d: usize) -> ASN1Block {
@@ -1018,7 +1104,7 @@ mod tests {
fn result_int(v: i16) -> Result<Vec<ASN1Block>,ASN1DecodeErr> { fn result_int(v: i16) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
let val = BigInt::from(v); let val = BigInt::from(v);
Ok(vec![ASN1Block::Integer(ASN1Class::Universal, val)]) Ok(vec![ASN1Block::Integer(ASN1Class::Universal, 0, val)])
} }
#[test] #[test]
@@ -1032,7 +1118,7 @@ mod tests {
} }
fn check_spec(d: &DateTime<Utc>, s: String) { fn check_spec(d: &DateTime<Utc>, s: String) {
let b = ASN1Block::GeneralizedTime(ASN1Class::Universal, d.clone()); let b = ASN1Block::GeneralizedTime(ASN1Class::Universal, 0, d.clone());
match to_der(&b) { match to_der(&b) {
Err(_) => assert_eq!(format!("Broken: {}", d), s), Err(_) => assert_eq!(format!("Broken: {}", d), s),
Ok(ref vec) => { Ok(ref vec) => {