OCSP查询没有颁发者证书的中间证书

时间:2018-09-07 07:33:45

标签: ssl certificate ssl-certificate ocsp

我已经编写了TLS代码,该代码正在Java上进行相互身份验证,因此客户端在服务器发送其证书之后发送其证书。我想通过从客户端到服务器端的OCSP验证证书链中的所有证书。

我写的循环逻辑是假设最后一个证书是链中的root(CA)证书,并且不发送任何OCSP查询;

    int certificateChainSize= x509Certificates.length;

    // Verifies certificate chain respectively (issuer certificate required).
    CertificateResult response = null;

    try {
        for (int i = 0; i < certificateChainSize-1 ; i++) {
            response = client.verify(x509Certificates[i], x509Certificates[i+1]);
        }
    } catch (OcspException e) {
        e.printStackTrace();
    }

当我测试TLS并获取Wireshark捕获时,我意识到作为客户端的Google Chrome浏览器一直在发送证书链而没有root。结果是;因为循环逻辑,所以不查询中间证书,因为我的代码假定中间证书是root。我需要颁发者证书来验证链中的任何证书。没有发行者证书(如果是根证书),是否有任何机制验证。

1 个答案:

答案 0 :(得分:0)

我认为您的设计有缺陷。

没有根证书时,无需针对OCSP服务器验证证书,因为该链不受信任并且OCSP验证的意义为零。

在主要的密码库中,吊销检查是在构建所有可能的证书链,选择最佳链并根据各种验证规则成功进行验证(其中大多数在§6 of RFC 5280 中进行了验证)的最后一步。仅当所有检查都成功时,客户端才会尝试对链中的每个证书进行吊销检查。成功的链构建和验证将意味着您已经拥有受信任的根证书,因为有效的链是根证书的基础。

此外,正如您在上一个线程Force Chrome to send all certificates in chain during TLS中所说的那样:

  

为了获得最大的兼容性,所有实现都应准备处理来自任何TLS版本的潜在无关证书和任意顺序,但必须首先使用最终实体证书。

此语句表明,后续i+1证书不一定是当前i证书的颁发者。结果,此行:

response = client.verify(x509Certificates[i], x509Certificates[i+1]);

由于输入错误,将返回意外结果。

您真正应该做的是:让OS加密库(作为操作系统的一部分提供)完成最艰巨的工作。我强烈建议您不要发明自己的加密货币并使用经过验证的工具。每个操作系统都有API,这些API可以构建,安排和验证证书链,并为您提供最好的证书。您应该将此链用作OCSP验证代码的输入,并且您的for循环将被认为是可靠的(取决于verify方法的内部逻辑)。

就像我说的那样,如果链构建过程失败,则没有太多理由执行OCSP验证。