为什么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处理程序在验证处理程序之前被调用。因此,一种可能性是,我最初在某个地方将"no_ocsp"设置为0,然后如果我得到没有附加消息的ocsp回调,则将其设置为1。然后在验证处理程序中,我可以对此进行检查,以尝试确定OCSP处理程序是否稍后会被调用。这似乎有点像一辆汽车,当有人靠近时,它会自动解锁,然后如果靠近的人放错钥匙,它就会自动锁定——换句话说,这肯定不是"正确"的安全方式?!

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

(我也看到过类似的问题,解释了如何获得OCSP装订的消息,但我的问题涉及到,根据回调的顺序,你如何以合理的方式实际使用它。需要明确的是:我可以毫无问题地获得OCSP_RESPONSE(

第三种选择是请求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);

最新更新