Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-23 Thread Michael Richardson

Blumenthal, Uri - 0553 - MITLL  wrote:
> Hmm... Registering an OID dedicated to express this case should be
> feasible, and perfectly within the ASN.1 rules. One question - where in
> the OID tree would it live, as offhand I don't have any idea. It can't
> be too deep down, and also, it better be fairly short.

In some vendor PEN space if 0.0 is a bad idea.
I'm sure that someone has one, or I can volunteer a number from mine.
I don't see why it has to be short if it never leaves in a legitimate CSR.

> From the ASN.1 point of view - there's nothing dumb in this
> idea. There's plenty of MIB objects expressing/representing all kinds
> of things - might as well add this.

+1.

--
]   Never tell me the odds! | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works| network architect  [
] m...@sandelman.ca  http://www.sandelman.ca/|   ruby on rails[



signature.asc
Description: PGP signature


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-22 Thread Blumenthal, Uri - 0553 - MITLL
Hmm... Registering an OID dedicated to express this case should be feasible, 
and perfectly within the ASN.1 rules. One question - where in the OID tree 
would it live, as offhand I don't have any idea. It can't be too deep down, and 
also, it better be fairly short.  

>From the ASN.1 point of view - there's nothing dumb in this idea. There's 
>plenty of MIB objects expressing/representing all kinds of things - might as 
>well add this.



On 3/22/19, 12:34, "openssl-users on behalf of Michael Wojcik" 
 
wrote:

> From: openssl-users [mailto:openssl-users-boun...@openssl.org] On Behalf 
Of
> Viktor Dukhovni
> Sent: Thursday, March 21, 2019 14:07
> To: openssl-users@openssl.org
>
> > On Mar 21, 2019, at 1:57 PM, Viktor Dukhovni 

> wrote:
> >
> >2.  Emit a "harmless" default OID (such as 0.0), returning to
> > the behaviour prior to 1.0.1i

What about registering a new OID for "missing required object"? Then at 
least there'd be a standard way to represent this case, and other parsers could 
decide to accommodate it however they prefer.

I'm by no means an ASN.1 expert, so this may be a dumb idea.

--
Michael Wojcik
Distinguished Engineer, Micro Focus






smime.p7s
Description: S/MIME cryptographic signature


RE: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-22 Thread Michael Wojcik
> From: openssl-users [mailto:openssl-users-boun...@openssl.org] On Behalf Of
> Viktor Dukhovni
> Sent: Thursday, March 21, 2019 14:07
> To: openssl-users@openssl.org
>
> > On Mar 21, 2019, at 1:57 PM, Viktor Dukhovni 
> wrote:
> >
> >2.  Emit a "harmless" default OID (such as 0.0), returning to
> > the behaviour prior to 1.0.1i

What about registering a new OID for "missing required object"? Then at least 
there'd be a standard way to represent this case, and other parsers could 
decide to accommodate it however they prefer.

I'm by no means an ASN.1 expert, so this may be a dumb idea.

--
Michael Wojcik
Distinguished Engineer, Micro Focus





Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-21 Thread Viktor Dukhovni
> On Mar 21, 2019, at 1:57 PM, Viktor Dukhovni  
> wrote:
> 
>1.  Return failure from i2d_ASN_OBJECT(), which then percolates
>   up to failure to encode the containing structure.
> 
>2.  Emit a "harmless" default OID (such as 0.0), returning to
>   the behaviour prior to 1.0.1i
> 
>3.  Emit the invalid empty OID (06 00) in the expectation that
>   this would not be something that other decoders would have
>   to support.  That is, it would only be used, as in this case,
>   to serialize and deserialize objects *within* an application,
>   and there would be no pressure on other implementations to
>   follow suit.
> 
> I am curious what other OpenSSL developers and users would like to
> see happen.  Any of the above?  Or something else?  The present
> behaviour seems wrong to me, because we're silently generating
> invalid structures with missing required fields (when encoding
> incompletely initialized structures).

I've opened https://github.com/openssl/openssl/issues/8553 to track
this issue.

-- 
Viktor.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-21 Thread Blumenthal, Uri - 0553 - MITLL
First, let me prefix that while I don't want to badmouth anybody, even 
incompetence cannot excuse deliberately generating bad/unparsable encoding. 
That's one of the cases when the cure is clearly worse than the disease.

On 3/21/19, 13:58, "openssl-users on behalf of Viktor Dukhovni" 
 
wrote:
> > On the OpenSSL side, having found that we emit dubious encodings
> > of structures with an (unspecified) null OID element, I am considering
> > whether it would make sense to encode them as a zero-length (invalid,
> > but faithful) ASN.1 OBJECT:
> > 
> >06 00
> > 
> > *and* decode these back to a zero length NID_undef object.

After discussing this idea with a friend, I am less enthusiastic
about this option.  His point is that if OpenSSL starts emitting
invalid empty OIDs as a way to support encoding incompletely
initialized structures, this could contaminate the ecosystem with
subsequent new downstream work-arounds in other implementations.

I don't see how it is worse than what's there now.

His order of "preference" is:

1.  Return failure from i2d_ASN_OBJECT(), which then percolates
up to failure to encode the containing structure.

That would be the correct but strict behavior: OID is required, therefore no 
OID -> no encoding. Just fail (hopefully with an explanatory error code, and 
documented!)

2.  Emit a "harmless" default OID (such as 0.0), returning to
the behaviour prior to 1.0.1i

I'm OK with that, and it's probably more acceptable than (1), though OID "0.0" 
is not the same as "no-OID". I wonder if there's ever a case when OID "0.0" can 
appear in this construct? If so, then (2) is unacceptable, otherwise I don't 
know.

But the original "fix" (can't call it that but in quotes and with big 
tongue-in-cheek) was there for a reason, however misguided the actual change 
turned out to be. What was the reason for changing this (original) behavior? 
Just desire for "purity" (), or something more tangible/reasonable?

3.  Emit the invalid empty OID (06 00) in the expectation that
this would not be something that other decoders would have
to support.  That is, it would only be used, as in this case,
to serialize and deserialize objects *within* an application,
and there would be no pressure on other implementations to
follow suit.

I'm OK with (3) too. In fact, this would probably be my first preference - and 
yes, implementations that care to support use cases with no-OID would have to 
support this. But at least they won't have a broken parser on their hands.

Failing in i2d_ASN1_OBJECT() is unlikely to do harm, because the
current invalid output is not better, and we've not seen any
complaints until now in ~5 years of OpenSSL 1.0.2 deployment.
So use of i2d on partially created objects looks rather rare,
and perhaps explicit failure is better than any ad-hoc output?

