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 <direc...@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:

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 via email to