Skip to content

Instantly share code, notes, and snippets.

@dgunning
Last active April 19, 2024 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dgunning/506d51914f3342cf487252d384a960bf to your computer and use it in GitHub Desktop.
Save dgunning/506d51914f3342cf487252d384a960bf to your computer and use it in GitHub Desktop.
Check if a certificate exists
import sys
import certifi
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import Encoding
def load_certificates_from_file(file_path):
"""Load all certificates from a file, automatically handling PEM and DER formats."""
certs = []
with open(file_path, 'rb') as file:
file_data = file.read()
if b'-----BEGIN CERTIFICATE-----' in file_data:
# Process as PEM
pem_data = file_data.split(b'-----END CERTIFICATE-----')
for data in pem_data:
if b'-----BEGIN CERTIFICATE-----' in data:
cert_data = data + b'-----END CERTIFICATE-----'
certs.append(x509.load_pem_x509_certificate(cert_data, default_backend()))
else:
# Process as DER
certs.append(x509.load_der_x509_certificate(file_data, default_backend()))
return certs
def read_certificate(file_path):
"""Read a single certificate from a file, detecting PEM or DER format."""
with open(file_path, 'rb') as file:
cert_data = file.read()
if b'-----BEGIN CERTIFICATE-----' in cert_data:
return x509.load_pem_x509_certificate(cert_data, default_backend())
else:
return x509.load_der_x509_certificate(cert_data, default_backend())
def check_certificate_exists(target_cert, bundle_certs):
"""Check if the target certificate exists in the list of bundle certificates by comparing fingerprints."""
target_fingerprint = target_cert.fingerprint(hashes.SHA256())
for cert in bundle_certs:
if cert.fingerprint(hashes.SHA256()) == target_fingerprint:
return True
return False
def add_certificate_to_bundle(cert, bundle_path):
"""Add a certificate to the PEM bundle."""
with open(bundle_path, 'ab') as bundle_file:
bundle_file.write(cert.public_bytes(Encoding.PEM))
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python check_cert.py <certificate_file>")
sys.exit(1)
cert_file_path = sys.argv[1]
cacert_file_path = certifi.where() # Use certifi to get the CA bundle path
# Load the target certificate and all certificates from the CA bundle
target_cert = read_certificate(cert_file_path)
bundle_certs = load_certificates_from_file(cacert_file_path)
# Check if the target certificate is in the CA bundle
exists = check_certificate_exists(target_cert, bundle_certs)
if exists:
print("Certificate already exists in the CA certificate file.")
else:
print("Certificate does not exist in the CA certificate file.")
user_input = input("Do you want to add this certificate to the CA bundle? (yes/no): ")
if user_input.lower() == 'yes':
add_certificate_to_bundle(target_cert, cacert_file_path)
print("Certificate has been added to the CA bundle.")
else:
print("Certificate was not added.")
import subprocess
import os
def get_certificate_by_name(common_name):
"""Retrieve a certificate from the macOS Keychain by common name."""
try:
# Define the path to the system keychain
keychain_path = "/Library/Keychains/System.keychain"
# Prepare the command to search the certificate
cmd = [
"security",
"find-certificate",
"-c", common_name,
"-p", # Output in PEM format
keychain_path
]
# Execute the command
result = subprocess.run(cmd, capture_output=True, text=True)
# Check for errors
if result.returncode != 0:
print("Error:", result.stderr)
return None
# Return the certificate data
return result.stdout
except Exception as e:
print("An error occurred:", e)
return None
# Example usage
cert_name = "Apple Root CA"
certificate = get_certificate_by_name(cert_name)
if certificate:
print("Certificate Found:\n", certificate)
else:
print("No certificate found with the name:", cert_name)
import subprocess
import os
def get_certificate_by_name(common_name):
"""Retrieve a certificate from the macOS Keychain by common name."""
try:
# Define the path to the system keychain
keychain_path = "/Library/Keychains/System.keychain"
# Prepare the command to search the certificate
cmd = [
"security",
"find-certificate",
"-c", common_name,
"-p", # Output in PEM format
keychain_path
]
# Execute the command
result = subprocess.run(cmd, capture_output=True, text=True)
# Check for errors
if result.returncode != 0:
print("Error:", result.stderr)
return None
# Return the certificate data
return result.stdout
except Exception as e:
print("An error occurred:", e)
return None
# Example usage
cert_name = "Apple Root CA"
certificate = get_certificate_by_name(cert_name)
if certificate:
print("Certificate Found:\n", certificate)
else:
print("No certificate found with the name:", cert_name)
import ssl
import socket
from OpenSSL import crypto
def get_certificate_chain(host, port=443):
""" Fetch the entire certificate chain from the server. """
context = ssl.create_default_context()
conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=host)
cert_chain = []
try:
conn.connect((host, port))
for cert_bin in conn.getpeercert(binary_form=False)['caIssuers']:
x509 = crypto.load_certificate(crypto.FILETYPE_ASN1, cert_bin)
cert_chain.append(x509)
return cert_chain
except Exception as e:
print(f"An error occurred: {e}")
finally:
conn.close()
def find_certificate_by_name(cert_chain, name):
""" Find and return the certificate that matches the given name. """
for cert in cert_chain:
subject = dict(cert.get_subject().get_components())
if subject[b'CN'] == name.encode():
return cert
return None
# Example usage:
chain = get_certificate_chain('www.google.com')
target_cert = find_certificate_by_name(chain, 'Google Trust Services')
if target_cert:
print("Certificate Found:")
print(crypto.dump_certificate(crypto.FILETYPE_PEM, target_cert).decode('utf-8'))
else:
print("No matching certificate found.")
import subprocess
import os
def get_certificate_by_name(common_name):
"""Retrieve a certificate from the macOS Keychain by common name."""
try:
# Define the path to the system keychain
keychain_path = "/Library/Keychains/System.keychain"
# Prepare the command to search the certificate
cmd = [
"security",
"find-certificate",
"-c", common_name,
"-p", # Output in PEM format
keychain_path
]
# Execute the command
result = subprocess.run(cmd, capture_output=True, text=True)
# Check for errors
if result.returncode != 0:
print("Error:", result.stderr)
return None
# Return the certificate data
return result.stdout
except Exception as e:
print("An error occurred:", e)
return None
# Example usage
cert_name = "Apple Root CA"
certificate = get_certificate_by_name(cert_name)
if certificate:
print("Certificate Found:\n", certificate)
else:
print("No certificate found with the name:", cert_name)
import virtualenv
import os
import subprocess
import pytest
def create_virtual_env(path):
"""Create a virtual environment in a specified directory and return the path to it."""
session = virtualenv.cli_run([str(path)])
return session.creator.dest # Correctly accessing the path to the created virtual environment
def install_dependencies(env_dir):
"""Install required dependencies in the virtual environment."""
subprocess.run([os.path.join(env_dir, 'bin', 'pip'), 'install', '--upgrade', 'pip'], check=True)
subprocess.run([os.path.join(env_dir, 'bin', 'pip'), 'install', 'certifi'], check=True)
def run_fixcert_script(env_dir, cert_file):
"""Run the fixcert.py script to add the certificate to cacerts."""
python_exec = os.path.join(env_dir, 'bin', 'python')
subprocess.run([python_exec, 'fixcert.py', cert_file], check=True)
def certificate_in_cacerts(env_dir, cert_content):
"""Check if the certificate content is in the cacerts.pem file used by certifi."""
import certifi
cacert_path = certifi.where()
with open(cacert_path, 'r') as f:
cacerts_content = f.read()
return cert_content in cacerts_content
@pytest.fixture
def setup_env(tmp_path):
"""Fixture to set up and tear down a virtual environment."""
env_path = tmp_path / "venv"
env_dir = create_virtual_env(env_path)
install_dependencies(env_dir)
yield env_dir
def test_certificate_installation(setup_env):
cert_content = "-----BEGIN CERTIFICATE-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzclLq9Xe2tcQg9Rgvec4E\n-----END CERTIFICATE-----"
cert_file = os.path.join(setup_env, 'temp_cert.pem')
with open(cert_file, 'w') as f:
f.write(cert_content)
run_fixcert_script(setup_env, cert_file)
assert certificate_in_cacerts(setup_env, cert_content), "Certificate was not found in cacerts."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment