[openssl-users] Problem with x509_verify_certificate

Viktor Dukhovni openssl-users at dukhovni.org
Wed Nov 21 23:04:07 UTC 2018


On Wed, Nov 21, 2018 at 11:36:46AM -0800, Ken wrote:

> I tested using s_client, on both systems, with no options, with CAfile 
> pointing to the correct CA, and with CAfile pointing to the WRONG CA 
> file - the only time it failed was on the new version, with the wrong 
> file. (Results attached.) I guess the new version is better at checking 
> things.

Perhaps you did not override CApath?  And the default CApath succeeds
with old, but not the new code?  For meaningful tests you need to
explicitly override both, and place just specific CA certs in CAfile,
leaving CApath empty.

> I tested the application, setting SSL_CERT_DIR and SSL_CERT_FILE, to the 
> empty directory and the CA file - did not help.

I don't believe I suggested setting SSL_CERT_FILE to an empty
directory, or an empty file.  Though putting a freshly minted
self-signed root that has never signed any certificates into CAfile,
can be one test to check that your application fails when it should
definitely fail.

> Then, I tested setting SSL_CERT_DIR to /var/lib/ca-certificates/openssl 
> (which seems to be the default, and did not change anything), and then 
> setting SSL_CERT_DIR to /var/lib/ca-certificates/pem/ - this made 
> FreeRDP happy with the certificate.
>
> I compared 
> Starfield_Root_Certificate_Authority_-_G2.pem in the openssl directory 
> on the two systems - they are a binary match.

But they're not the same, only the encapsulated X.509 certificates
are the same, but one is wrapped as a "trusted certificate" with a
specific trust EKU.

> Then I compared the output of
>
> openssl x509 -in /var/lib/ca-certificates/openssl/Starfield_Root_Certificate_Authority_-_G2.pem -noout -text
> and
> openssl x509 -in /var/lib/ca-certificates/pem/Starfield_Root_Certificate_Authority_-_G2.pem -noout -text

That is, they are NOT the same.

> The only difference is that the one from openssl ends with:
> 
> Trusted Uses:
>  TLS Web Server Authentication
> No Rejected Uses.
> Alias: Starfield Root Certificate Authority - G2

Well, that's "auxiliary" trust data outside the certificate.  It
is part of a "TRUSTED CERTICATE" encapsulation of a CA certificate,
and can be used to limit the "purpose" for which a certificate is
valid.

If your application does not specify "serverAuth" as the "purpose"
being verified, then verification should fail.

> Since I am trying to make a RDP connection, does this mean that the 
> openssl version of the CA is not valid, because it says "Web Server 
> Authentication". And, the new version makes more extensive checks that 
> the old version?

It is valid, but has a restricted purpose.  Your application needs
to specify that purpose, but FreeRDP may not specify its peer as a
"TLS Web Server" (really TLS server) when doing certificate verification.

> I now have a work-around to make this application work, but I would like 
> to know what really is going on - what changed to cause this.

The chain "extended Key Usage" is checked more consistently in
OpenSSL 1.1.x.

>  OpenSSL 1.0.2j-fips  26 Sep 2016

Note that in OpenSSL 1.0.2, the "s_client" command *always* loads the
*default* CAfile and default CApath, in *addition* to any CAfile
and CApath you might specify.  You need to point SSL_CERT_DIR to
an empty directory and SSL_CERT_FILE at the desired CAfile to make
sure that only the trusted certificates you want to test are used.

> 
> # s_client with "no" options:
> $ openssl s_client -quiet -connect owa.xxxxx.com:3389
> depth=2 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
> verify return:1
> depth=1 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
> verify return:1
> depth=0 OU = Domain Control Validated, CN = owa.xxxxx.com
> verify return:1

This succeeds.

> 
> # s_client, specifying correct CA:
> $ openssl s_client -quiet -connect owa.xxxxx.com:3389 -CApath ~/empty/ -CAfile sfroot-g2.crt
> depth=2 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
> verify return:1
> depth=1 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
> verify return:1
> depth=0 OU = Domain Control Validated, CN = owa.xxxxx.com
> verify return:1

This likewise.

> # s_client, specifying *WRONG* CA:
> $ openssl s_client -quiet -connect owa.xxxxx.com:3389 -CApath ~/empty/ -CAfile gdroot-g2.crt
> depth=2 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
> verify return:1
> depth=1 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
> verify return:1
> depth=0 OU = Domain Control Validated, CN = owa.xxxxx.com
> verify return:1

Probably still finds the right CA in the default CApath or CAfile.

> OpenSSL 1.1.0i-fips  14 Aug 2018

Note that to reduce WTF surprises, OpenSSL 1.1.x only loads the
*default* CAfile and CApath when you don't specify either on the
command-line, and you don't disable these with "-no-CAfile" or
"-no-CApath".  So the in tests below, you're not getting more than
what you ask for:

> # s_client with "no" options:
> $ openssl s_client -quiet -connect owa.xxxxx.com:3389
> depth=2 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
> verify return:1
> depth=1 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
> verify return:1
> depth=0 OU = Domain Control Validated, CN = owa.xxxxx.com
> verify return:1

This succeeds.

> # s_client, specifying correct CA:
> $ openssl s_client -quiet -connect owa.xxxxx.com:3389 -CApath ~/empty/ -CAfile sfroot-g2.crt
> depth=2 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Root Certificate Authority - G2
> verify return:1
> depth=1 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
> verify return:1
> depth=0 OU = Domain Control Validated, CN = owa.xxxxx.com
> verify return:1

This also succeeds.

> # s_client, specifying *WRONG* CA:
> $ openssl s_client -quiet -connect owa.xxxxx.com:3389 -CApath ~/empty/ -CAfile gdroot-g2.crt
> openssl s_client -quiet -connect owa.xxxxx.com:3389 -CApath ~/empty/ -CAfile gdroot-g2.crt
> depth=1 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", OU = http://certs.starfieldtech.com/repository/, CN = Starfield Secure Certificate Authority - G2
> verify error:num=20:unable to get local issuer certificate

Fails as expected.

-- 
	Viktor.


More information about the openssl-users mailing list