Python Failed to Verify any CRLs for SSL/TLS connections
Question: In Python 3.4, a `verify_flags` that can be used to check if a certificate was
revoked against CRL, by set it to `VERIFY_CRL_CHECK_LEAF` or
`VERIFY_CRL_CHECK_CHAIN`.

I wrote a simple program for testing. But on my systems, this script failed to
verify ANY connections even if it's perfectly valid.

    
    
    import ssl
    import socket
    
    def tlscheck(domain, port):
            addr = domain
    
            ctx = ssl.create_default_context()
            ctx.options &= ssl.CERT_REQUIRED
            ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
    
            ctx.check_hostname = True
    
            #ctx.load_default_certs()
            #ctx.set_default_verify_paths()
            #ctx.load_verify_locations(cafile="/etc/ssl/certs/ca-certificates.crt")
    
            sock = ctx.wrap_socket(socket.socket(), server_hostname=addr)
            sock.connect((addr, port))
    
            import pprint
            print("TLS Ceritificate:")
            pprint.pprint(sock.getpeercert())
            print("TLS Version:", sock.version())
            print("TLS Cipher:", sock.cipher()[0])
            exit()
    
    tlscheck("stackoverflow.com", 443)
    

My code always quits with `ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed (_ssl.c:645)`.

First I suspected that the certificate database was not loaded properly. But
after I tried `load_default_certs()`, `set_default_verify_paths()`,
`load_verify_locations(cafile="/etc/ssl/certs/ca-certificates.crt")`, and none
of them worked.

Also, `ctx.options &= ssl.CERT_REQUIRED` works as expected, it can tell if a
certificate chain is trusted or not. But not for CRLs... It also indicates
that my CAs are correct.

I know "/etc/ssl/certs/ca-certificates.crt" contains valid CAs. What is the
problem?


Answer: To check against CRL you have to manually download the CRL and put them in the
right place so that the underlying OpenSSL library will find it. There is no
automatic downloading of CRL and specifying the place where to look for the
CRL is not intuitive either. What you can do:

  * get the CRL distribution points from the certificate. For stackoverflow.com one is <http://crl3.digicert.com/sha2-ha-server-g5.crl>
  * download the current CRL from there
  * convert it from the DER format to PEM format, because this is what is expected in the next step:   
`openssl crl -inform der -in sha2-ha-server-g5.crl > sha2-ha-
server-g5.crl.pem`

  * add the location to the verify_locations:  
`ctx.load_verify_locations(cafile="./sha2-ha-server-g5.crl.pem")`

This way you can verify the certificate against the CRL.

