[openssl-users] SOLVED --- ASN.1: Parsing a 'context-specific' class (or app/private class)

Massimiliano Pala director at openca.org
Wed Sep 2 14:11:54 UTC 2015

Hi all,

since someone asked, here's my solution (if someone knows of a better 
one, please let me know).

The problem that I tried to solve is how to parse the CRYTPLIB-specific 
envelope for signatures. In particular, the example reported in my 
original e-mail was a DSA signature. The main issue here was how to 
parse a context-specific 0-tagged value inside the structure. Here's the 

         0:d=0  hl=2 l=  98 cons: SEQUENCE
         2:d=1  hl=2 l=   1 prim:  INTEGER           :03
         5:d=1  hl=2 l=  20 prim:  cont [ 0 ]
        27:d=1  hl=2 l=   9 cons:  SEQUENCE
        29:d=2  hl=2 l=   5 prim:   OBJECT            :sha1
        36:d=2  hl=2 l=   0 prim:   NULL
        38:d=1  hl=2 l=  11 cons:  SEQUENCE
        40:d=2  hl=2 l=   7 prim:   OBJECT :dsaEncryption
        49:d=2  hl=2 l=   0 prim:   NULL
        51:d=1  hl=2 l=  47 prim:  OCTET STRING

Since I could not find any ASN1 macro that would allow me to specify the 
field after the INTEGER (offset 5, class context-specific (0x80), no tag 
(0x0), and length 20), so I defined a new ASN1_ITEM type that uses the 
d2i_ASN1_bytes()/i2d_ASN1_bytes() for parsing or generating the value:

         // Defines the CRYPTLIB_KEYID as a string (keyID)

    ASN1_VALUE *cryptlib_keyid_d2i_func(ASN1_VALUE **a, const unsigned
    char **in, long length) {

         ASN1_VALUE * ret = NULL;
             // Return Value

         // Parse the key identifier
         ret = (ASN1_VALUE *)d2i_ASN1_bytes(NULL, in, length, 0,

         // Assigns the value (if the pointer to the structure was passed)
         if (a != NULL) *a = ret;

         // Returns the parsed value
         return ret;

    int cryptlib_keyid_i2d_func(ASN1_VALUE *a, unsigned char **in) {
         // Generates the DER from the passed value
         return i2d_ASN1_bytes((ASN1_STRING *)a, in, 0, 0x80);

    // Definition of the callbacks for the compat type
    static ASN1_COMPAT_FUNCS cryptlib_keyid_pf = {
             (ASN1_new_func *)ASN1_OCTET_STRING_new,
             (ASN1_free_func *)ASN1_OCTET_STRING_free,

    &cryptlib_keyid_pf, sizeof(*CRYPTLIB_KEYID*), "*CRYPTLIB_KEYID*"


This allowed me to define the CRYPTLIB_SIG by using the usual macros:

    typedef struct sig_t {
         ASN1_INTEGER *version;
    *CRYPTLIB_KEYID* *keyId;
         X509_ALGOR *hashAlgorithm;
         X509_ALGOR *sigAlgorithm;
         ASN1_OCTET_STRING *value;

             ASN1_SIMPLE(CRYPTLIB_SIG, version, ASN1_INTEGER),
             ASN1_SIMPLE(CRYPTLIB_SIG, hashAlgorithm, X509_ALGOR),
             ASN1_SIMPLE(CRYPTLIB_SIG, sigAlgorithm, X509_ALGOR),


Maybe a little hackerish solution... but this is the easiest I could 
think of. Does anybody have a better solution ?

Also, is there anybody who knows how to use the new ADB macros? Or is 
there any documentation on how to use them? That would be really useful 
to have...


P.S.: The contents of the 'value' field in CRYPTLIB_SIG can be simply 
parsed by using the appropriate key-parsing function. In the example, 
you can use the d2i_DSA_SIG()/i2d_DSA_SIG() for parsing the actual DSA 

P.P.S: Parsing application or private classes should require minimum 
changes (e.g., changing the class value from 0x80 to 0xC0 should allow 
to parse/generate private fields).

On 9/1/15 3:48 PM, Sec_Aficiondado wrote:
> Hi Massimiliano,
> Please do share it here on the list. There might not be an immediate need for it, but you'll save a couple of days to the next poor soul that ventures down the same path :)
> Your solution will be indexed and pop right up on search engines in the future.
> Thanks!
> Sent from my mobile
>> On Aug 31, 2015, at 7:10 PM, Massimiliano Pala <director at openca.org> wrote:
>> Hi all,
>> I actually figured it out, if anybody is curious about the solution for parsing this CRYPTLIB signature envelope (in this case DSA) - write to me directly, I will be happy to share the solution.
>> Cheers,
>> Max
>>> On 8/29/15 6:56 PM, Massimiliano Pala wrote:
>>> Hi all,
>>> I am trying to parse a sequence that has, after an integer, a 'private' (xclass) item. I was wondering what is the right templates / macros to be able to generate the ASN1 functions with the usual macro. An example of the structure I have to parse (B64 - DER), is the following:
>>> [ you can paste it into http://www.lapo.it/asn1js/ to get useful info. ]
>>> The field that is giving me issues is the 2nd field in the sequence - offest 5, length 20 (i.e., after SEQUENCE (2 bytes) + INTEGER (3 bytes) and then the 20bytes field that I want to parse). The type is 0x80 - context specific. By using the ASN1_get_object() function, I get the correct size (20), the tag (0), and the xclass (128). Now, how do I go in order to generate the useful ASN1 function with teh usual macros ? Here's an example (besides the second field) for what I am trying to do:
>>>     ASN1_SIMPLE(TYPE, field1, ASN1_INTEGER),
>>>     XXXXXXX(TYPE, field2, YYYYY),                      <<-- What shall be used here ? What Macro ?
>>>     ASN1_SEQUENCE_OF(TYPE, field3, ASN1_OBJECT),
>>>     ASN1_SEQUENCE_OF(TYPE, field3, ASN1_OBJECT),
>>>     ASN1_SIMPLE(TYPE, field3, ASN1_OCTET_STRING)       <<-- This might be wrong as well - just noticed it is a very
>>> } ASN1_SEQUENCE_END(TYPE)                                    weird encoding (octet-string that encapsulates a sequence of integers)
>>> Is there a way to have the macros do the work (e.g., shall I use other macros - template? - to define the field somehow) ? Or shall I just write my own d2i_ and i2d_ functions ?
>>> Please let me know,
>>> Cheers,
>>> Max
>>> _______________________________________________
>>> openssl-users mailing list
>>> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
>> _______________________________________________
>> openssl-users mailing list
>> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
> _______________________________________________
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20150902/f4725f6e/attachment-0001.html>

More information about the openssl-users mailing list