Question: why doesn't my wildcard matching work with OpenSSL?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Question: why doesn't my wildcard matching work with OpenSSL?

Paul Smith
I'm having problems trying to get wildcard matching working with
OpenSSL.  Full hostname matching is working fine, but when my
certification uses a wildcard I always get an error.  That includes
both with OpenSSL 1.1.1b linked into my normal client, AND with the
openssl CLI with a system default version.  However, trying to use this
same certificate and hostname matching works fine with Java and Python
clients.

Note for my C client I have not set any special flags for matching, I'm
just using the default and using SSL_set1_host() to add the hostname.
But, I can't even get it to work with openssl itself.

I feel like I must be missing something dumb.  Any pointers
appreciated!

For example, here's a connection attempt using the CLI... note if I
remove the -verify_hostname option the connection works fine:


$ openssl s_client -connect admin0.domain:8004 \
    -CAfile ca.cert -verify_hostname admin0.domain

CONNECTED(00000003)
depth=1 C = US, ST = MA, L = Boston, O = Mycorp, OU = Eng, CN = ca.mycorp.com
verify return:1
depth=0 CN = *.domain
verify return:1
---
Certificate chain
 0 s:/CN=*.domain
   i:/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
 1 s:/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
   i:/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
---
Server certificate
-----BEGIN CERTIFICATE-----
  ...
-----END CERTIFICATE-----
subject=/CN=*.domain
issuer=/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
---
Acceptable client certificate CA names
/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=nuocmd.mycorp.com
/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ...
Shared Requested Signature Algorithms: ...
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
  ...
---
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: ...
    Session-ID-ctx:
    Master-Key: ...
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1560181877
    Timeout   : 300 (sec)
    Verify return code: 62 (Hostname mismatch)


Reply | Threaded
Open this post in threaded view
|

Re: Question: why doesn't my wildcard matching work with OpenSSL?

Viktor Dukhovni
On Mon, Jun 10, 2019 at 01:52:06PM -0400, Paul Smith wrote:

> Note for my C client I have not set any special flags for matching, I'm
> just using the default and using SSL_set1_host() to add the hostname.
> But, I can't even get it to work with openssl itself.
>
> For example, here's a connection attempt using the CLI... note if I
> remove the -verify_hostname option the connection works fine:
>
> $ openssl s_client -connect admin0.domain:8004 \
>     -CAfile ca.cert -verify_hostname admin0.domain
>
> CONNECTED(00000003)
> depth=1 C = US, ST = MA, L = Boston, O = Mycorp, OU = Eng, CN = ca.mycorp.com
> verify return:1
> depth=0 CN = *.domain
> verify return:1
> ---
> Certificate chain
>  0 s:/CN=*.domain
>    i:/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
>  1 s:/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
>    i:/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
> ---
> Server certificate
> -----BEGIN CERTIFICATE-----
>   ...
> -----END CERTIFICATE-----
> subject=/CN=*.domain
> issuer=/C=US/ST=MA/L=Boston/O=Mycorp/OU=Eng/CN=ca.mycorp.com
> ---
>     Verify return code: 62 (Hostname mismatch)

It seems that you've elided too much information.  Is the hostname
really "admin0.domain", or is there some underlying domain name
that you've obfuscated?

--
        Viktor.
Reply | Threaded
Open this post in threaded view
|

Re: Question: why doesn't my wildcard matching work with OpenSSL?

Paul Smith
On Mon, 2019-06-10 at 14:23 -0400, Viktor Dukhovni wrote:
> > $ openssl s_client -connect admin0.domain:8004 \
> >      -CAfile ca.cert -verify_hostname admin0.domain
> >
> > ---
> >      Verify return code: 62 (Hostname mismatch)
>
> It seems that you've elided too much information.  Is the hostname
> really "admin0.domain", or is there some underlying domain name
> that you've obfuscated?

I tried not to elide anything other than a lot of keys and stuff.
Maybe that info isn't output?

That is actually the hostname (I have this running in a Docker
container to get the hostname set up without a lot of hassle).

But maybe that's my confusion.  What "hostname" is OpenSSL looking at?
I told it the name I wanted it to use for the verify on the command
line: "-verify_hostname admin0.domain", which matches the wildcard the
certificate provides.

That appears to be what the docs say; from verify(1ssl):

 -verify_hostname hostname
     Verify if the hostname matches DNS name in Subject Alternative Name
     or Common Name in the subject certificate.

I thought that's all it used: this value plus the wildcard in the
certificate.  Am I misunderstanding this?  Where else will openssl go
looking for hostnames to match?

Note that if I don't use wildcards but instead have a full hostname in
the certificate, then verify hostname does work.  It's only using a
wildcard that doesn't match the way I thought it would.

Thanks for the reply!

Reply | Threaded
Open this post in threaded view
|

Re: Question: why doesn't my wildcard matching work with OpenSSL?

