rusticata / der-parser Goto Github PK
View Code? Open in Web Editor NEWBER/DER parser written in pure Rust. Fast, zero-copy, safe.
License: Apache License 2.0
BER/DER parser written in pure Rust. Fast, zero-copy, safe.
License: Apache License 2.0
placeholder for now, roadmap is not defined yet
Some ideas:
&[u8]
to error type ? (consequence: BerError
will now have a lifetime, but we will be able to tell where the parsing failed)Cow<'a, [u8]>
everywhere so BerObject
can own databytes
crate), or new/recursive object types (resulting in a complex API)Hi,
to the best of my knowledge string character sets are not verified currently, for example PrintableString
or IA5String
. Is this correct?
To give some background for my question, suppose I parse an utf8 string and then do std::str::from_utf
, which I then expect to succeed.
String parser functions in src/der/parser.rs are named consistently: parse_der_<stringtype>()
. But there is one exception for VisibleString, whose parser function is named visiblestring()
This seems to be a typo.
Hi,
when parsing oids the binary representation is converted to Vec<u64>
.
I propose to keep the binary representation and provide api for the conversion to Vec<u64>
(or an iterator implementation).
In my case I use oids basically only for comparison with other oids.
The downsides I see for my proposal are:
Oid
would get an lifetime parameter (users of der-parser already handle lifetimes a lot, so I don't think this is a big issue)The advantages:
Oid
becomes smaller. In particular cloning does not heap allocate which is useful if you use them in many places.u64
can be too small (?)I also propose to add a proc macro for easy construction and a Hash
implementation.
I can implement the proposed changes if you are interested.
Not a Contribution
BerObject::as_pretty()
prints universal tag names when printing BerObjectContent::Tagged
and BerObjectContent::Unknown
contents. As of 5f76d92 (see #47) it includes the class name for BerObjectContent::Unknown
, but it didn't change anything about how tags are printed.
DER: [80, 4, de, ad, be, ef]
Output: Unknown(ContextSpecific,EndOfContent,[de, ad, be, ef])
DER: [42, 4, de, ad, be, ef]
Output: Unknown(Application,Integer,[de, ad, be, ef])
If I parse tagged content, I get similarly busted output:
-- Type1 ::= VisibleString
-- Type2 ::= [APPLICATION 3] IMPLICIT Type1
-- Type3 ::= [APPLICATION 2] Type2
-- Type4 ::= [1] Type3
DER: [a1, 9, 62, 7, 43, 5, 4a, 6f, 6e, 65, 73]
Output: ContextSpecific [CONTEXT-SPECIFIC Boolean] {
ContextSpecific [APPLICATION Integer] {
VisibleString("Jones")
}
}
There's two issues here. The first is of course that it's printing universal tag names for non-universal classes. The second is that it always prints ContextSpecific
for tagged objects even for other classes.
Parsing private tags is also curious:
DER: [c3, 4, de, ad, be, ef]
Output: Private(c:PRIVATE s:0 t:3): [de ad be ef]
It's no longer trying to print the tag name, but instead it prints "Private" twice with this odd formatting. It also puts the bytes outside of the parens, whereas Unknown puts it inside.
I would expect BerObjectContent::Unknown
and BerObjectContent::Private
to print similarly. For that matter, I don't even know why Private gets its own variant whereas ContextSpecific and Application share an "Unknown" one. I would have expected either all three to get their own variants, or all three to share a variant (the latter being simpler of course).
In any case, I would have expected something like Unknown(ContextSpecific(0),[de, ad, be, ef])
and Unknown(Application(2),[de, ad, be, ef])
(note how the tag name isn't interpreted), or possibly instead formatting similar to Private
. And for tagged vales, I might expect it to say something like Tagged [CONTEXT-SPECIFIC 1]
instead.
I think the core issue here is really the fact that tags and classes are separate, and so BerTag(2)
prints automatically as Integer
regardless of the class. I would expect this to be a problem for parsing too. For example, my parser for the tagged content looks like
parse_der_tagged_explicit(1, |i| {
parse_der_tagged_explicit(2, |i| {
parse_der_tagged_implicit(3, parse_der_content(DerTag::VisibleString))(i)
})(i)
})
Notice here how my parser doesn't mention classes anywhere. It parsed [a1, 9, 62, 7, 43, 5, 4a, 6f, 6e, 65, 73]
, but it would have happily parsed [61, 9, a2, 7, 43, 5, 4a, 6f, 6e, 65, 73]
as well despite the fact that the change in class means the tags might have very different meanings.
I really think this needs to be changed such that the class and tag are a single value. This also fixes the naming issue, as ASN.1 uses "tag" to mean "class and number". So we can use something like the following:
pub struct BerTag(pub BerClass, pub u32);
It can then have a Display
impl that prints like "{class}({number})"
(Debug
can just be derived). (EDIT: Or maybe it should print like [{class} {number}]
, optionally printing ContextSpecific
like [{number}]
to match ASN.1 notation for tagged types.)
This is of course a rather significant change to the crate.
If you look at my tagged parser above, you'll notice the use of |i| parse_fn(…)(i)
. This feels redundant, but it's necessary right now because parse_der_tagged_explicit
(and similar functions) take a F: Fn
but return an impl FnMut
. This means they can't be nested without the closure wrappers. My expectation is they could be modified to take F: FnMut
rather trivially (just by adding a mut
keyword) and the fact that they don't is likely an oversight due to the fact that none of the built-in parsers use them (and the doc examples don't nest them).
You decode integers as hex strings, but they are not encoded this way. Also, the error seems to get swallowed up. I can provide more information later, but for now I've simply commented out the integer branch in der_read_element_content_as
and get these as an unknown.
Hi,
thank you for this crate!
I'm guessing that in https://docs.rs/der-parser/5.0.0/der_parser/ber/enum.BerObjectContent.html#variant.BitString
the first element of the pair is the number of unused bits, but I wanted to ask to be sure :)
Am I correct?
(maybe the doc should have an entry for each variant of BerObjectContent
?)
Thanks!
I would really like to be able to concatenate relative OIDs onto base OIDs at compile-time. I'm not sure if this is actually possible, but I want to be able to write something like
const OID_BASE: Oid = oid!(1.2.840.1234);
const OID_SUB_1: Oid = oid!(OID_BASE 10);
const OID_SUB_2: Oid = oid!(OID_SUB_1 15);
Or some alternative syntax that achieves the same thing. I don't know if there's any way to achieve this without heap allocation. I really wish Rust had built-in syntax for "please flatten this array into the enclosing array literal".
The goal here is of course to be able to represent a tree of OIDs using a similar structure to how they're declared in ASN.1, instead of having to repeat the OID base everywhere.
difference is unmaintained
Details | |
---|---|
Status | unmaintained |
Package | difference |
Version | 2.0.0 |
URL | johannhof/difference.rs#45 |
Date | 2020-12-20 |
The author of the difference
crate is unresponsive.
Maintained alternatives:
See advisory page for additional details.
BerObject
doesn't seem to have any way of actually parsing a negative ASN.1 integer as a negative number. It only exposes .as_u32()
and .as_u64()
, both of which simply assume the whole thing is unsigned (even though ASN.1 integers are signed and BER/DER-encoding represents them as two's complement integers). Because of the variable length of an integer I can't even cast the result to a signed value, as e.g. -123
encodes as [0x85]
which is then just 133
(and therefore casting to a signed integer preserves the 133
representation).
The only nod towards signed integers is the existence of .as_bigint()
in addition to .as_biguint()
. Unfortunately (and completely undocumented), the result is always a positive BigInt
, as the implementation explicitly provides the positive sign instead of using the constructor that detects the sign from the bytes.
Example:
DerObject::from_int_slice(&BigInt::from(42).to_signed_bytes_be()).as_bigint().unwrap() // returns 42
DerObject::from_int_slice(&BigInt::from(-123).to_signed_bytes_be()).as_bigint().unwrap() // returns 133
BerObjectContent::Unknown
carries the BerTag
but not the BerClass
. I don't know why this is, it seems like an oversight, but the class is stored in the BerObjectHeader
. Unfortunately, the BerObject::as_pretty()
method only prints the contents (barring the ShowHeader
flag). What's more, it prints the enum name for any BerTag
s even if they don't belong to the Universal
class. This means that my pretty-printed object is showing up containing a Sequence[Unknown(EndOfContent,[de, ad, be, ef])]
. Printing the header tells me this is actually a context-specific tag, which means it should have been printed as something like Sequence[Unknown(ContextSpecific(0),[de, ad, be, ef])]
instead.
The oid!
macro evaluates to a reference to der_parser::…
. This doesn't work if I don't have the crate in my namespace, e.g. if I'm using the macro via use x509_parser::der_parser::oid;
. If this was a macro_rules!
macro I'd say it needs to be using $crate
, I hope proc macros have an equivalent (heck, can they just use $crate
directly too?).
I wonder if you can help me parse the last 2 fields in an ecdsa ssh private key. I have working code to handle the sequence, integer, and octet string, but the final 2 fields I can't figure out how to parse with der-parser
. Here's the ASN.1 structure:
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, publicKey [1] BIT STRING OPTIONAL
}
And here's my code, with the first 2 fields of the sequence working but last 2 wrong.
fn der_read_opt_oid(i:&[u8]) -> IResult<&[u8],DerObject,u32> {
parse_der_optional!(i, parse_der_oid)
}
fn der_read_opt_bitstring(i:&[u8]) -> IResult<&[u8],DerObject,u32> {
parse_der_optional!(i, parse_der_bitstring)
}
fn parse_oid(i: &[u8]) -> IResult<&[u8], DerObject> {
parse_der_explicit(i, DerTag::Oid as u8, parse_der_oid)
}
fn parse_bits(i: &[u8]) -> IResult<&[u8], DerObject> {
parse_der_explicit(i, DerTag::BitString as u8, parse_der_bitstring)
}
fn ecdsa_private(input: &[u8]) -> Algorithm {
match parse_der_sequence_defined!(
input,
parse_der_integer,
parse_der_octetstring,
der_read_opt_oid,
der_read_opt_bitstring,
) {
IResult::Done(_unparsed_suffix, der) => {
assert_eq!(_unparsed_suffix.len(), 0);
Algorithm::Ecdsa(0)
}
IResult::Error(error) => {
eprintln!("Error {}", error);
Algorithm::Unknown
}
IResult::Incomplete(_needed) => {
eprintln!("Incomplete {:?}", _needed);
Algorithm::Unknown
}
}
}
Here is an example program and its output. From looking at the data I believe there should be many more entries in the iterator.
Program:
extern crate der_parser;
fn main() {
let bytes = [0x30, 0x82, 0x4, 0xA4, 0x2, 0x1, 0x0, 0x2, 0x82, 0x1, 0x1, 0x0, 0xD8, 0xFE, 0xA3, 0x5E, 0x24, 0x58, 0xB9, 0xF4, 0x2, 0x49, 0x54, 0xBA, 0xAA, 0xCA, 0xA6, 0x13, 0x56, 0x4B, 0x40, 0x87, 0x1F, 0x70, 0x93, 0x19, 0x8E, 0x5E, 0x6A, 0x83, 0xE6, 0xBA, 0x54, 0x3F, 0x6C, 0xEF, 0x5C, 0xA1, 0xD2, 0x1C, 0x6E, 0xD2, 0x8C, 0x37, 0x17, 0x37, 0x3B, 0xC9, 0xE8, 0x77, 0x7E, 0xF9, 0xFE, 0xDA, 0xC5, 0x45, 0xBE, 0x53, 0x25, 0x67, 0xAA, 0x6E, 0xD1, 0x15, 0x44, 0xD5, 0x6, 0x9D, 0xE2, 0xAB, 0xE7, 0x46, 0xD1, 0x25, 0x75, 0x1B, 0x90, 0x61, 0xCA, 0xB8, 0x43, 0xE, 0x83, 0xFF, 0x74, 0xEA, 0xBD, 0xEC, 0x8D, 0x56, 0xC3, 0xBB, 0x35, 0xA0, 0x25, 0xE8, 0x4B, 0xBD, 0xCB, 0xD, 0xD7, 0x34, 0x67, 0x46, 0xED, 0xEA, 0x95, 0xCA, 0xBA, 0xC5, 0x52, 0x76, 0x17, 0x27, 0x43, 0xA2, 0xA5, 0x8E, 0x8B, 0x9F, 0x2C, 0x2, 0xB3, 0x7E, 0x46, 0xEC, 0x40, 0x14, 0xAE, 0x65, 0xBE, 0xF9, 0xD1, 0xF4, 0x2, 0xB9, 0xDD, 0xB4, 0x4A, 0x9B, 0xF2, 0xE3, 0xEB, 0xF, 0xB3, 0xF6, 0x13, 0xB7, 0xF8, 0xB5, 0x4E, 0x93, 0x65, 0xA4, 0x29, 0xBD, 0x99, 0xCF, 0xCB, 0xF3, 0xD5, 0x59, 0x47, 0xBC, 0x93, 0x85, 0x5E, 0xC8, 0x4B, 0xD0, 0x1, 0x22, 0xD, 0xE9, 0x14, 0x88, 0x8F, 0xB8, 0x4, 0x32, 0x55, 0xEC, 0xC9, 0xEE, 0x23, 0x80, 0x5C, 0x90, 0x99, 0x97, 0x2F, 0x17, 0xB7, 0x24, 0xA3, 0x7F, 0xDB, 0x85, 0x64, 0x86, 0xE9, 0x80, 0xF8, 0xFC, 0xB9, 0x85, 0xC8, 0x4C, 0x75, 0x82, 0x34, 0x24, 0xEA, 0xA1, 0x7, 0x45, 0x79, 0xBC, 0x8F, 0x95, 0xB5, 0xA, 0xF4, 0x94, 0x1B, 0x9E, 0x38, 0x18, 0x19, 0xDE, 0x2F, 0x3A, 0x16, 0x22, 0x8F, 0x3B, 0xBA, 0xE4, 0x0, 0x31, 0x79, 0x3F, 0x65, 0x7B, 0x60, 0x32, 0x71, 0xCE, 0x7A, 0xD2, 0xCE, 0xE2, 0x50, 0xBC, 0x43, 0x5F, 0x55, 0x7B, 0x2, 0x3, 0x1, 0x0, 0x1, 0x2, 0x82, 0x1, 0x0, 0x70, 0xF, 0xC8, 0xE4, 0x94, 0x56, 0xB1, 0xE9, 0x9E, 0xC8, 0xAA, 0x16, 0x20, 0x9F, 0xB8, 0xF6, 0xA1, 0x89, 0x9, 0x50, 0xFE, 0xDE, 0x8F, 0x49, 0x12, 0x6A, 0x16, 0xD, 0xFA, 0x38, 0xDD, 0xCB, 0x47, 0x81, 0xB1, 0xCF, 0xEC, 0x7, 0x3D, 0x0, 0x44, 0xE3, 0x2A, 0x7D, 0x1E, 0xC6, 0x5D, 0xE4, 0x60, 0x51, 0xD0, 0xD8, 0xC0, 0x2A, 0xD, 0x69, 0x39, 0x16, 0xF9, 0x40, 0x73, 0x7F, 0xCD, 0x65, 0x4A, 0x1E, 0x7D, 0x72, 0x13, 0x65, 0x52, 0x1B, 0x4B, 0x8, 0x2A, 0x1F, 0x26, 0xA6, 0xD4, 0x12, 0x89, 0xFE, 0x82, 0x2D, 0xBC, 0x59, 0x8E, 0x80, 0x71, 0x62, 0x9C, 0x6, 0x11, 0xAD, 0x8E, 0x77, 0xFC, 0x86, 0x30, 0x4E, 0x62, 0xCB, 0x91, 0x90, 0xA5, 0x3C, 0xE6, 0x9, 0x83, 0x55, 0x73, 0xD, 0x96, 0xF3, 0x47, 0x16, 0x7F, 0x6A, 0x7B, 0x3B, 0x5, 0xE1, 0x3F, 0xD5, 0x40, 0x1E, 0xAE, 0x14, 0xEF, 0xCE, 0x5A, 0x84, 0xAE, 0xB1, 0xE0, 0x7F, 0xA1, 0x8C, 0xC0, 0x49, 0x46, 0x84, 0x72, 0xE9, 0x97, 0xAA, 0xCF, 0xEC, 0x3F, 0xC4, 0x2C, 0xAA, 0xE7, 0xA7, 0xEF, 0xC4, 0xCD, 0xEA, 0x22, 0x4F, 0x9, 0xAA, 0x10, 0xF3, 0xB5, 0x4F, 0x8B, 0x9F, 0x4C, 0x7F, 0x6E, 0xE8, 0x37, 0x5E, 0xBC, 0xBF, 0x9, 0xC4, 0xAC, 0x75, 0x92, 0xF6, 0xC3, 0x19, 0x59, 0xC1, 0xF6, 0x83, 0xF0, 0xDA, 0x41, 0xD0, 0x64, 0x1B, 0x68, 0x30, 0x5F, 0x39, 0x75, 0x53, 0x19, 0xD8, 0xA5, 0xF2, 0xB1, 0x8B, 0x9C, 0xDE, 0xE1, 0x9, 0x43, 0xBD, 0x0, 0x9A, 0xA9, 0xB0, 0x25, 0x32, 0x11, 0x54, 0x64, 0x7, 0x8C, 0x41, 0x5B, 0x70, 0xA0, 0x65, 0x4F, 0x83, 0xA4, 0x17, 0xFA, 0xBD, 0x22, 0xAC, 0xB4, 0x5B, 0x11, 0x64, 0xC4, 0xA0, 0xDF, 0x61, 0x82, 0x1D, 0x55, 0x3B, 0x76, 0x1F, 0xFA, 0x4C, 0x8F, 0x31, 0xAB, 0x19, 0x2, 0x81, 0x81, 0x0, 0xE2, 0x18, 0xEB, 0xFB, 0x2A, 0x92, 0x9A, 0x14, 0x62, 0xE5, 0x31, 0x77, 0x2D, 0x6D, 0xFA, 0xFB, 0xBC, 0xF4, 0x78, 0x3C, 0x9A, 0xFB, 0xCD, 0xAB, 0x41, 0xC7, 0x6A, 0xAF, 0x2D, 0xF9, 0xF1, 0x24, 0x51, 0xBB, 0x5F, 0xD9, 0x94, 0x7, 0x5A, 0xFC, 0xDD, 0xFC, 0x42, 0xF8, 0xAB, 0xD0, 0x28, 0xF7, 0xF3, 0x92, 0x70, 0xDB, 0x5, 0xFC, 0x1D, 0x8B, 0xDE, 0xAE, 0xBC, 0xB4, 0x54, 0x96, 0xEC, 0x1B, 0x3E, 0x4E, 0x4, 0x20, 0x75, 0x75, 0x73, 0xFA, 0x1D, 0xF, 0x35, 0x24, 0x10, 0x91, 0xF2, 0x8A, 0xA0, 0xB5, 0x7F, 0x1A, 0x9C, 0x6B, 0xE5, 0x26, 0xC9, 0x90, 0x46, 0xD7, 0xB6, 0x81, 0x55, 0x5E, 0x14, 0xF7, 0xB5, 0x56, 0xC0, 0xC1, 0xC6, 0xB9, 0x94, 0x2A, 0x16, 0x57, 0x51, 0x2A, 0x4F, 0xC2, 0x31, 0x88, 0xAF, 0x73, 0xA5, 0xBE, 0xC2, 0x1B, 0x7A, 0xE8, 0x2, 0x3D, 0xC7, 0xF1, 0x68, 0xDF, 0x2, 0x81, 0x81, 0x0, 0xF5, 0xB1, 0x85, 0xF0, 0xC9, 0x85, 0x44, 0x4B, 0x41, 0xD9, 0x94, 0xBA, 0xC1, 0x98, 0xE8, 0x4A, 0x2B, 0xE3, 0x72, 0x80, 0x21, 0xB2, 0x52, 0x37, 0xAB, 0x39, 0x8B, 0x7F, 0xE8, 0xD0, 0x53, 0x7E, 0x3F, 0x6B, 0x47, 0xE2, 0x2C, 0xA6, 0xB7, 0x9A, 0xE6, 0x19, 0xF9, 0x90, 0xCA, 0xB2, 0x1F, 0x59, 0x4A, 0x58, 0xCA, 0xDF, 0xAE, 0x81, 0xBC, 0x9D, 0x5B, 0x53, 0xFA, 0x2C, 0x9D, 0x24, 0xAE, 0xBA, 0x4A, 0xED, 0x43, 0xCF, 0x2A, 0x66, 0x92, 0x49, 0xBD, 0xD5, 0x3D, 0x13, 0x4, 0xEA, 0x70, 0xDA, 0xFC, 0x2F, 0xBF, 0xB5, 0x8D, 0x90, 0x2B, 0xAC, 0xDF, 0xE1, 0x6C, 0x1F, 0xCB, 0x1, 0x18, 0x6E, 0xD6, 0xC8, 0xC6, 0x16, 0xAF, 0x4E, 0xDA, 0xFF, 0x3F, 0xF, 0x55, 0x28, 0xFD, 0xC8, 0xF3, 0x70, 0x50, 0x5A, 0x68, 0xD, 0xAB, 0x6E, 0x95, 0xD5, 0x3F, 0x83, 0x9C, 0x5C, 0x3C, 0x96, 0x3A, 0xE5, 0x2, 0x81, 0x80, 0x6D, 0xB0, 0xAF, 0x93, 0xFC, 0x14, 0x81, 0xC2, 0x10, 0x34, 0xA7, 0x69, 0xED, 0x55, 0x65, 0x25, 0x8A, 0x87, 0x84, 0x69, 0xCA, 0xBB, 0xD, 0xD, 0xDF, 0xEC, 0xD2, 0x7A, 0x48, 0xB0, 0xF0, 0xE7, 0xB0, 0xEB, 0x59, 0xD6, 0x22, 0x35, 0xEB, 0x53, 0xB0, 0x92, 0xB9, 0x1F, 0x11, 0xA3, 0xFC, 0xAC, 0x46, 0xB4, 0x2E, 0x22, 0x64, 0x65, 0xEB, 0x23, 0xB7, 0x96, 0x48, 0xA0, 0xA8, 0x45, 0x4C, 0x28, 0xEF, 0x72, 0x44, 0x18, 0x47, 0x44, 0x3, 0x4F, 0x3D, 0x97, 0xEA, 0x2D, 0x24, 0x8, 0xDA, 0x85, 0x9C, 0xF0, 0x50, 0xC8, 0xE5, 0x48, 0x87, 0x34, 0xE9, 0x27, 0x20, 0xE7, 0x78, 0x78, 0x88, 0xA5, 0xB, 0x41, 0x1D, 0xEE, 0x7, 0xB8, 0x3B, 0x24, 0x3F, 0x98, 0xA7, 0x9C, 0x17, 0x19, 0x92, 0xF6, 0x60, 0xB7, 0xB2, 0x7F, 0x45, 0xD3, 0x25, 0x32, 0xD5, 0xCF, 0x7, 0x7F, 0x57, 0xA8, 0x6C, 0x3B, 0x2, 0x81, 0x81, 0x0, 0xEA, 0x36, 0xD8, 0x13, 0x69, 0x58, 0x44, 0x79, 0x65, 0x85, 0xD0, 0x95, 0x93, 0xF6, 0x7B, 0x2, 0x32, 0x2, 0x79, 0xE5, 0x91, 0xB9, 0xD7, 0x4C, 0xC0, 0x4A, 0x74, 0x24, 0x74, 0x41, 0x1C, 0x46, 0xCE, 0x98, 0x2B, 0x87, 0x7D, 0xBF, 0x54, 0x6A, 0x32, 0x8E, 0x72, 0x6D, 0x47, 0xFD, 0x33, 0x8B, 0x40, 0x27, 0x93, 0x6, 0x56, 0xE9, 0xD0, 0x6F, 0x45, 0x5F, 0xB1, 0xAE, 0x94, 0x3, 0x23, 0x19, 0xEE, 0x51, 0x6E, 0x81, 0xEF, 0xCE, 0xA6, 0x7, 0xEC, 0x12, 0x7A, 0x4D, 0x46, 0x33, 0x63, 0x70, 0x2E, 0x56, 0x2A, 0x70, 0x1D, 0x4A, 0x61, 0x88, 0x44, 0x48, 0x35, 0x75, 0xBD, 0x65, 0x6, 0xF0, 0xAA, 0x89, 0xEC, 0xE4, 0x35, 0x2C, 0x7B, 0xF2, 0x35, 0x20, 0x1D, 0xB3, 0x9C, 0xF2, 0xD2, 0xB6, 0xAF, 0xB2, 0xEF, 0x5C, 0x90, 0x9F, 0x33, 0xF0, 0x7C, 0xC2, 0xAE, 0xEC, 0xF2, 0xC8, 0xD7, 0xCD, 0x2, 0x81, 0x81, 0x0, 0x85, 0xB4, 0xDD, 0x81, 0x45, 0x8, 0xF8, 0xA3, 0x29, 0x78, 0x8A, 0xD6, 0x90, 0x8, 0x6A, 0x16, 0x75, 0x16, 0x4B, 0x60, 0x93, 0x98, 0xE4, 0x6D, 0xAD, 0x9B, 0xF1, 0x9D, 0xFB, 0x1, 0xD0, 0x2B, 0x71, 0x6E, 0x6E, 0xB3, 0x9, 0xC9, 0x9A, 0x42, 0x20, 0xA8, 0x67, 0xBE, 0x19, 0x56, 0x87, 0xD8, 0x21, 0x36, 0x8C, 0xCC, 0xC, 0xF6, 0x82, 0xB2, 0xCD, 0xB6, 0x41, 0xC, 0xB1, 0x37, 0x69, 0x10, 0x74, 0x3D, 0x68, 0x79, 0x1D, 0x39, 0x47, 0x46, 0xC7, 0xE7, 0x43, 0x93, 0x6E, 0x79, 0x2A, 0xAE, 0x6D, 0x79, 0x86, 0x3, 0x61, 0xA8, 0xB1, 0xB2, 0x9D, 0x5D, 0x41, 0xF0, 0x98, 0x75, 0x32, 0x8D, 0x82, 0xB0, 0x8D, 0xC7, 0x98, 0x88, 0xFD, 0x5A, 0x10, 0x68, 0xE5, 0x79, 0xAF, 0xD5, 0x4A, 0x9F, 0x2A, 0xAD, 0xC7, 0xDF, 0x42, 0x15, 0xBE, 0xD2, 0xD2, 0x13, 0xEC, 0x5A, 0xEA, 0xA8, 0x13, 0x95];
let der = der_parser::parse_der(&bytes).unwrap();
let mut di = der.1.ref_iter();
println!("rest: {:?}", der.0);
println!("next1: {:?}", di.next());
println!("next2: {:?}", di.next());
}
Output:
rest: []
next1: Some(DerObject { class: 0, structured: 0, tag: 2, content: Integer(0) })
next2: None
Is there any way to get the asn1 length? It seems to be available in the DerElementHeader
noticed when i'm using a crate that relies on der-parsers 8.2, and build as nightly i'm getting the following not sure if this is a problem that can be resolved at this level
error[E0635]: unknown feature proc_macro_span_shrink
--> C:\Users\chris.cargo\registry\src\index.crates.io-6f17d22bba15001f\proc-macro2-1.0.56\src\lib.rs:92:30
|
92 | feature(proc_macro_span, proc_macro_span_shrink)
NOT A CONTRIBUTION
I'm looking to update my code that uses x509-parser (and transitively der-parser). I have code that takes an x509_parser::x509::AlgorithmIdentifier
, reads the parameters
field, and pretty-prints it. In x509-parser v0.12, the parameters are a DerObject
so that works. In v0.15 it's an Any
. The pretty-printing provided by der-parser exists on BerObject
.
So, my question, how do I convert an asn1_rs::Any
to a BerObject
? I would have expected BerObject
to implement TryFrom<Any>
but it doesn't1. Is there any alternative way I'm missing?
I see in the source a comment saying this is because of the lack of a max_depth
argument, but I would have expected such an implementation to be recursive, and perhaps a method on BerObject
for converting from Any
with a maximum depth specified. ↩
der-parser appears to use a crate internally called rusticata-macros
, but it doesn't re-export it. It would be nice if this could be re-exported, to make it easier for clients of der-parser to write their own parsers.
The drawback here is it means der-parser can't update to incompatible versions of rusticata-macros without making it a breaking change for der-parser, but the last two major version updates to rusticata-macros appear to have been accompanied by major version updates to der-parser anyway.
Hello,
I think that it would be useful if .as_u64()
could parse BIT STRING
values into numbers, too, as BitStrings turns out to be sometimes used as enumerated integer values in ASN.1 definitions.
I will maybe make a pull request for that if the maintainer is OK.
Found using cargo-fuzz
.
extern crate der_parser;
fn main() {
let data = b"\x03\x00\x00kk\x00\x00\x00\x00\x00\x00\x00.\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff;\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\xff\x0a\xff";
let _ = der_parser::parse_der(data);
}
thread '<unnamed>' panicked at 'attempt to subtract with overflow', /home/neo/dev/work/der-parser/src/der.rs:496
stack backtrace:
0: 0x55a334805553 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hf9ed9ccfd9f14c2b
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: 0x55a334801ea4 - std::sys_common::backtrace::_print::hd8a1b72dcf3955ef
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: 0x55a334806527 - std::panicking::default_hook::{{closure}}::h5ff605bba7612658
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:355
3: 0x55a3348060ab - std::panicking::default_hook::h9bc4f6dfee57d6bd
at /checkout/src/libstd/panicking.rs:371
4: 0x55a33480698b - std::panicking::rust_panic_with_hook::hdc01585dc2bf7122
at /checkout/src/libstd/panicking.rs:549
5: 0x55a334806864 - std::panicking::begin_panic::hf84f4975d9f9b642
at /checkout/src/libstd/panicking.rs:511
6: 0x55a334806799 - std::panicking::begin_panic_fmt::hcc3f360b2ba80419
at /checkout/src/libstd/panicking.rs:495
7: 0x55a334806727 - rust_begin_unwind
at /checkout/src/libstd/panicking.rs:471
8: 0x55a3348f8e3d - core::panicking::panic_fmt::h795d9a9608ddc2bb
at /checkout/src/libcore/panicking.rs:69
9: 0x55a3348f8d74 - core::panicking::panic::hcab3e0dfa81beee9
at /checkout/src/libcore/panicking.rs:49
10: 0x55a3347d963e - der_parser::der::der_read_element_content_as::hec8b190837fd2b88
at /home/neo/dev/work/der-parser/src/der.rs:494
11: 0x55a3347db053 - der_parser::der::der_read_element_content::h4613f91403cc33be
at /home/neo/dev/work/der-parser/src/der.rs:612
12: 0x55a3347f7a99 - der_parser::der::parse_der::h012b5d2e9c9f1cdb
at /home/neo/dev/work/der-parser/src/der.rs:834
13: 0x55a334766b01 - rust_fuzzer_test_input
at /home/neo/dev/work/der-parser/fuzz/fuzzers/fuzzer_script_1.rs:7
14: 0x55a33476a71a - libfuzzer_sys::test_input_wrap::{{closure}}::h01afe675cf6a0c88
at /home/neo/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc6/36a3928/src/lib.rs:13
15: 0x55a3347687df - std::panicking::try::do_call::hfeac5113da58e53b
at /checkout/src/libstd/panicking.rs:454
16: 0x55a33480c67b - <unknown>
at /checkout/src/libpanic_abort/lib.rs:40
==5893== ERROR: libFuzzer: deadly signal
#0 0x55a3348d80d9 in __sanitizer_print_stack_trace /checkout/src/compiler-rt/lib/asan/asan_stack.cc:38
#1 0x55a33477bb11 in fuzzer::Fuzzer::CrashCallback() /home/neo/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc6/36a3928/llvm/lib/Fuzzer/FuzzerLoop.cpp:280
#2 0x55a33477ba5b in fuzzer::Fuzzer::StaticCrashSignalCallback() /home/neo/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc6/36a3928/llvm/lib/Fuzzer/FuzzerLoop.cpp:264
#3 0x55a33479924d in fuzzer::CrashHandler(int, siginfo_t*, void*) /home/neo/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc6/36a3928/llvm/lib/Fuzzer/FuzzerUtilPosix.cpp:37
#4 0x7fa3147ecfdf (/usr/lib/libpthread.so.0+0x11fdf)
#5 0x7fa31424ea0f in __GI_raise (/usr/lib/libc.so.6+0x33a0f)
#6 0x7fa314250139 in __GI_abort (/usr/lib/libc.so.6+0x35139)
#7 0x55a33480c688 in panic_abort::__rust_start_panic::abort /checkout/src/libpanic_abort/lib.rs:61
#8 0x55a33480c688 in __rust_start_panic /checkout/src/libpanic_abort/lib.rs:56
NOTE: libFuzzer has rudimentary signal handlers.
Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal
MS: 5 CrossOver-PersAutoDict-ChangeBinInt-InsertByte-PersAutoDict- DE: "\x01\x00\x00\x00"-"\x00\x00"-; base unit: 2bdab388248e0d022b7b852c59983788a3ee86e4
0x3,0x0,0x0,0x6b,0x6b,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2e,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0xa,0xff,
\x03\x00\x00kk\x00\x00\x00\x00\x00\x00\x00.\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff;\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\xff\x0a\xff
artifact_prefix='artifacts/'; Test unit written to artifacts/crash-99d752339e4c2516982a7eba4ddbe586ee4972dc
Base64: AwAAa2sAAAAAAAAALgD///////////////////////87////////////AQAAAP8K/w==
I'm running into some kind of dependency conflict trying to use both der-parser=0.4.4 and nom_pem=1.0.3. When I add both of these, I can't compile nom_pem.
Compiling nom_pem v1.0.3
error[E0243]: wrong number of type arguments: expected at least 1, found 0
--> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/nom_pem-1.0.3/src/lib.rs:63:14
|
63 | NomError(nom::Err),
| ^^^^^^^^ expected at least 1 type argument
I think maybe it has something to do with the verbose-errors
feature maybe?
Hi,
der-parser currently uses the streaming variant of the nom parsers. Version 5 now offers complete variants.
The streaming versions make using optionals opt!
and many1!
etc. a bit cumbersome. There are a few issues in the nom repo with examples for such problems.
At least for the application in x509-parser (and other cryptography realated parsers in general) the parsing of partial data is not necessary (?).
To ease usage (and increase performance?) I suggest to switch to the complete nom parsers.
I suspect this is a Debian issue, but not sure. Recently Debian 10 updated its rustc to 1.41.1 (and cargo to 1.42.1). Since then this crate fails to build inside Suricata:
error: /builds/inliniac/suricata-ci/suricata/rust/target/release/deps/libder_oid_macro-6303e17a207c2efa.so: undefined symbol: llvm.x86.subborrow.64
--> /builds/inliniac/suricata-ci/suricata/rust/vendor/der-parser/src/lib.rs:171:9
|
171 | pub use der_oid_macro::oid;
| ^^^^^^^^^^^^^
This happens in Suricata CI builds.
Interestingly it does not happen on Debian 10 on ARM. Not sure what could cause this.
Parsing an empty sequence (30 00
) fails: Incomplete(Size(1))
Length 0 is wrongly interpreted as indefinite length.
Using any of the macros in this crate requires both of the following imports in one's own code to work:
// for the map!() macro
#[macro_use]
extern crate nom;
// for custom_check!()
#[macro_use]
extern crate rusticata_macros;
The former breaks code if you use dbg!()
from the standard library because Nom defines the same macro name with incompatible semantics.
Currently looking at: https://redmine.openinfosecfoundation.org/issues/2977
I've run into an issue where to be able to implement the detect-asn1 checks, some fields cannot be accessed with the current API, such as the length len
of the BerObjectHeader.
The parse_ber
function currently returns a BerObject
#[derive(Debug, Clone)]
pub struct BerObject<'a> {
pub class: BerClass,
pub structured: u8,
pub tag: BerTag,
pub content: BerObjectContent<'a>,
pub raw_tag: Option<&'a [u8]>,
}
Note, the similarities with BerObjectHeader
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct BerObjectHeader<'a> {
pub class: BerClass,
pub structured: u8,
pub tag: BerTag,
pub len: u64,
pub raw_tag: Option<&'a [u8]>,
}
And the following which is called in parse_ber
after both the header/content are parsed:
impl<'a> BerObject<'a> {
pub fn from_header_and_content<'hdr>(
hdr: BerObjectHeader<'hdr>,
c: BerObjectContent<'hdr>,
) -> BerObject<'hdr> {
BerObject {
class: hdr.class,
structured: hdr.structured,
tag: hdr.tag,
content: c,
raw_tag: hdr.raw_tag,
}
}
(Note, the len
from hdr is not copied and can no longer be accessed, the .to_header()
method on the BerObject explicitly sets this value to 0)
What if a BerObject looked like this?
/// Representation of a DER-encoded (X.690) object
#[derive(Debug, Clone)]
pub struct BerObject<'a> {
pub header: BerObjectHeader<'a>,
pub content: BerObjectContent<'a>,
}
Let me know what you think and I can start working on it!
I can run der-parser
just fine on Ubuntu 20.04, which comes with glibc
version 2.31:
$ ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9) 2.31
But when I run on Debian stretch in a docker environment, I run into the following error:
error: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /cfsetup_build/target/debug/deps/libder_oid_macro-9517fe04de556285.so)
--> src/config.rs:2:5
|
2 | use der_parser::{ber::BerObjectContent, parse_der};
| ^^^^^^^^^^
error: aborting due to previous error
It looks like there is an older version of glibc on stretch which is causing this.
I have a signed data encoded by DER, but get strange output while parse
pub fn parse_signed_data(input: &[u8]) {
let (_, top_object) = parse_der(input).unwrap();
let pretty_object = top_object.as_pretty(4, 4);
println!("{:?}", pretty_object);
}
The input
let raw_bytes = [
0x30, 0x82, 0x05, 0x20, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02, 0xA0,
0x82, 0x05, 0x11, 0x30, 0x82, 0x05, 0x0D, 0x02, 0x01, 0x01, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x09,
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0B, 0x06, 0x09, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01, 0xA0, 0x82, 0x03, 0x57, 0x30, 0x82, 0x03, 0x53,
0x30, 0x82, 0x02, 0x3B, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x77, 0xA4, 0xD5, 0xE2, 0x30,
0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x5A,
0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31, 0x0B, 0x30,
0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x53, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03,
0x55, 0x04, 0x07, 0x13, 0x02, 0x53, 0x48, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A,
0x13, 0x06, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04,
0x0B, 0x13, 0x06, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55,
0x04, 0x03, 0x13, 0x06, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x30, 0x1E, 0x17, 0x0D, 0x32, 0x30,
0x31, 0x31, 0x30, 0x38, 0x30, 0x36, 0x33, 0x39, 0x34, 0x33, 0x5A, 0x17, 0x0D, 0x33, 0x30, 0x31,
0x31, 0x30, 0x36, 0x30, 0x36, 0x33, 0x39, 0x34, 0x33, 0x5A, 0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09,
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x08, 0x13, 0x02, 0x53, 0x48, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13,
0x02, 0x53, 0x48, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x06, 0x71, 0x71,
0x71, 0x71, 0x71, 0x71, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x06, 0x71,
0x71, 0x71, 0x71, 0x71, 0x71, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x06,
0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82,
0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xA7, 0xE0, 0x84, 0x4E, 0x72, 0x99, 0xE0, 0x0F, 0x4A,
0x91, 0x06, 0x08, 0x03, 0xC7, 0x8C, 0x10, 0xB5, 0x54, 0x20, 0x03, 0x63, 0x06, 0xCB, 0x03, 0x1F,
0xB3, 0xA5, 0xAE, 0x5A, 0x4D, 0x47, 0xA2, 0x38, 0x3E, 0x57, 0xBD, 0xFF, 0x3F, 0x0E, 0xC0, 0xCD,
0x82, 0x17, 0x18, 0x72, 0x71, 0xE4, 0x4B, 0xDE, 0xEC, 0x3E, 0xAF, 0xFD, 0x8D, 0x36, 0xF0, 0xFF,
0x49, 0xE5, 0x5F, 0x6A, 0xB2, 0xE7, 0xCA, 0xBA, 0xF1, 0x0F, 0x65, 0x85, 0x92, 0xA6, 0xA2, 0xF9,
0x3B, 0xBC, 0xA3, 0xC1, 0x46, 0x42, 0xDF, 0x34, 0x30, 0x3A, 0x90, 0xA5, 0x0A, 0xD2, 0x41, 0xD1,
0xD7, 0x0F, 0xC0, 0xC2, 0x08, 0x41, 0x71, 0x16, 0x88, 0x4E, 0x4F, 0x5C, 0x48, 0xE1, 0xDE, 0x08,
0xB2, 0x1F, 0x10, 0x3B, 0xB2, 0x25, 0x35, 0xDB, 0xCF, 0xFD, 0x16, 0x4F, 0x5A, 0x9D, 0x2F, 0xF6,
0xCE, 0xC9, 0xB9, 0x57, 0xFE, 0x24, 0xE5, 0x52, 0x42, 0x02, 0x42, 0x1A, 0xE5, 0x42, 0xC3, 0xC5,
0x5D, 0x4D, 0x31, 0x52, 0x22, 0x7A, 0x44, 0x67, 0x99, 0xD9, 0x8A, 0x41, 0x4E, 0xAC, 0x11, 0x80,
0x66, 0x23, 0x47, 0x6D, 0xC3, 0x65, 0x14, 0x6C, 0x9D, 0x6F, 0x96, 0xD4, 0xDC, 0xC4, 0x85, 0x16,
0xCC, 0x34, 0x14, 0xE7, 0x38, 0xA3, 0x9D, 0x7D, 0xB2, 0x51, 0xE1, 0xE1, 0x3C, 0x90, 0xE7, 0x26,
0x7F, 0x12, 0x7C, 0x3B, 0xCC, 0xD3, 0x6A, 0x3F, 0xDF, 0x00, 0xFC, 0x1C, 0x7B, 0x2B, 0x48, 0x44,
0x84, 0xA4, 0x9D, 0xEB, 0xE9, 0x2F, 0x8E, 0x26, 0x6A, 0x38, 0x6F, 0xBB, 0xF1, 0x1C, 0x2B, 0x11,
0x29, 0x9D, 0xF0, 0x57, 0x91, 0x10, 0x60, 0xDD, 0xD2, 0xDC, 0x64, 0xAE, 0xDD, 0x94, 0x53, 0x40,
0xBF, 0xDB, 0x11, 0xEA, 0xB0, 0x15, 0xDA, 0xD2, 0x8B, 0xAA, 0x08, 0x70, 0x4A, 0x21, 0x1E, 0x54,
0x2C, 0xF9, 0x9E, 0x52, 0xD0, 0x6B, 0x13, 0x02, 0x03, 0x01, 0x00, 0x01, 0xA3, 0x21, 0x30, 0x1F,
0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14, 0xC5, 0x15, 0x25, 0x97, 0xD0,
0x4B, 0xF9, 0x05, 0x87, 0x37, 0x95, 0x2F, 0xF1, 0x68, 0x1A, 0x22, 0xB3, 0xA7, 0x7F, 0xFC, 0x30,
0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82,
0x01, 0x01, 0x00, 0x54, 0x9A, 0x99, 0x39, 0x86, 0x3B, 0xC0, 0x91, 0xBB, 0x53, 0xA5, 0xB2, 0x2D,
0x9B, 0xD3, 0x7E, 0xD1, 0x51, 0xB4, 0x5E, 0xC0, 0x36, 0x11, 0x2D, 0x52, 0x5C, 0x25, 0xDD, 0x91,
0xD2, 0x5B, 0x42, 0xFA, 0xF6, 0x0E, 0x50, 0x30, 0x68, 0x2E, 0x86, 0xD9, 0x46, 0x19, 0x99, 0x42,
0xD1, 0x87, 0x6F, 0xFF, 0x7E, 0xD2, 0x54, 0x93, 0x0D, 0x82, 0x6E, 0x85, 0xC2, 0x7D, 0x76, 0xA5,
0x58, 0x57, 0x6C, 0x06, 0xE5, 0x8E, 0x05, 0xF7, 0x8B, 0x58, 0xD9, 0xBC, 0x64, 0xB0, 0x5E, 0x31,
0x88, 0xFD, 0xB1, 0xDB, 0x63, 0x4B, 0xA1, 0x22, 0xD2, 0xA9, 0x71, 0x97, 0x34, 0x3D, 0x31, 0xE1,
0xF7, 0xEE, 0xF4, 0xD4, 0x66, 0x6F, 0xB0, 0xD0, 0x9C, 0xDB, 0x82, 0x2A, 0x57, 0x08, 0xF7, 0x9F,
0x33, 0x5B, 0xF3, 0x29, 0xF9, 0x21, 0xDB, 0xC6, 0x82, 0x4D, 0x09, 0x90, 0xBA, 0xA9, 0xD7, 0x7D,
0x2B, 0xDD, 0xE8, 0xCA, 0x86, 0x21, 0xDF, 0xA5, 0xE3, 0xED, 0xED, 0x3B, 0x07, 0x2E, 0xDD, 0xBA,
0x27, 0xB3, 0xAF, 0x4E, 0xBE, 0x09, 0x96, 0x14, 0x4A, 0xED, 0x5B, 0x5A, 0xB3, 0x6E, 0xD0, 0x1D,
0x9E, 0x45, 0xC0, 0x70, 0xDF, 0x75, 0x7B, 0x77, 0xA1, 0x57, 0xC5, 0x76, 0x60, 0x58, 0x5C, 0xF2,
0x2F, 0xAD, 0xF1, 0xAA, 0x15, 0xA6, 0x7D, 0x5A, 0x94, 0x95, 0xB7, 0x10, 0x81, 0xC5, 0xE4, 0x49,
0xF1, 0x87, 0xB3, 0xA5, 0x97, 0xF8, 0xBE, 0xC4, 0xE0, 0xFD, 0x12, 0xCB, 0x14, 0x86, 0x98, 0xA0,
0x73, 0xFE, 0xEF, 0x9B, 0xE0, 0x14, 0x6A, 0x0E, 0x06, 0xDE, 0x77, 0xE1, 0x5A, 0xC4, 0xF4, 0x4E,
0xEB, 0x8D, 0x37, 0xF1, 0x3A, 0xCF, 0x4D, 0x4D, 0x36, 0xFC, 0xC0, 0x92, 0xA4, 0xE9, 0xA6, 0x49,
0x7B, 0xCC, 0x93, 0x66, 0x51, 0x2A, 0x24, 0xD3, 0x15, 0x75, 0x9B, 0x6C, 0x4F, 0x60, 0x44, 0xE9,
0x15, 0x59, 0x68, 0x31, 0x82, 0x01, 0x8D, 0x30, 0x82, 0x01, 0x89, 0x02, 0x01, 0x01, 0x30, 0x62,
0x30, 0x5A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4E, 0x31,
0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x53, 0x48, 0x31, 0x0B, 0x30, 0x09,
0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x02, 0x53, 0x48, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55,
0x04, 0x0A, 0x13, 0x06, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03,
0x55, 0x04, 0x0B, 0x13, 0x06, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x31, 0x0F, 0x30, 0x0D, 0x06,
0x03, 0x55, 0x04, 0x03, 0x13, 0x06, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x02, 0x04, 0x77, 0xA4,
0xD5, 0xE2, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00,
0x04, 0x82, 0x01, 0x00, 0x4B, 0x60, 0xBF, 0xF7, 0xF0, 0x7F, 0x3E, 0x06, 0xBE, 0xCA, 0x8F, 0xAD,
0x7E, 0xB6, 0x1B, 0xBE, 0xE9, 0x0D, 0x27, 0x02, 0x35, 0xF1, 0x31, 0xA6, 0xF7, 0xA6, 0x08, 0x6A,
0x48, 0xE0, 0x77, 0xA9, 0xFA, 0x30, 0xB1, 0xDB, 0xA8, 0xD9, 0x70, 0x2A, 0xA2, 0x21, 0x96, 0x02,
0x6F, 0x45, 0x94, 0xBD, 0x75, 0xA9, 0x1C, 0xF6, 0x04, 0x61, 0xB5, 0xCD, 0x39, 0xA5, 0xAB, 0xDD,
0x58, 0xCD, 0x50, 0x01, 0x22, 0x55, 0x04, 0x1D, 0x5A, 0x6A, 0x7A, 0xD7, 0x30, 0xA0, 0xBD, 0x36,
0x9E, 0x9D, 0xC9, 0x66, 0xBA, 0x13, 0x75, 0xB4, 0x46, 0x28, 0xA5, 0xF0, 0x1F, 0x09, 0x36, 0x9C,
0x05, 0x01, 0x7A, 0x66, 0x94, 0x55, 0xD4, 0x12, 0x0D, 0xC0, 0x3F, 0x77, 0x31, 0xFD, 0x06, 0x41,
0x48, 0x43, 0xC3, 0x17, 0x7B, 0x7F, 0x7D, 0x45, 0x39, 0x73, 0x00, 0x1E, 0xC2, 0x99, 0x3A, 0x25,
0x59, 0xB2, 0x78, 0xDD, 0x3E, 0x86, 0x06, 0xF0, 0x6E, 0x84, 0x0C, 0xB6, 0x33, 0x69, 0x73, 0x9B,
0x52, 0xBA, 0x0B, 0x5D, 0x2F, 0x0A, 0x01, 0x30, 0x42, 0x93, 0x2E, 0x16, 0x6B, 0x9A, 0xDB, 0x82,
0xF2, 0x30, 0x90, 0x1D, 0xC6, 0x1B, 0xB2, 0x2E, 0x19, 0x97, 0x40, 0xEC, 0xE1, 0x3F, 0xF3, 0x56,
0xD2, 0xD3, 0xAC, 0xA6, 0xF9, 0x07, 0x5E, 0xCF, 0xBE, 0x91, 0x1B, 0xEE, 0x75, 0x30, 0xEE, 0x2B,
0x7C, 0x45, 0x52, 0x1A, 0x76, 0x2F, 0x67, 0xE7, 0xCC, 0x8B, 0xCD, 0x93, 0xAD, 0xE4, 0xED, 0xEE,
0x28, 0x64, 0x2D, 0x08, 0x4F, 0xB2, 0xA5, 0xE8, 0x38, 0x85, 0xDE, 0x65, 0x40, 0x06, 0x68, 0x6D,
0xF6, 0x13, 0xC5, 0xE1, 0x2F, 0xE8, 0xA1, 0x74, 0x20, 0x44, 0x56, 0xD2, 0x9C, 0xF4, 0x0B, 0x78,
0xA2, 0x10, 0x9F, 0xAC, 0x81, 0x82, 0x26, 0xC6, 0x63, 0xBC, 0x02, 0x7D, 0x2F, 0x6C, 0xD4, 0x2F,
0xBD, 0x08, 0xD0, 0xA7
];
The output
Sequence[
OID(OID(1.2.840.113549.1.7.2))
Unknown(EndOfContent,[30, 82, 5, d, 2, 1, 1, 31, f, 30, d, 6, 9, 60, 86, 48, 1, 65, 3, 4, 2, 1, 5, 0, 30, b, 6, 9, 2a, 86, 48, 86, f7, d, 1, 7, 1, a0, 82, 3, 57, 30, 82, 3, 53, 30, 82, 2, 3b, a0, 3, 2, 1, 2, 2, 4, 77, a4, d5, e2, 30, d, 6, 9, 2a, 86, 48, 86, f7, d, 1, 1, b, 5, 0, 30, 5a, 31, b, 30, 9, 6, 3, 55, 4, 6, 13, 2, 43, 4e, 31, b, 30, 9, 6, 3, 55, 4, 8, 13, 2, 53, 48, 31, b, 30, 9, 6, 3, 55, 4, 7, 13, 2, 53, 48, 31, f, 30, d, 6, 3, 55, 4, a, 13, 6, 71, 71, 71, 71, 71, 71, 31, f, 30, d, 6, 3, 55, 4, b, 13, 6, 71, 71, 71, 71, 71, 71, 31, f, 30, d, 6, 3, 55, 4, 3, 13, 6, 71, 71, 71, 71, 71, 71, 30, 1e, 17, d, 32, 30, 31, 31, 30, 38, 30, 36, 33, 39, 34, 33, 5a, 17, d, 33, 30, 31, 31, 30, 36, 30, 36, 33, 39, 34, 33, 5a, 30, 5a, 31, b, 30, 9, 6, 3, 55, 4, 6, 13, 2, 43, 4e, 31, b, 30, 9, 6, 3, 55, 4, 8, 13, 2, 53, 48, 31, b, 30, 9, 6, 3, 55, 4, 7, 13, 2, 53, 48, 31, f, 30, d, 6, 3, 55, 4, a, 13, 6, 71, 71, 71, 71, 71, 71, 31, f, 30, d, 6, 3, 55, 4, b, 13, 6, 71, 71, 71, 71, 71, 71, 31, f, 30, d, 6, 3, 55, 4, 3, 13, 6, 71, 71, 71, 71, 71, 71, 30, 82, 1, 22, 30, d, 6, 9, 2a, 86, 48, 86, f7, d, 1, 1, 1, 5, 0, 3, 82, 1, f, 0, 30, 82, 1, a, 2, 82, 1, 1, 0, a7, e0, 84, 4e, 72, 99, e0, f, 4a, 91, 6, 8, 3, c7, 8c, 10, b5, 54, 20, 3, 63, 6, cb, 3, 1f, b3, a5, ae, 5a, 4d, 47, a2, 38, 3e, 57, bd, ff, 3f, e, c0, cd, 82, 17, 18, 72, 71, e4, 4b, de, ec, 3e, af, fd, 8d, 36, f0, ff, 49, e5, 5f, 6a, b2, e7, ca, ba, f1, f, 65, 85, 92, a6, a2, f9, 3b, bc, a3, c1, 46, 42, df, 34, 30, 3a, 90, a5, a, d2, 41, d1, d7, f, c0, c2, 8, 41, 71, 16, 88, 4e, 4f, 5c, 48, e1, de, 8, b2, 1f, 10, 3b, b2, 25, 35, db, cf, fd, 16, 4f, 5a, 9d, 2f, f6, ce, c9, b9, 57, fe, 24, e5, 52, 42, 2, 42, 1a, e5, 42, c3, c5, 5d, 4d, 31, 52, 22, 7a, 44, 67, 99, d9, 8a, 41, 4e, ac, 11, 80, 66, 23, 47, 6d, c3, 65, 14, 6c, 9d, 6f, 96, d4, dc, c4, 85, 16, cc, 34, 14, e7, 38, a3, 9d, 7d, b2, 51, e1, e1, 3c, 90, e7, 26, 7f, 12, 7c, 3b, cc, d3, 6a, 3f, df, 0, fc, 1c, 7b, 2b, 48, 44, 84, a4, 9d, eb, e9, 2f, 8e, 26, 6a, 38, 6f, bb, f1, 1c, 2b, 11, 29, 9d, f0, 57, 91, 10, 60, dd, d2, dc, 64, ae, dd, 94, 53, 40, bf, db, 11, ea, b0, 15, da, d2, 8b, aa, 8, 70, 4a, 21, 1e, 54, 2c, f9, 9e, 52, d0, 6b, 13, 2, 3, 1, 0, 1, a3, 21, 30, 1f, 30, 1d, 6, 3, 55, 1d, e, 4, 16, 4, 14, c5, 15, 25, 97, d0, 4b, f9, 5, 87, 37, 95, 2f, f1, 68, 1a, 22, b3, a7, 7f, fc, 30, d, 6, 9, 2a, 86, 48, 86, f7, d, 1, 1, b, 5, 0, 3, 82, 1, 1, 0, 54, 9a, 99, 39, 86, 3b, c0, 91, bb, 53, a5, b2, 2d, 9b, d3, 7e, d1, 51, b4, 5e, c0, 36, 11, 2d, 52, 5c, 25, dd, 91, d2, 5b, 42, fa, f6, e, 50, 30, 68, 2e, 86, d9, 46, 19, 99, 42, d1, 87, 6f, ff, 7e, d2, 54, 93, d, 82, 6e, 85, c2, 7d, 76, a5, 58, 57, 6c, 6, e5, 8e, 5, f7, 8b, 58, d9, bc, 64, b0, 5e, 31, 88, fd, b1, db, 63, 4b, a1, 22, d2, a9, 71, 97, 34, 3d, 31, e1, f7, ee, f4, d4, 66, 6f, b0, d0, 9c, db, 82, 2a, 57, 8, f7, 9f, 33, 5b, f3, 29, f9, 21, db, c6, 82, 4d, 9, 90, ba, a9, d7, 7d, 2b, dd, e8, ca, 86, 21, df, a5, e3, ed, ed, 3b, 7, 2e, dd, ba, 27, b3, af, 4e, be, 9, 96, 14, 4a, ed, 5b, 5a, b3, 6e, d0, 1d, 9e, 45, c0, 70, df, 75, 7b, 77, a1, 57, c5, 76, 60, 58, 5c, f2, 2f, ad, f1, aa, 15, a6, 7d, 5a, 94, 95, b7, 10, 81, c5, e4, 49, f1, 87, b3, a5, 97, f8, be, c4, e0, fd, 12, cb, 14, 86, 98, a0, 73, fe, ef, 9b, e0, 14, 6a, e, 6, de, 77, e1, 5a, c4, f4, 4e, eb, 8d, 37, f1, 3a, cf, 4d, 4d, 36, fc, c0, 92, a4, e9, a6, 49, 7b, cc, 93, 66, 51, 2a, 24, d3, 15, 75, 9b, 6c, 4f, 60, 44, e9, 15, 59, 68, 31, 82, 1, 8d, 30, 82, 1, 89, 2, 1, 1, 30, 62, 30, 5a, 31, b, 30, 9, 6, 3, 55, 4, 6, 13, 2, 43, 4e, 31, b, 30, 9, 6, 3, 55, 4, 8, 13, 2, 53, 48, 31, b, 30, 9, 6, 3, 55, 4, 7, 13, 2, 53, 48, 31, f, 30, d, 6, 3, 55, 4, a, 13, 6, 71, 71, 71, 71, 71, 71, 31, f, 30, d, 6, 3, 55, 4, b, 13, 6, 71, 71, 71, 71, 71, 71, 31, f, 30, d, 6, 3, 55, 4, 3, 13, 6, 71, 71, 71, 71, 71, 71, 2, 4, 77, a4, d5, e2, 30, d, 6, 9, 60, 86, 48, 1, 65, 3, 4, 2, 1, 5, 0, 30, d, 6, 9, 2a, 86, 48, 86, f7, d, 1, 1, 1, 5, 0, 4, 82, 1, 0, 4b, 60, bf, f7, f0, 7f, 3e, 6, be, ca, 8f, ad, 7e, b6, 1b, be, e9, d, 27, 2, 35, f1, 31, a6, f7, a6, 8, 6a, 48, e0, 77, a9, fa, 30, b1, db, a8, d9, 70, 2a, a2, 21, 96, 2, 6f, 45, 94, bd, 75, a9, 1c, f6, 4, 61, b5, cd, 39, a5, ab, dd, 58, cd, 50, 1, 22, 55, 4, 1d, 5a, 6a, 7a, d7, 30, a0, bd, 36, 9e, 9d, c9, 66, ba, 13, 75, b4, 46, 28, a5, f0, 1f, 9, 36, 9c, 5, 1, 7a, 66, 94, 55, d4, 12, d, c0, 3f, 77, 31, fd, 6, 41, 48, 43, c3, 17, 7b, 7f, 7d, 45, 39, 73, 0, 1e, c2, 99, 3a, 25, 59, b2, 78, dd, 3e, 86, 6, f0, 6e, 84, c, b6, 33, 69, 73, 9b, 52, ba, b, 5d, 2f, a, 1, 30, 42, 93, 2e, 16, 6b, 9a, db, 82, f2, 30, 90, 1d, c6, 1b, b2, 2e, 19, 97, 40, ec, e1, 3f, f3, 56, d2, d3, ac, a6, f9, 7, 5e, cf, be, 91, 1b, ee, 75, 30, ee, 2b, 7c, 45, 52, 1a, 76, 2f, 67, e7, cc, 8b, cd, 93, ad, e4, ed, ee, 28, 64, 2d, 8, 4f, b2, a5, e8, 38, 85, de, 65, 40, 6, 68, 6d, f6, 13, c5, e1, 2f, e8, a1, 74, 20, 44, 56, d2, 9c, f4, b, 78, a2, 10, 9f, ac, 81, 82, 26, c6, 63, bc, 2, 7d, 2f, 6c, d4, 2f, bd, 8, d0, a7])
]
As show above, I think 0xA0 is not a unknown tag and the tag number should not be parsed as EOC, this is a context-specific tag.
Hello,
We are using your library to parse ASN.1 files from EMV cards. It works pretty well but we have a problem for some tags.
In EMV standards, tags like 0x8F
or 0x9F0F
means different things while there are both a "application-specific not-structured tag of value 15". Then it is not possible to differentiate them using BerObject
tag property.
Would it be possible to add a way to access the exact representation of the tag (as a byte slice for example) ? That would be very useful, at least for non-universal tags.
Not a Contribution
This field is a u8
and yet it can only hold the values 0
and 1
. This is confusing and leads to somewhat odd behavior such as serializing a header looks at the lsb, so hdr.structured = 2
is serialized as 0
. It also means you can have a header that is neither primitive nor constructed (as both accessors do an equality test on the flag).
Instead this should be a bool
. Anyone who wants to recover the 0u8
/1u8
value can just cast it to u8
(hdr.structured as u8
), so that actually simplifies the encoding, and it simplifies the decoding too because right now it's a conditional
let b = if i[0] & 0b0010_0000 != 0 { 1 } else { 0 };
and with this change it would just be let b = i[0] & 0b0010_0000 != 0
.
Code that prints this today such as .as_pretty()
currently prints e.g. s:0
or s:1
, so if you wanted to preserve that you'd need to add a cast to the printing, though it might actually be clearer to just let it print as s:false
or s:true
anyway.
I don't know why this is called structured
, that word doesn't appear anywhere in X.690, I would have expected it to be called constructed
instead.
Looking at the parsing implementation, for parse_der()
or parse_ber()
, any object with a BerClass::Private
tag is still parsed as though it were BerClass::Universal
, even though private tags are enterprise-specific and therefore assuming they have the same meaning as universal tags is unlikely to be true.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.