> From: owner-openssl-users On Behalf Of Danyk
> Sent: Tuesday, December 03, 2013 12:35

> "Almost. If the actual value is not OCTET STRING, change the type created
> in the first two (or whatever) lines, and i2d'ed in the fourth line.
> And OPENSSL_free the pointer allocated here (d) after you're
> done with that memory. "
> 
> I need to add an INTEGER extensions and PRINTABLESTRING extension.
> I tried folowing your instructions, and used an exmple from this forum,
but
> still get rubbish
> 
>         //1) create the integer and populate it:
> 
>       nid = OBJ_create("  1.3.6.1.4.1.12345", "EndEntityType",
> "EndEntityType");
>       ASN1_OBJECT* obj = OBJ_nid2obj(nid);
> 
>       ASN1_INTEGER * int1 = ASN1_INTEGER_new();
>         ASN1_INTEGER_set(int1, 1);
> 
>         //2) figure out the length it would take when converted from
> internal into der/asn1 wire encoding:
> 
>         int n =  i2d_ASN1_INTEGER(int1,NULL);
> 
You don't *need* to precompute the length, allocate memory, 
and then use it. For about 10 years i2d_* will allocate for you,
as you had in your 11/28 post. But if you want the harder way:

>         //3) Ensure we have the needed space for that:
> 
>         ASN1_OCTET_STRING data1;
>         data1.data = malloc(n);
>         data1.length = n;
> 
That leaves .type and .flags uninitialized, and depending on your C
implementation 
and the rest of your code probably garbage. It appears for this particular
code 
you don't actually need those fields, but it's very imprudent to depend on
that. 
Either set them explicitly, or at least fill (usually memset) the whole
struct to 0 
before using it so you don't get 'Heisenbugs'. And in real code you should
check 
for malloc failure (returned null) before using it.

>          //4) Fill out the ASN1 string by translating it again - this time
> into the buffer.
> 
>         unsigned char *  p =M_ASN1_STRING_data(&data1);
>         i2d_ASN1_INTEGER(int1,&p);
> 
It's confusing to set fields explicitly but use a macro to get one. 
You've already 'broken' the (weak) encapsulation, just use data1.data.

Alternatively and arguably cleaner do something like:
  int len = i2d_type (value, NULL);
  unsigned char * buf = malloc (len), * ptr = buf;
  i2d_type (value, &ptr);
  ASN1_OCTET_STRING * encoded = ASN1_OCTET_STRING_new ();
  ASN1_OCTET_STRING_set (encoded, buf, len);
  free (buf);
  // use encoded for the extension value 

or as above let i2d do allocation for you:
  unsigned char *buf = NULL;
  int len = i2d_type (value, &buf);
  // set the OCTET_STRING as above
  OPENSSL_free (buf);

>          //5) add to the extension stack.
> 
>         sk_X509_EXTENSION_push(st_exts,
> X509_EXTENSION_create_by_OBJ(NULL,
> obj, 0, &data1));
> 
> what is wrong with this?
> 
Except as above, nothing. (Assuming of course you then put st_exts in the
req,
but you showed that correct before.) Code almost equivalent to this works
for me, 
with the only significant differences that I use the config file for the new
OID (so 
the name is available at display) and I create EXTN by_NID instead of by
_OBJ.
(ISTR you had that also, but I'd have to go back and search for it.)

What do you mean by "rubbish"? Post an asn1parse (or a PEM) and say 
what you think is wrong in it.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to