Certificate subject match validation

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

Certificate subject match validation

George-Theodor Serbana
I am writing a SSL/TLS client (using Boost.Beast but underlying it's using OpenSSL) and although I have set on the SSL context the 'verify_peer' flag, there is no verification to prove the server presents an X509 which contains in the Subject Alternative Names the hostname of that server.

As this is probably the dumbest type of attack someone could do (using a valid certificate with another domain name), I am thinking I'm doing something wrong. But from the documentation, I saw that using "verify_peer" should perform all the verifications...

Now if not even this simple check is being done, how about expiration of the certificate, revocation status and other checks? Should they be performed manually as well? 

For now I am using X509_VERIFY_PARAM_set1_host with SSL_CTX_set1_param to do this specific check.

Best regards,
Theodor
Reply | Threaded
Open this post in threaded view
|

Re: Certificate subject match validation

Viktor Dukhovni
On Fri, Mar 27, 2020 at 07:38:35PM +0200, George-Theodor Serbana wrote:

> I am writing a SSL/TLS client (using Boost.Beast but underlying it's using
> OpenSSL) and although I have set on the SSL context the 'verify_peer' flag,
> there is no verification to prove the server presents an X509 which
> contains in the Subject Alternative Names the hostname of that server.
>
> As this is probably the dumbest type of attack someone could do (using a
> valid certificate with another domain name), I am thinking I'm doing
> something wrong. But from the documentation, I saw that using "verify_peer"
> should perform all the verifications...

It verifies the trust chain.  To also verify the peer name, you need to
specify the peer name via:

    SSL_set1_host()

> Now if not even this simple check is being done, how about expiration of
> the certificate, revocation status and other checks? Should they be
> performed manually as well?

No, that's what VERIFY_PEER is for.

> For now I am using X509_VERIFY_PARAM_set1_host with SSL_CTX_set1_param to
> do this specific check.

That's the slightly less convenient legacy API from OpenSSL 1.0.2.
In 1.1.0 and later, you can use SSL_set1_host() (and in some
cases also SSL_add1_host()).

See the SSL_set1_host(3) manpage for details.

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

Re: Certificate subject match validation

George-Theodor Serbana
> I am writing a SSL/TLS client (using Boost.Beast but underlying it's using
> OpenSSL) and although I have set on the SSL context the 'verify_peer' flag,
> there is no verification to prove the server presents an X509 which
> contains in the Subject Alternative Names the hostname of that server.
>
> As this is probably the dumbest type of attack someone could do (using a
> valid certificate with another domain name), I am thinking I'm doing
> something wrong. But from the documentation, I saw that using "verify_peer"
> should perform all the verifications...

It verifies the trust chain.  To also verify the peer name, you need to
specify the peer name via:

    SSL_set1_host()

> Now if not even this simple check is being done, how about expiration of
> the certificate, revocation status and other checks? Should they be
> performed manually as well?

No, that's what VERIFY_PEER is for.

> For now I am using X509_VERIFY_PARAM_set1_host with SSL_CTX_set1_param to
> do this specific check.

That's the slightly less convenient legacy API from OpenSSL 1.0.2.
In 1.1.0 and later, you can use SSL_set1_host() (and in some
cases also SSL_add1_host()).

See the SSL_set1_host(3) manpage for details.

---------------------------


Indeed I re-read the docs and it says that users should not assume that hostnames are validated by default without explicitly calling the API, I must've missed that bit and thank you for letting me know. I will shift towards using the newer SSL_set1_host together with some flags (I don't want any wildcards).

Now just to be extra safe I'm still asking: will the VERIFY_PEER option together with SSL_set1_host instruct OpenSSL to perform all possible checks on the certificate presented by the server such that no security breach remains at this level? Is there anything else that I should call or perform manually?

-- Theodor



Reply | Threaded
Open this post in threaded view
|

Re: Certificate subject match validation

Viktor Dukhovni
On Sat, Mar 28, 2020 at 10:56:20PM +0200, George-Theodor Serbana wrote:

> >  > For now I am using X509_VERIFY_PARAM_set1_host with SSL_CTX_set1_param to
> >  > do this specific check.
> >  
> >  That's the slightly less convenient legacy API from OpenSSL 1.0.2.
> >  In 1.1.0 and later, you can use SSL_set1_host() (and in some
> >  cases also SSL_add1_host()).
> >  
> >  See the SSL_set1_host(3) manpage for details.
>
> Indeed I re-read the docs and it says that users should not assume that
> hostnames are validated by default without explicitly calling the API, I
> must've missed that bit and thank you for letting me know. I will shift
> towards using the newer SSL_set1_host together with some flags (I don't
> want any wildcards).

If your needs are sufficiently narrow to rule out connecting to sites
that use wildcard certificates, perhaps they're also narrow enough to
rule out sites that don't have subjectAltNames, in which case the
flags could be:

So you'll call either of (here a NULL callback, set a non-null callback
if appropriate):

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);     /* Just once */
    SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);         /* Per connection */

followed by (per connection):

    SSL_set1_host(ssl, "www.example.org");
    SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_WILDCARDS
                         | X509_CHECK_FLAG_NEVER_CHECK_SUBJECT);

which also insists on a DNS subject altname (the preferred way to
authenticate DNS names), and never looks at any CN field in the subject
DN.

> Now just to be extra safe I'm still asking: will the VERIFY_PEER option
> together with SSL_set1_host instruct OpenSSL to perform all possible checks
> on the certificate presented by the server such that no security breach
> remains at this level? Is there anything else that I should call or perform
> manually?

No, the above is enough.  

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

Re: Certificate subject match validation

George-Theodor Serbana
Yes, indeed I don't want to take into account the CN, only the SANs. Thanks for the extra flag and all the clarifications!

Best regards,
Theodor




> >  > For now I am using X509_VERIFY_PARAM_set1_host with SSL_CTX_set1_param to
> >  > do this specific check.
> > 
> >  That's the slightly less convenient legacy API from OpenSSL 1.0.2.
> >  In 1.1.0 and later, you can use SSL_set1_host() (and in some
> >  cases also SSL_add1_host()).
> > 
> >  See the SSL_set1_host(3) manpage for details.
>
> Indeed I re-read the docs and it says that users should not assume that
> hostnames are validated by default without explicitly calling the API, I
> must've missed that bit and thank you for letting me know. I will shift
> towards using the newer SSL_set1_host together with some flags (I don't
> want any wildcards).

If your needs are sufficiently narrow to rule out connecting to sites
that use wildcard certificates, perhaps they're also narrow enough to
rule out sites that don't have subjectAltNames, in which case the
flags could be:

So you'll call either of (here a NULL callback, set a non-null callback
if appropriate):

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);     /* Just once */
    SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL);         /* Per connection */

followed by (per connection):

    SSL_set1_host(ssl, "www.example.org");
    SSL_set_hostflags(ssl, X509_CHECK_FLAG_NO_WILDCARDS
                         | X509_CHECK_FLAG_NEVER_CHECK_SUBJECT);

which also insists on a DNS subject altname (the preferred way to
authenticate DNS names), and never looks at any CN field in the subject
DN.

> Now just to be extra safe I'm still asking: will the VERIFY_PEER option
> together with SSL_set1_host instruct OpenSSL to perform all possible checks
> on the certificate presented by the server such that no security breach
> remains at this level? Is there anything else that I should call or perform
> manually?

No, the above is enough. 

--
    Viktor.