我需要使用C-land OpenSSL验证X509证书的域名。
我的理解是该库不会为我做这个,我必须大致实现以下算法:
name
设置为该值。name
设置为主题的CN字段。name
与请求的主机名进行比较,允许每个星号与[A-Za-z0-9 _] +匹配,但不能匹配'点'(。)。在我看来应该有足够的代码来执行此操作,但我还没有找到任何代码。
有人能找到这样的例子吗?或者,理智检查我的算法?
编辑:这就是我想出的:https://gist.github.com/2821083。看起来很奇怪,OpenSSL会把这个留给调用代码。
答案 0 :(得分:4)
你很喜欢 - 虽然要注意主题替代名称和原始IP地址和FQDN。你可能想偷窃
BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
来自http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_util_ssl.c的相关朋友和ssl_engine_init.c中的被调用者(这是服务器端的方式)所有选项。
当你采取openssl回调时 - 也要考虑日期&时间和链条,如果你没有提供已经在CTX中。
DW传递。
答案 1 :(得分:2)
看起来很奇怪,OpenSSL会将其留给调用代码。
是的,它在实践中存在很多问题,因为许多应用程序没有意识到他们必须手动执行检查。
OpenSSL 1.1.0将包含主机名验证(现在在HEAD
中(截至2013年9月))。根据更改日志,有一个-verify_name
选项,apps.c
响应-verify_hostname
开关。但是s_client
没有响应任何一个开关,因此不清楚如何为客户端实现或调用主机名检查。
如果
dnsName
扩展名的subjectAlternativeName
字段存在,请将name设置为该值。
可能有多个主题备用名称(SAN),因此请为多个备用名称做好准备。
否则,将name设置为主题的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 / Browser论坛。他们对创建证书有基准和扩展要求:
在基线文档中,您会发现,例如,列为公用名(CN)的IP也必须列在主题备用名称(SAN)中。
在扩展文档中,您会发现保留的IP(RFC 1918)不能出现在扩展验证(EV)证书中;和EV证书不能包含通配符。