ASN.1: Parsing a 'private' class

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

ASN.1: Parsing a 'private' class

Dr. Pala
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:

MGICAQOAFGZKq8/wIYS7Iueq6NuaC3ESPqUKMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAJTJ6W2QjBIbVQdAtLbPO3y1wazHAhRsXivNO/Eg4GMEgcmEx8OgsIxGzQ==

[ 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_SEQUENCE(TYPE) = {

     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
Reply | Threaded
Open this post in threaded view
|

Re: ASN.1: Parsing a 'private' class

Dr. Pala
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:
>
> MGICAQOAFGZKq8/wIYS7Iueq6NuaC3ESPqUKMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAJTJ6W2QjBIbVQdAtLbPO3y1wazHAhRsXivNO/Eg4GMEgcmEx8OgsIxGzQ==
>
>
> [ 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_SEQUENCE(TYPE) = {
>
>     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
Reply | Threaded
Open this post in threaded view
|

Re: ASN.1: Parsing a 'private' class

Sec_Aficiondado
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 <[hidden email]> 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:
>>
>> MGICAQOAFGZKq8/wIYS7Iueq6NuaC3ESPqUKMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAJTJ6W2QjBIbVQdAtLbPO3y1wazHAhRsXivNO/Eg4GMEgcmEx8OgsIxGzQ==
>>
>> [ 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_SEQUENCE(TYPE) = {
>>
>>    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
Reply | Threaded
Open this post in threaded view
|

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

Dr. Pala
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 parsing:
    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:
typedef ASN1_OCTET_STRING CRYPTLIB_KEYID;
    // 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, V_ASN1_CONTEXT_SPECIFIC);

    // 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_d2i_func,
        cryptlib_keyid_i2d_func
};

ASN1_ITEM_start(CRYPTLIB_KEYID)
  ASN1_ITYPE_COMPAT, V_ASN1_OCTET_STRING, NULL, 0, &cryptlib_keyid_pf, sizeof(CRYPTLIB_KEYID), "CRYPTLIB_KEYID"
ASN1_ITEM_end(CRYPTLIB_KEYID)

DECLARE_ASN1_FUNCTIONS(CRYPTLIB_KEYID);
IMPLEMENT_ASN1_FUNCTIONS(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;
} CRYPTLIB_SIG;

ASN1_SEQUENCE(CRYPTLIB_SIG) = {
        ASN1_SIMPLE(CRYPTLIB_SIG, version, ASN1_INTEGER),
        ASN1_SIMPLE(CRYPTLIB_SIG, keyId, CRYPTLIB_KEYID),
        ASN1_SIMPLE(CRYPTLIB_SIG, hashAlgorithm, X509_ALGOR),
        ASN1_SIMPLE(CRYPTLIB_SIG, sigAlgorithm, X509_ALGOR),
        ASN1_SIMPLE(CRYPTLIB_SIG, value, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(CRYPTLIB_SIG)

DECLARE_ASN1_FUNCTIONS(CRYPTLIB_SIG)
IMPLEMENT_ASN1_FUNCTIONS(CRYPTLIB_SIG)
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...

Cheers,
Max

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 signatures.

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 [hidden email] 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:

MGICAQOAFGZKq8/wIYS7Iueq6NuaC3ESPqUKMAkGBSsOAwIaBQAwCwYHKoZIzjgEAQUABC8wLQIVAJTJ6W2QjBIbVQdAtLbPO3y1wazHAhRsXivNO/Eg4GMEgcmEx8OgsIxGzQ== 

[ 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_SEQUENCE(TYPE) = {

   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


_______________________________________________
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: SOLVED --- ASN.1: Parsing a 'context-specific' class (or app/private class)

Dr. Stephen Henson
On Wed, Sep 02, 2015, Massimiliano Pala wrote:

> 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 parsing:
>
>         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:
>
[snip]
>
> Maybe a little hackerish solution... but this is the easiest I could
> think of. Does anybody have a better solution ?
>

Well at first sight that looks like an IMPLICIT tag which replaces the normal
tag with the context specific value. It is not possible to determine the
underlying type from the encoding itself as it has been replaced. So you need
the ASN.1 spec to see the appropriate type to use.

In that particular example it looks like an SHA1 hash (20 bytes long) so we
could use an implicitly tagged OCTET STRING like this:

        ASN1_IMP(struct_name, field_name, ASN1_OCTET_STRING, 0),

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
_______________________________________________
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

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

Sands, Daniel
> Well at first sight that looks like an IMPLICIT tag which replaces
> the normal
> tag with the context specific value. It is not possible to determine
> the
> underlying type from the encoding itself as it has been replaced. So
> you need
> the ASN.1 spec to see the appropriate type to use.
>
> In that particular example it looks like an SHA1 hash (20 bytes long)
> so we
> could use an implicitly tagged OCTET STRING like this:
>
> ASN1_IMP(struct_name, field_name, ASN1_OCTET_STRING, 0),

And often, implicit tags are intended for ASN.1 Choice constructs so
that you will know which option of the choice to parse into.

If the OP knew exactly what was being parsed, most likely there's an
RFC that defines the structure exactly, which relieves one of needing
to reverse-engineer it.
_______________________________________________
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

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

Dr. Stephen Henson
On Wed, Sep 02, 2015, Sands, Daniel wrote:

> > Well at first sight that looks like an IMPLICIT tag which replaces
> > the normal
> > tag with the context specific value. It is not possible to determine
> > the
> > underlying type from the encoding itself as it has been replaced. So
> > you need
> > the ASN.1 spec to see the appropriate type to use.
> >
> > In that particular example it looks like an SHA1 hash (20 bytes long)
> > so we
> > could use an implicitly tagged OCTET STRING like this:
> >
> > ASN1_IMP(struct_name, field_name, ASN1_OCTET_STRING, 0),
>
> And often, implicit tags are intended for ASN.1 Choice constructs so
> that you will know which option of the choice to parse into.
>

Or OPTIONAL and occasionally one does see tagged types for no apparent reason.
Also just because you see a universal tag doesn't mean that it isn't part of
a CHOICE: which would mean the parser would choke when it encountered an
unexpected tag.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
_______________________________________________
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users