Failing in i2d_ASN1_OBJECT() would be my second preference. My first preference 
would be your (3). I can live with (2), but I don't like it much because 
substituting a valid OID for a no-OID is "slippery".
 


smime.p7s
Description: S/MIME cryptographic signature


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-21 Thread Viktor Dukhovni
On Thu, Mar 21, 2019 at 05:22:24PM +, Blumenthal, Uri - 0553 - MITLL wrote:

> > On the DER padding front, the minimal
> > working suffix is 7 bytes:

Apparently I can't count today, clearly the suffix is 8 bytes.

> > 
> >30 03-- Length 3 sequence
> >06 01 00 -- OBJECT ID: 0.0
> >03 01 00 -- empty BIT STRING
> > 
> > On the OpenSSL side, having found that we emit dubious encodings
> > of structures with an (unspecified) null OID element, I am considering
> > whether it would make sense to encode them as a zero-length (invalid,
> > but faithful) ASN.1 OBJECT:
> > 
> >06 00
> > 
> > *and* decode these back to a zero length NID_undef object.

After discussing this idea with a friend, I am less enthusiastic
about this option.  His point is that if OpenSSL starts emitting
invalid empty OIDs as a way to support encoding incompletely
initialized structures, this could contaminate the ecosystem with
subsequent new downstream work-arounds in other implementations.

His order of "preference" is:

1.  Return failure from i2d_ASN_OBJECT(), which then percolates
up to failure to encode the containing structure.

2.  Emit a "harmless" default OID (such as 0.0), returning to
the behaviour prior to 1.0.1i

3.  Emit the invalid empty OID (06 00) in the expectation that
this would not be something that other decoders would have
to support.  That is, it would only be used, as in this case,
to serialize and deserialize objects *within* an application,
and there would be no pressure on other implementations to
follow suit.

I am curious what other OpenSSL developers and users would like to
see happen.  Any of the above?  Or something else?  The present
behaviour seems wrong to me, because we're silently generating
invalid structures with missing required fields (when encoding
incompletely initialized structures).

Failing in i2d_ASN1_OBJECT() is unlikely to do harm, because the
current invalid output is not better, and we've not seen any
complaints until now in ~5 years of OpenSSL 1.0.2 deployment.
So use of i2d on partially created objects looks rather rare,
and perhaps explicit failure is better than any ad-hoc output?

-- 
Viktor.


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-21 Thread Blumenthal, Uri - 0553 - MITLL
+1 to Viktor's points.

Regards,
Uri

Sent from my iPhone

> On Mar 21, 2019, at 12:52, Viktor Dukhovni  wrote:
> 
> On Thu, Mar 21, 2019 at 01:00:14PM +, Salz, Rich via openssl-users wrote:
> 
>>>   This software however is 7 years old, we’re not in a position to drop 
>>> everything and rewrite it.
>> 
>> Then don't upgrade?  If it's for a CA you don't need TLS 1.3 for example.
>> 
>> Or take the existing OpenSSL code that works and jam it into the current 
>> release.
> 
> Perhaps the OP is not an end-user, but rather maintains these modules
> for a user community, in which case "don't upgrade" is not generally
> an option.  In any case, it seems a bit premature to close the
> conversation.
> 
> While the original decision to use incomplete (and thus invalid)
> CSRs, is unfortunate, and not OpenSSL's fault, we can still continue
> to discuss meaningful options.  On the DER padding front, the minimal
> working suffix is 7 bytes:
> 
>30 03-- Length 3 sequence
>06 01 00 -- OBJECT ID: 0.0
>03 01 00 -- empty BIT STRING
> 
> One then also prepends a prefix (typically 4 bytes):
> 
>30 82 xx xx -- a sequence of 256 to 65535 bytes
>30 81 xx-- a sequence of 128 to 255 bytes
>30 xx   -- a sequence of up to 127 bytes
> 
> The "xx" length is the DER length of the CRI + 7 bytes for the
> suffix.
> 
> On the OpenSSL side, having found that we emit dubious encodings
> of structures with an (unspecified) null OID element, I am considering
> whether it would make sense to encode them as a zero-length (invalid,
> but faithful) ASN.1 OBJECT:
> 
>06 00
> 
> *and* decode these back to a zero length NID_undef object.  While
> these are likely to not interoperate with many other ASN.1 decoder
> implementations, just interoperating with the same version of OpenSSL
> would make it possible to encode/decode partially initialized
> structures in which some "objects" are as yet unspecified.
> 
> The reason I'm considering changes is that it now appears that the
> original commmit that stopped encoding single element OIDs, is not
> fully baked.  Just skipping required components of structures is
> not a good outcome.
> 
> -- 
>Viktor.


smime.p7s
Description: S/MIME cryptographic signature


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-21 Thread Viktor Dukhovni
On Thu, Mar 21, 2019 at 01:00:14PM +, Salz, Rich via openssl-users wrote:

> >This software however is 7 years old, we’re not in a position to drop 
> > everything and rewrite it.
> 
> Then don't upgrade?  If it's for a CA you don't need TLS 1.3 for example.
> 
> Or take the existing OpenSSL code that works and jam it into the current 
> release.

Perhaps the OP is not an end-user, but rather maintains these modules
for a user community, in which case "don't upgrade" is not generally
an option.  In any case, it seems a bit premature to close the
conversation.

While the original decision to use incomplete (and thus invalid)
CSRs, is unfortunate, and not OpenSSL's fault, we can still continue
to discuss meaningful options.  On the DER padding front, the minimal
working suffix is 7 bytes:

30 03-- Length 3 sequence
06 01 00 -- OBJECT ID: 0.0
03 01 00 -- empty BIT STRING

One then also prepends a prefix (typically 4 bytes):

30 82 xx xx -- a sequence of 256 to 65535 bytes
30 81 xx-- a sequence of 128 to 255 bytes
30 xx   -- a sequence of up to 127 bytes

The "xx" length is the DER length of the CRI + 7 bytes for the
suffix.

On the OpenSSL side, having found that we emit dubious encodings
of structures with an (unspecified) null OID element, I am considering
whether it would make sense to encode them as a zero-length (invalid,
but faithful) ASN.1 OBJECT:

06 00

*and* decode these back to a zero length NID_undef object.  While
these are likely to not interoperate with many other ASN.1 decoder
implementations, just interoperating with the same version of OpenSSL
would make it possible to encode/decode partially initialized
structures in which some "objects" are as yet unspecified.

