mirror of
https://github.com/moepman/acertmgr.git
synced 2024-11-14 18:35:27 +01:00
Refactor ssl functionality
use pyopenssl for certificate validty and requests
This commit is contained in:
parent
e39c3cf298
commit
9dc7941658
34
acertmgr.py
34
acertmgr.py
@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
|
|
||||||
import acme_tiny
|
import acme_tiny
|
||||||
|
import acertmgr_ssl
|
||||||
import acertmgr_web
|
import acertmgr_web
|
||||||
import datetime
|
import datetime
|
||||||
import dateutil.parser
|
|
||||||
import dateutil.relativedelta
|
import dateutil.relativedelta
|
||||||
import grp
|
import grp
|
||||||
import os
|
import os
|
||||||
@ -49,20 +49,7 @@ def cert_isValid(crt_file, ttl_days):
|
|||||||
if not os.path.isfile(crt_file):
|
if not os.path.isfile(crt_file):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# check validity using OpenSSL
|
(valid_from, valid_to) = acertmgr_ssl.cert_valid_times(crt_file)
|
||||||
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")
|
|
||||||
|
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if valid_from > now:
|
if valid_from > now:
|
||||||
@ -104,19 +91,10 @@ def cert_get(domain, settings):
|
|||||||
server = acertmgr_web.ACMEHTTPServer(port)
|
server = acertmgr_web.ACMEHTTPServer(port)
|
||||||
server.start()
|
server.start()
|
||||||
try:
|
try:
|
||||||
allnames = domain.split(' ')
|
key_fd = open(key_file, "r")
|
||||||
if len(allnames) == 1:
|
key = key_fd.read()
|
||||||
cr = subprocess.check_output(['openssl', 'req', '-new', '-sha256', '-key', key_file, '-out', csr_file, '-subj', '/CN=%s' % domain])
|
key_fd.close()
|
||||||
else:
|
cr = acertmgr_ssl.cert_request(domains.split(), key)
|
||||||
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
|
|
||||||
crt = acme_tiny.get_crt(acc_file, csr_file, challenge_dir)
|
crt = acme_tiny.get_crt(acc_file, csr_file, challenge_dir)
|
||||||
with open(crt_file, "w") as crt_fd:
|
with open(crt_file, "w") as crt_fd:
|
||||||
crt_fd.write(crt)
|
crt_fd.write(crt)
|
||||||
|
36
acertmgr_ssl.py
Normal file
36
acertmgr_ssl.py
Normal 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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user