Add support for printable strings.
This commit is contained in:
52
src/lib.rs
52
src/lib.rs
@@ -17,6 +17,7 @@ pub enum ASN1Block {
|
|||||||
ObjectIdentifier(ASN1Class, OID),
|
ObjectIdentifier(ASN1Class, OID),
|
||||||
IA5String(ASN1Class, String),
|
IA5String(ASN1Class, String),
|
||||||
UTF8String(ASN1Class, String),
|
UTF8String(ASN1Class, String),
|
||||||
|
PrintableString(ASN1Class, String),
|
||||||
Sequence(ASN1Class, Vec<ASN1Block>),
|
Sequence(ASN1Class, Vec<ASN1Block>),
|
||||||
Set(ASN1Class, Vec<ASN1Block>),
|
Set(ASN1Class, Vec<ASN1Block>),
|
||||||
Unknown(ASN1Class, BigUint, Vec<u8>)
|
Unknown(ASN1Class, BigUint, Vec<u8>)
|
||||||
@@ -62,6 +63,8 @@ macro_rules! oid {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PRINTABLE_CHARS: &'static str =
|
||||||
|
"ABCDEFGHIJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'()+,-./:=? ";
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug,PartialEq)]
|
#[derive(Clone,Copy,Debug,PartialEq)]
|
||||||
pub enum ASN1Class { Universal, Application, ContextSpecific, Private }
|
pub enum ASN1Class { Universal, Application, ContextSpecific, Private }
|
||||||
@@ -71,7 +74,8 @@ pub enum ASN1DecodeErr {
|
|||||||
EmptyBuffer,
|
EmptyBuffer,
|
||||||
BadBooleanLength,
|
BadBooleanLength,
|
||||||
LengthTooLarge,
|
LengthTooLarge,
|
||||||
UTF8DecodeFailure
|
UTF8DecodeFailure,
|
||||||
|
PrintableStringDecodeFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Debug,PartialEq)]
|
#[derive(Clone,Debug,PartialEq)]
|
||||||
@@ -173,6 +177,20 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
|
|||||||
return Err(e)
|
return Err(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// PRINTABLE STRING
|
||||||
|
Some(0x13) => {
|
||||||
|
let mut res = String::new();
|
||||||
|
let mut val = body.iter().map(|x| *x as char);
|
||||||
|
|
||||||
|
for c in val {
|
||||||
|
if PRINTABLE_CHARS.contains(c) {
|
||||||
|
res.push(c);
|
||||||
|
} else {
|
||||||
|
return Err(ASN1DecodeErr::PrintableStringDecodeFailure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push(ASN1Block::PrintableString(class, res));
|
||||||
|
}
|
||||||
// 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);
|
||||||
@@ -409,6 +427,24 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
|
|||||||
res.append(&mut body);
|
res.append(&mut body);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
// PrintableString
|
||||||
|
&ASN1Block::PrintableString(cl, ref str) => {
|
||||||
|
let mut body = Vec::new();
|
||||||
|
|
||||||
|
for c in str.chars() {
|
||||||
|
body.push(c as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
let inttag = BigUint::from_u8(0x13).unwrap();
|
||||||
|
let mut lenbytes = encode_len(body.len());
|
||||||
|
let mut tagbytes = encode_tag(cl, &inttag);
|
||||||
|
|
||||||
|
let mut res = Vec::new();
|
||||||
|
res.append(&mut tagbytes);
|
||||||
|
res.append(&mut lenbytes);
|
||||||
|
res.append(&mut body);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
// IA5String
|
// IA5String
|
||||||
&ASN1Block::IA5String(cl, ref str) => {
|
&ASN1Block::IA5String(cl, ref str) => {
|
||||||
let mut body = Vec::new();
|
let mut body = Vec::new();
|
||||||
@@ -724,6 +760,19 @@ mod tests {
|
|||||||
ASN1Block::Set(class, items)
|
ASN1Block::Set(class, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn arb_print<G: Gen>(g: &mut G, _d: usize) -> ASN1Block {
|
||||||
|
let class = ASN1Class::arbitrary(g);
|
||||||
|
let count = g.gen_range::<usize>(0, 384);
|
||||||
|
let mut items = Vec::new();
|
||||||
|
|
||||||
|
for _ in 0..count {
|
||||||
|
let v = g.choose(PRINTABLE_CHARS.as_bytes()).unwrap();
|
||||||
|
items.push(*v as char);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Block::PrintableString(class, 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 {
|
||||||
let class = ASN1Class::arbitrary(g);
|
let class = ASN1Class::arbitrary(g);
|
||||||
let count = g.gen_range::<usize>(0, 384);
|
let count = g.gen_range::<usize>(0, 384);
|
||||||
@@ -759,6 +808,7 @@ mod tests {
|
|||||||
arb_octstr,
|
arb_octstr,
|
||||||
arb_null,
|
arb_null,
|
||||||
arb_objid,
|
arb_objid,
|
||||||
|
arb_print,
|
||||||
arb_ia5,
|
arb_ia5,
|
||||||
arb_utf8,
|
arb_utf8,
|
||||||
arb_unknown];
|
arb_unknown];
|
||||||
|
|||||||
Reference in New Issue
Block a user