Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Blumenthal, Uri - 0553 - MITLL
> > For now the ASN.1 string is not an opaque structure.
> 
> Considering how OpenSSL design evolved, I suspect that the time may come
> when this string would become opaque. Therefore, I suggest that
> getter/setter functions should be added.

Any thoughts about the interface?

Alas, since I don't have any experience actually using these flags, I don't 
consider myself competent suggesting the API here.

Some flag bits look internal, and not necessarily ideal for applications to 
modify directly, so
while these might do:

long ASN1_STRING_get_flags(ASN1_STRING *);
void ASN1_STRING_set_flags(ASN1_STRING *, long);

This makes sense. Also, if there are flags that users are likely to need - 
perhaps explicit getter/setter calls for those individual flags? This would 
lower the likelihood of erroneously affecting unintended flags by a 
"ricochet"...

Perhaps all that's needed is:

int ASN1_BIT_STRING_set_unused(ASN1_STRING *, int);

which sets the unused bit count, checking that the ASN1_STRING type
is V_ASN1_BIT_STRING and the count is in the range [0,7].

That I don't know. I can't figure how or why I would use ..._set_unused()... 
But as I said, my competence in this particular thing is low.


smime.p7s
Description: S/MIME cryptographic signature


Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Viktor Dukhovni
On Tue, Jun 18, 2019 at 09:51:31PM +, Blumenthal, Uri - 0553 - MITLL wrote:

> > We should perhaps provide getter/setter functions for the flags, or
> > perhaps even a specific function for indicating the value is a bitstring,
> > and how many bits it holds.  For now the ASN.1 string is not an opaque
> > structure.
> 
> Considering how OpenSSL design evolved, I suspect that the time may come
> when this string would become opaque. Therefore, I suggest that
> getter/setter functions should be added.

Any thoughts about the interface?  Some flag bits look internal,
and not necessarily ideal for applications to modify directly, so
while these might do:

long ASN1_STRING_get_flags(ASN1_STRING *);
void ASN1_STRING_set_flags(ASN1_STRING *, long);

Perhaps all that's needed is:

int ASN1_BIT_STRING_set_unused(ASN1_STRING *, int);

which sets the unused bit count, checking that the ASN1_STRING type
is V_ASN1_BIT_STRING and the count is in the range [0,7].

-- 
Viktor.



Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Blumenthal, Uri - 0553 - MITLL
On 6/18/19, 5:44 PM, "openssl-users on behalf of Viktor Dukhovni" 
 
wrote:

We should
perhaps provide getter/setter functions for the flags, or perhaps
even a specific function for indicating the value is a bitstring,
and how many bits it holds.  For now the ASN.1 string is not an
opaque structure.

Considering how OpenSSL design evolved, I suspect that the time may come when 
this string would become opaque. Therefore, I suggest that getter/setter 
functions should be added.


smime.p7s
Description: S/MIME cryptographic signature


Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Viktor Dukhovni
On Tue, Jun 18, 2019 at 02:27:30PM -0700, Lisa Matias wrote:

> Sorry, I was just frustrated that the changes to OpenSSL 1.1.1 broke code
> which worked for nearly 15 years, by denying access to previously
> accessible C structs.

Those changes are needed to make sure that future changes in the
internals DO NOT break your code.  The internal data layout would
ideally not have been exposed the first place, but my time-machine
is out of order...

> Are you sure that the ASN.1 BIT STRING value is really stored as an ASN.1
> STRING in a X500_NAME_ENTRY, when it is a binary value and not a text value?

Yes, it is stored as ASN.1 string, which is just a buffer with a length,
but also has:

struct asn1_string_st {
int length;
int type;
unsigned char *data;
/*
 * The value of the following field depends on the type being held.  It
 * is mostly being used for BIT_STRING so if the input data has a
 * non-zero 'unused bits' value, it will be handled correctly
 */
long flags;
};

a type field (the NID for the associated OID) and flags as noted
in the comment.

> Regardless, I did try this as you helpfully suggested:
> 
> (X509_NAME_ENTRY_get_data (nameEntry)->flags) |=
> (ASN1_STRING_FLAG_BITS_LEFT | i);
> 
> And it seems to be working properly for x500UniqueIdentifer attribute,
> without any errors I can find during compile or in the content of the
> resulting certificates.
> 
> Thank you very much for your assistance.

You're welcome, that is the correct technique at present.  We should
perhaps provide getter/setter functions for the flags, or perhaps
even a specific function for indicating the value is a bitstring,
and how many bits it holds.  For now the ASN.1 string is not an
opaque structure.

-- 
Viktor.


Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Lisa Matias
Sorry, I was just frustrated that the changes to OpenSSL 1.1.1 broke code
which worked for nearly 15 years, by denying access to previously
accessible C structs.

I was able to use OpenSSL to generate a certificate with a subject
containing the x500UniqueIdentifier attribute as a pure ASN.1 BIT STRING,
as you can see with the following snippet from OpenSSL asn1parse.

  ___:d=5  hl=2 l=   3 prim: OBJECT:x500UniqueIdentifier
  ___:d=5  hl=2 l=  16 prim: BIT STRING

Are you sure that the ASN.1 BIT STRING value is really stored as an ASN.1
STRING in a X500_NAME_ENTRY, when it is a binary value and not a text value?

