def create_certificate(self, csr, issuer_options): """ Creates an ACME certificate. :param csr: :param issuer_options: :return: :raise Exception: """ authority = issuer_options.get('authority') create_immediately = issuer_options.get('create_immediately', False) acme_client, registration = setup_acme_client(authority) dns_provider = issuer_options.get('dns_provider') dns_provider_options = dns_provider.options if not dns_provider: raise InvalidConfiguration( "DNS Provider setting is required for ACME certificates.") credentials = json.loads(dns_provider.credentials) current_app.logger.debug("Using DNS provider: {0}".format( dns_provider.provider_type)) dns_provider_type = __import__(dns_provider.provider_type, globals(), locals(), [], 1) account_number = credentials.get("account_id") if dns_provider.provider_type == 'route53' and not account_number: error = "Route53 DNS Provider {} does not have an account number configured.".format( dns_provider.name) current_app.logger.error(error) raise InvalidConfiguration(error) domains = get_domains(issuer_options) if not create_immediately: # Create pending authorizations that we'll need to do the creation authz_domains = [] for d in domains: if type(d) == str: authz_domains.append(d) else: authz_domains.append(d.value) dns_authorization = authorization_service.create( account_number, authz_domains, dns_provider.provider_type) # Return id of the DNS Authorization return None, None, dns_authorization.id authorizations = get_authorizations(acme_client, account_number, domains, dns_provider_type, dns_provider_options) finalize_authorizations(acme_client, account_number, dns_provider_type, authorizations, dns_provider_options) pem_certificate, pem_certificate_chain = request_certificate( acme_client, authorizations, csr) # TODO add external ID (if possible) return pem_certificate, pem_certificate_chain, None
def __init__(self, *args, **kwargs): """Initialize the plugin with the appropriate details.""" sender = current_app.config.get("LEMUR_EMAIL_SENDER", "ses").lower() if sender not in ["ses", "smtp"]: raise InvalidConfiguration( "Email sender type {0} is not recognized.")
def revoke_certificate(self, certificate, crl_reason=0): if not self.reuse_account(certificate.authority): raise InvalidConfiguration( "There is no ACME account saved, unable to revoke the certificate." ) acme_client, _ = self.setup_acme_client(certificate.authority) fullchain_com = jose.ComparableX509( OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, certificate.body)) try: acme_client.revoke( fullchain_com, crl_reason ) # revocation reason as int (per RFC 5280 section 5.3.1) except (errors.ConflictError, errors.ClientError, errors.Error) as e: # Certificate already revoked. current_app.logger.error( "Certificate revocation failed with message: " + e.detail) metrics.send("acme_revoke_certificate_failure", "counter", 1) return False current_app.logger.warning("Certificate succesfully revoked: " + certificate.name) metrics.send("acme_revoke_certificate_success", "counter", 1) return True
def create_certificate(self, csr, issuer_options): """ Creates an ACME certificate. :param csr: :param issuer_options: :return: :raise Exception: """ self.acme = AcmeDnsHandler() authority = issuer_options.get("authority") create_immediately = issuer_options.get("create_immediately", False) acme_client, registration = self.acme.setup_acme_client(authority) dns_provider = issuer_options.get("dns_provider", {}) if dns_provider: dns_provider_options = dns_provider.options credentials = json.loads(dns_provider.credentials) current_app.logger.debug("Using DNS provider: {0}".format( dns_provider.provider_type)) dns_provider_plugin = __import__(dns_provider.provider_type, globals(), locals(), [], 1) account_number = credentials.get("account_id") provider_type = dns_provider.provider_type if provider_type == "route53" and not account_number: error = "Route53 DNS Provider {} does not have an account number configured.".format( dns_provider.name) current_app.logger.error(error) raise InvalidConfiguration(error) else: dns_provider = {} dns_provider_options = None account_number = None provider_type = None domains = self.acme.get_domains(issuer_options) if not create_immediately: # Create pending authorizations that we'll need to do the creation dns_authorization = authorization_service.create( account_number, domains, provider_type) # Return id of the DNS Authorization return None, None, dns_authorization.id authorizations = self.acme.get_authorizations( acme_client, account_number, domains, dns_provider_plugin, dns_provider_options, ) self.acme.finalize_authorizations( acme_client, account_number, dns_provider_plugin, authorizations, dns_provider_options, ) pem_certificate, pem_certificate_chain = self.acme.request_certificate( acme_client, authorizations, csr) # TODO add external ID (if possible) return pem_certificate, pem_certificate_chain, None
def create_authority(options): """ Creates an authority, this authority is then used by Lemur to allow a user to specify which Certificate Authority they want to sign their certificate. :param options: :return: """ role = {"username": "", "password": "", "name": "ejbca"} plugin_options = options.get("plugin", {}).get("plugin_options") if not plugin_options: error = "Invalid options for lemur_ejbca plugin: {}".format( options) current_app.logger.error(error) raise InvalidConfiguration(error) # Define static auth_root based off configuration variable by default. However, if user has passed a # certificate, use this certificate as the root. ejbca_root = current_app.config.get("EJBCA_ROOT") chain = "" for option in plugin_options: if option.get("name") == "certificate": ejbca_root = option.get("value") elif option.get("name") == "chain": chain = option.get("chain") return ejbca_root, chain, [role]
def create_authority(options): """ Creates an authority, this authority is then used by Lemur to allow a user to specify which Certificate Authority they want to sign their certificate. :param options: :return: """ name = "acme" if options['name']: name += "_" + '_'.join(options['name'].split(" ")) role = {"username": "", "password": "", "name": name} plugin_options = options.get("plugin", {}).get("plugin_options") if not plugin_options: error = "Invalid options for lemur_acme plugin: {}".format(options) current_app.logger.error(error) raise InvalidConfiguration(error) # Define static acme_root based off configuration variable by default. However, if user has passed a # certificate, use this certificate as the root. acme_root = current_app.config.get("ACME_ROOT") for option in plugin_options: if option.get("name") == "certificate": acme_root = option.get("value") return acme_root, "", [role]
def validate_conf(app, required_vars): """ Ensures that the given fields are set in the applications conf. :param app: :param required_vars: list """ for var in required_vars: if not app.config.get(var): raise InvalidConfiguration("Required variable '{var}' is not set in Lemur's conf.".format(var=var))
def create_certificate(self, csr, issuer_options): """ Creates an ACME certificate. :param csr: :param issuer_options: :return: :raise Exception: """ self.acme = AcmeDnsHandler() authority = issuer_options.get("authority") create_immediately = issuer_options.get("create_immediately", False) acme_client, registration = self.acme.setup_acme_client(authority) domains = self.acme.get_domains(issuer_options) dns_provider = issuer_options.get("dns_provider", {}) if dns_provider: for domain in domains: # Currently, we only support specifying one DNS provider per certificate, even if that # certificate has multiple SANs that may belong to different provid self.acme.dns_providers_for_domain[domain] = [dns_provider] credentials = json.loads(dns_provider.credentials) current_app.logger.debug("Using DNS provider: {0}".format( dns_provider.provider_type)) account_number = credentials.get("account_id") provider_type = dns_provider.provider_type if provider_type == "route53" and not account_number: error = "Route53 DNS Provider {} does not have an account number configured.".format( dns_provider.name) current_app.logger.error(error) raise InvalidConfiguration(error) else: dns_provider = {} account_number = None provider_type = None for domain in domains: self.acme.autodetect_dns_providers(domain) # Create pending authorizations that we'll need to do the creation dns_authorization = authorization_service.create( account_number, domains, provider_type) if not create_immediately: # Return id of the DNS Authorization return None, None, dns_authorization.id pem_certificate, pem_certificate_chain = self.create_certificate_immediately( acme_client, dns_authorization, csr) # TODO add external ID (if possible) return pem_certificate, pem_certificate_chain, None
def check_validation(validation): """ Checks that the given validation string compiles successfully. :param validation: :return str: The validation pattern, if compilation succeeds """ try: compiled = re.compile(validation) except re.error as e: raise InvalidConfiguration(f"Validation {validation} couldn't compile. Reason: {e}") return compiled.pattern
def create_authority(options): """ Creates an authority, this authority is then used by Lemur to allow a user to specify which Certificate Authority they want to sign their certificate. :param options: :return: """ role = {'username': '', 'password': '', 'name': 'acme'} plugin_options = options.get('plugin', {}).get('plugin_options') if not plugin_options: error = "Invalid options for lemur_acme plugin: {}".format(options) current_app.logger.error(error) raise InvalidConfiguration(error) # Define static acme_root based off configuration variable by default. However, if user has passed a # certificate, use this certificate as the root. acme_root = current_app.config.get('ACME_ROOT') for option in plugin_options: if option.get('name') == 'certificate': acme_root = option.get('value') return acme_root, "", [role]