Git Product home page Git Product logo

Comments (9)

chifflier avatar chifflier commented on May 27, 2024 1

The initial problem is now fixed (master branch, to be released as 7.0.0), so I'm closing this issue.
Please open other issues if needed.
Thanks

from der-parser.

cuserdzy avatar cuserdzy commented on May 27, 2024

I'm not sure if this function should process if hdr.class is DerClass::ContextSpecific

fn der_read_element_content_recursive<'a>(
    i: &'a [u8],
    hdr: DerObjectHeader<'a>,
    max_depth: usize,
) -> DerResult<'a> {
    match hdr.class {
        DerClass::Universal | DerClass::Private => (),
        _ => {
            let (i, content) = ber_get_object_content(i, &hdr, max_depth)?;
            let content = DerObjectContent::Unknown(hdr.tag, content);
            let obj = DerObject::from_header_and_content(hdr, content);
            return Ok((i, obj));
        }
    }
    match der_read_element_content_as(i, hdr.tag, hdr.len, hdr.is_constructed(), max_depth) {
        Ok((rem, content)) => Ok((rem, DerObject::from_header_and_content(hdr, content))),
        Err(Err::Error(BerError::UnknownTag)) => {
            let (rem, content) = ber_get_object_content(i, &hdr, max_depth)?;
            let content = DerObjectContent::Unknown(hdr.tag, content);
            let obj = DerObject::from_header_and_content(hdr, content);
            Ok((rem, obj))
        }
        Err(e) => Err(e),
    }
}

from der-parser.

chifflier avatar chifflier commented on May 27, 2024

Hmm, parse_der may be too restrictive here. If I remember correctly, recursive parsing is not done, because this function has not way to determine if parsing is explicit or implicit from the encoding only (this function has no context). Maybe I should let parse_der try to parse a valid header, and descend if possible, but I'm unsure this would be a good idea.

The usual method with der-parser is to specify the expected tag and parsing function (for ex using parse_der_tagged_explicit). See for example krb5_parser.rs.

What are you trying to do? Maybe I can help if you give more details

from der-parser.

scouten avatar scouten commented on May 27, 2024

@chifflier FWIW I am encountering a similar issue. In my case, I am attempting to parse a CMS (RFC 5652) data structure, specifically the signed and unsigned attributes types, where the structure of the data is not assigned within the RFC that I'm parsing.

I've observed that a context-specific [0] tag nested deeply within that structure yields the same EOC data pattern that @cuserdzy describes; this is an undesirable outcome in my case.

from der-parser.

scouten avatar scouten commented on May 27, 2024

@cuserdzy don't know if you're still facing this issue (or someone else may come along who does have a similar issue), but you can reparse the data blobs. The following code snippet could probably use some cleaning up, but it will reparse into such structures recursively:

fn reparse_unknown_o<'a>(o: BerObject<'a>) -> BerResult<'a> {
    // Workaround for https://github.com/rusticata/der-parser/issues/38.

    let new_o = match o.content {
        BerObjectContent::Sequence(v) => {
            let (_, new_v) = reparse_unknown_v(v)?;
            BerObject::from_header_and_content(o.header, BerObjectContent::Sequence(new_v))
        }

        BerObjectContent::Set(v) => {
            let (_, new_v) = reparse_unknown_v(v)?;
            BerObject::from_header_and_content(o.header, BerObjectContent::Set(new_v))
        }

        BerObjectContent::Optional(Some(boxed_obj)) => {
            let (_, new_o) = reparse_unknown_o(*boxed_obj)?;
            BerObject::from_header_and_content(
                o.header,
                BerObjectContent::Optional(Some(Box::new(new_o))),
            )
        }

        BerObjectContent::Tagged(class, tag, boxed_obj) => {
            let (_, new_o) = reparse_unknown_o(*boxed_obj)?;
            BerObject::from_header_and_content(
                o.header,
                BerObjectContent::Tagged(class, tag, Box::new(new_o)),
            )
        }

        BerObjectContent::Unknown(_tag, data) => {
            if o.header.class == BerClass::ContextSpecific && o.header.structured == 1 {
                // Tagged entries may contain multiple objects. The BerObjectContent enum
                // doesn't have a way to represent this directly, so we wrap this in an
                // implicit sequence.

                let mut objs: Vec<BerObject<'a>> = Vec::new();
                let mut i = data;
                while !i.is_empty() {
                    let (i2, obj) = parse_der(i)?;
                    let (_, obj) = reparse_unknown_o(obj)?;
                    objs.push(obj);
                    i = i2;
                }

                BerObject::from_header_and_content(o.header, BerObjectContent::Sequence(objs))
            } else {
                o
            }
        }

        _ => o,
    };

    Ok((&[], new_o))
}

fn reparse_unknown_v<'a>(v: Vec<BerObject<'a>>) -> BerResult<Vec<BerObject<'a>>> {
    let new_v: Result<Vec<BerObject<'a>>, nom::Err<BerError>> = v
        .into_iter()
        .map(|o| match reparse_unknown_o(o) {
            Ok((_i, new_o)) => Ok(new_o),
            Err(e) => Err(e),
        })
        .collect();

    match new_v {
        Ok(v) => Ok((&[], v)),
        Err(e) => Err(e),
    }
}

from der-parser.

nganhkhoa avatar nganhkhoa commented on May 27, 2024

I would add to the problem that I also share the same Unknown content for CMS data. And it get worse, as in X.509 ber sequence, with extra information (extension).

PKCS#7/CMS data contains a nested list of certificate X.509, which also has a context-specific [0] data. I have to manually parse the content as a sequence.

Why don't we support 0xA0 tag? It is in the specs anyway.

https://stackoverflow.com/a/43056617/13173256

P.S: the binary for my data is the signature blob in Mach-O (Apple binary) for signed binary. So I would expect the binary data is correctly encoded.

P.S 2: BER encoding, but DER also share the same

from der-parser.

chifflier avatar chifflier commented on May 27, 2024

Hi,
It's not that tag 0xA0 is not supported: the problem is using the function parse_der, because it cannot automatically guess the contents of the tagged value. Without the ASN.1 grammar, it's not possible to know if the value is EXPLICIT or IMPLICIT, and so it cannot be decoded.
When dealing with such cases, the best way is to guide the parser by giving the expected functions, as DER parser design doc section explains.

Note: I have a crate (not yet published, but the code is mostly ready) to decode most PKCS formats, including PKCS#7 and CMS (the crate does not perform cryptographic operations). I intended to publish it later, but if you are interested I can push it to github.

from der-parser.

scouten avatar scouten commented on May 27, 2024

FWIW I am unsubscribing as I no longer have the need for CMS parsing.

from der-parser.

nganhkhoa avatar nganhkhoa commented on May 27, 2024

I would love to see the crate published. But I don't insist pushing something to the public when you're not feeling it. Having a good parser for most certificate standards is very useful. Thank you.

Just a guessing, I think you use serialization to make the decodable/codable (cryptographic standard) structs. Because manually parsing is more error-prone than serializing. And while serialization is experimental, it would be too early to publish code using the feature.

from der-parser.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.