]> git.siccegge.de Git - tooling/letool.git/blobdiff - sicceggetools/acme/certificate.py
Change everything
[tooling/letool.git] / sicceggetools / acme / certificate.py
diff --git a/sicceggetools/acme/certificate.py b/sicceggetools/acme/certificate.py
new file mode 100644 (file)
index 0000000..4ff1496
--- /dev/null
@@ -0,0 +1,67 @@
+#!/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))
+