In order to investigate and patch exim to support proper certificate validation (expiration) I have setup everything on giggler.
The src is in /home/mdf/build/exim-4.30
Installs into /home/mdf/exim/
Run as '/home/mdf/exim/bin/exim -bd -d' and watch the debug output.
Make changes in exim-4.30/src/tls-openssl.c et al.
Rebuild and install using 'cd /home/mdf/build/exim-4.30/; make && make install'
The problem appears to be that X509_verify_cert(X509_STORE_CTX *ctx) is never called, but when I added that in... infinite loop.
Looking at the stunnel code (which exim's TLS support for openssl is based on) it appears that X509_verify_cert() is not call in it's verify_callback() routine, either (ssl.c). So I'm at a loss for now, I'll look at it again later.
48543 SSL info: SSLv3 write certificate request A
48543 SSL info: SSLv3 flush data
48543 LOG: MAIN
48543 Inside verify_callback, state is 0, dn=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=Certificate Authority/emailAddress=gshapiro@test.smtp.org
48543 LOG: MAIN
48543 SSL verify error: depth=1 error=self signed certificate in certificate chain cert=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=Certificate Authority/emailAddress=gshapiro@test.smtp.org
48543 SSL verify failure overridden (host in tls_try_verify_hosts)
48543 LOG: MAIN
48543 Inside verify_callback, state is 1, dn=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=Certificate Authority/emailAddress=gshapiro@test.smtp.org
48543 SSL verify ok: depth=1 cert=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=Certificate Authority/emailAddress=gshapiro@test.smtp.org
48543 LOG: MAIN
48543 Inside verify_callback, state is 0, dn=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=test.smtp.org/emailAddress=postmaster@test.smtp.org
48543 LOG: MAIN
48543 SSL verify error: depth=0 error=certificate has expired cert=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=test.smtp.org/emailAddress=postmaster@test.smtp.org
48543 SSL verify failure overridden (host in tls_try_verify_hosts)
48543 LOG: MAIN
48543 Inside verify_callback, state is 1, dn=/C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=test.smtp.org/emailAddress=postmaster@test.smtp.org
48543 SSL peer: /C=US/ST=California/L=Emeryville/O=test.smtp.org/CN=test.smtp.org/emailAddress=postmaster@test.smtp.org
48543 SSL info: SSLv3 read client certificate A
48543 SSL info: SSLv3 read client key exchange A
This verify_callback routine is scary. It's called twice, with two args and two other variables being evaluated inline, for a total of 2^5 possible states. I really just want to ask the following questions.
- Is the certificate valid (not expired)
- Is the certificate revoked (patchfile from Vivek)
- Is the certificate signed by a known & trusted issuer (CA)
The other concern is that the verify_callback routine actually sets the certificate to be verified, even when it's not valid, so as to suppot the tls_try_verify functionality. This functionality should probably just exist outside of verify_callback, then the decision about when to continue or not based on the verification and validity of the peer certificate can be made independently, without being so intertwined.