Support more string types.
This commit is contained in:
117
src/lib.rs
117
src/lib.rs
@@ -15,9 +15,12 @@ pub enum ASN1Block {
|
|||||||
OctetString(ASN1Class, Vec<u8>),
|
OctetString(ASN1Class, Vec<u8>),
|
||||||
Null(ASN1Class),
|
Null(ASN1Class),
|
||||||
ObjectIdentifier(ASN1Class, OID),
|
ObjectIdentifier(ASN1Class, OID),
|
||||||
|
TeletexString(ASN1Class, String),
|
||||||
|
PrintableString(ASN1Class, String),
|
||||||
|
UniversalString(ASN1Class, String),
|
||||||
IA5String(ASN1Class, String),
|
IA5String(ASN1Class, String),
|
||||||
UTF8String(ASN1Class, String),
|
UTF8String(ASN1Class, String),
|
||||||
PrintableString(ASN1Class, String),
|
BMPString(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>)
|
||||||
@@ -191,11 +194,38 @@ pub fn from_der(i: &[u8]) -> Result<Vec<ASN1Block>,ASN1DecodeErr> {
|
|||||||
}
|
}
|
||||||
result.push(ASN1Block::PrintableString(class, res));
|
result.push(ASN1Block::PrintableString(class, res));
|
||||||
}
|
}
|
||||||
|
// TELETEX STRINGS
|
||||||
|
Some(0x14) => {
|
||||||
|
match String::from_utf8(body.to_vec()) {
|
||||||
|
Ok(v) =>
|
||||||
|
result.push(ASN1Block::TeletexString(class, v)),
|
||||||
|
Err(_) =>
|
||||||
|
return Err(ASN1DecodeErr::UTF8DecodeFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
// 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)))
|
result.push(ASN1Block::IA5String(class, String::from_iter(val)))
|
||||||
}
|
}
|
||||||
|
// UNIVERSAL STRINGS
|
||||||
|
Some(0x1C) => {
|
||||||
|
match String::from_utf8(body.to_vec()) {
|
||||||
|
Ok(v) =>
|
||||||
|
result.push(ASN1Block::UniversalString(class, v)),
|
||||||
|
Err(_) =>
|
||||||
|
return Err(ASN1DecodeErr::UTF8DecodeFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// UNIVERSAL STRINGS
|
||||||
|
Some(0x1E) => {
|
||||||
|
match String::from_utf8(body.to_vec()) {
|
||||||
|
Ok(v) =>
|
||||||
|
result.push(ASN1Block::BMPString(class, v)),
|
||||||
|
Err(_) =>
|
||||||
|
return Err(ASN1DecodeErr::UTF8DecodeFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
// Dunno.
|
// Dunno.
|
||||||
_ => {
|
_ => {
|
||||||
result.push(ASN1Block::Unknown(class, tag, body.to_vec()));
|
result.push(ASN1Block::Unknown(class, tag, body.to_vec()));
|
||||||
@@ -427,55 +457,18 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
|
|||||||
res.append(&mut body);
|
res.append(&mut body);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
// PrintableString
|
&ASN1Block::UTF8String(cl, ref str) =>
|
||||||
&ASN1Block::PrintableString(cl, ref str) => {
|
encode_asn1_string(0x0c, false, cl, str),
|
||||||
let mut body = Vec::new();
|
&ASN1Block::PrintableString(cl, ref str) =>
|
||||||
|
encode_asn1_string(0x13, true, cl, str),
|
||||||
for c in str.chars() {
|
&ASN1Block::TeletexString(cl, ref str) =>
|
||||||
body.push(c as u8);
|
encode_asn1_string(0x14, false, cl, str),
|
||||||
}
|
&ASN1Block::UniversalString(cl, ref str) =>
|
||||||
|
encode_asn1_string(0x1c, false, cl, str),
|
||||||
let inttag = BigUint::from_u8(0x13).unwrap();
|
&ASN1Block::IA5String(cl, ref str) =>
|
||||||
let mut lenbytes = encode_len(body.len());
|
encode_asn1_string(0x16, true, cl, str),
|
||||||
let mut tagbytes = encode_tag(cl, &inttag);
|
&ASN1Block::BMPString(cl, ref str) =>
|
||||||
|
encode_asn1_string(0x1e, false, cl, str),
|
||||||
let mut res = Vec::new();
|
|
||||||
res.append(&mut tagbytes);
|
|
||||||
res.append(&mut lenbytes);
|
|
||||||
res.append(&mut body);
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
// IA5String
|
|
||||||
&ASN1Block::IA5String(cl, ref str) => {
|
|
||||||
let mut body = Vec::new();
|
|
||||||
|
|
||||||
for c in str.chars() {
|
|
||||||
body.push(c as u8);
|
|
||||||
}
|
|
||||||
|
|
||||||
let inttag = BigUint::from_u8(0x16).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)
|
|
||||||
}
|
|
||||||
// UTF8STRING
|
|
||||||
&ASN1Block::UTF8String(cl, ref val) => {
|
|
||||||
let mut body = val.clone().into_bytes();
|
|
||||||
let inttag = BigUint::from_u8(0x0C).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)
|
|
||||||
}
|
|
||||||
// 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);
|
||||||
@@ -490,6 +483,30 @@ pub fn to_der(i: &ASN1Block) -> Result<Vec<u8>,ASN1EncodeErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_asn1_string(tag: u8, force_chars: bool, c: ASN1Class, s: &String)
|
||||||
|
-> Result<Vec<u8>,ASN1EncodeErr>
|
||||||
|
{
|
||||||
|
let mut body = { if force_chars {
|
||||||
|
let mut out = Vec::new();
|
||||||
|
|
||||||
|
for c in s.chars() {
|
||||||
|
out.push(c as u8);
|
||||||
|
}
|
||||||
|
out
|
||||||
|
} else {
|
||||||
|
s.clone().into_bytes()
|
||||||
|
} };
|
||||||
|
let inttag = BigUint::from_u8(tag).unwrap();
|
||||||
|
let mut lenbytes = encode_len(body.len());
|
||||||
|
let mut tagbytes = encode_tag(c, &inttag);
|
||||||
|
|
||||||
|
let mut res = Vec::new();
|
||||||
|
res.append(&mut tagbytes);
|
||||||
|
res.append(&mut lenbytes);
|
||||||
|
res.append(&mut body);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_tag(c: ASN1Class, t: &BigUint) -> Vec<u8> {
|
fn encode_tag(c: ASN1Class, t: &BigUint) -> Vec<u8> {
|
||||||
let cbyte = encode_class(c);
|
let cbyte = encode_class(c);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user