Esempio n. 1
0
 def _validate_cert(cls, ca_cert, ca_key, ca_key_pass):
     if not ca_cert:
         LOG.info("Using CA Certificate from config.")
         try:
             ca_cert = open(CONF.certificates.ca_certificate, 'rb').read()
         except IOError:
             raise exceptions.CertificateGenerationException(
                 msg="Failed to load CA Certificate {0}."
                     .format(CONF.certificates.ca_certificate)
             )
     if not ca_key:
         LOG.info("Using CA Private Key from config.")
         try:
             ca_key = open(CONF.certificates.ca_private_key, 'rb').read()
         except IOError:
             raise exceptions.CertificateGenerationException(
                 msg="Failed to load CA Private Key {0}."
                     .format(CONF.certificates.ca_private_key)
             )
     if not ca_key_pass:
         ca_key_pass = CONF.certificates.ca_private_key_passphrase
         if ca_key_pass:
             LOG.info("Using CA Private Key Passphrase from config.")
         else:
             LOG.info("No Passphrase found for CA Private Key, not using "
                      "one.")
Esempio n. 2
0
    def sign_cert(cls, csr, validity=None, **kwargs):
        """Signs a certificate using Anchor based on the specified CSR

        :param csr: A Certificate Signing Request
        :param validity: Will be ignored for now
        :param kwargs: Will be ignored for now

        :return: Signed certificate
        :raises Exception: if certificate signing fails
        """
        LOG.debug("Signing a certificate request using Anchor")

        try:
            LOG.debug('Certificate: %s', csr)
            r = requests.post(CONF.anchor.url,
                              data={
                                  'user': CONF.anchor.username,
                                  'secret': CONF.anchor.password,
                                  'encoding': 'pem',
                                  'csr': csr
                              })

            if r.status_code != 200:
                LOG.debug('Anchor returned: %s', r.content)
                raise AnchorException(
                    _("Anchor returned Status Code : "
                      "{0}").format(str(r.status_code)))

            return r.content

        except Exception as e:
            LOG.error("Unable to sign certificate.")
            raise exceptions.CertificateGenerationException(msg=e)
Esempio n. 3
0
    def sign_cert(cls, csr, validity, ca_cert=None, ca_key=None,
                  ca_key_pass=None, ca_digest=None):
        """Signs a certificate using our private CA based on the specified CSR

        The signed certificate will be valid from now until <validity> seconds
        from now.

        :param csr: A Certificate Signing Request
        :param validity: Valid for <validity> seconds from the current time
        :param ca_cert: Signing Certificate (default: config)
        :param ca_key: Signing Certificate Key (default: config)
        :param ca_key_pass: Signing Certificate Key Pass (default: config)
        :param ca_digest: Digest method to use for signing (default: config)

        :return: Signed certificate
        :raises Exception: if certificate signing fails
        """
        LOG.info("Signing a certificate request using OpenSSL locally.")
        cls._validate_cert(ca_cert, ca_key, ca_key_pass)
        if not ca_digest:
            ca_digest = CONF.certificates.signing_digest
        try:
            algorithm = getattr(hashes, ca_digest.upper())()
        except AttributeError:
            raise crypto_exceptions.UnsupportedAlgorithm(
                "Supplied digest method not found: %s" % ca_digest
            )

        if not ca_cert:
            with open(CONF.certificates.ca_certificate, 'rb') as f:
                ca_cert = f.read()
        if not ca_key:
            with open(CONF.certificates.ca_private_key, 'rb') as f:
                ca_key = f.read()
        if not ca_key_pass:
            ca_key_pass = CONF.certificates.ca_private_key_passphrase
            if ca_key_pass is not None:
                ca_key_pass = ca_key_pass.encode('utf-8')

        try:
            lo_cert = x509.load_pem_x509_certificate(
                data=ca_cert, backend=backends.default_backend())
            lo_key = serialization.load_pem_private_key(
                data=ca_key, password=ca_key_pass,
                backend=backends.default_backend())
            lo_req = x509.load_pem_x509_csr(data=csr,
                                            backend=backends.default_backend())
            new_cert = x509.CertificateBuilder()
            new_cert = new_cert.serial_number(cls._new_serial())
            valid_from_datetime = datetime.datetime.utcnow()
            valid_to_datetime = (datetime.datetime.utcnow() +
                                 datetime.timedelta(seconds=validity))
            new_cert = new_cert.not_valid_before(valid_from_datetime)
            new_cert = new_cert.not_valid_after(valid_to_datetime)
            new_cert = new_cert.issuer_name(lo_cert.subject)
            new_cert = new_cert.subject_name(lo_req.subject)
            new_cert = new_cert.public_key(lo_req.public_key())
            new_cert = new_cert.add_extension(
                x509.BasicConstraints(ca=False, path_length=None),
                critical=True
            )
            cn_str = lo_req.subject.get_attributes_for_oid(
                x509.oid.NameOID.COMMON_NAME)[0].value
            new_cert = new_cert.add_extension(
                x509.SubjectAlternativeName([x509.DNSName(cn_str)]),
                critical=False
            )
            new_cert = new_cert.add_extension(
                x509.KeyUsage(
                    digital_signature=True,
                    key_encipherment=True,
                    data_encipherment=True,
                    key_agreement=True,
                    content_commitment=False,
                    key_cert_sign=False,
                    crl_sign=False,
                    encipher_only=False,
                    decipher_only=False
                ),
                critical=True
            )
            new_cert = new_cert.add_extension(
                x509.ExtendedKeyUsage([
                    x509.oid.ExtendedKeyUsageOID.SERVER_AUTH,
                    x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH
                ]),
                critical=True
            )
            signed_cert = new_cert.sign(private_key=lo_key,
                                        algorithm=algorithm,
                                        backend=backends.default_backend())
            return signed_cert.public_bytes(
                encoding=serialization.Encoding.PEM)
        except Exception as e:
            LOG.error("Unable to sign certificate.")
            raise exceptions.CertificateGenerationException(msg=e)
Esempio n. 4
0
    def sign_cert(cls, csr, validity, ca_cert=None, ca_key=None,
                  ca_key_pass=None, ca_digest=None):
        """Signs a certificate using our private CA based on the specified CSR

        The signed certificate will be valid from now until <validity> seconds
        from now.

        :param csr: A Certificate Signing Request
        :param validity: Valid for <validity> seconds from the current time
        :param ca_cert: Signing Certificate (default: config)
        :param ca_key: Signing Certificate Key (default: config)
        :param ca_key_pass: Signing Certificate Key Pass (default: config)
        :param ca_digest: Digest method to use for signing (default: config)

        :return: Signed certificate
        :raises Exception: if certificate signing fails
        """
        LOG.info(_LI(
            "Signing a certificate request using pyOpenSSL locally."
        ))
        cls._validate_cert(ca_cert, ca_key, ca_key_pass)
        if not ca_digest:
            ca_digest = CONF.certificates.signing_digest
        if not ca_cert:
            with open(CONF.certificates.ca_certificate, 'r') as f:
                ca_cert = f.read()
        if not ca_key:
            with open(CONF.certificates.ca_private_key, 'r') as f:
                ca_key = f.read()
        if not ca_key_pass:
            ca_key_pass = CONF.certificates.ca_private_key_passphrase

        try:
            lo_cert = crypto.load_certificate(crypto.FILETYPE_PEM, ca_cert)
            lo_key = crypto.load_privatekey(crypto.FILETYPE_PEM, ca_key,
                                            ca_key_pass)
            lo_req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr)

            new_cert = crypto.X509()
            new_cert.set_version(2)
            new_cert.set_serial_number(cls._new_serial())
            new_cert.gmtime_adj_notBefore(0)
            new_cert.gmtime_adj_notAfter(validity)
            new_cert.set_issuer(lo_cert.get_subject())
            new_cert.set_subject(lo_req.get_subject())
            new_cert.set_pubkey(lo_req.get_pubkey())
            exts = [
                crypto.X509Extension(
                    six.b('basicConstraints'), True, six.b('CA:false')),
                crypto.X509Extension(
                    six.b('keyUsage'), True,
                    six.b('digitalSignature, keyEncipherment')),
                crypto.X509Extension(
                    six.b('extendedKeyUsage'), False,
                    six.b('clientAuth, serverAuth')),
                crypto.X509Extension(
                    six.b('nsCertType'), False,
                    six.b('client, server'))
            ]
            new_cert.add_extensions(exts)
            new_cert.sign(lo_key, ca_digest)

            return crypto.dump_certificate(crypto.FILETYPE_PEM, new_cert)
        except Exception as e:
            LOG.error(_LE("Unable to sign certificate."))
            raise exceptions.CertificateGenerationException(msg=e)