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.")
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)
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)
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)