def test_encryption(client): from lemur.common.utils import data_encrypt, data_decrypt plaintext = "encrypt this string" assert (data_decrypt(data_encrypt(plaintext)) == plaintext) plaintext = 123 assert (data_decrypt(data_encrypt(plaintext)) == str(plaintext)) plaintext = {"this": "is a test"} assert (data_decrypt(data_encrypt(plaintext)) == str(plaintext))
def create(**kwargs): """ Creates a new authority. """ ca_name = kwargs.get("name") if get_by_name(ca_name): raise Exception(f"Authority with name {ca_name} already exists") if role_service.get_by_name( f"{ca_name}_admin") or role_service.get_by_name( f"{ca_name}_operator"): raise Exception( f"Admin and/or operator roles for authority {ca_name} already exist" ) body, private_key, chain, roles = mint(**kwargs) kwargs["creator"].roles = list(set(list(kwargs["creator"].roles) + roles)) kwargs["body"] = body kwargs["private_key"] = private_key kwargs["chain"] = chain if kwargs.get("roles"): kwargs["roles"] += roles else: kwargs["roles"] = roles cert = upload(**kwargs) kwargs["authority_certificate"] = cert if kwargs.get("plugin", {}).get("plugin_options", []): # encrypt the private key before persisting in DB for option in kwargs.get("plugin").get("plugin_options"): if option["name"] == "acme_private_key" and option["value"]: option["value"] = data_encrypt(option["value"]) kwargs["options"] = json.dumps(kwargs["plugin"]["plugin_options"]) authority = Authority(**kwargs) authority = database.create(authority) kwargs["creator"].authorities.append(authority) log_service.audit_log("create_authority", ca_name, "Created new authority") issuer = kwargs["plugin"]["plugin_object"] current_app.logger.warning( f"Created new authority {ca_name} with issuer {issuer.title}") metrics.send("authority_created", "counter", 1, metric_tags=dict(owner=authority.owner)) return authority
def setup_acme_client(self, authority): if not authority.options: raise InvalidAuthority("Invalid authority. Options not set") options = {} for option in json.loads(authority.options): options[option["name"]] = option.get("value") email = options.get("email", current_app.config.get("ACME_EMAIL")) tel = options.get("telephone", current_app.config.get("ACME_TEL")) directory_url = options.get( "acme_url", current_app.config.get("ACME_DIRECTORY_URL")) existing_key = options.get("acme_private_key", current_app.config.get("ACME_PRIVATE_KEY")) existing_regr = options.get("acme_regr", current_app.config.get("ACME_REGR")) eab_kid = options.get("eab_kid", None) eab_hmac_key = options.get("eab_hmac_key", None) if existing_key and existing_regr: current_app.logger.debug("Reusing existing ACME account") # Reuse the same account for each certificate issuance # existing_key might be encrypted if not is_json(existing_key): # decrypt the private key, if not already in plaintext (json format) existing_key = data_decrypt(existing_key) key = jose.JWK.json_loads(existing_key) regr = messages.RegistrationResource.json_loads(existing_regr) current_app.logger.debug( "Connecting with directory at {0}".format(directory_url)) net = ClientNetwork(key, account=regr) client = BackwardsCompatibleClientV2(net, key, directory_url) return client, {} else: # Create an account for each certificate issuance key = jose.JWKRSA(key=generate_private_key("RSA2048")) current_app.logger.debug("Creating a new ACME account") current_app.logger.debug( "Connecting with directory at {0}".format(directory_url)) net = ClientNetwork(key, account=None, timeout=3600) client = BackwardsCompatibleClientV2(net, key, directory_url) if eab_kid and eab_hmac_key: # external account binding (eab_kid and eab_hmac_key could be potentially single use to establish # long-term credentials) eab = messages.ExternalAccountBinding.from_data( account_public_key=key.public_key(), kid=eab_kid, hmac_key=eab_hmac_key, directory=client.directory) registration = client.new_account_and_tos( messages.NewRegistration.from_data( email=email, external_account_binding=eab)) else: registration = client.new_account_and_tos( messages.NewRegistration.from_data(email=email)) # if store_account is checked, add the private_key and registration resources to the options if options['store_account']: new_options = json.loads(authority.options) # the key returned by fields_to_partial_json is missing the key type, so we add it manually key_dict = key.fields_to_partial_json() key_dict["kty"] = "RSA" acme_private_key = { "name": "acme_private_key", "value": data_encrypt(json.dumps(key_dict)) } new_options.append(acme_private_key) acme_regr = { "name": "acme_regr", "value": json.dumps({ "body": {}, "uri": registration.uri }) } new_options.append(acme_regr) authorities_service.update_options( authority.id, options=json.dumps(new_options)) current_app.logger.debug("Connected: {0}".format(registration.uri)) return client, registration