Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Apache: Dev

SSLRequire: requiring a particular OID in extKeyUsage

 

 

Apache dev RSS feed   Index | Next | Previous | View Threaded


minfrin at sharp

Oct 9, 2009, 10:56 AM

Post #1 of 4 (221 views)
Permalink
SSLRequire: requiring a particular OID in extKeyUsage

Hi all,

I am trying to solve the problem of limiting access to those who present
a client cert containing a specific extKeyUsage OID.

So far, the config that I have for httpd-trunk is this:

SSLRequire "1.3.6.1.5.5.7.3.4" in PeerExtList("2.5.29.37")

Stepping through the code in a debugger, the PeerExtList() returns a
list containing just one single entry in the list: "A, B, C", when in
theory, it should return an actual list "A, "B", "C".

As a result, while stepping through the code, an attempt is made to
compare "B" with "A, B, C", and this comparison fails, and we get 403
forbidden (I would have expected it to compare "B" to "A", "B" and then
(not) "C" in turn, resulting in success).

Can someone confirm for me whether I am using SSLRequire correctly, or
whether I have found something that needs a patch?

I tried this also on httpd-2.2, using the config below, and this gives
the same behaviour:

SSLRequire "1.3.6.1.5.5.7.3.4" in OID("2.5.29.37")

Regards,
Graham
--
Attachments: smime.p7s (3.22 KB)


jorton at redhat

Oct 15, 2009, 5:49 AM

Post #2 of 4 (184 views)
Permalink
Re: SSLRequire: requiring a particular OID in extKeyUsage [In reply to]

On Fri, Oct 09, 2009 at 07:56:42PM +0200, Graham Leggett wrote:
> I am trying to solve the problem of limiting access to those who present
> a client cert containing a specific extKeyUsage OID.
>
> So far, the config that I have for httpd-trunk is this:
>
> SSLRequire "1.3.6.1.5.5.7.3.4" in PeerExtList("2.5.29.37")
>
> Stepping through the code in a debugger, the PeerExtList() returns a
> list containing just one single entry in the list: "A, B, C", when in
> theory, it should return an actual list "A, "B", "C".

Are you trying to match against the contents of the (single) extKeyUsage
extension? That isn't how PeerExtList works, or at least, was written
and documented to work, AFAICT: PeerExtList will return a list of the
value of each extension in the cert with the given OID.

Does that make sense? This is just from reading the trunk code/docs, I
may be missing something.

To solve your problem: parsing the string which OpenSSL spits out as a
representation of the extKeyUsage list would sound a bit hacky. I guess
I'd recommend doing it as a set of custom variables:

SSL_{CLIENT,SERVER}_EXT_KEYUSAGE_{CLIENT_AUTH,EMAIL_PROTECTION,...}

which evaluate to 0 or 1 depending on whether the indicated usage is
present in the extKeyUsage extension. Would something like that work?

Regards, Joe


minfrin at sharp

Oct 15, 2009, 6:43 AM

Post #3 of 4 (181 views)
Permalink
Re: SSLRequire: requiring a particular OID in extKeyUsage [In reply to]

Joe Orton wrote:

> Are you trying to match against the contents of the (single) extKeyUsage
> extension? That isn't how PeerExtList works, or at least, was written
> and documented to work, AFAICT: PeerExtList will return a list of the
> value of each extension in the cert with the given OID.
>
> Does that make sense? This is just from reading the trunk code/docs, I
> may be missing something.
>
> To solve your problem: parsing the string which OpenSSL spits out as a
> representation of the extKeyUsage list would sound a bit hacky. I guess
> I'd recommend doing it as a set of custom variables:
>
> SSL_{CLIENT,SERVER}_EXT_KEYUSAGE_{CLIENT_AUTH,EMAIL_PROTECTION,...}
>
> which evaluate to 0 or 1 depending on whether the indicated usage is
> present in the extKeyUsage extension. Would something like that work?

The problem I'm trying to solve is that we'll be issuing certs with our
own extKeyUsage values, and I would imagine they would be inventing
values with custom oids for various purposes, so something generic would
be needed, as opposed to fixed "well known" oids.

One of the key things I was struggling with was trying to understand how
it currently was supposed to work, so I didn't hack it in the wrong
direction.

