Created
July 10, 2018 16:01
-
-
Save jnhmcknight/46a06ac0d329fa34d97d95c4c883ff50 to your computer and use it in GitHub Desktop.
Inject an arbitrary certificate authority into a certifi bundle
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
#!/usr/bin/env python | |
""" | |
Usage: python ./inject_ca.py <path/to/new/ca.crt> [<path/to/other/new/ca.crt> [...]] | |
""" | |
import certifi | |
import os | |
import re | |
import sys | |
from OpenSSL.crypto import load_certificate, FILETYPE_PEM | |
certifi_bundle = certifi.where() | |
def x509_to_str(x509obj): | |
return 'CN={} O={}'.format(x509obj.CN, x509obj.O) | |
def check_add_ca(ca_to_add): | |
""" | |
Check for the presence of the new CA and don't readd it if it is already present | |
""" | |
cert_file_string = open(ca_to_add, "rb").read() | |
cert = load_certificate(FILETYPE_PEM, cert_file_string) | |
sha256_fingerprint = str(cert.digest("sha256")).lower() | |
pattern = re.compile('^# SHA256 Fingerprint: {}$'.format(sha256_fingerprint)) | |
already_included = False | |
with open(certifi_bundle, 'rb') as infile: | |
print('Checking if cert has already been injected into virtualenv') | |
for line in infile: | |
match = pattern.match(line) | |
if match is not None: | |
already_included = True | |
if already_included: | |
print('Certificate was already included. Nothing to do.') | |
return 0 | |
print('Certificate will be added to cert store.') | |
customca = ''' | |
# Issuer: {issuer} | |
# Subject: {subject} | |
# Label: "{label}" | |
# Serial: {serial} | |
# MD5 Fingerprint: {md5} | |
# SHA1 Fingerprint: {sha1} | |
# SHA256 Fingerprint: {sha256} | |
{cert}'''.format( | |
issuer=x509_to_str(cert.get_issuer()), | |
subject=x509_to_str(cert.get_subject()), | |
label=str(cert.get_subject().CN), | |
serial=str(cert.get_serial_number()), | |
md5=str(cert.digest('md5')).lower(), | |
sha1=str(cert.digest('sha1')).lower(), | |
sha256=sha256_fingerprint, | |
cert=cert_file_string) | |
print('Writing: {}'.format(customca)) | |
with open(certifi_bundle, 'ab') as outfile: | |
outfile.write(customca) | |
if len(sys.argv) < 2: | |
print('You must specify a certificate to add to the certifi store!') | |
sys.exit(1) | |
for new_cert in sys.argv[1:]: | |
if not os.path.isfile(new_cert): | |
print('Cannot add certificate, file not found: {}'.format(new_cert)) | |
continue | |
check_add_ca(new_cert) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment