kellerkindt / asn1rs

Generates Rust Code and optionally compatible Protobuf schema files from ASN.1 definitions.
http://asn1.rs
Apache License 2.0
51 stars 19 forks source link

DER Support #10

Open masihyeganeh opened 4 years ago

masihyeganeh commented 4 years ago

Hi. My project heavily depends on parsing DER encoded data. Your crate is by far the most interesting ASN1 parsers. Is it hard to implement DER for it too? I can contribute to that but I'm not sure where to start.

kellerkindt commented 4 years ago

Hi there, I dont know how hard it is to implement DER-serialization. Maybe you can gather useful information from this pdf or directly from ITU / ITU-DER.

I'd suggest the following steps in implementing DER support:

Feel free to contribute via PRs whenever you like to :)

kellerkindt commented 4 years ago

@masihyeganeh I suggest to await the current refactoring (see #11) which should make it easy-ish to extend this crate with another encoding (DER in your case) and without the need to codegen for it.

kellerkindt commented 4 years ago

Hi there, refactoring is almost complete. I'll get rid of (the) old (uper) code soon/next.

If you want to, you can look into implementing a DerReader and DerWriter, analogue to println and uPER. The showcase demonstrates basic inline-usage. The idea is to only have to swap the UperWriter/-Reader with a DerWriter/-Reader in the uper_proof function to create a der_proof function without further code generation.

I guess some ASN syntax and types you'll need are not parsed or implemented yet. If you show some samples I'll might focus on them next. Otherwise I'll probably keep on trying to get LDAP working next.

I'll gladly accept a PR for a working implementation :smiley:

masihyeganeh commented 4 years ago

Fantastic. Would you please release a version on crates.io so I can play with it? I couldn't make it work with master branch.

kellerkindt commented 4 years ago

@masihyeganeh I just did, but I would also like to know why it did not work for you. Maybe its and issue with my repository layout? If so, I might be able to fix it, if you are give me a more concrete error description.

masihyeganeh commented 4 years ago

Thanks. It was because of my other dependencies. My old version of reqwest was conflicting with yours. Can you please implement SET and SET OF before I start to figure out how to implement DER? It is really similar to SEQUENCE I think. I'm not that familiar with detail of ASN, I should try to implement it somehow based on rfc

masihyeganeh commented 3 years ago

I just started to implement DER, but I think I'm lost. I copied src/syn/io/uper.rs to src/syn/io/der.rs and started changing it, but I found out that in other parts of code, like this one, there is direct dependency on Uper*: https://github.com/kellerkindt/asn1rs/blob/e9ac0599b2c059a3400c1db88edfd412a08a82e1/src/io/buffer.rs#L27

It is not clear to me how to implement it, what files I need to change and ... Considering that DER is the simplest implementation of this family, I hope we can do it soon.

And by the way, I tested your experimental-set-setof branch with my asn file and it worked well (almost, there was a minor catch). I hope you merge it soon.

kellerkindt commented 3 years ago

I just added the der-support branch where I copied the UPER related modules for DER. Let me explain real quick:

Depending on how similar the DER/(u)PER traits are, I will/we can try to unify them later. But I suggest to 'just get it working' for now - even if this means duplicat-ish code/declarations atm. Refactoring working code with proper tests is much easier than trying to get the structure, abstraction and impl right at once.

I hope this helps you to get you going :smile:

EDIT: regarding the experimental-set-setof branch, #13 describes the current blocker for merging. EDIT2: Poke me, if you need access to the tags which aren't yet represented in the type constraints and thus not available in the read/write adapter calls. But I can prioritize this if you need it.

masihyeganeh commented 3 years ago

Thanks man. This should make working on it a lot easier. I looked at the implementation of your uper for hour and I think I know how it works now but not actually sure about it. I need to confirm it with you.

Look, der (and ber and cer) is way simpler than uper; There is no difference between types. Always there is a 2 bit class, 1 bit to tell if it is primitive or constructed and 5 bits tag in first octet. Second octed is like : 1 bit to tell it's length type and usually next 7 bits tell it's actual length or how many octets should we read as number to know the length. Next n octets is the value

That's all. Nothing more. No especial case or anything. I'm sure you can implement it in minutes, but I had to read your code for hours to know what is going on. For example I'm not sure it it is ok to directly call read_bit or not. I'm not sure how ro read 2 bits as a number (or enum). I saw some ranges in there and I think I need to set start and end of buffer, but it's confusing for me.

If you can give some of your time, here is a simple explaiantion of ber implementation (der is just ber, but simpler, always there is length): https://en.m.wikipedia.org/wiki/X.690#BER_encoding

Or if you don't have time, please guide me through it. Thanks

mouse07410 commented 7 months ago

@kellerkindt @masihyeganeh Any update on this? It would be great to have Rust code for DER encoding/decoding generated directly from the ASN.1 files.

kellerkindt commented 7 months ago

So, I've set up a basic workflow for the (Distinguished) Encoding Rules support, see the very very early boolean example

I noticed the https://asn1.io/asn1playground is now rate limited pretty early, which makes it hard for me to verify my implementations. Does anybody know an alternative for DER?

EDIT: Started to use asn1js as reference

mouse07410 commented 7 months ago

Please consider https://GitHub.com/mouse07410/asn1c, as a cross-testing platform.