The reason I'm considering changes is that it now appears that the
original commmit that stopped encoding single element OIDs, is not
fully baked.  Just skipping required components of structures is
not a good outcome.

-- 
Viktor.


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-21 Thread Salz, Rich via openssl-users
>This software however is 7 years old, we’re not in a position to drop 
> everything and rewrite it.
  

Then don't upgrade?  If it's for a CA you don't need TLS 1.3 for example.

Or take the existing OpenSSL code that works and jam it into the current 
release.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-20 Thread Viktor Dukhovni
> On Mar 20, 2019, at 9:35 PM, Viktor Dukhovni  
> wrote:
> 
> Your github issue notes a change from 1.0.1 to 1.0.2, not a change
> within the 1.0.2 patch release series...
> 
> Changes of behaviour between 1.0.1 and 1.0.2 were not off limits.
> 
> When testing a short program to reproduce the reported symptoms
> I see the same output encoding (BAD OBJECT) with both 1.0.1 and
> 1.0.2.  For me, it is only 0.9.8 and 1.0.0 that generate the "0" OID.

The change dates back to:

  
https://github.com/openssl/openssl/commit/38a503fb8adaad331b8a67aaa9eb2fa915113ed0

which first appeared in OpenSSL 1.0.1i.  It was cherry-picked onto the
1.0.2 branch:

   
https://github.com/openssl/openssl/commit/ff4cfc4c588c41d5e8d2d530231bc36cbc525add

The effect of this is that "NID_undef" generates an empty ASN.1 value, rather
than an OID of "0.0".  Single component OIDs are not representable in ASN.1
BER/DER since the OID encoding combines the first elements as a single value.

Encoding "NID_undef" (uninitialized OID) as 0.0 isn't right, because there is no
OID, and we're pretending to have an OID of 0.0.  Of course not encoding 
anything
isn't great either, we're then skipping an element of the enclosing structure 
and
generating incorrect ASN.1 for the containing structure.

Really what could/should probably happen here, is that i2d should fail, because
the structure specifies an object that has no ASN.1 encoding.

-- 
Viktor.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-20 Thread Viktor Dukhovni
> On Mar 20, 2019, at 8:36 PM, Graham Leggett  wrote:
> 
> The problem seems that at some point during the 1.0.2 releases, the X509_REQ 
> was previously serialised with what looks like an empty X509_ALGOR structure:
> 
> 507:d=2  hl=2 l=   1 prim: OBJECT:itu-t
> 
> and at some point openssl changed to serialise with a bad object instead:
> 
> 508:d=2  hl=2 l=   0 prim: OBJECT:BAD OBJECT
> 
> A change from something from optional to mandatory should have happened in 
> the 1.1.0 release, not within the 1.0.2 point releases.

Sorry, are you saying that the serialized form changed in a 1.0.2
patch release?  I may have missed that detail.

Your github issue notes a change from 1.0.1 to 1.0.2, not a change
within the 1.0.2 patch release series...

Changes of behaviour between 1.0.1 and 1.0.2 were not off limits.

When testing a short program to reproduce the reported symptoms
I see the same output encoding (BAD OBJECT) with both 1.0.1 and
1.0.2.  For me, it is only 0.9.8 and 1.0.0 that generate the "0" OID.

0:d=0  hl=3 l= 163 cons: SEQUENCE
3:d=1  hl=3 l= 152 cons: SEQUENCE
6:d=2  hl=2 l=   1 prim: INTEGER   :00
9:d=2  hl=2 l=  51 cons: SEQUENCE
   11:d=3  hl=2 l=  11 cons: SET
   13:d=4  hl=2 l=   9 cons: SEQUENCE
   15:d=5  hl=2 l=   3 prim: OBJECT:countryName
   20:d=5  hl=2 l=   2 prim: PRINTABLESTRING   :US
   24:d=3  hl=2 l=  13 cons: SET
   26:d=4  hl=2 l=  11 cons: SEQUENCE
   28:d=5  hl=2 l=   3 prim: OBJECT:organizationName
   33:d=5  hl=2 l=   4 prim: UTF8STRING:None
   39:d=3  hl=2 l=  21 cons: SET
   41:d=4  hl=2 l=  19 cons: SEQUENCE
   43:d=5  hl=2 l=   3 prim: OBJECT:commonName
   48:d=5  hl=2 l=  12 prim: UTF8STRING:test.example
   62:d=2  hl=2 l=  92 cons: SEQUENCE
   64:d=3  hl=2 l=  13 cons: SEQUENCE
   66:d=4  hl=2 l=   9 prim: OBJECT:rsaEncryption
   77:d=4  hl=2 l=   0 prim: NULL
   79:d=3  hl=2 l=  75 prim: BIT STRING
  156:d=2  hl=2 l=   0 cons: cont [ 0 ]
  158:d=1  hl=2 l=   3 cons: SEQUENCE
  160:d=2  hl=2 l=   1 prim: OBJECT:0.0
  163:d=1  hl=2 l=   1 prim: BIT STRING

With 1.0.1 I get:

0:d=0  hl=3 l= 162 cons: SEQUENCE
3:d=1  hl=3 l= 152 cons: SEQUENCE
6:d=2  hl=2 l=   1 prim: INTEGER   :00
9:d=2  hl=2 l=  51 cons: SEQUENCE
   11:d=3  hl=2 l=  11 cons: SET
   13:d=4  hl=2 l=   9 cons: SEQUENCE
   15:d=5  hl=2 l=   3 prim: OBJECT:countryName
   20:d=5  hl=2 l=   2 prim: PRINTABLESTRING   :US
   24:d=3  hl=2 l=  13 cons: SET
   26:d=4  hl=2 l=  11 cons: SEQUENCE
   28:d=5  hl=2 l=   3 prim: OBJECT:organizationName
   33:d=5  hl=2 l=   4 prim: UTF8STRING:None
   39:d=3  hl=2 l=  21 cons: SET
   41:d=4  hl=2 l=  19 cons: SEQUENCE
   43:d=5  hl=2 l=   3 prim: OBJECT:commonName
   48:d=5  hl=2 l=  12 prim: UTF8STRING:test.example
   62:d=2  hl=2 l=  92 cons: SEQUENCE
   64:d=3  hl=2 l=  13 cons: SEQUENCE
   66:d=4  hl=2 l=   9 prim: OBJECT:rsaEncryption
   77:d=4  hl=2 l=   0 prim: NULL
   79:d=3  hl=2 l=  75 prim: BIT STRING
  156:d=2  hl=2 l=   0 cons: cont [ 0 ]
  158:d=1  hl=2 l=   2 cons: SEQUENCE
  160:d=2  hl=2 l=   0 prim: OBJECT:BAD OBJECT
  162:d=1  hl=2 l=   1 prim: BIT STRING

