dovecot.pkoch at dfgh.net
2013-Apr-07 11:19 UTC
[Dovecot] ssl_require_crl does not work as expected
Hi I'm trying to use dovecot with client certificates. We produce our certificates with our on CA and we do NOT use certificate revocation lists. So I put "ssl_require_crl = no" into 10-ssl.conf. I did not find a solution neither in the wiki nor somewhere else, so I finally started to read the source. My impression is that openssl will always try to use CRLs. If "ssl_require_crl = no" dovecot will use CRLs but tries to ignore openssl error codes X509_V_ERR_UNABLE_TO_GET_CRL and X509_V_ERR_CRL_HAS_EXPIRED. This is done in ssl_verify_client_cert() in ssl-proxy-openssl.c line 871, namely i_info("proxy=%d, require_crl=%d, error=%d", proxy->client_proxy, proxy->set->ssl_require_crl, ctx->error ); if (proxy->client_proxy && !proxy->set->ssl_require_crl && (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL || ctx->error == X509_V_ERR_CRL_HAS_EXPIRED)) { /* no CRL given with the CA list. don't worry about it. */ preverify_ok = 1; } With my setup proxy->client_proxy is 0. I added the i_info() to check this and with this modification my syslog shows: Apr 7 13:01:16 d600 dovecot: master: Dovecot v2.1.15 starting up (core dumps disabled) Apr 7 13:01:21 d600 dovecot: auth: Debug: Loading modules from directory: /usr/dovecot/lib/dovecot/auth Apr 7 13:01:21 d600 dovecot: auth: Debug: auth client connected (pid=26175) Apr 7 13:01:22 d600 dovecot: imap-login: proxy=0, require_crl=0, error=3 Apr 7 13:01:22 d600 dovecot: imap-login: Invalid certificate: unable to get certificate CRL: /CN=...user cert.../C=DE Apr 7 13:01:22 d600 dovecot: imap-login: proxy=0, require_crl=0, error=3 Apr 7 13:01:22 d600 dovecot: imap-login: Invalid certificate: unable to get certificate CRL: /CN=...intermedieate cert.../C=DE Apr 7 13:01:22 d600 dovecot: imap-login: proxy=0, require_crl=0, error=3 Apr 7 13:01:22 d600 dovecot: imap-login: Invalid certificate: unable to get certificate CRL: /CN=Root-CA.../C=DE I dont know what the proxy-stuff is about so instead of ignoring CRL-related errors I tried to disable CRL-checking. I therefore commented out two lines in ssl_proxy_ctx_verify_client() in ssl-proxy-openssl.c line 1004, namely: // X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | // X509_V_FLAG_CRL_CHECK_ALL); This tells OpenSSL not to check CRLs. Of course in production code this should be done only if "ssl_require_crl = no". Similar code is contained in iostream-openssl-context.c, namely in routine ssl_iostream_ctx_verify_remote_cert() Is this a bug? Peter
On 7.4.2013, at 14.19, dovecot.pkoch at dfgh.net wrote:> My impression is that openssl will always try to use CRLs. If > "ssl_require_crl = no" > dovecot will use CRLs but tries to ignore openssl error codes > X509_V_ERR_UNABLE_TO_GET_CRL and X509_V_ERR_CRL_HAS_EXPIRED. > > This is done in ssl_verify_client_cert() in ssl-proxy-openssl.c line 871, > namely > > if (proxy->client_proxy && !proxy->set->ssl_require_crl && > (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL || > ctx->error == X509_V_ERR_CRL_HAS_EXPIRED)) { > /* no CRL given with the CA list. don't worry about it. */ > preverify_ok = 1; > }After thinking enough about this, I kind of see what's happening: The ssl_require_crl setting wasn't intended to do what you want it to do. It was meant for Dovecot proxying code where it needs to act as an SSL client to remote server. So the setting should instead have been named ssl_require_client_crl. For server's client cert checks you should be able to simply generate an empty CRL I think?> I dont know what the proxy-stuff is about so instead of ignoring CRL-related > errors I tried to disable CRL-checking. I therefore commented out two lines > in > ssl_proxy_ctx_verify_client() in ssl-proxy-openssl.c line 1004, namely: > > // X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | > // X509_V_FLAG_CRL_CHECK_ALL);If you remove the "proxy->client_proxy &&" check it should work just as well, I think?> Similar code is contained in iostream-openssl-context.c, > namely in routine ssl_iostream_ctx_verify_remote_cert()Now I'm wondering why this code works as SSL client even though I'm not reading CRLs anywhere.. I guess I should spend some time looking into how exactly CRLs should work.