~lutostag/ubuntu/trusty/maas/1.5.2+packagefix

« back to all changes in this revision

Viewing changes to src/maasserver/security.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2014-03-28 10:43:53 UTC
  • mto: This revision was merged to the branch mainline in revision 57.
  • Revision ID: package-import@ubuntu.com-20140328104353-ekpolg0pm5xnvq2s
Tags: upstream-1.5+bzr2204
ImportĀ upstreamĀ versionĀ 1.5+bzr2204

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Security-related code, primarily relating to TLS."""
 
5
 
 
6
from __future__ import (
 
7
    absolute_import,
 
8
    print_function,
 
9
    unicode_literals,
 
10
    )
 
11
 
 
12
str = None
 
13
 
 
14
__metaclass__ = type
 
15
__all__ = [
 
16
    "get_region_certificate",
 
17
]
 
18
 
 
19
from datetime import datetime
 
20
 
 
21
from maasserver import locks
 
22
from maasserver.models.config import Config
 
23
from provisioningserver.utils import synchronous
 
24
from pytz import UTC
 
25
from twisted.internet import ssl
 
26
 
 
27
 
 
28
def get_serial():
 
29
    ref = datetime(2012, 01, 16, tzinfo=UTC)
 
30
    now = datetime.now(tz=UTC)
 
31
    serial = (now - ref).total_seconds()
 
32
    return int(serial)
 
33
 
 
34
 
 
35
def load_region_certificate():
 
36
    upem = Config.objects.get_config("rpc_region_certificate")
 
37
    if upem is None:
 
38
        return None
 
39
    else:
 
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)
 
45
 
 
46
 
 
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)
 
53
 
 
54
 
 
55
def generate_region_certificate():
 
56
    key = ssl.KeyPair.generate(size=2048)
 
57
    return key.selfSignedCert(serialNumber=get_serial(), CN="MAAS Region")
 
58
 
 
59
 
 
60
@synchronous
 
61
def get_region_certificate():
 
62
    cert = load_region_certificate()
 
63
    if cert is None:
 
64
        with locks.security:
 
65
            # Load again, while holding the security lock.
 
66
            cert = load_region_certificate()
 
67
            if cert is None:
 
68
                cert = generate_region_certificate()
 
69
                save_region_certificate(cert)
 
70
    return cert