-- 
Viktor.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-20 Thread Graham Leggett
On 19 Mar 2019, at 18:00, Viktor Dukhovni  wrote
:
> Well, the *standard* structure for passing around just the unsigned
> data underlying a CSR (X509_REQ), is a CertificationRequestInfo
> (X509_REQ_INFO).  So if the modules are to use *standard* structures
> to communicate.  The object being passed needs to be either a CSR
> (signed) or the enclosed CRI (unsigned).

I agree - it is the ideal structure to use, however translating this into real 
world implementation there aren’t any APIs in openssl that allow us to do this 
today, and it is very likely that the same limitation exists in other APIs we 
would like to support in future (NSS, native APIs, etc).

This software however is 7 years old, we’re not in a position to drop 
everything and rewrite it.

> You could, for example, sign the request with some suitable key
> (ideally the private key corresponding to the public key in the
> CSR, if available) before handing it off.  If the signing key is
> not the enclosed public key, it would not pass "req -verify" (it
> never did before either, for lack of a signature), but the called
> module would be able to decode a CSR, and work as before.

In our world we’re translating from various protocols (scep, spkac, etc etc) 
where proof of possession isn’t a signed X509_REQ, but is rather a challenge 
passphrase, previous certificate, etc etc, to a standard object (CSR) that can 
then be signed by a range of modules (simple local signing, signing on a 
smartcard, etc etc).

As a result while in the ideal world we would be dealing with signed CSRs, in 
our world we have to support a CSR with proof of possession supplied alongside 
in a range of possible formats.

We might have to go with the sign-with-a-dummy-signature route, but this would 
be unfortunate.

>> I don’t follow - in order to get access to the data inside the X509_REQ_INFO
>> structure, I need to first wrap it in a X509_REQ, otherwise I have no API
>> calls to get access to the data inside it.
> 
> No need to get access to the data inside an X509_REQ_INFO is expected.
> That object's sole purpose is to be serializable for signing.
> 
> You have rather an edge-case, where for some reason you're delegating
> signing to a CA module by passing it a non-standard structure that
> *resembles* a CSR, which is however for some reason not signed with
> the subject key (not signed at all), and you expect the CA to apply
> policy, by decoding the CRI inside  this non-CSR.
> 
> OpenSSL 1.1.x does not have structure member accessors for a CRI,
> but they would be easy to add, that's essentially what the X509_REQ
> accessors do:
> 
>long X509_REQ_get_version(const X509_REQ *req)
>{
>   return ASN1_INTEGER_get(req->req_info.version);
>}
> 
>X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req)
>{
>   return req->req_info.subject;
>}
> 
>int X509_REQ_get_attr_count(const X509_REQ *req)
>{
>   return X509at_get_attr_count(req->req_info.attributes);
>}
> 
>int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
>{
>   return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos);
>}
> 
>int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
>int lastpos)
>{
>   return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos);
>}
> 
>X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
>{
>   return X509at_get_attr(req->req_info.attributes, loc);
>}
> 
>X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
>{
>   return X509at_delete_attr(req->req_info.attributes, loc);
>}
> 
> If one were to "void the warranty", one could cast the (X509_REQ_INFO
> *) as an (X509_REQ *), and the accessors would just work, but you
> must not do that, the internal details might change some day, as
> they did between 1.1.x and 1.0.2 (where the X509_REQ_INFO is a
> separately allocated structure pointed to by the X509_REQ).

We’re a modular CA, we don’t dictate to our modules what they can and can’t do, 
so to say “that object’s sole purpose” is a contradiction.

It turns out that the module that checks the proof of possession against an 
LDAP server needs to pull out the subject of the CSR in order to make the LDAP 
query, which in turn means it needs to be able to read the contents of the 
X509_REQ (or X509_REQ_INFO).

X509_REQ_INFO prevents us from seeing the information, and so this won’t work 
for us.

>> The modules are Apache httpd modules, and the boundaries between the modules
>> are hooks that pass DER encoded structures between each module.
> 
> Well, so the key question is, why not pass an actual CSR.  What's
> preventing the CSR from being signed?

Protocols like scep and spkac don’t supply a CSR, that’s not how they work.

>>> This isn't pretty, and perhaps we need some new functions to explicitly
>>> embed a CRI in a CSR, but it is certainly something you can do 

Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-19 Thread Viktor Dukhovni
On Tue, Mar 19, 2019 at 02:04:14PM +0200, Graham Leggett wrote:

> > Why do you need to do the encode and decode?  What's wrong with the original
> > request object?
> 
> The code is a modular ca, and different modules communicate with each other
> generically using the standard DER encoded structures.

Well, the *standard* structure for passing around just the unsigned
data underlying a CSR (X509_REQ), is a CertificationRequestInfo
(X509_REQ_INFO).  So if the modules are to use *standard* structures
to communicate.  The object being passed needs to be either a CSR
(signed) or the enclosed CRI (unsigned).

You could, for example, sign the request with some suitable key
(ideally the private key corresponding to the public key in the
CSR, if available) before handing it off.  If the signing key is
not the enclosed public key, it would not pass "req -verify" (it
never did before either, for lack of a signature), but the called
module would be able to decode a CSR, and work as before.

> > > While I can see a d2i_X509_REQ_INFO() function, I can’t find a
> > > corresponding function in openssl 1.1.0+ that assigns this to a
> > > X509_REQ, unless I am missing it?
> > 
> > It should not be needed.
> 
> I don’t follow - in order to get access to the data inside the X509_REQ_INFO
> structure, I need to first wrap it in a X509_REQ, otherwise I have no API
> calls to get access to the data inside it.

No need to get access to the data inside an X509_REQ_INFO is expected.
That object's sole purpose is to be serializable for signing.

You have rather an edge-case, where for some reason you're delegating
signing to a CA module by passing it a non-standard structure that
*resembles* a CSR, which is however for some reason not signed with
the subject key (not signed at all), and you expect the CA to apply
policy, by decoding the CRI inside  this non-CSR.

OpenSSL 1.1.x does not have structure member accessors for a CRI,
but they would be easy to add, that's essentially what the X509_REQ
accessors do:

long X509_REQ_get_version(const X509_REQ *req)
{
return ASN1_INTEGER_get(req->req_info.version);
}

X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req)
{
return req->req_info.subject;
}

int X509_REQ_get_attr_count(const X509_REQ *req)
{
return X509at_get_attr_count(req->req_info.attributes);
}

