Ignore:
Timestamp:
Feb 16, 2017, 12:07:01 AM (8 years ago)
Author:
andersk
Message:
export-scripts-certs: Add many more sanity checks
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/fedora/config/etc/httpd/export-scripts-certs

    r2813 r2821  
    77import sys
    88import textwrap
     9from OpenSSL import crypto, SSL
    910
    1011CERTS_DIR = '/var/lib/scripts-certs'
     
    2829error = False
    2930
     31def err(e):
     32    global error
     33    sys.stderr.write(e)
     34    error = True
     35
    3036def conf(vhost):
    3137    name, = vhost['scriptsVhostName']
    3238    aliases = vhost.get('scriptsVhostAlias', [])
    3339    certs, = vhost['scriptsVhostCertificate']
    34     key_filename, = vhost['scriptsVhostCertificateKeyFile']
     40    try:
     41        key_filename, = vhost['scriptsVhostCertificateKeyFile']
     42    except KeyError:
     43        err('Error: missing scriptsVhostCertificateKeyFile for vhost {}\n'.format(name))
     44        return
    3545
    36     certs = ''.join('-----BEGIN CERTIFICATE-----\n' + '\n'.join(textwrap.wrap(cert, 64)) + '\n-----END CERTIFICATE-----\n' for cert in certs.split())
    37     cert_filename = base64.urlsafe_b64encode(hashlib.sha256(certs).digest()).strip() + '.pem'
     46    try:
     47        certs = [crypto.load_certificate(crypto.FILETYPE_ASN1, base64.b64decode(cert)) for cert in certs.split()]
     48    except (TypeError, crypto.Error) as e:
     49        err('Error: malformed certificate list for vhost {}: {}\n'.format(name, e))
     50        return
     51
     52    if not certs:
     53        err('Error: empty certificate list for vhost {}\n'.format(name))
     54        return
     55
     56    key_path = os.path.join('/etc/pki/tls/private', key_filename)
     57    if os.path.split(os.path.abspath(key_path)) != ('/etc/pki/tls/private', key_filename):
     58        err('Error: bad key filename {} for vhost {}\n'.format(key_path, name))
     59        return
     60
     61    ctx = SSL.Context(SSL.SSLv23_METHOD)
     62    try:
     63        ctx.use_privatekey_file(key_path, crypto.FILETYPE_PEM)
     64    except (SSL.Error, crypto.Error) as e:
     65        err('Error: could not read key {} for vhost {}: {}\n'.format(key_path, name, e))
     66        return
     67
     68    ctx.use_certificate(certs[0])
     69    for cert in certs[1:]:
     70        ctx.add_extra_chain_cert(cert)
     71
     72    try:
     73        ctx.check_privatekey()
     74    except SSL.Error as e:
     75        err('Error: key {} does not match certificate for vhost {}: {}\n'.format(key_path, name, e))
     76        return
     77
     78    certs_pem = ''.join(crypto.dump_certificate(crypto.FILETYPE_PEM, cert) for cert in certs)
     79    cert_filename = base64.urlsafe_b64encode(hashlib.sha256(certs_pem).digest()).strip() + '.pem'
    3880    cert_filenames.add(cert_filename)
    3981    cert_path = os.path.join(CERTS_DIR, cert_filename)
    4082    if not os.path.exists(cert_path):
    4183        with open(cert_path + '.new', 'w') as cert_file:
    42             cert_file.write(certs)
     84            cert_file.write(certs_pem)
    4385        os.rename(cert_path + '.new', cert_path)
    44 
    45     key_path = os.path.join('/etc/pki/tls/private', key_filename)
    46     if not os.path.exists(key_path):
    47         sys.stderr.write("Error: key file {} does not exist for vhost {}\n".format(key_path, name))
    48         global error
    49         error = True
    50         return
    5186
    5287    for port in 443, 444:
Note: See TracChangeset for help on using the changeset viewer.