Viktor Dukhovni
> On Jun 10, 2019, at 2:39 PM, Paul Smith <[hidden email]> wrote:
>
> On Mon, 2019-06-10 at 14:23 -0400, Viktor Dukhovni wrote:
>>> $ openssl s_client -connect admin0.domain:8004 \
>>>     -CAfile ca.cert -verify_hostname admin0.domain
>>>
>>> ---
>>>     Verify return code: 62 (Hostname mismatch)
>>
>> It seems that you've elided too much information.  Is the hostname
>> really "admin0.domain", or is there some underlying domain name
>> that you've obfuscated?
>
> I tried not to elide anything other than a lot of keys and stuff.
> Maybe that info isn't output?
>
> That is actually the hostname (I have this running in a Docker
> container to get the hostname set up without a lot of hassle).

As a safety measure, OpenSSL does not support "*.tld" wildcards.
The non-wildcard portion of the domain name needs to have at
least two labels.  It seems I've neglected to document this... :-(

You can have "*.domain.example", but not "*.domain".

--
        Viktor.

Reply | Threaded
Open this post in threaded view
|

RE: Question: why doesn't my wildcard matching work with OpenSSL?

Michael Wojcik
In reply to this post by Paul Smith
I don't know why you sent this to me directly rather than to the list.

> From: Paul Smith [mailto:[hidden email]]
> Sent: Monday, June 10, 2019 12:54
> To: Michael Wojcik
>
> On Mon, 2019-06-10 at 18:49 +0000, Michael Wojcik wrote:
> > Argh. You cut out the actual relevant information. We need to see the
> > server certificate.
> >
> > In particulary, does it contain any Subject Alternative Name
> > extensions?
>
> What I cut out was only the base64-encoded certificate.

Yes. That was what we needed to see. The certificate.

> There weren't any settings shown there.

I didn't mention "settings". I discussed Subject Alternative Name extensions, which are part of the certificate.

> > I have a vague memory that wildcard matching only works with SANs.

As it turns out, you're hitting the OpenSSL restriction on wildcards with fewer than two domain components, as Viktor explained. I'd forgotten about that restriction.

However, I still recommend using a proper X.509v3 server certificate with one or more SANs. If you're running your own CA using the openssl utiltity, there are various online tutorials showing how to generate modern certificates.

--
Michael Wojcik
Distinguished Engineer, Micro Focus



Reply | Threaded
Open this post in threaded view
|

Re: Question: why doesn't my wildcard matching work with OpenSSL?

Paul Smith
On Mon, 2019-06-10 at 20:12 +0000, Michael Wojcik wrote:
> > What I cut out was only the base64-encoded certificate.
>
> Yes. That was what we needed to see. The certificate.

Yep, that's my bad.  Thanks for the reminder.

> As it turns out, you're hitting the OpenSSL restriction on wildcards
> with fewer than two domain components, as Viktor explained. I'd
> forgotten about that restriction.
>
> However, I still recommend using a proper X.509v3 server certificate
> with one or more SANs. If you're running your own CA using the
> openssl utiltity, there are various online tutorials showing how to
> generate modern certificates.

Just to be clear, this is being seen in our docker-based test
environment using a virtual network and the docker resolvers, where
we're creating our own certificates so we can easily do both positive
and negative testing with things like good/bad hostnames, expired
certificates, incorrect chains, testing key rotation, etc. etc.

Our Java and Python clients work fine, but the C/C++ clients were
failing.

These certificates aren't being used "for real".

I'll look into enhancing our test environment to address this.  Cheers!

Reply | Threaded
Open this post in threaded view
|

Re: Question: why doesn't my wildcard matching work with OpenSSL?

Paul Smith
In reply to this post by Viktor Dukhovni
On Mon, 2019-06-10 at 15:14 -0400, Viktor Dukhovni wrote:
> As a safety measure, OpenSSL does not support "*.tld" wildcards.
> The non-wildcard portion of the domain name needs to have at
> least two labels.  It seems I've neglected to document this... :-(
>
> You can have "*.domain.example", but not "*.domain".

I see, thanks, that's good info.  We will try to figure out how to
modify our Docker-based test configuration to use a multi-label domain
name for its private network.

I'm not sure how or if that will impact users, outside of our test
environment.


Is this something controlled by an option for X509_check_host() or is
it just hardcoded and can't be modified?  I didn't see any options in
the docs that seem to manage that, unless it's a side-effect.

Reply | Threaded
Open this post in threaded view
|

Re: Question: why doesn't my wildcard matching work with OpenSSL?

Viktor Dukhovni
> On Jun 10, 2019, at 4:41 PM, Paul Smith <[hidden email]> wrote:
>
>> As a safety measure, OpenSSL does not support "*.tld" wildcards.
>> The non-wildcard portion of the domain name needs to have at
>> least two labels.  It seems I've neglected to document this... :-(
>>
>> You can have "*.domain.example", but not "*.domain".
>
> Is this something controlled by an option for X509_check_host() or is
> it just hardcoded and can't be modified?  I didn't see any options in
> the docs that seem to manage that, unless it's a side-effect.

This is not presently configurable.  I see some references to
similar policies in at least some of the major browsers, not
just OpenSSL, so it is probably best to avoid *.tld wildcards.

--
        Viktor.