int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
{
return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos);
}

int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
 int lastpos)
{
return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos);
}

X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
{
return X509at_get_attr(req->req_info.attributes, loc);
}

X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
{
return X509at_delete_attr(req->req_info.attributes, loc);
}

If one were to "void the warranty", one could cast the (X509_REQ_INFO
*) as an (X509_REQ *), and the accessors would just work, but you
must not do that, the internal details might change some day, as
they did between 1.1.x and 1.0.2 (where the X509_REQ_INFO is a
separately allocated structure pointed to by the X509_REQ).

> > Can you be more specific about these "module boundaries”?
> 
> The modules are Apache httpd modules, and the boundaries between the modules
> are hooks that pass DER encoded structures between each module.

Well, so the key question is, why not pass an actual CSR.  What's
preventing the CSR from being signed?

> > This isn't pretty, and perhaps we need some new functions to explicitly
> > embed a CRI in a CSR, but it is certainly something you can do in the
> > short term.
> 
> Can we not rather fix the initialisation of the X509_REQ in X509_REQ_new()
> so that it works like it used to? It seems like a massive headache to do
> something that used to be trivial.

No, because it is not broken.  The "massive headache" is peculiar to
the rather odd choice of "RPC" between these Apache modules, where
a non-CSR is masquerading as a CSR.

> I see there have been changes to openssl code relating to how structures
> are initialised, I suspect an error has crept in where an ASN.1 object is
> missing instead of empty, thus the malformed CSR.

There is no error.  The X509_REQ_INFO and X509_ALGOR (signature
algorithm) are now embedded in the CSR, and are no longer optional.

Your immediate choices are to sign a CSR, or to embed your CRI in
an outer DER wrapper that simulates a CSR.  Signing with some
key (ideally the subject key) seems simplest.

Even if we provide the "missing" CRI accessors in OpenSSL 1.1.1c,
I don't think that would practically solve your problem, because
some users would have 1.1.0, 1.1.1, 1.1.1a or 1.1.1b.

The DER wrapper is also simple (commented hex):

$ openssl req 

Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-19 Thread Graham Leggett
On 19 Mar 2019, at 03:22, Viktor Dukhovni  wrote:

>> On Mar 18, 2019, at 8:22 PM, Graham Leggett  wrote:
>> 
>> How would I decode the X509_REQ_INFO structure on the other side, turning it 
>> back into X509_REQ?
> 
> The function returns the DER form of the CRI, which can then be signed.
> You can use d2i_X509_REQ_INFO() to get an X509_REQ_INFO, but indeed there's
> not much you can do with that, other than DER-encode it again and sign.
> 
> Why do you need to do the encode and decode?  What's wrong with the original
> request object?

The code is a modular ca, and different modules communicate with each other 
generically using the standard DER encoded structures. Openssl isn’t visible 
through the API, it is an implementation detail.

>> While I can see a d2i_X509_REQ_INFO() function, I can’t find a corresponding 
>> function in openssl 1.1.0+ that assigns this to a X509_REQ, unless I am 
>> missing it?
> 
> It should not be needed.

I don’t follow - in order to get access to the data inside the X509_REQ_INFO 
structure, I need to first wrap it in a X509_REQ, otherwise I have no API calls 
to get access to the data inside it.

>> By way of concrete example, having crossed the module boundary we need to 
>> pull out details from the X509_REQ_INFO, which can only be done if this 
>> structure has been assigned to a X509_REQ first:
> 
> Can you be more specific about these "module boundaries”?

The modules are Apache httpd modules, and the boundaries between the modules 
are hooks that pass DER encoded structures between each module.

> In any case, given the DER form of the CRI, it is easy to construct
> the DER form of an enclosing CSR with a dummy signature:
> 
>   0:d=0  hl=4 l= 360 cons: SEQUENCE   -- Outer sequence and length:  
> 30 82 01 68
> 
>   4:d=1  hl=3 l= 210 cons: SEQUENCE   -- DER encoding of CRI
>   7:d=2  hl=2 l=   1 prim: INTEGER   :00
>   10:d=2  hl=2 l=   0 cons: SEQUENCE
>   12:d=2  hl=3 l= 159 cons: SEQUENCE
>   15:d=3  hl=2 l=  13 cons: SEQUENCE
>   17:d=4  hl=2 l=   9 prim: OBJECT:rsaEncryption
>   28:d=4  hl=2 l=   0 prim: NULL
>   30:d=3  hl=3 l= 141 prim: BIT STRING
>  174:d=2  hl=2 l=  41 cons: cont [ 0 ]
>  176:d=3  hl=2 l=  39 cons: SEQUENCE
>  178:d=4  hl=2 l=   9 prim: OBJECT:Extension Request
>  189:d=4  hl=2 l=  26 cons: SET
>  191:d=5  hl=2 l=  24 cons: SEQUENCE
>  193:d=6  hl=2 l=  22 cons: SEQUENCE
>  195:d=7  hl=2 l=   3 prim: OBJECT:X509v3 Subject Alternative 
> Name
>  200:d=7  hl=2 l=  15 prim: OCTET STRING  [HEX 
> DUMP]:300D820B6578616D706C652E636F6D
> 
>  217:d=1  hl=2 l=  13 cons: SEQUENCE  -- Signature algorithm OID 
> and parameters
>  219:d=2  hl=2 l=   9 prim: OBJECT:sha256WithRSAEncryption
>  230:d=2  hl=2 l=   0 prim: NULL
>  232:d=1  hl=3 l= 129 prim: BIT STRING-- Signature data
> 
> In the above we see that the CRI, needs (typically) an ~4-byte prefix
> of (0x30 + DER encoded length) and a suffix of the form:
> 
>   30 0d -- 13 byte sequence
>06 09 2a 86 48 86 f7 0d 01 01 0b  -- 9 byte OID 
> (sha256WithRSAEncryption)
>05 00 -- NULL parameters
>03 81 81 00   -- 128 byte bit string with 0 unused 
> bits
>xx xx xx xx ... xx-- 128 bytes of random data.
> 
> your random data could be all zeros.  The trailer length is then a
> fixed 147 bytes.  Add that to the length of CRI and prepend the
> outer sequence (0x30 + DER encoded (length CRI + 147)), then the
> CRI and then the trailer, and presto-magic you have a CSR with
> a bogus signature, but one that will encode and decode, just not
> pass "req -verify".
> 
> This isn't pretty, and perhaps we need some new functions to explicitly
> embed a CRI in a CSR, but it is certainly something you can do in the
> short term.

