Example #1
0
    def create_certificate(self):
        """ Create Node certificate from Cluster CA authority

        """
        if self.certificate is None:
            # Get PKI next serial number
            cluster = Cluster.objects.get()
            serial = cluster.ca_serial
            serial += 1

            crt, key = ssl_utils.mk_signed_cert(ssl_utils.get_ca_cert_path(),
                                                ssl_utils.get_ca_key_path(),
                                                self.name, 'FR', '', '', '',
                                                '', serial)

            # TODO: Error handling
            # Save serial number
            cluster.ca_serial = serial
            cluster.save()

            # Store the certificate
            certificate = SSLCertificate()
            certificate.name = str(crt.get_subject())
            certificate.cn = str(self.name)
            certificate.o = 'FR'
            certificate.cert = crt.as_pem().decode('utf8')
            certificate.key = key.as_pem(cipher=None).decode('utf8')
            certificate.status = 'V'
            certificate.issuer = str(crt.get_issuer())
            certificate.validfrom = str(crt.get_not_before().get_datetime())
            certificate.validtill = str(crt.get_not_after().get_datetime())
            certificate.serial = str(serial)
            certificate.is_ca = False

            internal = cluster.ca_certificate
            certificate.chain = str(internal.cert)

            certificate.save()
            self.certificate = certificate
            self.save()
Example #2
0
def sign(request):
    """ method dedicated to sign an external certificate request
    :param request: Django POST request object
    :param POST['csr']: The PEM certificate request
    """
    cert = SSLCertificate()
    cert.cert = ""
    cert.key = ""
    cert.chain = ""
    cert.csr = ""

    if request.method == 'POST':
        dataPosted = request.POST

        error = dict()
        err = None
        try:
            cert.csr = str(dataPosted['csr'])
        except:
            err = True
            error['csr'] = "PEM Certificate request required"
            pass

        if err:
            return render_to_response('cert_sign.html', {
                'cert': cert,
                'error': error
            },
                                      context_instance=RequestContext(request))

        # Check the request
        try:
            x509Request = X509.load_request_string(cert.csr)
        except:
            error['csr'] = "Invalid PEM Certificate Request"
            return render_to_response('cert_sign.html', {
                'cert': cert,
                'error': error
            },
                                      context_instance=RequestContext(request))

        # Get cluster
        cluster = Cluster.objects.get()

        # Find the internal CA's certificate and private key
        internal = cluster.ca_certificate
        ca_key = RSA.load_key_string(internal.key.encode('utf8'))
        ca_cert = X509.load_cert_string(internal.cert.encode('utf8'))

        # Get PKI next serial number
        serial = cluster.ca_serial
        serial += 1

        # Create a certificate from the request
        crt = mk_cert(serial)
        crt.set_pubkey(x509Request.get_pubkey())

        pk = EVP.PKey()
        pk.assign_rsa(ca_key)

        issuer = X509.X509_Name()
        subject = X509.X509_Name()

        fields = str(x509Request.get_subject()).split('/')
        for field in fields:
            tmp = field.split('=')
            if str(tmp[0]) == "CN":
                subject.CN = tmp[1]
                cert.cn = tmp[1]
            elif str(tmp[0]) == "C":
                subject.C = tmp[1]
                cert.c = tmp[1]
            elif str(tmp[0]) == "ST":
                subject.ST = tmp[1]
                cert.st = tmp[1]
            elif str(tmp[0]) == "L":
                subject.L = tmp[1]
                cert.l = tmp[1]
            elif str(tmp[0]) == "O":
                subject.O = tmp[1]
                cert.o = tmp[1]
            elif str(tmp[0]) == "OU":
                subject.OU = tmp[1]
                cert.ou = tmp[1]

        fields = str(ca_cert.get_subject()).split('/')
        for field in fields:
            tmp = field.split('=')
            if str(tmp[0]) == "CN":
                issuer.CN = tmp[1]
            elif str(tmp[0]) == "C":
                issuer.C = tmp[1]
            elif str(tmp[0]) == "ST":
                issuer.ST = tmp[1]
            elif str(tmp[0]) == "L":
                issuer.L = tmp[1]
            elif str(tmp[0]) == "O":
                issuer.O = tmp[1]
            elif str(tmp[0]) == "OU":
                issuer.OU = tmp[1]

        crt.set_subject(subject)
        crt.set_issuer(issuer)

        crt.add_ext(X509.new_extension('basicConstraints', 'CA:FALSE'))
        crt.add_ext(
            X509.new_extension('subjectKeyIdentifier',
                               str(crt.get_fingerprint())))

        try:
            crt.sign(pk, 'sha256')
        except Exception as e:
            print(e)

        # Save serial number
        cluster.ca_serial = serial
        cluster.save()

        # Store the certificate
        cert.cert = crt.as_pem().decode('utf8')
        cert.name = str(crt.get_subject())
        cert.status = 'V'
        cert.issuer = str(internal.issuer)
        cert.validfrom = str(crt.get_not_before().get_datetime())
        cert.validtill = str(crt.get_not_after().get_datetime())
        cert.is_ca = False
        cert.chain = str(internal.cert)
        cert.serial = str(serial)
        cert.save()

        return HttpResponseRedirect('/system/cert/')

    return render_to_response('cert_sign.html', {
        'cert': cert,
    },
                              context_instance=RequestContext(request))
