OpenSSL 将其留给调用代码似乎真的很奇怪。
是的,它在实践中非常有问题的遗漏,因为很多应用程序没有意识到他们必须手动执行检查。
OpenSSL 1.1.0 将包括主机名验证(HEAD
现在(截至 2013 年 9 月))。根据更改日志,有一个-verify_name
选项,并apps.c
响应-verify_hostname
开关。但s_client
不响应任一开关,因此不清楚如何为客户端实施或调用主机名检查。
如果存在扩展的dnsName
字段subjectAlternativeName
,请将 name 设置为该值。
可能有多个主题备用名称 (SAN),因此请准备好多个。
否则,将名称设置为主题的 CN 字段。
我相信您也需要检查是否匹配。
将名称与请求的主机名进行比较,允许每个星号匹配 [A-Za-z0-9_]+,但不匹配“点”(.)。
它更痛苦。您还必须确保您没有匹配 gTLD 或 ccTLD。例如,您不想匹配针对 gTLD 颁发的证书*.com
。该证书可能是由坏人签发的;)
ccTLD 类似于 *.eu、*.us 或 இலங்கை (nic.lk)。其中大约有 5000 个,Mozilla 在http://publicsuffix.org/上提供了一个列表。原始列表位于https://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1。
在我看来,应该有大量的代码来执行此操作,但我还没有找到任何代码。
除了 van Gulik 的建议,你也可以试试 Curl。我相当肯定 Curl 包含主机名匹配代码。
您甚至可以验证证书格式是否正确。在 Web 上下文中负责的组是 CA/浏览器论坛。他们对创建证书有基线和扩展要求:
例如,在基线文档中,您会发现列为通用名称 (CN) 的 IP 也必须列在主题备用名称 (SAN) 中。
In the extended docs, you will find that reserved IPs (RFC 1918) cannot be present in a extended validation (EV) certificate; and EV certificates cannot contain wild cards.