5

我需要使用 C-land OpenSSL 验证 X509 证书的域。

我的理解是该库不会为我执行此操作,并且我必须大致实现以下算法:

  1. 如果 subjectAlternativeName 扩展的 dnsName 字段存在,则设置name为该值。
  2. 否则,设置name为主题的 CN 字段。
  3. 与请求的主机名进行比较name,允许每个星号匹配 [A-Za-z0-9_]+,但不匹配“点”(.)。

在我看来,应该有大量的代码来执行此操作,但我还没有找到任何代码。

任何人都可以找到这样的例子吗?或者,对我的算法进行健全性检查?

编辑:这就是我想出的:https ://gist.github.com/2821083 。OpenSSL 将其留给调用代码似乎真的很奇怪。

4

2 回答 2

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 中提供,还请考虑日期和时间以及链。

德。

于 2012-06-01T11:07:31.637 回答
2

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.

于 2013-12-02T05:01:47.443 回答