1 Answer
1

In most protocols/applications using SSL the client needs to check BOTH (1) the server presents a valid certificate, meaning one issued by a trusted CA and not expired, revoked or tampered AND (2) that certificate is for the server you want, not somebody else to whom your connection was routed by mistake or by deliberate attack. (There are rare cases where you don't need server authentication only confidentiality, but then you are probably better off using the "anon" or "aNULL" ciphersuites which explicitly do not authenticate.)

OpenSSL to date does (1) but not (2), and normally supports only CA root certs in its truststore; one CA root might be 'responsible' for thousands or millions of server certs, and if for example Verisign issued certs to both bigbank.com and localdiner.com that doesn't mean I want to give my bigbank accounts to localdiner. So the application needs to do (2), either in a verify_callback, or after the handshake completes but before sending (sensitive) data. The next major release 1.0.2 is planned to contain enhancements to cert chain validation, and I believe also name validation in at least some cases. Note for HTTPS using RFC 2818 or other TLS-based protocols using RFC 6125, you need to check both CommonName in Subject and the SubjectAlternativeNames extension if present.

I don't know why OpenSSL (and before that SSLeay) doesn't do it already. One might say that some unusual SSL/TLS applications want something other than the standard CN/SAN -- but there are other areas where OpenSSL handles the common case and provides callbacks or options for the rare cases. I think it was probably just too much work and not enough people (until very recently).

+1 But: Doesn't checking the IP address in the cert (which openSSL seems to do) cover #2? In fact, isn't that the only way to do such a thing?
–
goldilocksJun 23 '14 at 13:27

1

@goldilocks Certificates commonly don't even have an IP address in them. They're usually issued to a name.
–
derobertJun 23 '14 at 14:14

and even when a cert does have an IP-address in "name" -- which is indeed rare, but definitely possible for SAN and historically but unofficially for CN -- OpenSSL doesn't check it. What makes you say it 'seems to'? If I test the case of a server on IP#B using a cert for IP#A, openssl s_client is happy, but curl https: (which uses openssl but adds name check, unless you override) gives error.
–
dave_thompson_085Jun 24 '14 at 8:47