Created
January 4, 2018 21:25
-
-
Save uilianries/0459f59287bd63e49b1b8ef03b30d421 to your computer and use it in GitHub Desktop.
Validate x509 certificate using pyOpenSSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
@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()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi
Hi @kerk12, I think you are interested in this article http://www.yothenberg.com/validate-x509-certificate-in-python/
regards.