Openssl 为什么在验证回调之后调用OCSP装订回调?

Openssl 为什么在验证回调之后调用OCSP装订回调?,openssl,ocsp,Openssl,Ocsp,我不是OpenSSL专家,但我一直在尝试编写一些代码来处理连接到SSL安全服务器的客户端的OCSP绑定。我对OCSP的理解是,它用于证明提交的证书未被撤销,这意味着我不需要处理管理发行人发布的CRL的问题 我使用SSL_CTX_set_verify设置回调以处理证书的验证(好的,处理OpenSSL自身内部验证过程的异常。我假设,但无法找到该内部过程未检查证书吊销状态的肯定证据),目前,我的代码利用这个机会检查发卡机构是否受信任(或者如果不受信任,则检查发卡机构的发卡机构是否受信任,依此类推,直到

我不是OpenSSL专家,但我一直在尝试编写一些代码来处理连接到SSL安全服务器的客户端的OCSP绑定。我对OCSP的理解是,它用于证明提交的证书未被撤销,这意味着我不需要处理管理发行人发布的CRL的问题

我使用SSL_CTX_set_verify设置回调以处理证书的验证(好的,处理OpenSSL自身内部验证过程的异常。我假设,但无法找到该内部过程未检查证书吊销状态的肯定证据),目前,我的代码利用这个机会检查发卡机构是否受信任(或者如果不受信任,则检查发卡机构的发卡机构是否受信任,依此类推,直到链被信任或拒绝),以及其他事项,如证书是否过期。(这也可能已经检查过了,但这对我的问题并不重要)

我修改了代码,添加了

SSL_set_tlsext_status_type(<the ssl object>, TLSEXT_STATUSTYPE_ocsp); 
SSL_CTX_set_tlsext_status_cb(<the context>, ssl_cb_ocsp_verify);
SSL\u set\u tlsext\u status\u type(,tlsext\u status type\u ocsp);
SSL\u CTX\u设置\u tlsext\u状态\u cb(,SSL\u cb\u ocsp\u验证);
然后我可以得到响应并在处理程序中检查它。到目前为止,一切都很好

但奇怪的是,我在得到SSL\u CTX\u set\u verify处理程序之后得到了OCSP回调。在我(无可否认是天真的)看来,这意味着我有两个选择:

1) 使用CRL或执行我自己的OCSP请求,检查验证回调中的吊销状态。如果这样做,那么在OCSP回调中执行任何操作都没有意义,因为我已经确定了证书的吊销状态 2) 不要在验证回调中检查吊销状态,并疯狂地希望调用OCSP处理程序

我注意到,如果来自服务器的响应不包含装订好的OCSP消息,则在验证处理程序之前调用OCSP处理程序。因此,一种可能性是,我最初将某个地方的标志“no_ocsp”设置为0,然后如果我得到没有附加消息的ocsp回调,则将其设置为1。然后在验证处理程序中,我可以检查这一点,以尝试确定稍后是否调用OCSP处理程序。这看起来有点像一辆车,当任何人靠近时,它会自动解锁,然后如果接近的人把错误的钥匙放进去,它就会自动锁定——换句话说,这肯定不是“正确”的安全方式

因此,我对如何使用OCSP、OpenSSL或两者都有一些基本的误解!我做错了什么


(我看到过类似的问题,解释了如何获取OCSP订书信息,但我的问题涉及到,考虑到回调的顺序,您实际如何以合理的方式使用它。明确地说:我可以毫无问题地获得OCSP_响应)第三种选择是请求CRL积分和OCSP回复,然后按照正确的顺序验证自己

您可以使用OCSP_basic_verify在回调中验证OCSP装订的回复。然后,一旦建立了连接,您就可以通过

X509_STORE_CTX* ctx = ...

// fill up ctx, if not yet initialized
ctx->chain = chain;
ctx->get_crl = []( X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x ) -> int
{ .. your method to download CRL .. }
// disable additional CRL lookup by the library
ctx->lookup_crls = [] (X509_STORE_CTX *ctx, X509_NAME *nm) ->STACK_OF( X509_CRL ) * { return nullptr; };
// other possible options are: X509_V_FLAG_EXTENDED_CRL_SUPPORT, X509_V_FLAG_CRL_CHECK_ALL, X509_V_FLAG_USE_DELTAS
ctx->param->flags = X509_V_FLAG_CRL_CHECK;

// this will evaluate how well the CRL fits the leaf certificate you want to validate
ctx->check_revocation(ctx);

// this validates the CRL itself, if it is signed and stuff
// 0 - bad
// 1 - okay
int ok = ctx->check_crl(ctx, m_crl);

//  This gives actual revocation result
// 0 - bad (ctx->error = X509_V_ERR_CERT_REVOKED or something else)
// 1 - okay
// 2 - CRL_REASON_REMOVE_FROM_CRL
int result = ctx->cert_crl(ctx, m_crl, leafCertificate);

“…处理OpenSSL自身内部验证过程的异常。我假设”-还要注意,1.02之前的OpenSSL不执行主机名匹配。如果需要,你必须这样做。啊哈,谢谢你的提示!我发现了一份白皮书“关于openssl证书验证的所有您一直想知道的事情(但不敢问)”,它提供了一些关于这方面的额外信息,但不幸的是,在您相信服务器告诉您的内容(例如OCSP装订)之前,它没有提供OCSP(除了简短的提及之外)方面的信息,您首先要信任该服务器,因此OpenSSL可能首先验证服务器的证书,以确保它是一个有效且可信的证书。然后,假设证书看起来有效,您将希望查看它是否已被吊销——此时您将处理/处理Stapped OCSP响应。