Atkelar (atkelar) wrote,

ASN.1 - Oh the agony!

Computer related stuff this time, quite close to the machine level even. If you're not into that stuff, don't waste your time her, OK?

Time to vent a bit again... In my quest to understand interfaces, protocols and "stuff" in development work, I usually go ahead and implement them myself. Yes, I have made a (crude but working) web, DNS, SMTP, POP3, IMAP4 client *and* server and an IRC client library. Why? Because now I know how these things work and how I can use them to my advantage. Oh and yes, I use C# for that.

During the SMTP/POP/IMAP implementation, I realized that these wouldn't be much use (as if they ever would be) if the didn't support TLS. Looking a bit at the API that MS provides for that but I couldn't find anything useful related to certificate handling and "special features" of TLS... these are always tied to newer versions of the library and the library is tied to the OS - hence: upgrade to Windows 8 or be cursed without some key features.

Aaaand off we go, coding a TLS wrapper for .NET data streams... can't be that hard, can it? Finished a crude implementation that allowed me to use RSA-SHA1-AES based connections rather quick, despite some "issues" (and debugging isn't exactly easy here... I mean, if the decryption yields a scrambled block of data, WHICH of the countless parameters and data blocks was wrong? What bugged me on my implementation, is the lack of certificate validation. I just have to accept the certificate by loading it into the .NET wrapper class which doesn't provide much info and relies heavily on the Windows certificate infrastructure... Some of the more advanced stuff requires lower-level access to that certificate data however. Oh and come to think of it, trusting the MS-implementation of crypto-code is also a bit... well... ahem.
Since I had to code my own HMAC-implementation anyhow (.NET has some strange version, but not the one required by TLS) I decided to give it a go and implement other algorithms as well.

So now I have these algorithms implemented and verified:
MD5, SHA1, SHA224, SHA256, SHA384, SHA512, SHA512/224, SHA512/384, HMAC, AES-128, AES-192, AES-256, RSA-PSS, RSA-OAEP, RSA-PKCS#1.5, Diffie-Hellman

Unverified, due to the lack of test vectors: PBKDF2 (HMAC-Based)

And what about the certificates?
Glad you ask... For some strange reason, RSA decided to base their specs (what later became the standard) on a data model defined by ASN.1 notation. Never heard of it? Check WikiPedia - and read up on it: Here...

X509 certificates (a.k.a. the ".cer" files and what's exchanged durint TLS handshake) are stored as "DER" encoded ASN.1 data structures. It took me weeks to find details about DER encoding that didn't require purchase of some expensive "standard document". And since certificates aren't the only data structures involved here that is based on ASN.1, I implemented a simple DER parser. I can now read a certificate file (X509v3) and make sense of what's stored inside it. Even all the nifty extensions and flags that are hidden or just unavailable in MS's version.

But I'm still not at the end of the chain to the most basic tech here... A few days ago, I decided to revamp that DER parser into something a bit more "complete". And to do that, I wanted to auto-generate C# code from the ASN.1 specs. Looing throught he internet, I only discovered a left over project that's no longer serviced. And thus I had to get my hands dirty once more. Goal: Parse ASN1 syntax and create read/write code for the structures defined within.

This is where it got dirty: ASN1 syntax is very... umm... flexible. It pretends to define structures in a readable form and yet it has countless "if then else but not in case Y" combination of keywords and symbols. And it totally lacks terminators. that means that it's even very hard or close to impossible to make out one declaration from the next.

So far, my "compiler" (or parser rather) is able to produce output from a module that includes all the module headers, the names of the exported symbols and iterating through the imports-list to load other modules. It also can parse value and type assignments (simple ones) and thus successfully imports the ASN-Module "UsefulDefinitions {joint-iso-itu-t ds(5) module(1) usefulDefinitions(0) 5}" and the 60-some OIDs that it defines. And here's the nifty problem I stumbled upon: the "InformationFramework" module and the "ServiceAdministration" module import symbols... from each other! In C-terms that would be File-A including File-B and File-B including File-A... WTF? How can one spec be based on the other and vice versa? Who f***d up here? If I'm correct about the lax syntax, it is mandatory to know during parsing what an identifier refers to: a type, a value or whatever - to make the right parsing decision. But if I cannot evaluate the "imported" names because of circular references, it's pretty hopeless to try to parse a file correctly. A standard that relies on an output of "whatever" isn't really a good choice for security, is it? Or am I just missing a point here?

Tags: computer, oid, programming, techtalk

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 1 comment