Regardless, I did try this as you helpfully suggested:

(X509_NAME_ENTRY_get_data (nameEntry)->flags) |=
(ASN1_STRING_FLAG_BITS_LEFT | i);


And it seems to be working properly for x500UniqueIdentifer attribute,
without any errors I can find during compile or in the content of the
resulting certificates.

Thank you very much for your assistance.

Lisa.


On Tue, 18 Jun 2019 at 12:30, Viktor Dukhovni 
wrote:

> On Tue, Jun 18, 2019 at 07:16:46AM -0700, Lisa Matias wrote:
>
> > If you look here:
> >
> > https://www.openssl.org/docs/man1.1.0/man3/X509_NAME_ENTRY_get_data.html
> >
> > It states:
> >
> > *X509_NAME_ENTRY_get_data() retrieves the field value of ne in
> > and ASN1_STRING structure.*
>
> Regardless of the entry type, the underlying value is always stored
> as an ASN.1 string.
>
> struct X509_name_entry_st {
> ASN1_OBJECT *object;/* AttributeType */
> ASN1_STRING *value; /* AttributeValue */
> int set;/* index of RDNSequence for this entry
> */
> int size;   /* temp variable */
> };
>
> The flags you're looking for are associated with the ASN.1 string.
> To indicate that it is a bit-string you set:
>
> value->flags |= ASN1_STRING_FLAG_BITS_LEFT | i
>
> where "i" is the number of unused bits in the final octet.
>
> > Unfortunately this does not work for any non-string X.500 attributes such
> > as x500UniqueIdentifer which is defined as an ASN.1 BIT STRING.
>
> Actually, it does.
>
> --
> Viktor.
>


Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Viktor Dukhovni
On Tue, Jun 18, 2019 at 07:16:46AM -0700, Lisa Matias wrote:

> If you look here:
> 
> https://www.openssl.org/docs/man1.1.0/man3/X509_NAME_ENTRY_get_data.html
> 
> It states:
> 
> *X509_NAME_ENTRY_get_data() retrieves the field value of ne in
> and ASN1_STRING structure.*

Regardless of the entry type, the underlying value is always stored
as an ASN.1 string.

struct X509_name_entry_st {
ASN1_OBJECT *object;/* AttributeType */
ASN1_STRING *value; /* AttributeValue */
int set;/* index of RDNSequence for this entry */
int size;   /* temp variable */
};

The flags you're looking for are associated with the ASN.1 string.
To indicate that it is a bit-string you set:

value->flags |= ASN1_STRING_FLAG_BITS_LEFT | i

where "i" is the number of unused bits in the final octet.

> Unfortunately this does not work for any non-string X.500 attributes such
> as x500UniqueIdentifer which is defined as an ASN.1 BIT STRING.

Actually, it does.

-- 
Viktor.


Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-18 Thread Lisa Matias
If you look here:

https://www.openssl.org/docs/man1.1.0/man3/X509_NAME_ENTRY_get_data.html

It states:

*X509_NAME_ENTRY_get_data() retrieves the field value of ne in
and ASN1_STRING structure.*


Unfortunately this does not work for any non-string X.500 attributes such
as x500UniqueIdentifer which is defined as an ASN.1 BIT STRING.

I am only looking to fix in OpenSSL 1.1.1, what was previously working in
all older versions of OpenSSL all the way back to 0.9.7 which included a
way to support non-string attributes in X509_NAME_ENTRY.

Thanks.

Lisa.



On Mon, 17 Jun 2019 at 22:37, Viktor Dukhovni 
wrote:

> On Mon, Jun 17, 2019 at 09:19:41PM -0700, Lisa Matias wrote:
>
> > X509_NAME_ENTRY *nameEntry;
> > nameEntry = X509_NAME_ENTRY_create_by_NID (, nid,
> > derTagToVType (tag), buffer, bufferLength);
> > *nameEntry->value->flags = specifiedFlags;*
>
> Can you be a bit more explicit about why you need to do this?
> What flags do you intend to set and why?
>
> That said, you can use:
>
> ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne);
>
> to get the ASN1_STRING holding the value, and since ASN1_STRINGs
> are not opaque types, you can just use:
>
> value->flags = ...
>
> asuming that's a sensible thing to do.  You may however be straying
> into undocumented behaviour, and so it might be good to know whether
> perhaps there's a better way of getting the result you actually want.
>
> --
> Viktor.
>


Re: how to set flags in X509_NAME_ENTRY in OpenSSL 1.1.1

2019-06-17 Thread Viktor Dukhovni
On Mon, Jun 17, 2019 at 09:19:41PM -0700, Lisa Matias wrote:

> X509_NAME_ENTRY *nameEntry;
> nameEntry = X509_NAME_ENTRY_create_by_NID (, nid,
> derTagToVType (tag), buffer, bufferLength);
> *nameEntry->value->flags = specifiedFlags;*

Can you be a bit more explicit about why you need to do this?
What flags do you intend to set and why?

That said, you can use:

ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne);

to get the ASN1_STRING holding the value, and since ASN1_STRINGs
are not opaque types, you can just use:

value->flags = ...

asuming that's a sensible thing to do.  You may however be straying
into undocumented behaviour, and so it might be good to know whether
perhaps there's a better way of getting the result you actually want.

-- 
Viktor.