Refactor ssl functionality

use pyopenssl for certificate validty and requests
This commit is contained in:
David Klaftenegger 2016-04-04 01:08:24 +02:00 committed by Markus Hauschild
parent e39c3cf298
commit 9dc7941658
2 changed files with 42 additions and 28 deletions

View File

@ -6,9 +6,9 @@
import acme_tiny
import acertmgr_ssl
import acertmgr_web
import datetime
import dateutil.parser
import dateutil.relativedelta
import grp
import os
@ -49,20 +49,7 @@ def cert_isValid(crt_file, ttl_days):
if not os.path.isfile(crt_file):
return False
else:
# check validity using OpenSSL
vc = subprocess.check_output(['openssl', 'x509', '-in', crt_file, '-noout', '-dates'])
m = re.search(b"notBefore=(.+)", vc)
if m:
valid_from = dateutil.parser.parse(m.group(1), ignoretz=True)
else:
raise InvalidCertificateError("No notBefore date found")
m = re.search(b"notAfter=(.+)", vc)
if m:
valid_to = dateutil.parser.parse(m.group(1), ignoretz=True)
else:
raise InvalidCertificateError("No notAfter date found")
(valid_from, valid_to) = acertmgr_ssl.cert_valid_times(crt_file)
now = datetime.datetime.now()
if valid_from > now:
@ -104,19 +91,10 @@ def cert_get(domain, settings):
server = acertmgr_web.ACMEHTTPServer(port)
server.start()
try:
allnames = domain.split(' ')
if len(allnames) == 1:
cr = subprocess.check_output(['openssl', 'req', '-new', '-sha256', '-key', key_file, '-out', csr_file, '-subj', '/CN=%s' % domain])
else:
cnt = 0
altnames = []
for alias in allnames[1:]
cnt = cnt + 1
altnames.append('DNS.%d=%s' % cnt, alias)
subject = '/CN=%s subjectAltName=%s' % allnames[0], ','.join(altnames)
cr = subprocess.check_output(['openssl', 'req', '-new', '-sha256', '-key', key_file, '-out', csr_file, '-reqexts', 'SAN', '-subj', subject])
# get certificate
key_fd = open(key_file, "r")
key = key_fd.read()
key_fd.close()
cr = acertmgr_ssl.cert_request(domains.split(), key)
crt = acme_tiny.get_crt(acc_file, csr_file, challenge_dir)
with open(crt_file, "w") as crt_fd:
crt_fd.write(crt)

36
acertmgr_ssl.py Normal file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# acertmgr - ssl management functions
# Copyright (c) Markus Hauschild & David Klaftenegger, 2016.
# available under the ISC license, see LICENSE
from OpenSSL import crypto
# @brief retrieve notBefore and notAfter dates of a certificate file
# @param cert_file the path to the certificate
# @return the tuple of dates: (notBefore, notAfter)
def cert_valid_times(cert_file):
with open(cert_file) as f:
cert_data = f.read()
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_data)
asn1time = str('%Y%m%d%H%M%SZ'.encode('utf8'))
not_before = datetime.datetime.strptime(str(cert.get_notBefore()), asn1time)
not_after = datetime.datetime.strptime(str(cert.get_notAfter()), asn1time)
return (not_before, not_after)
# @brief create a certificate signing request
# @param names list of domain names the certificate should be valid for
# @param key_data the key to use with the certificate in PEM format
# @return the CSR in PEM format
def cert_request(names, key_data):
req = crypto.X509Req()
req.get_subject().commonName = names[0]
entries = ['DNS:'+name for name in names]
extensions = [crypto.X509Extension('subjectAltName', False, ', '.join(entries))]
req.add_extensions(extensions)
key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_data)
req.set_pubkey(key)
req.sign(key, 'sha256')
return crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)