为什么OCSP装订回调称为AFTER验证回调?

时间:2014-04-30 14:33:41

标签: openssl ocsp

我不是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_CTX_set_verify处理程序后获得了OCSP回调 。对于我(诚然天真)的想法,这意味着我有两个选择:

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

如果来自服务器的响应不包含装订的OCSP消息,我确实注意到在验证处理程序之前,OCSP处理程序被称为。所以有一种可能性就是我在某个地方设置了一些旗帜&#39; no_ocsp&#39;最初为0,然后如果我得到没有附加消息的OCSP回调,则将其设置为1.然后在验证处理程序中,我可以检查这一点以尝试确定是否稍后将调用OCSP处理程序。这看起来有点像一辆随着任何人接近而自行解锁的汽车,然后如果接近的人把错误的钥匙插入,它就会锁定自己 - 换句话说,它肯定不是正确的&#39;做安全的方法?!

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

(我已经看过类似的问题,解释了如何获取 OCSP-stapled消息,但我的问题与你如何以合理的方式实际使用它有关,给定顺序回调。要明确:我可以毫无问题地获得OCSP_RESPONSE)

1 个答案:

答案 0 :(得分:0)

第三种选择是请求CRL积分和OCSP回复,然后以正确的顺序验证自己。

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

检查CRL
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);