-
-
Save uilianries/0459f59287bd63e49b1b8ef03b30d421 to your computer and use it in GitHub Desktop.
| import sys | |
| import os | |
| from OpenSSL import crypto | |
| def verify_certificate_chain(cert_path, trusted_certs): | |
| # Download the certificate from the url and load the certificate | |
| cert_file = open(cert_path, 'r') | |
| cert_data = cert_file.read() | |
| certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert_data) | |
| #Create a certificate store and add your trusted certs | |
| try: | |
| store = crypto.X509Store() | |
| # Assuming the certificates are in PEM format in a trusted_certs list | |
| for _cert in trusted_certs: | |
| cert_file = open(_cert, 'r') | |
| cert_data = cert_file.read() | |
| client_certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert_data) | |
| store.add_cert(client_certificate) | |
| # Create a certificate context using the store and the downloaded certificate | |
| store_ctx = crypto.X509StoreContext(store, certificate) | |
| # Verify the certificate, returns None if it can validate the certificate | |
| store_ctx.verify_certificate() | |
| return True | |
| except Exception as e: | |
| print(e) | |
| return False | |
| if __name__ == "__main__": | |
| certs_dir = os.path.join(os.sep, "etc", "nginx", "certs") | |
| cert_path = os.path.join(certs_dir, "client", "client.crt") | |
| trusted_certs = [os.path.join(certs_dir, "ca", "ca.crt")] | |
| if not verify_certificate_chain(cert_path, trusted_certs): | |
| print("Invalid certificate!") | |
| sys.exit(1) | |
| print("Valid certificate!") | |
| sys.exit(0) |
can you get the valid certificate chain?about the chain info.
Hi
It should be noted that this cannot be used to verify "untrusted" certificates (for example an untrusted intermediate), say:
Root CA -> Rogue Issuing CA -> Fake End User Cert.It would be awesome if pyOpenSSL provided a way to verify untrusted chains, as the openssl library does with the
openssl verifycommand with the-untrustedparameter. :(
Hi @kerk12, I think you are interested in this article http://www.yothenberg.com/validate-x509-certificate-in-python/
regards.
@kerk12 @sepulm01
Solved here? pyca/pyopenssl#948
so if we want to verify untrusted chain, we just loop over every certificates?
Any idea on how to get the CA for a given certificate "dynamically" out of the system's certificate store? In case someone wanted to verify a certificate given a URL instead of static files.
This can load the certificate, but couldn't figure out on how to get the corresponding CA:
sock = socket()
sock.connect((hostname, port))
peername = sock.getpeername()
ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible
ctx.check_hostname = False
ctx.verify_mode = SSL.VERIFY_NONE
sock_ssl = SSL.Connection(ctx, sock)
sock_ssl.set_connect_state()
sock_ssl.set_tlsext_host_name(hostname_idna)
sock_ssl.do_handshake()
cert = sock_ssl.get_peer_certificate()
chain = sock_ssl.get_peer_cert_chain()
crypto_cert = cert.to_cryptography()
sock_ssl.close()
sock.close()
It should be noted that this cannot be used to verify "untrusted" certificates (for example an untrusted intermediate), say:
Root CA -> Rogue Issuing CA -> Fake End User Cert.It would be awesome if pyOpenSSL provided a way to verify untrusted chains, as the openssl library does with the
openssl verifycommand with the-untrustedparameter. :(