Can we not rather fix the initialisation of the X509_REQ in X509_REQ_new() so 
that it works like it used to? It seems like a massive headache to do something 
that used to be trivial.

I see there have been changes to openssl code relating to how structures are 
initialised, I suspect an error has crept in where an ASN.1 object is missing 
instead of empty, thus the malformed CSR.

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Viktor Dukhovni
> On Mar 18, 2019, at 8:22 PM, Graham Leggett  wrote:
> 
> How would I decode the X509_REQ_INFO structure on the other side, turning it 
> back into X509_REQ?

The function returns the DER form of the CRI, which can then be signed.
You can use d2i_X509_REQ_INFO() to get an X509_REQ_INFO, but indeed there's
not much you can do with that, other than DER-encode it again and sign.

Why do you need to do the encode and decode?  What's wrong with the original
request object?

> While I can see a d2i_X509_REQ_INFO() function, I can’t find a corresponding 
> function in openssl 1.1.0+ that assigns this to a X509_REQ, unless I am 
> missing it?

It should not be needed.

> By way of concrete example, having crossed the module boundary we need to 
> pull out details from the X509_REQ_INFO, which can only be done if this 
> structure has been assigned to a X509_REQ first:

Can you be more specific about these "module boundaries"?

In any case, given the DER form of the CRI, it is easy to construct
the DER form of an enclosing CSR with a dummy signature:

0:d=0  hl=4 l= 360 cons: SEQUENCE   -- Outer sequence and length:  
30 82 01 68

4:d=1  hl=3 l= 210 cons: SEQUENCE   -- DER encoding of CRI
7:d=2  hl=2 l=   1 prim: INTEGER   :00
   10:d=2  hl=2 l=   0 cons: SEQUENCE
   12:d=2  hl=3 l= 159 cons: SEQUENCE
   15:d=3  hl=2 l=  13 cons: SEQUENCE
   17:d=4  hl=2 l=   9 prim: OBJECT:rsaEncryption
   28:d=4  hl=2 l=   0 prim: NULL
   30:d=3  hl=3 l= 141 prim: BIT STRING
  174:d=2  hl=2 l=  41 cons: cont [ 0 ]
  176:d=3  hl=2 l=  39 cons: SEQUENCE
  178:d=4  hl=2 l=   9 prim: OBJECT:Extension Request
  189:d=4  hl=2 l=  26 cons: SET
  191:d=5  hl=2 l=  24 cons: SEQUENCE
  193:d=6  hl=2 l=  22 cons: SEQUENCE
  195:d=7  hl=2 l=   3 prim: OBJECT:X509v3 Subject Alternative 
Name
  200:d=7  hl=2 l=  15 prim: OCTET STRING  [HEX 
DUMP]:300D820B6578616D706C652E636F6D

  217:d=1  hl=2 l=  13 cons: SEQUENCE  -- Signature algorithm OID 
and parameters
  219:d=2  hl=2 l=   9 prim: OBJECT:sha256WithRSAEncryption
  230:d=2  hl=2 l=   0 prim: NULL
  232:d=1  hl=3 l= 129 prim: BIT STRING-- Signature data

In the above we see that the CRI, needs (typically) an ~4-byte prefix
of (0x30 + DER encoded length) and a suffix of the form:

30 0d -- 13 byte sequence
06 09 2a 86 48 86 f7 0d 01 01 0b  -- 9 byte OID 
(sha256WithRSAEncryption)
05 00 -- NULL parameters
03 81 81 00   -- 128 byte bit string with 0 unused 
bits
xx xx xx xx ... xx-- 128 bytes of random data.

your random data could be all zeros.  The trailer length is then a
fixed 147 bytes.  Add that to the length of CRI and prepend the
outer sequence (0x30 + DER encoded (length CRI + 147)), then the
CRI and then the trailer, and presto-magic you have a CSR with
a bogus signature, but one that will encode and decode, just not
pass "req -verify".

This isn't pretty, and perhaps we need some new functions to explicitly
embed a CRI in a CSR, but it is certainly something you can do in the
short term.

-- 
Viktor.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Graham Leggett
On 18 Mar 2019, at 22:02, Dave Coombs  wrote:

>> This makes sense - however there don’t appear to be any APIs in openssl that 
>> allow you to manipulate a X509_REQ_INFO structure. I can create it, and 
>> encode/decode it, but there is no X509_REQ_INFO_get_subject_name() (or 
>> friends) to populate the structure. X509_REQ_INFO itself is opaque.
> 
> I believe you said you're using 1.0.2, right?  The structures aren't opaque 
> there.  You can make your X509_REQ and populate its name etc as you already 
> are, and then i2d_X509_REQ_INFO its req_info member.
> 
> (Even in the 1.1 API, where they are opaque, i2d_re_X509_REQ_tbs will encode 
> a given X509_REQ's X509_REQ_INFO for you.)

How would I decode the X509_REQ_INFO structure on the other side, turning it 
back into X509_REQ?

While I can see a d2i_X509_REQ_INFO() function, I can’t find a corresponding 
function in openssl 1.1.0+ that assigns this to a X509_REQ, unless I am missing 
it?

By way of concrete example, having crossed the module boundary we need to pull 
out details from the X509_REQ_INFO, which can only be done if this structure 
has been assigned to a X509_REQ first:

https://source.redwax.eu/projects/RS/repos/mod_ca/browse/mod_ca_ldap.c#368

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Graham Leggett
On 18 Mar 2019, at 22:27, Viktor Dukhovni  wrote:

>> (Even in the 1.1 API, where they are opaque, i2d_re_X509_REQ_tbs will encode 
>> a given X509_REQ's X509_REQ_INFO for you.)
> 
> Yes, i2d_re_X509_REQ_tbs is the key function for constructing the
> "to be signed" (tbs) request:
> 
>  int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
>  {
>  req->req_info.enc.modified = 1;
>  return i2d_X509_REQ_INFO(>req_info, pp);
>  }
> 
> By setting the "modified" bit, it ensures that the DER representation
> will be re-generated with any changes made to the object.
> 
> So the OP can create the "partially filled in" X509_REQ and then call
> i2d_re_X509_REQ_tbs() function to generate the DER CRI blob to sign. 
> This removes any temptation to "cheat" by just casting the (X509_REQ *)
> as an (X509_REQ_INFO *) and calling i2d_X509_REQ_INFO() on that (first
> member of the X509_REQ structure).  The i2d_re_X509_REQ_tbs() function
> achieves the same effect in a type safe supported manner.

Can you confirm what structure is being encoded by i2d_re_X509_REQ_tbs, is this 
a X509_REQ_INFO?

The man page doesn’t explicitly specify the output formats of any of the 
related functions:

https://www.openssl.org/docs/man1.1.1/man3/i2d_re_X509_REQ_tbs.html

Looking at the source, we have X509_REQ_INFO being returned:

int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
{
req->req_info.enc.modified = 1;
return i2d_X509_REQ_INFO(>req_info, pp);
}

What would the corresponding functions need to be in the openssl v1.0.x world 
to achieve the same output as i2d_re_X509_REQ_tbs?

Would it just be to copy the above code in?

Regards,
Graham
—



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Viktor Dukhovni
> On Mar 18, 2019, at 4:02 PM, Dave Coombs  wrote:
> 
> (Even in the 1.1 API, where they are opaque, i2d_re_X509_REQ_tbs will encode 
> a given X509_REQ's X509_REQ_INFO for you.)

Yes, i2d_re_X509_REQ_tbs is the key function for constructing the
"to be signed" (tbs) request:

  int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
  {
  req->req_info.enc.modified = 1;
  return i2d_X509_REQ_INFO(>req_info, pp);
  }

By setting the "modified" bit, it ensures that the DER representation
will be re-generated with any changes made to the object.

So the OP can create the "partially filled in" X509_REQ and then call
i2d_re_X509_REQ_tbs() function to generate the DER CRI blob to sign. 
This removes any temptation to "cheat" by just casting the (X509_REQ *)
as an (X509_REQ_INFO *) and calling i2d_X509_REQ_INFO() on that (first
member of the X509_REQ structure).  The i2d_re_X509_REQ_tbs() function
achieves the same effect in a type safe supported manner.

-- 
Viktor.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Dave Coombs
> This makes sense - however there don’t appear to be any APIs in openssl that 
> allow you to manipulate a X509_REQ_INFO structure. I can create it, and 
> encode/decode it, but there is no X509_REQ_INFO_get_subject_name() (or 
> friends) to populate the structure. X509_REQ_INFO itself is opaque.

I believe you said you're using 1.0.2, right?  The structures aren't opaque 
there.  You can make your X509_REQ and populate its name etc as you already 
are, and then i2d_X509_REQ_INFO its req_info member.

(Even in the 1.1 API, where they are opaque, i2d_re_X509_REQ_tbs will encode a 
given X509_REQ's X509_REQ_INFO for you.)

Good luck,
  -Dave



smime.p7s
Description: S/MIME cryptographic signature


Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Graham Leggett
On 18 Mar 2019, at 18:49, Viktor Dukhovni  wrote:

> A mandatory part of the CSR is missing.  It is malformed.

Some further digging shows the CSR is indeed malformed - the old openssl code 
created a CSR like this:

  507:d=2  hl=2 l=   1 prim: OBJECT:itu-t

while the new openssl code produces a CSR like this:

  508:d=2  hl=2 l=   0 prim: OBJECT:BAD OBJECT

It looks like X509_REQ_new() in older versions of openssl created an object 
with an empty signature, while the new code produces a bad signature.

> Since you don't have a CSR, the fix is to not attempt to encode the data
> as a CSR.  It sounds like what you have is a CRI (that is a
> CertificationRequestInfo structure) so you'll need to encode that instead.
> 
>  https://tools.ietf.org/html/rfc2986#section-4
> 
> The relevant codec functions are:  i2d_X509_REQ_INFO and d2i_X509_REQ_INFO.
> 
> A CSR is:
> 
>   CertificationRequest ::= SEQUENCE {
>certificationRequestInfo CertificationRequestInfo,
>signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
>signature  BIT STRING
>   }
> 
> which encapsulates the CRI a larger signed structure, adding precisely
> the bits you're missing.

This makes sense - however there don’t appear to be any APIs in openssl that 
allow you to manipulate a X509_REQ_INFO structure. I can create it, and 
encode/decode it, but there is no X509_REQ_INFO_get_subject_name() (or friends) 
to populate the structure. X509_REQ_INFO itself is opaque.

> An alternative (if you must) is to create an actual CSR, with a dummy
> signature OID, and signature and then ignore the signature on the other
> side.

This looks like a workaround for now, what API call would I use to do that?

The X509_REQ structure is opaque, so I can’t see what options I have for 
setting any OIDs.

Regards,
Graham
—



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Viktor Dukhovni



> On Mar 18, 2019, at 6:51 AM, Graham Leggett  wrote:
> 
> The CSR is incomplete, but isn’t malformed.

A mandatory part of the CSR is missing.  It is malformed.

> The CSR is the in the process of being built. Part of that process involves 
> sending the partially complete CSR to another module, which then completes 
> the CSR structure. This used to work, but has regressed when moving from 
> rhel6 to rhel7.
> 
>> which has a non-zero length signature algorithm OID (l = 9).  Your
>> example has "l=0" where one would expect the signature OID after
>> the extensions.
> 
> How do I fix openssl to parse this as it did before?

Since you don't have a CSR, the fix is to not attempt to encode the data
as a CSR.  It sounds like what you have is a CRI (that is a
CertificationRequestInfo structure) so you'll need to encode that instead.

  https://tools.ietf.org/html/rfc2986#section-4

The relevant codec functions are:  i2d_X509_REQ_INFO and d2i_X509_REQ_INFO.

A CSR is:

   CertificationRequest ::= SEQUENCE {
certificationRequestInfo CertificationRequestInfo,
signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
signature  BIT STRING
   }

which encapsulates the CRI a larger signed structure, adding precisely
the bits you're missing.

An alternative (if you must) is to create an actual CSR, with a dummy
signature OID, and signature and then ignore the signature on the other
side.

-- 
Viktor.



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Graham Leggett
On 18 Mar 2019, at 12:51, Graham Leggett  wrote:

>> which has a non-zero length signature algorithm OID (l = 9).  Your
>> example has "l=0" where one would expect the signature OID after
>> the extensions.
> 
> How do I fix openssl to parse this as it did before?

I've raised this at https://github.com/openssl/openssl/issues/8514 to give more 
context.

Regards,
Graham
—



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-18 Thread Graham Leggett
On 18 Mar 2019, at 04:55, Viktor Dukhovni  wrote:

> On Mon, Mar 18, 2019 at 01:06:19AM +0200, Graham Leggett wrote:
> 
>> [root@localhost ~]# openssl req -in req.bin -inform der
>> unable to load X509 request
>> 139903756527504:error:0D0C40D8:asn1 encoding 
>> routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287:
>> 139903756527504:error:0D08303A:asn1 encoding 
>> routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 
>> error:tasn_dec.c:720:Field=algorithm, Type=X509_ALGOR
>> 139903756527504:error:0D08303A:asn1 encoding 
>> routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 
>> error:tasn_dec.c:720:Field=sig_alg, Type=X509_REQ
> 
> The CSR is malformed.

The CSR is incomplete, but isn’t malformed.

The CSR is the in the process of being built. Part of that process involves 
sending the partially complete CSR to another module, which then completes the 
CSR structure. This used to work, but has regressed when moving from rhel6 to 
rhel7.

> which has a non-zero length signature algorithm OID (l = 9).  Your
> example has "l=0" where one would expect the signature OID after
> the extensions.

How do I fix openssl to parse this as it did before?

Regards,
Graham
—



Re: i2d_X509_REQ() -> d2i_X509_REQ() = asn1 encoding routines:c2i_ASN1_OBJECT:invalid object encoding:a_object.c:287

2019-03-17 Thread Viktor Dukhovni
On Mon, Mar 18, 2019 at 01:06:19AM +0200, Graham Leggett wrote:

> [root@localhost ~]# openssl req -in req.bin -inform der
> unable to load X509 request
> 139903756527504:error:0D0C40D8:asn1 encoding routines:c2i_ASN1_OBJECT:invalid 
> object encoding:a_object.c:287:
> 139903756527504:error:0D08303A:asn1 encoding 
> routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 
> error:tasn_dec.c:720:Field=algorithm, Type=X509_ALGOR
> 139903756527504:error:0D08303A:asn1 encoding 
> routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 
> error:tasn_dec.c:720:Field=sig_alg, Type=X509_REQ

The CSR is malformed.

> The CSR can be found here: http://www.sharp.fm/req.bin
> 
> Would it be possible to confirm what is wrong with this request?

Running "openssl asn1parse -inform DER" we get:

0:d=0  hl=4 l= 509 cons: SEQUENCE
4:d=1  hl=4 l= 498 cons: SEQUENCE
8:d=2  hl=2 l=   1 prim: INTEGER   :00
   11:d=2  hl=2 l=  67 cons: SEQUENCE
   13:d=3  hl=2 l=  14 cons: SET
   15:d=4  hl=2 l=  12 cons: SEQUENCE
   17:d=5  hl=2 l=   3 prim: OBJECT:commonName
   22:d=5  hl=2 l=   5 prim: UTF8STRING:Test1
   29:d=3  hl=2 l=  49 cons: SET
   31:d=4  hl=2 l=  47 cons: SEQUENCE
   33:d=5  hl=2 l=   3 prim: OBJECT:serialNumber
   38:d=5  hl=2 l=  40 prim: PRINTABLESTRING   
:354616bb0358f9474f1e84af5550567f8b6c4d5b
   80:d=2  hl=4 l= 290 cons: SEQUENCE
   84:d=3  hl=2 l=  13 cons: SEQUENCE
   86:d=4  hl=2 l=   9 prim: OBJECT:rsaEncryption
   97:d=4  hl=2 l=   0 prim: NULL
   99:d=3  hl=4 l= 271 prim: BIT STRING
  374:d=2  hl=3 l= 129 cons: cont [ 0 ]
  377:d=3  hl=2 l=  42 cons: SEQUENCE
  379:d=4  hl=2 l=   9 prim: OBJECT:challengePassword
  390:d=4  hl=2 l=  29 cons: SET
  392:d=5  hl=2 l=  27 prim: IA5STRING :dfwrrdq4uhec96yj23io8soav0
  421:d=3  hl=2 l=  83 cons: SEQUENCE
  423:d=4  hl=2 l=   9 prim: OBJECT:Extension Request
  434:d=4  hl=2 l=  70 cons: SET
  436:d=5  hl=2 l=  68 cons: SEQUENCE
  438:d=6  hl=2 l=  66 cons: SEQUENCE
  440:d=7  hl=2 l=   3 prim: OBJECT:X509v3 Subject Alternative 
Name
  445:d=7  hl=2 l=  59 prim: OCTET STRING  [HEX 
DUMP]:303981373335343631366262303335386639343734663165383461663535353035363766386236633464356240756B2E736173686B65792E6F7267
  506:d=1  hl=2 l=   2 cons: SEQUENCE
  508:d=2  hl=2 l=   0 prim: OBJECT:BAD OBJECT:[]
  510:d=1  hl=2 l=   1 prim: BIT STRING

Whereas with:

$ openssl req -config <(
printf "distinguished_name = dn\n[dn]\nprompt=yes\n[v3req]\n%s\n" \
   "subjectAltName = DNS:example.com"
) -reqexts v3req -new -newkey rsa:1024 -keyout /dev/null \
  -nodes -subj / 2>/dev/null | openssl asn1parse

we get:

0:d=0  hl=4 l= 360 cons: SEQUENCE
4:d=1  hl=3 l= 210 cons: SEQUENCE
7:d=2  hl=2 l=   1 prim: INTEGER   :00
   10:d=2  hl=2 l=   0 cons: SEQUENCE
   12:d=2  hl=3 l= 159 cons: SEQUENCE
   15:d=3  hl=2 l=  13 cons: SEQUENCE
   17:d=4  hl=2 l=   9 prim: OBJECT:rsaEncryption
   28:d=4  hl=2 l=   0 prim: NULL
   30:d=3  hl=3 l= 141 prim: BIT STRING
  174:d=2  hl=2 l=  41 cons: cont [ 0 ]
  176:d=3  hl=2 l=  39 cons: SEQUENCE
  178:d=4  hl=2 l=   9 prim: OBJECT:Extension Request
  189:d=4  hl=2 l=  26 cons: SET
  191:d=5  hl=2 l=  24 cons: SEQUENCE
  193:d=6  hl=2 l=  22 cons: SEQUENCE
  195:d=7  hl=2 l=   3 prim: OBJECT:X509v3 Subject Alternative 
Name
  200:d=7  hl=2 l=  15 prim: OCTET STRING  [HEX 
DUMP]:300D820B6578616D706C652E636F6D
  217:d=1  hl=2 l=  13 cons: SEQUENCE
  219:d=2  hl=2 l=   9 prim: OBJECT:sha256WithRSAEncryption
  230:d=2  hl=2 l=   0 prim: NULL
  232:d=1  hl=3 l= 129 prim: BIT STRING

which has a non-zero length signature algorithm OID (l = 9).  Your
example has "l=0" where one would expect the signature OID after
the extensions.

-- 
Viktor.