-
-
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 verify
command with the-untrusted
parameter. :(
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 verify
command with the-untrusted
parameter. :(