Python Failed to Verify any CRLs for SSL/TLS conne

2019-09-09 05:39发布

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?

标签: python ssl
1条回答
Melony?
2楼-- · 2019-09-09 06:18

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.

查看更多
登录 后发表回答