--- /dev/null
+#!/usr/bin/python
+
+import logging
+import os
+import os.path
+
+from cryptography import x509
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives import serialization
+from cryptography.x509.oid import NameOID
+
+import OpenSSL
+
+class Certificate:
+ def __init__(self, servicetype, name, sans):
+ self._name = name
+ self._sans = sans
+ self._servicetype = servicetype
+ self._basename = os.path.join("certs", servicetype, name)
+ if os.path.exists(os.path.join(self._basename, "key.pem")):
+ self._from_private_key()
+ elif os.path.exists(os.path.join(self._basename, "csr.pem")):
+ self._from_csr()
+ else:
+ self._from_scratch()
+
+
+ def _from_private_key(self):
+ with open(os.path.join(self._basename, "key.pem"), "rb") as keyfd:
+ private_key = serialization.load_pem_private_key(
+ keyfd.read(),
+ password=None,
+ backend=default_backend())
+
+ builder = x509.CertificateSigningRequestBuilder()
+ builder = builder.subject_name(x509.Name([
+ x509.NameAttribute(NameOID.COMMON_NAME, self._name.decode()),
+ ]))
+ builder = builder.add_extension(
+ x509.SubjectAlternativeName([x509.DNSName(x.decode()) for x in self._sans]),
+ critical=False)
+
+ request = builder.sign(private_key, hashes.SHA512(), default_backend())
+ self._requeststring = request.public_bytes(serialization.Encoding.PEM)
+
+
+ def _from_csr(self):
+ if os.path.exists(os.path.join(self._basename, "csr.pem")):
+ with open(os.path.join(self._basename, "csr.pem"), "rb") as csrfd:
+ self._requeststring = csrfd.read()
+
+
+ def _from_scratch(self):
+ raise NotImplementedError("Key generation is currently not implemented")
+
+
+ def asString(self):
+ return self._requeststring
+
+
+ def save(self, certificate, chain):
+ with open(os.path.join(self._basename, "cert.pem"), "wb") as certfd:
+ certfd.write(certificate.body._dump(OpenSSL.crypto.FILETYPE_PEM))
+ for cert in chain:
+ certfd.write(cert._dump(OpenSSL.crypto.FILETYPE_PEM))
+