Example #3
0
def load(request):
    """ method dedicated to certificate importation
    :param request: Django POST request object
    :param POST['cert']: The PEM X509 certificate
    :param POST['key']: The PEM X509 key
    :param POST['chain']: The PEM X509 certificate chain
    """
    cert = SSLCertificate()
    cert.cert = ""
    cert.key = ""
    cert.chain = ""
    if request.method == 'POST':
        dataPosted = request.POST

        error = dict()
        err = None
        try:
            cert_cert = dataPosted['cert']
        except:
            err = True
            error['cert'] = "X509 PEM Certificate required"
            pass

        try:
            cert_key = dataPosted['key']
        except:
            err = True
            error['key'] = "X509 PEM Key required"
            pass

        try:
            cert.chain = str(dataPosted['chain'])
        except:
            pass

        if err:
            return render_to_response('cert_import.html', {
                'cert': cert,
                'error': error
            },
                                      context_instance=RequestContext(request))

        # Check the certificate
        try:
            x509Cert = X509.load_cert_string(bytes(cert_cert, 'utf8'))
            cert.cert = str(cert_cert)
        except:
            error['cert'] = "Invalid X509 PEM Certificate"
            return render_to_response('cert_import.html', {
                'cert': cert,
                'error': error
            },
                                      context_instance=RequestContext(request))

        global keypass
        try:
            keypass = str(dataPosted['keypass'])
        except:
            pass

        # Check the private key
        try:
            bio = BIO.MemoryBuffer(bytes(cert_key, 'utf8'))
            RSA.load_key_bio(bio, callback=read_pass_from_POST)
            cert.key = str(cert_key)
        except RSA.RSAError:
            try:
                bio = BIO.MemoryBuffer(bytes(cert_key, 'utf8'))
                EC.load_key_bio(bio, callback=read_pass_from_POST)
                cert.key = str(cert_key)
            except RSA.RSAError:
                error['keypass'] = "******"
            except Exception as e:
                logger.exception(e)
                error['key'] = "Invalid PEM KEY"
        except Exception as e:
            logger.exception(e)
            error['key'] = "Invalid PEM KEY"

        if error:
            return render_to_response('cert_import.html', {
                'cert': cert,
                'error': error
            },
                                      context_instance=RequestContext(request))

        # Store certificate details
        cert.name = str(x509Cert.get_subject())
        cert.status = 'V'
        cert.issuer = str(x509Cert.get_issuer())
        try:
            cert.validfrom = str(x509Cert.get_not_before().get_datetime())
        except Exception as e:
            logger.error(
                "Exception while retrieving validation date 'before' of certificates : "
            )
            logger.exception(e)

        try:
            cert.validtill = str(x509Cert.get_not_after().get_datetime())
        except Exception as e:
            logger.error(
                "Exception while retrieving validation date 'after' of certificates : "
            )
            logger.exception(e)

        if x509Cert.check_ca():
            cert.is_ca = True
        else:
            cert.is_ca = False

        # Find certificate fields
        fields = cert.name.split('/')
        for field in fields:
            tmp = field.split('=')
            if str(tmp[0]) == "CN":
                cert.cn = tmp[1]
            elif str(tmp[0]) == "C":
                cert.c = tmp[1]
            elif str(tmp[0]) == "ST":
                cert.st = tmp[1]
            elif str(tmp[0]) == "L":
                cert.l = tmp[1]
            elif str(tmp[0]) == "O":
                cert.o = tmp[1]
            elif str(tmp[0]) == "OU":
                cert.ou = tmp[1]

        # if cert.cn is empty check if subjectAltName is set en use it
        if (not cert.cn):
            alt_name = x509Cert.get_ext('subjectAltName').get_value()
            if (alt_name):
                cert.cn = alt_name

        cert.save()

        return HttpResponseRedirect('/system/cert/')

    return render_to_response('cert_import.html', {
        'cert': cert,
    },
                              context_instance=RequestContext(request))