One reason for writing this article was a discussion I had with a colleague. Apparently, I did not pay attention at school, because I thought that the TLS handshake also checks the contents of the certificate, in particular if the certificate has been issued for the name of the service that you call. That does not appear to be the case. The TLS handshake protocol only checks if you have a valid certificate, i.e. signed by a known CA and not expired.
It is as if Immigration only checks if you have a valid passport, but does not look inside if the picture matches your head. You could have found, borrowed, bought, or stolen someone else's passport: it is not checked (except if it is listed as missing - the CRL).
As already mentioned in section 3.1 on p.5 in the RFC2818: HTTP over TLS, from 2000:
If the hostname does not match the identity in the certificate, user oriented clients MUST either notify the user (clients MAY give the user the opportunity to continue with the connection in any case) or terminate the connection with a bad certificate error. Automated clients MUST log the error to an appropriate audit log (if available) and SHOULD terminate the connection (with a bad certificate error). Automated clients MAY provide a configuration setting that disables this check, but MUST provide a setting which enables it.
In RFC7525: TLS Recommendations (2015) is stated in section 6.1 on p.17:
6.1 Host Name Validation
Application authors should take note that some TLS implementations do not validate host names. If the TLS implementation they are using does not validate host names, authors might need to write their own validation code or consider using a different TLS implementation.
It is noted that the requirements regarding host name validation (and, in general, binding between the TLS layer and the protocol that runs above it) vary between different protocols. For HTTPS, these requirements are defined by Section 3 of [RFC2818].
Readers are referred to [RFC6125] for further details regarding generic host name validation in the TLS context. In addition, that RFC contains a long list of example protocols, some of which implement a policy very different from HTTPS.
This refers to section 6 on pp.21..22 in RFC6125: Service Identity, from 2011:
6. Verifying Service Identity
This section provides rules and guidelines for implementers of application client software regarding algorithms for verification of application service identity.
At a high level, the client verifies the application service's identity by performing the actions listed below (which are defined in the following subsections of this document):
- The client constructs a list of acceptable reference identifiers based on the source domain and, optionally, the type of service to which the client is connecting.
- The server provides its identifiers in the form of a PKIX certificate.
- The client checks each of its reference identifiers against the presented identifiers for the purpose of finding a match.
- When checking a reference identifier against a presented identifier, the client matches the source domain of the identifiers and, optionally, their application service type.
Yeah, sure, hahaha.
So it is up to the client application to verify that the subject of the certificate matches the service that the application calls. I can understand this: the underlying security library does not know from where the application has received the certificate. In order to have the application verify the certificate, it must be able to retrieve the details from the certificate via the library, and actually do so. But frequently the application never gets to see the certificate: often TLS is terminated at a proxy. Then there is no identity known to check, never mind to subsequently authorize it (see section “X. Authorization”).
Browsers do check the certificate: MS Edge refuses to make a connection with a site that does not match the certificate; as a user, you can not overrule that. Chrome still gives you that option. Only FireFox will provide you with the necessary information about the certificate and give you the opportunity to accept it.
My impression is that custom-made applications usually do NOT verify the certificate. So usually authentication is incomplete.