1
# Copyright 2014 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Security-related code, primarily relating to TLS."""
6
from __future__ import (
16
"get_region_certificate",
19
from datetime import datetime
21
from maasserver import locks
22
from maasserver.models.config import Config
23
from provisioningserver.utils import synchronous
25
from twisted.internet import ssl
29
ref = datetime(2012, 01, 16, tzinfo=UTC)
30
now = datetime.now(tz=UTC)
31
serial = (now - ref).total_seconds()
35
def load_region_certificate():
36
upem = Config.objects.get_config("rpc_region_certificate")
40
# The certificate will be returned as a unicode string. However,
41
# it's in PEM form, a base-64 encoded certificate and key, so we
42
# need to get back to bytes, then parse it.
43
pem = upem.decode("ascii")
44
return ssl.PrivateCertificate.loadPEM(pem)
47
def save_region_certificate(cert):
48
assert isinstance(cert, ssl.PrivateCertificate)
49
# We'll store the PEM dump of the certificate in the database. We'll
50
# get this as a byte-string, so we need to decode to unicode.
51
upem = cert.dumpPEM().decode("ascii")
52
Config.objects.set_config("rpc_region_certificate", upem)
55
def generate_region_certificate():
56
key = ssl.KeyPair.generate(size=2048)
57
return key.selfSignedCert(serialNumber=get_serial(), CN="MAAS Region")
61
def get_region_certificate():
62
cert = load_region_certificate()
65
# Load again, while holding the security lock.
66
cert = load_region_certificate()
68
cert = generate_region_certificate()
69
save_region_certificate(cert)