From what I can see, we have a set of oid values (which in this case,
extKeyUsage, which contains just one value: "A,B,C") associated with a
key, which can in turn can contain a set of values (which in this case
contains "A", "B" and "C").

Looking further at the expression syntax of SSLRequire, it looks like
this might do the trick:

SSLRequire "1.3.6.1.5.5.7.3.4" in { PeerExtList("2.5.29.37") }

Let me dig and see if it works.

Regards,
Graham
--


jorton at redhat

Oct 15, 2009, 7:31 AM

Post #4 of 4 (182 views)
Permalink
Re: SSLRequire: requiring a particular OID in extKeyUsage [In reply to]

On Thu, Oct 15, 2009 at 03:43:36PM +0200, Graham Leggett wrote:
> Joe Orton wrote:
>
> > Are you trying to match against the contents of the (single) extKeyUsage
> > extension? That isn't how PeerExtList works, or at least, was written
> > and documented to work, AFAICT: PeerExtList will return a list of the
> > value of each extension in the cert with the given OID.
> >
> > Does that make sense? This is just from reading the trunk code/docs, I
> > may be missing something.
> >
> > To solve your problem: parsing the string which OpenSSL spits out as a
> > representation of the extKeyUsage list would sound a bit hacky. I guess
> > I'd recommend doing it as a set of custom variables:
> >
> > SSL_{CLIENT,SERVER}_EXT_KEYUSAGE_{CLIENT_AUTH,EMAIL_PROTECTION,...}
> >
> > which evaluate to 0 or 1 depending on whether the indicated usage is
> > present in the extKeyUsage extension. Would something like that work?
>
> The problem I'm trying to solve is that we'll be issuing certs with our
> own extKeyUsage values, and I would imagine they would be inventing
> values with custom oids for various purposes, so something generic would
> be needed, as opposed to fixed "well known" oids.

OK, fair enough. So, maybe just a function (bleh) which takes an OID
and returns true/false if there is an extended key usage extension
present with the given key purpose OID listed?

SSLRequire PeerKeyPurpose("OID")

> One of the key things I was struggling with was trying to understand how
> it currently was supposed to work, so I didn't hack it in the wrong
> direction.
>
> >From what I can see, we have a set of oid values (which in this case,
> extKeyUsage, which contains just one value: "A,B,C") associated with a
> key, which can in turn can contain a set of values (which in this case
> contains "A", "B" and "C").

Kind of. A certificate can have any number of extensions. Each
extension is a (key, value) pair, where the key is an OID, and the value
is an ASN.1 structure specific to the key. When evaluating "foo in
PeerExtList(bar)", mod_ssl will look at each extension with key OID
'bar' and transform the associated ASN.1 structure to a string, then
return true if any of those strings match 'foo'.

The "extended key usage" extension is defined simply as a list of OIDs -
from the ASN.1 in RFC 5280:

ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId

KeyPurposeId ::= OBJECT IDENTIFIER

when you use PeerExtList on that structure, OpenSSL will do something
random, unspecified, and possibly useful to that ASN.1 structure, to
transform it into a string. From your testing results, it makes a
comma-separated string of the OID numbers.

The wrong way to solve this is to have OpenSSL go through all those
hoops to transform the ASN.1 extension value into a string, parse the
string, and then match against the returned OIDs. The way OpenSSL does
that is unspecified and may change - maybe it will use spaces to
separate the OIDs in a future version, for example. Who knows.

The right way to solve this is to extract the EXTENDED_KEY_USAGE OpenSSL
data structure and match against the OIDs, without converting it to a
string. SSL_X509_isSGC has an example of how to do this, though uses an
older extension API; ssl_engine_ocsp.c:extract_responder_uri is a better
example of using the OpenSSL extension API.

> Looking further at the expression syntax of SSLRequire, it looks like
> this might do the trick:
>
> SSLRequire "1.3.6.1.5.5.7.3.4" in { PeerExtList("2.5.29.37") }

This won't match the grammar - the docs do show this accurately, it must
be SSLRequire "foo" in PeerExtList("..."), if you look at the code in
ssl_expr_eval.c it has a special case for PeerExtList in the code
handling the "in" operator.

Regards, Joe

Apache dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.